Merge branch 'community-scripts:main' into main
This commit is contained in:
@@ -9,7 +9,7 @@ APP="authentik"
|
|||||||
var_tags="${var_tags:-auth}"
|
var_tags="${var_tags:-auth}"
|
||||||
var_cpu="${var_cpu:-4}"
|
var_cpu="${var_cpu:-4}"
|
||||||
var_ram="${var_ram:-4096}"
|
var_ram="${var_ram:-4096}"
|
||||||
var_disk="${var_disk:-10}"
|
var_disk="${var_disk:-16}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-13}"
|
var_version="${var_version:-13}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|||||||
@@ -51,7 +51,14 @@ function update_script() {
|
|||||||
msg_info "Building HyperDX"
|
msg_info "Building HyperDX"
|
||||||
$STD yarn install
|
$STD yarn install
|
||||||
$STD yarn workspace @hyperdx/common-utils run build
|
$STD yarn workspace @hyperdx/common-utils run build
|
||||||
$STD yarn workspace @hyperdx/api run build
|
rm -rf /opt/clickstack/packages/api/build
|
||||||
|
yarn workspace @hyperdx/api exec tsc >>"$(get_active_logfile)" 2>&1 || true
|
||||||
|
$STD yarn workspace @hyperdx/api exec tsc-alias
|
||||||
|
cp -r /opt/clickstack/packages/api/src/opamp/proto /opt/clickstack/packages/api/build/opamp/ 2>/dev/null || true
|
||||||
|
[[ -f /opt/clickstack/packages/api/build/index.js ]] || {
|
||||||
|
msg_error "HyperDX API build failed: build/index.js not found"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
$STD yarn workspace @hyperdx/app run build
|
$STD yarn workspace @hyperdx/app run build
|
||||||
msg_ok "Built HyperDX"
|
msg_ok "Built HyperDX"
|
||||||
|
|
||||||
@@ -83,6 +90,7 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export CLICKSTACK="no"
|
||||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "CLICKSTACK" --yesno "Install ClickStack observability stack?\n\n(HyperDX UI + OTel Collector + MongoDB)\nRequires: 4 CPU, 8GB RAM, 30GB Disk" 12 58); then
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "CLICKSTACK" --yesno "Install ClickStack observability stack?\n\n(HyperDX UI + OTel Collector + MongoDB)\nRequires: 4 CPU, 8GB RAM, 30GB Disk" 12 58); then
|
||||||
export CLICKSTACK="yes"
|
export CLICKSTACK="yes"
|
||||||
var_cpu="4"
|
var_cpu="4"
|
||||||
|
|||||||
6
ct/headers/stoatchat
Normal file
6
ct/headers/stoatchat
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
_____ __ __ __ __
|
||||||
|
/ ___// /_____ ____ _/ /______/ /_ ____ _/ /_
|
||||||
|
\__ \/ __/ __ \/ __ `/ __/ ___/ __ \/ __ `/ __/
|
||||||
|
___/ / /_/ /_/ / /_/ / /_/ /__/ / / / /_/ / /_
|
||||||
|
/____/\__/\____/\__,_/\__/\___/_/ /_/\__,_/\__/
|
||||||
|
|
||||||
6
ct/headers/xyops
Normal file
6
ct/headers/xyops
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
____
|
||||||
|
_ ____ __/ __ \____ _____
|
||||||
|
| |/_/ / / / / / / __ \/ ___/
|
||||||
|
_> </ /_/ / /_/ / /_/ (__ )
|
||||||
|
/_/|_|\__, /\____/ .___/____/
|
||||||
|
/____/ /_/
|
||||||
44
ct/hoodik.sh
44
ct/hoodik.sh
@@ -8,9 +8,9 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
|
|
||||||
APP="Hoodik"
|
APP="Hoodik"
|
||||||
var_tags="${var_tags:-cloud;storage}"
|
var_tags="${var_tags:-cloud;storage}"
|
||||||
var_cpu="${var_cpu:-4}"
|
var_cpu="${var_cpu:-1}"
|
||||||
var_ram="${var_ram:-4096}"
|
var_ram="${var_ram:-1024}"
|
||||||
var_disk="${var_disk:-20}"
|
var_disk="${var_disk:-5}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-13}"
|
var_version="${var_version:-13}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
@@ -25,53 +25,31 @@ function update_script() {
|
|||||||
check_container_storage
|
check_container_storage
|
||||||
check_container_resources
|
check_container_resources
|
||||||
|
|
||||||
if [[ ! -f /usr/local/bin/hoodik ]]; then
|
if [[ ! -f /opt/hoodik/hoodik ]]; then
|
||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "hoodik" "hudikhq/hoodik"; then
|
if check_for_gh_release "hoodik" "hudikhq/hoodik"; then
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Service"
|
||||||
systemctl stop hoodik
|
systemctl stop hoodik
|
||||||
msg_ok "Stopped Services"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
msg_info "Backing up Configuration"
|
msg_info "Backing up Configuration"
|
||||||
cp /opt/hoodik/.env /opt/hoodik.env.bak
|
cp /opt/hoodik/.env /opt/hoodik.env.bak
|
||||||
msg_ok "Backed up Configuration"
|
msg_ok "Backed up Configuration"
|
||||||
|
|
||||||
msg_info "Updating Hoodik (Patience - this takes 15-20 minutes)"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "hoodik" "hudikhq/hoodik" "prebuild" "latest" "/opt/hoodik" "*x86_64.tar.gz"
|
||||||
source ~/.cargo/env
|
|
||||||
rm -rf /opt/hoodik
|
|
||||||
fetch_and_deploy_gh_release "hoodik" "hudikhq/hoodik" "tarball" "latest" "/opt/hoodik"
|
|
||||||
cd /opt/hoodik
|
|
||||||
|
|
||||||
msg_info "Building Frontend"
|
|
||||||
$STD yarn install --frozen-lockfile
|
|
||||||
$STD yarn wasm-pack
|
|
||||||
$STD yarn web:build
|
|
||||||
msg_ok "Built Frontend"
|
|
||||||
|
|
||||||
msg_info "Building Backend"
|
|
||||||
$STD cargo build --release
|
|
||||||
cp /opt/hoodik/target/release/hoodik /usr/local/bin/hoodik
|
|
||||||
chmod +x /usr/local/bin/hoodik
|
|
||||||
msg_ok "Updated Hoodik"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
msg_info "Restoring Configuration"
|
||||||
cp /opt/hoodik.env.bak /opt/hoodik/.env
|
cp /opt/hoodik.env.bak /opt/hoodik/.env
|
||||||
rm -f /opt/hoodik.env.bak
|
rm -f /opt/hoodik.env.bak
|
||||||
msg_ok "Restored Configuration"
|
msg_ok "Restored Configuration"
|
||||||
|
|
||||||
msg_info "Cleaning Up"
|
msg_info "Starting Service"
|
||||||
rm -rf /opt/hoodik/target
|
|
||||||
rm -rf /root/.cargo/registry
|
|
||||||
rm -rf /opt/hoodik/node_modules
|
|
||||||
msg_ok "Cleaned"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start hoodik
|
systemctl start hoodik
|
||||||
msg_ok "Started Services"
|
msg_ok "Started Service"
|
||||||
msg_ok "Updated Successfully"
|
msg_ok "Updated successfully!"
|
||||||
fi
|
fi
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
@@ -83,4 +61,4 @@ description
|
|||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5443${CL}"
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5443/auth/register${CL}"
|
||||||
|
|||||||
@@ -39,10 +39,7 @@ function update_script() {
|
|||||||
msg_info "Building Application"
|
msg_info "Building Application"
|
||||||
cd /opt/puter
|
cd /opt/puter
|
||||||
$STD npm ci
|
$STD npm ci
|
||||||
cd /opt/puter/src/gui
|
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
cd /opt/puter
|
|
||||||
cp -r src/gui/dist dist
|
|
||||||
msg_ok "Built Application"
|
msg_ok "Built Application"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
@@ -60,4 +57,4 @@ description
|
|||||||
msg_ok "Completed Successfully!\n"
|
msg_ok "Completed Successfully!\n"
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:4100${CL}"
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}.nip.io:4100${CL}"
|
||||||
|
|||||||
85
ct/stoatchat.sh
Normal file
85
ct/stoatchat.sh
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/stoatchat/stoatchat
|
||||||
|
|
||||||
|
APP="Stoatchat"
|
||||||
|
var_tags="${var_tags:-chat;messaging;community}"
|
||||||
|
var_cpu="${var_cpu:-4}"
|
||||||
|
var_ram="${var_ram:-10240}"
|
||||||
|
var_disk="${var_disk:-30}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/stoatchat ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "stoatchat" "stoatchat/stoatchat"; then
|
||||||
|
msg_info "Stopping Services"
|
||||||
|
systemctl stop stoatchat-api stoatchat-events stoatchat-autumn stoatchat-january stoatchat-crond
|
||||||
|
msg_ok "Stopped Services"
|
||||||
|
|
||||||
|
msg_info "Backing up Configuration"
|
||||||
|
cp /Revolt.toml /opt/stoatchat_revolt.toml.bak
|
||||||
|
msg_ok "Backed up Configuration"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "stoatchat" "stoatchat/stoatchat" "tarball"
|
||||||
|
|
||||||
|
msg_info "Rebuilding Backend (Patience)"
|
||||||
|
cd /opt/stoatchat
|
||||||
|
$STD cargo build --release --bins -j 2
|
||||||
|
msg_ok "Rebuilt Backend"
|
||||||
|
|
||||||
|
msg_info "Updating Web Frontend"
|
||||||
|
FORWEB_VERSION=$(get_latest_github_release "stoatchat/for-web")
|
||||||
|
$STD git -C /opt/stoatchat-web fetch --tags
|
||||||
|
$STD git -C /opt/stoatchat-web checkout "$FORWEB_VERSION"
|
||||||
|
$STD git -C /opt/stoatchat-web submodule update --init --recursive
|
||||||
|
cd /opt/stoatchat-web
|
||||||
|
$STD pnpm install --frozen-lockfile
|
||||||
|
$STD pnpm --filter stoat.js build
|
||||||
|
$STD pnpm --filter solid-livekit-components build
|
||||||
|
$STD pnpm --filter "@lingui-solid/babel-plugin-lingui-macro" build
|
||||||
|
$STD pnpm --filter "@lingui-solid/babel-plugin-extract-messages" build
|
||||||
|
$STD pnpm --filter client exec lingui compile --typescript
|
||||||
|
$STD pnpm --filter client exec node scripts/copyAssets.mjs
|
||||||
|
$STD pnpm --filter client exec panda codegen
|
||||||
|
$STD pnpm --filter client exec vite build
|
||||||
|
msg_ok "Updated Web Frontend"
|
||||||
|
|
||||||
|
msg_info "Restoring Configuration"
|
||||||
|
cp /opt/stoatchat_revolt.toml.bak /Revolt.toml
|
||||||
|
rm -f /opt/stoatchat_revolt.toml.bak
|
||||||
|
msg_ok "Restored Configuration"
|
||||||
|
|
||||||
|
msg_info "Starting Services"
|
||||||
|
systemctl start stoatchat-api stoatchat-events stoatchat-autumn stoatchat-january stoatchat-crond
|
||||||
|
msg_ok "Started Services"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
||||||
72
ct/xyops.sh
Normal file
72
ct/xyops.sh
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/build.func)
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/pixlcore/xyops
|
||||||
|
|
||||||
|
APP="xyOps"
|
||||||
|
var_tags="${var_tags:-scheduler;automation;monitoring}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-2048}"
|
||||||
|
var_disk="${var_disk:-8}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/xyops ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "xyops" "pixlcore/xyops"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop xyops
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
msg_info "Backing up Data"
|
||||||
|
cp -r /opt/xyops/data /opt/xyops_data_backup
|
||||||
|
cp -r /opt/xyops/conf /opt/xyops_conf_backup
|
||||||
|
msg_ok "Backed up Data"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "xyops" "pixlcore/xyops" "tarball"
|
||||||
|
|
||||||
|
msg_info "Rebuilding Application"
|
||||||
|
cd /opt/xyops
|
||||||
|
$STD npm install
|
||||||
|
$STD node bin/build.js dist
|
||||||
|
chmod 644 /opt/xyops/node_modules/useragent-ng/lib/regexps.js
|
||||||
|
msg_ok "Rebuilt Application"
|
||||||
|
|
||||||
|
msg_info "Restoring Data"
|
||||||
|
cp -r /opt/xyops_data_backup/. /opt/xyops/data
|
||||||
|
cp -r /opt/xyops_conf_backup/. /opt/xyops/conf
|
||||||
|
rm -rf /opt/xyops_data_backup /opt/xyops_conf_backup
|
||||||
|
msg_ok "Restored Data"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start xyops
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5522${CL}"
|
||||||
@@ -207,7 +207,14 @@ EOF
|
|||||||
msg_info "Building HyperDX"
|
msg_info "Building HyperDX"
|
||||||
$STD yarn install
|
$STD yarn install
|
||||||
$STD yarn workspace @hyperdx/common-utils run build
|
$STD yarn workspace @hyperdx/common-utils run build
|
||||||
$STD yarn workspace @hyperdx/api run build
|
rm -rf /opt/clickstack/packages/api/build
|
||||||
|
yarn workspace @hyperdx/api exec tsc >>"$(get_active_logfile)" 2>&1 || true
|
||||||
|
$STD yarn workspace @hyperdx/api exec tsc-alias
|
||||||
|
cp -r /opt/clickstack/packages/api/src/opamp/proto /opt/clickstack/packages/api/build/opamp/ 2>/dev/null || true
|
||||||
|
[[ -f /opt/clickstack/packages/api/build/index.js ]] || {
|
||||||
|
msg_error "HyperDX API build failed: build/index.js not found"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
$STD yarn workspace @hyperdx/app run build
|
$STD yarn workspace @hyperdx/app run build
|
||||||
msg_ok "Built HyperDX"
|
msg_ok "Built HyperDX"
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ DATA_DIR=/opt/hoodik_data
|
|||||||
HTTP_PORT=5443
|
HTTP_PORT=5443
|
||||||
HTTP_ADDRESS=0.0.0.0
|
HTTP_ADDRESS=0.0.0.0
|
||||||
JWT_SECRET=${JWT_SECRET}
|
JWT_SECRET=${JWT_SECRET}
|
||||||
APP_URL=http://127.0.0.1:5443
|
APP_URL=http://${LOCAL_IP}:5443
|
||||||
SSL_DISABLED=true
|
SSL_DISABLED=true
|
||||||
|
COOKIE_SECURE=false
|
||||||
|
COOKIE_HTTP_ONLY=false
|
||||||
MAILER_TYPE=none
|
MAILER_TYPE=none
|
||||||
RUST_LOG=hoodik=info,error=info
|
RUST_LOG=hoodik=info,error=info
|
||||||
EOF
|
EOF
|
||||||
@@ -41,14 +43,14 @@ Type=simple
|
|||||||
User=root
|
User=root
|
||||||
WorkingDirectory=/opt/hoodik_data
|
WorkingDirectory=/opt/hoodik_data
|
||||||
EnvironmentFile=/opt/hoodik/.env
|
EnvironmentFile=/opt/hoodik/.env
|
||||||
ExecStart=/opt/hoodik
|
ExecStart=/opt/hoodik/hoodik
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
systemctl enable -q --now hoodik.service
|
systemctl enable -q --now hoodik
|
||||||
msg_ok "Created Service"
|
msg_ok "Created Service"
|
||||||
|
|
||||||
motd_ssh
|
motd_ssh
|
||||||
|
|||||||
@@ -14,36 +14,28 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y \
|
$STD apt install -y build-essential
|
||||||
build-essential
|
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
PG_VERSION="17" PG_MODULES="pgvector" setup_postgresql
|
PG_VERSION="17" PG_MODULES="pgvector" setup_postgresql
|
||||||
|
|
||||||
msg_info "Installing pg_search from ParadeDB"
|
|
||||||
ARCH=$(dpkg --print-architecture)
|
|
||||||
CODENAME=$(. /etc/os-release && echo "${VERSION_CODENAME:-bookworm}")
|
CODENAME=$(. /etc/os-release && echo "${VERSION_CODENAME:-bookworm}")
|
||||||
PDB_VERSION=$(curl -fsSL "https://api.github.com/repos/paradedb/paradedb/releases/latest" | grep -oP '"tag_name":\s*"\K[^"]+')
|
fetch_and_deploy_gh_release "paradedb" "paradedb/paradedb" "binary" "latest" "" "postgresql-17-pg-search_*-1PARADEDB-${CODENAME}_$(dpkg --print-architecture).deb"
|
||||||
PDB_VERSION_NUM="${PDB_VERSION#v}"
|
|
||||||
DEB_NAME="postgresql-17-pg-search_${PDB_VERSION_NUM}-1PARADEDB-${CODENAME}_${ARCH}.deb"
|
msg_info "Configuring pg_search preload library"
|
||||||
DEB_URL="https://github.com/paradedb/paradedb/releases/download/${PDB_VERSION}/${DEB_NAME}"
|
if ! grep -q "shared_preload_libraries.*pg_search" /etc/postgresql/17/main/postgresql.conf; then
|
||||||
curl -fsSL -o "/tmp/${DEB_NAME}" "$DEB_URL"
|
echo "shared_preload_libraries = 'pg_search'" >>/etc/postgresql/17/main/postgresql.conf
|
||||||
dpkg -i "/tmp/${DEB_NAME}" >/dev/null 2>&1 || $STD apt install -f -y
|
fi
|
||||||
rm -f "/tmp/${DEB_NAME}"
|
systemctl restart postgresql
|
||||||
msg_ok "Installed pg_search from ParadeDB"
|
msg_ok "Configured pg_search preload library"
|
||||||
|
|
||||||
PG_DB_NAME="lobehub" PG_DB_USER="lobehub" PG_DB_EXTENSIONS="vector,pg_search" setup_postgresql_db
|
PG_DB_NAME="lobehub" PG_DB_USER="lobehub" PG_DB_EXTENSIONS="vector,pg_search" setup_postgresql_db
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs
|
||||||
|
|
||||||
msg_info "Installing pnpm"
|
|
||||||
$STD npm install -g pnpm
|
|
||||||
msg_ok "Installed pnpm"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "lobehub" "lobehub/lobehub" "tarball"
|
fetch_and_deploy_gh_release "lobehub" "lobehub/lobehub" "tarball"
|
||||||
|
|
||||||
msg_info "Building Application"
|
msg_info "Building Application"
|
||||||
cd /opt/lobehub
|
cd /opt/lobehub
|
||||||
export NODE_OPTIONS="--max-old-space-size=8192"
|
|
||||||
export DATABASE_URL="postgres://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME}"
|
export DATABASE_URL="postgres://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME}"
|
||||||
export DATABASE_DRIVER="node"
|
export DATABASE_DRIVER="node"
|
||||||
export KEY_VAULTS_SECRET="$(openssl rand -base64 32)"
|
export KEY_VAULTS_SECRET="$(openssl rand -base64 32)"
|
||||||
@@ -51,7 +43,6 @@ export AUTH_SECRET="$(openssl rand -base64 32)"
|
|||||||
export APP_URL="http://localhost:3210"
|
export APP_URL="http://localhost:3210"
|
||||||
$STD pnpm install
|
$STD pnpm install
|
||||||
$STD pnpm run build:docker
|
$STD pnpm run build:docker
|
||||||
unset NODE_OPTIONS
|
|
||||||
msg_ok "Built Application"
|
msg_ok "Built Application"
|
||||||
|
|
||||||
msg_info "Configuring Application"
|
msg_info "Configuring Application"
|
||||||
|
|||||||
@@ -26,13 +26,8 @@ fetch_and_deploy_gh_release "puter" "HeyPuter/puter" "tarball"
|
|||||||
|
|
||||||
msg_info "Building Application"
|
msg_info "Building Application"
|
||||||
cd /opt/puter
|
cd /opt/puter
|
||||||
node -e "const f=require('fs'),p=JSON.parse(f.readFileSync('package.json'));p.overrides={'better-sqlite3':'>=12.0.0'};f.writeFileSync('package.json',JSON.stringify(p,null,2))"
|
$STD npm ci
|
||||||
rm -f package-lock.json
|
|
||||||
$STD npm install
|
|
||||||
cd /opt/puter/src/gui
|
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
cd /opt/puter
|
|
||||||
cp -r src/gui/dist dist
|
|
||||||
msg_ok "Built Application"
|
msg_ok "Built Application"
|
||||||
|
|
||||||
msg_info "Creating Directories"
|
msg_info "Creating Directories"
|
||||||
@@ -43,10 +38,10 @@ msg_info "Configuring Application"
|
|||||||
cat <<EOF >/etc/puter/config.json
|
cat <<EOF >/etc/puter/config.json
|
||||||
{
|
{
|
||||||
"config_name": "proxmox",
|
"config_name": "proxmox",
|
||||||
"domain": "${LOCAL_IP}",
|
"domain": "${LOCAL_IP}.nip.io",
|
||||||
"protocol": "http",
|
"protocol": "http",
|
||||||
"http_port": 4100,
|
"http_port": 4100,
|
||||||
"experimental_no_subdomain": true,
|
"allow_nipio_domains": true,
|
||||||
"services": {
|
"services": {
|
||||||
"database": {
|
"database": {
|
||||||
"engine": "sqlite",
|
"engine": "sqlite",
|
||||||
@@ -67,8 +62,8 @@ After=network.target
|
|||||||
Type=simple
|
Type=simple
|
||||||
User=root
|
User=root
|
||||||
WorkingDirectory=/opt/puter
|
WorkingDirectory=/opt/puter
|
||||||
Environment=CONFIG_PATH=/etc/puter
|
Environment=PUTER_CONFIG_PATH=/etc/puter/config.json
|
||||||
ExecStart=/usr/bin/npm start
|
ExecStart=/usr/bin/node --enable-source-maps -r /opt/puter/dist/src/backend/telemetry.js /opt/puter/dist/src/backend/index.js
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
|
|
||||||
|
|||||||
242
install/stoatchat-install.sh
Normal file
242
install/stoatchat-install.sh
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/stoatchat/stoatchat
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt install -y \
|
||||||
|
pkg-config \
|
||||||
|
libssl-dev \
|
||||||
|
build-essential \
|
||||||
|
git \
|
||||||
|
redis-server \
|
||||||
|
rabbitmq-server \
|
||||||
|
nginx
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
setup_mongodb
|
||||||
|
|
||||||
|
msg_info "Configuring RabbitMQ"
|
||||||
|
systemctl enable -q --now rabbitmq-server
|
||||||
|
until rabbitmqctl status &>/dev/null; do sleep 1; done
|
||||||
|
$STD rabbitmqctl add_user rabbituser rabbitpass
|
||||||
|
$STD rabbitmqctl set_permissions -p / rabbituser ".*" ".*" ".*"
|
||||||
|
msg_ok "Configured RabbitMQ"
|
||||||
|
|
||||||
|
setup_rust
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "stoatchat" "stoatchat/stoatchat" "tarball"
|
||||||
|
|
||||||
|
msg_info "Building Backend (Patience)"
|
||||||
|
cd /opt/stoatchat
|
||||||
|
$STD cargo build --release --bins -j 2
|
||||||
|
msg_ok "Built Backend"
|
||||||
|
|
||||||
|
NODE_VERSION="22" setup_nodejs
|
||||||
|
|
||||||
|
msg_info "Installing pnpm"
|
||||||
|
$STD npm install -g pnpm@10.28.1
|
||||||
|
msg_ok "Installed pnpm"
|
||||||
|
|
||||||
|
msg_info "Cloning Web Frontend"
|
||||||
|
FORWEB_VERSION=$(get_latest_github_release "stoatchat/for-web")
|
||||||
|
$STD git clone --recursive "https://github.com/stoatchat/for-web" /opt/stoatchat-web
|
||||||
|
$STD git -C /opt/stoatchat-web checkout "$FORWEB_VERSION"
|
||||||
|
$STD git -C /opt/stoatchat-web submodule update --init --recursive
|
||||||
|
msg_ok "Cloned Web Frontend"
|
||||||
|
|
||||||
|
msg_info "Building Web Frontend"
|
||||||
|
cd /opt/stoatchat-web
|
||||||
|
$STD pnpm install --frozen-lockfile
|
||||||
|
$STD pnpm --filter stoat.js build
|
||||||
|
$STD pnpm --filter solid-livekit-components build
|
||||||
|
$STD pnpm --filter "@lingui-solid/babel-plugin-lingui-macro" build
|
||||||
|
$STD pnpm --filter "@lingui-solid/babel-plugin-extract-messages" build
|
||||||
|
$STD pnpm --filter client exec lingui compile --typescript
|
||||||
|
$STD pnpm --filter client exec node scripts/copyAssets.mjs
|
||||||
|
$STD pnpm --filter client exec panda codegen
|
||||||
|
VITE_API_URL="http://${LOCAL_IP}/api" \
|
||||||
|
VITE_WS_URL="ws://${LOCAL_IP}/ws" \
|
||||||
|
VITE_MEDIA_URL="http://${LOCAL_IP}/autumn" \
|
||||||
|
VITE_PROXY_URL="http://${LOCAL_IP}/january" \
|
||||||
|
$STD pnpm --filter client exec vite build
|
||||||
|
msg_ok "Built Web Frontend"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "minio" "minio/minio" "singlefile" "latest" "/opt/stoatchat" "minio_linux_amd64"
|
||||||
|
mv /opt/stoatchat/minio_linux_amd64 /usr/local/bin/minio
|
||||||
|
chmod +x /usr/local/bin/minio
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "mc" "minio/mc" "singlefile" "latest" "/opt/stoatchat" "mc_linux_amd64"
|
||||||
|
mv /opt/stoatchat/mc_linux_amd64 /usr/local/bin/mc
|
||||||
|
chmod +x /usr/local/bin/mc
|
||||||
|
|
||||||
|
msg_info "Configuring MinIO"
|
||||||
|
mkdir -p /opt/stoatchat/data/minio
|
||||||
|
cat <<EOF >/etc/systemd/system/stoatchat-minio.service
|
||||||
|
[Unit]
|
||||||
|
Description=Stoatchat MinIO Object Storage
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
Environment=MINIO_ROOT_USER=minioautumn
|
||||||
|
Environment=MINIO_ROOT_PASSWORD=minioautumn
|
||||||
|
ExecStart=/usr/local/bin/minio server /opt/stoatchat/data/minio --console-address :9001
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now stoatchat-minio
|
||||||
|
msg_ok "Configured MinIO"
|
||||||
|
|
||||||
|
msg_info "Creating MinIO Bucket"
|
||||||
|
until mc alias set local http://127.0.0.1:9000 minioautumn minioautumn &>/dev/null; do sleep 1; done
|
||||||
|
$STD mc mb local/revolt-uploads
|
||||||
|
msg_ok "Created MinIO Bucket"
|
||||||
|
|
||||||
|
FILES_ENCRYPTION_KEY=$(openssl rand -base64 32)
|
||||||
|
|
||||||
|
msg_info "Creating Configuration"
|
||||||
|
cat <<EOF >/Revolt.toml
|
||||||
|
[database]
|
||||||
|
mongodb = "mongodb://127.0.0.1:27017"
|
||||||
|
redis = "redis://127.0.0.1:6379/"
|
||||||
|
|
||||||
|
[hosts]
|
||||||
|
app = "http://${LOCAL_IP}"
|
||||||
|
api = "http://${LOCAL_IP}/api"
|
||||||
|
events = "ws://${LOCAL_IP}/ws"
|
||||||
|
autumn = "http://${LOCAL_IP}/autumn"
|
||||||
|
january = "http://${LOCAL_IP}/january"
|
||||||
|
|
||||||
|
[rabbit]
|
||||||
|
host = "127.0.0.1"
|
||||||
|
port = 5672
|
||||||
|
username = "rabbituser"
|
||||||
|
password = "rabbitpass"
|
||||||
|
|
||||||
|
[files]
|
||||||
|
encryption_key = "${FILES_ENCRYPTION_KEY}"
|
||||||
|
|
||||||
|
[files.s3]
|
||||||
|
endpoint = "http://127.0.0.1:9000"
|
||||||
|
path_style_buckets = true
|
||||||
|
region = "minio"
|
||||||
|
access_key_id = "minioautumn"
|
||||||
|
secret_access_key = "minioautumn"
|
||||||
|
default_bucket = "revolt-uploads"
|
||||||
|
|
||||||
|
[api.registration]
|
||||||
|
invite_only = false
|
||||||
|
EOF
|
||||||
|
ln -sf /Revolt.toml /opt/stoatchat/Revolt.toml
|
||||||
|
msg_ok "Created Configuration"
|
||||||
|
|
||||||
|
msg_info "Configuring Nginx"
|
||||||
|
cat <<EOF >/etc/nginx/sites-available/stoatchat
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
client_max_body_size 20M;
|
||||||
|
|
||||||
|
location /api {
|
||||||
|
proxy_pass http://127.0.0.1:14702;
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /ws {
|
||||||
|
proxy_pass http://127.0.0.1:14703;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade \$http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /autumn {
|
||||||
|
proxy_pass http://127.0.0.1:14704;
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /january {
|
||||||
|
proxy_pass http://127.0.0.1:14705;
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /opt/stoatchat-web/packages/client/dist;
|
||||||
|
try_files \$uri \$uri/ /index.html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
ln -sf /etc/nginx/sites-available/stoatchat /etc/nginx/sites-enabled/stoatchat
|
||||||
|
rm -f /etc/nginx/sites-enabled/default
|
||||||
|
systemctl enable -q --now nginx
|
||||||
|
msg_ok "Configured Nginx"
|
||||||
|
|
||||||
|
msg_info "Creating Backend Services"
|
||||||
|
for SVC in api events autumn january crond; do
|
||||||
|
case $SVC in
|
||||||
|
api)
|
||||||
|
PORT=14702
|
||||||
|
BIN=delta
|
||||||
|
;;
|
||||||
|
events)
|
||||||
|
PORT=14703
|
||||||
|
BIN=bonfire
|
||||||
|
;;
|
||||||
|
autumn)
|
||||||
|
PORT=14704
|
||||||
|
BIN=autumn
|
||||||
|
;;
|
||||||
|
january)
|
||||||
|
PORT=14705
|
||||||
|
BIN=january
|
||||||
|
;;
|
||||||
|
crond)
|
||||||
|
PORT=0
|
||||||
|
BIN=crond
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
cat <<EOF >/etc/systemd/system/stoatchat-${SVC}.service
|
||||||
|
[Unit]
|
||||||
|
Description=Stoatchat ${SVC} service
|
||||||
|
After=network.target stoatchat-minio.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/stoatchat
|
||||||
|
ExecStart=/opt/stoatchat/target/release/${BIN}
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now "stoatchat-${SVC}"
|
||||||
|
done
|
||||||
|
msg_ok "Created Backend Services"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
71
install/xyops-install.sh
Normal file
71
install/xyops-install.sh
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/pixlcore/xyops
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt install -y \
|
||||||
|
build-essential \
|
||||||
|
python3 \
|
||||||
|
python3-setuptools \
|
||||||
|
pkg-config \
|
||||||
|
libssl-dev \
|
||||||
|
zlib1g-dev
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
NODE_VERSION="22" setup_nodejs
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "xyops" "pixlcore/xyops" "tarball"
|
||||||
|
|
||||||
|
msg_info "Building Application"
|
||||||
|
cd /opt/xyops
|
||||||
|
$STD npm install
|
||||||
|
$STD node bin/build.js dist
|
||||||
|
chmod 644 /opt/xyops/node_modules/useragent-ng/lib/regexps.js
|
||||||
|
msg_ok "Built Application"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "xysat" "pixlcore/xysat" "tarball" "latest" "/opt/xyops/satellite"
|
||||||
|
|
||||||
|
msg_info "Building xySat Satellite"
|
||||||
|
cd /opt/xyops/satellite
|
||||||
|
$STD npm install
|
||||||
|
msg_ok "Built xySat Satellite"
|
||||||
|
|
||||||
|
msg_info "Setting up Directories"
|
||||||
|
mkdir -p /opt/xyops/data /opt/xyops/logs /opt/xyops/temp /opt/xyops/conf
|
||||||
|
msg_ok "Set up Directories"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/xyops.service
|
||||||
|
[Unit]
|
||||||
|
Description=xyOps Task Scheduler and Server Monitor
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/xyops
|
||||||
|
Environment=XYOPS_foreground=1
|
||||||
|
ExecStart=/usr/bin/node /opt/xyops/lib/main.js
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now xyops
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -41,4 +41,4 @@
|
|||||||
"type": "warning"
|
"type": "warning"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
"script": "ct/hoodik.sh",
|
"script": "ct/hoodik.sh",
|
||||||
"config_path": "/opt/hoodik/.env",
|
"config_path": "/opt/hoodik/.env",
|
||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 4,
|
"cpu": 1,
|
||||||
"ram": 4096,
|
"ram": 1024,
|
||||||
"hdd": 20,
|
"hdd": 5,
|
||||||
"os": "Debian",
|
"os": "Debian",
|
||||||
"version": "13"
|
"version": "13"
|
||||||
}
|
}
|
||||||
@@ -36,21 +36,9 @@
|
|||||||
"text": "First visit will prompt you to create an admin account",
|
"text": "First visit will prompt you to create an admin account",
|
||||||
"type": "info"
|
"type": "info"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"text": "Installation builds Rust backend and Vue frontend from source - takes 15-20 minutes",
|
|
||||||
"type": "warning"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Requires 4GB RAM and 20GB disk for build process",
|
|
||||||
"type": "warning"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"text": "Data is stored in /opt/hoodik_data",
|
"text": "Data is stored in /opt/hoodik_data",
|
||||||
"type": "info"
|
"type": "info"
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "SSL is disabled by default - use a reverse proxy for HTTPS",
|
|
||||||
"type": "warning"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -37,4 +37,4 @@
|
|||||||
"type": "info"
|
"type": "info"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -45,4 +45,4 @@
|
|||||||
"type": "info"
|
"type": "info"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -33,8 +33,16 @@
|
|||||||
},
|
},
|
||||||
"notes": [
|
"notes": [
|
||||||
{
|
{
|
||||||
"text": "Configuration is stored in /etc/puter and data in /var/puter.",
|
"text": "Access via http://<IP>.nip.io:4100 (not the raw IP). nip.io is required for Puter's subdomain routing.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Camera, microphone, and other media capture features require HTTPS (a secure context). They will not work on the default HTTP setup.",
|
||||||
|
"type": "warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Configuration is stored in /etc/puter/config.json and data in /var/puter.",
|
||||||
"type": "info"
|
"type": "info"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
52
json/stoatchat.json
Normal file
52
json/stoatchat.json
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"name": "Stoatchat",
|
||||||
|
"slug": "stoatchat",
|
||||||
|
"categories": [
|
||||||
|
22
|
||||||
|
],
|
||||||
|
"date_created": "2026-05-08",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": 80,
|
||||||
|
"documentation": "https://github.com/stoatchat/self-hosted",
|
||||||
|
"website": "https://stoat.chat",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/stoatchat.webp",
|
||||||
|
"description": "A self-hostable open-source chat platform and community server. Stoatchat is a fork of Revolt, featuring real-time messaging, voice channels, file sharing, and a full-featured web client. Built with Rust (backend) and SolidJS (frontend).",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/stoatchat.sh",
|
||||||
|
"config_path": "/Revolt.toml",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 4,
|
||||||
|
"ram": 10240,
|
||||||
|
"hdd": 30,
|
||||||
|
"os": "Debian",
|
||||||
|
"version": "13"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "Initial setup takes 30-60 minutes due to Rust compilation and frontend build. Do not interrupt the process.",
|
||||||
|
"type": "warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "The first account registered becomes the instance administrator. Registration is open by default; set invite_only = true in /Revolt.toml to restrict it.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Voice and video calls require additional LiveKit setup. See https://github.com/stoatchat/self-hosted for details.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "The files encryption key in /Revolt.toml is generated during installation. Back it up — losing it will make all uploaded files unreadable.",
|
||||||
|
"type": "warning"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
48
json/xyops.json
Normal file
48
json/xyops.json
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"name": "xyOps",
|
||||||
|
"slug": "xyops",
|
||||||
|
"categories": [
|
||||||
|
19
|
||||||
|
],
|
||||||
|
"date_created": "2026-05-08",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": 5522,
|
||||||
|
"documentation": "https://github.com/pixlcore/xyops/tree/main/docs",
|
||||||
|
"website": "https://github.com/pixlcore/xyops",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/xyops.webp",
|
||||||
|
"description": "A complete task scheduler and server monitoring system with workflow automation, multi-server management, real-time monitoring, and a built-in satellite agent (xySat) for running jobs on remote servers.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/xyops.sh",
|
||||||
|
"config_path": "/opt/xyops/conf/config.json",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 2,
|
||||||
|
"ram": 2048,
|
||||||
|
"hdd": 8,
|
||||||
|
"os": "Debian",
|
||||||
|
"version": "13"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": "admin",
|
||||||
|
"password": "admin"
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "Change the default admin password immediately after first login.",
|
||||||
|
"type": "warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "A local xySat satellite is started automatically alongside the conductor, allowing jobs to run on this server right away.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "The WebSocket port 5523 is used for secure wss:// connections. Port 5522 serves the web interface and ws:// connections.",
|
||||||
|
"type": "info"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -14,9 +14,18 @@ declare -A MSG_INFO_SHOWN
|
|||||||
[[ -n "${_CORE_FUNC_LOADED:-}" ]] && return
|
[[ -n "${_CORE_FUNC_LOADED:-}" ]] && return
|
||||||
_CORE_FUNC_LOADED=1
|
_CORE_FUNC_LOADED=1
|
||||||
|
|
||||||
|
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main}"
|
||||||
|
|
||||||
|
load_api_functions() {
|
||||||
|
if ! declare -f post_to_api_vm >/dev/null 2>&1; then
|
||||||
|
source /dev/stdin <<<$(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/api.func")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
load_functions() {
|
load_functions() {
|
||||||
[[ -n "${__FUNCTIONS_LOADED:-}" ]] && return
|
[[ -n "${__FUNCTIONS_LOADED:-}" ]] && return
|
||||||
__FUNCTIONS_LOADED=1
|
__FUNCTIONS_LOADED=1
|
||||||
|
load_api_functions
|
||||||
color
|
color
|
||||||
formatting
|
formatting
|
||||||
icons
|
icons
|
||||||
@@ -31,6 +40,12 @@ load_functions() {
|
|||||||
arch_check
|
arch_check
|
||||||
}
|
}
|
||||||
|
|
||||||
|
load_cloud_init_functions() {
|
||||||
|
if ! declare -f setup_cloud_init >/dev/null 2>&1; then
|
||||||
|
source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/cloud-init.func") 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Function to download & save header files
|
# Function to download & save header files
|
||||||
get_header() {
|
get_header() {
|
||||||
local app_name=$(echo "${APP,,}" | tr ' ' '-')
|
local app_name=$(echo "${APP,,}" | tr ' ' '-')
|
||||||
@@ -98,6 +113,7 @@ icons() {
|
|||||||
DNSOK="✔️ "
|
DNSOK="✔️ "
|
||||||
DNSFAIL="${TAB}✖️${TAB}"
|
DNSFAIL="${TAB}✖️${TAB}"
|
||||||
INFO="${TAB}💡${TAB}${CL}"
|
INFO="${TAB}💡${TAB}${CL}"
|
||||||
|
CLOUD="${TAB}☁️${TAB}${CL}"
|
||||||
OS="${TAB}🖥️${TAB}${CL}"
|
OS="${TAB}🖥️${TAB}${CL}"
|
||||||
OSVERSION="${TAB}🌟${TAB}${CL}"
|
OSVERSION="${TAB}🌟${TAB}${CL}"
|
||||||
CONTAINERTYPE="${TAB}📦${TAB}${CL}"
|
CONTAINERTYPE="${TAB}📦${TAB}${CL}"
|
||||||
@@ -495,6 +511,20 @@ msg_debug() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error_handler() {
|
||||||
|
local exit_code="$?"
|
||||||
|
local line_number="${1:-unknown}"
|
||||||
|
local command="${2:-unknown}"
|
||||||
|
|
||||||
|
if declare -f post_update_to_api >/dev/null 2>&1; then
|
||||||
|
post_update_to_api "failed" "$exit_code"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local error_message="${RD}[ERROR]${CL} 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
|
||||||
|
}
|
||||||
|
|
||||||
# Displays error message and immediately terminates script
|
# Displays error message and immediately terminates script
|
||||||
fatal() {
|
fatal() {
|
||||||
msg_error "$1"
|
msg_error "$1"
|
||||||
@@ -530,9 +560,13 @@ cleanup_vmid() {
|
|||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
local exit_code=$?
|
local exit_code=$?
|
||||||
|
stop_spinner
|
||||||
if [[ "$(dirs -p | wc -l)" -gt 1 ]]; then
|
if [[ "$(dirs -p | wc -l)" -gt 1 ]]; then
|
||||||
popd >/dev/null || true
|
popd >/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
if [[ -n "${TEMP_DIR:-}" && -d "$TEMP_DIR" ]]; then
|
||||||
|
rm -rf "$TEMP_DIR"
|
||||||
|
fi
|
||||||
# Report final telemetry status if post_to_api_vm was called but no update was sent
|
# Report final telemetry status if post_to_api_vm was called but no update was sent
|
||||||
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
|
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
|
||||||
if declare -f post_update_to_api >/dev/null 2>&1; then
|
if declare -f post_update_to_api >/dev/null 2>&1; then
|
||||||
@@ -557,13 +591,32 @@ check_root() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pve_check() {
|
pve_check() {
|
||||||
if ! pveversion | grep -Eq "pve-manager/(8\.[1-4]|9\.[0-1])(\.[0-9]+)*"; then
|
local pve_ver
|
||||||
msg_error "This version of Proxmox Virtual Environment is not supported"
|
pve_ver="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
||||||
echo -e "Requires Proxmox Virtual Environment Version 8.1 - 8.4 or 9.0 - 9.1."
|
|
||||||
echo -e "Exiting..."
|
if [[ "$pve_ver" =~ ^8\.([0-9]+) ]]; then
|
||||||
sleep 2
|
local minor="${BASH_REMATCH[1]}"
|
||||||
exit
|
if ((minor < 0 || minor > 9)); then
|
||||||
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
|
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||||
|
exit 105
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$pve_ver" =~ ^9\.([0-9]+) ]]; then
|
||||||
|
local minor="${BASH_REMATCH[1]}"
|
||||||
|
if ((minor < 0 || minor > 1)); then
|
||||||
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
|
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||||
|
exit 105
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
|
msg_error "Supported versions: Proxmox VE 8.0 – 8.9 or 9.0 – 9.1"
|
||||||
|
exit 105
|
||||||
}
|
}
|
||||||
|
|
||||||
arch_check() {
|
arch_check() {
|
||||||
@@ -576,12 +629,460 @@ arch_check() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssh_check() {
|
||||||
|
if command -v pveversion >/dev/null 2>&1 && [ -n "${SSH_CLIENT:-}" ]; 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
|
||||||
|
:
|
||||||
|
else
|
||||||
|
clear
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
exit_script() {
|
exit_script() {
|
||||||
clear
|
clear
|
||||||
echo -e "\n${CROSS}${RD}User exited script${CL}\n"
|
echo -e "\n${CROSS}${RD}User exited script${CL}\n"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sanitize_vm_hostname() {
|
||||||
|
local hostname="${1,,}"
|
||||||
|
hostname=$(echo "$hostname" | tr -cs 'a-z0-9-' '-' | sed 's/^-//;s/-$//')
|
||||||
|
echo "${hostname:0:63}"
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_confirm_new_vm() {
|
||||||
|
local title="$1"
|
||||||
|
local message="$2"
|
||||||
|
local height="${3:-10}"
|
||||||
|
local width="${4:-58}"
|
||||||
|
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "$title" --yesno "$message" "$height" "$width"
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_choose_settings_mode() {
|
||||||
|
local message="${1:-Use Default Settings?}"
|
||||||
|
local height="${2:-10}"
|
||||||
|
local width="${3:-58}"
|
||||||
|
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "$message" --no-button Advanced "$height" "$width"
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_confirm_advanced_settings() {
|
||||||
|
local message="$1"
|
||||||
|
local height="${2:-10}"
|
||||||
|
local width="${3:-58}"
|
||||||
|
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "$message" --no-button Do-Over "$height" "$width"
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_vmid() {
|
||||||
|
local default_vmid="${1:-$(get_valid_nextid)}"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 "$default_vmid" --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
|
if [ -z "$VMID" ]; then
|
||||||
|
VMID=$(get_valid_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 "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_apply_machine_type() {
|
||||||
|
local machine_type="${1:-i440fx}"
|
||||||
|
|
||||||
|
if [ "$machine_type" = "q35" ]; then
|
||||||
|
MACHINE_TYPE="q35"
|
||||||
|
FORMAT=""
|
||||||
|
MACHINE=" -machine q35"
|
||||||
|
else
|
||||||
|
MACHINE_TYPE="i440fx"
|
||||||
|
FORMAT=",efitype=4m"
|
||||||
|
MACHINE=""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_machine_type_label() {
|
||||||
|
case "${1:-i440fx}" in
|
||||||
|
q35)
|
||||||
|
echo "Q35 (Modern)"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "i440fx"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_machine_type() {
|
||||||
|
local default_machine="${1:-i440fx}"
|
||||||
|
local i440fx_default="ON"
|
||||||
|
local q35_default="OFF"
|
||||||
|
local machine_choice
|
||||||
|
|
||||||
|
if [ "$default_machine" = "q35" ]; then
|
||||||
|
i440fx_default="OFF"
|
||||||
|
q35_default="ON"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if machine_choice=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
|
||||||
|
"i440fx" "Machine i440fx" "$i440fx_default" \
|
||||||
|
"q35" "Machine q35" "$q35_default" \
|
||||||
|
3>&1 1>&2 2>&3); then
|
||||||
|
vm_apply_machine_type "$machine_choice"
|
||||||
|
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$(vm_machine_type_label "$MACHINE_TYPE")${CL}"
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_cloud_init() {
|
||||||
|
local default_user="${1:-root}"
|
||||||
|
|
||||||
|
USE_CLOUD_INIT="no"
|
||||||
|
load_cloud_init_functions
|
||||||
|
|
||||||
|
if ! declare -f configure_cloud_init_interactive >/dev/null 2>&1; then
|
||||||
|
echo -e "${CLOUD}${BOLD}${DGN}Cloud-Init: ${BGN}unavailable${CL}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
configure_cloud_init_interactive "$default_user" || true
|
||||||
|
USE_CLOUD_INIT="${CLOUDINIT_ENABLE:-no}"
|
||||||
|
echo -e "${CLOUD}${BOLD}${DGN}Cloud-Init: ${BGN}${USE_CLOUD_INIT}${CL}"
|
||||||
|
|
||||||
|
if [ "$USE_CLOUD_INIT" = "yes" ] && declare -f configure_cloudinit_ssh_keys >/dev/null 2>&1; then
|
||||||
|
configure_cloudinit_ssh_keys || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_disk_size() {
|
||||||
|
local default_size="${1:-8G}"
|
||||||
|
local prompt_message="${2:-Set Disk Size in GiB (e.g., 10, 20)}"
|
||||||
|
|
||||||
|
if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "$prompt_message" 8 58 "$default_size" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
|
DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
|
||||||
|
if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
|
||||||
|
DISK_SIZE="${DISK_SIZE}G"
|
||||||
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
|
||||||
|
elif [[ "$DISK_SIZE" =~ ^[0-9]+G$ ]]; then
|
||||||
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
|
||||||
|
else
|
||||||
|
echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_disk_cache() {
|
||||||
|
local default_cache="${1:-none}"
|
||||||
|
local none_default="ON"
|
||||||
|
local write_default="OFF"
|
||||||
|
local cache_choice
|
||||||
|
|
||||||
|
if [ "$default_cache" = "writethrough" ]; then
|
||||||
|
none_default="OFF"
|
||||||
|
write_default="ON"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if cache_choice=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
||||||
|
"0" "None (Default)" "$none_default" \
|
||||||
|
"1" "Write Through" "$write_default" \
|
||||||
|
3>&1 1>&2 2>&3); then
|
||||||
|
if [ "$cache_choice" = "1" ]; then
|
||||||
|
DISK_CACHE="cache=writethrough,"
|
||||||
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}Write Through${CL}"
|
||||||
|
else
|
||||||
|
DISK_CACHE=""
|
||||||
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_hostname() {
|
||||||
|
local default_hostname="${1:-vm}"
|
||||||
|
local adjusted_hostname
|
||||||
|
local input_hostname
|
||||||
|
|
||||||
|
if input_hostname=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 "$default_hostname" --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
|
if [ -z "$input_hostname" ]; then
|
||||||
|
HN="$default_hostname"
|
||||||
|
else
|
||||||
|
adjusted_hostname=$(sanitize_vm_hostname "$input_hostname")
|
||||||
|
HN="${adjusted_hostname:-$default_hostname}"
|
||||||
|
if [ "$HN" != "${input_hostname,,}" ]; then
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "HOSTNAME ADJUSTED" --msgbox "Invalid characters detected. Hostname has been adjusted to:\n\n $HN" 10 58
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_cpu_model() {
|
||||||
|
local default_model="${1:-kvm64}"
|
||||||
|
local kvm_default="ON"
|
||||||
|
local host_default="OFF"
|
||||||
|
local cpu_choice
|
||||||
|
|
||||||
|
if [ "$default_model" = "host" ]; then
|
||||||
|
kvm_default="OFF"
|
||||||
|
host_default="ON"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if cpu_choice=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
||||||
|
"0" "KVM64 (Default)" "$kvm_default" \
|
||||||
|
"1" "Host" "$host_default" \
|
||||||
|
3>&1 1>&2 2>&3); then
|
||||||
|
if [ "$cpu_choice" = "1" ]; then
|
||||||
|
CPU_TYPE=" -cpu host"
|
||||||
|
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
||||||
|
else
|
||||||
|
CPU_TYPE=""
|
||||||
|
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_cpu_cores() {
|
||||||
|
local default_cores="${1:-2}"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 "$default_cores" --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
|
if [ -z "$CORE_COUNT" ]; then
|
||||||
|
CORE_COUNT="$default_cores"
|
||||||
|
fi
|
||||||
|
if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then
|
||||||
|
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "CPU Cores must be a positive integer (e.g., 2)." 8 58
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_ram() {
|
||||||
|
local default_ram="${1:-2048}"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 "$default_ram" --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
|
if [ -z "$RAM_SIZE" ]; then
|
||||||
|
RAM_SIZE="$default_ram"
|
||||||
|
fi
|
||||||
|
if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then
|
||||||
|
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "RAM Size must be a positive integer in MiB (e.g., 2048)." 8 58
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_bridge() {
|
||||||
|
local default_bridge="${1:-vmbr0}"
|
||||||
|
|
||||||
|
if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 "$default_bridge" --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
|
if [ -z "$BRG" ]; then
|
||||||
|
BRG="$default_bridge"
|
||||||
|
fi
|
||||||
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_mac() {
|
||||||
|
local default_mac="${1:-$GEN_MAC}"
|
||||||
|
local input_mac
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
if input_mac=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 "$default_mac" --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
|
if [ -z "$input_mac" ]; then
|
||||||
|
MAC="$default_mac"
|
||||||
|
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [[ "$input_mac" =~ ^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$ ]]; then
|
||||||
|
MAC="$input_mac"
|
||||||
|
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "Invalid MAC address format. Use XX:XX:XX:XX:XX:XX (e.g., AA:BB:CC:DD:EE:FF)." 8 58
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_vlan() {
|
||||||
|
local default_vlan="${1:-}"
|
||||||
|
local input_vlan
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
if input_vlan=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan (leave blank for default)" 8 58 "$default_vlan" --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
|
if [ -z "$input_vlan" ]; then
|
||||||
|
VLAN=""
|
||||||
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [[ "$input_vlan" =~ ^[0-9]+$ ]] && [ "$input_vlan" -ge 1 ] && [ "$input_vlan" -le 4094 ]; then
|
||||||
|
VLAN=",tag=$input_vlan"
|
||||||
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$input_vlan${CL}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "VLAN must be a number between 1 and 4094, or leave blank for default." 8 58
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_mtu() {
|
||||||
|
local default_mtu="${1:-}"
|
||||||
|
local input_mtu
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
if input_mtu=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 "$default_mtu" --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
|
if [ -z "$input_mtu" ]; then
|
||||||
|
MTU=""
|
||||||
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [[ "$input_mtu" =~ ^[0-9]+$ ]] && [ "$input_mtu" -ge 576 ] && [ "$input_mtu" -le 65520 ]; then
|
||||||
|
MTU=",mtu=$input_mtu"
|
||||||
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$input_mtu${CL}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "MTU Size must be a number between 576 and 65520, or leave blank for default." 8 58
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_prompt_start_vm() {
|
||||||
|
local default_start="${1:-yes}"
|
||||||
|
local default_flag=()
|
||||||
|
|
||||||
|
if [ "$default_start" = "no" ]; then
|
||||||
|
default_flag=(--defaultno)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if whiptail --backtitle "Proxmox VE Helper Scripts" "${default_flag[@]}" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58; then
|
||||||
|
START_VM="yes"
|
||||||
|
else
|
||||||
|
START_VM="no"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}${START_VM}${CL}"
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_apply_storage_layout() {
|
||||||
|
local storage_type="$1"
|
||||||
|
|
||||||
|
case $storage_type in
|
||||||
|
nfs | dir | cifs)
|
||||||
|
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=""
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
DISK_EXT=""
|
||||||
|
DISK_REF=""
|
||||||
|
DISK_IMPORT_FORMAT="raw"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_select_storage() {
|
||||||
|
local hostname="${1:-${HN:-vm}}"
|
||||||
|
local storage_menu=()
|
||||||
|
local msg_max_length=0
|
||||||
|
local line tag type free item
|
||||||
|
local offset=2
|
||||||
|
local valid_storage
|
||||||
|
|
||||||
|
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 "
|
||||||
|
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_storage=$(pvesm status -content images | awk 'NR>1')
|
||||||
|
if [ -z "$valid_storage" ]; then
|
||||||
|
msg_error "Unable to detect a valid storage location."
|
||||||
|
exit
|
||||||
|
elif [ $((${#storage_menu[@]} / 3)) -eq 1 ]; then
|
||||||
|
STORAGE=${storage_menu[0]}
|
||||||
|
else
|
||||||
|
if [ -n "${SPINNER_PID:-}" ] && ps -p "$SPINNER_PID" >/dev/null 2>&1; then
|
||||||
|
kill "$SPINNER_PID" >/dev/null 2>&1 || true
|
||||||
|
SPINNER_ACTIVE=0
|
||||||
|
printf "\r\e[2K" >&2
|
||||||
|
fi
|
||||||
|
while [ -z "${STORAGE:+x}" ]; do
|
||||||
|
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
||||||
|
"Which storage pool would you like to use for ${hostname}?\nTo make a selection, use the Spacebar.\n" \
|
||||||
|
16 $(($msg_max_length + 23)) 6 \
|
||||||
|
"${storage_menu[@]}" 3>&1 1>&2 2>&3)
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
|
||||||
|
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
|
||||||
|
|
||||||
|
STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
|
||||||
|
vm_apply_storage_layout "$STORAGE_TYPE"
|
||||||
|
}
|
||||||
|
|
||||||
|
vm_define_disk_references() {
|
||||||
|
local disk_count="${1:-2}"
|
||||||
|
local i disk_name
|
||||||
|
|
||||||
|
for ((i = 0; i < disk_count; i++)); do
|
||||||
|
disk_name="vm-${VMID}-disk-${i}${DISK_EXT:-}"
|
||||||
|
printf -v "DISK${i}" '%s' "$disk_name"
|
||||||
|
printf -v "DISK${i}_REF" '%s' "${STORAGE}:${DISK_REF:-}${disk_name}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
check_hostname_conflict() {
|
check_hostname_conflict() {
|
||||||
local hostname="$1"
|
local hostname="$1"
|
||||||
if qm list | awk '{print $2}' | grep -qx "$hostname"; then
|
if qm list | awk '{print $2}' | grep -qx "$hostname"; then
|
||||||
@@ -591,6 +1092,8 @@ check_hostname_conflict() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set_description() {
|
set_description() {
|
||||||
|
local description_title="${APP:-${NSAPP} VM}"
|
||||||
|
|
||||||
DESCRIPTION=$(
|
DESCRIPTION=$(
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
<div align='center'>
|
<div align='center'>
|
||||||
@@ -598,7 +1101,7 @@ set_description() {
|
|||||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<h2 style='font-size: 24px; margin: 20px 0;'>${NSAPP} VM</h2>
|
<h2 style='font-size: 24px; margin: 20px 0;'>${description_title}</h2>
|
||||||
|
|
||||||
<p style='margin: 16px 0;'>
|
<p style='margin: 16px 0;'>
|
||||||
<a href='https://ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>
|
<a href='https://ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>
|
||||||
|
|||||||
@@ -2,221 +2,51 @@
|
|||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: Agent-Fennec
|
# Author: Agent-Fennec
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
|
||||||
source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
|
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main}"
|
||||||
|
source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/api.func")
|
||||||
|
source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/vm-core.func")
|
||||||
|
source <(curl -fsSL "$COMMUNITY_SCRIPTS_URL/misc/cloud-init.func") || true
|
||||||
|
load_functions
|
||||||
|
|
||||||
function header_info() {
|
APP="AlmaLinux 10 VM"
|
||||||
clear
|
APP_TYPE="vm"
|
||||||
cat <<"EOF"
|
|
||||||
|
|
||||||
█████╗ ██╗ ███╗ ███╗ █████╗ ██╗ ██╗███╗ ██╗██╗ ██╗██╗ ██╗
|
|
||||||
██╔══██╗██║ ████╗ ████║██╔══██╗██║ ██║████╗ ██║██║ ██║╚██╗██╔╝
|
|
||||||
███████║██║ ██╔████╔██║███████║██║ ██║██╔██╗ ██║██║ ██║ ╚███╔╝
|
|
||||||
██╔══██║██║ ██║╚██╔╝██║██╔══██║██║ ██║██║╚██╗██║██║ ██║ ██╔██╗
|
|
||||||
██║ ██║███████╗██║ ╚═╝ ██║██║ ██║███████╗██║██║ ╚████║╚██████╔╝██╔╝ ██╗
|
|
||||||
╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝
|
|
||||||
|
|
||||||
AlmaLinux 10 Installer
|
|
||||||
(Heliotrope Lion)
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "\n Loading..."
|
|
||||||
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
|
|
||||||
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
|
||||||
METHOD=""
|
|
||||||
NSAPP="almalinux10vm"
|
NSAPP="almalinux10vm"
|
||||||
var_os="almalinux"
|
var_os="almalinux"
|
||||||
var_version="10"
|
var_version="10"
|
||||||
|
|
||||||
YW=$(echo "\033[33m")
|
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
|
||||||
BL=$(echo "\033[36m")
|
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
||||||
RD=$(echo "\033[01;31m")
|
METHOD=""
|
||||||
BGN=$(echo "\033[4;92m")
|
|
||||||
GN=$(echo "\033[1;92m")
|
|
||||||
DGN=$(echo "\033[32m")
|
|
||||||
CL=$(echo "\033[m")
|
|
||||||
|
|
||||||
CL=$(echo "\033[m")
|
|
||||||
BOLD=$(echo "\033[1m")
|
|
||||||
BFR="\\r\\033[K"
|
|
||||||
HOLD=" "
|
|
||||||
TAB=" "
|
|
||||||
|
|
||||||
CM="${TAB}✔️${TAB}${CL}"
|
|
||||||
CROSS="${TAB}✖️${TAB}${CL}"
|
|
||||||
INFO="${TAB}💡${TAB}${CL}"
|
|
||||||
OS="${TAB}🖥️${TAB}${CL}"
|
|
||||||
CONTAINERTYPE="${TAB}📦${TAB}${CL}"
|
|
||||||
DISKSIZE="${TAB}💾${TAB}${CL}"
|
|
||||||
CPUCORE="${TAB}🧠${TAB}${CL}"
|
|
||||||
RAMSIZE="${TAB}🛠️${TAB}${CL}"
|
|
||||||
CONTAINERID="${TAB}🆔${TAB}${CL}"
|
|
||||||
HOSTNAME="${TAB}🏠${TAB}${CL}"
|
|
||||||
BRIDGE="${TAB}🌉${TAB}${CL}"
|
|
||||||
GATEWAY="${TAB}🌐${TAB}${CL}"
|
|
||||||
DEFAULT="${TAB}⚙️${TAB}${CL}"
|
|
||||||
MACADDRESS="${TAB}🔗${TAB}${CL}"
|
|
||||||
VLANTAG="${TAB}🏷️${TAB}${CL}"
|
|
||||||
CREATING="${TAB}🚀${TAB}${CL}"
|
|
||||||
ADVANCED="${TAB}🧩${TAB}${CL}"
|
|
||||||
|
|
||||||
THIN="discard=on,ssd=1,"
|
THIN="discard=on,ssd=1,"
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
trap 'post_update_to_api "failed" "130"' SIGINT
|
trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT
|
||||||
trap 'post_update_to_api "failed" "143"' SIGTERM
|
trap 'post_update_to_api "failed" "TERMINATED"' SIGTERM
|
||||||
|
|
||||||
function error_handler() {
|
function error_handler() {
|
||||||
local exit_code="$?"
|
local exit_code="$?"
|
||||||
local line_number="$1"
|
local line_number="$1"
|
||||||
local command="$2"
|
local command="$2"
|
||||||
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${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}"
|
||||||
post_update_to_api "failed" "${exit_code}"
|
post_update_to_api "failed" "${command}"
|
||||||
echo -e "\n$error_message\n"
|
echo -e "\n$error_message\n"
|
||||||
cleanup_vmid
|
cleanup_vmid
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_valid_nextid() {
|
|
||||||
local try_id
|
|
||||||
try_id=$(pvesh get /cluster/nextid)
|
|
||||||
while true; do
|
|
||||||
if [ -f "/etc/pve/qemu-server/${try_id}.conf" ] || [ -f "/etc/pve/lxc/${try_id}.conf" ]; then
|
|
||||||
try_id=$((try_id + 1))
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
if lvs --noheadings -o lv_name | grep -qE "(^|[-_])${try_id}($|[-_])"; then
|
|
||||||
try_id=$((try_id + 1))
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
break
|
|
||||||
done
|
|
||||||
echo "$try_id"
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanup_vmid() {
|
|
||||||
if qm status "$VMID" &>/dev/null; then
|
|
||||||
qm stop "$VMID" &>/dev/null
|
|
||||||
qm destroy "$VMID" &>/dev/null
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanup() {
|
|
||||||
local exit_code=$?
|
|
||||||
popd 2>/dev/null || true
|
|
||||||
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
|
|
||||||
if [[ $exit_code -eq 0 ]]; then
|
|
||||||
post_update_to_api "done" "none" || true
|
|
||||||
else
|
|
||||||
post_update_to_api "failed" "$exit_code" || true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
rm -rf "$TEMP_DIR"
|
|
||||||
rm -f "${WORK_FILE:-}"
|
|
||||||
}
|
|
||||||
|
|
||||||
TEMP_DIR=$(mktemp -d)
|
TEMP_DIR=$(mktemp -d)
|
||||||
pushd "$TEMP_DIR" >/dev/null
|
pushd "$TEMP_DIR" >/dev/null
|
||||||
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "AlmaLinux 10 VM" --yesno "This will create a New AlmaLinux 10 VM. Proceed?" 10 58; then
|
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "AlmaLinux 10 VM" --yesno "This will create a New AlmaLinux 10 VM. Proceed?" 10 58; then
|
||||||
:
|
:
|
||||||
else
|
else
|
||||||
header_info && echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
|
header_info && exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
function msg_info() {
|
|
||||||
local msg="$1"
|
|
||||||
echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function msg_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
|
|
||||||
}
|
|
||||||
|
|
||||||
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
|
|
||||||
# Supported: Proxmox VE 8.0.x – 8.9.x, 9.0 and 9.1
|
|
||||||
pve_check() {
|
|
||||||
local PVE_VER
|
|
||||||
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
|
||||||
|
|
||||||
# Check for Proxmox VE 8.x: allow 8.0–8.9
|
|
||||||
if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then
|
|
||||||
local MINOR="${BASH_REMATCH[1]}"
|
|
||||||
if ((MINOR < 0 || MINOR > 9)); then
|
|
||||||
msg_error "This version of Proxmox VE is not supported."
|
|
||||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for Proxmox VE 9.x: allow 9.0 and 9.1
|
|
||||||
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
|
|
||||||
local MINOR="${BASH_REMATCH[1]}"
|
|
||||||
if ((MINOR < 0 || MINOR > 1)); then
|
|
||||||
msg_error "This version of Proxmox VE is not supported."
|
|
||||||
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# All other unsupported versions
|
|
||||||
msg_error "This version of Proxmox VE is not supported."
|
|
||||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
function arch_check() {
|
|
||||||
if [ "$(dpkg --print-architecture)" != "amd64" ]; then
|
|
||||||
echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n"
|
|
||||||
echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
|
|
||||||
echo -e "Exiting..."
|
|
||||||
sleep 2
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function 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 "\n${CROSS}${RD}User exited script${CL}\n"
|
|
||||||
popd >/dev/null 2>&1 || true
|
|
||||||
rm -rf "${TEMP_DIR:-}"
|
|
||||||
rm -f "${WORK_FILE:-}"
|
|
||||||
exec bash
|
|
||||||
}
|
|
||||||
|
|
||||||
function default_settings() {
|
function default_settings() {
|
||||||
|
configure_cloudinit_ssh_keys || true
|
||||||
VMID=$(get_valid_nextid)
|
VMID=$(get_valid_nextid)
|
||||||
FORMAT=""
|
FORMAT=""
|
||||||
MACHINE=" -machine q35"
|
MACHINE=" -machine q35"
|
||||||
@@ -264,7 +94,7 @@ function advanced_settings() {
|
|||||||
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
|
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -282,10 +112,10 @@ function advanced_settings() {
|
|||||||
MACHINE=" -machine q35"
|
MACHINE=" -machine q35"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "$DISK_SIZE" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "10" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
|
DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
|
||||||
if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
|
if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
|
||||||
DISK_SIZE="${DISK_SIZE}G"
|
DISK_SIZE="${DISK_SIZE}G"
|
||||||
@@ -294,10 +124,10 @@ function advanced_settings() {
|
|||||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
|
||||||
else
|
else
|
||||||
echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
|
echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
||||||
@@ -312,7 +142,7 @@ function advanced_settings() {
|
|||||||
DISK_CACHE=""
|
DISK_CACHE=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 almalinux --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 almalinux --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
@@ -320,13 +150,10 @@ function advanced_settings() {
|
|||||||
HN="almalinux"
|
HN="almalinux"
|
||||||
else
|
else
|
||||||
HN=$(echo "${VM_NAME,,}" | tr -cs 'a-z0-9-' '-' | sed 's/^-//;s/-$//')
|
HN=$(echo "${VM_NAME,,}" | tr -cs 'a-z0-9-' '-' | sed 's/^-//;s/-$//')
|
||||||
if [ "$HN" != "${VM_NAME,,}" ]; then
|
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "HOSTNAME ADJUSTED" --msgbox "Invalid characters detected. Hostname has been adjusted to:\n\n $HN" 10 58
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --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 \
|
||||||
@@ -341,7 +168,7 @@ function advanced_settings() {
|
|||||||
CPU_TYPE=" -cpu x86-64-v3"
|
CPU_TYPE=" -cpu x86-64-v3"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
@@ -353,7 +180,7 @@ function advanced_settings() {
|
|||||||
fi
|
fi
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "CPU Cores must be a positive integer (e.g., 2)." 8 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "CPU Cores must be a positive integer (e.g., 2)." 8 58
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -366,17 +193,15 @@ function advanced_settings() {
|
|||||||
fi
|
fi
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "RAM Size must be a positive integer in MiB (e.g., 2048)." 8 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "RAM Size must be a positive integer in MiB (e.g., 2048)." 8 58
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
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 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
|
if [ -z "$BRG" ]; then BRG="vmbr0"; fi
|
||||||
BRG="vmbr0"
|
|
||||||
fi
|
|
||||||
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
@@ -391,9 +216,9 @@ function advanced_settings() {
|
|||||||
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
|
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "Invalid MAC address format. Use XX:XX:XX:XX:XX:XX (e.g., AA:BB:CC:DD:EE:FF)." 8 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "Invalid MAC address format. Use XX:XX:XX:XX:XX:XX." 8 58
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -410,9 +235,9 @@ function advanced_settings() {
|
|||||||
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "VLAN must be a number between 1 and 4094, or leave blank for default." 8 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "VLAN must be a number between 1 and 4094, or leave blank." 8 58
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -429,9 +254,9 @@ function advanced_settings() {
|
|||||||
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "MTU Size must be a number between 576 and 65520, or leave blank for default." 8 58
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "MTU Size must be between 576 and 65520, or leave blank." 8 58
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -443,6 +268,8 @@ function advanced_settings() {
|
|||||||
START_VM="no"
|
START_VM="no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
configure_cloudinit_ssh_keys || true
|
||||||
|
|
||||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create an AlmaLinux 10 VM?" --no-button Do-Over 10 58); then
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create an AlmaLinux 10 VM?" --no-button Do-Over 10 58); then
|
||||||
echo -e "${CREATING}${BOLD}${DGN}Creating an AlmaLinux 10 VM using the above advanced settings${CL}"
|
echo -e "${CREATING}${BOLD}${DGN}Creating an AlmaLinux 10 VM using the above advanced settings${CL}"
|
||||||
else
|
else
|
||||||
@@ -464,12 +291,7 @@ function start_script() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
check_root
|
|
||||||
arch_check
|
|
||||||
pve_check
|
|
||||||
ssh_check
|
|
||||||
start_script
|
start_script
|
||||||
|
|
||||||
post_to_api_vm
|
post_to_api_vm
|
||||||
|
|
||||||
msg_info "Validating Storage"
|
msg_info "Validating Storage"
|
||||||
@@ -496,7 +318,7 @@ while [ -z "${STORAGE:+x}" ]; do
|
|||||||
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
||||||
"Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
|
"Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
|
||||||
16 $((MSG_MAX_LENGTH + 23)) 6 \
|
16 $((MSG_MAX_LENGTH + 23)) 6 \
|
||||||
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit-script
|
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || exit_script
|
||||||
done
|
done
|
||||||
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
|
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
|
||||||
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
|
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
|
||||||
@@ -506,8 +328,8 @@ msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
if ! command -v virt-customize &>/dev/null; then
|
if ! command -v virt-customize &>/dev/null; then
|
||||||
msg_info "Installing libguestfs-tools"
|
msg_info "Installing libguestfs-tools"
|
||||||
apt-get -qq update >/dev/null 2>&1
|
$STD apt-get update
|
||||||
apt-get -qq install -y libguestfs-tools >/dev/null 2>&1
|
$STD apt-get install -y libguestfs-tools
|
||||||
msg_ok "Installed libguestfs-tools"
|
msg_ok "Installed libguestfs-tools"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -530,24 +352,13 @@ cp "$FILE" "$WORK_FILE"
|
|||||||
popd >/dev/null
|
popd >/dev/null
|
||||||
rm -rf "$TEMP_DIR"
|
rm -rf "$TEMP_DIR"
|
||||||
|
|
||||||
# Set hostname
|
|
||||||
virt-customize -q -a "$WORK_FILE" --hostname "${HN}" >/dev/null 2>&1
|
virt-customize -q -a "$WORK_FILE" --hostname "${HN}" >/dev/null 2>&1
|
||||||
|
|
||||||
# Prepare for unique machine-id on first boot
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "truncate -s 0 /etc/machine-id" >/dev/null 2>&1
|
virt-customize -q -a "$WORK_FILE" --run-command "truncate -s 0 /etc/machine-id" >/dev/null 2>&1
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "rm -f /var/lib/dbus/machine-id" >/dev/null 2>&1
|
virt-customize -q -a "$WORK_FILE" --run-command "rm -f /var/lib/dbus/machine-id" >/dev/null 2>&1
|
||||||
|
|
||||||
# Disable systemd-firstboot to prevent interactive prompts blocking the console
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "systemctl disable systemd-firstboot.service 2>/dev/null; rm -f /etc/systemd/system/sysinit.target.wants/systemd-firstboot.service; ln -sf /dev/null /etc/systemd/system/systemd-firstboot.service" >/dev/null 2>&1 || true
|
virt-customize -q -a "$WORK_FILE" --run-command "systemctl disable systemd-firstboot.service 2>/dev/null; rm -f /etc/systemd/system/sysinit.target.wants/systemd-firstboot.service; ln -sf /dev/null /etc/systemd/system/systemd-firstboot.service" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
# Cloud-Init handles SSH and login
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config" >/dev/null 2>&1 || true
|
virt-customize -q -a "$WORK_FILE" --run-command "sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config" >/dev/null 2>&1 || true
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config" >/dev/null 2>&1 || true
|
virt-customize -q -a "$WORK_FILE" --run-command "sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
# Enable serial console login
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "systemctl enable serial-getty@ttyS0.service" >/dev/null 2>&1 || true
|
virt-customize -q -a "$WORK_FILE" --run-command "systemctl enable serial-getty@ttyS0.service" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
# Relabel SELinux contexts after all modifications (required for AlmaLinux/RHEL)
|
|
||||||
virt-customize -q -a "$WORK_FILE" --selinux-relabel >/dev/null 2>&1 || true
|
virt-customize -q -a "$WORK_FILE" --selinux-relabel >/dev/null 2>&1 || true
|
||||||
|
|
||||||
msg_ok "Customized image"
|
msg_ok "Customized image"
|
||||||
@@ -579,7 +390,6 @@ for i in {0,1,2}; do
|
|||||||
eval DISK"${i}"_REF="${STORAGE}":"${DISK_REF:-}""${!disk}"
|
eval DISK"${i}"_REF="${STORAGE}":"${DISK_REF:-}""${!disk}"
|
||||||
done
|
done
|
||||||
|
|
||||||
# For block/btrfs storage, pre-convert qcow2 to raw to ensure compatibility
|
|
||||||
if [[ "$STORAGE_TYPE" != "nfs" && "$STORAGE_TYPE" != "dir" ]]; then
|
if [[ "$STORAGE_TYPE" != "nfs" && "$STORAGE_TYPE" != "dir" ]]; then
|
||||||
msg_info "Converting image to raw format"
|
msg_info "Converting image to raw format"
|
||||||
RAW_FILE=$(mktemp --suffix=.raw)
|
RAW_FILE=$(mktemp --suffix=.raw)
|
||||||
@@ -598,49 +408,19 @@ qm importdisk "$VMID" "${WORK_FILE}" "$STORAGE" ${DISK_IMPORT:-} 1>&/dev/null
|
|||||||
qm set "$VMID" \
|
qm set "$VMID" \
|
||||||
-efidisk0 "${DISK0_REF}"${FORMAT} \
|
-efidisk0 "${DISK0_REF}"${FORMAT} \
|
||||||
-scsi0 "${DISK1_REF}",${DISK_CACHE}${THIN}size="${DISK_SIZE}" \
|
-scsi0 "${DISK1_REF}",${DISK_CACHE}${THIN}size="${DISK_SIZE}" \
|
||||||
-scsi1 "${STORAGE}":cloudinit \
|
|
||||||
-tpmstate0 "${DISK2_REF}",version=v2.0 \
|
-tpmstate0 "${DISK2_REF}",version=v2.0 \
|
||||||
-boot order=scsi0 \
|
-boot order=scsi0 \
|
||||||
-serial0 socket >/dev/null
|
-serial0 socket >/dev/null
|
||||||
|
|
||||||
# Clean up work file
|
|
||||||
rm -f "$WORK_FILE"
|
rm -f "$WORK_FILE"
|
||||||
|
msg_ok "Created an AlmaLinux 10 VM ${CL}${BL}(${HN})"
|
||||||
|
|
||||||
DESCRIPTION=$(
|
|
||||||
cat <<EOF
|
|
||||||
<div align='center'>
|
|
||||||
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
|
||||||
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<h2 style='font-size: 24px; margin: 20px 0;'>AlmaLinux 10 VM</h2>
|
|
||||||
|
|
||||||
<p style='margin: 16px 0;'>
|
|
||||||
<a href='https://ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>
|
|
||||||
<img src='https://img.shields.io/badge/☕-Buy us a coffee-blue' alt='spend Coffee' />
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<span style='margin: 0 10px;'>
|
|
||||||
<i class="fa fa-github fa-fw" style="color: #f5f5f5;"></i>
|
|
||||||
<a href='https://github.com/community-scripts/ProxmoxVE' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>GitHub</a>
|
|
||||||
</span>
|
|
||||||
<span style='margin: 0 10px;'>
|
|
||||||
<i class="fa fa-comments fa-fw" style="color: #f5f5f5;"></i>
|
|
||||||
<a href='https://github.com/community-scripts/ProxmoxVE/discussions' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Discussions</a>
|
|
||||||
</span>
|
|
||||||
<span style='margin: 0 10px;'>
|
|
||||||
<i class="fa fa-exclamation-circle fa-fw" style="color: #f5f5f5;"></i>
|
|
||||||
<a href='https://github.com/community-scripts/ProxmoxVE/issues' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Issues</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
qm set "$VMID" -description "$DESCRIPTION" >/dev/null
|
|
||||||
msg_info "Resizing disk to ${DISK_SIZE}"
|
msg_info "Resizing disk to ${DISK_SIZE}"
|
||||||
qm resize "$VMID" scsi0 "${DISK_SIZE}" >/dev/null
|
qm resize "$VMID" scsi0 "${DISK_SIZE}" >/dev/null
|
||||||
|
msg_ok "Resized disk to ${DISK_SIZE}"
|
||||||
|
|
||||||
|
setup_cloud_init "$VMID" "$STORAGE" "$HN" "yes"
|
||||||
|
|
||||||
msg_ok "Created an AlmaLinux 10 VM ${CL}${BL}(${HN})"
|
|
||||||
if [ "$START_VM" == "yes" ]; then
|
if [ "$START_VM" == "yes" ]; then
|
||||||
msg_info "Starting AlmaLinux 10 VM"
|
msg_info "Starting AlmaLinux 10 VM"
|
||||||
qm start "$VMID"
|
qm start "$VMID"
|
||||||
@@ -649,5 +429,8 @@ fi
|
|||||||
|
|
||||||
post_update_to_api "done" "none"
|
post_update_to_api "done" "none"
|
||||||
|
|
||||||
msg_ok "Completed successfully"
|
msg_ok "Completed successfully!"
|
||||||
echo -e "Setup Cloud-Init before starting \nMore info at https://github.com/community-scripts/ProxmoxVE/discussions/272 \n"
|
if [ -n "${CLOUDINIT_CRED_FILE:-}" ]; then
|
||||||
|
echo -e "${INFO}${YW} Cloud-Init credentials saved to: ${BGN}${CLOUDINIT_CRED_FILE}${CL}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|||||||
6
vm/headers/almalinux-10-vm
Normal file
6
vm/headers/almalinux-10-vm
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
___ __ __ _ _______ _ ____ ___
|
||||||
|
/ | / /___ ___ ____ _/ / (_)___ __ ___ __ < / __ \ | | / / |/ /
|
||||||
|
/ /| | / / __ `__ \/ __ `/ / / / __ \/ / / / |/_/ / / / / / | | / / /|_/ /
|
||||||
|
/ ___ |/ / / / / / / /_/ / /___/ / / / / /_/ /> < / / /_/ / | |/ / / / /
|
||||||
|
/_/ |_/_/_/ /_/ /_/\__,_/_____/_/_/ /_/\__,_/_/|_| /_/\____/ |___/_/ /_/
|
||||||
|
|
||||||
6
vm/headers/ubuntu2604-vm
Normal file
6
vm/headers/ubuntu2604-vm
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
__ ____ __ ___ _____ ____ __ __ _ ____ ___
|
||||||
|
/ / / / /_ __ ______ / /___ __ |__ \ / ___/ / __ \/ // / | | / / |/ /
|
||||||
|
/ / / / __ \/ / / / __ \/ __/ / / / __/ // __ \ / / / / // /_ | | / / /|_/ /
|
||||||
|
/ /_/ / /_/ / /_/ / / / / /_/ /_/ / / __// /_/ // /_/ /__ __/ | |/ / / / /
|
||||||
|
\____/_.___/\__,_/_/ /_/\__/\__,_/ /____/\____(_)____/ /_/ |___/_/ /_/
|
||||||
|
|
||||||
177
vm/ubuntu2604-vm.sh
Normal file
177
vm/ubuntu2604-vm.sh
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
||||||
|
|
||||||
|
source <(curl -fsSL "${COMMUNITY_SCRIPTS_URL:-https://git.community-scripts.org/community-scripts/ProxmoxVED/raw/branch/main}/misc/vm-core.func")
|
||||||
|
load_functions
|
||||||
|
|
||||||
|
function header_info {
|
||||||
|
clear
|
||||||
|
cat <<"EOF"
|
||||||
|
__ ____ __ ___ ______ ____ __ __ _ ____ ___
|
||||||
|
/ / / / /_ __ ______ / /___ __ |__ \ / ____// __ \/ // / | | / / |/ /
|
||||||
|
/ / / / __ \/ / / / __ \/ __/ / / / __/ //___ \ / / / / // /_ | | / / /|_/ /
|
||||||
|
/ /_/ / /_/ / /_/ / / / / /_/ /_/ / / __/____/ // /_/ /__ __/ | |/ / / / /
|
||||||
|
\____/_.___/\__,_/_/ /_/\__/\__,_/ /____/_____(_)____/ /_/ |___/_/ /_/ (Plucky Puffin)
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
APP="Ubuntu 26.04 VM"
|
||||||
|
APP_TYPE="vm"
|
||||||
|
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
|
||||||
|
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
||||||
|
METHOD=""
|
||||||
|
NSAPP="ubuntu2604-vm"
|
||||||
|
var_os="ubuntu"
|
||||||
|
var_version="2604"
|
||||||
|
THIN="discard=on,ssd=1,"
|
||||||
|
USE_CLOUD_INIT="no"
|
||||||
|
|
||||||
|
header_info
|
||||||
|
echo -e "\n Loading..."
|
||||||
|
|
||||||
|
set -e
|
||||||
|
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||||
|
trap cleanup EXIT
|
||||||
|
trap 'post_update_to_api "failed" "130"' SIGINT
|
||||||
|
trap 'post_update_to_api "failed" "143"' SIGTERM
|
||||||
|
trap 'post_update_to_api "failed" "129"; exit 129' SIGHUP
|
||||||
|
|
||||||
|
TEMP_DIR=$(mktemp -d)
|
||||||
|
pushd "$TEMP_DIR" >/dev/null
|
||||||
|
|
||||||
|
if vm_confirm_new_vm "$APP" "This will create a New $APP. Proceed?"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
header_info && exit_script
|
||||||
|
fi
|
||||||
|
|
||||||
|
check_root
|
||||||
|
arch_check
|
||||||
|
pve_check
|
||||||
|
ssh_check
|
||||||
|
vm_prompt_cloud_init "ubuntu"
|
||||||
|
|
||||||
|
function default_settings() {
|
||||||
|
VMID=$(get_valid_nextid)
|
||||||
|
vm_apply_machine_type "q35"
|
||||||
|
DISK_SIZE="7G"
|
||||||
|
DISK_CACHE=""
|
||||||
|
HN="ubuntu"
|
||||||
|
CPU_TYPE=""
|
||||||
|
CORE_COUNT="2"
|
||||||
|
RAM_SIZE="2048"
|
||||||
|
BRG="vmbr0"
|
||||||
|
MAC="$GEN_MAC"
|
||||||
|
VLAN=""
|
||||||
|
MTU=""
|
||||||
|
START_VM="yes"
|
||||||
|
METHOD="default"
|
||||||
|
|
||||||
|
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
|
||||||
|
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$(vm_machine_type_label "$MACHINE_TYPE")${CL}"
|
||||||
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
|
||||||
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
|
||||||
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
|
||||||
|
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
|
||||||
|
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
|
||||||
|
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
|
||||||
|
echo -e "${CLOUD}${BOLD}${DGN}Cloud-Init: ${BGN}${USE_CLOUD_INIT}${CL}"
|
||||||
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
|
||||||
|
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}${MAC}${CL}"
|
||||||
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
|
||||||
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
|
||||||
|
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}${START_VM}${CL}"
|
||||||
|
echo -e "${CREATING}${BOLD}${DGN}Creating a Ubuntu 26.04 VM using the above default settings${CL}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function advanced_settings() {
|
||||||
|
METHOD="advanced"
|
||||||
|
echo -e "${CLOUD}${BOLD}${DGN}Cloud-Init: ${BGN}${USE_CLOUD_INIT}${CL}"
|
||||||
|
vm_prompt_vmid "${VMID:-$(get_valid_nextid)}"
|
||||||
|
vm_prompt_machine_type "q35"
|
||||||
|
vm_prompt_disk_size "${DISK_SIZE:-7G}" "Set Disk Size in GiB (e.g., 10, 20)"
|
||||||
|
vm_prompt_disk_cache "none"
|
||||||
|
vm_prompt_hostname "ubuntu"
|
||||||
|
vm_prompt_cpu_model "kvm64"
|
||||||
|
vm_prompt_cpu_cores "2"
|
||||||
|
vm_prompt_ram "2048"
|
||||||
|
vm_prompt_bridge "vmbr0"
|
||||||
|
vm_prompt_mac "$GEN_MAC"
|
||||||
|
vm_prompt_vlan
|
||||||
|
vm_prompt_mtu
|
||||||
|
vm_prompt_start_vm "yes"
|
||||||
|
|
||||||
|
if vm_confirm_advanced_settings "Ready to create a Ubuntu 26.04 VM?"; then
|
||||||
|
echo -e "${CREATING}${BOLD}${DGN}Creating a Ubuntu 26.04 VM using the above advanced settings${CL}"
|
||||||
|
else
|
||||||
|
header_info
|
||||||
|
echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
|
||||||
|
advanced_settings
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function start_script() {
|
||||||
|
if vm_choose_settings_mode; then
|
||||||
|
header_info
|
||||||
|
echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings${CL}"
|
||||||
|
default_settings
|
||||||
|
else
|
||||||
|
header_info
|
||||||
|
echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
|
||||||
|
advanced_settings
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
start_script
|
||||||
|
post_to_api_vm
|
||||||
|
|
||||||
|
vm_select_storage "$HN"
|
||||||
|
vm_define_disk_references 2
|
||||||
|
DISK_IMPORT="-format ${DISK_IMPORT_FORMAT}"
|
||||||
|
|
||||||
|
msg_info "Retrieving the URL for the Ubuntu 26.04 Disk Image"
|
||||||
|
URL="https://cloud-images.ubuntu.com/releases/server/26.04/release/ubuntu-26.04-server-cloudimg-amd64.img"
|
||||||
|
sleep 2
|
||||||
|
msg_ok "${CL}${BL}${URL}${CL}"
|
||||||
|
curl -f#SL -o "$(basename "$URL")" "$URL"
|
||||||
|
echo -en "\e[1A\e[0K"
|
||||||
|
FILE="$(basename "$URL")"
|
||||||
|
msg_ok "Downloaded ${CL}${BL}${FILE}${CL}"
|
||||||
|
|
||||||
|
msg_info "Creating a Ubuntu 26.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 community-script -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=${DISK_SIZE} \
|
||||||
|
-boot order=scsi0 \
|
||||||
|
-serial0 socket >/dev/null
|
||||||
|
set_description
|
||||||
|
|
||||||
|
msg_info "Resizing disk to $DISK_SIZE"
|
||||||
|
qm resize $VMID scsi0 ${DISK_SIZE} >/dev/null
|
||||||
|
|
||||||
|
if [ "$USE_CLOUD_INIT" = "yes" ] && declare -f setup_cloud_init >/dev/null 2>&1; then
|
||||||
|
setup_cloud_init "$VMID" "$STORAGE" "$HN" "yes" "${CLOUDINIT_USER:-ubuntu}" "${CLOUDINIT_NETWORK_MODE:-dhcp}" "${CLOUDINIT_IP:-}" "${CLOUDINIT_GW:-}" "${CLOUDINIT_DNS:-${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_ok "Created a Ubuntu 26.04 VM ${CL}${BL}(${HN})"
|
||||||
|
if [ "$START_VM" = "yes" ]; then
|
||||||
|
msg_info "Starting Ubuntu 26.04 VM"
|
||||||
|
qm start $VMID
|
||||||
|
msg_ok "Started Ubuntu 26.04 VM"
|
||||||
|
fi
|
||||||
|
|
||||||
|
post_update_to_api "done" "none"
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
if [ "$USE_CLOUD_INIT" = "yes" ] && declare -f display_cloud_init_info >/dev/null 2>&1; then
|
||||||
|
display_cloud_init_info "$VMID" "$HN"
|
||||||
|
else
|
||||||
|
echo -e "Cloud-Init is disabled. The VM disk was resized on the Proxmox side only.\nIf the guest does not auto-expand its root filesystem after first boot, expand it manually inside the VM.\n\nMore info at https://github.com/community-scripts/ProxmoxVED/discussions/272 \n"
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user