mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-02-05 21:03:24 +01:00
Compare commits
27 Commits
feat/sqlse
...
pr-update-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e437d804ca | ||
|
|
6ed9afb40b | ||
|
|
fbf04bee6a | ||
|
|
c9bb2788be | ||
|
|
93e4eb5b22 | ||
|
|
f4d4a00180 | ||
|
|
101f882022 | ||
|
|
8f97908896 | ||
|
|
833a6a248b | ||
|
|
9a65218900 | ||
|
|
b61abacb76 | ||
|
|
273c5c75ee | ||
|
|
06d9199d89 | ||
|
|
5d5c273fb6 | ||
|
|
92506cdc34 | ||
|
|
5db509eb16 | ||
|
|
129f2f6329 | ||
|
|
be9d26885a | ||
|
|
ddd130dbe3 | ||
|
|
93c52abebd | ||
|
|
a74f6ee3c3 | ||
|
|
b36051375b | ||
|
|
7b8a3a111d | ||
|
|
be994ce84f | ||
|
|
4bd5c7b54b | ||
|
|
868446a4b6 | ||
|
|
5f31954d91 |
32
CHANGELOG.md
32
CHANGELOG.md
@@ -398,6 +398,31 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## 2026-02-05
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Nginx-UI ([#11573](https://github.com/community-scripts/ProxmoxVE/pull/11573))
|
||||||
|
- New: SQL-Server 2025 | Refactor SQL-Server 2022 [@MickLesk](https://github.com/MickLesk) ([#11546](https://github.com/community-scripts/ProxmoxVE/pull/11546))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Refactor: Docker-VM (Multi-OS / Cloud-Init / Stabilization) [@MickLesk](https://github.com/MickLesk) ([#9047](https://github.com/community-scripts/ProxmoxVE/pull/9047))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- cloud-init: add interactive SSH key discovery and selection [@MickLesk](https://github.com/MickLesk) ([#11547](https://github.com/community-scripts/ProxmoxVE/pull/11547))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix(frontend): theme respective syntax highlighting [@ls-root](https://github.com/ls-root) ([#11565](https://github.com/community-scripts/ProxmoxVE/pull/11565))
|
||||||
|
|
||||||
## 2026-02-04
|
## 2026-02-04
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
@@ -407,8 +432,11 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- Add log directory and permissions for koillection [@shineangelic](https://github.com/shineangelic) ([#11553](https://github.com/community-scripts/ProxmoxVE/pull/11553))
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- [FIX] Scanopy: ensure Scanopy Daemon update [@vhsdream](https://github.com/vhsdream) ([#11541](https://github.com/community-scripts/ProxmoxVE/pull/11541))
|
||||||
- Immich: pin version to 2.5.3 [@vhsdream](https://github.com/vhsdream) ([#11515](https://github.com/community-scripts/ProxmoxVE/pull/11515))
|
- Immich: pin version to 2.5.3 [@vhsdream](https://github.com/vhsdream) ([#11515](https://github.com/community-scripts/ProxmoxVE/pull/11515))
|
||||||
|
|
||||||
### 💾 Core
|
### 💾 Core
|
||||||
@@ -429,6 +457,10 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
- fix(frontend): implement weighted search scoring for command menu [@ls-root](https://github.com/ls-root) ([#11534](https://github.com/community-scripts/ProxmoxVE/pull/11534))
|
- fix(frontend): implement weighted search scoring for command menu [@ls-root](https://github.com/ls-root) ([#11534](https://github.com/community-scripts/ProxmoxVE/pull/11534))
|
||||||
|
|
||||||
|
### ❔ Uncategorized
|
||||||
|
|
||||||
|
- [FIX] Immich Public Proxy docs link [@vhsdream](https://github.com/vhsdream) ([#11543](https://github.com/community-scripts/ProxmoxVE/pull/11543))
|
||||||
|
|
||||||
## 2026-02-03
|
## 2026-02-03
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
|
|||||||
6
ct/headers/nginx-ui
Normal file
6
ct/headers/nginx-ui
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
_ __ _ __ ______
|
||||||
|
/ | / /___ _(_)___ _ __ / / / / _/
|
||||||
|
/ |/ / __ `/ / __ \| |/_/_____/ / / // /
|
||||||
|
/ /| / /_/ / / / / /> </_____/ /_/ // /
|
||||||
|
/_/ |_/\__, /_/_/ /_/_/|_| \____/___/
|
||||||
|
/____/
|
||||||
6
ct/headers/opencloud
Normal file
6
ct/headers/opencloud
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
____ ________ __
|
||||||
|
/ __ \____ ___ ____ / ____/ /___ __ ______/ /
|
||||||
|
/ / / / __ \/ _ \/ __ \/ / / / __ \/ / / / __ /
|
||||||
|
/ /_/ / /_/ / __/ / / / /___/ / /_/ / /_/ / /_/ /
|
||||||
|
\____/ .___/\___/_/ /_/\____/_/\____/\__,_/\__,_/
|
||||||
|
/_/
|
||||||
6
ct/headers/sqlserver2025
Normal file
6
ct/headers/sqlserver2025
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
_____ ____ __ _____ ___ ____ ___ ______
|
||||||
|
/ ___// __ \ / / / ___/___ ______ _____ _____ |__ \ / __ \__ \ / ____/
|
||||||
|
\__ \/ / / / / / \__ \/ _ \/ ___/ | / / _ \/ ___/ __/ // / / /_/ //___ \
|
||||||
|
___/ / /_/ / / /___ ___/ / __/ / | |/ / __/ / / __// /_/ / __/____/ /
|
||||||
|
/____/\___\_\/_____/ /____/\___/_/ |___/\___/_/ /____/\____/____/_____/
|
||||||
|
|
||||||
@@ -59,6 +59,8 @@ function update_script() {
|
|||||||
$STD yarn install
|
$STD yarn install
|
||||||
$STD yarn build
|
$STD yarn build
|
||||||
mkdir -p /opt/koillection/public/uploads
|
mkdir -p /opt/koillection/public/uploads
|
||||||
|
mkdir -p /opt/koillection/var/log
|
||||||
|
chown -R www-data:www-data /opt/koillection/var/log
|
||||||
chown -R www-data:www-data /opt/koillection/public/uploads
|
chown -R www-data:www-data /opt/koillection/public/uploads
|
||||||
rm -r /opt/koillection-backup
|
rm -r /opt/koillection-backup
|
||||||
|
|
||||||
|
|||||||
68
ct/nginx-ui.sh
Normal file
68
ct/nginx-ui.sh
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://nginxui.com
|
||||||
|
|
||||||
|
APP="Nginx-UI"
|
||||||
|
var_tags="${var_tags:-webserver;nginx;proxy}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-512}"
|
||||||
|
var_disk="${var_disk:-4}"
|
||||||
|
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 [[ ! -f /usr/local/bin/nginx-ui ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "nginx-ui" "0xJacky/nginx-ui"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop nginx-ui
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
msg_info "Backing up Configuration"
|
||||||
|
cp /usr/local/etc/nginx-ui/app.ini /tmp/nginx-ui-app.ini.bak
|
||||||
|
msg_ok "Backed up Configuration"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nginx-ui" "0xJacky/nginx-ui" "prebuild" "latest" "/opt/nginx-ui" "nginx-ui-linux-64.tar.gz"
|
||||||
|
|
||||||
|
msg_info "Updating Binary"
|
||||||
|
cp /opt/nginx-ui/nginx-ui /usr/local/bin/nginx-ui
|
||||||
|
chmod +x /usr/local/bin/nginx-ui
|
||||||
|
rm -rf /opt/nginx-ui
|
||||||
|
msg_ok "Updated Binary"
|
||||||
|
|
||||||
|
msg_info "Restoring Configuration"
|
||||||
|
mv /tmp/nginx-ui-app.ini.bak /usr/local/etc/nginx-ui/app.ini
|
||||||
|
msg_ok "Restored Configuration"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start nginx-ui
|
||||||
|
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}:9000${CL}"
|
||||||
60
ct/opencloud.sh
Normal file
60
ct/opencloud.sh
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: vhsdream
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://opencloud.eu
|
||||||
|
|
||||||
|
APP="OpenCloud"
|
||||||
|
var_tags="${var_tags:-files;cloud}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-2048}"
|
||||||
|
var_disk="${var_disk:-20}"
|
||||||
|
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 /etc/opencloud ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
RELEASE="v5.0.1"
|
||||||
|
if check_for_gh_release "opencloud" "opencloud-eu/opencloud" "${RELEASE}"; then
|
||||||
|
msg_info "Stopping services"
|
||||||
|
systemctl stop opencloud opencloud-wopi
|
||||||
|
msg_ok "Stopped services"
|
||||||
|
|
||||||
|
msg_info "Updating packages"
|
||||||
|
$STD apt-get update
|
||||||
|
$STD apt-get dist-upgrade -y
|
||||||
|
msg_ok "Updated packages"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "opencloud" "opencloud-eu/opencloud" "singlefile" "${RELEASE}" "/usr/bin" "opencloud-*-linux-amd64"
|
||||||
|
|
||||||
|
msg_info "Starting services"
|
||||||
|
systemctl start opencloud opencloud-wopi
|
||||||
|
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}https://<your-OpenCloud-FQDN>${CL}"
|
||||||
@@ -29,7 +29,7 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "scanopy" "scanopy/scanopy"; then
|
if check_for_gh_release "Scanopy" "scanopy/scanopy"; then
|
||||||
msg_info "Stopping services"
|
msg_info "Stopping services"
|
||||||
systemctl stop scanopy-server
|
systemctl stop scanopy-server
|
||||||
[[ -f /etc/systemd/system/scanopy-daemon.service ]] && systemctl stop scanopy-daemon
|
[[ -f /etc/systemd/system/scanopy-daemon.service ]] && systemctl stop scanopy-daemon
|
||||||
@@ -40,7 +40,7 @@ function update_script() {
|
|||||||
[[ -f /opt/scanopy/oidc.toml ]] && cp /opt/scanopy/oidc.toml /opt/scanopy.oidc.toml
|
[[ -f /opt/scanopy/oidc.toml ]] && cp /opt/scanopy/oidc.toml /opt/scanopy.oidc.toml
|
||||||
msg_ok "Backed up configurations"
|
msg_ok "Backed up configurations"
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
||||||
|
|
||||||
ensure_dependencies pkg-config libssl-dev
|
ensure_dependencies pkg-config libssl-dev
|
||||||
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
|
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
|
||||||
@@ -61,19 +61,22 @@ function update_script() {
|
|||||||
$STD npm run build
|
$STD npm run build
|
||||||
msg_ok "Created frontend UI"
|
msg_ok "Created frontend UI"
|
||||||
|
|
||||||
msg_info "Building scanopy-server (patience)"
|
msg_info "Building Scanopy Server (patience)"
|
||||||
cd /opt/scanopy/backend
|
cd /opt/scanopy/backend
|
||||||
$STD cargo build --release --bin server
|
$STD cargo build --release --bin server
|
||||||
mv ./target/release/server /usr/bin/scanopy-server
|
mv ./target/release/server /usr/bin/scanopy-server
|
||||||
msg_ok "Built scanopy-server"
|
msg_ok "Built Scanopy Server"
|
||||||
|
|
||||||
[[ -f /etc/systemd/system/scanopy-daemon.service ]] &&
|
if [[ -f /etc/systemd/system/scanopy-daemon.service ]]; then
|
||||||
fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "singlefile" "latest" "/usr/local/bin" "scanopy-daemon-linux-amd64" &&
|
fetch_and_deploy_gh_release "Scanopy Daemon" "scanopy/scanopy" "singlefile" "latest" "/usr/local/bin" "scanopy-daemon-linux-amd64"
|
||||||
rm -f /usr/bin/scanopy-daemon ~/configure_daemon.sh &&
|
mv "/usr/local/bin/Scanopy Daemon" /usr/local/bin/scanopy-daemon
|
||||||
|
rm -f /usr/bin/scanopy-daemon ~/configure_daemon.sh
|
||||||
sed -i -e 's|usr/bin|usr/local/bin|' \
|
sed -i -e 's|usr/bin|usr/local/bin|' \
|
||||||
-e 's/push/daemon_poll/' \
|
-e 's/push/daemon_poll/' \
|
||||||
-e 's/pull/server_poll/' /etc/systemd/system/scanopy-daemon.service &&
|
-e 's/pull/server_poll/' /etc/systemd/system/scanopy-daemon.service
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
msg_ok "Updated Scanopy Daemon"
|
||||||
|
fi
|
||||||
|
|
||||||
msg_info "Starting services"
|
msg_info "Starting services"
|
||||||
systemctl start scanopy-server
|
systemctl start scanopy-server
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated": "2026-02-04T18:17:33Z",
|
"generated": "2026-02-05T12:12:20Z",
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
{
|
||||||
"slug": "2fauth",
|
"slug": "2fauth",
|
||||||
@@ -186,9 +186,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "comfyui",
|
"slug": "comfyui",
|
||||||
"repo": "comfyanonymous/ComfyUI",
|
"repo": "comfyanonymous/ComfyUI",
|
||||||
"version": "v0.12.2",
|
"version": "v0.12.3",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T06:09:31Z"
|
"date": "2026-02-05T07:04:07Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "commafeed",
|
"slug": "commafeed",
|
||||||
@@ -221,9 +221,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "cronicle",
|
"slug": "cronicle",
|
||||||
"repo": "jhuckaby/Cronicle",
|
"repo": "jhuckaby/Cronicle",
|
||||||
"version": "v0.9.102",
|
"version": "v0.9.103",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-12-19T03:45:13Z"
|
"date": "2026-02-05T03:09:04Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "cryptpad",
|
"slug": "cryptpad",
|
||||||
@@ -445,9 +445,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "headscale",
|
"slug": "headscale",
|
||||||
"repo": "juanfont/headscale",
|
"repo": "juanfont/headscale",
|
||||||
"version": "v0.27.1",
|
"version": "v0.28.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-11-11T19:32:29Z"
|
"date": "2026-02-04T20:40:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "healthchecks",
|
"slug": "healthchecks",
|
||||||
@@ -494,9 +494,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "homepage",
|
"slug": "homepage",
|
||||||
"repo": "gethomepage/homepage",
|
"repo": "gethomepage/homepage",
|
||||||
"version": "v1.9.0",
|
"version": "v1.10.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-01-19T05:46:09Z"
|
"date": "2026-02-05T06:17:32Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "homer",
|
"slug": "homer",
|
||||||
@@ -515,9 +515,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "huntarr",
|
"slug": "huntarr",
|
||||||
"repo": "plexguide/Huntarr.io",
|
"repo": "plexguide/Huntarr.io",
|
||||||
"version": "9.1.12",
|
"version": "9.2.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T14:28:36Z"
|
"date": "2026-02-05T04:18:08Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "inspircd",
|
"slug": "inspircd",
|
||||||
@@ -536,16 +536,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "invoiceninja",
|
"slug": "invoiceninja",
|
||||||
"repo": "invoiceninja/invoiceninja",
|
"repo": "invoiceninja/invoiceninja",
|
||||||
"version": "v5.12.53",
|
"version": "v5.12.55",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T00:52:01Z"
|
"date": "2026-02-05T01:06:15Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "jackett",
|
"slug": "jackett",
|
||||||
"repo": "Jackett/Jackett",
|
"repo": "Jackett/Jackett",
|
||||||
"version": "v0.24.1027",
|
"version": "v0.24.1032",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T05:56:22Z"
|
"date": "2026-02-05T05:55:27Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "joplin-server",
|
"slug": "joplin-server",
|
||||||
@@ -746,9 +746,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "mealie",
|
"slug": "mealie",
|
||||||
"repo": "mealie-recipes/mealie",
|
"repo": "mealie-recipes/mealie",
|
||||||
"version": "v3.10.1",
|
"version": "v3.10.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-03T01:04:38Z"
|
"date": "2026-02-04T23:32:32Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "mediamanager",
|
"slug": "mediamanager",
|
||||||
@@ -781,9 +781,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "metube",
|
"slug": "metube",
|
||||||
"repo": "alexta69/metube",
|
"repo": "alexta69/metube",
|
||||||
"version": "2026.02.03",
|
"version": "2026.02.04",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-03T21:49:49Z"
|
"date": "2026-02-04T20:01:18Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "miniflux",
|
"slug": "miniflux",
|
||||||
@@ -1096,9 +1096,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "pulse",
|
"slug": "pulse",
|
||||||
"repo": "rcourtman/Pulse",
|
"repo": "rcourtman/Pulse",
|
||||||
"version": "v5.1.0",
|
"version": "v5.1.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T17:43:59Z"
|
"date": "2026-02-05T00:18:57Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "pve-scripts-local",
|
"slug": "pve-scripts-local",
|
||||||
@@ -1271,9 +1271,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "speedtest-tracker",
|
"slug": "speedtest-tracker",
|
||||||
"repo": "alexjustesen/speedtest-tracker",
|
"repo": "alexjustesen/speedtest-tracker",
|
||||||
"version": "v1.13.7",
|
"version": "v1.13.8",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T16:47:42Z"
|
"date": "2026-02-04T19:24:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "spoolman",
|
"slug": "spoolman",
|
||||||
@@ -1292,9 +1292,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "stirling-pdf",
|
"slug": "stirling-pdf",
|
||||||
"repo": "Stirling-Tools/Stirling-PDF",
|
"repo": "Stirling-Tools/Stirling-PDF",
|
||||||
"version": "v2.4.3",
|
"version": "v2.4.4",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-01-31T22:19:14Z"
|
"date": "2026-02-05T00:15:53Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "streamlink-webui",
|
"slug": "streamlink-webui",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
"updateable": true,
|
"updateable": true,
|
||||||
"privileged": false,
|
"privileged": false,
|
||||||
"interface_port": 3000,
|
"interface_port": 3000,
|
||||||
"documentation": "https://github.com/alangrainger/immich-public-proxy/docs",
|
"documentation": "https://github.com/alangrainger/immich-public-proxy/tree/main/docs",
|
||||||
"website": "https://github.com/alangrainger/immich-public-proxy",
|
"website": "https://github.com/alangrainger/immich-public-proxy",
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/immich-public-proxy.webp",
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/immich-public-proxy.webp",
|
||||||
"config_path": "/opt/immich-proxy/app/.env",
|
"config_path": "/opt/immich-proxy/app/.env",
|
||||||
|
|||||||
48
frontend/public/json/nginx-ui.json
Normal file
48
frontend/public/json/nginx-ui.json
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"name": "Nginx UI",
|
||||||
|
"slug": "nginx-ui",
|
||||||
|
"categories": [
|
||||||
|
21
|
||||||
|
],
|
||||||
|
"date_created": "2026-02-05",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": 9000,
|
||||||
|
"documentation": "https://nginxui.com/guide/",
|
||||||
|
"website": "https://nginxui.com",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/nginx-ui.webp",
|
||||||
|
"config_path": "/usr/local/etc/nginx-ui/app.ini",
|
||||||
|
"description": "Nginx UI is a comprehensive web-based interface designed to simplify the management and configuration of Nginx servers. It provides features like online statistics, ChatGPT-powered config assistant, automatic Let's Encrypt certificates, and config file editing with syntax highlighting.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/nginx-ui.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 1,
|
||||||
|
"ram": 512,
|
||||||
|
"hdd": 4,
|
||||||
|
"os": "Debian",
|
||||||
|
"version": "13"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": "admin",
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "Nginx runs on ports 80/443, Nginx UI management interface on port 9000.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "SSL certificates can be managed automatically with Let's Encrypt integration.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Initial Login data: `cat ~/nginx-ui.creds`",
|
||||||
|
"type": "info"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
64
frontend/public/json/opencloud.json
Normal file
64
frontend/public/json/opencloud.json
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"name": "OpenCloud",
|
||||||
|
"slug": "opencloud",
|
||||||
|
"categories": [
|
||||||
|
11
|
||||||
|
],
|
||||||
|
"date_created": "2025-12-12",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": 443,
|
||||||
|
"documentation": "https://docs.opencloud.eu",
|
||||||
|
"config_path": "/etc/opencloud/opencloud.env, /etc/opencloud/opencloud.yaml, /etc/opencloud/csp.yaml",
|
||||||
|
"website": "https://opencloud.eu",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/opencloud.webp",
|
||||||
|
"description": "OpenCloud is the file sharing and collaboration solution of the Heinlein Group. Through intelligent file management and a strong open source community, files become valuable resources, effectively structured and usable in the long term. With flexible data rooms and intelligent access rights, teams can access and work together on data anytime, anywhere without barriers, but with a lot of productivity.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/opencloud.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 2,
|
||||||
|
"ram": 2048,
|
||||||
|
"hdd": 20,
|
||||||
|
"os": "Debian",
|
||||||
|
"version": "13"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": "admin",
|
||||||
|
"password": "randomly generated during the installation process"
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "Valid TLS certificates and fully-qualified domain names behind a reverse proxy (Caddy) for 3 services - OpenCloud, Collabora, and WOPI are **REQUIRED**",
|
||||||
|
"type": "warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Forgot your admin password? Check `admin_password` in the 'idm' section in `/etc/opencloud/opencloud.yaml`",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "**Optional External Apps**: extract zip archives from App Store to `/etc/opencloud/assets/apps`",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "**Optional CalDAV and CardDAV**: requires separate Radicale install. Edit and rename `/opt/opencloud/proxy.yaml.bak` and change your Radicale config to use `http_x_remote_user` as the auth method",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "**Optional OpenID**: Authelia and PocketID supported. Uncomment relevant lines in `/opt/opencloud/opencloud.env` and consult OpenCloud GitHub discussions for configuration tips",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "**Optional Full-text Search with Apache Tika**: requires your own Tika LXC. See `https://community-scripts.github.io/ProxmoxVE/scripts?id=apache-tika`",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "**Relevant services**: `opencloud.service`, `opencloud-wopi.service`, `coolwsd.service`",
|
||||||
|
"type": "info"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,52 +1,52 @@
|
|||||||
{
|
{
|
||||||
"name": "SQL Server 2025",
|
"name": "SQL Server 2025",
|
||||||
"slug": "sqlserver2025",
|
"slug": "sqlserver2025",
|
||||||
"categories": [
|
"categories": [
|
||||||
8
|
8
|
||||||
],
|
],
|
||||||
"date_created": "2026-02-04",
|
"date_created": "2026-02-05",
|
||||||
"type": "ct",
|
"type": "ct",
|
||||||
"updateable": true,
|
"updateable": true,
|
||||||
"privileged": true,
|
"privileged": true,
|
||||||
"interface_port": 1433,
|
"interface_port": 1433,
|
||||||
"documentation": "https://learn.microsoft.com/en-us/sql/sql-server/?view=sql-server-ver17",
|
"documentation": "https://learn.microsoft.com/en-us/sql/sql-server/?view=sql-server-ver17",
|
||||||
"website": "https://www.microsoft.com/en-us/sql-server/sql-server-2025",
|
"website": "https://www.microsoft.com/en-us/sql-server/sql-server-2025",
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/microsoft-sql-server.webp",
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/microsoft-sql-server.webp",
|
||||||
"config_path": "",
|
"config_path": "",
|
||||||
"description": "Script to automatically set up a SQL Server 2025 installation with Ubuntu 24.04 support.",
|
"description": "Script to automatically set up a SQL Server 2025 installation with Ubuntu 24.04 support.",
|
||||||
"install_methods": [
|
"install_methods": [
|
||||||
{
|
{
|
||||||
"type": "default",
|
"type": "default",
|
||||||
"script": "ct/sqlserver2025.sh",
|
"script": "ct/sqlserver2025.sh",
|
||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 2,
|
"cpu": 2,
|
||||||
"ram": 2048,
|
"ram": 2048,
|
||||||
"hdd": 10,
|
"hdd": 10,
|
||||||
"os": "Ubuntu",
|
"os": "Ubuntu",
|
||||||
"version": "24.04"
|
"version": "24.04"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default_credentials": {
|
"default_credentials": {
|
||||||
"username": null,
|
"username": null,
|
||||||
"password": null
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "If you choose not to run the installation setup, execute: `/opt/mssql/bin/mssql-conf setup` in LXC shell.",
|
||||||
|
"type": "info"
|
||||||
},
|
},
|
||||||
"notes": [
|
{
|
||||||
{
|
"text": "You can setup the admin account 'SA' during installation",
|
||||||
"text": "If you choose not to run the installation setup, execute: `/opt/mssql/bin/mssql-conf setup` in LXC shell.",
|
"type": "info"
|
||||||
"type": "info"
|
},
|
||||||
},
|
{
|
||||||
{
|
"text": "Make sure you disable the SA account if you intend to use this in production!",
|
||||||
"text": "You can setup the admin account 'SA' during installation",
|
"type": "warning"
|
||||||
"type": "info"
|
},
|
||||||
},
|
{
|
||||||
{
|
"text": "Ubuntu 24.04 support requires SQL Server 2025 CU1 or later",
|
||||||
"text": "Make sure you disable the SA account if you intend to use this in production!",
|
"type": "info"
|
||||||
"type": "warning"
|
}
|
||||||
},
|
]
|
||||||
{
|
|
||||||
"text": "Ubuntu 24.04 support requires SQL Server 2025 CU1 or later",
|
|
||||||
"type": "info"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,10 @@ import { ScriptSchema } from "./_schemas/schemas";
|
|||||||
import Categories from "./_components/categories";
|
import Categories from "./_components/categories";
|
||||||
import Note from "./_components/note";
|
import Note from "./_components/note";
|
||||||
|
|
||||||
import { nord } from "react-syntax-highlighter/dist/esm/styles/hljs";
|
import { githubGist, nord } from "react-syntax-highlighter/dist/esm/styles/hljs";
|
||||||
import SyntaxHighlighter from "react-syntax-highlighter";
|
import SyntaxHighlighter from "react-syntax-highlighter";
|
||||||
import { ScriptItem } from "../scripts/_components/script-item";
|
import { ScriptItem } from "../scripts/_components/script-item";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
|
||||||
const initialScript: Script = {
|
const initialScript: Script = {
|
||||||
name: "",
|
name: "",
|
||||||
@@ -58,6 +59,7 @@ const initialScript: Script = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function JSONGenerator() {
|
export default function JSONGenerator() {
|
||||||
|
const { theme } = useTheme();
|
||||||
const [script, setScript] = useState<Script>(initialScript);
|
const [script, setScript] = useState<Script>(initialScript);
|
||||||
const [isCopied, setIsCopied] = useState(false);
|
const [isCopied, setIsCopied] = useState(false);
|
||||||
const [isValid, setIsValid] = useState(false);
|
const [isValid, setIsValid] = useState(false);
|
||||||
@@ -357,7 +359,7 @@ export default function JSONGenerator() {
|
|||||||
|
|
||||||
<SyntaxHighlighter
|
<SyntaxHighlighter
|
||||||
language="json"
|
language="json"
|
||||||
style={nord}
|
style={theme === "light" ? githubGist : nord}
|
||||||
className="mt-4 p-4 bg-secondary rounded shadow overflow-x-scroll"
|
className="mt-4 p-4 bg-secondary rounded shadow overflow-x-scroll"
|
||||||
>
|
>
|
||||||
{JSON.stringify(script, null, 2)}
|
{JSON.stringify(script, null, 2)}
|
||||||
|
|||||||
99
install/nginx-ui-install.sh
Normal file
99
install/nginx-ui-install.sh
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://nginxui.com
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt install -y \
|
||||||
|
nginx \
|
||||||
|
logrotate
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "nginx-ui" "0xJacky/nginx-ui" "prebuild" "latest" "/opt/nginx-ui" "nginx-ui-linux-64.tar.gz"
|
||||||
|
|
||||||
|
msg_info "Installing Nginx UI"
|
||||||
|
cp /opt/nginx-ui/nginx-ui /usr/local/bin/nginx-ui
|
||||||
|
chmod +x /usr/local/bin/nginx-ui
|
||||||
|
rm -rf /opt/nginx-ui
|
||||||
|
msg_ok "Installed Nginx UI"
|
||||||
|
|
||||||
|
msg_info "Configuring Nginx UI"
|
||||||
|
mkdir -p /usr/local/etc/nginx-ui
|
||||||
|
cat <<EOF >/usr/local/etc/nginx-ui/app.ini
|
||||||
|
[server]
|
||||||
|
HttpHost = 0.0.0.0
|
||||||
|
HttpPort = 9000
|
||||||
|
RunMode = release
|
||||||
|
JwtSecret = $(openssl rand -hex 32)
|
||||||
|
|
||||||
|
[nginx]
|
||||||
|
AccessLogPath = /var/log/nginx/access.log
|
||||||
|
ErrorLogPath = /var/log/nginx/error.log
|
||||||
|
ConfigDir = /etc/nginx
|
||||||
|
PIDPath = /run/nginx.pid
|
||||||
|
TestConfigCmd = nginx -t
|
||||||
|
ReloadCmd = nginx -s reload
|
||||||
|
RestartCmd = systemctl restart nginx
|
||||||
|
|
||||||
|
[app]
|
||||||
|
PageSize = 10
|
||||||
|
|
||||||
|
[cert]
|
||||||
|
Email =
|
||||||
|
CADir =
|
||||||
|
RenewalInterval = 7
|
||||||
|
RecursiveNameservers =
|
||||||
|
EOF
|
||||||
|
msg_ok "Configured Nginx UI"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/nginx-ui.service
|
||||||
|
[Unit]
|
||||||
|
Description=Another WebUI for Nginx
|
||||||
|
Documentation=https://nginxui.com
|
||||||
|
After=network.target nginx.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/local/bin/nginx-ui --config /usr/local/etc/nginx-ui/app.ini
|
||||||
|
RuntimeDirectory=nginx-ui
|
||||||
|
WorkingDirectory=/var/run/nginx-ui
|
||||||
|
Restart=on-failure
|
||||||
|
TimeoutStopSec=5
|
||||||
|
KillMode=mixed
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl daemon-reload
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
msg_info "Creating Initial Admin User"
|
||||||
|
systemctl start nginx-ui
|
||||||
|
sleep 3
|
||||||
|
systemctl stop nginx-ui
|
||||||
|
sleep 1
|
||||||
|
/usr/local/bin/nginx-ui reset-password --config /usr/local/etc/nginx-ui/app.ini &>/tmp/nginx-ui-reset.log || true
|
||||||
|
ADMIN_PASS=$(grep -oP 'Password: \K\S+' /tmp/nginx-ui-reset.log || echo "admin")
|
||||||
|
echo -e "Nginx-UI Credentials\nUsername: admin\nPassword: $ADMIN_PASS" >~/nginx-ui.creds
|
||||||
|
rm -f /tmp/nginx-ui-reset.log
|
||||||
|
msg_ok "Created Initial Admin User"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl enable -q --now nginx-ui
|
||||||
|
rm -rf /etc/nginx/sites-enabled/default
|
||||||
|
msg_ok "Started Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
213
install/opencloud-install.sh
Normal file
213
install/opencloud-install.sh
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: vhsdream
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://opencloud.eu
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
MAX_ATTEMPTS=3
|
||||||
|
servers=("opencloud" "collabora" "wopi")
|
||||||
|
attempt=0
|
||||||
|
for server in "${servers[@]}"; do
|
||||||
|
until ((attempt >= MAX_ATTEMPTS)); do
|
||||||
|
attempt=$((attempt + 1))
|
||||||
|
read -rp "${TAB3}Enter the FQDN of your ${server^} server (ATTEMPT $attempt/$MAX_ATTEMPTS) (eg $server.domain.tld): " fqdn
|
||||||
|
if [[ -z "$fqdn" ]]; then
|
||||||
|
msg_warn "Domain cannot be empty!"
|
||||||
|
elif [[ "$fqdn" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
||||||
|
msg_warn "IP address not allowed! Please use a FQDN"
|
||||||
|
elif [[ "$fqdn" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$ ]]; then
|
||||||
|
export ${server^^}_FQDN="$fqdn"
|
||||||
|
attempt=0
|
||||||
|
break
|
||||||
|
else
|
||||||
|
msg_warn "Invalid domain format!"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if ((attempt >= MAX_ATTEMPTS)); then
|
||||||
|
msg_error "No more attempts - aborting script!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
msg_info "Installing Collabora Online"
|
||||||
|
curl -fsSL https://collaboraoffice.com/downloads/gpg/collaboraonline-release-keyring.gpg -o /etc/apt/keyrings/collaboraonline-release-keyring.gpg
|
||||||
|
cat <<EOF >/etc/apt/sources.list.d/colloboraonline.sources
|
||||||
|
Types: deb
|
||||||
|
URIs: https://www.collaboraoffice.com/repos/CollaboraOnline/CODE-deb
|
||||||
|
Suites: ./
|
||||||
|
Signed-By: /etc/apt/keyrings/collaboraonline-release-keyring.gpg
|
||||||
|
EOF
|
||||||
|
$STD apt-get update
|
||||||
|
$STD apt-get install -y coolwsd code-brand
|
||||||
|
systemctl stop coolwsd
|
||||||
|
mkdir -p /etc/systemd/system/coolwsd.service.d
|
||||||
|
cat <<EOF >/etc/systemd/system/coolwsd.service.d/override.conf
|
||||||
|
[Unit]
|
||||||
|
Before=opencloud-wopi.service
|
||||||
|
EOF
|
||||||
|
systemctl daemon-reload
|
||||||
|
COOLPASS="$(openssl rand -base64 36)"
|
||||||
|
$STD sudo -u cool coolconfig set-admin-password --user=admin --password="$COOLPASS"
|
||||||
|
echo "$COOLPASS" >~/.coolpass
|
||||||
|
msg_ok "Installed Collabora Online"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "opencloud" "opencloud-eu/opencloud" "singlefile" "v5.0.1" "/usr/bin" "opencloud-*-linux-amd64"
|
||||||
|
|
||||||
|
msg_info "Configuring OpenCloud"
|
||||||
|
DATA_DIR="/var/lib/opencloud/"
|
||||||
|
CONFIG_DIR="/etc/opencloud"
|
||||||
|
ENV_FILE="${CONFIG_DIR}/opencloud.env"
|
||||||
|
mkdir -p "$DATA_DIR" "$CONFIG_DIR"/assets/apps
|
||||||
|
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/opencloud-eu/opencloud-compose/refs/heads/main/config/opencloud/csp.yaml -o "$CONFIG_DIR"/csp.yaml
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/opencloud-eu/opencloud-compose/refs/heads/main/config/opencloud/proxy.yaml -o "$CONFIG_DIR"/proxy.yaml.bak
|
||||||
|
|
||||||
|
cat <<EOF >"$ENV_FILE"
|
||||||
|
OC_URL=https://${OPENCLOUD_FQDN}
|
||||||
|
OC_INSECURE=false
|
||||||
|
IDM_CREATE_DEMO_USERS=false
|
||||||
|
OC_LOG_LEVEL=warning
|
||||||
|
OC_CONFIG_DIR=${CONFIG_DIR}
|
||||||
|
OC_BASE_DATA_PATH=${DATA_DIR}
|
||||||
|
STORAGE_SYSTEM_OC_ROOT=${DATA_DIR}/storage/metadata
|
||||||
|
|
||||||
|
## Web
|
||||||
|
WEB_ASSET_CORE_PATH=${CONFIG_DIR}/web/assets
|
||||||
|
WEB_ASSET_APPS_PATH=${CONFIG_DIR}/web/assets/apps
|
||||||
|
WEB_UI_CONFIG_FILE=${CONFIG_DIR}/web/config.json
|
||||||
|
# WEB_ASSET_THEMES_PATH=${CONFIG_DIR}/web/assets/themes
|
||||||
|
# WEB_UI_THEME_PATH=
|
||||||
|
|
||||||
|
## Frontend
|
||||||
|
FRONTEND_DISABLE_RADICALE=true
|
||||||
|
FRONTEND_GROUPWARE_ENABLED=false
|
||||||
|
GRAPH_INCLUDE_OCM_SHAREES=true
|
||||||
|
|
||||||
|
## Proxy
|
||||||
|
PROXY_TLS=false
|
||||||
|
PROXY_CSP_CONFIG_FILE_LOCATION=${CONFIG_DIR}/csp.yaml
|
||||||
|
|
||||||
|
## Collaboration - requires VALID TLS
|
||||||
|
COLLABORA_DOMAIN=${COLLABORA_FQDN}
|
||||||
|
COLLABORATION_APP_NAME="CollaboraOnline"
|
||||||
|
COLLABORATION_APP_PRODUCT="Collabora"
|
||||||
|
COLLABORATION_APP_ADDR=https://${COLLABORA_FQDN}
|
||||||
|
COLLABORATION_APP_INSECURE=false
|
||||||
|
COLLABORATION_HTTP_ADDR=0.0.0.0:9300
|
||||||
|
COLLABORATION_WOPI_SRC=https://${WOPI_FQDN}
|
||||||
|
COLLABORATION_JWT_SECRET=
|
||||||
|
|
||||||
|
## Notifications - Email settings
|
||||||
|
# NOTIFICATIONS_SMTP_HOST=
|
||||||
|
# NOTIFICATIONS_SMTP_PORT=
|
||||||
|
# NOTIFICATIONS_SMTP_SENDER=
|
||||||
|
# NOTIFICATIONS_SMTP_USERNAME=
|
||||||
|
# NOTIFICATIONS_SMTP_PASSWORD=
|
||||||
|
# NOTIFICATIONS_SMTP_AUTHENTICATION=login
|
||||||
|
## Encryption method. Possible values are 'starttls', 'ssltls' and 'none'
|
||||||
|
# NOTIFICATIONS_SMTP_ENCRYPTION=starttls
|
||||||
|
## Allow insecure connections. Defaults to false.
|
||||||
|
# NOTIFICATIONS_SMTP_INSECURE=false
|
||||||
|
|
||||||
|
## Start additional services at runtime
|
||||||
|
## Examples: notifications, antivirus etc.
|
||||||
|
## Do not uncomment unless configured above.
|
||||||
|
# OC_ADD_RUN_SERVICES="notifications"
|
||||||
|
|
||||||
|
## OpenID - via web browser
|
||||||
|
## uncomment for OpenID in general
|
||||||
|
# OC_EXCLUDE_RUN_SERVICES=idp
|
||||||
|
# OC_OIDC_ISSUER=<your auth URL>
|
||||||
|
# IDP_DOMAIN=<your auth URL>
|
||||||
|
# PROXY_OIDC_ACCESS_TOKEN_VERIFY_METHOD=none
|
||||||
|
# PROXY_OIDC_REWRITE_WELLKNOWN=true
|
||||||
|
# PROXY_USER_OIDC_CLAIM=preferred_username
|
||||||
|
# PROXY_USER_CS3_CLAIM=username
|
||||||
|
## automatically create accounts
|
||||||
|
# PROXY_AUTOPROVISION_ACCOUNTS=true
|
||||||
|
# WEB_OIDC_SCOPE=openid profile email groups
|
||||||
|
# GRAPH_ASSIGN_DEFAULT_USER_ROLE=false
|
||||||
|
#
|
||||||
|
## uncomment below if using PocketID
|
||||||
|
# WEB_OIDC_CLIENT_ID=<generated in PocketID>
|
||||||
|
# WEB_OIDC_METADATA_URL=<your auth URL>/.well-known/openid-configuration
|
||||||
|
|
||||||
|
## Full Text Search - Apache Tika
|
||||||
|
## Requires a separate install of Tika - see https://community-scripts.github.io/ProxmoxVE/scripts?id=apache-tika
|
||||||
|
# SEARCH_EXTRACTOR_TYPE=tika
|
||||||
|
# FRONTEND_FULL_TEXT_SEARCH_ENABLED=true
|
||||||
|
# SEARCH_EXTRACTOR_TIKA_TIKA_URL=<your-tika-url>
|
||||||
|
|
||||||
|
## External storage test - Only NFS v4.2+ is supported
|
||||||
|
## User files
|
||||||
|
# STORAGE_USERS_POSIX_ROOT=<path-to-your-bind_mount>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF >/etc/systemd/system/opencloud.service
|
||||||
|
[Unit]
|
||||||
|
Description=OpenCloud server
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=opencloud
|
||||||
|
Group=opencloud
|
||||||
|
EnvironmentFile=${ENV_FILE}
|
||||||
|
ExecStart=/usr/bin/opencloud server
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF >/etc/systemd/system/opencloud-wopi.service
|
||||||
|
[Unit]
|
||||||
|
Description=OpenCloud WOPI Server
|
||||||
|
Wants=coolwsd.service
|
||||||
|
After=opencloud.service coolwsd.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=opencloud
|
||||||
|
Group=opencloud
|
||||||
|
EnvironmentFile=${ENV_FILE}
|
||||||
|
ExecStartPre=/bin/sleep 10
|
||||||
|
ExecStart=/usr/bin/opencloud collaboration server
|
||||||
|
Restart=always
|
||||||
|
KillSignal=SIGKILL
|
||||||
|
KillMode=mixed
|
||||||
|
TimeoutStopSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
$STD sudo -u cool coolconfig set ssl.enable false
|
||||||
|
$STD sudo -u cool coolconfig set ssl.termination true
|
||||||
|
$STD sudo -u cool coolconfig set ssl.ssl_verification true
|
||||||
|
sed -i "s|CSP2\"/>|CSP2\">frame-ancestors https://${OPENCLOUD_FQDN}</content_security_policy>|" /etc/coolwsd/coolwsd.xml
|
||||||
|
useradd -r -M -s /usr/sbin/nologin opencloud
|
||||||
|
chown -R opencloud:opencloud "$CONFIG_DIR" "$DATA_DIR"
|
||||||
|
sudo -u opencloud opencloud init --config-path "$CONFIG_DIR" --insecure no
|
||||||
|
OPENCLOUD_SECRET="$(sed -n '/jwt/p' "$CONFIG_DIR"/opencloud.yaml | awk '{print $2}')"
|
||||||
|
sed -i "s/JWT_SECRET=/&${OPENCLOUD_SECRET//&/\\&}/" "$ENV_FILE"
|
||||||
|
msg_ok "Configured OpenCloud"
|
||||||
|
|
||||||
|
msg_info "Starting services"
|
||||||
|
systemctl enable -q --now coolwsd opencloud
|
||||||
|
sleep 5
|
||||||
|
systemctl enable -q --now opencloud-wopi
|
||||||
|
msg_ok "Started services"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -23,7 +23,7 @@ msg_ok "Installed Dependencies"
|
|||||||
PG_VERSION=17 setup_postgresql
|
PG_VERSION=17 setup_postgresql
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
PG_DB_NAME="scanopy_db" PG_DB_USER="scanopy" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
PG_DB_NAME="scanopy_db" PG_DB_USER="scanopy" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
||||||
fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
fetch_and_deploy_gh_release "Scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
||||||
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
|
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
|
||||||
RUST_TOOLCHAIN=$TOOLCHAIN setup_rust
|
RUST_TOOLCHAIN=$TOOLCHAIN setup_rust
|
||||||
|
|
||||||
@@ -35,11 +35,11 @@ $STD npm ci --no-fund --no-audit
|
|||||||
$STD npm run build
|
$STD npm run build
|
||||||
msg_ok "Created frontend UI"
|
msg_ok "Created frontend UI"
|
||||||
|
|
||||||
msg_info "Building scanopy-server (patience)"
|
msg_info "Building Scanopy Server (patience)"
|
||||||
cd /opt/scanopy/backend
|
cd /opt/scanopy/backend
|
||||||
$STD cargo build --release --bin server
|
$STD cargo build --release --bin server
|
||||||
mv ./target/release/server /usr/bin/scanopy-server
|
mv ./target/release/server /usr/bin/scanopy-server
|
||||||
msg_ok "Built scanopy-server"
|
msg_ok "Built Scanopy Server"
|
||||||
|
|
||||||
msg_info "Configuring server for first-run"
|
msg_info "Configuring server for first-run"
|
||||||
cat <<EOF >/opt/scanopy/.env
|
cat <<EOF >/opt/scanopy/.env
|
||||||
|
|||||||
@@ -28,13 +28,210 @@
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# These can be overridden before sourcing this library
|
# These can be overridden before sourcing this library
|
||||||
|
|
||||||
|
# Disable 'unbound variable' errors for this library (restored at end)
|
||||||
|
_OLD_SET_STATE=$(set +o | grep -E 'set -(e|u|o)')
|
||||||
|
set +u
|
||||||
|
|
||||||
CLOUDINIT_DEFAULT_USER="${CLOUDINIT_DEFAULT_USER:-root}"
|
CLOUDINIT_DEFAULT_USER="${CLOUDINIT_DEFAULT_USER:-root}"
|
||||||
CLOUDINIT_DNS_SERVERS="${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}"
|
CLOUDINIT_DNS_SERVERS="${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}"
|
||||||
CLOUDINIT_SEARCH_DOMAIN="${CLOUDINIT_SEARCH_DOMAIN:-local}"
|
CLOUDINIT_SEARCH_DOMAIN="${CLOUDINIT_SEARCH_DOMAIN:-local}"
|
||||||
CLOUDINIT_SSH_KEYS="${CLOUDINIT_SSH_KEYS:-/root/.ssh/authorized_keys}"
|
CLOUDINIT_SSH_KEYS="${CLOUDINIT_SSH_KEYS:-}" # Empty by default - user must explicitly provide keys
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 2: HELPER FUNCTIONS
|
# SECTION 2: SSH KEY DISCOVERY AND SELECTION
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# _ci_ssh_extract_keys_from_file - Extracts valid SSH public keys from a file
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
function _ci_ssh_extract_keys_from_file() {
|
||||||
|
local file="$1"
|
||||||
|
[[ -f "$file" && -r "$file" ]] || return 0
|
||||||
|
grep -E '^(ssh-(rsa|ed25519|dss|ecdsa)|ecdsa-sha2-)' "$file" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# _ci_ssh_discover_files - Scans standard paths for SSH keys
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
function _ci_ssh_discover_files() {
|
||||||
|
local -a cand=()
|
||||||
|
shopt -s nullglob
|
||||||
|
cand+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2)
|
||||||
|
cand+=(/root/.ssh/*.pub)
|
||||||
|
cand+=(/etc/ssh/authorized_keys /etc/ssh/authorized_keys.d/*)
|
||||||
|
shopt -u nullglob
|
||||||
|
printf '%s\0' "${cand[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# _ci_ssh_build_choices - Builds whiptail checklist from SSH key files
|
||||||
|
#
|
||||||
|
# Sets: CI_SSH_CHOICES (array), CI_SSH_COUNT (int), CI_SSH_MAPFILE (path)
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
function _ci_ssh_build_choices() {
|
||||||
|
local -a files=("$@")
|
||||||
|
CI_SSH_CHOICES=()
|
||||||
|
CI_SSH_COUNT=0
|
||||||
|
CI_SSH_MAPFILE="$(mktemp)"
|
||||||
|
local id key typ fp cmt base
|
||||||
|
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
[[ -f "$f" && -r "$f" ]] || continue
|
||||||
|
base="$(basename -- "$f")"
|
||||||
|
# Skip known_hosts and private keys
|
||||||
|
case "$base" in
|
||||||
|
known_hosts | known_hosts.* | config) continue ;;
|
||||||
|
id_*) [[ "$f" != *.pub ]] && continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
while IFS= read -r key; do
|
||||||
|
[[ -n "$key" ]] || continue
|
||||||
|
|
||||||
|
typ=""
|
||||||
|
fp=""
|
||||||
|
cmt=""
|
||||||
|
read -r _typ _b64 _cmt <<<"$key"
|
||||||
|
typ="${_typ:-key}"
|
||||||
|
cmt="${_cmt:-}"
|
||||||
|
|
||||||
|
# Get fingerprint via ssh-keygen if available
|
||||||
|
if command -v ssh-keygen >/dev/null 2>&1; then
|
||||||
|
fp="$(printf '%s\n' "$key" | ssh-keygen -lf - 2>/dev/null | awk '{print $2}')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Shorten long comments
|
||||||
|
[[ ${#cmt} -gt 40 ]] && cmt="${cmt:0:37}..."
|
||||||
|
|
||||||
|
CI_SSH_COUNT=$((CI_SSH_COUNT + 1))
|
||||||
|
id="K${CI_SSH_COUNT}"
|
||||||
|
echo "${id}|${key}" >>"$CI_SSH_MAPFILE"
|
||||||
|
CI_SSH_CHOICES+=("$id" "[$typ] ${fp:+$fp }${cmt:+$cmt }— ${base}" "OFF")
|
||||||
|
done < <(_ci_ssh_extract_keys_from_file "$f")
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# configure_cloudinit_ssh_keys - Interactive SSH key selection for Cloud-Init
|
||||||
|
#
|
||||||
|
# Usage: configure_cloudinit_ssh_keys
|
||||||
|
# Sets: CLOUDINIT_SSH_KEYS (path to temporary file with selected keys)
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
function configure_cloudinit_ssh_keys() {
|
||||||
|
local backtitle="Proxmox VE Helper Scripts"
|
||||||
|
local ssh_key_mode
|
||||||
|
|
||||||
|
# Create temp file for selected keys
|
||||||
|
CLOUDINIT_SSH_KEYS_TEMP="$(mktemp)"
|
||||||
|
: >"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||||
|
|
||||||
|
# Discover keys and build choices
|
||||||
|
IFS=$'\0' read -r -d '' -a _def_files < <(_ci_ssh_discover_files && printf '\0')
|
||||||
|
_ci_ssh_build_choices "${_def_files[@]}"
|
||||||
|
local default_key_count="$CI_SSH_COUNT"
|
||||||
|
|
||||||
|
if [[ "$default_key_count" -gt 0 ]]; then
|
||||||
|
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
|
||||||
|
"Provision SSH keys for Cloud-Init VM:" 14 72 4 \
|
||||||
|
"found" "Select from detected keys (${default_key_count})" \
|
||||||
|
"manual" "Paste a single public key" \
|
||||||
|
"folder" "Scan another folder (path or glob)" \
|
||||||
|
"none" "No SSH keys (password auth only)" 3>&1 1>&2 2>&3) || return 1
|
||||||
|
else
|
||||||
|
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
|
||||||
|
"No host keys detected. Choose:" 12 72 3 \
|
||||||
|
"manual" "Paste a single public key" \
|
||||||
|
"folder" "Scan another folder (path or glob)" \
|
||||||
|
"none" "No SSH keys (password auth only)" 3>&1 1>&2 2>&3) || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$ssh_key_mode" in
|
||||||
|
found)
|
||||||
|
# Show checklist with individual keys
|
||||||
|
local selection
|
||||||
|
selection=$(whiptail --backtitle "$backtitle" --title "SELECT SSH KEYS" \
|
||||||
|
--checklist "Select one or more keys to import:" 20 140 10 "${CI_SSH_CHOICES[@]}" 3>&1 1>&2 2>&3) || return 1
|
||||||
|
|
||||||
|
for tag in $selection; do
|
||||||
|
tag="${tag%\"}"
|
||||||
|
tag="${tag#\"}"
|
||||||
|
local line
|
||||||
|
line=$(grep -E "^${tag}\|" "$CI_SSH_MAPFILE" | head -n1 | cut -d'|' -f2-)
|
||||||
|
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||||
|
done
|
||||||
|
local imported
|
||||||
|
imported=$(wc -l <"$CLOUDINIT_SSH_KEYS_TEMP")
|
||||||
|
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}${imported} key(s) selected${CL}"
|
||||||
|
;;
|
||||||
|
manual)
|
||||||
|
local pubkey
|
||||||
|
pubkey=$(whiptail --backtitle "$backtitle" --title "PASTE SSH PUBLIC KEY" \
|
||||||
|
--inputbox "Paste your SSH public key (ssh-rsa, ssh-ed25519, etc.):" 10 76 3>&1 1>&2 2>&3) || return 1
|
||||||
|
if [[ -n "$pubkey" ]]; then
|
||||||
|
echo "$pubkey" >"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||||
|
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}1 key added manually${CL}"
|
||||||
|
else
|
||||||
|
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}none (empty input)${CL}"
|
||||||
|
CLOUDINIT_SSH_KEYS=""
|
||||||
|
rm -f "$CLOUDINIT_SSH_KEYS_TEMP" "$CI_SSH_MAPFILE" 2>/dev/null
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
folder)
|
||||||
|
local glob_path
|
||||||
|
glob_path=$(whiptail --backtitle "$backtitle" --title "SCAN FOLDER/GLOB" \
|
||||||
|
--inputbox "Enter a folder or glob to scan (e.g. /root/.ssh/*.pub):" 10 72 3>&1 1>&2 2>&3) || return 1
|
||||||
|
if [[ -n "$glob_path" ]]; then
|
||||||
|
shopt -s nullglob
|
||||||
|
local -a _scan_files=($glob_path)
|
||||||
|
shopt -u nullglob
|
||||||
|
if [[ "${#_scan_files[@]}" -gt 0 ]]; then
|
||||||
|
_ci_ssh_build_choices "${_scan_files[@]}"
|
||||||
|
if [[ "$CI_SSH_COUNT" -gt 0 ]]; then
|
||||||
|
local folder_selection
|
||||||
|
folder_selection=$(whiptail --backtitle "$backtitle" --title "SELECT FOLDER KEYS" \
|
||||||
|
--checklist "Select key(s) to import:" 20 140 10 "${CI_SSH_CHOICES[@]}" 3>&1 1>&2 2>&3) || return 1
|
||||||
|
for tag in $folder_selection; do
|
||||||
|
tag="${tag%\"}"
|
||||||
|
tag="${tag#\"}"
|
||||||
|
local line
|
||||||
|
line=$(grep -E "^${tag}\|" "$CI_SSH_MAPFILE" | head -n1 | cut -d'|' -f2-)
|
||||||
|
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$CLOUDINIT_SSH_KEYS_TEMP"
|
||||||
|
done
|
||||||
|
local imported
|
||||||
|
imported=$(wc -l <"$CLOUDINIT_SSH_KEYS_TEMP")
|
||||||
|
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}${imported} key(s) from folder${CL}"
|
||||||
|
else
|
||||||
|
whiptail --backtitle "$backtitle" --msgbox "No keys found in: $glob_path" 8 60
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
whiptail --backtitle "$backtitle" --msgbox "Path/glob returned no files." 8 60
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
none | *)
|
||||||
|
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}none (password auth only)${CL}"
|
||||||
|
CLOUDINIT_SSH_KEYS=""
|
||||||
|
rm -f "$CLOUDINIT_SSH_KEYS_TEMP" "$CI_SSH_MAPFILE" 2>/dev/null
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Cleanup mapfile
|
||||||
|
rm -f "$CI_SSH_MAPFILE" 2>/dev/null
|
||||||
|
|
||||||
|
# Set the variable for setup_cloud_init to use
|
||||||
|
if [[ -s "$CLOUDINIT_SSH_KEYS_TEMP" ]]; then
|
||||||
|
CLOUDINIT_SSH_KEYS="$CLOUDINIT_SSH_KEYS_TEMP"
|
||||||
|
else
|
||||||
|
CLOUDINIT_SSH_KEYS=""
|
||||||
|
rm -f "$CLOUDINIT_SSH_KEYS_TEMP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# SECTION 3: HELPER FUNCTIONS
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -144,9 +341,10 @@ function setup_cloud_init() {
|
|||||||
local cipassword=$(openssl rand -base64 16)
|
local cipassword=$(openssl rand -base64 16)
|
||||||
qm set "$vmid" --cipassword "$cipassword" >/dev/null
|
qm set "$vmid" --cipassword "$cipassword" >/dev/null
|
||||||
|
|
||||||
# Add SSH keys if available
|
# Add SSH keys only if explicitly provided (not auto-imported from host)
|
||||||
if [ -f "$CLOUDINIT_SSH_KEYS" ]; then
|
if [ -n "${CLOUDINIT_SSH_KEYS:-}" ] && [ -f "$CLOUDINIT_SSH_KEYS" ]; then
|
||||||
qm set "$vmid" --sshkeys "$CLOUDINIT_SSH_KEYS" >/dev/null 2>&1 || true
|
qm set "$vmid" --sshkeys "$CLOUDINIT_SSH_KEYS" >/dev/null 2>&1 || true
|
||||||
|
_ci_msg_info "SSH keys imported from: $CLOUDINIT_SSH_KEYS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Configure network
|
# Configure network
|
||||||
@@ -459,6 +657,11 @@ export -f wait_for_cloud_init 2>/dev/null || true
|
|||||||
export -f validate_ip_cidr 2>/dev/null || true
|
export -f validate_ip_cidr 2>/dev/null || true
|
||||||
export -f validate_ip 2>/dev/null || true
|
export -f validate_ip 2>/dev/null || true
|
||||||
|
|
||||||
|
# Restore previous shell options if they were saved
|
||||||
|
if [ -n "${_OLD_SET_STATE:-}" ]; then
|
||||||
|
eval "$_OLD_SET_STATE"
|
||||||
|
fi
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 7: EXAMPLES & DOCUMENTATION
|
# SECTION 7: EXAMPLES & DOCUMENTATION
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|||||||
6
tools/headers/immich-public-proxy
Normal file
6
tools/headers/immich-public-proxy
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
____ _ __ ____ __ ___ ____
|
||||||
|
/ _/___ ___ ____ ___ (_)____/ /_ / __ \__ __/ /_ / (_)____ / __ \_________ _ ____ __
|
||||||
|
/ // __ `__ \/ __ `__ \/ / ___/ __ \ / /_/ / / / / __ \/ / / ___/ / /_/ / ___/ __ \| |/_/ / / /
|
||||||
|
_/ // / / / / / / / / / / / /__/ / / / / ____/ /_/ / /_/ / / / /__ / ____/ / / /_/ /> </ /_/ /
|
||||||
|
/___/_/ /_/ /_/_/ /_/ /_/_/\___/_/ /_/ /_/ \__,_/_.___/_/_/\___/ /_/ /_/ \____/_/|_|\__, /
|
||||||
|
/____/
|
||||||
732
vm/docker-vm.sh
732
vm/docker-vm.sh
@@ -1,71 +1,45 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: thost96 (thost96) | Co-Author: michelroegl-brunner
|
# Author: thost96 (thost96) | michelroegl-brunner | MickLesk
|
||||||
# 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)
|
# ==============================================================================
|
||||||
|
# Docker VM - Creates a Docker-ready Virtual Machine
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
function header_info() {
|
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/api.func) 2>/dev/null
|
||||||
clear
|
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/vm-core.func) 2>/dev/null
|
||||||
cat <<"EOF"
|
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/cloud-init.func) 2>/dev/null || true
|
||||||
____ __ _ ____ ___
|
load_functions
|
||||||
/ __ \____ _____/ /_____ _____ | | / / |/ /
|
|
||||||
/ / / / __ \/ ___/ //_/ _ \/ ___/ | | / / /|_/ /
|
# ==============================================================================
|
||||||
/ /_/ / /_/ / /__/ ,< / __/ / | |/ / / / /
|
# SCRIPT VARIABLES
|
||||||
/_____/\____/\___/_/|_|\___/_/ |___/_/ /_/
|
# ==============================================================================
|
||||||
|
APP="Docker"
|
||||||
|
APP_TYPE="vm"
|
||||||
|
NSAPP="docker-vm"
|
||||||
|
var_os="debian"
|
||||||
|
var_version="13"
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
header_info
|
|
||||||
echo -e "\n Loading..."
|
|
||||||
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
|
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
|
||||||
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
||||||
METHOD=""
|
METHOD=""
|
||||||
NSAPP="docker-vm"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="12"
|
|
||||||
DISK_SIZE="10G"
|
DISK_SIZE="10G"
|
||||||
|
USE_CLOUD_INIT="no"
|
||||||
YW=$(echo "\033[33m")
|
OS_TYPE=""
|
||||||
BL=$(echo "\033[36m")
|
OS_VERSION=""
|
||||||
RD=$(echo "\033[01;31m")
|
|
||||||
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}"
|
|
||||||
CLOUD="${TAB}☁️${TAB}${CL}"
|
|
||||||
|
|
||||||
THIN="discard=on,ssd=1,"
|
THIN="discard=on,ssd=1,"
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# ERROR HANDLING & CLEANUP
|
||||||
|
# ==============================================================================
|
||||||
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" "INTERRUPTED"' SIGINT
|
trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT
|
||||||
trap 'post_update_to_api "failed" "TERMINATED"' 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"
|
||||||
@@ -76,140 +50,96 @@ function error_handler() {
|
|||||||
cleanup_vmid
|
cleanup_vmid
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_valid_nextid() {
|
# ==============================================================================
|
||||||
local try_id
|
# OS SELECTION FUNCTIONS
|
||||||
try_id=$(pvesh get /cluster/nextid)
|
# ==============================================================================
|
||||||
while true; do
|
function select_os() {
|
||||||
if [ -f "/etc/pve/qemu-server/${try_id}.conf" ] || [ -f "/etc/pve/lxc/${try_id}.conf" ]; then
|
if OS_CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SELECT OS" --radiolist \
|
||||||
try_id=$((try_id + 1))
|
"Choose Operating System for Docker VM" 14 68 4 \
|
||||||
continue
|
"debian13" "Debian 13 (Trixie) - Latest" ON \
|
||||||
|
"debian12" "Debian 12 (Bookworm) - Stable" OFF \
|
||||||
|
"ubuntu2404" "Ubuntu 24.04 LTS (Noble)" OFF \
|
||||||
|
"ubuntu2204" "Ubuntu 22.04 LTS (Jammy)" OFF \
|
||||||
|
3>&1 1>&2 2>&3); then
|
||||||
|
case $OS_CHOICE in
|
||||||
|
debian13)
|
||||||
|
OS_TYPE="debian"
|
||||||
|
OS_VERSION="13"
|
||||||
|
OS_CODENAME="trixie"
|
||||||
|
OS_DISPLAY="Debian 13 (Trixie)"
|
||||||
|
;;
|
||||||
|
debian12)
|
||||||
|
OS_TYPE="debian"
|
||||||
|
OS_VERSION="12"
|
||||||
|
OS_CODENAME="bookworm"
|
||||||
|
OS_DISPLAY="Debian 12 (Bookworm)"
|
||||||
|
;;
|
||||||
|
ubuntu2404)
|
||||||
|
OS_TYPE="ubuntu"
|
||||||
|
OS_VERSION="24.04"
|
||||||
|
OS_CODENAME="noble"
|
||||||
|
OS_DISPLAY="Ubuntu 24.04 LTS"
|
||||||
|
;;
|
||||||
|
ubuntu2204)
|
||||||
|
OS_TYPE="ubuntu"
|
||||||
|
OS_VERSION="22.04"
|
||||||
|
OS_CODENAME="jammy"
|
||||||
|
OS_DISPLAY="Ubuntu 22.04 LTS"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}${OS_DISPLAY}${CL}"
|
||||||
|
else
|
||||||
|
exit_script
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function select_cloud_init() {
|
||||||
|
if [ "$OS_TYPE" = "ubuntu" ]; then
|
||||||
|
USE_CLOUD_INIT="yes"
|
||||||
|
echo -e "${CLOUD:-${TAB}☁️${TAB}${CL}}${BOLD}${DGN}Cloud-Init: ${BGN}yes (Ubuntu requires Cloud-Init)${CL}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "CLOUD-INIT" \
|
||||||
|
--yesno "Enable Cloud-Init for VM configuration?\n\nCloud-Init allows automatic configuration of:\n- User accounts and passwords\n- SSH keys\n- Network settings (DHCP/Static)\n- DNS configuration\n\nYou can also configure these settings later in Proxmox UI.\n\nNote: Debian without Cloud-Init will use nocloud image with console auto-login." 18 68); then
|
||||||
|
USE_CLOUD_INIT="yes"
|
||||||
|
echo -e "${CLOUD:-${TAB}☁️${TAB}${CL}}${BOLD}${DGN}Cloud-Init: ${BGN}yes${CL}"
|
||||||
|
else
|
||||||
|
USE_CLOUD_INIT="no"
|
||||||
|
echo -e "${CLOUD:-${TAB}☁️${TAB}${CL}}${BOLD}${DGN}Cloud-Init: ${BGN}no${CL}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_image_url() {
|
||||||
|
local arch=$(dpkg --print-architecture)
|
||||||
|
case $OS_TYPE in
|
||||||
|
debian)
|
||||||
|
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
||||||
|
echo "https://cloud.debian.org/images/cloud/${OS_CODENAME}/latest/debian-${OS_VERSION}-generic-${arch}.qcow2"
|
||||||
|
else
|
||||||
|
echo "https://cloud.debian.org/images/cloud/${OS_CODENAME}/latest/debian-${OS_VERSION}-nocloud-${arch}.qcow2"
|
||||||
fi
|
fi
|
||||||
if lvs --noheadings -o lv_name | grep -qE "(^|[-_])${try_id}($|[-_])"; then
|
;;
|
||||||
try_id=$((try_id + 1))
|
ubuntu)
|
||||||
continue
|
echo "https://cloud-images.ubuntu.com/${OS_CODENAME}/current/${OS_CODENAME}-server-cloudimg-${arch}.img"
|
||||||
fi
|
;;
|
||||||
break
|
esac
|
||||||
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() {
|
|
||||||
popd >/dev/null
|
|
||||||
post_update_to_api "done" "none"
|
|
||||||
rm -rf $TEMP_DIR
|
|
||||||
}
|
|
||||||
|
|
||||||
TEMP_DIR=$(mktemp -d)
|
|
||||||
pushd $TEMP_DIR >/dev/null
|
|
||||||
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Docker VM" --yesno "This will create a New Docker VM. Proceed?" 10 58; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
header_info && echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
|
|
||||||
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"
|
|
||||||
exit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# SETTINGS FUNCTIONS
|
||||||
|
# ==============================================================================
|
||||||
function default_settings() {
|
function default_settings() {
|
||||||
|
select_os
|
||||||
|
select_cloud_init
|
||||||
|
|
||||||
VMID=$(get_valid_nextid)
|
VMID=$(get_valid_nextid)
|
||||||
FORMAT=",efitype=4m"
|
FORMAT=""
|
||||||
MACHINE=""
|
MACHINE=" -machine q35"
|
||||||
DISK_CACHE=""
|
DISK_CACHE=""
|
||||||
DISK_SIZE="10G"
|
DISK_SIZE="10G"
|
||||||
HN="docker"
|
HN="docker"
|
||||||
CPU_TYPE=""
|
CPU_TYPE=" -cpu host"
|
||||||
CORE_COUNT="2"
|
CORE_COUNT="2"
|
||||||
RAM_SIZE="4096"
|
RAM_SIZE="4096"
|
||||||
BRG="vmbr0"
|
BRG="vmbr0"
|
||||||
@@ -218,12 +148,13 @@ function default_settings() {
|
|||||||
MTU=""
|
MTU=""
|
||||||
START_VM="yes"
|
START_VM="yes"
|
||||||
METHOD="default"
|
METHOD="default"
|
||||||
|
|
||||||
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
|
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
|
||||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}"
|
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}Q35 (Modern)${CL}"
|
||||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
|
||||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
|
||||||
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
|
||||||
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
|
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
||||||
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${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 "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
|
||||||
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
|
||||||
@@ -231,12 +162,22 @@ function default_settings() {
|
|||||||
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
|
||||||
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
|
||||||
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
||||||
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above default settings${CL}"
|
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above settings${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function advanced_settings() {
|
function advanced_settings() {
|
||||||
|
select_os
|
||||||
|
select_cloud_init
|
||||||
|
|
||||||
|
# SSH Key selection for Cloud-Init VMs
|
||||||
|
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
||||||
|
configure_cloudinit_ssh_keys || true
|
||||||
|
fi
|
||||||
|
|
||||||
METHOD="advanced"
|
METHOD="advanced"
|
||||||
[ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
|
[ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
|
||||||
|
|
||||||
|
# VM ID
|
||||||
while true; do
|
while true; do
|
||||||
if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $VMID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $VMID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z "$VMID" ]; then
|
if [ -z "$VMID" ]; then
|
||||||
@@ -250,27 +191,29 @@ 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
|
||||||
|
|
||||||
|
# Machine Type
|
||||||
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
|
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
|
||||||
"i440fx" "Machine i440fx" ON \
|
"q35" "Q35 (Modern, PCIe)" ON \
|
||||||
"q35" "Machine q35" OFF \
|
"i440fx" "i440fx (Legacy, PCI)" OFF \
|
||||||
3>&1 1>&2 2>&3); then
|
3>&1 1>&2 2>&3); then
|
||||||
if [ $MACH = q35 ]; then
|
if [ $MACH = q35 ]; then
|
||||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
|
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}Q35 (Modern)${CL}"
|
||||||
FORMAT=""
|
FORMAT=""
|
||||||
MACHINE=" -machine q35"
|
MACHINE=" -machine q35"
|
||||||
else
|
else
|
||||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
|
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx (Legacy)${CL}"
|
||||||
FORMAT=",efitype=4m"
|
FORMAT=",efitype=4m"
|
||||||
MACHINE=""
|
MACHINE=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Disk Size
|
||||||
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 "$DISK_SIZE" --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
|
||||||
@@ -280,12 +223,13 @@ 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
|
||||||
|
|
||||||
|
# Disk Cache
|
||||||
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 \
|
||||||
"0" "None (Default)" ON \
|
"0" "None (Default)" ON \
|
||||||
"1" "Write Through" OFF \
|
"1" "Write Through" OFF \
|
||||||
@@ -298,24 +242,25 @@ function advanced_settings() {
|
|||||||
DISK_CACHE=""
|
DISK_CACHE=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Hostname
|
||||||
if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 docker --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 docker --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $VM_NAME ]; then
|
if [ -z $VM_NAME ]; then
|
||||||
HN="docker"
|
HN="docker"
|
||||||
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
|
||||||
else
|
else
|
||||||
HN=$(echo ${VM_NAME,,} | tr -d ' ')
|
HN=$(echo ${VM_NAME,,} | tr -d ' ')
|
||||||
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
|
||||||
fi
|
fi
|
||||||
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# CPU Model
|
||||||
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 \
|
||||||
"0" "KVM64 (Default)" ON \
|
"1" "Host (Recommended)" ON \
|
||||||
"1" "Host" OFF \
|
"0" "KVM64" OFF \
|
||||||
3>&1 1>&2 2>&3); then
|
3>&1 1>&2 2>&3); then
|
||||||
if [ $CPU_TYPE1 = "1" ]; then
|
if [ $CPU_TYPE1 = "1" ]; then
|
||||||
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
||||||
@@ -325,80 +270,78 @@ function advanced_settings() {
|
|||||||
CPU_TYPE=""
|
CPU_TYPE=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# CPU Cores
|
||||||
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $CORE_COUNT ]; then
|
if [ -z $CORE_COUNT ]; then
|
||||||
CORE_COUNT="2"
|
CORE_COUNT="2"
|
||||||
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
|
|
||||||
else
|
|
||||||
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
|
|
||||||
fi
|
fi
|
||||||
|
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
# RAM Size
|
||||||
|
if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $RAM_SIZE ]; then
|
if [ -z $RAM_SIZE ]; then
|
||||||
RAM_SIZE="2048"
|
RAM_SIZE="4096"
|
||||||
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
|
|
||||||
else
|
|
||||||
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
|
|
||||||
fi
|
fi
|
||||||
|
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Bridge
|
||||||
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"
|
BRG="vmbr0"
|
||||||
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
|
||||||
else
|
|
||||||
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
|
||||||
fi
|
fi
|
||||||
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# MAC Address
|
||||||
if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $MAC1 ]; then
|
if [ -z $MAC1 ]; then
|
||||||
MAC="$GEN_MAC"
|
MAC="$GEN_MAC"
|
||||||
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
|
|
||||||
else
|
else
|
||||||
MAC="$MAC1"
|
MAC="$MAC1"
|
||||||
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}"
|
|
||||||
fi
|
fi
|
||||||
|
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
# VLAN
|
||||||
|
if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan (leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $VLAN1 ]; then
|
if [ -z $VLAN1 ]; then
|
||||||
VLAN1="Default"
|
VLAN1="Default"
|
||||||
VLAN=""
|
VLAN=""
|
||||||
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
|
||||||
else
|
else
|
||||||
VLAN=",tag=$VLAN1"
|
VLAN=",tag=$VLAN1"
|
||||||
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
|
||||||
fi
|
fi
|
||||||
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# MTU
|
||||||
if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $MTU1 ]; then
|
if [ -z $MTU1 ]; then
|
||||||
MTU1="Default"
|
MTU1="Default"
|
||||||
MTU=""
|
MTU=""
|
||||||
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
|
||||||
else
|
else
|
||||||
MTU=",mtu=$MTU1"
|
MTU=",mtu=$MTU1"
|
||||||
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
|
||||||
fi
|
fi
|
||||||
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
||||||
else
|
else
|
||||||
exit-script
|
exit_script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Start VM
|
||||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then
|
||||||
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
||||||
START_VM="yes"
|
START_VM="yes"
|
||||||
@@ -407,6 +350,7 @@ function advanced_settings() {
|
|||||||
START_VM="no"
|
START_VM="no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Confirm
|
||||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Docker VM?" --no-button Do-Over 10 58); then
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Docker VM?" --no-button Do-Over 10 58); then
|
||||||
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above advanced settings${CL}"
|
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above advanced settings${CL}"
|
||||||
else
|
else
|
||||||
@@ -427,13 +371,28 @@ function start_script() {
|
|||||||
advanced_settings
|
advanced_settings
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# MAIN EXECUTION
|
||||||
|
# ==============================================================================
|
||||||
|
header_info
|
||||||
|
|
||||||
check_root
|
check_root
|
||||||
arch_check
|
arch_check
|
||||||
pve_check
|
pve_check
|
||||||
ssh_check
|
|
||||||
|
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Docker VM" --yesno "This will create a New Docker VM. Proceed?" 10 58; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
header_info && echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
|
||||||
|
fi
|
||||||
|
|
||||||
start_script
|
start_script
|
||||||
post_to_api_vm
|
post_to_api_vm
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# STORAGE SELECTION
|
||||||
|
# ==============================================================================
|
||||||
msg_info "Validating Storage"
|
msg_info "Validating Storage"
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
TAG=$(echo $line | awk '{print $1}')
|
TAG=$(echo $line | awk '{print $1}')
|
||||||
@@ -446,6 +405,7 @@ while read -r line; do
|
|||||||
fi
|
fi
|
||||||
STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
|
STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
|
||||||
done < <(pvesm status -content images | awk 'NR>1')
|
done < <(pvesm status -content images | awk 'NR>1')
|
||||||
|
|
||||||
VALID=$(pvesm status -content images | awk 'NR>1')
|
VALID=$(pvesm status -content images | awk 'NR>1')
|
||||||
if [ -z "$VALID" ]; then
|
if [ -z "$VALID" ]; then
|
||||||
msg_error "Unable to detect a valid storage location."
|
msg_error "Unable to detect a valid storage location."
|
||||||
@@ -453,6 +413,8 @@ if [ -z "$VALID" ]; then
|
|||||||
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
|
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
|
||||||
STORAGE=${STORAGE_MENU[0]}
|
STORAGE=${STORAGE_MENU[0]}
|
||||||
else
|
else
|
||||||
|
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
|
||||||
|
printf "\e[?25h"
|
||||||
while [ -z "${STORAGE:+x}" ]; do
|
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" \
|
||||||
@@ -462,112 +424,288 @@ else
|
|||||||
fi
|
fi
|
||||||
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}."
|
||||||
msg_info "Retrieving the URL for the Debian 12 Qcow2 Disk Image"
|
|
||||||
URL="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-$(dpkg --print-architecture).qcow2"
|
|
||||||
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}"
|
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# PREREQUISITES
|
||||||
|
# ==============================================================================
|
||||||
|
if ! command -v virt-customize &>/dev/null; then
|
||||||
|
msg_info "Installing libguestfs-tools"
|
||||||
|
apt-get -qq update >/dev/null
|
||||||
|
apt-get -qq install libguestfs-tools lsb-release -y >/dev/null
|
||||||
|
apt-get -qq install dhcpcd-base -y >/dev/null 2>&1 || true
|
||||||
|
msg_ok "Installed libguestfs-tools"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# IMAGE DOWNLOAD
|
||||||
|
# ==============================================================================
|
||||||
|
msg_info "Retrieving the URL for the ${OS_DISPLAY} Qcow2 Disk Image"
|
||||||
|
URL=$(get_image_url)
|
||||||
|
CACHE_DIR="/var/lib/vz/template/cache"
|
||||||
|
CACHE_FILE="$CACHE_DIR/$(basename "$URL")"
|
||||||
|
mkdir -p "$CACHE_DIR"
|
||||||
|
msg_ok "${CL}${BL}${URL}${CL}"
|
||||||
|
|
||||||
|
if [[ ! -s "$CACHE_FILE" ]]; then
|
||||||
|
curl -f#SL -o "$CACHE_FILE" "$URL"
|
||||||
|
echo -en "\e[1A\e[0K"
|
||||||
|
msg_ok "Downloaded ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
|
||||||
|
else
|
||||||
|
msg_ok "Using cached image ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# STORAGE TYPE DETECTION
|
||||||
|
# ==============================================================================
|
||||||
STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
|
STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
|
||||||
case $STORAGE_TYPE in
|
case $STORAGE_TYPE in
|
||||||
nfs | dir)
|
nfs | dir)
|
||||||
DISK_EXT=".qcow2"
|
DISK_EXT=".qcow2"
|
||||||
DISK_REF="$VMID/"
|
DISK_REF="$VMID/"
|
||||||
DISK_IMPORT="-format qcow2"
|
DISK_IMPORT="--format qcow2"
|
||||||
THIN=""
|
THIN=""
|
||||||
;;
|
;;
|
||||||
btrfs)
|
btrfs)
|
||||||
DISK_EXT=".raw"
|
DISK_EXT=".raw"
|
||||||
DISK_REF="$VMID/"
|
DISK_REF="$VMID/"
|
||||||
DISK_IMPORT="-format raw"
|
DISK_IMPORT="--format raw"
|
||||||
FORMAT=",efitype=4m"
|
FORMAT=",efitype=4m"
|
||||||
THIN=""
|
THIN=""
|
||||||
;;
|
;;
|
||||||
|
*)
|
||||||
|
DISK_EXT=""
|
||||||
|
DISK_REF=""
|
||||||
|
DISK_IMPORT="--format raw"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
for i in {0,1}; do
|
|
||||||
disk="DISK$i"
|
# ==============================================================================
|
||||||
eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}
|
# IMAGE CUSTOMIZATION WITH DOCKER
|
||||||
eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}
|
# ==============================================================================
|
||||||
|
msg_info "Preparing ${OS_DISPLAY} image with Docker"
|
||||||
|
|
||||||
|
WORK_FILE=$(mktemp --suffix=.qcow2)
|
||||||
|
cp "$CACHE_FILE" "$WORK_FILE"
|
||||||
|
|
||||||
|
export LIBGUESTFS_BACKEND_SETTINGS=dns=8.8.8.8,1.1.1.1
|
||||||
|
|
||||||
|
DOCKER_PREINSTALLED="no"
|
||||||
|
|
||||||
|
# Install qemu-guest-agent and Docker during image customization
|
||||||
|
msg_info "Installing base packages in image"
|
||||||
|
if virt-customize -a "$WORK_FILE" --install qemu-guest-agent,curl,ca-certificates >/dev/null 2>&1; then
|
||||||
|
msg_ok "Installed base packages"
|
||||||
|
|
||||||
|
msg_info "Installing Docker (this may take 2-5 minutes)"
|
||||||
|
if virt-customize -q -a "$WORK_FILE" --run-command "curl -fsSL https://get.docker.com | sh" >/dev/null 2>&1 &&
|
||||||
|
virt-customize -q -a "$WORK_FILE" --run-command "systemctl enable docker" >/dev/null 2>&1; then
|
||||||
|
msg_ok "Installed Docker"
|
||||||
|
|
||||||
|
msg_info "Configuring Docker daemon"
|
||||||
|
# Optimize Docker daemon configuration
|
||||||
|
virt-customize -q -a "$WORK_FILE" --run-command "mkdir -p /etc/docker" >/dev/null 2>&1
|
||||||
|
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/docker/daemon.json << EOF
|
||||||
|
{
|
||||||
|
"storage-driver": "overlay2",
|
||||||
|
"log-driver": "json-file",
|
||||||
|
"log-opts": {
|
||||||
|
"max-size": "10m",
|
||||||
|
"max-file": "3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF' >/dev/null 2>&1
|
||||||
|
DOCKER_PREINSTALLED="yes"
|
||||||
|
msg_ok "Configured Docker daemon"
|
||||||
|
else
|
||||||
|
msg_ok "Docker will be installed on first boot"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
msg_ok "Packages will be installed on first boot"
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Finalizing image (hostname, SSH config)"
|
||||||
|
# Set hostname and prepare for unique machine-id
|
||||||
|
virt-customize -q -a "$WORK_FILE" --hostname "${HN}" >/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
|
||||||
|
|
||||||
|
# Configure SSH for Cloud-Init
|
||||||
|
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
||||||
|
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
|
||||||
|
else
|
||||||
|
# Configure auto-login for nocloud images (no Cloud-Init)
|
||||||
|
virt-customize -q -a "$WORK_FILE" --run-command "mkdir -p /etc/systemd/system/serial-getty@ttyS0.service.d" >/dev/null 2>&1 || true
|
||||||
|
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/systemd/system/serial-getty@ttyS0.service.d/autologin.conf << EOF
|
||||||
|
[Service]
|
||||||
|
ExecStart=
|
||||||
|
ExecStart=-/sbin/agetty --autologin root --noclear %I \$TERM
|
||||||
|
EOF' >/dev/null 2>&1 || true
|
||||||
|
virt-customize -q -a "$WORK_FILE" --run-command "mkdir -p /etc/systemd/system/getty@tty1.service.d" >/dev/null 2>&1 || true
|
||||||
|
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/systemd/system/getty@tty1.service.d/autologin.conf << EOF
|
||||||
|
[Service]
|
||||||
|
ExecStart=
|
||||||
|
ExecStart=-/sbin/agetty --autologin root --noclear %I \$TERM
|
||||||
|
EOF' >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
msg_ok "Finalized image"
|
||||||
|
|
||||||
|
# Create first-boot Docker install script (fallback if virt-customize failed)
|
||||||
|
if [ "$DOCKER_PREINSTALLED" = "no" ]; then
|
||||||
|
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /root/install-docker.sh << "DOCKERSCRIPT"
|
||||||
|
#!/bin/bash
|
||||||
|
exec > /var/log/install-docker.log 2>&1
|
||||||
|
echo "[$(date)] Starting Docker installation"
|
||||||
|
|
||||||
|
for i in {1..30}; do
|
||||||
|
ping -c 1 8.8.8.8 >/dev/null 2>&1 && break
|
||||||
|
sleep 2
|
||||||
done
|
done
|
||||||
|
|
||||||
if ! command -v virt-customize &>/dev/null; then
|
apt-get update
|
||||||
msg_info "Installing Pre-Requisite libguestfs-tools onto Host"
|
apt-get install -y qemu-guest-agent curl ca-certificates
|
||||||
apt-get -qq update >/dev/null
|
curl -fsSL https://get.docker.com | sh
|
||||||
apt-get -qq install libguestfs-tools lsb-release -y >/dev/null
|
systemctl enable docker
|
||||||
# Workaround for Proxmox VE 9.0 libguestfs issue
|
systemctl start docker
|
||||||
apt-get -qq install dhcpcd-base -y >/dev/null 2>&1 || true
|
|
||||||
msg_ok "Installed libguestfs-tools successfully"
|
mkdir -p /etc/docker
|
||||||
|
cat > /etc/docker/daemon.json << DAEMON
|
||||||
|
{
|
||||||
|
"storage-driver": "overlay2",
|
||||||
|
"log-driver": "json-file",
|
||||||
|
"log-opts": { "max-size": "10m", "max-file": "3" }
|
||||||
|
}
|
||||||
|
DAEMON
|
||||||
|
systemctl restart docker
|
||||||
|
|
||||||
|
touch /root/.docker-installed
|
||||||
|
echo "[$(date)] Docker installation completed"
|
||||||
|
DOCKERSCRIPT
|
||||||
|
chmod +x /root/install-docker.sh' >/dev/null 2>&1
|
||||||
|
|
||||||
|
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/systemd/system/install-docker.service << "DOCKERSERVICE"
|
||||||
|
[Unit]
|
||||||
|
Description=Install Docker on First Boot
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
ConditionPathExists=!/root/.docker-installed
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/root/install-docker.sh
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
DOCKERSERVICE
|
||||||
|
systemctl enable install-docker.service' >/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Adding Docker and Docker Compose Plugin to Debian 12 Qcow2 Disk Image"
|
# Resize disk to target size
|
||||||
virt-customize -q -a "${FILE}" --install qemu-guest-agent,apt-transport-https,ca-certificates,curl,gnupg,software-properties-common,lsb-release >/dev/null &&
|
msg_info "Resizing disk image to ${DISK_SIZE}"
|
||||||
virt-customize -q -a "${FILE}" --run-command "mkdir -p /etc/apt/keyrings && curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg" >/dev/null &&
|
qemu-img resize "$WORK_FILE" "${DISK_SIZE}" >/dev/null 2>&1
|
||||||
virt-customize -q -a "${FILE}" --run-command "echo 'deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable' > /etc/apt/sources.list.d/docker.list" >/dev/null &&
|
msg_ok "Resized disk image"
|
||||||
virt-customize -q -a "${FILE}" --run-command "apt-get update -qq && apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin" >/dev/null &&
|
|
||||||
virt-customize -q -a "${FILE}" --run-command "systemctl enable docker" >/dev/null &&
|
|
||||||
virt-customize -q -a "${FILE}" --hostname "${HN}" >/dev/null &&
|
|
||||||
virt-customize -q -a "${FILE}" --run-command "echo -n > /etc/machine-id" >/dev/null
|
|
||||||
msg_ok "Added Docker and Docker Compose Plugin to Debian 12 Qcow2 Disk Image successfully"
|
|
||||||
|
|
||||||
msg_info "Expanding root partition to use full disk space"
|
# ==============================================================================
|
||||||
qemu-img create -f qcow2 expanded.qcow2 ${DISK_SIZE} >/dev/null 2>&1
|
# VM CREATION
|
||||||
virt-resize --expand /dev/sda1 ${FILE} expanded.qcow2 >/dev/null 2>&1
|
# ==============================================================================
|
||||||
mv expanded.qcow2 ${FILE} >/dev/null 2>&1
|
msg_info "Creating Docker VM shell"
|
||||||
msg_ok "Expanded image to full size"
|
|
||||||
|
|
||||||
msg_info "Creating a Docker VM"
|
|
||||||
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
||||||
-name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci
|
-name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci >/dev/null
|
||||||
pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null
|
|
||||||
qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null
|
msg_ok "Created VM shell"
|
||||||
qm set $VMID \
|
|
||||||
-efidisk0 ${DISK0_REF}${FORMAT} \
|
# ==============================================================================
|
||||||
-scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \
|
# DISK IMPORT
|
||||||
-boot order=scsi0 \
|
# ==============================================================================
|
||||||
-serial0 socket >/dev/null
|
msg_info "Importing disk into storage ($STORAGE)"
|
||||||
qm resize $VMID scsi0 8G >/dev/null
|
|
||||||
|
if qm disk import --help >/dev/null 2>&1; then
|
||||||
|
IMPORT_CMD=(qm disk import)
|
||||||
|
else
|
||||||
|
IMPORT_CMD=(qm importdisk)
|
||||||
|
fi
|
||||||
|
|
||||||
|
IMPORT_OUT="$("${IMPORT_CMD[@]}" "$VMID" "$WORK_FILE" "$STORAGE" ${DISK_IMPORT:-} 2>&1 || true)"
|
||||||
|
DISK_REF_IMPORTED="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk '\([^']\+\)'.*/\1/p" | tr -d "\r\"'")"
|
||||||
|
[[ -z "$DISK_REF_IMPORTED" ]] && DISK_REF_IMPORTED="$(pvesm list "$STORAGE" | awk -v id="$VMID" '$5 ~ ("vm-"id"-disk-") {print $1":"$5}' | sort | tail -n1)"
|
||||||
|
[[ -z "$DISK_REF_IMPORTED" ]] && {
|
||||||
|
msg_error "Unable to determine imported disk reference."
|
||||||
|
echo "$IMPORT_OUT"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_ok "Imported disk (${CL}${BL}${DISK_REF_IMPORTED}${CL})"
|
||||||
|
|
||||||
|
# Clean up work file
|
||||||
|
rm -f "$WORK_FILE"
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# VM CONFIGURATION
|
||||||
|
# ==============================================================================
|
||||||
|
msg_info "Attaching EFI and root disk"
|
||||||
|
|
||||||
|
qm set "$VMID" \
|
||||||
|
--efidisk0 "${STORAGE}:0,efitype=4m" \
|
||||||
|
--scsi0 "${DISK_REF_IMPORTED},${DISK_CACHE}${THIN%,}" \
|
||||||
|
--boot order=scsi0 \
|
||||||
|
--serial0 socket >/dev/null
|
||||||
|
|
||||||
qm set $VMID --agent enabled=1 >/dev/null
|
qm set $VMID --agent enabled=1 >/dev/null
|
||||||
|
|
||||||
DESCRIPTION=$(
|
msg_ok "Attached EFI and root disk"
|
||||||
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;'>Docker VM</h2>
|
# Set VM description
|
||||||
|
set_description
|
||||||
|
|
||||||
<p style='margin: 16px 0;'>
|
# Cloud-Init configuration
|
||||||
<a href='https://ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>
|
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
||||||
<img src='https://img.shields.io/badge/☕-Buy us a coffee-blue' alt='spend Coffee' />
|
msg_info "Configuring Cloud-Init"
|
||||||
</a>
|
setup_cloud_init "$VMID" "$STORAGE" "$HN" "yes"
|
||||||
</p>
|
msg_ok "Cloud-Init configured"
|
||||||
|
fi
|
||||||
|
|
||||||
<span style='margin: 0 10px;'>
|
# Start VM
|
||||||
<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_ok "Created a Docker VM ${CL}${BL}(${HN})"
|
|
||||||
if [ "$START_VM" == "yes" ]; then
|
if [ "$START_VM" == "yes" ]; then
|
||||||
msg_info "Starting Docker VM"
|
msg_info "Starting Docker VM"
|
||||||
qm start $VMID
|
qm start $VMID >/dev/null 2>&1
|
||||||
msg_ok "Started Docker VM"
|
msg_ok "Started Docker VM"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# FINAL OUTPUT
|
||||||
|
# ==============================================================================
|
||||||
|
VM_IP=""
|
||||||
|
if [ "$START_VM" == "yes" ]; then
|
||||||
|
set +e
|
||||||
|
for i in {1..10}; do
|
||||||
|
VM_IP=$(qm guest cmd "$VMID" network-get-interfaces 2>/dev/null |
|
||||||
|
jq -r '.[] | select(.name != "lo") | ."ip-addresses"[]? | select(."ip-address-type" == "ipv4") | ."ip-address"' 2>/dev/null |
|
||||||
|
grep -v "^127\." | head -1) || true
|
||||||
|
[ -n "$VM_IP" ] && break
|
||||||
|
sleep 3
|
||||||
|
done
|
||||||
|
set -e
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "\n${INFO}${BOLD}${GN}Docker VM Configuration Summary:${CL}"
|
||||||
|
echo -e "${TAB}${DGN}VM ID: ${BGN}${VMID}${CL}"
|
||||||
|
echo -e "${TAB}${DGN}Hostname: ${BGN}${HN}${CL}"
|
||||||
|
echo -e "${TAB}${DGN}OS: ${BGN}${OS_DISPLAY}${CL}"
|
||||||
|
[ -n "$VM_IP" ] && echo -e "${TAB}${DGN}IP Address: ${BGN}${VM_IP}${CL}"
|
||||||
|
|
||||||
|
if [ "$DOCKER_PREINSTALLED" = "yes" ]; then
|
||||||
|
echo -e "${TAB}${DGN}Docker: ${BGN}Pre-installed (via get.docker.com)${CL}"
|
||||||
|
else
|
||||||
|
echo -e "${TAB}${DGN}Docker: ${BGN}Installing on first boot${CL}"
|
||||||
|
echo -e "${TAB}${YW}⚠️ Wait 2-3 minutes for installation to complete${CL}"
|
||||||
|
echo -e "${TAB}${YW}⚠️ Check progress: ${BL}cat /var/log/install-docker.log${CL}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
||||||
|
display_cloud_init_info "$VMID" "$HN" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
post_update_to_api "done" "none"
|
post_update_to_api "done" "none"
|
||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
|
|||||||
6
vm/headers/docker-vm
Normal file
6
vm/headers/docker-vm
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
____ __
|
||||||
|
/ __ \____ _____/ /_____ _____
|
||||||
|
/ / / / __ \/ ___/ //_/ _ \/ ___/
|
||||||
|
/ /_/ / /_/ / /__/ ,< / __/ /
|
||||||
|
/_____/\____/\___/_/|_|\___/_/
|
||||||
|
|
||||||
Reference in New Issue
Block a user