mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-11-09 23:12:53 +01:00
Compare commits
41 Commits
2026-11-03
...
2026-11-06
| Author | SHA1 | Date | |
|---|---|---|---|
| 1d5fdefc4e | |||
| 6a0c9b002d | |||
| 81d218adc2 | |||
| 125c2c44a7 | |||
| d63c98936b | |||
| df10e1d2dd | |||
| 50c5b786e4 | |||
| 3c0e693c2d | |||
| d8f3874f42 | |||
| 1a2bbb06bb | |||
| 996900f145 | |||
| bc348949c4 | |||
| 5720358d1b | |||
| ebf9cf656e | |||
| c5c406b392 | |||
| 745043bd9a | |||
| c0df6c9870 | |||
| 5e5e840458 | |||
| 4adef93eb9 | |||
| 94aa8e7ab0 | |||
| eb7d180f9f | |||
| 6e6ca04f24 | |||
| ce04c99aa2 | |||
| df705aefc4 | |||
| 4fd7aa7edb | |||
| c55556144a | |||
| 43481c25fd | |||
| d2970719e4 | |||
| 215f9be228 | |||
| 3e7fcf1350 | |||
| 8ba3582919 | |||
| 37e4a33615 | |||
| 3e54356653 | |||
| 1f03150b77 | |||
| cfa250a795 | |||
| bb4c1f2fbf | |||
| 793fba1a53 | |||
| 06b788ee81 | |||
| 667da6a8fb | |||
| e40a258a27 | |||
| ff5aac3889 |
+27
@@ -0,0 +1,27 @@
|
||||
name: Check Script Repo URL
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: ["main"]
|
||||
paths:
|
||||
- "ct/**"
|
||||
- "install/**"
|
||||
- "vm/**"
|
||||
- "tools/**"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check:
|
||||
if: github.repository == 'community-scripts/ProxmoxVE'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Reject DevScripts URLs
|
||||
run: |
|
||||
if grep -rnE 'community-scripts/(ProxmoxVED|DevScripts)/' ct install vm tools; then
|
||||
echo "::error::These lines point at DevScripts, so telemetry files the runs there. Use community-scripts/ProxmoxVE."
|
||||
exit 1
|
||||
fi
|
||||
@@ -571,6 +571,78 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
</details>
|
||||
|
||||
## 2026-11-06
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- UmbrelOS-VM: report runs as ProxmoxVE, not DevScripts [@MickLesk](https://github.com/MickLesk) ([#18497](https://github.com/community-scripts/ProxmoxVE/pull/18497))
|
||||
- Caddy: skip the xCaddy test build below 2 GB RAM [@MickLesk](https://github.com/MickLesk) ([#18472](https://github.com/community-scripts/ProxmoxVE/pull/18472))
|
||||
- Thingsboard: keep the package defaults in thingsboard.conf [@MickLesk](https://github.com/MickLesk) ([#18499](https://github.com/community-scripts/ProxmoxVE/pull/18499))
|
||||
- Nexterm: keep the extracted app out of the /tmp cleanup [@MickLesk](https://github.com/MickLesk) ([#18501](https://github.com/community-scripts/ProxmoxVE/pull/18501))
|
||||
- PLANKA: run the service with node instead of nodemon [@MickLesk](https://github.com/MickLesk) ([#18503](https://github.com/community-scripts/ProxmoxVE/pull/18503))
|
||||
- MeTube/Yubal: install Deno without its shell setup [@MickLesk](https://github.com/MickLesk) ([#18406](https://github.com/community-scripts/ProxmoxVE/pull/18406))
|
||||
- OPNsense VM: size the temp space check to the unpacked image | say why the EFI disk could not be allocated [@MickLesk](https://github.com/MickLesk) ([#18404](https://github.com/community-scripts/ProxmoxVE/pull/18404))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Technitium DNS: read the version from its GitHub releases [@MickLesk](https://github.com/MickLesk) ([#18425](https://github.com/community-scripts/ProxmoxVE/pull/18425))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- fix: spot same-filesystem bind mounts on Alpine [@rcourtman](https://github.com/rcourtman) ([core#212](https://github.com/community-scripts/core/pull/212))
|
||||
- fix: report a container that went down during setup, keep finished installs [@MickLesk](https://github.com/MickLesk) ([core#211](https://github.com/community-scripts/core/pull/211))
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- ci: reject DevScripts URLs in scripts [@MickLesk](https://github.com/MickLesk) ([#18498](https://github.com/community-scripts/ProxmoxVE/pull/18498))
|
||||
|
||||
## 2026-11-05
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- OpenWRT-VM: leave the NIC untagged on a bridge without a port [@MickLesk](https://github.com/MickLesk) ([#18473](https://github.com/community-scripts/ProxmoxVE/pull/18473))
|
||||
- Podman: skip Portainer where Podman has no Quadlet [@MickLesk](https://github.com/MickLesk) ([#18469](https://github.com/community-scripts/ProxmoxVE/pull/18469))
|
||||
- Planka: change npm start argument to --production [@CerberusStyle](https://github.com/CerberusStyle) ([#18478](https://github.com/community-scripts/ProxmoxVE/pull/18478))
|
||||
- OPNsense VM: wait for the FreeBSD login prompt instead of 180 seconds [@MickLesk](https://github.com/MickLesk) ([#18467](https://github.com/community-scripts/ProxmoxVE/pull/18467))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- truenas-VM: let a failed ISO lookup reach its own error [@MickLesk](https://github.com/MickLesk) ([#18476](https://github.com/community-scripts/ProxmoxVE/pull/18476))
|
||||
- proxmox-mail-gateway: take the repo suite from the container [@MickLesk](https://github.com/MickLesk) ([#18475](https://github.com/community-scripts/ProxmoxVE/pull/18475))
|
||||
- Immich: Bump to 3.3.6 and minor improvement [@MickLesk](https://github.com/MickLesk) ([#18474](https://github.com/community-scripts/ProxmoxVE/pull/18474))
|
||||
- Tududi: run 2.0 on PostgreSQL, keep SQLite installs on 1.15.0 [@MickLesk](https://github.com/MickLesk) ([#18465](https://github.com/community-scripts/ProxmoxVE/pull/18465))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- fix: keep the existing install until the new archive has extracted [@rcourtman](https://github.com/rcourtman) ([core#201](https://github.com/community-scripts/core/pull/201))
|
||||
- fix: keep the install when a clone or an Alpine extract fails [@rcourtman](https://github.com/rcourtman) ([core#210](https://github.com/community-scripts/core/pull/210))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Arcane: write both env names, stop shipping the unused .env [@MickLesk](https://github.com/MickLesk) ([#18466](https://github.com/community-scripts/ProxmoxVE/pull/18466))
|
||||
|
||||
## 2026-11-04
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Teleport: Poll readyz instead of fixed 10 second sleep. [@cthach](https://github.com/cthach) ([#18461](https://github.com/community-scripts/ProxmoxVE/pull/18461))
|
||||
- n8n: install past its unsatisfiable canvas dependencies [@MickLesk](https://github.com/MickLesk) ([#18439](https://github.com/community-scripts/ProxmoxVE/pull/18439))
|
||||
- Teable: add Redis cache [@MickLesk](https://github.com/MickLesk) ([#18450](https://github.com/community-scripts/ProxmoxVE/pull/18450))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- feat: say why download_gpg_key failed [@MickLesk](https://github.com/MickLesk) ([core#208](https://github.com/community-scripts/core/pull/208))
|
||||
- feat: read the MOTD's OS version at login [@MickLesk](https://github.com/MickLesk) ([core#207](https://github.com/community-scripts/core/pull/207))
|
||||
- feat: skip screen clear when there is no terminal | pin only the scripts own app with var_appversion [@MickLesk](https://github.com/MickLesk) ([core#203](https://github.com/community-scripts/core/pull/203))
|
||||
|
||||
## 2026-11-03
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
+7
-3
@@ -55,9 +55,13 @@ update_deb_based() {
|
||||
setup_go
|
||||
fetch_and_deploy_gh_release "xcaddy" "caddyserver/xcaddy" "binary"
|
||||
|
||||
msg_info "Updating xCaddy"
|
||||
$STD xcaddy build
|
||||
msg_ok "Updated xCaddy"
|
||||
if (($(awk '/^MemTotal:/ {print int($2 / 1024)}' /proc/meminfo) < 1900)); then
|
||||
msg_warn "xCaddy updated; its test build was skipped because linking Caddy needs about 2 GB RAM"
|
||||
else
|
||||
msg_info "Updating xCaddy"
|
||||
$STD xcaddy build
|
||||
msg_ok "Updated xCaddy"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
msg_ok "Updated successfully!"
|
||||
|
||||
+3
-3
@@ -75,7 +75,7 @@ EOF
|
||||
BASE_DIR=${STAGING_DIR}/base-images
|
||||
SOURCE_DIR=${STAGING_DIR}/image-source
|
||||
cd /tmp
|
||||
RELEASE="v3.3.5"
|
||||
RELEASE="v3.3.6"
|
||||
if [[ -f ~/.intel_version ]]; then
|
||||
INTEL_SRC="https://raw.githubusercontent.com/immich-app/immich/${RELEASE}/machine-learning"
|
||||
curl -fsSL "${INTEL_SRC}/scripts/install-intel-runtime.sh" -o ./intel-runtime 2>/dev/null ||
|
||||
@@ -292,7 +292,7 @@ EOF
|
||||
msg_ok "Pre-installed Python ${ML_PYTHON}"
|
||||
msg_info "Updating Intel OpenVINO machine-learning"
|
||||
for attempt in $(seq 1 3); do
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra openvino --no-dev --upgrade-package watchfiles --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
[[ $attempt -eq 3 ]] && { ML_FAILED=1; break; }
|
||||
# Parallel fetches can trip DNS rate limits (AdGuard, Pi-hole); retry one at a time.
|
||||
export UV_CONCURRENT_DOWNLOADS=1 UV_CONCURRENT_BUILDS=1 UV_CONCURRENT_INSTALLS=1
|
||||
@@ -310,7 +310,7 @@ EOF
|
||||
msg_ok "Pre-installed Python ${ML_PYTHON}"
|
||||
msg_info "Updating machine-learning"
|
||||
for attempt in $(seq 1 3); do
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra cpu --no-dev --upgrade-package watchfiles --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
[[ $attempt -eq 3 ]] && { ML_FAILED=1; break; }
|
||||
# Parallel fetches can trip DNS rate limits (AdGuard, Pi-hole); retry one at a time.
|
||||
export UV_CONCURRENT_DOWNLOADS=1 UV_CONCURRENT_BUILDS=1 UV_CONCURRENT_INSTALLS=1
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ function update_script() {
|
||||
source ~/.bashrc
|
||||
if ! command -v deno &>/dev/null; then
|
||||
export DENO_INSTALL="/usr/local"
|
||||
curl -fsSL https://deno.land/install.sh | $STD sh -s -- -y
|
||||
curl -fsSL https://deno.land/install.sh | CI=1 $STD sh -s
|
||||
else
|
||||
$STD deno upgrade
|
||||
fi
|
||||
|
||||
@@ -46,7 +46,10 @@ EOF
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
$STD npm install -g n8n@latest
|
||||
# n8n-nodes-base 2.46.0 pins both @napi-rs/canvas musl binaries as hard
|
||||
# dependencies, which no os/cpu/libc combination can satisfy. Drop --force
|
||||
# once upstream makes them optional again.
|
||||
$STD npm install -g n8n@latest --force
|
||||
systemctl restart n8n
|
||||
msg_ok "Updated n8n"
|
||||
msg_ok "Updated successfully!"
|
||||
|
||||
@@ -31,6 +31,8 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
echo "x /tmp/nexterm-sea-*" >/etc/tmpfiles.d/nexterm.conf
|
||||
|
||||
if check_for_gh_release "nexterm-engine" "gnmyt/Nexterm"; then
|
||||
msg_info "Stopping nexterm-engine"
|
||||
systemctl stop nexterm-engine
|
||||
@@ -46,6 +48,7 @@ function update_script() {
|
||||
if check_for_gh_release "nexterm-server" "gnmyt/Nexterm"; then
|
||||
msg_info "Stopping nexterm-server"
|
||||
systemctl stop nexterm-server
|
||||
rm -rf /tmp/nexterm-sea-*
|
||||
msg_ok "Stopped nexterm-server"
|
||||
|
||||
fetch_and_deploy_gh_release "nexterm-server" "gnmyt/Nexterm" "singlefile" "latest" "/opt/nexterm/server" "nexterm-server-linux-$(arch_resolve "x64" "arm64")"
|
||||
|
||||
@@ -30,6 +30,15 @@ function update_script() {
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! grep -q "^Environment=HOME=" /etc/systemd/system/planka.service; then
|
||||
msg_info "Updating Service"
|
||||
sed -i -e '/^Environment=NODE_ENV=/d' -e 's|^ExecStart=.*|Environment=NODE_ENV=production\nEnvironment=HOME=/root\nExecStart=/usr/bin/node app.js --prod|' /etc/systemd/system/planka.service
|
||||
systemctl daemon-reload
|
||||
systemctl restart planka
|
||||
msg_ok "Updated Service"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "planka" "plankanban/planka"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop planka
|
||||
|
||||
@@ -32,6 +32,16 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
ensure_dependencies redis-server
|
||||
systemctl enable -q --now redis-server
|
||||
if ! grep -q "BACKEND_CACHE_REDIS_URI" /opt/teable/.env; then
|
||||
sed -i '/^BACKEND_CACHE_SQLITE_URI=/d' /opt/teable/.env
|
||||
sed -i 's|^BACKEND_CACHE_PROVIDER=.*|BACKEND_CACHE_PROVIDER=redis\nBACKEND_CACHE_REDIS_URI=redis://127.0.0.1:6379/0|' /opt/teable/.env
|
||||
sed -i 's|^After=network.target postgresql.service$|After=network.target postgresql.service redis-server.service|' /etc/systemd/system/teable.service
|
||||
systemctl daemon-reload
|
||||
systemctl restart teable
|
||||
fi
|
||||
|
||||
if check_for_gh_release "teable" "teableio/teable"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop teable
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ function update_script() {
|
||||
$STD apt install -y aspnetcore-runtime-10.0
|
||||
fi
|
||||
|
||||
RELEASE=$(curl -fsSL https://technitium.com/dns/ | grep -oP 'Version \K[\d.]+')
|
||||
RELEASE=$(get_latest_github_release "TechnitiumSoftware/DnsServer")
|
||||
if [[ ! -f ~/.technitium || ${RELEASE} != "$(cat ~/.technitium 2>/dev/null)" ]]; then
|
||||
fetch_and_deploy_from_url "https://download.technitium.com/dns/DnsServerPortable.tar.gz" /opt/technitium/dns
|
||||
echo "${RELEASE}" >~/.technitium
|
||||
|
||||
+19
-1
@@ -31,12 +31,30 @@ function update_script() {
|
||||
fi
|
||||
|
||||
JAVA_VERSION="25" setup_java
|
||||
|
||||
if ! grep -q "install.data_dir" /etc/thingsboard/conf/thingsboard.conf; then
|
||||
msg_info "Restoring Package Defaults"
|
||||
cat <<'EOF' >>/etc/thingsboard/conf/thingsboard.conf
|
||||
|
||||
export JAVA_OPTS="$JAVA_OPTS -Dplatform=deb -Dinstall.data_dir=/usr/share/thingsboard/data"
|
||||
export JAVA_OPTS="$JAVA_OPTS -Xlog:gc*,heap*,age*,safepoint=debug:file=/var/log/thingsboard/gc.log:time,uptime,level,tags:filecount=10,filesize=10M"
|
||||
export JAVA_OPTS="$JAVA_OPTS -XX:+IgnoreUnrecognizedVMOptions -XX:+HeapDumpOnOutOfMemoryError"
|
||||
export JAVA_OPTS="$JAVA_OPTS -XX:-UseBiasedLocking -XX:+UseTLAB -XX:+ResizeTLAB -XX:+PerfDisableSharedMem -XX:+UseCondCardMark"
|
||||
export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=500 -XX:+UseStringDeduplication -XX:+ParallelRefProcEnabled -XX:MaxTenuringThreshold=10"
|
||||
export LOG_FILENAME=thingsboard.out
|
||||
export LOADER_PATH=/usr/share/thingsboard/conf,/usr/share/thingsboard/extensions
|
||||
export SQL_DATA_FOLDER=/usr/share/thingsboard/data/sql
|
||||
EOF
|
||||
systemctl restart thingsboard
|
||||
msg_ok "Restored Package Defaults"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "thingsboard" "thingsboard/thingsboard"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop thingsboard
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
fetch_and_deploy_gh_release "thingsboard" "thingsboard/thingsboard" "binary" "latest" "/tmp" "thingsboard-*.deb"
|
||||
DPKG_FORCE_CONFOLD=1 fetch_and_deploy_gh_release "thingsboard" "thingsboard/thingsboard" "binary" "latest" "/tmp" "thingsboard-*.deb"
|
||||
|
||||
msg_info "Running Database Upgrade"
|
||||
$STD /usr/share/thingsboard/bin/install/upgrade.sh
|
||||
|
||||
+14
-2
@@ -32,7 +32,14 @@ function update_script() {
|
||||
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
|
||||
if check_for_gh_release "tududi" "chrisvel/tududi"; then
|
||||
RELEASE=""
|
||||
if ! grep -qs '^DATABASE_URL=' /opt/tududi/backend/.env; then
|
||||
RELEASE="v1.15.0"
|
||||
msg_warn "Tududi 2.0 runs on PostgreSQL only, so this SQLite install stays on 1.15.0"
|
||||
msg_warn "To move to 2.0, export in Settings > Backups and import into a new Tududi LXC"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "tududi" "chrisvel/tududi" "${RELEASE}" "2.0 needs PostgreSQL"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop tududi
|
||||
msg_ok "Stopped Service"
|
||||
@@ -43,9 +50,14 @@ function update_script() {
|
||||
else
|
||||
cp /opt/tududi/.env /opt/tududi.env
|
||||
fi
|
||||
if ! grep -q '^TUDUDI_UPLOAD_PATH=' /opt/tududi.env; then
|
||||
mkdir -p /opt/tududi-uploads
|
||||
[[ -d /opt/tududi/backend/uploads ]] && cp -a /opt/tududi/backend/uploads/. /opt/tududi-uploads/
|
||||
echo "TUDUDI_UPLOAD_PATH=/opt/tududi-uploads" >>/opt/tududi.env
|
||||
fi
|
||||
msg_ok "Backed up env file"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "latest" "/opt/tududi"
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "${CHECK_UPDATE_RELEASE}" "/opt/tududi"
|
||||
|
||||
msg_info "Updating Tududi"
|
||||
cd /opt/tududi
|
||||
|
||||
@@ -23,10 +23,15 @@ setup_deb_based() {
|
||||
setup_go
|
||||
fetch_and_deploy_gh_release "xcaddy" "caddyserver/xcaddy" "binary"
|
||||
|
||||
msg_info "Setup xCaddy"
|
||||
$STD apt install -y git
|
||||
$STD xcaddy build
|
||||
msg_ok "Setup xCaddy"
|
||||
if (($(awk '/^MemTotal:/ {print int($2 / 1024)}' /proc/meminfo) < 1900)); then
|
||||
msg_warn "xCaddy is installed; its test build was skipped because linking Caddy needs about 2 GB RAM"
|
||||
else
|
||||
msg_info "Setup xCaddy"
|
||||
cd /opt
|
||||
$STD xcaddy build
|
||||
msg_ok "Setup xCaddy"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -69,10 +74,14 @@ EOF
|
||||
GO_VERSION="$(curl -fsSL https://go.dev/VERSION?m=text | head -1 | cut -c3-)" setup_go
|
||||
fetch_and_deploy_gh_release "xcaddy" "caddyserver/xcaddy" "prebuild" "latest" "/opt/xcaddy" "xcaddy_*_linux_$(arch_resolve).tar.gz"
|
||||
ln -sf /opt/xcaddy/xcaddy /usr/local/bin/xcaddy
|
||||
msg_info "Setup xCaddy"
|
||||
cd /opt
|
||||
$STD xcaddy build
|
||||
msg_ok "Setup xCaddy"
|
||||
if (($(awk '/^MemTotal:/ {print int($2 / 1024)}' /proc/meminfo) < 1900)); then
|
||||
msg_warn "xCaddy is installed; its test build was skipped because linking Caddy needs about 2 GB RAM"
|
||||
else
|
||||
msg_info "Setup xCaddy"
|
||||
cd /opt
|
||||
$STD xcaddy build
|
||||
msg_ok "Setup xCaddy"
|
||||
fi
|
||||
fi
|
||||
|
||||
msg_info "Enabling Caddy Service"
|
||||
|
||||
@@ -23,7 +23,7 @@ if [[ "$(arch_resolve)" == "amd64" ]] && ! grep -qm1 sse4_2 /proc/cpuinfo; then
|
||||
exit 236
|
||||
fi
|
||||
|
||||
RELEASE="v3.3.5"
|
||||
RELEASE="v3.3.6"
|
||||
if lscpu | grep -q 'GenuineIntel'; then
|
||||
echo ""
|
||||
echo ""
|
||||
@@ -146,10 +146,10 @@ mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
|
||||
|
||||
msg_info "Installing GeoNames data"
|
||||
cd "$GEO_DIR"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/admin1CodesASCII.txt" "admin1CodesASCII.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/admin2Codes.txt" "admin2Codes.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/countryInfo.txt" "countryInfo.txt"
|
||||
curl_with_retry "https://download.geonames.org/export/dump/cities500.zip" "cities500.zip"
|
||||
CURL_RETRIES=6 CURL_CONNECT_TO=30 curl_with_retry "https://download.geonames.org/export/dump/admin1CodesASCII.txt" "admin1CodesASCII.txt"
|
||||
CURL_RETRIES=6 CURL_CONNECT_TO=30 curl_with_retry "https://download.geonames.org/export/dump/admin2Codes.txt" "admin2Codes.txt"
|
||||
CURL_RETRIES=6 CURL_CONNECT_TO=30 curl_with_retry "https://download.geonames.org/export/dump/countryInfo.txt" "countryInfo.txt"
|
||||
CURL_RETRIES=6 CURL_CONNECT_TO=30 curl_with_retry "https://download.geonames.org/export/dump/cities500.zip" "cities500.zip"
|
||||
curl_with_retry "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/v5.1.2/geojson/ne_10m_admin_0_countries.geojson" "ne_10m_admin_0_countries.geojson"
|
||||
unzip -q cities500.zip
|
||||
date --iso-8601=seconds | tr -d "\n" >geodata-date.txt
|
||||
@@ -463,7 +463,7 @@ if [[ -f ~/.openvino ]]; then
|
||||
msg_ok "Pre-installed Python ${ML_PYTHON}"
|
||||
msg_info "Installing Intel OpenVINO machine-learning"
|
||||
for attempt in $(seq 1 3); do
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra openvino --no-dev --upgrade-package watchfiles --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
[[ $attempt -eq 3 ]] && { msg_error "uv sync failed three times, the machine-learning environment was not built"; exit 1; }
|
||||
# Parallel fetches can trip DNS rate limits (AdGuard, Pi-hole); retry one at a time.
|
||||
export UV_CONCURRENT_DOWNLOADS=1 UV_CONCURRENT_BUILDS=1 UV_CONCURRENT_INSTALLS=1
|
||||
@@ -481,7 +481,7 @@ else
|
||||
msg_ok "Pre-installed Python ${ML_PYTHON}"
|
||||
msg_info "Installing machine-learning"
|
||||
for attempt in $(seq 1 3); do
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT,UV_CONCURRENT_DOWNLOADS,UV_CONCURRENT_BUILDS,UV_CONCURRENT_INSTALLS -Pnu immich uv sync --extra cpu --no-dev --upgrade-package watchfiles --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
|
||||
[[ $attempt -eq 3 ]] && { msg_error "uv sync failed three times, the machine-learning environment was not built"; exit 1; }
|
||||
# Parallel fetches can trip DNS rate limits (AdGuard, Pi-hole); retry one at a time.
|
||||
export UV_CONCURRENT_DOWNLOADS=1 UV_CONCURRENT_BUILDS=1 UV_CONCURRENT_INSTALLS=1
|
||||
|
||||
@@ -26,7 +26,7 @@ NODE_VERSION="24" NODE_MODULE="corepack,pnpm" setup_nodejs
|
||||
|
||||
msg_info "Installing Deno"
|
||||
export DENO_INSTALL="/usr/local"
|
||||
curl -fsSL https://deno.land/install.sh | $STD sh -s -- -y
|
||||
curl -fsSL https://deno.land/install.sh | CI=1 $STD sh -s
|
||||
[[ ":$PATH:" != *":/usr/local/bin:"* ]] &&
|
||||
echo -e "\nexport PATH=\"/usr/local/bin:\$PATH\"" >>~/.bashrc &&
|
||||
source ~/.bashrc
|
||||
|
||||
@@ -23,7 +23,10 @@ msg_ok "Installed Dependencies"
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
|
||||
msg_info "Installing n8n (Patience)"
|
||||
$STD npm install -g n8n@latest
|
||||
# n8n-nodes-base 2.46.0 pins both @napi-rs/canvas musl binaries as hard
|
||||
# dependencies, which no os/cpu/libc combination can satisfy. Drop --force
|
||||
# once upstream makes them optional again.
|
||||
$STD npm install -g n8n@latest --force
|
||||
msg_ok "Installed n8n"
|
||||
|
||||
msg_info "Creating Service"
|
||||
|
||||
@@ -33,6 +33,7 @@ LOCAL_ENGINE_TOKEN=${LOCAL_ENGINE_TOKEN}
|
||||
ENCRYPTION_KEY=${ENCRYPTION_KEY}
|
||||
EOF
|
||||
chmod 0640 /etc/nexterm-engine/config.yaml /etc/nexterm-server/server.env
|
||||
echo "x /tmp/nexterm-sea-*" >/etc/tmpfiles.d/nexterm.conf
|
||||
msg_ok "Configured Nexterm"
|
||||
|
||||
msg_info "Creating Services"
|
||||
|
||||
@@ -70,7 +70,9 @@ After=network.target
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/opt/planka
|
||||
ExecStart=/usr/bin/npm start --prod
|
||||
Environment=NODE_ENV=production
|
||||
Environment=HOME=/root
|
||||
ExecStart=/usr/bin/node app.js --prod
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
|
||||
@@ -48,6 +48,10 @@ msg_ok "Installed Podman"
|
||||
|
||||
mkdir -p /etc/containers/systemd
|
||||
|
||||
if [[ ! -x /usr/libexec/podman/quadlet ]]; then
|
||||
msg_warn "Portainer runs as a Quadlet unit, which needs Podman 4.4 or newer (Debian 13); skipping it"
|
||||
var_podman_portainer="n" var_podman_portainer_agent="n"
|
||||
fi
|
||||
prompt="${var_podman_portainer:-}"
|
||||
[[ -n "$prompt" ]] || read -r -p "${TAB3}Would you like to add Portainer? <y/N> " prompt || true
|
||||
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
|
||||
|
||||
@@ -16,9 +16,9 @@ update_os
|
||||
msg_info "Installing Proxmox Mail Gateway"
|
||||
setup_deb822_repo \
|
||||
"pmg" \
|
||||
"https://enterprise.proxmox.com/debian/proxmox-release-trixie.gpg" \
|
||||
"https://enterprise.proxmox.com/debian/proxmox-release-$(get_os_info codename).gpg" \
|
||||
"http://download.proxmox.com/debian/pmg" \
|
||||
"trixie" \
|
||||
"$(get_os_info codename)" \
|
||||
"pmg-no-subscription"
|
||||
$STD apt install -y proxmox-mailgateway-container
|
||||
msg_ok "Installed Proxmox Mail Gateway"
|
||||
|
||||
@@ -17,7 +17,8 @@ msg_info "Installing Dependencies"
|
||||
$STD apt install -y \
|
||||
build-essential \
|
||||
python3 \
|
||||
git
|
||||
git \
|
||||
redis-server
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="pnpm" setup_nodejs
|
||||
@@ -56,8 +57,8 @@ SECRET_KEY=${SECRET_KEY}
|
||||
PORT=3000
|
||||
NODE_ENV=production
|
||||
NEXT_TELEMETRY_DISABLED=1
|
||||
BACKEND_CACHE_PROVIDER=sqlite
|
||||
BACKEND_CACHE_SQLITE_URI=sqlite:///opt/teable/.assets/.cache.db
|
||||
BACKEND_CACHE_PROVIDER=redis
|
||||
BACKEND_CACHE_REDIS_URI=redis://127.0.0.1:6379/0
|
||||
NEXTJS_DIR=apps/nextjs-app
|
||||
EOF
|
||||
ln -sf /opt/teable /app
|
||||
@@ -70,10 +71,11 @@ fi
|
||||
msg_ok "Configured Teable"
|
||||
|
||||
msg_info "Creating Service"
|
||||
systemctl enable -q --now redis-server
|
||||
cat <<EOF >/etc/systemd/system/teable.service
|
||||
[Unit]
|
||||
Description=Teable
|
||||
After=network.target postgresql.service
|
||||
After=network.target postgresql.service redis-server.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
@@ -23,7 +23,7 @@ setup_deb822_repo \
|
||||
$STD apt install -y aspnetcore-runtime-10.0
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
RELEASE=$(curl -fsSL https://technitium.com/dns/ | grep -oP 'Version \K[\d.]+')
|
||||
RELEASE=$(get_latest_github_release "TechnitiumSoftware/DnsServer")
|
||||
fetch_and_deploy_from_url "https://download.technitium.com/dns/DnsServerPortable.tar.gz" /opt/technitium/dns
|
||||
echo "${RELEASE}" >~/.technitium
|
||||
|
||||
|
||||
@@ -24,7 +24,11 @@ msg_info "Configuring Teleport"
|
||||
$STD apt install -y teleport
|
||||
$STD teleport configure -o /etc/teleport.yaml
|
||||
systemctl enable -q --now teleport
|
||||
sleep 10
|
||||
SECONDS=0
|
||||
until teleport debug readyz &>/dev/null; do
|
||||
sleep 2
|
||||
((SECONDS >= 120)) && { msg_error "Teleport did not become ready in time"; exit 1; }
|
||||
done
|
||||
tctl users add teleport-admin --roles=editor,access --logins=root >~/teleportadmin.txt
|
||||
sed -i "s|https://[^:]*:3080|https://${LOCAL_IP}:3080|g" ~/teleportadmin.txt
|
||||
msg_ok "Configured Teleport"
|
||||
|
||||
@@ -26,7 +26,8 @@ PG_DB_NAME="thingsboard_db" PG_DB_USER="thingsboard" setup_postgresql_db
|
||||
fetch_and_deploy_gh_release "thingsboard" "thingsboard/thingsboard" "binary" "latest" "/tmp" "thingsboard-*.deb"
|
||||
|
||||
msg_info "Configuring ThingsBoard"
|
||||
cat <<EOF >/etc/thingsboard/conf/thingsboard.conf
|
||||
cat <<EOF >>/etc/thingsboard/conf/thingsboard.conf
|
||||
|
||||
# DB Configuration
|
||||
export DATABASE_TS_TYPE=sql
|
||||
export SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/${PG_DB_NAME}
|
||||
|
||||
@@ -13,13 +13,9 @@ setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y \
|
||||
sqlite3 \
|
||||
yq
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="tududi" PG_DB_USER="tududi" setup_postgresql_db
|
||||
fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "latest" "/opt/tududi"
|
||||
|
||||
msg_info "Configuring Tududi"
|
||||
@@ -30,30 +26,22 @@ $STD npm run frontend:build
|
||||
mv ./dist ./backend
|
||||
msg_ok "Configured Tududi"
|
||||
|
||||
msg_info "Creating env and database"
|
||||
DB_LOCATION="/opt/tududi-db"
|
||||
UPLOAD_DIR="/opt/tududi-uploads"
|
||||
mkdir -p {"$DB_LOCATION","$UPLOAD_DIR"}
|
||||
msg_info "Creating env"
|
||||
mkdir -p /opt/tududi-uploads
|
||||
SECRET="$(openssl rand -hex 64)"
|
||||
sed -e '/^NODE_ENV=/s/=.*$/=production/' \
|
||||
-e 's/^TUDUDI_USER/# TUDUDI_USER/g' \
|
||||
-e "/_SECRET=/s/=.*$/=${SECRET}/" \
|
||||
-e '/^# DB_FILE=/s/^# //' \
|
||||
-e "s|^DB_FILE=.*|DB_FILE=${DB_LOCATION}/production.sqlite3|" \
|
||||
-e "/^# TUDUDI_ALLOWED/s/^# //; \
|
||||
\|_ORIGINS=|s|=.*$|=<your tududi IP or FDQN>|" \
|
||||
-e "/^# TUDUDI_UPLOAD/s/^# //; \
|
||||
\|UPLOAD_PATH=|s|=.*$|=${UPLOAD_DIR}|" \
|
||||
-e "s/^TUDUDI_SESSION_SECRET=.*/TUDUDI_SESSION_SECRET=${SECRET}/" \
|
||||
-e "s|^DATABASE_URL=.*|DATABASE_URL=postgres://tududi:${PG_DB_PASS}@localhost:5432/tududi|" \
|
||||
/opt/tududi/backend/.env.example >/opt/tududi/backend/.env
|
||||
export DB_FILE="${DB_LOCATION}/production.sqlite3"
|
||||
$STD npm run db:init
|
||||
msg_ok "Created env and database"
|
||||
echo "TUDUDI_UPLOAD_PATH=/opt/tududi-uploads" >>/opt/tududi/backend/.env
|
||||
msg_ok "Created env"
|
||||
|
||||
msg_info "Creating service"
|
||||
cat <<EOF >/etc/systemd/system/tududi.service
|
||||
[Unit]
|
||||
Description=Tududi Service
|
||||
After=network.target
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
@@ -31,7 +31,7 @@ ln -sf /opt/bun/bin/bunx /usr/local/bin/bunx
|
||||
msg_ok "Installed Bun"
|
||||
|
||||
msg_info "Installing Deno"
|
||||
$STD sh -c "curl -fsSL https://deno.land/install.sh | DENO_INSTALL=/usr/local sh -s -- -y"
|
||||
curl -fsSL https://deno.land/install.sh | CI=1 $STD sh -s
|
||||
msg_ok "Installed Deno"
|
||||
|
||||
msg_info "Creating directories"
|
||||
|
||||
+17
-13
@@ -58,8 +58,21 @@ function uninstall() {
|
||||
# ==============================================================================
|
||||
# UPDATE
|
||||
# ==============================================================================
|
||||
# Arcane 3 needs the ARCANE_* names, the current latest image reads only the old ones.
|
||||
function sync_env_names() {
|
||||
local key
|
||||
for key in ENCRYPTION_KEY PROJECTS_DIRECTORY; do
|
||||
grep -q "^[[:space:]]*- ARCANE_${key}=" "$COMPOSE_FILE" || sed -i "/^[[:space:]]*- ${key}=/{p;s/- ${key}=/- ARCANE_${key}=/;}" "$COMPOSE_FILE"
|
||||
grep -q "^[[:space:]]*- ${key}=" "$COMPOSE_FILE" || sed -i "/^[[:space:]]*- ARCANE_${key}=/{p;s/- ARCANE_${key}=/- ${key}=/;}" "$COMPOSE_FILE"
|
||||
done
|
||||
if [[ -f "$ENV_FILE" ]]; then
|
||||
sed -i 's/^ARCANE_#/#ARCANE_/' "$ENV_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
function update() {
|
||||
chown -R 65532:65532 /etc/arcane/projects /etc/arcane/builds 2>/dev/null || true
|
||||
sync_env_names
|
||||
|
||||
msg_info "Pulling latest ${APP} image"
|
||||
cd "$INSTALL_PATH"
|
||||
@@ -85,9 +98,8 @@ function install() {
|
||||
msg_ok "Created ${INSTALL_PATH}"
|
||||
|
||||
# Generate secrets and config values
|
||||
local ENCRYPTION_KEY JWT_SECRET PROJ_DIR BUILDS_DIR
|
||||
local ENCRYPTION_KEY PROJ_DIR BUILDS_DIR
|
||||
ENCRYPTION_KEY=$(random_password 32)
|
||||
JWT_SECRET=$(random_password 32)
|
||||
PROJ_DIR="/etc/arcane/projects"
|
||||
BUILDS_DIR="/etc/arcane/builds"
|
||||
|
||||
@@ -108,20 +120,12 @@ function install() {
|
||||
curl -fsSL "https://raw.githubusercontent.com/getarcaneapp/arcane/refs/heads/main/docker/examples/compose.basic.yaml" -o "$COMPOSE_FILE"
|
||||
msg_ok "Downloaded Docker Compose file"
|
||||
|
||||
msg_info "Downloading .env file"
|
||||
curl -fsSL "https://raw.githubusercontent.com/getarcaneapp/arcane/refs/heads/main/.env.example" -o "$ENV_FILE"
|
||||
chmod 600 "$ENV_FILE"
|
||||
msg_ok "Downloaded .env file"
|
||||
|
||||
msg_info "Configuring compose and env files"
|
||||
msg_info "Configuring compose file"
|
||||
sed -i '/^[[:space:]]*#/!s|/host/path/to/projects|'"$PROJ_DIR"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|/host/path/to/builds|'"$BUILDS_DIR"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|ENCRYPTION_KEY=.*|ENCRYPTION_KEY='"$ENCRYPTION_KEY"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|JWT_SECRET=.*|JWT_SECRET='"$JWT_SECRET"'|g' "$COMPOSE_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|APP_URL=.*|APP_URL=http://localhost:'"$DEFAULT_PORT"'|g' "$ENV_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|ENCRYPTION_KEY=.*|#&|g' "$ENV_FILE"
|
||||
sed -i '/^[[:space:]]*#/!s|JWT_SECRET=.*|#&|g' "$ENV_FILE"
|
||||
msg_ok "Configured compose and env files"
|
||||
sync_env_names
|
||||
msg_ok "Configured compose file"
|
||||
|
||||
msg_info "Starting ${APP}"
|
||||
cd "$INSTALL_PATH"
|
||||
|
||||
+13
-1
@@ -4,7 +4,7 @@
|
||||
# License: MIT
|
||||
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
|
||||
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/DevScripts/main}"
|
||||
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main}"
|
||||
source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/pve/vm-core.func")
|
||||
load_functions
|
||||
|
||||
@@ -341,6 +341,18 @@ if [[ "$VM_STATE" != *stopped* ]]; then
|
||||
fi
|
||||
msg_ok "OpenWrt has shut down"
|
||||
|
||||
# pve-bridge tags a NIC on a port of the bridge; a bridge without one only takes tags when VLAN-aware
|
||||
if [[ -n "$LAN_VLAN" && -d "/sys/class/net/${LAN_BRG}/bridge" && "$(cat "/sys/class/net/${LAN_BRG}/bridge/vlan_filtering" 2>/dev/null)" != "1" ]] &&
|
||||
! ls "/sys/class/net/${LAN_BRG}/brif" 2>/dev/null | grep -qE '^((eth|bond)[0-9]+|en[^.]+)(\.[0-9]+)?$'; then
|
||||
msg_warn "LAN bridge ${LAN_BRG} has no physical port and is not VLAN-aware; the LAN NIC stays untagged"
|
||||
LAN_VLAN=""
|
||||
fi
|
||||
if [[ -n "$VLAN" && -d "/sys/class/net/${BRG}/bridge" && "$(cat "/sys/class/net/${BRG}/bridge/vlan_filtering" 2>/dev/null)" != "1" ]] &&
|
||||
! ls "/sys/class/net/${BRG}/brif" 2>/dev/null | grep -qE '^((eth|bond)[0-9]+|en[^.]+)(\.[0-9]+)?$'; then
|
||||
msg_warn "WAN bridge ${BRG} has no physical port and is not VLAN-aware; the WAN NIC stays untagged"
|
||||
VLAN=""
|
||||
fi
|
||||
|
||||
msg_info "Adding bridge interfaces on Proxmox side"
|
||||
qm set $VMID \
|
||||
-net0 virtio,bridge=${LAN_BRG},macaddr=${LAN_MAC}${LAN_VLAN}${MTU} \
|
||||
|
||||
+27
-16
@@ -47,7 +47,7 @@ function check_disk_space() {
|
||||
}
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
if ! check_disk_space "$TEMP_DIR" 20 && [ -d "/var/tmp" ] && check_disk_space "/var/tmp" 20; then
|
||||
if ! check_disk_space "$TEMP_DIR" 4 && [ -d "/var/tmp" ] && check_disk_space "/var/tmp" 4; then
|
||||
rm -rf "$TEMP_DIR"
|
||||
TEMP_DIR=$(mktemp -d /var/tmp/opnsense-vm.XXXXXX)
|
||||
fi
|
||||
@@ -364,15 +364,6 @@ FREEBSD_VER="$VM_INDEX_LATEST"
|
||||
URL="$VM_INDEX_URL"
|
||||
msg_ok "Download URL: ${CL}${BL}${URL}${CL}"
|
||||
|
||||
# Check available disk space (require at least 20GB for safety)
|
||||
if ! check_disk_space "$TEMP_DIR" 20; then
|
||||
AVAILABLE_GB=$(df -h "$TEMP_DIR" | awk 'NR==2 {print $4}')
|
||||
msg_error "Insufficient disk space in temporary directory ($TEMP_DIR)."
|
||||
msg_error "Available: ${AVAILABLE_GB}, Required: ~20GB for FreeBSD image decompression."
|
||||
msg_error "Please free up space or ensure /tmp has sufficient storage."
|
||||
exit 214
|
||||
fi
|
||||
|
||||
msg_info "Downloading FreeBSD Image"
|
||||
# A mirror serving an error page returns 200, so size decides whether this
|
||||
# is an image. Anything real here is far above 5 MB.
|
||||
@@ -381,11 +372,12 @@ vm_fetch_image "$URL" "$CACHE_FILE" --cache --verify-xz --min-bytes $((5 * 1024
|
||||
echo -en "\e[1A\e[0K"
|
||||
msg_ok "Downloaded ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
|
||||
|
||||
# Check disk space again before decompression
|
||||
if ! check_disk_space "$TEMP_DIR" 15; then
|
||||
NEED_GB=$(($(xz --robot -l "$CACHE_FILE" | awk '$1 == "totals" {print $5}') / 1024 / 1024 / 1024 + 1))
|
||||
if ! check_disk_space "$TEMP_DIR" "$NEED_GB"; then
|
||||
AVAILABLE_GB=$(df -h "$TEMP_DIR" | awk 'NR==2 {print $4}')
|
||||
msg_error "Insufficient disk space for decompression."
|
||||
msg_error "Available: ${AVAILABLE_GB}, Required: ~15GB for decompressed image."
|
||||
msg_error "Insufficient disk space for decompression in ${TEMP_DIR}."
|
||||
msg_error "Available: ${AVAILABLE_GB}, Required: ~${NEED_GB}GB for the decompressed image."
|
||||
msg_error "Please free up space or ensure /tmp or /var/tmp has sufficient storage."
|
||||
exit 214
|
||||
fi
|
||||
|
||||
@@ -417,7 +409,7 @@ while :; do
|
||||
alloc_delay=$((alloc_delay * 2))
|
||||
continue
|
||||
fi
|
||||
echo -e "$alloc_err" >&2
|
||||
msg_error "Could not allocate the EFI disk on ${STORAGE}: ${alloc_err}"
|
||||
exit 220
|
||||
done
|
||||
vm_import_disk "$VMID" "$FILE" "$STORAGE"
|
||||
@@ -442,7 +434,26 @@ msg_ok "Bridge interfaces have been successfully added."
|
||||
msg_ok "Created a OPNsense VM ${CL}${BL}(${HN})"
|
||||
msg_ok "Starting OPNsense VM (the bootstrap takes 10-30 minutes)"
|
||||
$STD qm start $VMID
|
||||
sleep 180
|
||||
# The FreeBSD image prints its login prompt on the serial console too. Boot takes
|
||||
# under a minute with DHCP, each NIC without a DHCP server adds a 60s timeout.
|
||||
SERIAL_LOG="${TEMP_DIR}/serial-${VMID}.log"
|
||||
timeout 900 socat -u "UNIX-CONNECT:/var/run/qemu-server/${VMID}.serial0" - >"$SERIAL_LOG" 2>/dev/null &
|
||||
SERIAL_PID=$!
|
||||
boot_wait=0
|
||||
until grep -aq 'login:' "$SERIAL_LOG" 2>/dev/null || ! kill -0 "$SERIAL_PID" 2>/dev/null; do
|
||||
sleep 5
|
||||
boot_wait=$((boot_wait + 5))
|
||||
done
|
||||
kill "$SERIAL_PID" 2>/dev/null || true
|
||||
if grep -aq 'login:' "$SERIAL_LOG" 2>/dev/null; then
|
||||
msg_ok "FreeBSD booted after ${boot_wait}s"
|
||||
elif [ $boot_wait -lt 180 ]; then
|
||||
msg_warn "Could not read the serial console, waiting 3 minutes instead"
|
||||
sleep $((180 - boot_wait))
|
||||
else
|
||||
msg_warn "No login prompt on the serial console after $((boot_wait / 60)) minutes; continuing"
|
||||
fi
|
||||
sleep 3
|
||||
send_line_to_vm "root"
|
||||
sleep 2
|
||||
send_line_to_vm ""
|
||||
|
||||
+3
-2
@@ -39,7 +39,7 @@ function truenas_iso_lookup() {
|
||||
local pre_releases=()
|
||||
|
||||
local all_paths=$(
|
||||
curl -sL "$BASE_URL" |
|
||||
curl -fsSL "${_CS_CURL_RETRY[@]}" --max-time 90 "$BASE_URL" |
|
||||
grep -oE 'href="[^"]+\.iso"' |
|
||||
sed 's/href="//; s/"$//' |
|
||||
grep -vE '(MASTER|ALPHA)' |
|
||||
@@ -47,6 +47,7 @@ function truenas_iso_lookup() {
|
||||
)
|
||||
|
||||
while read -r path; do
|
||||
[[ -n "$path" ]] || continue
|
||||
local filename=$(basename "$path")
|
||||
local version=$(echo "$filename" | sed -E 's/.*TrueNAS-SCALE-([0-9]{2}\.[0-9]{2}(\.[0-9]+)*(-RC[0-9]|-BETA[0-9])?)\.iso.*/\1/')
|
||||
if [[ "$version" =~ (RC|BETA) ]]; then
|
||||
@@ -139,7 +140,7 @@ post_to_api_vm
|
||||
vm_select_storage "$HN"
|
||||
|
||||
if [ -z "${SELECTED_ISO:-}" ]; then
|
||||
SELECTED_ISO=$(truenas_iso_lookup | grep -vE 'RC|BETA' | sort -V | tail -n 1)
|
||||
SELECTED_ISO=$(truenas_iso_lookup | grep -vE 'RC|BETA' | sort -V | tail -n 1) || true
|
||||
|
||||
if [ -z "$SELECTED_ISO" ]; then
|
||||
msg_error "Could not find a stable ISO for fallback."
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
# Author: MickLesk (CanbiZ)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
|
||||
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/ProxmoxVED/main}"
|
||||
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main}"
|
||||
source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/pve/vm-core.func")
|
||||
load_functions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user