Compare commits

..
Author SHA1 Message Date
MickLesk a2475416c9 BookOrbit: retry the client build when the bundler crashes
Since rolldown 1.2.8, vite build dies at random with SIGSEGV or SIGBUS
(rolldown#10860, closed upstream), which stopped the 3.3.0 update with exit
139 (#17753). Retry the client build up to three times before giving up.
2026-10-08 09:47:00 +02:00
MickLesk 2d0f0de182 Immich: only mention the HEIC patch when it applies
On 3.3.0 the sharp call it rewrites is gone, so every run printed "pattern not found, skipped" into the spinner line and then "Patched". Check for the pattern first and stay silent otherwise.
2026-10-08 09:25:38 +02:00
MickLesk 53a69bbaba Immich: stop when uv sync keeps failing
After three failed attempts the loop still reported the machine-learning step as done, so an update ended in "Updated successfully" with no usable venv and immich-ml failing on start. Exit with an error instead.
2026-10-08 09:24:58 +02:00
MickLesk 22cd9219d6 Immich: run machine learning on Python 3.13
3.3.0 requires Python >=3.12 for machine learning and upstream builds both its CPU and OpenVINO images on 3.13. The CPU path still pinned 3.11, so uv sync failed on every update and install (#17762).
2026-10-08 09:24:22 +02:00
MickLesk a2a2e5a7b4 Immich: pin v3.3.0 again
Reapplies #17759, reverted in #17767 because machine learning broke on 3.3.0; the fixes follow.
2026-10-08 09:23:40 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 386a148e84 Update CHANGELOG.md (#17769)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-08 07:23:01 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 2c0a19263a Update CHANGELOG.md (#17768)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-08 04:13:24 +00:00
CanbiZ (MickLesk) 2a38085984 Revert "Immich: Pin to v3.3.0 (#17759)" (#17767)
This reverts commit a5431e295b.
2026-10-08 06:13:00 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 5e8e2ef477 Update CHANGELOG.md (#17761)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-07 21:03:08 +00:00
Chris a5431e295b Immich: Pin to v3.3.0 (#17759)
* Immich: Pin version to 3.3.0

- New features
- Bugfixes

* Enable new Machine Learning models by default
2026-10-07 23:02:37 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 7ddb0c68de Update CHANGELOG.md (#17756)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-07 19:40:30 +00:00
CanbiZ (MickLesk) 096f0ba2db AudioMuse-AI: replace the venv on update without asking (#17738)
uv venv on an existing .venv asks before replacing it and refuses outright
without a terminal, so updates through update-apps.sh failed and left the
services stopped (#17734). --clear replaces it the way the interactive prompt
did.
2026-10-07 21:40:00 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] b24d1e2631 Update CHANGELOG.md (#17755)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-07 19:39:27 +00:00
CanbiZ (MickLesk) 46c0210af7 Pangolin: Unpin Release, stable enough, Bump to latest (#17740)
* Pangolin: Unpin Release, stable enough, Bump to latest

* Remove default PANGOLIN_VERSION in install script
2026-10-07 21:39:05 +02:00
CanbiZ (MickLesk) 5af976eb97 Refactor: Archlinux-VM (#17741)
* Refactor archlinux-vm.sh and update defaults

Refactor Arch Linux VM script to improve structure and update default settings.

* Update Arch Linux VM script to use dynamic ISO path
2026-10-07 21:38:56 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 19a400c04b Update CHANGELOG.md (#17754)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-07 19:36:54 +00:00
CanbiZ (MickLesk) 712656a330 Refactor: MikroTik RouterOS (#17748)
* Refactor: MikroTik RouterOS

* Update COMMUNITY_SCRIPTS_URL to ProxmoxVE repository
2026-10-07 21:36:18 +02:00
MickLesk 3b768aaeb9 minor qf: update ISO handling in TrueNAS and Umbrel OS VM scripts 2026-10-07 16:00:36 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 008e2d90be Update CHANGELOG.md (#17749)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-07 13:23:39 +00:00
push-app-to-main[bot] fa8b74a00b Add fedora-vm (vm) (#17747)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-10-07 15:23:06 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 1dfe79f968 Update CHANGELOG.md (#17745)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-07 13:04:43 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 111a281b3e Update CHANGELOG.md (#17743)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-07 12:06:30 +00:00
samvandenbosscheandClaude Sonnet 5.5 b755ec70d5 paperclip: run service as a dedicated non-root user (#17707)
Claude Code refuses --dangerously-skip-permissions as root, which blocked
Paperclip onboarding. Run onboarding and the systemd service as a
non-root user (var_paperclip_user, default paperclip) with an optional
var_paperclip_pass (account locked if unset). Existing installs are
migrated on update.

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-07 14:06:14 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] beff70719f Update CHANGELOG.md (#17742)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-07 12:06:00 +00:00
Sim Kai Long cec9f13da1 OpenCloud: bump to v8.1.0, rebuild search index on upgrade (#17710)
v8 changes the search index format; existing files are not found by
search until the index is rebuilt. When updating from 7.x or older, run
the reindex as a transient systemd unit (the CLI cancels the rebuild if
interrupted), wait for it, and report the outcome.
2026-10-07 14:05:30 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] ea59019670 Update CHANGELOG.md (#17739)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-07 06:32:46 +00:00
CerberusStyleandCanbiZ 13bfd8aa15 Thingsboard: update Java version from 17 to 25 (#17733)
* Update Java version from 17 to 25 in install script

* Set JAVA_VERSION before checking for gh release

---------

Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
2026-10-07 08:32:22 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 175bbe9da7 Update CHANGELOG.md (#17737)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-07 05:38:39 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 48706f41d5 Update CHANGELOG.md (#17730)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 15:39:40 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 017691457a Update CHANGELOG.md (#17729)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 14:29:29 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 17f5ac84e5 Update CHANGELOG.md (#17728)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 14:27:31 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 0b0ad2e9bd Update CHANGELOG.md (#17727)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 14:27:19 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 78a4d809c7 Update CHANGELOG.md (#17726)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 14:26:51 +00:00
CanbiZ (MickLesk) 36078aa896 Webtrees: stop serving data/ and the source folders directly (#17724)
Caddy served all of /opt/webtrees through file_server, so media under
data/media could be fetched by URL without passing webtrees' privacy rules.
webtrees only protects data/ with an .htaccess, which Caddy ignores. Deny the
folders webtrees' own nginx guide keeps private, plus dotfiles.

update_script adds the rule to existing Caddyfiles on every update, not only
when a new release is out, and keeps the old file if the result fails
caddy validate.
2026-10-06 16:26:21 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 69bbf389f3 Update CHANGELOG.md (#17725)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 14:23:09 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 1da0c463ca Update CHANGELOG.md (#17723)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 13:54:15 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 745f88d484 Update CHANGELOG.md (#17722)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 13:53:39 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 0fba89af41 Update CHANGELOG.md (#17720)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 13:31:19 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 2fa0128614 Update CHANGELOG.md (#17719)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 13:24:53 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] efd8a86c2a Update CHANGELOG.md (#17718)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 13:23:14 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] c7257f3f9d Update CHANGELOG.md (#17717)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 11:40:22 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 15263edeaf Update CHANGELOG.md (#17716)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 11:32:56 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 463d9828d9 Update CHANGELOG.md (#17715)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 11:32:35 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 405d2fa578 Update CHANGELOG.md (#17714)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 11:10:46 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 185ae4fde2 Update CHANGELOG.md (#17712)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-06 08:49:06 +00:00
push-app-to-main[bot] bf3fad3984 Add pricebuddy (ct) (#17708)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-10-06 10:48:36 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 10af1ac41f Update CHANGELOG.md (#17705)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 11:18:22 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 79e33e9fdc Update CHANGELOG.md (#17704)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 11:18:04 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] b87fe56bf0 Update CHANGELOG.md (#17703)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 11:14:42 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 0826ebad2a Update CHANGELOG.md (#17702)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 11:13:34 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 11c549ca4d Update CHANGELOG.md (#17701)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 11:04:22 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 8ae3b842e4 Update CHANGELOG.md (#17700)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 10:48:56 +00:00
CanbiZ (MickLesk) 7d9648dc90 wanderer: set the proxy secret and install plugins in their own directories (#17698)
0.21 requires POCKETBASE_PROXY_SECRET on both services, or every
incoming federation request is rejected; both read the same .env.

Each plugin archive holds one directory, which the deploy strips, so all
three landed flat in plugins/ and overwrote each other. wanderer only
loads direct child directories, so it found none. Existing installs are
moved over on the next update.
2026-10-05 12:48:29 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 9d0b1e0354 Update CHANGELOG.md (#17699)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 10:48:08 +00:00
CanbiZ (MickLesk) 231b2fb1b7 discourse: serve stylesheets and repair the update (#17697)
nginx passed X-Accel-Mapping on every request. Stylesheets are sent
from tmp/, outside that mapping, so Rack redirected nginx to their
filesystem path and the page loaded without CSS. Existing installs get
the line removed on update.

The update called yarn, which is not installed, ran Rails without the
production environment or rbenv on PATH, asked for PostgreSQL 16 on a
17 install and left sidekiq running.
2026-10-05 12:47:42 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] e49cff4d54 Update CHANGELOG.md (#17696)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 09:03:34 +00:00
CanbiZ (MickLesk) 1c1295a9fd Point to DevScripts, the renamed ProxmoxVED (#17694)
Contribution docs, the PR template and the workflows that talk to the
testing repository use the new name. Migration PRs are matched by either
name, and three license headers pointed at contributor forks.
2026-10-05 11:03:02 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] ca6e8f407e Update CHANGELOG.md (#17695)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 08:40:08 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] e8a575dff4 Update CHANGELOG.md (#17692)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 06:50:51 +00:00
github-actions[bot] 5b5e8dc4f3 wikijs: bump Node.js from 24 to 26 (#17689)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-05 08:50:27 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] bcbe464ff9 Update CHANGELOG.md (#17691)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 06:47:58 +00:00
github-actions[bot] 7bde0ac8d9 jotty: bump Node.js from 22 to 24 (#17688)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-05 08:47:32 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] c225acc722 Update CHANGELOG.md (#17687)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-05 06:17:15 +00:00
Jason O'Brien aaa341b6b2 monitor-all: read container IP from the host side (#17686)
The CT check resolved the IP by running ip inside the guest via pct
exec, which depends on the guest having it installed. If not, this
always comes back empty, so the container is restarted every cycle
despite answering ping. lxc-info reports the addresses from the
host without running anything inside the guest.

Fixes #17685
2026-10-05 08:16:45 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 1142165f73 Update CHANGELOG.md (#17683)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-04 12:03:50 +00:00
CanbiZ (MickLesk) 63e2ce0849 immich: read the Intel runtime from the pinned release (#17677)
The URLs came from the ML Dockerfile on main, which upstream moved into
scripts/install-intel-runtime.sh, so update failed on the grep and
OpenVINO installs found no packages.
2026-10-04 14:03:24 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 2c33ecf7cf Update CHANGELOG.md (#17680)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-04 09:45:56 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 22a5672945 Update CHANGELOG.md (#17679)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-04 09:45:31 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] bee57cc60f Update CHANGELOG.md (#17678)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-04 09:45:09 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 5ae725fb1b Update CHANGELOG.md (#17671)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-04 00:50:10 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 5ef159a377 Archive old changelog entries (#17670)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-04 00:49:40 +00:00
community-scripts-pr-app[bot]andgithub-actions[bot] 086ce89fc0 Update CHANGELOG.md (#17669)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-03 23:28:16 +00:00
CanbiZ (MickLesk) 713382315d hermesagent: download the installer before running it (#17666)
bash <(curl ...) ran an empty script when the download failed and exited 0, so the failure surfaced one line later as chmod on a missing directory.
2026-10-04 01:27:55 +02:00
CanbiZ (MickLesk) ca2bbb9b76 frigate: raise the Node heap for the web build (#17667) 2026-10-04 01:27:49 +02:00
community-scripts-pr-app[bot]andgithub-actions[bot] 99746e749c Update CHANGELOG.md (#17664)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-10-03 18:51:21 +00:00
45 changed files with 1100 additions and 1312 deletions
+84
View File
@@ -1,3 +1,87 @@
## 2026-09-30
### 🆕 New Scripts
- Shoko ([#17617](https://github.com/community-scripts/ProxmoxVE/pull/17617))
- SIlo ([#17614](https://github.com/community-scripts/ProxmoxVE/pull/17614))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix(blocky): restart on failure and wait for network-online [@haplo](https://github.com/haplo) ([#17601](https://github.com/community-scripts/ProxmoxVE/pull/17601))
- SparkyFitness: update sed replacement [@tomfrenzel](https://github.com/tomfrenzel) ([#17604](https://github.com/community-scripts/ProxmoxVE/pull/17604))
### 💾 Core
- vm: autologin on the serial console for images without cloud-init [@MickLesk](https://github.com/MickLesk) ([core#80](https://github.com/community-scripts/core/pull/80))
- download_gpg_key: make dearmored keyrings world-readable [@MickLesk](https://github.com/MickLesk) ([core#79](https://github.com/community-scripts/core/pull/79))
## 2026-09-29
### 🆕 New Scripts
- Anki Sync Server ([#17416](https://github.com/community-scripts/ProxmoxVE/pull/17416))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix(kaneo): build with Vite+ instead of Turbo [@tinsever](https://github.com/tinsever) ([#17599](https://github.com/community-scripts/ProxmoxVE/pull/17599))
- tianji: raise the Node heap for the static build on install [@MickLesk](https://github.com/MickLesk) ([#17582](https://github.com/community-scripts/ProxmoxVE/pull/17582))
- fix(romm): snapshot Redis hourly like the upstream image [@DenislavDenev](https://github.com/DenislavDenev) ([#17562](https://github.com/community-scripts/ProxmoxVE/pull/17562))
- checkmate: bump Node.js from 22 to 24 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#17554](https://github.com/community-scripts/ProxmoxVE/pull/17554))
- #### 🔧 Refactor
- Drop the scripts base pin from every ct/ script [@MickLesk](https://github.com/MickLesk) ([#17585](https://github.com/community-scripts/ProxmoxVE/pull/17585))
- odoo: move to Debian 13 and stay on the installed major on update [@MickLesk](https://github.com/MickLesk) ([#17581](https://github.com/community-scripts/ProxmoxVE/pull/17581))
- manyfold: use upstream f3d for headless renders on amd64 [@MickLesk](https://github.com/MickLesk) ([#17583](https://github.com/community-scripts/ProxmoxVE/pull/17583))
### 💾 Core
- Default the scripts base to ProxmoxVE [@MickLesk](https://github.com/MickLesk) ([core#76](https://github.com/community-scripts/core/pull/76))
### 🧰 Tools
- #### 🐞 Bug Fixes
- all-templates: handle the arch column of pveam available [@MickLesk](https://github.com/MickLesk) ([#17579](https://github.com/community-scripts/ProxmoxVE/pull/17579))
### 📂 Github
- Skip automated core pull requests in the changelog [@MickLesk](https://github.com/MickLesk) ([#17589](https://github.com/community-scripts/ProxmoxVE/pull/17589))
- Post a test command for vm/, tools/ and turnkey/ changes too [@MickLesk](https://github.com/MickLesk) ([#17587](https://github.com/community-scripts/ProxmoxVE/pull/17587))
- Remove the PocketBase AI bot [@MickLesk](https://github.com/MickLesk) ([#17591](https://github.com/community-scripts/ProxmoxVE/pull/17591))
## 2026-09-28
### 🚀 Updated Scripts
- Immich: Pin version to 3.2.4 [@vhsdream](https://github.com/vhsdream) ([#17564](https://github.com/community-scripts/ProxmoxVE/pull/17564))
- #### 🐞 Bug Fixes
- fix(autocaliweb): wire .env into all service units, not just autocali… [@bobartlett](https://github.com/bobartlett) ([#17561](https://github.com/community-scripts/ProxmoxVE/pull/17561))
- Zipline: Change cp command [@Mraedis](https://github.com/Mraedis) ([#17559](https://github.com/community-scripts/ProxmoxVE/pull/17559))
- Borg-UI: start through upstream's start.sh so migrations run [@MickLesk](https://github.com/MickLesk) ([#17563](https://github.com/community-scripts/ProxmoxVE/pull/17563))
- linkding: serve favicons and preview images [@MickLesk](https://github.com/MickLesk) ([#17557](https://github.com/community-scripts/ProxmoxVE/pull/17557))
- SparkyFitness: Fill in the nginx resolver 1.7.3 added [@MickLesk](https://github.com/MickLesk) ([#17556](https://github.com/community-scripts/ProxmoxVE/pull/17556))
- #### 🔧 Refactor
- Plane: Replace MinIO installation with Silo [@MickLesk](https://github.com/MickLesk) ([#17347](https://github.com/community-scripts/ProxmoxVE/pull/17347))
## 2026-09-27
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix(aurral): bump to Node 26 and bypass strict engine pin [@JodyVanden](https://github.com/JodyVanden) ([#17543](https://github.com/community-scripts/ProxmoxVE/pull/17543))
- Tracearr: fetch map tiles on install/update [@durzo](https://github.com/durzo) ([#17544](https://github.com/community-scripts/ProxmoxVE/pull/17544))
- fix(autocaliweb): define INSTALL_DIR before first use [@bobartlett](https://github.com/bobartlett) ([#17545](https://github.com/community-scripts/ProxmoxVE/pull/17545))
## 2026-09-26
### 🚀 Updated Scripts
+74
View File
@@ -0,0 +1,74 @@
## 2026-10-03
### 🆕 New Scripts
- Keeper.sh ([#17659](https://github.com/community-scripts/ProxmoxVE/pull/17659))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- hermesagent: download the installer before running it [@MickLesk](https://github.com/MickLesk) ([#17666](https://github.com/community-scripts/ProxmoxVE/pull/17666))
- frigate: raise the Node heap for the web build [@MickLesk](https://github.com/MickLesk) ([#17667](https://github.com/community-scripts/ProxmoxVE/pull/17667))
- Tracearr: workaround for failing map tiles download and data preservation [@durzo](https://github.com/durzo) ([#17661](https://github.com/community-scripts/ProxmoxVE/pull/17661))
- fix(nginxproxymanager): clean yarn cache after builds to prevent disk growth [@PsycoStea](https://github.com/PsycoStea) ([#17653](https://github.com/community-scripts/ProxmoxVE/pull/17653))
- #### 🔧 Refactor
- Several Scripts: refactor msg_ blocks, generate passwords with helper, add CLEAN_INSTALL_KEEP [@MickLesk](https://github.com/MickLesk) ([#17655](https://github.com/community-scripts/ProxmoxVE/pull/17655))
### 💾 Core
- detect_repo_source: read the license header and fall back to ProxmoxVE [@MickLesk](https://github.com/MickLesk) ([core#85](https://github.com/community-scripts/core/pull/85))
## 2026-10-02
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- zerobyte: upgrade Bun on update [@MickLesk](https://github.com/MickLesk) ([#17646](https://github.com/community-scripts/ProxmoxVE/pull/17646))
- sure: keep Active Storage uploads across updates [@MickLesk](https://github.com/MickLesk) ([#17648](https://github.com/community-scripts/ProxmoxVE/pull/17648))
- twenty: run upstreams upgrade command instead of the removed setup-db.ts [@MickLesk](https://github.com/MickLesk) ([#17647](https://github.com/community-scripts/ProxmoxVE/pull/17647))
- #### 🔧 Refactor
- NPM: Refactor / Fix npm openresty user and certbot version [@MickLesk](https://github.com/MickLesk) ([#17649](https://github.com/community-scripts/ProxmoxVE/pull/17649))
- several scripts: use the release helpers instead of hand-rolled version checks and downloads [@MickLesk](https://github.com/MickLesk) ([#17625](https://github.com/community-scripts/ProxmoxVE/pull/17625))
### 💾 Core
- QoL: message blocks, clean-install keep list, password helper, network limits [@MickLesk](https://github.com/MickLesk) ([core#61](https://github.com/community-scripts/core/pull/61))
## 2026-10-01
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- romm: keep the asset links in sync with ROMM_BASE_PATH [@MickLesk](https://github.com/MickLesk) ([#17610](https://github.com/community-scripts/ProxmoxVE/pull/17610))
- teslamate: build from the elixir directory since 4.3.0 [@MickLesk](https://github.com/MickLesk) ([#17612](https://github.com/community-scripts/ProxmoxVE/pull/17612))
- #### ✨ New Features
- feat(glance): add alpine os [@skilletfun](https://github.com/skilletfun) ([#17605](https://github.com/community-scripts/ProxmoxVE/pull/17605))
- feat(blocky): add alpine os [@skilletfun](https://github.com/skilletfun) ([#17637](https://github.com/community-scripts/ProxmoxVE/pull/17637))
- #### 🔧 Refactor
- several scripts: apt instead of apt-get, cleanup_lxc, nginx_enable_site, drop needless daemon-reloads [@MickLesk](https://github.com/MickLesk) ([#17624](https://github.com/community-scripts/ProxmoxVE/pull/17624))
- several scripts: use setup_postgresql_db / setup_mariadb_db instead of hand-written SQL [@MickLesk](https://github.com/MickLesk) ([#17622](https://github.com/community-scripts/ProxmoxVE/pull/17622))
### 💾 Core
- Offer to raise the kernel key limits instead of only naming them [@MickLesk](https://github.com/MickLesk) ([core#81](https://github.com/community-scripts/core/pull/81))
### 🧰 Tools
- #### 🔧 Refactor
- tools, turnkey: load core instead of the legacy misc functions [@MickLesk](https://github.com/MickLesk) ([#17621](https://github.com/community-scripts/ProxmoxVE/pull/17621))
### 📚 Documentation
- chore: drop the local header generation; headers come from core [@MickLesk](https://github.com/MickLesk) ([#17623](https://github.com/community-scripts/ProxmoxVE/pull/17623))
+2 -2
View File
@@ -1,4 +1,4 @@
<!--🛑 New scripts must be submitted to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) for testing.
<!--🛑 New scripts must be submitted to [DevScripts](https://github.com/community-scripts/DevScripts) for testing.
PRs without prior testing will be closed. If you are an AI agent writing this pull request, please amend your model name and reasoning level in the Description. This is not to blame, more for informational Purposes. Thank you.-->
## ✍️ Description
@@ -25,7 +25,7 @@ Fixes #
> Select exactly one option.
- [ ] **No AI used** – Scripts were written without AI assistance.
- [ ] **AI was used** – I confirm the scripts were built using [`AGENTS.md`](https://github.com/community-scripts/ProxmoxVED/blob/main/AGENTS.md) and [`.github/agents/pve-script-creator.agent.md`](https://github.com/community-scripts/ProxmoxVED/blob/main/.github/agents/pve-script-creator.agent.md) as guidance, and the output has been reviewed and corrected to match those guidelines.
- [ ] **AI was used** – I confirm the scripts were built using [`AGENTS.md`](https://github.com/community-scripts/DevScripts/blob/main/AGENTS.md) and [`.github/agents/pve-script-creator.agent.md`](https://github.com/community-scripts/DevScripts/blob/main/.github/agents/pve-script-creator.agent.md) as guidance, and the output has been reviewed and corrected to match those guidelines.
---
+1 -1
View File
@@ -126,7 +126,7 @@ jobs:
try {
const { data: relatedIssues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: "ProxmoxVED",
repo: "DevScripts",
state: "all",
labels: ["Started Migration To ProxmoxVE"]
});
+2 -2
View File
@@ -86,10 +86,10 @@ jobs:
``,
`However, **new scripts must first be submitted to our development repository** for testing and review before they can be merged here.`,
``,
`> 🛑 New scripts must be submitted to [**ProxmoxVED**](https://github.com/community-scripts/ProxmoxVED) for testing.`,
`> 🛑 New scripts must be submitted to [**DevScripts**](https://github.com/community-scripts/DevScripts) for testing.`,
`> PRs without prior testing will be closed.`,
``,
`Please open your PR at **https://github.com/community-scripts/ProxmoxVED** instead.`,
`Please open your PR at **https://github.com/community-scripts/DevScripts** instead.`,
`Once your script has been tested and approved there, it will be pushed to this repository automatically.`,
``,
`This PR will now be closed. Thank you for understanding! 🙏`,
+5 -5
View File
@@ -12,7 +12,7 @@ jobs:
if: github.event.pull_request.merged == true && github.repository == 'community-scripts/ProxmoxVE'
runs-on: self-hosted
env:
DEV_REPO: community-scripts/ProxmoxVED
DEV_REPO: community-scripts/DevScripts
steps:
- name: Checkout target repo (merge commit)
@@ -60,7 +60,7 @@ jobs:
echo "count=$(printf '%s' "$slugs" | wc -w | tr -d '[:space:]')" >> "$GITHUB_OUTPUT"
echo "Slugs in this PR: ${slugs:-<none>}"
- name: Resolve the matching ProxmoxVED issue
- name: Resolve the matching DevScripts issue
id: find_issue
shell: bash
env:
@@ -71,7 +71,7 @@ jobs:
# creates, so migration PRs carry an exact back-reference. Guessing from
# titles or file names is never needed for them.
matched=$(printf '%s' "$PR_BODY" \
| grep -oE 'community-scripts/ProxmoxVED#[0-9]+' \
| grep -oE 'community-scripts/(ProxmoxVED|DevScripts)#[0-9]+' \
| sed 's/.*#//' || true)
if [ -n "$matched" ]; then
@@ -96,7 +96,7 @@ jobs:
[ -n "$row" ] || continue
num=$(printf '%s' "$row" | jq -r '.number')
# Same slug derivation the ProxmoxVED workflows use, so both
# Same slug derivation the DevScripts workflows use, so both
# sides agree on what "alpine-cinny" means.
name=$(printf '%s' "$row" | jq -r '.body // ""' \
| sed -n '/^###[[:space:]]*Name of the Script/,/^###/p' \
@@ -124,7 +124,7 @@ jobs:
echo "issue_numbers=$matched" >> "$GITHUB_OUTPUT"
echo "Closing: ${matched:-<none>}"
- name: Comment on and close matching ProxmoxVED issues
- name: Comment on and close matching DevScripts issues
if: steps.find_issue.outputs.issue_numbers != ''
shell: bash
env:
+132 -160
View File
@@ -110,6 +110,9 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
@@ -123,7 +126,14 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
<details>
<summary><h4>September (26 entries)</h4></summary>
<summary><h4>October (3 entries)</h4></summary>
[View October 2026 Changelog](.github/changelogs/2026/10.md)
</details>
<details>
<summary><h4>September (30 entries)</h4></summary>
[View September 2026 Changelog](.github/changelogs/2026/09.md)
@@ -549,6 +559,121 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details>
## 2026-10-08
### 🚀 Updated Scripts
- Revert "Immich: Pin to v3.3.0" [@MickLesk](https://github.com/MickLesk) ([#17767](https://github.com/community-scripts/ProxmoxVE/pull/17767))
### 💾 Core
- Shared VM helpers: disk import, releases, checksums, first boot, IP by MAC [@MickLesk](https://github.com/MickLesk) ([core#117](https://github.com/community-scripts/core/pull/117))
## 2026-10-07
### 🆕 New Scripts
- Fedora VM ([#17747](https://github.com/community-scripts/ProxmoxVE/pull/17747))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- AudioMuse-AI: replace the venv on update without asking [@MickLesk](https://github.com/MickLesk) ([#17738](https://github.com/community-scripts/ProxmoxVE/pull/17738))
- paperclip: run as a dedicated non-root user so Claude Code can skip permissions [@samvandenbossche](https://github.com/samvandenbossche) ([#17707](https://github.com/community-scripts/ProxmoxVE/pull/17707))
- Thingsboard: update Java version from 17 to 25 [@CerberusStyle](https://github.com/CerberusStyle) ([#17733](https://github.com/community-scripts/ProxmoxVE/pull/17733))
- #### ✨ New Features
- Immich: Pin to v3.3.0 [@vhsdream](https://github.com/vhsdream) ([#17759](https://github.com/community-scripts/ProxmoxVE/pull/17759))
- #### 💥 Breaking Changes
- OpenCloud: bump to v8.1.0, rebuild search index on upgrade [@SimKaiLong](https://github.com/SimKaiLong) ([#17710](https://github.com/community-scripts/ProxmoxVE/pull/17710))
- #### 🔧 Refactor
- Pangolin: Unpin Release, stable enough, Bump to latest [@MickLesk](https://github.com/MickLesk) ([#17740](https://github.com/community-scripts/ProxmoxVE/pull/17740))
- Refactor: Archlinux-VM [@MickLesk](https://github.com/MickLesk) ([#17741](https://github.com/community-scripts/ProxmoxVE/pull/17741))
- Refactor: MikroTik RouterOS [@MickLesk](https://github.com/MickLesk) ([#17748](https://github.com/community-scripts/ProxmoxVE/pull/17748))
### 💾 Core
- Fix Fedora and BLS cloud image console setup [@MickLesk](https://github.com/MickLesk) ([core#116](https://github.com/community-scripts/core/pull/116))
- Keep setup_nodejs alive when the caller's directory is gone [@MickLesk](https://github.com/MickLesk) ([core#114](https://github.com/community-scripts/core/pull/114))
## 2026-10-06
### 🆕 New Scripts
- Pricebuddy ([#17708](https://github.com/community-scripts/ProxmoxVE/pull/17708))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Webtrees: stop serving data/ and the source folders directly [@MickLesk](https://github.com/MickLesk) ([#17724](https://github.com/community-scripts/ProxmoxVE/pull/17724))
### 💾 Core
- Incus: check the architecture on Incus hosts too [@MickLesk](https://github.com/MickLesk) ([core#113](https://github.com/community-scripts/core/pull/113))
- Incus: Pass the app's var_* settings into Incus containers [@MickLesk](https://github.com/MickLesk) ([core#112](https://github.com/community-scripts/core/pull/112))
- Incus: stub storage_content_check on Incus [@MickLesk](https://github.com/MickLesk) ([core#104](https://github.com/community-scripts/core/pull/104))
- Incus: map Proxmox template versions to Incus image names [@MickLesk](https://github.com/MickLesk) ([core#111](https://github.com/community-scripts/core/pull/111))
- Incus: read storage names from .vars files [@MickLesk](https://github.com/MickLesk) ([core#110](https://github.com/community-scripts/core/pull/110))
- Incus: show the spinner inside containers again [@MickLesk](https://github.com/MickLesk) ([core#109](https://github.com/community-scripts/core/pull/109))
- Incus: set the hostname with sh, so it works before bash is installed [@MickLesk](https://github.com/MickLesk) ([core#102](https://github.com/community-scripts/core/pull/102))
- Incus: reserve a plain address on Incus, leave the gateway to the network [@MickLesk](https://github.com/MickLesk) ([core#101](https://github.com/community-scripts/core/pull/101))
- Incus: Wait for the network on Alpine OS too [@MickLesk](https://github.com/MickLesk) ([core#105](https://github.com/community-scripts/core/pull/105))
- Incus: do not fail the build when hostname -I is missing [@MickLesk](https://github.com/MickLesk) ([core#103](https://github.com/community-scripts/core/pull/103))
- Incus: Fuse always in unprivileged Containers, attach TUN only when container lacks it [@MickLesk](https://github.com/MickLesk) ([core#108](https://github.com/community-scripts/core/pull/108))
- Incus: accept mode=generated [@MickLesk](https://github.com/MickLesk) ([core#106](https://github.com/community-scripts/core/pull/106))
- Incus: pass the full install environment into Incus containers (quoted) [@MickLesk](https://github.com/MickLesk) ([core#107](https://github.com/community-scripts/core/pull/107))
## 2026-10-05
### 🚀 Updated Scripts
- Point to DevScripts, the renamed ProxmoxVED [@MickLesk](https://github.com/MickLesk) ([#17694](https://github.com/community-scripts/ProxmoxVE/pull/17694))
- #### 🐞 Bug Fixes
- wanderer: set the proxy secret and install plugins in their own directories [@MickLesk](https://github.com/MickLesk) ([#17698](https://github.com/community-scripts/ProxmoxVE/pull/17698))
- discourse: serve stylesheets and repair the update [@MickLesk](https://github.com/MickLesk) ([#17697](https://github.com/community-scripts/ProxmoxVE/pull/17697))
- wikijs: bump Node.js from 24 to 26 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#17689](https://github.com/community-scripts/ProxmoxVE/pull/17689))
- jotty: bump Node.js from 22 to 24 [@github-actions[bot]](https://github.com/github-actions[bot]) ([#17688](https://github.com/community-scripts/ProxmoxVE/pull/17688))
### 💾 Core
- Read releases from github.com when the API is rate limited, resume stalled downloads [@MickLesk](https://github.com/MickLesk) ([core#99](https://github.com/community-scripts/core/pull/99))
- Check for template and container storage before the settings menu [@MickLesk](https://github.com/MickLesk) ([core#98](https://github.com/community-scripts/core/pull/98))
- Check /etc/pve before the settings menu [@MickLesk](https://github.com/MickLesk) ([core#97](https://github.com/community-scripts/core/pull/97))
- Check container settings before pct create rejects them [@MickLesk](https://github.com/MickLesk) ([core#96](https://github.com/community-scripts/core/pull/96))
- PVE: Smart Diagnosis - say why a container would not start [@MickLesk](https://github.com/MickLesk) ([core#95](https://github.com/community-scripts/core/pull/95))
- Retry template downloads that pveam reports as done but are not [@MickLesk](https://github.com/MickLesk) ([core#94](https://github.com/community-scripts/core/pull/94))
- Check the OS release against pve-container before creating anything [@MickLesk](https://github.com/MickLesk) ([core#93](https://github.com/community-scripts/core/pull/93))
- Rename "ProxmoxVED"-Links to "DevScripts" [@MickLesk](https://github.com/MickLesk) ([core#91](https://github.com/community-scripts/core/pull/91))
### 🧰 Tools
- #### 🐞 Bug Fixes
- monitor-all: read container IPs from the host side [@jasonobrien](https://github.com/jasonobrien) ([#17686](https://github.com/community-scripts/ProxmoxVE/pull/17686))
## 2026-10-04
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- immich: read the Intel runtime from the pinned release [@MickLesk](https://github.com/MickLesk) ([#17677](https://github.com/community-scripts/ProxmoxVE/pull/17677))
### 💾 Core
- better explain unsupported version & upgrade path for pve [@MickLesk](https://github.com/MickLesk) ([core#86](https://github.com/community-scripts/core/pull/86))
- Quote PostgreSQL identifiers and drop spaces from the creds file name [@MickLesk](https://github.com/MickLesk) ([core#89](https://github.com/community-scripts/core/pull/89))
- Find the default Rust toolchain in current rustup output [@MickLesk](https://github.com/MickLesk) ([core#88](https://github.com/community-scripts/core/pull/88))
## 2026-10-03
### 🆕 New Scripts
@@ -559,6 +684,8 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- #### 🐞 Bug Fixes
- hermesagent: download the installer before running it [@MickLesk](https://github.com/MickLesk) ([#17666](https://github.com/community-scripts/ProxmoxVE/pull/17666))
- frigate: raise the Node heap for the web build [@MickLesk](https://github.com/MickLesk) ([#17667](https://github.com/community-scripts/ProxmoxVE/pull/17667))
- Tracearr: workaround for failing map tiles download and data preservation [@durzo](https://github.com/durzo) ([#17661](https://github.com/community-scripts/ProxmoxVE/pull/17661))
- fix(nginxproxymanager): clean yarn cache after builds to prevent disk growth [@PsycoStea](https://github.com/PsycoStea) ([#17653](https://github.com/community-scripts/ProxmoxVE/pull/17653))
@@ -566,6 +693,10 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- Several Scripts: refactor msg_ blocks, generate passwords with helper, add CLEAN_INSTALL_KEEP [@MickLesk](https://github.com/MickLesk) ([#17655](https://github.com/community-scripts/ProxmoxVE/pull/17655))
### 💾 Core
- detect_repo_source: read the license header and fall back to ProxmoxVE [@MickLesk](https://github.com/MickLesk) ([core#85](https://github.com/community-scripts/core/pull/85))
## 2026-10-02
### 🚀 Updated Scripts
@@ -1209,162 +1340,3 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
### 💾 Core
- setup_go: resolve bare major.minor versions to the latest patch release [@MickLesk](https://github.com/MickLesk) ([core#24](https://github.com/community-scripts/core/pull/24))
## 2026-09-03
### 🚀 Updated Scripts
- Immich: bump libheif and libraw [@vhsdream](https://github.com/vhsdream) ([#16996](https://github.com/community-scripts/ProxmoxVE/pull/16996))
- #### 🐞 Bug Fixes
- romm: allow git-based npm dependency for rom-patcher under npm v12 [@MickLesk](https://github.com/MickLesk) ([#16990](https://github.com/community-scripts/ProxmoxVE/pull/16990))
- Pin Go to the version each project declares in go.mod [@MickLesk](https://github.com/MickLesk) ([#16976](https://github.com/community-scripts/ProxmoxVE/pull/16976))
- Authentik update 2026.8.1 [@thieneret](https://github.com/thieneret) ([#16980](https://github.com/community-scripts/ProxmoxVE/pull/16980))
## 2026-09-02
### 🆕 New Scripts
- OwnTracks-Recorder ([#16967](https://github.com/community-scripts/ProxmoxVE/pull/16967))
- PeerTube ([#16966](https://github.com/community-scripts/ProxmoxVE/pull/16966))
- Kaneo ([#16965](https://github.com/community-scripts/ProxmoxVE/pull/16965))
- JDownloader ([#16964](https://github.com/community-scripts/ProxmoxVE/pull/16964))
- ReadMeABook ([#16963](https://github.com/community-scripts/ProxmoxVE/pull/16963))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Enhance backup process in teddycloud.sh [@MickLesk](https://github.com/MickLesk) ([#16946](https://github.com/community-scripts/ProxmoxVE/pull/16946))
- mealie: copy Nuxt generate output and use pnpm when lockfile is present [@mjhuff](https://github.com/mjhuff) ([#16938](https://github.com/community-scripts/ProxmoxVE/pull/16938))
- OpenThread-BR: Clean build directory before update [@tomfrenzel](https://github.com/tomfrenzel) ([#16949](https://github.com/community-scripts/ProxmoxVE/pull/16949))
- #### 🔧 Refactor
- Scripts: use shared core bootstrap for final 114 Script Batch [@MickLesk](https://github.com/MickLesk) ([#16953](https://github.com/community-scripts/ProxmoxVE/pull/16953))
- Scripts: use shared core bootstrap for next 115 Script Batch [@MickLesk](https://github.com/MickLesk) ([#16952](https://github.com/community-scripts/ProxmoxVE/pull/16952))
- Scripts: use shared core bootstrap for next 115 Script Batch [@MickLesk](https://github.com/MickLesk) ([#16951](https://github.com/community-scripts/ProxmoxVE/pull/16951))
- Scripts: use shared core bootstrap for next 100 Script Batch [@MickLesk](https://github.com/MickLesk) ([#16950](https://github.com/community-scripts/ProxmoxVE/pull/16950))
### 💾 Core
- setup_meilisearch: generate a 32-byte master key [@MickLesk](https://github.com/MickLesk) ([core#20](https://github.com/community-scripts/core/pull/20))
- setup_meilisearch: generate a 32-byte master key [@MickLesk](https://github.com/MickLesk) ([core#19](https://github.com/community-scripts/core/pull/19))
- setup_nodejs: restore the npm allowScripts bypass lost in the migration [@MickLesk](https://github.com/MickLesk) ([core#18](https://github.com/community-scripts/core/pull/18))
## 2026-09-01
### 🆕 New Scripts
- Mailpit ([#16942](https://github.com/community-scripts/ProxmoxVE/pull/16942))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Revert Aurral to Node22 [@Copilot](https://github.com/Copilot) ([#16930](https://github.com/community-scripts/ProxmoxVE/pull/16930))
- jellyfin: verify repo suite via fallback chain and use ensure_dependencies for clearer apt failures [@MickLesk](https://github.com/MickLesk) ([#16916](https://github.com/community-scripts/ProxmoxVE/pull/16916))
- #### 🔧 Refactor
- Move the next 25 scripts onto the core engine [@MickLesk](https://github.com/MickLesk) ([#16934](https://github.com/community-scripts/ProxmoxVE/pull/16934))
### 💾 Core
- Generate app headers [@github-actions[bot]](https://github.com/github-actions[bot]) ([core#15](https://github.com/community-scripts/core/pull/15))
- Report the exit code the engine actually saw [@MickLesk](https://github.com/MickLesk) ([core#17](https://github.com/community-scripts/core/pull/17))
- Silence npm's update notice so the real error stays visible [@MickLesk](https://github.com/MickLesk) ([core#16](https://github.com/community-scripts/core/pull/16))
### 🧰 Tools
- #### 🐞 Bug Fixes
- fix(add-iptag): merge live IPv4 addresses for running LXCs [@phillf](https://github.com/phillf) ([#16691](https://github.com/community-scripts/ProxmoxVE/pull/16691))
## 2026-08-31
### 🆕 New Scripts
- Aurral ([#16908](https://github.com/community-scripts/ProxmoxVE/pull/16908))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- openwebui: add UV_HTTP_TIMEOUT and retry loop to prevent uv install hangs [@MickLesk](https://github.com/MickLesk) ([#16917](https://github.com/community-scripts/ProxmoxVE/pull/16917))
- bambuddy: force asyncio loop, uvloop breaks camera proxy handlers [@MickLesk](https://github.com/MickLesk) ([#16904](https://github.com/community-scripts/ProxmoxVE/pull/16904))
- bookorbit: raise service start timeout, migration can exceed systemd default [@MickLesk](https://github.com/MickLesk) ([#16860](https://github.com/community-scripts/ProxmoxVE/pull/16860))
- node-red: remove --unsafe-perm flag [@MickLesk](https://github.com/MickLesk) ([#16859](https://github.com/community-scripts/ProxmoxVE/pull/16859))
- directus: add build-essential dependency [@MickLesk](https://github.com/MickLesk) ([#16858](https://github.com/community-scripts/ProxmoxVE/pull/16858))
- #### ✨ New Features
- haos-vm: add optional x86-64-v2-AES CPU option, future HA numpy builds need it [@MickLesk](https://github.com/MickLesk) ([#16868](https://github.com/community-scripts/ProxmoxVE/pull/16868))
- #### 🔧 Refactor
- omv: migrate to new package repo host (packages.openmediavault.org) is dead [@MickLesk](https://github.com/MickLesk) ([#16918](https://github.com/community-scripts/ProxmoxVE/pull/16918))
- yuvomi/aurral: bump NODE_VERSION [@MickLesk](https://github.com/MickLesk) ([#16914](https://github.com/community-scripts/ProxmoxVE/pull/16914))
- vaultwarden: relax cargo release profile via env vars to avoid build OOM [@MickLesk](https://github.com/MickLesk) ([#16915](https://github.com/community-scripts/ProxmoxVE/pull/16915))
- kima-hub/maintainerr/planka/spliit: bump NODE_VERSION [@MickLesk](https://github.com/MickLesk) ([#16905](https://github.com/community-scripts/ProxmoxVE/pull/16905))
- gatus: pin Go toolchain to gatus's own go.mod version [@MickLesk](https://github.com/MickLesk) ([#16893](https://github.com/community-scripts/ProxmoxVE/pull/16893))
- immich: tolerate enable-maintenance-mode crash, same as disable-maintenance-mode [@MickLesk](https://github.com/MickLesk) ([#16866](https://github.com/community-scripts/ProxmoxVE/pull/16866))
- move the hardware-accelerated scripts onto new core [@MickLesk](https://github.com/MickLesk) ([#16864](https://github.com/community-scripts/ProxmoxVE/pull/16864))
- ntopng: use ntop.org's documented apt repo per Debian codename, not always apt-stable [@MickLesk](https://github.com/MickLesk) ([#16862](https://github.com/community-scripts/ProxmoxVE/pull/16862))
- Refactor: OpenGist [@MickLesk](https://github.com/MickLesk) ([#16861](https://github.com/community-scripts/ProxmoxVE/pull/16861))
### 💾 Core
- Refactor VM script settings and fix load_functions errors [@MickLesk](https://github.com/MickLesk) ([core#13](https://github.com/community-scripts/core/pull/13))
- Ask ProxmoxVE to refresh its changelog on merge [@MickLesk](https://github.com/MickLesk) ([core#11](https://github.com/community-scripts/core/pull/11))
- Lift the settings summary and the mode fork into vm-core [@MickLesk](https://github.com/MickLesk) ([core#12](https://github.com/community-scripts/core/pull/12))
### 🧰 Tools
- #### 🐞 Bug Fixes
- filebrowser-quantum: strip removed disableIndexing key on update, restart service [@MickLesk](https://github.com/MickLesk) ([#16892](https://github.com/community-scripts/ProxmoxVE/pull/16892))
### 📚 Documentation
- Include engine pull requests in the changelog [@MickLesk](https://github.com/MickLesk) ([#16867](https://github.com/community-scripts/ProxmoxVE/pull/16867))
## 2026-08-30
### 🆕 New Scripts
- SolidInvoice ([#16869](https://github.com/community-scripts/ProxmoxVE/pull/16869))
- Super-Productivity ([#16870](https://github.com/community-scripts/ProxmoxVE/pull/16870))
- Defguard ([#16871](https://github.com/community-scripts/ProxmoxVE/pull/16871))
- OpenBao ([#16872](https://github.com/community-scripts/ProxmoxVE/pull/16872))
### 🚀 Updated Scripts
- #### 🔧 Refactor
- general: remove gitea links overall [@MickLesk](https://github.com/MickLesk) ([#16863](https://github.com/community-scripts/ProxmoxVE/pull/16863))
## 2026-08-29
### 📚 Documentation
- github action: post the command that tests a ct/ or install/ change [@MickLesk](https://github.com/MickLesk) ([#16833](https://github.com/community-scripts/ProxmoxVE/pull/16833))
## 2026-08-28
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- homepage: set CI=true so pnpm can self-heal node_modules without a TTY [@MickLesk](https://github.com/MickLesk) ([#16841](https://github.com/community-scripts/ProxmoxVE/pull/16841))
- droppedneedle: launch via automatic_upgrade orchestrator [@MickLesk](https://github.com/MickLesk) ([#16834](https://github.com/community-scripts/ProxmoxVE/pull/16834))
- calibre-web: point cps at explicit db path, src-layout package has no default anymore [@MickLesk](https://github.com/MickLesk) ([#16832](https://github.com/community-scripts/ProxmoxVE/pull/16832))
- podman: pull portainer images before systemd unit start to avoid start timeout [@MickLesk](https://github.com/MickLesk) ([#16831](https://github.com/community-scripts/ProxmoxVE/pull/16831))
- gitea: make gitea own its home dir instead of toggling group perms [@MickLesk](https://github.com/MickLesk) ([#16830](https://github.com/community-scripts/ProxmoxVE/pull/16830))
- pve-ups: fix: add pip binary [@CrazyWolf13](https://github.com/CrazyWolf13) ([#16820](https://github.com/community-scripts/ProxmoxVE/pull/16820))
- #### 🔧 Refactor
- Refactor: Calibre-Web database creation [@MickLesk](https://github.com/MickLesk) ([#16842](https://github.com/community-scripts/ProxmoxVE/pull/16842))
- mastodon: read .ruby-version dynamically instead of hardcoding 4.0.5 [@MickLesk](https://github.com/MickLesk) ([#16829](https://github.com/community-scripts/ProxmoxVE/pull/16829))
+6 -6
View File
@@ -9,13 +9,13 @@ For detailed coding standards and full documentation, visit **[community-scripts
## How Can I Help?
> [!IMPORTANT]
> **New scripts** must always be submitted to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) first — not to this repository.
> **New scripts** must always be submitted to [DevScripts](https://github.com/community-scripts/DevScripts) first — not to this repository.
> PRs with new scripts opened directly against ProxmoxVE **will be closed without review**.
> **Bug fixes, improvements, and features for existing scripts** go here (ProxmoxVE).
| I want to… | Where to go |
| :------------------------------------------ | :------------------------------------------------------------------------------------------- |
| **Add a brand-new script** | [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) — testing repo for new scripts |
| **Add a brand-new script** | [DevScripts](https://github.com/community-scripts/DevScripts) — testing repo for new scripts |
| **Fix a bug or improve an existing script** | This repo (ProxmoxVE) — open a PR here |
| **Add a feature to an existing script** | This repo (ProxmoxVE) — open a PR here |
| Report a bug or broken script | [Open an Issue](https://github.com/community-scripts/ProxmoxVE/issues) |
@@ -55,13 +55,13 @@ Use existing scripts in [`ct/`](ct/) and [`install/`](install/) as reference. Fu
New scripts are **not accepted directly in this repository**. The workflow is:
1. Fork [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) and clone it
1. Fork [DevScripts](https://github.com/community-scripts/DevScripts) and clone it
2. Create a branch: `git switch -c feat/myapp`
3. Write your two script files:
- `ct/myapp.sh`
- `install/myapp-install.sh`
4. Test thoroughly in ProxmoxVED — run the script against a real Proxmox instance
5. Open a PR in **ProxmoxVED** for review and testing
4. Test thoroughly in DevScripts — run the script against a real Proxmox instance
5. Open a PR in **DevScripts** for review and testing
6. Once accepted and verified there, the script will be promoted to ProxmoxVE by maintainers
Follow the coding standards at [community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution).
@@ -193,5 +193,5 @@ create` still ran and the container was still built.
- **Website metadata** (name, description, logo, tags) is managed via the website — use the "Report Issue" link on any script page to request changes. Do not submit metadata changes via repo files.
- **JSON files** in `json/` define script properties used by the website. See existing files for structure reference.
- Keep PRs small and focused. One fix or feature per PR is ideal.
- PRs with **new scripts** opened against ProxmoxVE will be closed — submit them to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) instead.
- PRs with **new scripts** opened against ProxmoxVE will be closed — submit them to [DevScripts](https://github.com/community-scripts/DevScripts) instead.
- PRs that fail CI checks will not be merged.
+2 -2
View File
@@ -93,7 +93,7 @@ This project runs on community contributions. Whether you want to write new scri
| I want to… | Go here |
| ------------------------------------- | ------------------------------------------------------------------------------------------------- |
| Add a **new** script | [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) — new scripts are tested here first |
| Add a **new** script | [DevScripts](https://github.com/community-scripts/DevScripts) — new scripts are tested here first |
| Fix or improve an **existing** script | [Contributing Guidelines](CONTRIBUTING.md) — open a PR in this repo |
| Report a bug or broken script | [Issues](https://github.com/community-scripts/ProxmoxVE/issues) |
| Request a new script or feature | [Discussions](https://github.com/community-scripts/ProxmoxVE/discussions) |
@@ -102,7 +102,7 @@ This project runs on community contributions. Whether you want to write new scri
### Before you open a PR
- **New scripts go to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED), not here.** PRs with new scripts opened directly against this repo will be closed.
- **New scripts go to [DevScripts](https://github.com/community-scripts/DevScripts), not here.** PRs with new scripts opened directly against this repo will be closed.
- Bug fixes and improvements to existing scripts belong in this repo — read the [Contributing Guidelines](CONTRIBUTING.md) first.
- Keep PRs focused. One fix or feature per PR.
- Document what your script installs and any non-obvious decisions in the corresponding JSON metadata file.
+1 -1
View File
@@ -58,7 +58,7 @@ function update_script() {
msg_info "Updating Python Environment (${AUDIOMUSE_BACKEND})"
cd /opt/audiomuse-ai
$STD uv venv --seed --python "$PY_VERSION" /opt/audiomuse-ai/.venv
$STD uv venv --clear --seed --python "$PY_VERSION" /opt/audiomuse-ai/.venv
$STD uv pip install --python /opt/audiomuse-ai/.venv \
-r "/opt/audiomuse-ai/requirements/${REQ_COMMON}" \
-r "/opt/audiomuse-ai/requirements/${REQ_ACCEL}"
+6 -1
View File
@@ -48,7 +48,12 @@ function update_script() {
$STD corepack prepare "pnpm@${PNPM_VERSION}" --activate
$STD pnpm install --frozen-lockfile
$STD pnpm --filter client run build-only
# vite's bundler (rolldown) crashes at random on some builds, rolldown#10860.
for attempt in 1 2 3; do
$STD pnpm --filter client run build-only && break
[[ $attempt -eq 3 ]] && { msg_error "Client build failed three times"; exit 1; }
msg_warn "Client build failed (attempt $attempt), retrying"
done
$STD pnpm --filter server run build
cp -r /opt/bookorbit/client/dist /opt/bookorbit/server/public
mkdir -p /opt/bookorbit/server/migrations
+21 -14
View File
@@ -36,28 +36,35 @@ function update_script() {
exit
fi
msg_info "Stopping Service"
systemctl stop discourse
msg_ok "Stopped Service"
if grep -q 'X-Accel-Mapping' /etc/nginx/sites-available/discourse 2>/dev/null; then
msg_info "Fixing stylesheet delivery in Nginx"
sed -i '/X-Accel-Mapping/d' /etc/nginx/sites-available/discourse
$STD systemctl reload nginx
msg_ok "Fixed stylesheet delivery in Nginx"
fi
create_backup /opt/discourse/.env
msg_info "Stopping Services"
systemctl stop discourse discourse-sidekiq
msg_ok "Stopped Services"
msg_info "Updating Discourse"
PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
cd /opt/discourse
git pull origin main
$STD bundle install --deployment --without test development
$STD yarn install
export PATH="$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
set -a
source /opt/discourse/.env
set +a
$STD git pull origin main
$STD bundle install
$STD pnpm install
$STD runuser -u postgres -- psql -d discourse -c "CREATE EXTENSION IF NOT EXISTS vector;"
$STD bundle exec rails assets:precompile
$STD bundle exec rails db:migrate
$STD bundle exec rails assets:precompile
msg_ok "Updated Discourse"
restore_backup
msg_info "Starting Service"
systemctl start discourse
msg_ok "Started Service"
msg_info "Starting Services"
systemctl start discourse discourse-sidekiq
msg_ok "Started Services"
msg_ok "Updated successfully!"
exit
}
+29 -37
View File
@@ -65,28 +65,29 @@ EOF
msg_ok "Installed/upgraded Testing repo packages"
fi
if [[ -f /etc/apt/sources.list.d/mise.list ]]; then
msg_info "Moving Mise to the GitHub release"
$STD apt purge -y mise
rm -f /etc/apt/sources.list.d/mise.list /etc/apt/keyrings/mise-archive-keyring.pub
msg_ok "Removed the Mise APT repository"
fi
if check_for_gh_release "mise" "jdx/mise"; then
fetch_and_deploy_gh_release "mise" "jdx/mise" "singlefile" "latest" "/usr/local/bin" "mise-v*-linux-$(arch_resolve "x64" "arm64")"
if [[ ! -f /etc/apt/sources.list.d/mise.list ]]; then
msg_info "Installing Mise"
curl -fSs https://mise.jdx.dev/gpg-key.pub | tee /etc/apt/keyrings/mise-archive-keyring.pub 1>/dev/null
echo "deb [signed-by=/etc/apt/keyrings/mise-archive-keyring.pub arch=$(arch_resolve)] https://mise.jdx.dev/deb stable main" >/etc/apt/sources.list.d/mise.list
ensure_dependencies mise
msg_ok "Installed Mise"
fi
STAGING_DIR=/opt/staging
BASE_DIR=${STAGING_DIR}/base-images
SOURCE_DIR=${STAGING_DIR}/image-source
cd /tmp
RELEASE="v3.3.0"
if [[ -f ~/.intel_version ]]; then
curl_with_retry "https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/machine-learning/Dockerfile" "Dockerfile"
readarray -t INTEL_URLS < <(
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $3}'
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
)
INTEL_RELEASE="$(grep "intel-opencl-icd_" ./Dockerfile | awk -F '_' '{print $2}')"
if [[ "$INTEL_RELEASE" != "$(cat ~/.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 ||
curl_with_retry "${INTEL_SRC}/Dockerfile" "./intel-runtime"
readarray -t INTEL_URLS < <(grep -oE 'https://github\.com/intel/[^[:space:]]+\.deb' ./intel-runtime)
INTEL_RELEASE="$(grep -oE 'intel-opencl-icd_[^_]+' ./intel-runtime | cut -d_ -f2)" || true
rm -f ./intel-runtime
if [[ -z "$INTEL_RELEASE" ]]; then
msg_warn "No Intel runtime found for Immich ${RELEASE}, keeping the installed one"
elif [[ "$INTEL_RELEASE" != "$(cat ~/.intel_version)" ]]; then
msg_info "Updating Intel OpenVINO dependencies"
for url in "${INTEL_URLS[@]}"; do
curl_with_retry "$url" "$(basename "$url")"
@@ -98,7 +99,6 @@ EOF
rm ./*.deb
$STD apt-mark hold libigdgmm12
dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version
rm -f ./Dockerfile
msg_ok "Updated Intel OpenVINO dependencies"
fi
fi
@@ -114,7 +114,6 @@ EOF
msg_ok "Image-processing libraries up to date"
fi
RELEASE="v3.2.4"
if check_for_gh_release "Immich" "immich-app/immich" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
msg_info "Enabling Maintenance Mode"
@@ -275,12 +274,13 @@ EOF
msg_info "Updating Intel OpenVINO machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT -Pnu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
[[ $attempt -lt 3 ]] && msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
[[ $attempt -eq 3 ]] && { msg_error "uv sync failed three times, the machine-learning environment was not built"; exit 1; }
msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
done
patchelf --clear-execstack "${VIRTUAL_ENV}/lib/python3.13/site-packages/onnxruntime/capi/onnxruntime_pybind11_state.cpython-313-$(arch_resolve "x86_64" "aarch64")-linux-gnu.so"
msg_ok "Updated Intel OpenVINO machine-learning"
else
ML_PYTHON="python3.11"
ML_PYTHON="python3.13"
msg_info "Pre-installing Python ${ML_PYTHON} for machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV -Pnu immich uv python install "${ML_PYTHON}" && break
@@ -290,7 +290,8 @@ EOF
msg_info "Updating machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT -Pnu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
[[ $attempt -lt 3 ]] && msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
[[ $attempt -eq 3 ]] && { msg_error "uv sync failed three times, the machine-learning environment was not built"; exit 1; }
msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
done
msg_ok "Updated machine-learning"
fi
@@ -334,6 +335,10 @@ EOF
sed -i -e '$a\' "$INSTALL_DIR"/.env
echo "IMMICH_HELMET_FILE=true" >>"$INSTALL_DIR"/.env
fi
if ! grep -q 'MODEL_REVISION' "$INSTALL_DIR"/.env; then
sed -i -e '$a\' "$INSTALL_DIR"/.env
echo "MACHINE_LEARNING_MODEL_REVISION=v2" >>"$INSTALL_DIR"/.env
fi
if grep -q 'ExecStart=/usr/bin/node' /etc/systemd/system/immich-web.service; then
sed -i '/^EnvironmentFile=/d' /etc/systemd/system/immich-web.service
@@ -342,25 +347,12 @@ EOF
fi
# MickLesk temporary patch for HEIC thumbnail gen
msg_info "Patching media.repository.js"
MEDIA_REPO_JS="/opt/immich/app/dist/repositories/media.repository.js"
if [[ -f "$MEDIA_REPO_JS" ]]; then
python3 - <<'PY'
from pathlib import Path
p = Path('/opt/immich/app/dist/repositories/media.repository.js')
s = p.read_text()
old = "(0, sharp_1.default)(input).metadata()"
new = "(0, sharp_1.default)(input, { unlimited: true, limitInputPixels: false }).metadata()"
if new in s:
print('hotfix already there')
elif old in s:
p.write_text(s.replace(old, new, 1))
print('hotfix applied')
else:
print('pattern not found, skipped')
PY
fi
if grep -qF "(0, sharp_1.default)(input).metadata()" "$MEDIA_REPO_JS" 2>/dev/null; then
msg_info "Patching media.repository.js"
sed -i '0,/(0, sharp_1\.default)(input)\.metadata()/s//(0, sharp_1.default)(input, { unlimited: true, limitInputPixels: false }).metadata()/' "$MEDIA_REPO_JS"
msg_ok "Patched media.repository.js"
fi
# chown excluding upload dir contents (may be a mount with restricted permissions)
chown immich:immich "$INSTALL_DIR"
+1 -1
View File
@@ -38,7 +38,7 @@ function update_script() {
create_backup /opt/jotty/.env /opt/jotty/data /opt/jotty/config
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "jotty" "fccview/jotty" "prebuild" "latest" "/opt/jotty" "jotty_*_prebuild.tar.gz"
restore_backup
+30 -1
View File
@@ -31,8 +31,9 @@ function update_script() {
exit
fi
RELEASE="v7.4.0"
RELEASE="v8.1.0"
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
OLD_VERSION="$(cat ~/.opencloud 2>/dev/null)"
msg_info "Stopping services"
systemctl stop opencloud opencloud-wopi
msg_ok "Stopped services"
@@ -70,6 +71,34 @@ function update_script() {
msg_info "Starting services"
systemctl start opencloud opencloud-wopi
msg_ok "Started services"
if [[ -z "$OLD_VERSION" || "${OLD_VERSION#v}" =~ ^[0-7]\. ]]; then
# The index CLI cancels the rebuild when interrupted, so it runs as its own unit and the
# update only waits for it. Restart covers a search service that is still starting.
msg_info "Rebuilding search index (safe to interrupt, it continues in the background)"
REINDEX_START="$(date '+%Y-%m-%d %H:%M:%S')"
systemctl reset-failed opencloud-reindex &>/dev/null || true
$STD systemd-run --unit=opencloud-reindex --uid=opencloud --gid=opencloud \
-p EnvironmentFile=/etc/opencloud/opencloud.env -p Restart=on-failure -p RestartSec=15 \
-p StartLimitIntervalSec=900 -p StartLimitBurst=20 \
/usr/bin/opencloud search index --all-spaces --force-rescan --insecure
while [[ "$(systemctl show -p ActiveState --value opencloud-reindex)" =~ ^(active|activating)$ ]]; do
sleep 10
done
if [[ "$(systemctl show -p ActiveState --value opencloud-reindex)" == "failed" ]]; then
msg_ok "Stopped waiting for the search index rebuild"
msg_warn "The rebuild did not complete, see: journalctl -u opencloud-reindex"
msg_warn "Retry with: systemctl reset-failed opencloud-reindex; systemd-run --unit=opencloud-reindex \
--uid=opencloud --gid=opencloud -p EnvironmentFile=/etc/opencloud/opencloud.env \
/usr/bin/opencloud search index --all-spaces --force-rescan --insecure"
else
msg_ok "Rebuilt search index"
if journalctl -u opencloud-reindex --since "$REINDEX_START" --no-pager | grep -qE '/[0-9]+ ERROR'; then
msg_warn "Some spaces could not be indexed, see: journalctl -u opencloud-reindex"
fi
msg_warn "Once search finds older files, remove the old index: rm -rf /var/lib/opencloud/search/bleve"
fi
fi
msg_ok "Updated successfully"
fi
exit
+3 -4
View File
@@ -7,7 +7,6 @@ source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_
# Source: https://pangolin.net/ | Github: https://github.com/fosrl/pangolin
APP="Pangolin"
PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.23.0}"
var_tags="${var_tags:-proxy}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
@@ -38,7 +37,7 @@ function update_script() {
ensure_dependencies build-essential python3
if ! command -v psql &>/dev/null; then
msg_error "This installation uses SQLite and cannot be upgraded to Pangolin ${PANGOLIN_VERSION}."
msg_error "This installation uses SQLite and cannot be upgraded to latest Pangolin."
echo -e "${INFO}${YW}Starting with Pangolin 1.20.0, PostgreSQL is required as the database backend.${CL}"
echo -e "${INFO}${YW}An automatic migration of your existing SQLite data is not supported.${CL}"
echo -e "${INFO}${YW}Please create a new LXC with the Pangolin install script, which sets up PostgreSQL automatically.${CL}"
@@ -48,7 +47,7 @@ function update_script() {
NODE_VERSION="24" setup_nodejs
if check_for_gh_release "pangolin" "fosrl/pangolin" "$PANGOLIN_VERSION" "Pinned to a tested release because Pangolin's schema changes have repeatedly broken unattended updates. To try a newer version at your own risk, run: 'export PANGOLIN_VERSION=<tag>' and re-run update. If it breaks, please open an issue at https://github.com/community-scripts/ProxmoxVE/issues with the error log."; then
if check_for_gh_release "pangolin" "fosrl/pangolin"; then
msg_info "Stopping Service"
systemctl stop pangolin
systemctl stop gerbil
@@ -57,7 +56,7 @@ function update_script() {
DB_URL=$(sed -n 's/.*connection_string: "\(.*\)".*/\1/p' /opt/pangolin/config/config.yml)
create_backup /opt/pangolin/config
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VERSION"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
msg_info "Updating Pangolin"
+29 -1
View File
@@ -15,6 +15,8 @@ var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
export var_paperclip_user="${var_paperclip_user:-}"
export var_paperclip_pass="${var_paperclip_pass:-}"
header_info "$APP"
variables
@@ -59,9 +61,35 @@ function update_script() {
@openai/codex@latest
msg_ok "Updated Agent CLIs"
# Claude Code refuses --dangerously-skip-permissions as root; migrate existing installs to a dedicated user
PAPERCLIP_USER=$(sed -n 's/^User=//p' /etc/systemd/system/paperclip.service)
if [[ -z "$PAPERCLIP_USER" || "$PAPERCLIP_USER" == "root" ]]; then
PAPERCLIP_USER="${var_paperclip_user:-paperclip}"
if [[ "$PAPERCLIP_USER" == "root" || ! "$PAPERCLIP_USER" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]]; then
msg_error "Invalid var_paperclip_user '${PAPERCLIP_USER}' (must be a non-root lowercase Linux username)"
exit 1
fi
PAPERCLIP_USER_HOME="/home/${PAPERCLIP_USER}"
id -u "$PAPERCLIP_USER" &>/dev/null || useradd -m -d "$PAPERCLIP_USER_HOME" -s /bin/bash "$PAPERCLIP_USER"
passwd -S "$PAPERCLIP_USER" 2>/dev/null | grep -q " P " || passwd -l "$PAPERCLIP_USER" &>/dev/null
mkdir -p "${PAPERCLIP_USER_HOME}/.claude" "${PAPERCLIP_USER_HOME}/.codex"
[[ -d /root/.claude ]] && cp -a /root/.claude/. "${PAPERCLIP_USER_HOME}/.claude/"
[[ -d /root/.codex ]] && cp -a /root/.codex/. "${PAPERCLIP_USER_HOME}/.codex/"
sed -i \
-e "s|^User=.*|User=${PAPERCLIP_USER}\nGroup=${PAPERCLIP_USER}|" \
-e "s|^Environment=HOME=.*|Environment=HOME=${PAPERCLIP_USER_HOME}|" \
-e "s|^Environment=CODEX_HOME=.*|Environment=CODEX_HOME=${PAPERCLIP_USER_HOME}/.codex|" \
-e "s|/root/.local/bin|${PAPERCLIP_USER_HOME}/.local/bin|" \
/etc/systemd/system/paperclip.service
systemctl daemon-reload
fi
PAPERCLIP_USER_HOME=$(getent passwd "$PAPERCLIP_USER" | cut -d: -f6)
chmod 600 /opt/paperclip-ai/.env
chown -R "${PAPERCLIP_USER}:${PAPERCLIP_USER}" /opt/paperclip-ai /opt/paperclip-data "$PAPERCLIP_USER_HOME"
msg_info "Running Database Migrations"
set -a && source /opt/paperclip-ai/.env && set +a
$STD pnpm db:migrate
$STD runuser -u "$PAPERCLIP_USER" -- env HOME="$PAPERCLIP_USER_HOME" bash -c 'cd /opt/paperclip-ai && pnpm db:migrate'
msg_ok "Ran Database Migrations"
msg_info "Starting Service"
+106
View File
@@ -0,0 +1,106 @@
#!/usr/bin/env bash
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/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://github.com/jez500/pricebuddy
APP="PriceBuddy"
var_tags="${var_tags:-shopping;price-tracker}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-3072}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-no}" # the bundled scraper runs Google Chrome, which is amd64-only
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/pricebuddy ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "pricebuddy" "jez500/pricebuddy"; then
msg_info "Stopping PriceBuddy Worker"
systemctl stop pricebuddy-worker
msg_ok "Stopped PriceBuddy Worker"
setup_composer
NODE_VERSION="22" setup_nodejs
create_backup /opt/pricebuddy/.env /opt/pricebuddy/storage
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pricebuddy" "jez500/pricebuddy" "tarball"
restore_backup
msg_info "Updating PriceBuddy"
cd /opt/pricebuddy
sed -i "s/^APP_VERSION=.*/APP_VERSION=$(cat ~/.pricebuddy)/" .env
$STD composer install --no-dev --optimize-autoloader --no-interaction
$STD npm install
$STD npm run build
$STD php artisan storage:link
$STD php artisan migrate --force
$STD php artisan optimize
$STD php artisan icons:cache
$STD php artisan buddy:regenerate-price-cache
chown -R www-data:www-data /opt/pricebuddy
msg_ok "Updated PriceBuddy"
msg_info "Starting PriceBuddy Worker"
systemctl start pricebuddy-worker
msg_ok "Started PriceBuddy Worker"
msg_ok "Updated successfully!"
fi
if check_for_gh_release "seleniumbase-scrapper" "jez500/seleniumbase-scrapper"; then
msg_info "Stopping SeleniumBase Scrapper"
systemctl stop seleniumbase-scrapper
msg_ok "Stopped SeleniumBase Scrapper"
msg_info "Updating Google Chrome"
apt_update_safe
upgrade_packages_with_retry google-chrome-stable
msg_ok "Updated Google Chrome"
PYTHON_VERSION="3.12" setup_uv
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "seleniumbase-scrapper" "jez500/seleniumbase-scrapper" "tarball"
msg_info "Updating SeleniumBase Scrapper"
$STD uv venv --python 3.12 /opt/seleniumbase-scrapper/.venv
$STD uv pip install --python /opt/seleniumbase-scrapper/.venv/bin/python \
"seleniumbase==$(sed -n 's/^ARG SELENIUMBASE_VERSION=v//p' /opt/seleniumbase-scrapper/Dockerfile)" \
flask \
beautifulsoup4
$STD /opt/seleniumbase-scrapper/.venv/bin/seleniumbase get chromedriver
msg_ok "Updated SeleniumBase Scrapper"
msg_info "Starting SeleniumBase Scrapper"
systemctl start seleniumbase-scrapper
msg_ok "Started SeleniumBase Scrapper"
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 "${GATEWAY}${BGN}http://${IP}${CL}"
echo -e "${INFO}${YW}Log in as admin@example.com - the password is APP_USER_PASSWORD in /opt/pricebuddy/.env${CL}"
+1
View File
@@ -30,6 +30,7 @@ function update_script() {
exit
fi
JAVA_VERSION="25" setup_java
if check_for_gh_release "thingsboard" "thingsboard/thingsboard"; then
msg_info "Stopping Service"
systemctl stop thingsboard
+1 -1
View File
@@ -3,7 +3,7 @@ _cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../cor
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Joost van den Berg (montagneId)
# License: MIT | https://github.com/montagneid/ProxmoxVED/raw/main/LICENSE
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/umbraco/Umbraco-CMS
APP="Umbraco"
+18 -1
View File
@@ -148,6 +148,23 @@ EOF
msg_ok "Migrated wanderer services"
fi
if ! grep -q '^POCKETBASE_PROXY_SECRET=' /opt/wanderer/.env; then
msg_info "Adding POCKETBASE_PROXY_SECRET"
echo "POCKETBASE_PROXY_SECRET=$(openssl rand -hex 32)" >>/opt/wanderer/.env
systemctl restart wanderer-web
msg_ok "Added POCKETBASE_PROXY_SECRET"
fi
if [[ -f /opt/wanderer_data/plugins/plugin.json ]]; then
msg_info "Reinstalling wanderer plugins, one directory each"
find /opt/wanderer_data/plugins -maxdepth 1 -type f -delete
for plugin in hammerhead komoot strava; do
rm -f ~/.wanderer-plugin-${plugin}
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "latest" "/opt/wanderer_data/plugins/${plugin}" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
done
msg_ok "Reinstalled wanderer plugins"
fi
if check_for_gh_release "wanderer" "open-wanderer/wanderer"; then
msg_info "Stopping service"
systemctl stop wanderer-web
@@ -170,7 +187,7 @@ EOF
[[ -e /opt/wanderer/db/data/plugins ]] || ln -sfn /opt/wanderer_data/plugins /opt/wanderer/db/data/plugins
msg_info "Installing wanderer plugins"
for plugin in hammerhead komoot strava; do
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "${CHECK_UPDATE_RELEASE:-latest}" "/opt/wanderer_data/plugins" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "${CHECK_UPDATE_RELEASE:-latest}" "/opt/wanderer_data/plugins/${plugin}" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
done
msg_ok "Installed wanderer plugins"
msg_ok "Updated wanderer"
+14
View File
@@ -31,6 +31,20 @@ function update_script() {
exit
fi
if ! grep -q "@private" /etc/caddy/Caddyfile; then
msg_info "Blocking direct access to webtrees data"
cp /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak
sed -i '\|root \* /opt/webtrees|a\ @private path /app/* /data/* /modules_v4/* /resources/* /vendor/* /.*\n respond @private 403' /etc/caddy/Caddyfile
if grep -q "@private" /etc/caddy/Caddyfile && caddy validate --config /etc/caddy/Caddyfile &>/dev/null; then
rm -f /etc/caddy/Caddyfile.bak
systemctl reload-or-restart caddy
msg_ok "Blocked direct access to webtrees data"
else
mv /etc/caddy/Caddyfile.bak /etc/caddy/Caddyfile
msg_warn "Could not patch /etc/caddy/Caddyfile - deny /data/ there by hand"
fi
fi
if check_for_gh_release "webtrees" "fisharebest/webtrees"; then
msg_info "Stopping Service"
PHP_VER=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
+1 -1
View File
@@ -30,7 +30,7 @@ function update_script() {
exit
fi
NODE_VERSION="24" NODE_MODULE="yarn,node-gyp" setup_nodejs
NODE_VERSION="26" NODE_MODULE="yarn,node-gyp" setup_nodejs
if check_for_gh_release "wikijs" "requarks/wiki"; then
msg_info "Verifying whether ${APP}' new release is v3.x+ and current install uses SQLite."
+6 -1
View File
@@ -33,7 +33,12 @@ PNPM_VERSION=$(jq -r '.packageManager | ltrimstr("pnpm@")' /opt/bookorbit/packag
$STD corepack prepare "pnpm@${PNPM_VERSION}" --activate
$STD pnpm install --frozen-lockfile
$STD pnpm --filter client run build-only
# vite's bundler (rolldown) crashes at random on some builds, rolldown#10860.
for attempt in 1 2 3; do
$STD pnpm --filter client run build-only && break
[[ $attempt -eq 3 ]] && { msg_error "Client build failed three times"; exit 1; }
msg_warn "Client build failed (attempt $attempt), retrying"
done
$STD pnpm --filter server run build
cp -r /opt/bookorbit/client/dist /opt/bookorbit/server/public
mkdir -p /opt/bookorbit/server/migrations
-1
View File
@@ -203,7 +203,6 @@ server {
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Accel-Mapping /opt/discourse/public/=/downloads/;
}
}
EOF
+1 -1
View File
@@ -236,7 +236,7 @@ $STD bash /opt/frigate/.devcontainer/initialize.sh
$STD make version
cd /opt/frigate/web
$STD npm install
$STD npm run build
NODE_OPTIONS="--max-old-space-size=4096" $STD npm run build
mv /opt/frigate/web/dist/BASE_PATH/monacoeditorwork/* /opt/frigate/web/dist/assets/
rm -rf /opt/frigate/web/dist/BASE_PATH
cp -r /opt/frigate/web/dist/* /opt/frigate/web/
+3 -1
View File
@@ -45,11 +45,13 @@ if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
fi
msg_info "Installing Hermes Agent"
curl -fsSL https://hermes-agent.nousresearch.com/install.sh -o /tmp/hermes-install.sh
$STD setsid --wait bash -c '
set -a; source /etc/default/hermes; set +a
export npm_config_yes=true
bash <(curl -fsSL https://hermes-agent.nousresearch.com/install.sh) --skip-setup --hermes-home /home/hermes/.hermes --dir /home/hermes/.hermes/hermes-agent
bash /tmp/hermes-install.sh --skip-setup --hermes-home /home/hermes/.hermes --dir /home/hermes/.hermes/hermes-agent
'
rm -f /tmp/hermes-install.sh
chown -R hermes:hermes /home/hermes
chmod 750 /home/hermes
chmod 700 /home/hermes/.hermes
+23 -27
View File
@@ -13,6 +13,7 @@ setting_up_container
network_check
update_os
RELEASE="v3.3.0"
if lscpu | grep -q 'GenuineIntel'; then
echo ""
echo ""
@@ -33,11 +34,11 @@ if lscpu | grep -q 'GenuineIntel'; then
msg_info "Installing Intel OpenVINO dependencies"
tmp_dir=$(mktemp -d)
$STD pushd "$tmp_dir"
curl_with_retry "https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/machine-learning/Dockerfile" "Dockerfile"
readarray -t INTEL_URLS < <(
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $3}'
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
)
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 ||
curl_with_retry "${INTEL_SRC}/Dockerfile" "./intel-runtime"
readarray -t INTEL_URLS < <(grep -oE 'https://github\.com/intel/[^[:space:]]+\.deb' ./intel-runtime)
rm -f ./intel-runtime
for url in "${INTEL_URLS[@]}"; do
curl_with_retry "$url" "$(basename "$url")"
done
@@ -122,7 +123,12 @@ if [[ "$CTTYPE" == "0" && -d /dev/dri ]]; then
fi
msg_ok "Dependencies Installed"
fetch_and_deploy_gh_release "mise" "jdx/mise" "singlefile" "latest" "/usr/local/bin" "mise-v*-linux-$(arch_resolve "x64" "arm64")"
msg_info "Installing Mise"
curl -fSs https://mise.jdx.dev/gpg-key.pub | tee /etc/apt/keyrings/mise-archive-keyring.pub 1>/dev/null
echo "deb [signed-by=/etc/apt/keyrings/mise-archive-keyring.pub arch=$(arch_resolve)] https://mise.jdx.dev/deb stable main" >/etc/apt/sources.list.d/mise.list
apt_update_safe
$STD apt install -y mise
msg_ok "Installed Mise"
msg_info "Configuring Debian Testing Repo"
if [[ -f /etc/apt/sources.list.d/debian.sources ]]; then
@@ -348,7 +354,7 @@ ML_DIR="${APP_DIR}/machine-learning"
GEO_DIR="${INSTALL_DIR}/geodata"
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "v3.2.4" "$SRC_DIR"
fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "${RELEASE}" "$SRC_DIR"
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1] | split("+")[0]' ${SRC_DIR}/package.json)"
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
@@ -436,12 +442,13 @@ if [[ -f ~/.openvino ]]; then
msg_info "Installing Intel OpenVINO machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT -Pnu immich uv sync --extra openvino --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
[[ $attempt -lt 3 ]] && msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
[[ $attempt -eq 3 ]] && { msg_error "uv sync failed three times, the machine-learning environment was not built"; exit 1; }
msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
done
patchelf --clear-execstack "${VIRTUAL_ENV}/lib/python3.13/site-packages/onnxruntime/capi/onnxruntime_pybind11_state.cpython-313-$(arch_resolve "x86_64" "aarch64")-linux-gnu.so"
msg_ok "Installed Intel OpenVINO machine-learning"
else
ML_PYTHON="python3.11"
ML_PYTHON="python3.13"
msg_info "Pre-installing Python ${ML_PYTHON} for machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV -Pnu immich uv python install "${ML_PYTHON}" && break
@@ -451,7 +458,8 @@ else
msg_info "Installing machine-learning"
for attempt in $(seq 1 3); do
$STD sudo --preserve-env=VIRTUAL_ENV,UV_HTTP_TIMEOUT -Pnu immich uv sync --extra cpu --no-dev --active --link-mode copy -n -p "${ML_PYTHON}" --managed-python && break
[[ $attempt -lt 3 ]] && msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
[[ $attempt -eq 3 ]] && { msg_error "uv sync failed three times, the machine-learning environment was not built"; exit 1; }
msg_warn "uv sync attempt $attempt failed, retrying..." && sleep 10
done
msg_ok "Installed machine-learning"
fi
@@ -482,25 +490,12 @@ ln -s "$GEO_DIR" "$APP_DIR"
msg_ok "Installed GeoNames data"
# MickLesk temporary patch for HEIC thumbnail gen
msg_info "Patching media.repository.js"
MEDIA_REPO_JS="/opt/immich/app/dist/repositories/media.repository.js"
if [[ -f "$MEDIA_REPO_JS" ]]; then
python3 - <<'PY'
from pathlib import Path
p = Path('/opt/immich/app/dist/repositories/media.repository.js')
s = p.read_text()
old = "(0, sharp_1.default)(input).metadata()"
new = "(0, sharp_1.default)(input, { unlimited: true, limitInputPixels: false }).metadata()"
if new in s:
print('hotfix already there')
elif old in s:
p.write_text(s.replace(old, new, 1))
print('hotfix applied')
else:
print('pattern not found, skipped')
PY
if grep -qF "(0, sharp_1.default)(input).metadata()" "$MEDIA_REPO_JS" 2>/dev/null; then
msg_info "Patching media.repository.js"
sed -i '0,/(0, sharp_1\.default)(input)\.metadata()/s//(0, sharp_1.default)(input, { unlimited: true, limitInputPixels: false }).metadata()/' "$MEDIA_REPO_JS"
msg_ok "Patched media.repository.js"
fi
msg_ok "Patched media.repository.js"
mkdir -p /var/log/immich
touch /var/log/immich/{web.log,ml.log}
@@ -531,6 +526,7 @@ MACHINE_LEARNING_CACHE_FOLDER=${INSTALL_DIR}/cache
## - inference speed while reducing accuracy
## - Default is FP32
# MACHINE_LEARNING_OPENVINO_PRECISION=FP16
MACHINE_LEARNING_MODEL_REVISION=v2
IMMICH_MEDIA_LOCATION=${UPLOAD_DIR}
EOF
+1 -1
View File
@@ -13,7 +13,7 @@ setting_up_container
network_check
update_os
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
NODE_VERSION="24" NODE_MODULE="yarn" setup_nodejs
fetch_and_deploy_gh_release "jotty" "fccview/jotty" "prebuild" "latest" "/opt/jotty" "jotty_*_prebuild.tar.gz"
msg_info "Setup jotty"
+1 -1
View File
@@ -2,7 +2,7 @@
# Copyright (c) 2021-2026 community-scripts ORG
# Author: (AminGholizad)
# License: MIT | https://github.com/AminGholizad/ProxmoxVED/raw/main/LICENSE
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/PanSalut/Koffan
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+1 -1
View File
@@ -64,7 +64,7 @@ $STD sudo -u cool coolconfig set-admin-password --user=admin --password="$COOLPA
echo "$COOLPASS" >~/.coolpass
msg_ok "Installed Collabora Online"
fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "v7.4.0" "/usr/bin" "opencloud-*-linux-$(arch_resolve)"
fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "v8.1.0" "/usr/bin" "opencloud-*-linux-$(arch_resolve)"
mv /usr/bin/OpenCloud /usr/bin/opencloud
msg_info "Configuring OpenCloud"
+1 -4
View File
@@ -22,13 +22,10 @@ msg_ok "Installed Dependencies"
NODE_VERSION="24" setup_nodejs
PG_VERSION="17" setup_postgresql
PG_DB_NAME="pangolin" PG_DB_USER="pangolin" setup_postgresql_db
PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.23.0}"
fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VERSION"
fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball"
fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
fetch_and_deploy_gh_release "traefik" "traefik/traefik" "prebuild" "latest" "/usr/bin" "traefik_v*_linux_$(arch_resolve).tar.gz"
# Read the variable first and prompt only when it is unset, so the install can
# be supplied up front. Same convention as install/forgejo-runner-install.sh.
pango_url="${var_pangolin_url:-}"
if [[ -z "$pango_url" ]]; then
read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " pango_url
+28 -9
View File
@@ -46,8 +46,21 @@ msg_info "Configuring Paperclip"
PAPERCLIP_HOME="/opt/paperclip-data"
PAPERCLIP_CONFIG="${PAPERCLIP_HOME}/instances/default/config.json"
mkdir -p /opt/paperclip-data
mkdir -p /root/.claude /root/.codex
PAPERCLIP_USER="${var_paperclip_user:-paperclip}"
# Claude Code refuses --dangerously-skip-permissions as root, so run as a dedicated user
if [[ "$PAPERCLIP_USER" == "root" || ! "$PAPERCLIP_USER" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]]; then
msg_error "Invalid var_paperclip_user '${PAPERCLIP_USER}' (must be a non-root lowercase Linux username)"
exit 1
fi
PAPERCLIP_USER_HOME="/home/${PAPERCLIP_USER}"
id -u "$PAPERCLIP_USER" &>/dev/null || useradd -m -d "$PAPERCLIP_USER_HOME" -s /bin/bash "$PAPERCLIP_USER"
if [[ -n "${var_paperclip_pass:-}" ]]; then
printf '%s:%s\n' "$PAPERCLIP_USER" "$var_paperclip_pass" | chpasswd
else
passwd -l "$PAPERCLIP_USER" &>/dev/null
fi
unset var_paperclip_pass
mkdir -p /opt/paperclip-data "${PAPERCLIP_USER_HOME}/.claude" "${PAPERCLIP_USER_HOME}/.codex"
BETTER_AUTH_SECRET=$(openssl rand -hex 32)
cat <<EOF >/opt/paperclip-ai/.env
DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}
@@ -62,11 +75,13 @@ PAPERCLIP_DEPLOYMENT_EXPOSURE=private
PAPERCLIP_PUBLIC_URL=http://${LOCAL_IP}:3100
BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
EOF
chmod 600 /opt/paperclip-ai/.env
chown -R "${PAPERCLIP_USER}:${PAPERCLIP_USER}" /opt/paperclip-ai /opt/paperclip-data "$PAPERCLIP_USER_HOME"
msg_ok "Configured Paperclip"
msg_info "Running Database Migrations"
set -a && source /opt/paperclip-ai/.env && set +a
$STD pnpm db:migrate
$STD runuser -u "$PAPERCLIP_USER" -- env HOME="$PAPERCLIP_USER_HOME" pnpm db:migrate
msg_ok "Ran Database Migrations"
msg_info "Bootstrapping Paperclip"
@@ -77,7 +92,8 @@ for PAPERCLIP_ONBOARD_CMD in \
"pnpm paperclipai onboard --yes --bind lan" \
"pnpm paperclipai onboard --yes"; do
rm -f "$PAPERCLIP_ONBOARD_LOG"
setsid env \
setsid runuser -u "$PAPERCLIP_USER" -- env \
HOME="$PAPERCLIP_USER_HOME" \
PAPERCLIP_HOME="$PAPERCLIP_HOME" \
PAPERCLIP_CONFIG="$PAPERCLIP_CONFIG" \
bash -c 'cd /opt/paperclip-ai && exec "$@"' _ $PAPERCLIP_ONBOARD_CMD \
@@ -109,7 +125,8 @@ if [[ ! -f "$PAPERCLIP_CONFIG" ]]; then
fi
if grep -q 'authenticated' $PAPERCLIP_CONFIG; then
pnpm paperclipai auth bootstrap-ceo >"$PAPERCLIP_BOOTSTRAP_LOG" 2>&1 || true
chown "${PAPERCLIP_USER}:${PAPERCLIP_USER}" /opt/paperclip-ai
runuser -u "$PAPERCLIP_USER" -- env HOME="$PAPERCLIP_USER_HOME" bash -c 'cd /opt/paperclip-ai && pnpm paperclipai auth bootstrap-ceo' >"$PAPERCLIP_BOOTSTRAP_LOG" 2>&1 || true
PAPERCLIP_INVITE_URL=$(awk -F'Invite URL: ' '/Invite URL:/ {print $2; exit}' "$PAPERCLIP_BOOTSTRAP_LOG")
PAPERCLIP_INVITE_EXPIRY=$(awk -F'Expires: ' '/Expires:/ {print $2; exit}' "$PAPERCLIP_BOOTSTRAP_LOG")
if [[ -n "$PAPERCLIP_INVITE_URL" ]]; then
@@ -131,6 +148,7 @@ else
fi
rm -f "$PAPERCLIP_ONBOARD_LOG" "$PAPERCLIP_BOOTSTRAP_LOG"
msg_ok "Bootstrapped Paperclip"
echo -e "${INFO}${YW} Authenticate Claude Code and Codex as the service user: ${BGN}su - ${PAPERCLIP_USER}${CL}"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/paperclip.service
@@ -141,12 +159,13 @@ Requires=postgresql.service
[Service]
Type=simple
User=root
User=${PAPERCLIP_USER}
Group=${PAPERCLIP_USER}
WorkingDirectory=/opt/paperclip-ai
EnvironmentFile=/opt/paperclip-ai/.env
Environment=HOME=/root
Environment=CODEX_HOME=/root/.codex
Environment=PATH=/root/.local/bin:/usr/local/bin:/usr/bin:/bin
Environment=HOME=${PAPERCLIP_USER_HOME}
Environment=CODEX_HOME=${PAPERCLIP_USER_HOME}/.codex
Environment=PATH=${PAPERCLIP_USER_HOME}/.local/bin:/usr/local/bin:/usr/bin:/bin
Environment=DISABLE_AUTOUPDATER=1
ExecStart=/usr/bin/env pnpm paperclipai run
Restart=on-failure
+168
View File
@@ -0,0 +1,168 @@
#!/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://github.com/jez500/pricebuddy
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 \
cron \
xvfb
msg_ok "Installed Dependencies"
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MEMORY_LIMIT="2048M" setup_php
setup_composer
NODE_VERSION="22" setup_nodejs
setup_mariadb
MARIADB_DB_NAME="pricebuddy" MARIADB_DB_USER="pricebuddy" setup_mariadb_db
PYTHON_VERSION="3.12" setup_uv
msg_info "Installing Google Chrome"
setup_deb822_repo \
"google-chrome" \
"https://dl.google.com/linux/linux_signing_key.pub" \
"https://dl.google.com/linux/chrome/deb/" \
"stable"
$STD apt install -y google-chrome-stable
# the package adds its own .list for the same repo, which apt rejects next to the deb822 source
rm -f /etc/apt/sources.list.d/google-chrome.list
msg_ok "Installed Google Chrome"
fetch_and_deploy_gh_release "seleniumbase-scrapper" "jez500/seleniumbase-scrapper" "tarball"
msg_info "Setting up SeleniumBase Scrapper"
$STD uv venv --python 3.12 /opt/seleniumbase-scrapper/.venv
# the SeleniumBase release upstream builds and tests its image against
$STD uv pip install --python /opt/seleniumbase-scrapper/.venv/bin/python \
"seleniumbase==$(sed -n 's/^ARG SELENIUMBASE_VERSION=v//p' /opt/seleniumbase-scrapper/Dockerfile)" \
flask \
beautifulsoup4
$STD /opt/seleniumbase-scrapper/.venv/bin/seleniumbase get chromedriver
msg_ok "Set up SeleniumBase Scrapper"
fetch_and_deploy_gh_release "pricebuddy" "jez500/pricebuddy" "tarball"
msg_info "Setting up PriceBuddy"
cd /opt/pricebuddy
cat <<EOF >/opt/pricebuddy/.env
APP_NAME=PriceBuddy
APP_ENV=production
APP_KEY=base64:$(openssl rand -base64 32)
APP_DEBUG=false
APP_URL=http://${LOCAL_IP}
APP_VERSION=$(cat ~/.pricebuddy)
DB_CONNECTION=mariadb
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=pricebuddy
DB_USERNAME=pricebuddy
DB_PASSWORD=${MARIADB_DB_PASS}
SCRAPER_BASE_URL=http://127.0.0.1:3000
APP_USER_EMAIL=admin@example.com
APP_USER_PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c16)
EOF
$STD composer install --no-dev --optimize-autoloader --no-interaction
$STD npm install
$STD npm run build
$STD php artisan storage:link
# reads APP_USER_* for the admin via env(), so it has to run before optimize caches the config
$STD php artisan buddy:init-db
$STD php artisan optimize
$STD php artisan icons:cache
chown -R www-data:www-data /opt/pricebuddy
chmod 600 /opt/pricebuddy/.env
msg_ok "Set up PriceBuddy"
msg_info "Configuring Nginx"
PHP_SOCK=$(get_php_fpm_socket)
cat <<EOF >/etc/nginx/sites-available/pricebuddy
server {
listen 80;
server_name _;
root /opt/pricebuddy/public;
index index.php;
charset utf-8;
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php\$ {
fastcgi_pass unix:${PHP_SOCK};
fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 300;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
EOF
nginx_enable_site "pricebuddy"
msg_ok "Configured Nginx"
msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/seleniumbase-scrapper.service
[Unit]
Description=SeleniumBase Scrapper for PriceBuddy
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/seleniumbase-scrapper/api
Environment=API_HOST=127.0.0.1
Environment=API_PORT=3000
ExecStart=/opt/seleniumbase-scrapper/.venv/bin/python /opt/seleniumbase-scrapper/api/server.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/systemd/system/pricebuddy-worker.service
[Unit]
Description=PriceBuddy Queue Worker
After=network.target mariadb.service
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/pricebuddy
ExecStart=/usr/bin/php /opt/pricebuddy/artisan queue:work
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF >/etc/cron.d/pricebuddy
* * * * * www-data cd /opt/pricebuddy && php artisan schedule:run >/dev/null 2>&1
EOF
systemctl enable -q --now seleniumbase-scrapper pricebuddy-worker
msg_ok "Created Services"
motd_ssh
customize
cleanup_lxc
+1 -1
View File
@@ -20,7 +20,7 @@ $STD apt install -y \
fonts-dejavu-core
msg_ok "Installed Dependencies"
JAVA_VERSION="17" setup_java
JAVA_VERSION="25" setup_java
PG_VERSION="16" setup_postgresql
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"
+1 -1
View File
@@ -2,7 +2,7 @@
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Joost van den Berg (montagneId)
# License: MIT | https://github.com/montagneid/ProxmoxVED/raw/main/LICENSE
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/umbraco/Umbraco-CMS
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
+2 -1
View File
@@ -33,7 +33,7 @@ msg_ok "Installed wanderer"
msg_info "Installing wanderer plugins"
for plugin in hammerhead komoot strava; do
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "latest" "/opt/wanderer_data/plugins" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "latest" "/opt/wanderer_data/plugins/${plugin}" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
done
msg_ok "Installed wanderer plugins"
@@ -49,6 +49,7 @@ PB_URL=${LOCAL_IP}:8090
PUBLIC_POCKETBASE_URL=http://${LOCAL_IP}:8090
PUBLIC_VALHALLA_URL=https://valhalla1.openstreetmap.de
POCKETBASE_ENCRYPTION_KEY=${POCKETBASE_KEY}
POCKETBASE_PROXY_SECRET=$(openssl rand -hex 32)
PB_DB_LOCATION=/opt/wanderer_data/pb_data
MEILI_DB_PATH=/opt/wanderer_data/meili_data
EOF
+3
View File
@@ -36,6 +36,9 @@ PHP_SOCK=$(get_php_fpm_socket)
cat <<EOF >/etc/caddy/Caddyfile
:80 {
root * /opt/webtrees
# Caddy ignores data/.htaccess; media must go through webtrees so its privacy rules apply.
@private path /app/* /data/* /modules_v4/* /resources/* /vendor/* /.*
respond @private 403
php_fastcgi unix/${PHP_SOCK}
file_server
encode gzip
+1 -1
View File
@@ -17,7 +17,7 @@ msg_info "Installing Dependencies"
$STD apt install -y git
msg_ok "Installed Dependencies"
NODE_VERSION="24" NODE_MODULE="yarn,node-gyp" setup_nodejs
NODE_VERSION="26" NODE_MODULE="yarn,node-gyp" setup_nodejs
PG_VERSION="17" setup_postgresql
PG_DB_NAME="wiki" PG_DB_USER="wikijs_user" PG_DB_EXTENSIONS="pg_trgm" setup_postgresql_db
fetch_and_deploy_gh_release "wikijs" "requarks/wiki" "prebuild" "latest" "/opt/wikijs" "wiki-js.tar.gz"
+3 -2
View File
@@ -110,8 +110,9 @@ while true; do
pct start "$instance" >/dev/null 2>&1
continue
fi
# Not every container names its interface eth0.
IP=$(pct exec "$instance" -- ip -4 -o addr show scope global 2>/dev/null | awk '{print $4}' | cut -d/ -f1 | head -n1)
# Read the IP from the host side; pct exec depends on tools inside the
# guest, which minimal/OCI images may lack.
IP=$(lxc-info -n "$instance" -iH 2>/dev/null | awk '/^[0-9.]+$/ && !/^(127|169\.254)\./ {print; exit}')
if [ -z "$IP" ] || ! ping -c 1 -W 2 "$IP" >/dev/null 2>&1; then
echo "$(date): CT $instance is not responding, restarting..."
pct stop "$instance" >/dev/null 2>&1
+55 -522
View File
@@ -1,218 +1,42 @@
#!/usr/bin/env bash
#!/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 /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
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
function header_info {
clear
cat <<"EOF"
___ __ __ _ _ ____ ___
/ | __________/ /_ / / (_)___ __ ___ __ | | / / |/ /
/ /| | / ___/ ___/ __ \ / / / / __ \/ / / / |/_/ | | / / /|_/ /
/ ___ |/ / / /__/ / / / / /___/ / / / / /_/ /> < | |/ / / / /
/_/ |_/_/ \___/_/ /_/ /_____/_/_/ /_/\__,_/_/|_| |___/_/ /_/
EOF
}
header_info
echo -e "\n Loading..."
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
METHOD=""
APP="Arch Linux"
APP_TYPE="vm"
NSAPP="archlinux-vm"
var_os="arch-linux"
var_version="n.d."
YW=$(echo "\033[33m")
BL=$(echo "\033[36m")
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,"
header_info
echo -e "\n Loading..."
set -e
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
trap cleanup EXIT
trap 'post_update_to_api "failed" "130"' SIGINT
trap 'post_update_to_api "failed" "143"' SIGTERM
trap 'post_update_to_api "failed" "129"; exit 129' SIGHUP
function error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
echo -e "\n$error_message\n"
cleanup_vmid
}
function get_valid_nextid() {
local try_id
try_id=$(pvesh get /cluster/nextid)
while true; do
if [ -f "/etc/pve/qemu-server/${try_id}.conf" ] || [ -f "/etc/pve/lxc/${try_id}.conf" ]; then
try_id=$((try_id + 1))
continue
fi
if lvs --noheadings -o lv_name | grep -qE "(^|[-_])${try_id}($|[-_])"; then
try_id=$((try_id + 1))
continue
fi
break
done
echo "$try_id"
}
function cleanup_vmid() {
if qm status $VMID &>/dev/null; then
qm stop $VMID &>/dev/null
qm destroy $VMID &>/dev/null
fi
}
function cleanup() {
local exit_code=$?
popd >/dev/null
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
if [[ $exit_code -eq 0 ]]; then
post_update_to_api "done" "none"
else
post_update_to_api "failed" "$exit_code"
fi
fi
rm -rf $TEMP_DIR
}
vm_require_arch amd64
TEMP_DIR=$(mktemp -d)
pushd $TEMP_DIR >/dev/null
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Arch Linux VM" --yesno "This will create a New Arch Linux 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.2
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 105
fi
return 0
fi
# Check for Proxmox VE 9.x: allow 9.0 and 9.2
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR < 0 || MINOR > 2)); then
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported: Proxmox VE version 9.0 – 9.2"
exit 105
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.2"
exit 105
}
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
}
function default_settings() {
vm_apply_machine_type "i440fx"
VMID=$(get_valid_nextid)
MACHINE=""
DISK_SIZE="4G"
DISK_SIZE="10G"
DISK_CACHE=""
HN="arch-linux"
CPU_TYPE=""
@@ -224,219 +48,28 @@ function default_settings() {
MTU=""
START_VM="yes"
METHOD="default"
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}${MAC}${CL}"
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
echo -e "${CREATING}${BOLD}${DGN}Creating a Arch Linux VM using the above default settings${CL}"
vm_echo_default_settings
}
function advanced_settings() {
METHOD="advanced"
[ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
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 [ -z "$VMID" ]; then
VMID=$(get_valid_nextid)
fi
if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then
echo -e "${CROSS}${RD} ID $VMID is already in use${CL}"
sleep 2
continue
fi
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
break
else
exit-script
fi
done
vm_prompt_vmid "${VMID:-$(get_valid_nextid)}"
vm_prompt_machine_type "i440fx"
vm_prompt_disk_size "10G"
vm_prompt_disk_cache "none"
vm_prompt_hostname "arch-linux"
vm_prompt_cpu_model "kvm64"
vm_prompt_cpu_cores "1"
vm_prompt_ram "1024"
vm_prompt_bridge "vmbr0"
vm_prompt_mac "$GEN_MAC"
vm_prompt_vlan
vm_prompt_mtu
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
"i440fx" "Machine i440fx" ON \
"q35" "Machine q35" OFF \
3>&1 1>&2 2>&3); then
if [ "$MACH" = q35 ]; then
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
MACHINE=" -machine q35"
else
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
MACHINE=""
fi
else
exit-script
fi
vm_prompt_verbose "no"
vm_prompt_start_vm "yes"
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 ' ')
if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
DISK_SIZE="${DISK_SIZE}G"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
elif [[ "$DISK_SIZE" =~ ^[0-9]+G$ ]]; then
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
else
echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
exit-script
fi
else
exit-script
fi
if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
"0" "None (Default)" ON \
"1" "Write Through" OFF \
3>&1 1>&2 2>&3); then
if [ "$DISK_CACHE" = "1" ]; then
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}Write Through${CL}"
DISK_CACHE="cache=writethrough,"
else
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
DISK_CACHE=""
fi
else
exit-script
fi
if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 arch-linux --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$VM_NAME" ]; then
HN="arch-linux"
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
else
HN=$(echo "${VM_NAME,,}" | tr -cs 'a-z0-9-' '-' | sed 's/^-//;s/-$//')
if [ "$HN" != "${VM_NAME,,}" ]; then
whiptail --backtitle "Proxmox VE Helper Scripts" --title "HOSTNAME ADJUSTED" --msgbox "Invalid characters detected. Hostname has been adjusted to:\n\n $HN" 10 58
fi
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
fi
else
exit-script
fi
if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
"0" "KVM64 (Default)" ON \
"1" "Host" OFF \
3>&1 1>&2 2>&3); then
if [ "$CPU_TYPE1" = "1" ]; then
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
CPU_TYPE=" -cpu host"
else
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
CPU_TYPE=""
fi
else
exit-script
fi
while true; do
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$CORE_COUNT" ]; then CORE_COUNT="2"; fi
if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "CPU Cores must be a positive integer (e.g., 2)." 8 58
else
exit-script
fi
done
while true; do
if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$RAM_SIZE" ]; then RAM_SIZE="2048"; fi
if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "RAM Size must be a positive integer in MiB (e.g., 2048)." 8 58
else
exit-script
fi
done
if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$BRG" ]; then
BRG="vmbr0"
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
else
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
fi
else
exit-script
fi
while true; do
if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 "$GEN_MAC" --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$MAC1" ]; then
MAC="$GEN_MAC"
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
break
fi
if [[ "$MAC1" =~ ^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$ ]]; then
MAC="$MAC1"
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "Invalid MAC address format. Use XX:XX:XX:XX:XX:XX (e.g., AA:BB:CC:DD:EE:FF)." 8 58
else
exit-script
fi
done
while true; do
if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$VLAN1" ]; then
VLAN1="Default"
VLAN=""
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
break
fi
if [[ "$VLAN1" =~ ^[0-9]+$ ]] && [ "$VLAN1" -ge 1 ] && [ "$VLAN1" -le 4094 ]; then
VLAN=",tag=$VLAN1"
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "VLAN must be a number between 1 and 4094, or leave blank for default." 8 58
else
exit-script
fi
done
while true; do
if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$MTU1" ]; then
MTU1="Default"
MTU=""
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
break
fi
if [[ "$MTU1" =~ ^[0-9]+$ ]] && [ "$MTU1" -ge 576 ] && [ "$MTU1" -le 65520 ]; then
MTU=",mtu=$MTU1"
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "MTU Size must be a number between 576 and 65520, or leave blank for default." 8 58
else
exit-script
fi
done
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}"
START_VM="yes"
else
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}no${CL}"
START_VM="no"
fi
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Arch Linux VM?" --no-button Do-Over 10 58); then
if vm_confirm_advanced_settings "Ready to create a Arch Linux VM?"; then
echo -e "${CREATING}${BOLD}${DGN}Creating a Arch Linux VM using the above advanced settings${CL}"
else
header_info
@@ -445,154 +78,54 @@ function advanced_settings() {
fi
}
function start_script() {
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then
header_info
echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings${CL}"
default_settings
else
header_info
echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
advanced_settings
fi
}
check_root
arch_check
pve_check
ssh_check
start_script
vm_preflight
vm_start_script "Use Default Settings?\n\nDefaults:\n• 1 CPU Core\n• 1 GB RAM\n• 10 GB Disk" 13 58
post_to_api_vm
msg_info "Validating Storage"
while read -r line; do
TAG=$(echo "$line" | awk '{print $1}')
TYPE=$(echo "$line" | awk '{printf "%-10s", $2}')
FREE=$(echo "$line" | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
ITEM=" Type: $TYPE Free: $FREE "
OFFSET=2
if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
fi
STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
done < <(pvesm status -content images | awk 'NR>1')
VALID=$(pvesm status -content images | awk 'NR>1')
if [ -z "$VALID" ]; then
msg_error "Unable to detect a valid storage location."
exit
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
STORAGE=${STORAGE_MENU[0]}
else
while [ -z "${STORAGE:+x}" ]; do
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
"Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
16 $(($MSG_MAX_LENGTH + 23)) 6 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3)
done
fi
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
vm_select_storage "$HN"
msg_info "Retrieving the URL for the Arch Linux .iso File"
URL=https://geo.mirror.pkgbuild.com/iso/latest/archlinux-x86_64.iso
FILENAME="archlinux-x86_64.iso"
vm_select_iso_storage "$FILENAME" "$HN"
CACHE_FILE="$ISO_PATH"
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}"
STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
case $STORAGE_TYPE in
nfs | dir | cifs)
DISK_EXT=".qcow2"
DISK_REF="$VMID/"
DISK_IMPORT="--format qcow2"
THIN=""
;;
btrfs)
DISK_EXT=".raw"
DISK_REF="$VMID/"
DISK_IMPORT="--format raw"
THIN=""
;;
*)
DISK_EXT=""
DISK_REF=""
DISK_IMPORT="--format raw"
;;
esac
vm_fetch_image "$URL" "$CACHE_FILE" --cache --min-bytes $((100 * 1024 * 1024)) || exit 115
msg_info "Creating a Arch Linux VM"
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
-name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci
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" "${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 226
}
msg_ok "Imported disk (${CL}${BL}${DISK_REF_IMPORTED}${CL})"
# The ISO is the installer, not the system: an empty disk takes scsi0 and wins
# the boot order as soon as something is on it.
qm set $VMID \
-efidisk0 ${STORAGE}:0,efitype=4m \
-scsi0 ${DISK_REF_IMPORTED},${DISK_CACHE}${THIN%,} \
-ide2 ${STORAGE}:cloudinit \
-boot order=scsi0 \
-scsi0 ${STORAGE}:${DISK_SIZE%G},${DISK_CACHE}${THIN%,} \
-cdrom "$ISO_VOLUME" \
-boot order='scsi0;ide2' \
-serial0 socket >/dev/null
DESCRIPTION=$(
cat <<EOF
<div align='center'>
<a href='https://community-scripts.org' 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;'>Arch Linux VM</h2>
<p style='margin: 16px 0;'>
<a href='https://ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>
<img src='https://img.shields.io/badge/&#x2615;-Buy us a coffee-blue' alt='spend Coffee' />
</a>
</p>
<span style='margin: 0 10px;'>
<i class="fa fa-github fa-fw" style="color: #f5f5f5;"></i>
<a href='https://github.com/community-scripts/ProxmoxVE' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>GitHub</a>
</span>
<span style='margin: 0 10px;'>
<i class="fa fa-comments fa-fw" style="color: #f5f5f5;"></i>
<a href='https://github.com/community-scripts/ProxmoxVE/discussions' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Discussions</a>
</span>
<span style='margin: 0 10px;'>
<i class="fa fa-exclamation-circle fa-fw" style="color: #f5f5f5;"></i>
<a href='https://github.com/community-scripts/ProxmoxVE/issues' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Issues</a>
</span>
</div>
EOF
)
qm set $VMID -description "$DESCRIPTION" >/dev/null
if [ -n "$DISK_SIZE" ]; then
msg_info "Resizing disk to $DISK_SIZE GB"
qm resize $VMID scsi0 ${DISK_SIZE} >/dev/null
else
msg_info "Using default disk size of $DEFAULT_DISK_SIZE GB"
qm resize $VMID scsi0 ${DEFAULT_DISK_SIZE} >/dev/null
fi
set_description
msg_ok "Created a Arch Linux VM ${CL}${BL}(${HN})"
if [ "$START_VM" == "yes" ]; then
msg_info "Starting Arch Linux VM"
qm start $VMID
$STD qm start $VMID
msg_ok "Started Arch Linux VM"
fi
post_update_to_api "done" "none"
echo -e "\n${INFO}${BOLD}${GN}Arch Linux 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}Disk Size: ${BGN}${DISK_SIZE}${CL}"
echo -e "\n${INFO}${BOLD}${YW}Next Steps:${CL}"
echo -e "${TAB}1. Open the VM Console in Proxmox - the live ISO logs in as root by itself"
echo -e "${TAB}2. Run ${BL}archinstall${CL}, or install by hand, onto ${BL}/dev/sda${CL}"
echo -e "${TAB}3. Detach the ISO afterwards (${BL}qm set ${VMID} --ide2 none${CL}) -- the boot"
echo -e "${TAB} order already prefers the disk"
echo -e "${TAB}4. The ISO carries no Cloud-Init and no guest agent. Install"
echo -e "${TAB} ${BL}qemu-guest-agent${CL} in the guest for Proxmox to show its IP"
msg_ok "Completed successfully!\n"
+183
View File
@@ -0,0 +1,183 @@
#!/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://fedoraproject.org/cloud/
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
APP="Fedora"
APP_TYPE="vm"
NSAPP="fedora-vm"
var_os="fedora"
var_version=" "
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
METHOD=""
THIN="discard=on,ssd=1,"
header_info
echo -e "\n Loading..."
set -e
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
trap cleanup EXIT
trap 'post_update_to_api "failed" "130"' SIGINT
trap 'post_update_to_api "failed" "143"' SIGTERM
trap 'post_update_to_api "failed" "129"; exit 129' SIGHUP
TEMP_DIR=$(mktemp -d)
pushd "$TEMP_DIR" >/dev/null
vm_preflight
# Fedora Cloud Base sets no password and has no console login, so the only
# question is which credentials.
CLOUDINIT_REQUIRED=1
vm_prompt_cloud_init "fedora"
function default_settings() {
VMID=$(get_valid_nextid)
vm_apply_machine_type "q35"
DISK_SIZE="20G"
DISK_CACHE=""
HN="fedora"
CPU_TYPE=" -cpu host"
CORE_COUNT="2"
RAM_SIZE="2048"
BRG="vmbr0"
MAC="$GEN_MAC"
VLAN=""
MTU=""
START_VM="yes"
METHOD="default"
echo -e "${CLOUD}${BOLD}${DGN}Cloud-Init: ${BGN}${USE_CLOUD_INIT}${CL}"
vm_echo_default_settings
}
function advanced_settings() {
METHOD="advanced"
vm_prompt_vmid "${VMID:-$(get_valid_nextid)}"
vm_prompt_machine_type "q35"
vm_prompt_disk_size "20G" "Set Disk Size in GiB"
vm_prompt_disk_cache "none"
vm_prompt_hostname "fedora"
vm_prompt_cpu_model "host"
vm_prompt_cpu_cores "2"
vm_prompt_ram "2048"
vm_prompt_bridge "vmbr0"
vm_prompt_mac "$GEN_MAC"
vm_prompt_vlan
vm_prompt_mtu
vm_prompt_verbose "no"
vm_prompt_start_vm "yes"
if vm_confirm_advanced_settings "Ready to create a Fedora VM?"; then
echo -e "${CREATING}${BOLD}${DGN}Creating a Fedora VM using the above advanced settings${CL}"
else
header_info
echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
advanced_settings
fi
}
vm_start_script "Use Default Settings?\n\nDefaults:\n• 2 CPU Cores\n• 2 GB RAM\n• 20 GB Disk\n• Cloud-Init enabled" 14 58
post_to_api_vm
vm_select_storage "$HN"
if ! command -v virt-customize &>/dev/null; then
msg_info "Installing libguestfs-tools"
$STD apt-get update
$STD apt-get install -y libguestfs-tools
msg_ok "Installed libguestfs-tools"
fi
msg_info "Retrieving the URL for the Fedora Cloud Base image"
MIRROR="https://dl.fedoraproject.org/pub/fedora/linux/releases"
FEDORA_RELEASE=$(curl -fsSL "$MIRROR/" 2>/dev/null | grep -oP 'href="\K[0-9]+(?=/")' | sort -rn | head -1)
[[ -z "$FEDORA_RELEASE" ]] && FEDORA_RELEASE="44"
FEDORA_ARCH="$(vm_arch_resolve x86_64 aarch64)"
IMAGE_DIR="${MIRROR}/${FEDORA_RELEASE}/Cloud/${FEDORA_ARCH}/images"
FILE=$(curl -fsSL "${IMAGE_DIR}/" 2>/dev/null | grep -oP 'href="\KFedora-Cloud-Base-Generic-[^"]+\.'"${FEDORA_ARCH}"'\.qcow2(?=")' | sort -V | tail -1)
if [[ -z "$FILE" ]]; then
msg_error "Could not determine the current Fedora Cloud image"
exit 1
fi
msg_ok "Fedora ${CL}${BL}${FEDORA_RELEASE}${CL} ${GN}(${FILE})"
URL="${IMAGE_DIR}/${FILE}"
CACHE_FILE="$(vm_image_cache_path "$URL")"
vm_fetch_image "$URL" "$CACHE_FILE" --cache --min-bytes $((100 * 1024 * 1024)) || exit 115
WORK_FILE=$(mktemp --suffix=.qcow2)
cp "$CACHE_FILE" "$WORK_FILE"
popd >/dev/null
rm -rf "$TEMP_DIR"
vm_prepare_cloud_image "$WORK_FILE" "$HN" || true
msg_info "Customizing ${FILE}"
CUSTOMIZE_FAILURES_BEFORE=${#_VM_PREPARE_FAILED[@]}
_vm_customize "Fedora serial console" "$WORK_FILE" --run-command "systemctl enable serial-getty@ttyS0.service"
_vm_customize "Fedora SELinux relabel" "$WORK_FILE" --selinux-relabel
if ((${#_VM_PREPARE_FAILED[@]} == CUSTOMIZE_FAILURES_BEFORE)); then
msg_ok "Customized image"
else
msg_warn "Fedora image customization incomplete; see warnings above"
fi
STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
vm_apply_storage_layout "$STORAGE_TYPE"
vm_define_disk_references 3
if [[ "$DISK_IMPORT_FORMAT" == "raw" ]]; then
msg_info "Converting image to raw format"
RAW_FILE=$(mktemp --suffix=.raw)
qemu-img convert -f qcow2 -O raw "$WORK_FILE" "$RAW_FILE"
rm -f "$WORK_FILE"
WORK_FILE="$RAW_FILE"
msg_ok "Converted image to raw format"
fi
msg_info "Creating a Fedora VM"
qm create "$VMID" -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores "$CORE_COUNT" -memory "$RAM_SIZE" \
-name "$HN" -tags community-script -net0 virtio,bridge="$BRG",macaddr="$MAC""$VLAN""$MTU" -onboot 1 -ostype l26 -scsihw virtio-scsi-pci
vm_alloc_efi_disk "$DISK0"
pvesm alloc "$STORAGE" "$VMID" "$DISK2" 4M 1>&/dev/null
qm importdisk "$VMID" "$WORK_FILE" "$STORAGE" -format "$DISK_IMPORT_FORMAT" 1>&/dev/null
qm set "$VMID" \
-efidisk0 "${DISK0_REF}${FORMAT:-}" \
-scsi0 "${DISK1_REF}",${DISK_CACHE}${THIN}size="${DISK_SIZE}" \
-tpmstate0 "${DISK2_REF}",version=v2.0 \
-boot order=scsi0 \
-serial0 socket >/dev/null
set_description
rm -f "$WORK_FILE"
msg_ok "Created a Fedora VM ${CL}${BL}(${HN})"
vm_resize_disk
vm_provision "$VMID" || true
if [ "$START_VM" == "yes" ]; then
msg_info "Starting Fedora VM"
$STD qm start "$VMID"
msg_ok "Started Fedora VM"
fi
post_update_to_api "done" "none"
echo -e "\n${INFO}${BOLD}${GN}Fedora 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}Release: ${BGN}Fedora ${FEDORA_RELEASE} (${FEDORA_ARCH})${CL}"
if [ -n "${CLOUDINIT_CRED_FILE:-}" ]; then
echo -e "${TAB}${DGN}Cloud-Init credentials: ${BGN}${CLOUDINIT_CRED_FILE}${CL}"
fi
msg_ok "Completed successfully!\n"
+42 -488
View File
@@ -1,219 +1,43 @@
#!/usr/bin/env bash
#!/usr/bin/env bash
# Copyright (c) 2021-2026 tteck
# Author: tteck (tteckster)
# License: MIT
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
source /dev/stdin <<<$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func)
COMMUNITY_SCRIPTS_URL="${COMMUNITY_SCRIPTS_URL:-https://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
function header_info {
clear
cat <<"EOF"
__ ____ __ __ _ __ ____ __ ____ _____ ________ ______
/ |/ (_) /___________ / /_(_) /__ / __ \____ __ __/ /____ _____/ __ \/ ___/ / ____/ / / / __ \
/ /|_/ / / //_/ ___/ __ \/ __/ / //_/ / /_/ / __ \/ / / / __/ _ \/ ___/ / / /\__ \ / / / /_/ / /_/ /
/ / / / / ,< / / / /_/ / /_/ / ,< / _, _/ /_/ / /_/ / /_/ __/ / / /_/ /___/ / / /___/ __ / _, _/
/_/ /_/_/_/|_/_/ \____/\__/_/_/|_| /_/ |_|\____/\__,_/\__/\___/_/ \____//____/ \____/_/ /_/_/ |_|
EOF
}
header_info
echo -e "Loading..."
GEN_MAC=$(echo '00 60 2f'$(od -An -N3 -t xC /dev/urandom) | sed -e 's/ /:/g' | tr '[:lower:]' '[:upper:]')
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
METHOD=""
APP="MikroTik RouterOS"
APP_TYPE="vm"
NSAPP="mikrotik-routeros"
var_os="mikrotik"
var_version=" "
DISK_SIZE="1G"
YW=$(echo "\033[33m")
BL=$(echo "\033[36m")
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,"
header_info
echo -e "Loading..."
set -e
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
trap cleanup EXIT
trap 'post_update_to_api "failed" "130"' SIGINT
trap 'post_update_to_api "failed" "143"' SIGTERM
trap 'post_update_to_api "failed" "129"; exit 129' SIGHUP
function error_handler() {
local exit_code="$?"
local line_number="$1"
local command="$2"
local error_message="${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}"
post_update_to_api "failed" "${exit_code}"
echo -e "\n$error_message\n"
cleanup_vmid
}
function get_valid_nextid() {
local try_id
try_id=$(pvesh get /cluster/nextid)
while true; do
if [ -f "/etc/pve/qemu-server/${try_id}.conf" ] || [ -f "/etc/pve/lxc/${try_id}.conf" ]; then
try_id=$((try_id + 1))
continue
fi
if lvs --noheadings -o lv_name | grep -qE "(^|[-_])${try_id}($|[-_])"; then
try_id=$((try_id + 1))
continue
fi
break
done
echo "$try_id"
}
function cleanup_vmid() {
if qm status $VMID &>/dev/null; then
qm stop $VMID &>/dev/null
qm destroy $VMID &>/dev/null
fi
}
function cleanup() {
local exit_code=$?
popd >/dev/null
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
if [[ $exit_code -eq 0 ]]; then
post_update_to_api "done" "none"
else
post_update_to_api "failed" "$exit_code"
fi
fi
rm -rf $TEMP_DIR
}
vm_require_arch amd64
TEMP_DIR=$(mktemp -d)
pushd $TEMP_DIR >/dev/null
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Mikrotik RouterOS CHR VM" --yesno "This will create a Mikrotik RouterOS CHR 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.2
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 105
fi
return 0
fi
# Check for Proxmox VE 9.x: allow 9.0 and 9.2
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR < 0 || MINOR > 2)); then
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported: Proxmox VE version 9.0 – 9.2"
exit 105
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.2"
exit 105
}
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
}
function default_settings() {
vm_apply_machine_type "i440fx"
VMID=$(get_valid_nextid)
FORMAT=",efitype=4m"
MACHINE=""
DISK_SIZE="8G"
DISK_CACHE=""
HN="mikrotik-routeros-chr"
@@ -227,20 +51,7 @@ function default_settings() {
START_VM="yes"
CLOUD_INIT="no"
METHOD="default"
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx${CL}"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}${DISK_SIZE}${CL}"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}${MAC}${CL}"
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
echo -e "${CREATING}${BOLD}${DGN}Creating a Mikrotik RouterOS VM using the above default settings${CL}"
vm_echo_default_settings
}
function get_mikrotik_version() {
@@ -307,204 +118,23 @@ function get_mikrotik_version() {
function advanced_settings() {
METHOD="advanced"
[ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
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 [ -z "$VMID" ]; then
VMID=$(get_valid_nextid)
fi
if pct status "$VMID" &>/dev/null || qm status "$VMID" &>/dev/null; then
echo -e "${CROSS}${RD} ID $VMID is already in use${CL}"
sleep 2
continue
fi
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
break
else
exit-script
fi
done
vm_prompt_vmid "${VMID:-$(get_valid_nextid)}"
vm_prompt_machine_type "i440fx"
vm_prompt_disk_size "8G"
vm_prompt_disk_cache "none"
vm_prompt_hostname "mikrotik-routeros-chr"
vm_prompt_cpu_model "kvm64"
vm_prompt_cpu_cores "2"
vm_prompt_ram "512"
vm_prompt_bridge "vmbr0"
vm_prompt_mac "$GEN_MAC"
vm_prompt_vlan
vm_prompt_mtu
vm_prompt_verbose "no"
vm_prompt_start_vm "yes"
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
"i440fx" "Machine i440fx" ON \
"q35" "Machine q35" OFF \
3>&1 1>&2 2>&3); then
if [ $MACH = q35 ]; then
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
FORMAT=""
MACHINE=" -machine q35"
else
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
FORMAT=",efitype=4m"
MACHINE=""
fi
else
exit-script
fi
if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "$DISK_SIZE" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
DISK_SIZE="${DISK_SIZE}G"
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
elif [[ "$DISK_SIZE" =~ ^[0-9]+G$ ]]; then
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
else
echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
exit-script
fi
else
exit-script
fi
if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
"0" "None (Default)" ON \
"1" "Write Through" OFF \
3>&1 1>&2 2>&3); then
if [ $DISK_CACHE = "1" ]; then
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}Write Through${CL}"
DISK_CACHE="cache=writethrough,"
else
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
DISK_CACHE=""
fi
else
exit-script
fi
if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 mikrotik-routeros-chr --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z $VM_NAME ]; then
HN="mikrotik-routeros-chr"
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
else
HN=$(echo "${VM_NAME,,}" | tr -cs 'a-z0-9-' '-' | sed 's/^-//;s/-$//')
if [ "$HN" != "${VM_NAME,,}" ]; then
whiptail --backtitle "Proxmox VE Helper Scripts" --title "HOSTNAME ADJUSTED" --msgbox "Invalid characters detected. Hostname has been adjusted to:\n\n $HN" 10 58
fi
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
fi
else
exit-script
fi
if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
"0" "KVM64 (Default)" ON \
"1" "Host" OFF \
3>&1 1>&2 2>&3); then
if [ $CPU_TYPE1 = "1" ]; then
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
CPU_TYPE=" -cpu host"
else
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
CPU_TYPE=""
fi
else
exit-script
fi
while true; do
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$CORE_COUNT" ]; then CORE_COUNT="2"; fi
if [[ "$CORE_COUNT" =~ ^[1-9][0-9]*$ ]]; then
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "CPU Cores must be a positive integer (e.g., 2)." 8 58
else
exit-script
fi
done
while true; do
if RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 2048 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$RAM_SIZE" ]; then RAM_SIZE="2048"; fi
if [[ "$RAM_SIZE" =~ ^[1-9][0-9]*$ ]]; then
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "RAM Size must be a positive integer in MiB (e.g., 2048)." 8 58
else
exit-script
fi
done
if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z $BRG ]; then
BRG="vmbr0"
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
else
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
fi
else
exit-script
fi
while true; do
if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$MAC1" ]; then
MAC="$GEN_MAC"
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
break
fi
if [[ "$MAC1" =~ ^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$ ]]; then
MAC="$MAC1"
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "Invalid MAC address format. Use XX:XX:XX:XX:XX:XX (e.g., AA:BB:CC:DD:EE:FF)." 8 58
else
exit-script
fi
done
while true; do
if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$VLAN1" ]; then
VLAN1="Default"
VLAN=""
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
break
fi
if [[ "$VLAN1" =~ ^[0-9]+$ ]] && [ "$VLAN1" -ge 1 ] && [ "$VLAN1" -le 4094 ]; then
VLAN=",tag=$VLAN1"
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "VLAN must be a number between 1 and 4094, or leave blank for default." 8 58
else
exit-script
fi
done
while true; do
if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
if [ -z "$MTU1" ]; then
MTU1="Default"
MTU=""
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
break
fi
if [[ "$MTU1" =~ ^[0-9]+$ ]] && [ "$MTU1" -ge 576 ] && [ "$MTU1" -le 65520 ]; then
MTU=",mtu=$MTU1"
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
break
fi
whiptail --backtitle "Proxmox VE Helper Scripts" --title "INVALID INPUT" --msgbox "MTU Size must be a number between 576 and 65520, or leave blank for default." 8 58
else
exit-script
fi
done
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}"
START_VM="yes"
else
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}no${CL}"
START_VM="no"
fi
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Mikrotik RouterOS CHR VM?" --no-button Do-Over 10 58); then
echo -e "${CREATING}${BOLD}${DGN}Creating a Mikrotik RouterOS CHR VM using the above advanced settings${CL}"
if vm_confirm_advanced_settings "Ready to create a MikroTik RouterOS VM?"; then
echo -e "${CREATING}${BOLD}${DGN}Creating a MikroTik RouterOS VM using the above advanced settings${CL}"
else
header_info
echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
@@ -512,54 +142,12 @@ function advanced_settings() {
fi
}
function start_script() {
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "SETTINGS" --yesno "Use Default Settings?" --no-button Advanced 10 58); then
header_info
echo -e "${DEFAULT}${BOLD}${BL}Using Default Settings${CL}"
default_settings
else
header_info
echo -e "${ADVANCED}${BOLD}${RD}Using Advanced Settings${CL}"
advanced_settings
fi
}
check_root
arch_check
pve_check
ssh_check
start_script
vm_preflight
vm_start_script "Use Default Settings?\n\nDefaults:\n• 2 CPU Cores\n• 512 MB RAM\n• 8 GB Disk" 13 58
post_to_api_vm
msg_info "Validating Storage"
while read -r line; do
TAG=$(echo $line | awk '{print $1}')
TYPE=$(echo $line | awk '{printf "%-10s", $2}')
FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
ITEM=" Type: $TYPE Free: $FREE "
OFFSET=2
if [[ $((${#ITEM} + $OFFSET)) -gt ${MSG_MAX_LENGTH:-} ]]; then
MSG_MAX_LENGTH=$((${#ITEM} + $OFFSET))
fi
STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
done < <(pvesm status -content images | awk 'NR>1')
VALID=$(pvesm status -content images | awk 'NR>1')
if [ -z "$VALID" ]; then
echo -e "\n${RD}⚠ Unable to detect a valid storage location.${CL}"
echo -e "Exiting..."
exit
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
STORAGE=${STORAGE_MENU[0]}
else
while [ -z "${STORAGE:+x}" ]; do
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
"Which storage pool would you like to use for the Mikrotik RouterOS CHR VM?\n\n" \
16 $(($MSG_MAX_LENGTH + 23)) 6 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3)
done
fi
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
vm_select_storage "$HN"
msg_info "Getting URL for Latest Mikrotik RouterOS CHR Disk Image"
MIK_VER=$(get_mikrotik_version s)
@@ -576,12 +164,14 @@ URL=https://download.mikrotik.com/routeros/$MIK_VER/chr-$MIK_VER.img.zip
sleep 2
msg_ok "Downloading from URL: ${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}"
# A mirror serving an error page returns 200, so size decides whether this
# is an image. Anything real here is far above 5 MB.
CACHE_FILE="$(vm_image_cache_path "$URL")"
vm_fetch_image "$URL" "$CACHE_FILE" --cache --min-bytes $((5 * 1024 * 1024)) || exit 115
msg_info "Extracting Mikrotik RouterOS CHR Disk Image"
gunzip -f -S .zip $FILE
# Decompress out of the cache rather than over it, gunzip eats its input.
FILE="$(basename "${CACHE_FILE%.zip}")"
gunzip -c -S .zip "$CACHE_FILE" >"$FILE"
STORAGE_TYPE=$(pvesm status -storage $STORAGE | awk 'NR>1 {print $2}')
case $STORAGE_TYPE in
nfs | dir)
@@ -614,54 +204,18 @@ msg_info "Creating Mikrotik RouterOS CHR VM"
qm create $VMID -tablet 0 -localtime 1 -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
qm importdisk $VMID ${FILE%.*} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null
qm importdisk $VMID "$FILE" $STORAGE ${DISK_IMPORT:-} 1>&/dev/null
qm set $VMID \
-scsi0 "$DISK_REF" \
-boot order=scsi0 >/dev/null
DESCRIPTION=$(
cat <<EOF
<div align='center'>
<a href='https://community-scripts.org' 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;'>Mikrotik RouterOS CHR</h2>
<p style='margin: 16px 0;'>
<a href='https://ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>
<img src='https://img.shields.io/badge/&#x2615;-Buy us a coffee-blue' alt='spend Coffee' />
</a>
</p>
<span style='margin: 0 10px;'>
<i class="fa fa-github fa-fw" style="color: #f5f5f5;"></i>
<a href='https://github.com/community-scripts/ProxmoxVE' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>GitHub</a>
</span>
<span style='margin: 0 10px;'>
<i class="fa fa-comments fa-fw" style="color: #f5f5f5;"></i>
<a href='https://github.com/community-scripts/ProxmoxVE/discussions' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Discussions</a>
</span>
<span style='margin: 0 10px;'>
<i class="fa fa-exclamation-circle fa-fw" style="color: #f5f5f5;"></i>
<a href='https://github.com/community-scripts/ProxmoxVE/issues' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Issues</a>
</span>
</div>
EOF
)
qm set $VMID -description "$DESCRIPTION" >/dev/null
if [ -n "$DISK_SIZE" ]; then
msg_info "Resizing disk to $DISK_SIZE GB"
qm resize $VMID scsi0 ${DISK_SIZE} >/dev/null
else
msg_info "Using default disk size of $DEFAULT_DISK_SIZE GB"
qm resize $VMID scsi0 ${DEFAULT_DISK_SIZE} >/dev/null
fi
set_description
vm_resize_disk
msg_ok "Mikrotik RouterOS CHR VM ${CL}${BL}(${HN})"
if [ "$START_VM" == "yes" ]; then
msg_info "Starting Mikrotik RouterOS CHR VM"
qm start $VMID
$STD qm start $VMID
msg_ok "Started Mikrotik RouterOS CHR VM"
fi
post_update_to_api "done" "none"
+3 -3
View File
@@ -149,8 +149,8 @@ fi
FULL_URL="https://download.truenas.com/${SELECTED_ISO#/}"
ISO_NAME=$(basename "$FULL_URL")
CACHE_DIR="/var/lib/vz/template/iso"
CACHE_FILE="$CACHE_DIR/$ISO_NAME"
vm_select_iso_storage "$ISO_NAME" "$HN"
CACHE_FILE="$ISO_PATH"
msg_info "Retrieving the ISO for the TrueNAS Disk Image"
MIN_ISO_BYTES=$((500 * 1024 * 1024))
@@ -162,7 +162,7 @@ qm create "$VMID"${MACHINE} -bios ovmf -agent enabled=1 -tablet 0 -localtime 1${
-cores "$CORE_COUNT" -memory "$RAM_SIZE" -balloon 0 -name "$HN" -tags community-script \
-net0 "virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU" -onboot 1 -ostype l26 \
-efidisk0 $STORAGE:1,efitype=4m,pre-enrolled-keys=0 -sata0 ${STORAGE}:${DISK_SIZE%G},ssd=1 \
-scsihw virtio-scsi-single -cdrom local:iso/$ISO_NAME -boot order='sata0;ide2' -vga virtio >/dev/null
-scsihw virtio-scsi-single -cdrom "$ISO_VOLUME" -boot order='sata0;ide2' -vga virtio >/dev/null
msg_ok "Created VM shell"
if [ "$IMPORT_DISKS" == "yes" ]; then
+3 -4
View File
@@ -96,9 +96,8 @@ URL="https://download.umbrel.com/release/${UMBREL_RELEASE}/umbrelos-amd64-usb-in
# The upstream file name is the same for every release, so the version goes into
# the cached name -- otherwise the cache serves 1.7.4 to someone asking for 2.0.
ISO_NAME="umbrelos-${UMBREL_RELEASE}-amd64-usb-installer.iso"
CACHE_DIR="/var/lib/vz/template/iso"
CACHE_FILE="${CACHE_DIR}/${ISO_NAME}"
mkdir -p "$CACHE_DIR"
vm_select_iso_storage "$ISO_NAME" "$HN"
CACHE_FILE="$ISO_PATH"
msg_ok "${CL}${BL}${URL}${CL}"
# download.umbrel.com answers 307 for any name at all, so a redirect proves
@@ -114,7 +113,7 @@ qm create "$VMID"${MACHINE} -bios ovmf -agent enabled=1 -tablet 0 -localtime 1 $
-net0 "virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU" -onboot 1 -ostype l26 -scsihw virtio-scsi-pci \
-efidisk0 "${STORAGE}:1,efitype=4m,pre-enrolled-keys=0" \
-scsi0 "${STORAGE}:${DISK_SIZE%G},${DISK_CACHE:-}${THIN%,}" \
-cdrom "local:iso/${ISO_NAME}" -boot order='scsi0;ide2' >/dev/null
-cdrom "$ISO_VOLUME" -boot order='scsi0;ide2' >/dev/null
set_description
msg_ok "Created a Umbrel OS VM ${CL}${BL}(${HN})"