mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-02-05 12:53:27 +01:00
Compare commits
2 Commits
pr-update-
...
update_app
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3182bca7c7 | ||
|
|
5d8ffd68c4 |
310
.github/changelogs/2026/01.md
generated
vendored
310
.github/changelogs/2026/01.md
generated
vendored
@@ -1,156 +1,14 @@
|
|||||||
## 2026-01-31
|
## 2026-01-27
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- shelfmark ([#11371](https://github.com/community-scripts/ProxmoxVE/pull/11371))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- fix: yubal: add git [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11394](https://github.com/community-scripts/ProxmoxVE/pull/11394))
|
|
||||||
|
|
||||||
## 2026-01-30
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- languagetool ([#11370](https://github.com/community-scripts/ProxmoxVE/pull/11370))
|
|
||||||
- Ampache ([#11369](https://github.com/community-scripts/ProxmoxVE/pull/11369))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Refactor: remove redundant PHP_MODULE entries in several scripts [@MickLesk](https://github.com/MickLesk) ([#11362](https://github.com/community-scripts/ProxmoxVE/pull/11362))
|
|
||||||
- Refactor: Koillection [@MickLesk](https://github.com/MickLesk) ([#11361](https://github.com/community-scripts/ProxmoxVE/pull/11361))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- core: meilisearch - add data migration for version upgrades [@MickLesk](https://github.com/MickLesk) ([#11356](https://github.com/community-scripts/ProxmoxVE/pull/11356))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- [tools] Add `fetch_and_deploy_from_url()` [@tremor021](https://github.com/tremor021) ([#11376](https://github.com/community-scripts/ProxmoxVE/pull/11376))
|
|
||||||
- core: php - improve module handling and prevent installation failures [@MickLesk](https://github.com/MickLesk) ([#11358](https://github.com/community-scripts/ProxmoxVE/pull/11358))
|
|
||||||
|
|
||||||
## 2026-01-29
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Alpine-Valkey [@MickLesk](https://github.com/MickLesk) ([#11320](https://github.com/community-scripts/ProxmoxVE/pull/11320))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Immich: Pin version to 2.5.2 [@vhsdream](https://github.com/vhsdream) ([#11335](https://github.com/community-scripts/ProxmoxVE/pull/11335))
|
|
||||||
- Kollection: Update to php 8.5 [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11315](https://github.com/community-scripts/ProxmoxVE/pull/11315))
|
|
||||||
- Notifiarr: change installation check from apt to systemd service [@MickLesk](https://github.com/MickLesk) ([#11319](https://github.com/community-scripts/ProxmoxVE/pull/11319))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- [FEAT] Immich: Enable Maintenance Mode before update [@vhsdream](https://github.com/vhsdream) ([#11342](https://github.com/community-scripts/ProxmoxVE/pull/11342))
|
|
||||||
- jellyfin: add logrotate instead of reducing log level [@MickLesk](https://github.com/MickLesk) ([#11326](https://github.com/community-scripts/ProxmoxVE/pull/11326))
|
|
||||||
- core: Add config file handling options | Fix Vikunja update with interactive overwrite [@MickLesk](https://github.com/MickLesk) ([#11317](https://github.com/community-scripts/ProxmoxVE/pull/11317))
|
|
||||||
- Immich: v2.5.0 [@vhsdream](https://github.com/vhsdream) ([#11240](https://github.com/community-scripts/ProxmoxVE/pull/11240))
|
|
||||||
|
|
||||||
- #### 💥 Breaking Changes
|
|
||||||
|
|
||||||
- fix: vikunja v1 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11308](https://github.com/community-scripts/ProxmoxVE/pull/11308))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Refactor: Byparr [@vhsdream](https://github.com/vhsdream) ([#11338](https://github.com/community-scripts/ProxmoxVE/pull/11338))
|
|
||||||
- cloudflare: Remove deprecated DNS-over-HTTPS proxy option [@MickLesk](https://github.com/MickLesk) ([#11068](https://github.com/community-scripts/ProxmoxVE/pull/11068))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- build.func: Replace storage variable with searchdomain variable [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11322](https://github.com/community-scripts/ProxmoxVE/pull/11322))
|
|
||||||
|
|
||||||
### 📂 Github
|
|
||||||
|
|
||||||
- Add workflow to lock closed issues [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11316](https://github.com/community-scripts/ProxmoxVE/pull/11316))
|
|
||||||
|
|
||||||
## 2026-01-28
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- nodecast-tv ([#11287](https://github.com/community-scripts/ProxmoxVE/pull/11287))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Ubuntu 25.04 VM - Change default start from yes to no [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11292](https://github.com/community-scripts/ProxmoxVE/pull/11292))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- various scripts: use setup_meilisearch function [@MickLesk](https://github.com/MickLesk) ([#11259](https://github.com/community-scripts/ProxmoxVE/pull/11259))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Refactor: NPMPlus / Default Login [@MickLesk](https://github.com/MickLesk) ([#11262](https://github.com/community-scripts/ProxmoxVE/pull/11262))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- core: sed patch for ram [@lavacano](https://github.com/lavacano) ([#11285](https://github.com/community-scripts/ProxmoxVE/pull/11285))
|
|
||||||
- Fix installer loop caused by invalid whiptail menu separator [@Mesteriis](https://github.com/Mesteriis) ([#11237](https://github.com/community-scripts/ProxmoxVE/pull/11237))
|
|
||||||
- core: fix Debian 13 LXC template root ownership bug [@MickLesk](https://github.com/MickLesk) ([#11277](https://github.com/community-scripts/ProxmoxVE/pull/11277))
|
|
||||||
- tools.func: prevent systemd-tmpfiles failure in unprivileged LXC during deb install [@MickLesk](https://github.com/MickLesk) ([#11271](https://github.com/community-scripts/ProxmoxVE/pull/11271))
|
|
||||||
- tools.func: fix php "wait_for" hint [@MickLesk](https://github.com/MickLesk) ([#11254](https://github.com/community-scripts/ProxmoxVE/pull/11254))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- core: update dynamic values in LXC profile on update_motd_ip [@MickLesk](https://github.com/MickLesk) ([#11268](https://github.com/community-scripts/ProxmoxVE/pull/11268))
|
|
||||||
- tools.func: add new function - setup_meilisearch [@MickLesk](https://github.com/MickLesk) ([#11258](https://github.com/community-scripts/ProxmoxVE/pull/11258))
|
|
||||||
|
|
||||||
### 📂 Github
|
|
||||||
|
|
||||||
- github: add GitHub-based versions.json updater [@MickLesk](https://github.com/MickLesk) ([#10021](https://github.com/community-scripts/ProxmoxVE/pull/10021))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- Frontend: use github-versions.json for version display [@MickLesk](https://github.com/MickLesk) ([#11281](https://github.com/community-scripts/ProxmoxVE/pull/11281))
|
|
||||||
|
|
||||||
- #### 📝 Script Information
|
|
||||||
|
|
||||||
- fix: homarr: conf location [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11253](https://github.com/community-scripts/ProxmoxVE/pull/11253))
|
|
||||||
|
|
||||||
## 2026-01-27
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
- [FIX] Jotty: backup and restore custom config [@vhsdream](https://github.com/vhsdream) ([#11212](https://github.com/community-scripts/ProxmoxVE/pull/11212))
|
- [FIX] Jotty: backup and restore custom config [@vhsdream](https://github.com/vhsdream) ([#11212](https://github.com/community-scripts/ProxmoxVE/pull/11212))
|
||||||
- Immich: update libraw [@vhsdream](https://github.com/vhsdream) ([#11233](https://github.com/community-scripts/ProxmoxVE/pull/11233))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- grist: enable optional enterprise features toggle [@MickLesk](https://github.com/MickLesk) ([#11239](https://github.com/community-scripts/ProxmoxVE/pull/11239))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Termix: use nginx.conf from upstream repo [@MickLesk](https://github.com/MickLesk) ([#11228](https://github.com/community-scripts/ProxmoxVE/pull/11228))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- feat: add NVIDIA driver install prompt for GPU-enabled containers [@devdecrux](https://github.com/devdecrux) ([#11184](https://github.com/community-scripts/ProxmoxVE/pull/11184))
|
|
||||||
|
|
||||||
### 📚 Documentation
|
### 📚 Documentation
|
||||||
|
|
||||||
- doc setup_deb822_repo arg order [@chrnie](https://github.com/chrnie) ([#11215](https://github.com/community-scripts/ProxmoxVE/pull/11215))
|
- doc setup_deb822_repo arg order [@chrnie](https://github.com/chrnie) ([#11215](https://github.com/community-scripts/ProxmoxVE/pull/11215))
|
||||||
- changelog: archive old entries to year/month files [@MickLesk](https://github.com/MickLesk) ([#11225](https://github.com/community-scripts/ProxmoxVE/pull/11225))
|
|
||||||
|
|
||||||
## 2026-01-26
|
## 2026-01-26
|
||||||
|
|
||||||
@@ -242,7 +100,7 @@
|
|||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
|
|
||||||
- Tracearr ([#11079](https://github.com/community-scripts/ProxmoxVE/pull/11079))
|
- Tracearr ([#11079](https://github.com/community-scripts/ProxmoxVE/pull/11079))
|
||||||
- Dawarich ([#11075](https://github.com/community-scripts/ProxmoxVE/pull/11075))
|
- Dawarich ([#11075](https://github.com/community-scripts/ProxmoxVE/pull/11075))
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
@@ -392,7 +250,7 @@
|
|||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
|
|
||||||
- Termix ([#10887](https://github.com/community-scripts/ProxmoxVE/pull/10887))
|
- Termix ([#10887](https://github.com/community-scripts/ProxmoxVE/pull/10887))
|
||||||
- ThingsBoard ([#10904](https://github.com/community-scripts/ProxmoxVE/pull/10904))
|
- ThingsBoard ([#10904](https://github.com/community-scripts/ProxmoxVE/pull/10904))
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
@@ -461,7 +319,7 @@
|
|||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
|
|
||||||
- Flatnotes ([#10857](https://github.com/community-scripts/ProxmoxVE/pull/10857))
|
- Flatnotes ([#10857](https://github.com/community-scripts/ProxmoxVE/pull/10857))
|
||||||
- Unifi OS Server ([#10856](https://github.com/community-scripts/ProxmoxVE/pull/10856))
|
- Unifi OS Server ([#10856](https://github.com/community-scripts/ProxmoxVE/pull/10856))
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
@@ -527,7 +385,7 @@
|
|||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
|
|
||||||
- Investbrain ([#10774](https://github.com/community-scripts/ProxmoxVE/pull/10774))
|
- Investbrain ([#10774](https://github.com/community-scripts/ProxmoxVE/pull/10774))
|
||||||
- Fladder ([#10768](https://github.com/community-scripts/ProxmoxVE/pull/10768))
|
- Fladder ([#10768](https://github.com/community-scripts/ProxmoxVE/pull/10768))
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
@@ -716,7 +574,7 @@
|
|||||||
### 📚 Documentation
|
### 📚 Documentation
|
||||||
|
|
||||||
- [gh] New Script template update [@tremor021](https://github.com/tremor021) ([#10607](https://github.com/community-scripts/ProxmoxVE/pull/10607))
|
- [gh] New Script template update [@tremor021](https://github.com/tremor021) ([#10607](https://github.com/community-scripts/ProxmoxVE/pull/10607))
|
||||||
- chore: bump copyright to 2026 - happy new year [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10585](https://github.com/community-scripts/ProxmoxVE/pull/10585))
|
- chore: bump copyright to 2026 - happy new year [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10585](https://github.com/community-scripts/ProxmoxVE/pull/10585))
|
||||||
|
|
||||||
### 📂 Github
|
### 📂 Github
|
||||||
|
|
||||||
@@ -797,7 +655,7 @@
|
|||||||
### ❔ Uncategorized
|
### ❔ Uncategorized
|
||||||
|
|
||||||
- Wireguard: Update WGDashboard notes URL to the new link [@tremor021](https://github.com/tremor021) ([#10496](https://github.com/community-scripts/ProxmoxVE/pull/10496))
|
- Wireguard: Update WGDashboard notes URL to the new link [@tremor021](https://github.com/tremor021) ([#10496](https://github.com/community-scripts/ProxmoxVE/pull/10496))
|
||||||
- InvoiceNinja: Update database credentias information [@tremor021](https://github.com/tremor021) ([#10497](https://github.com/community-scripts/ProxmoxVE/pull/10497))
|
- InvoiceNinja: Update database credentias information [@tremor021](https://github.com/tremor021) ([#10497](https://github.com/community-scripts/ProxmoxVE/pull/10497))
|
||||||
|
|
||||||
## 2026-01-02
|
## 2026-01-02
|
||||||
|
|
||||||
@@ -826,3 +684,157 @@
|
|||||||
- #### 🐞 Bug Fixes
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
- Fix MariaDB runtime directory persistence on container reboot [@Copilot](https://github.com/Copilot) ([#10468](https://github.com/community-scripts/ProxmoxVE/pull/10468))
|
- Fix MariaDB runtime directory persistence on container reboot [@Copilot](https://github.com/Copilot) ([#10468](https://github.com/community-scripts/ProxmoxVE/pull/10468))
|
||||||
|
|
||||||
|
|
||||||
|
## 2026-01-31
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- shelfmark ([#11371](https://github.com/community-scripts/ProxmoxVE/pull/11371))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix: yubal: add git [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11394](https://github.com/community-scripts/ProxmoxVE/pull/11394))
|
||||||
|
|
||||||
|
## 2026-01-30
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- languagetool ([#11370](https://github.com/community-scripts/ProxmoxVE/pull/11370))
|
||||||
|
- Ampache ([#11369](https://github.com/community-scripts/ProxmoxVE/pull/11369))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Refactor: remove redundant PHP_MODULE entries in several scripts [@MickLesk](https://github.com/MickLesk) ([#11362](https://github.com/community-scripts/ProxmoxVE/pull/11362))
|
||||||
|
- Refactor: Koillection [@MickLesk](https://github.com/MickLesk) ([#11361](https://github.com/community-scripts/ProxmoxVE/pull/11361))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- core: meilisearch - add data migration for version upgrades [@MickLesk](https://github.com/MickLesk) ([#11356](https://github.com/community-scripts/ProxmoxVE/pull/11356))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- [tools] Add `fetch_and_deploy_from_url()` [@tremor021](https://github.com/tremor021) ([#11376](https://github.com/community-scripts/ProxmoxVE/pull/11376))
|
||||||
|
- core: php - improve module handling and prevent installation failures [@MickLesk](https://github.com/MickLesk) ([#11358](https://github.com/community-scripts/ProxmoxVE/pull/11358))
|
||||||
|
|
||||||
|
## 2026-01-29
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Alpine-Valkey [@MickLesk](https://github.com/MickLesk) ([#11320](https://github.com/community-scripts/ProxmoxVE/pull/11320))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Immich: Pin version to 2.5.2 [@vhsdream](https://github.com/vhsdream) ([#11335](https://github.com/community-scripts/ProxmoxVE/pull/11335))
|
||||||
|
- Kollection: Update to php 8.5 [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11315](https://github.com/community-scripts/ProxmoxVE/pull/11315))
|
||||||
|
- Notifiarr: change installation check from apt to systemd service [@MickLesk](https://github.com/MickLesk) ([#11319](https://github.com/community-scripts/ProxmoxVE/pull/11319))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- [FEAT] Immich: Enable Maintenance Mode before update [@vhsdream](https://github.com/vhsdream) ([#11342](https://github.com/community-scripts/ProxmoxVE/pull/11342))
|
||||||
|
- jellyfin: add logrotate instead of reducing log level [@MickLesk](https://github.com/MickLesk) ([#11326](https://github.com/community-scripts/ProxmoxVE/pull/11326))
|
||||||
|
- core: Add config file handling options | Fix Vikunja update with interactive overwrite [@MickLesk](https://github.com/MickLesk) ([#11317](https://github.com/community-scripts/ProxmoxVE/pull/11317))
|
||||||
|
- Immich: v2.5.0 [@vhsdream](https://github.com/vhsdream) ([#11240](https://github.com/community-scripts/ProxmoxVE/pull/11240))
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- fix: vikunja v1 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11308](https://github.com/community-scripts/ProxmoxVE/pull/11308))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Refactor: Byparr [@vhsdream](https://github.com/vhsdream) ([#11338](https://github.com/community-scripts/ProxmoxVE/pull/11338))
|
||||||
|
- cloudflare: Remove deprecated DNS-over-HTTPS proxy option [@MickLesk](https://github.com/MickLesk) ([#11068](https://github.com/community-scripts/ProxmoxVE/pull/11068))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- build.func: Replace storage variable with searchdomain variable [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11322](https://github.com/community-scripts/ProxmoxVE/pull/11322))
|
||||||
|
|
||||||
|
### 📂 Github
|
||||||
|
|
||||||
|
- Add workflow to lock closed issues [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11316](https://github.com/community-scripts/ProxmoxVE/pull/11316))
|
||||||
|
|
||||||
|
## 2026-01-28
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- nodecast-tv ([#11287](https://github.com/community-scripts/ProxmoxVE/pull/11287))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Ubuntu 25.04 VM - Change default start from yes to no [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#11292](https://github.com/community-scripts/ProxmoxVE/pull/11292))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- various scripts: use setup_meilisearch function [@MickLesk](https://github.com/MickLesk) ([#11259](https://github.com/community-scripts/ProxmoxVE/pull/11259))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Refactor: NPMPlus / Default Login [@MickLesk](https://github.com/MickLesk) ([#11262](https://github.com/community-scripts/ProxmoxVE/pull/11262))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- core: sed patch for ram [@lavacano](https://github.com/lavacano) ([#11285](https://github.com/community-scripts/ProxmoxVE/pull/11285))
|
||||||
|
- Fix installer loop caused by invalid whiptail menu separator [@Mesteriis](https://github.com/Mesteriis) ([#11237](https://github.com/community-scripts/ProxmoxVE/pull/11237))
|
||||||
|
- core: fix Debian 13 LXC template root ownership bug [@MickLesk](https://github.com/MickLesk) ([#11277](https://github.com/community-scripts/ProxmoxVE/pull/11277))
|
||||||
|
- tools.func: prevent systemd-tmpfiles failure in unprivileged LXC during deb install [@MickLesk](https://github.com/MickLesk) ([#11271](https://github.com/community-scripts/ProxmoxVE/pull/11271))
|
||||||
|
- tools.func: fix php "wait_for" hint [@MickLesk](https://github.com/MickLesk) ([#11254](https://github.com/community-scripts/ProxmoxVE/pull/11254))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- core: update dynamic values in LXC profile on update_motd_ip [@MickLesk](https://github.com/MickLesk) ([#11268](https://github.com/community-scripts/ProxmoxVE/pull/11268))
|
||||||
|
- tools.func: add new function - setup_meilisearch [@MickLesk](https://github.com/MickLesk) ([#11258](https://github.com/community-scripts/ProxmoxVE/pull/11258))
|
||||||
|
|
||||||
|
### 📂 Github
|
||||||
|
|
||||||
|
- github: add GitHub-based versions.json updater [@MickLesk](https://github.com/MickLesk) ([#10021](https://github.com/community-scripts/ProxmoxVE/pull/10021))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Frontend: use github-versions.json for version display [@MickLesk](https://github.com/MickLesk) ([#11281](https://github.com/community-scripts/ProxmoxVE/pull/11281))
|
||||||
|
|
||||||
|
- #### 📝 Script Information
|
||||||
|
|
||||||
|
- fix: homarr: conf location [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11253](https://github.com/community-scripts/ProxmoxVE/pull/11253))
|
||||||
|
|
||||||
|
## 2026-01-27
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Immich: update libraw [@vhsdream](https://github.com/vhsdream) ([#11233](https://github.com/community-scripts/ProxmoxVE/pull/11233))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- grist: enable optional enterprise features toggle [@MickLesk](https://github.com/MickLesk) ([#11239](https://github.com/community-scripts/ProxmoxVE/pull/11239))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Termix: use nginx.conf from upstream repo [@MickLesk](https://github.com/MickLesk) ([#11228](https://github.com/community-scripts/ProxmoxVE/pull/11228))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- feat: add NVIDIA driver install prompt for GPU-enabled containers [@devdecrux](https://github.com/devdecrux) ([#11184](https://github.com/community-scripts/ProxmoxVE/pull/11184))
|
||||||
|
|
||||||
|
### 📚 Documentation
|
||||||
|
|
||||||
|
- doc setup_deb822_repo arg order [@chrnie](https://github.com/chrnie) ([#11215](https://github.com/community-scripts/ProxmoxVE/pull/11215))
|
||||||
|
- changelog: archive old entries to year/month files [@MickLesk](https://github.com/MickLesk) ([#11225](https://github.com/community-scripts/ProxmoxVE/pull/11225))
|
||||||
121
.github/changelogs/2026/02.md
generated
vendored
121
.github/changelogs/2026/02.md
generated
vendored
@@ -1,121 +0,0 @@
|
|||||||
## 2026-02-04
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Wishlist ([#11527](https://github.com/community-scripts/ProxmoxVE/pull/11527))
|
|
||||||
- WriteFreely ([#11524](https://github.com/community-scripts/ProxmoxVE/pull/11524))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- core: create vm-core.func from dev [@MickLesk](https://github.com/MickLesk) ([#11528](https://github.com/community-scripts/ProxmoxVE/pull/11528))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- fix(frontend): implement weighted search scoring for command menu [@ls-root](https://github.com/ls-root) ([#11534](https://github.com/community-scripts/ProxmoxVE/pull/11534))
|
|
||||||
|
|
||||||
## 2026-02-03
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Wealthfolio ([#11511](https://github.com/community-scripts/ProxmoxVE/pull/11511))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- [FIX] Shelfmark: unpin Chromium version [@vhsdream](https://github.com/vhsdream) ([#11505](https://github.com/community-scripts/ProxmoxVE/pull/11505))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- [FEAT] Scanopy: automatically update integrated daemon [@vhsdream](https://github.com/vhsdream) ([#11506](https://github.com/community-scripts/ProxmoxVE/pull/11506))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- [FIX] tools.func: trim spaces in app_lc when checking for gh release [@vhsdream](https://github.com/vhsdream) ([#11512](https://github.com/community-scripts/ProxmoxVE/pull/11512))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- fix(frontend): decouple table pagination from summary fetching [@ls-root](https://github.com/ls-root) ([#11495](https://github.com/community-scripts/ProxmoxVE/pull/11495))
|
|
||||||
|
|
||||||
## 2026-02-02
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- rustypaste | Alpine-rustypaste ([#11457](https://github.com/community-scripts/ProxmoxVE/pull/11457))
|
|
||||||
- KitchenOwl ([#11453](https://github.com/community-scripts/ProxmoxVE/pull/11453))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Grist: Update dependencies [@tremor021](https://github.com/tremor021) ([#11489](https://github.com/community-scripts/ProxmoxVE/pull/11489))
|
|
||||||
- Allow "downgrade" of libigdgmm12 [@vhsdream](https://github.com/vhsdream) ([#11478](https://github.com/community-scripts/ProxmoxVE/pull/11478))
|
|
||||||
- Disable NPM install and update due to OpenResty SHA-1 signature issues [@MickLesk](https://github.com/MickLesk) ([#11471](https://github.com/community-scripts/ProxmoxVE/pull/11471))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- Refactor: Forgejo & readeck - migrate to codeberg functions [@MickLesk](https://github.com/MickLesk) ([#11460](https://github.com/community-scripts/ProxmoxVE/pull/11460))
|
|
||||||
|
|
||||||
- #### 💥 Breaking Changes
|
|
||||||
|
|
||||||
- [FIX] Scanopy: remove daemon build [@vhsdream](https://github.com/vhsdream) ([#11444](https://github.com/community-scripts/ProxmoxVE/pull/11444))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Refactor: Vaultwarden [@MickLesk](https://github.com/MickLesk) ([#11445](https://github.com/community-scripts/ProxmoxVE/pull/11445))
|
|
||||||
- various scripts: use ensure_dependencies instead of apt [@MickLesk](https://github.com/MickLesk) ([#11463](https://github.com/community-scripts/ProxmoxVE/pull/11463))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- cleanup(frontend): remove unused /category-view route [@ls-root](https://github.com/ls-root) ([#11461](https://github.com/community-scripts/ProxmoxVE/pull/11461))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- feat(frontend): preview tab [@ls-root](https://github.com/ls-root) ([#11475](https://github.com/community-scripts/ProxmoxVE/pull/11475))
|
|
||||||
|
|
||||||
## 2026-02-01
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- fix headers [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11422](https://github.com/community-scripts/ProxmoxVE/pull/11422))
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- 2fauth: export PHP_VERSION for nginx config [@MickLesk](https://github.com/MickLesk) ([#11441](https://github.com/community-scripts/ProxmoxVE/pull/11441))
|
|
||||||
- Prometheus Paperless NGX Exporter: Set correct binary path in systemd unit file [@andygrunwald](https://github.com/andygrunwald) ([#11438](https://github.com/community-scripts/ProxmoxVE/pull/11438))
|
|
||||||
- tracearr: install/update new prestart script from upstream [@durzo](https://github.com/durzo) ([#11433](https://github.com/community-scripts/ProxmoxVE/pull/11433))
|
|
||||||
- n8n: Fix dependencies [@tremor021](https://github.com/tremor021) ([#11429](https://github.com/community-scripts/ProxmoxVE/pull/11429))
|
|
||||||
- [Hotfix] Bunkerweb update [@vhsdream](https://github.com/vhsdream) ([#11402](https://github.com/community-scripts/ProxmoxVE/pull/11402))
|
|
||||||
- [Hotfix] Immich: revert healthcheck feature [@vhsdream](https://github.com/vhsdream) ([#11427](https://github.com/community-scripts/ProxmoxVE/pull/11427))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- tools.func: add codeberg functions & autocaliweb: migrate from GitHub to Codeberg [@MickLesk](https://github.com/MickLesk) ([#11440](https://github.com/community-scripts/ProxmoxVE/pull/11440))
|
|
||||||
- Immich Refactor #2 [@vhsdream](https://github.com/vhsdream) ([#11375](https://github.com/community-scripts/ProxmoxVE/pull/11375))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- WordPress: Refactor [@tremor021](https://github.com/tremor021) ([#11408](https://github.com/community-scripts/ProxmoxVE/pull/11408))
|
|
||||||
- Refactor: Whisparr [@tremor021](https://github.com/tremor021) ([#11411](https://github.com/community-scripts/ProxmoxVE/pull/11411))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- [tools]: Update `fetch_and_deply_from_url()` [@tremor021](https://github.com/tremor021) ([#11410](https://github.com/community-scripts/ProxmoxVE/pull/11410))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- feat(frontend): implement UX refinements and syntax highlighting [@ls-root](https://github.com/ls-root) ([#11423](https://github.com/community-scripts/ProxmoxVE/pull/11423))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- feat(frontend): add contribution CTA to empty search state [@ls-root](https://github.com/ls-root) ([#11412](https://github.com/community-scripts/ProxmoxVE/pull/11412))
|
|
||||||
97
.github/workflows/changelog-archive.yml
generated
vendored
97
.github/workflows/changelog-archive.yml
generated
vendored
@@ -54,9 +54,8 @@ jobs:
|
|||||||
|
|
||||||
console.log(`Cutoff date: ${cutoffDate.toISOString().split('T')[0]}`);
|
console.log(`Cutoff date: ${cutoffDate.toISOString().split('T')[0]}`);
|
||||||
|
|
||||||
// Read changelog and normalize line endings
|
// Read changelog
|
||||||
let content = await fs.readFile(CHANGELOG_PATH, 'utf-8');
|
const content = await fs.readFile(CHANGELOG_PATH, 'utf-8');
|
||||||
content = content.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
||||||
const lines = content.split('\n');
|
const lines = content.split('\n');
|
||||||
|
|
||||||
// Parse entries
|
// Parse entries
|
||||||
@@ -67,39 +66,9 @@ jobs:
|
|||||||
let currentDate = null;
|
let currentDate = null;
|
||||||
let currentContent = [];
|
let currentContent = [];
|
||||||
let inHeader = true;
|
let inHeader = true;
|
||||||
let inOldHistory = false;
|
|
||||||
let historyDetailsDepth = 0;
|
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (const line of lines) {
|
||||||
const line = lines[i];
|
|
||||||
const match = line.match(datePattern);
|
const match = line.match(datePattern);
|
||||||
|
|
||||||
// Detect the start of History section: <details> followed by line with 📜 History
|
|
||||||
if (inHeader && !inOldHistory && line.trim() === '<details>') {
|
|
||||||
// Look ahead to see if this is the History section
|
|
||||||
const nextLine = lines[i + 1] || '';
|
|
||||||
if (nextLine.includes('📜 History')) {
|
|
||||||
inOldHistory = true;
|
|
||||||
historyDetailsDepth = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track nested details tags to find the end of History section
|
|
||||||
if (inOldHistory) {
|
|
||||||
if (line.trim() === '<details>') {
|
|
||||||
historyDetailsDepth++;
|
|
||||||
}
|
|
||||||
if (line.trim() === '</details>') {
|
|
||||||
historyDetailsDepth--;
|
|
||||||
if (historyDetailsDepth === 0) {
|
|
||||||
// We've closed the main History details tag
|
|
||||||
inOldHistory = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
inHeader = false;
|
inHeader = false;
|
||||||
|
|
||||||
@@ -179,55 +148,30 @@ jobs:
|
|||||||
let existingContent = '';
|
let existingContent = '';
|
||||||
try {
|
try {
|
||||||
existingContent = await fs.readFile(monthPath, 'utf-8');
|
existingContent = await fs.readFile(monthPath, 'utf-8');
|
||||||
// Normalize line endings to prevent regex issues
|
|
||||||
existingContent = existingContent.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// File doesn't exist
|
// File doesn't exist
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse existing entries into a Map (date -> content) for deduplication
|
// Merge new entries with existing (avoid duplicates)
|
||||||
const allEntries = new Map();
|
const existingDates = new Set();
|
||||||
|
const existingDatePattern = /^## (\d{4}-\d{2}-\d{2})$/gm;
|
||||||
// Helper function to parse entries from content
|
let match;
|
||||||
const parseEntries = (content) => {
|
while ((match = existingDatePattern.exec(existingContent)) !== null) {
|
||||||
const entries = new Map();
|
existingDates.add(match[1]);
|
||||||
const parts = content.split(/(?=^## \d{4}-\d{2}-\d{2}$)/m);
|
|
||||||
for (const part of parts) {
|
|
||||||
const trimmed = part.trim();
|
|
||||||
if (!trimmed) continue;
|
|
||||||
const dateMatch = trimmed.match(/^## (\d{4}-\d{2}-\d{2})/);
|
|
||||||
if (dateMatch) {
|
|
||||||
entries.set(dateMatch[1], trimmed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entries;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parse existing content
|
|
||||||
if (existingContent) {
|
|
||||||
const existingEntries = parseEntries(existingContent);
|
|
||||||
for (const [date, content] of existingEntries) {
|
|
||||||
allEntries.set(date, content);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new entries (existing entries take precedence to avoid overwriting)
|
const newEntries = archiveData[year][month].filter(entry => {
|
||||||
let addedCount = 0;
|
|
||||||
for (const entry of archiveData[year][month]) {
|
|
||||||
const dateMatch = entry.match(/^## (\d{4}-\d{2}-\d{2})/);
|
const dateMatch = entry.match(/^## (\d{4}-\d{2}-\d{2})/);
|
||||||
if (dateMatch && !allEntries.has(dateMatch[1])) {
|
return dateMatch && !existingDates.has(dateMatch[1]);
|
||||||
allEntries.set(dateMatch[1], entry.trim());
|
});
|
||||||
addedCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort entries by date (newest first) and write
|
if (newEntries.length > 0) {
|
||||||
const sortedDates = [...allEntries.keys()].sort().reverse();
|
const allContent = existingContent
|
||||||
const sortedContent = sortedDates.map(date => allEntries.get(date)).join('\n\n');
|
? existingContent + '\n\n' + newEntries.join('\n\n')
|
||||||
|
: newEntries.join('\n\n');
|
||||||
if (addedCount > 0 || !existingContent) {
|
|
||||||
await fs.writeFile(monthPath, sortedContent + '\n', 'utf-8');
|
await fs.writeFile(monthPath, allContent, 'utf-8');
|
||||||
console.log(`Updated: ${monthPath} (${allEntries.size} total entries, +${addedCount} new)`);
|
console.log(`Updated: ${monthPath} (+${newEntries.length} entries)`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,8 +218,7 @@ jobs:
|
|||||||
// Count entries in month file
|
// Count entries in month file
|
||||||
let entryCount = 0;
|
let entryCount = 0;
|
||||||
try {
|
try {
|
||||||
let monthContent = await fs.readFile(monthPath, 'utf-8');
|
const monthContent = await fs.readFile(monthPath, 'utf-8');
|
||||||
monthContent = monthContent.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
||||||
entryCount = (monthContent.match(/^## \d{4}-\d{2}-\d{2}$/gm) || []).length;
|
entryCount = (monthContent.match(/^## \d{4}-\d{2}-\d{2}$/gm) || []).length;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
entryCount = (archiveData[year]?.[month] || []).length;
|
entryCount = (archiveData[year]?.[month] || []).length;
|
||||||
|
|||||||
476
CHANGELOG.md
476
CHANGELOG.md
@@ -21,14 +21,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h4>February (4 entries)</h4></summary>
|
<summary><h4>January - 27 entries</h4></summary>
|
||||||
|
|
||||||
[View February 2026 Changelog](.github/changelogs/2026/02.md)
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><h4>January (31 entries)</h4></summary>
|
|
||||||
|
|
||||||
[View January 2026 Changelog](.github/changelogs/2026/01.md)
|
[View January 2026 Changelog](.github/changelogs/2026/01.md)
|
||||||
|
|
||||||
@@ -398,19 +391,386 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## 2026-02-05
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
<details>
|
||||||
|
<summary><h2>📜 History</h2></summary>
|
||||||
|
|
||||||
- Refactor: Docker-VM (Multi-OS / Cloud-Init / Stabilization) [@MickLesk](https://github.com/MickLesk) ([#9047](https://github.com/community-scripts/ProxmoxVE/pull/9047))
|
|
||||||
|
|
||||||
### 💾 Core
|
<details>
|
||||||
|
<summary><h3>2026</h3></summary>
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- cloud-init: add interactive SSH key discovery and selection [@MickLesk](https://github.com/MickLesk) ([#11547](https://github.com/community-scripts/ProxmoxVE/pull/11547))
|
<details>
|
||||||
|
<summary><h4>January (31 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View January 2026 Changelog](.github/changelogs/2026/01.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h3>2025</h3></summary>
|
||||||
|
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>December (31 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View December 2025 Changelog](.github/changelogs/2025/12.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>November (29 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View November 2025 Changelog](.github/changelogs/2025/11.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>October (30 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View October 2025 Changelog](.github/changelogs/2025/10.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>September (29 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View September 2025 Changelog](.github/changelogs/2025/09.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>August (30 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View August 2025 Changelog](.github/changelogs/2025/08.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>July (29 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View July 2025 Changelog](.github/changelogs/2025/07.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>June (29 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View June 2025 Changelog](.github/changelogs/2025/06.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>May (30 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View May 2025 Changelog](.github/changelogs/2025/05.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>April (25 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View April 2025 Changelog](.github/changelogs/2025/04.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>March (30 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View March 2025 Changelog](.github/changelogs/2025/03.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>February (26 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View February 2025 Changelog](.github/changelogs/2025/02.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>January (27 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View January 2025 Changelog](.github/changelogs/2025/01.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h3>2024</h3></summary>
|
||||||
|
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>December (22 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View December 2024 Changelog](.github/changelogs/2024/12.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>November (15 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View November 2024 Changelog](.github/changelogs/2024/11.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>October (9 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View October 2024 Changelog](.github/changelogs/2024/10.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>September (1 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View September 2024 Changelog](.github/changelogs/2024/09.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>August (2 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View August 2024 Changelog](.github/changelogs/2024/08.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>July (0 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View July 2024 Changelog](.github/changelogs/2024/07.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>June (8 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View June 2024 Changelog](.github/changelogs/2024/06.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>May (16 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View May 2024 Changelog](.github/changelogs/2024/05.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>April (14 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View April 2024 Changelog](.github/changelogs/2024/04.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>March (5 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View March 2024 Changelog](.github/changelogs/2024/03.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>February (9 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View February 2024 Changelog](.github/changelogs/2024/02.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>January (9 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View January 2024 Changelog](.github/changelogs/2024/01.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h3>2023</h3></summary>
|
||||||
|
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>December (3 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View December 2023 Changelog](.github/changelogs/2023/12.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>November (3 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View November 2023 Changelog](.github/changelogs/2023/11.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>October (7 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View October 2023 Changelog](.github/changelogs/2023/10.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>September (10 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View September 2023 Changelog](.github/changelogs/2023/09.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>August (7 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View August 2023 Changelog](.github/changelogs/2023/08.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>July (5 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View July 2023 Changelog](.github/changelogs/2023/07.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>June (5 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View June 2023 Changelog](.github/changelogs/2023/06.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>May (8 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View May 2023 Changelog](.github/changelogs/2023/05.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>April (8 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View April 2023 Changelog](.github/changelogs/2023/04.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>March (8 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View March 2023 Changelog](.github/changelogs/2023/03.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>February (6 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View February 2023 Changelog](.github/changelogs/2023/02.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>January (15 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View January 2023 Changelog](.github/changelogs/2023/01.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h3>2022</h3></summary>
|
||||||
|
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>December (7 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View December 2022 Changelog](.github/changelogs/2022/12.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>November (7 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View November 2022 Changelog](.github/changelogs/2022/11.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>October (2 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View October 2022 Changelog](.github/changelogs/2022/10.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>September (9 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View September 2022 Changelog](.github/changelogs/2022/09.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>August (7 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View August 2022 Changelog](.github/changelogs/2022/08.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>July (10 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View July 2022 Changelog](.github/changelogs/2022/07.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>June (1 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View June 2022 Changelog](.github/changelogs/2022/06.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>May (8 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View May 2022 Changelog](.github/changelogs/2022/05.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>April (13 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View April 2022 Changelog](.github/changelogs/2022/04.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>March (20 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View March 2022 Changelog](.github/changelogs/2022/03.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>February (15 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View February 2022 Changelog](.github/changelogs/2022/02.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><h4>January (3 entries)</h4></summary>
|
||||||
|
|
||||||
|
[View January 2022 Changelog](.github/changelogs/2022/01.md)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## 2026-02-04
|
## 2026-02-04
|
||||||
|
|
||||||
@@ -419,37 +779,12 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
- Wishlist ([#11527](https://github.com/community-scripts/ProxmoxVE/pull/11527))
|
- Wishlist ([#11527](https://github.com/community-scripts/ProxmoxVE/pull/11527))
|
||||||
- WriteFreely ([#11524](https://github.com/community-scripts/ProxmoxVE/pull/11524))
|
- WriteFreely ([#11524](https://github.com/community-scripts/ProxmoxVE/pull/11524))
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- Add log directory and permissions for koillection [@shineangelic](https://github.com/shineangelic) ([#11553](https://github.com/community-scripts/ProxmoxVE/pull/11553))
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- [FIX] Scanopy: ensure Scanopy Daemon update [@vhsdream](https://github.com/vhsdream) ([#11541](https://github.com/community-scripts/ProxmoxVE/pull/11541))
|
|
||||||
- Immich: pin version to 2.5.3 [@vhsdream](https://github.com/vhsdream) ([#11515](https://github.com/community-scripts/ProxmoxVE/pull/11515))
|
|
||||||
|
|
||||||
### 💾 Core
|
### 💾 Core
|
||||||
|
|
||||||
- #### ✨ New Features
|
- #### ✨ New Features
|
||||||
|
|
||||||
- core: create vm-core.func from dev [@MickLesk](https://github.com/MickLesk) ([#11528](https://github.com/community-scripts/ProxmoxVE/pull/11528))
|
- core: create vm-core.func from dev [@MickLesk](https://github.com/MickLesk) ([#11528](https://github.com/community-scripts/ProxmoxVE/pull/11528))
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- [ADDON] Immich Public Proxy addon [@vhsdream](https://github.com/vhsdream) ([#11518](https://github.com/community-scripts/ProxmoxVE/pull/11518))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- fix(frontend): implement weighted search scoring for command menu [@ls-root](https://github.com/ls-root) ([#11534](https://github.com/community-scripts/ProxmoxVE/pull/11534))
|
|
||||||
|
|
||||||
### ❔ Uncategorized
|
|
||||||
|
|
||||||
- [FIX] Immich Public Proxy docs link [@vhsdream](https://github.com/vhsdream) ([#11543](https://github.com/community-scripts/ProxmoxVE/pull/11543))
|
|
||||||
|
|
||||||
## 2026-02-03
|
## 2026-02-03
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
@@ -1303,3 +1638,64 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
- #### 🔧 Refactor
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
- Refactor: IP-Tag (Multiple IP / Performance / Execution Time) [@MickLesk](https://github.com/MickLesk) ([#10558](https://github.com/community-scripts/ProxmoxVE/pull/10558))
|
- Refactor: IP-Tag (Multiple IP / Performance / Execution Time) [@MickLesk](https://github.com/MickLesk) ([#10558](https://github.com/community-scripts/ProxmoxVE/pull/10558))
|
||||||
|
|
||||||
|
## 2026-01-04
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- PocketID: Update PocketID for 2.x [@tremor021](https://github.com/tremor021) ([#10506](https://github.com/community-scripts/ProxmoxVE/pull/10506))
|
||||||
|
- fix: reitti: nginx [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10511](https://github.com/community-scripts/ProxmoxVE/pull/10511))
|
||||||
|
- MagicMirror: bump to nodejs 24 [@MickLesk](https://github.com/MickLesk) ([#10534](https://github.com/community-scripts/ProxmoxVE/pull/10534))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Refactor: SFTPGo [@tremor021](https://github.com/tremor021) ([#10518](https://github.com/community-scripts/ProxmoxVE/pull/10518))
|
||||||
|
- Refactor: Pelican Wings [@tremor021](https://github.com/tremor021) ([#10517](https://github.com/community-scripts/ProxmoxVE/pull/10517))
|
||||||
|
- Refactor: Pelican Panel [@tremor021](https://github.com/tremor021) ([#10516](https://github.com/community-scripts/ProxmoxVE/pull/10516))
|
||||||
|
- Refactor: Audiobookshelf [@tremor021](https://github.com/tremor021) ([#10519](https://github.com/community-scripts/ProxmoxVE/pull/10519))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Export IPV6_METHOD to trigger verb_ip6() function [@remz1337](https://github.com/remz1337) ([#10538](https://github.com/community-scripts/ProxmoxVE/pull/10538))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- #### 📝 Script Information
|
||||||
|
|
||||||
|
- Prowlarr: Update config_path [@tremor021](https://github.com/tremor021) ([#10504](https://github.com/community-scripts/ProxmoxVE/pull/10504))
|
||||||
|
|
||||||
|
## 2026-01-03
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Fix ownership and permissions for InvoiceNinja setup [@twinzdragonz](https://github.com/twinzdragonz) ([#10298](https://github.com/community-scripts/ProxmoxVE/pull/10298))
|
||||||
|
- Fix headscale Caddyfile to pass non-API URLs [@IlyaSemenov](https://github.com/IlyaSemenov) ([#10493](https://github.com/community-scripts/ProxmoxVE/pull/10493))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- [core]: Preserve log files [@tremor021](https://github.com/tremor021) ([#10509](https://github.com/community-scripts/ProxmoxVE/pull/10509))
|
||||||
|
|
||||||
|
### ❔ Uncategorized
|
||||||
|
|
||||||
|
- Wireguard: Update WGDashboard notes URL to the new link [@tremor021](https://github.com/tremor021) ([#10496](https://github.com/community-scripts/ProxmoxVE/pull/10496))
|
||||||
|
- InvoiceNinja: Update database credentias information [@tremor021](https://github.com/tremor021) ([#10497](https://github.com/community-scripts/ProxmoxVE/pull/10497))
|
||||||
|
|
||||||
|
## 2026-01-02
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Fix Intel Level Zero package conflict on Debian 13 [@Copilot](https://github.com/Copilot) ([#10467](https://github.com/community-scripts/ProxmoxVE/pull/10467))
|
||||||
|
|
||||||
|
### ❔ Uncategorized
|
||||||
|
|
||||||
|
- Extend guidance for changing the immich upload location for #10447 [@jshprentz](https://github.com/jshprentz) ([#10475](https://github.com/community-scripts/ProxmoxVE/pull/10475))
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
_____ ____ __ _____ ___ ____ ___ ______
|
|
||||||
/ ___// __ \ / / / ___/___ ______ _____ _____ |__ \ / __ \__ \ / ____/
|
|
||||||
\__ \/ / / / / / \__ \/ _ \/ ___/ | / / _ \/ ___/ __/ // / / /_/ //___ \
|
|
||||||
___/ / /_/ / / /___ ___/ / __/ / | |/ / __/ / / __// /_/ / __/____/ /
|
|
||||||
/____/\___\_\/_____/ /____/\___/_/ |___/\___/_/ /____/\____/____/_____/
|
|
||||||
|
|
||||||
@@ -36,6 +36,10 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
setup_uv
|
||||||
|
PNPM_VERSION="$(curl -fsSL "https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/package.json" | jq -r '.packageManager | split("@")[1]')"
|
||||||
|
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
|
||||||
|
|
||||||
if [[ ! -f /etc/apt/preferences.d/preferences ]]; then
|
if [[ ! -f /etc/apt/preferences.d/preferences ]]; then
|
||||||
msg_info "Adding Debian Testing repo"
|
msg_info "Adding Debian Testing repo"
|
||||||
sed -i 's/ trixie-updates/ trixie-updates testing/g' /etc/apt/sources.list.d/debian.sources
|
sed -i 's/ trixie-updates/ trixie-updates testing/g' /etc/apt/sources.list.d/debian.sources
|
||||||
@@ -105,7 +109,7 @@ EOF
|
|||||||
msg_ok "Image-processing libraries up to date"
|
msg_ok "Image-processing libraries up to date"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RELEASE="2.5.3"
|
RELEASE="2.5.2"
|
||||||
if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then
|
if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then
|
||||||
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
|
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
|
||||||
msg_info "Enabling Maintenance Mode"
|
msg_info "Enabling Maintenance Mode"
|
||||||
@@ -160,10 +164,7 @@ EOF
|
|||||||
rm -rf "${APP_DIR:?}"/*
|
rm -rf "${APP_DIR:?}"/*
|
||||||
)
|
)
|
||||||
|
|
||||||
setup_uv
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v${RELEASE}" "$SRC_DIR"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v${RELEASE}" "$SRC_DIR"
|
||||||
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1]' ${SRC_DIR}/package.json)"
|
|
||||||
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
|
|
||||||
|
|
||||||
msg_info "Updating Immich web and microservices"
|
msg_info "Updating Immich web and microservices"
|
||||||
cd "$SRC_DIR"/server
|
cd "$SRC_DIR"/server
|
||||||
|
|||||||
@@ -59,8 +59,6 @@ function update_script() {
|
|||||||
$STD yarn install
|
$STD yarn install
|
||||||
$STD yarn build
|
$STD yarn build
|
||||||
mkdir -p /opt/koillection/public/uploads
|
mkdir -p /opt/koillection/public/uploads
|
||||||
mkdir -p /opt/koillection/var/log
|
|
||||||
chown -R www-data:www-data /opt/koillection/var/log
|
|
||||||
chown -R www-data:www-data /opt/koillection/public/uploads
|
chown -R www-data:www-data /opt/koillection/public/uploads
|
||||||
rm -r /opt/koillection-backup
|
rm -r /opt/koillection-backup
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "Scanopy" "scanopy/scanopy"; then
|
if check_for_gh_release "scanopy" "scanopy/scanopy"; then
|
||||||
msg_info "Stopping services"
|
msg_info "Stopping services"
|
||||||
systemctl stop scanopy-server
|
systemctl stop scanopy-server
|
||||||
[[ -f /etc/systemd/system/scanopy-daemon.service ]] && systemctl stop scanopy-daemon
|
[[ -f /etc/systemd/system/scanopy-daemon.service ]] && systemctl stop scanopy-daemon
|
||||||
@@ -40,7 +40,7 @@ function update_script() {
|
|||||||
[[ -f /opt/scanopy/oidc.toml ]] && cp /opt/scanopy/oidc.toml /opt/scanopy.oidc.toml
|
[[ -f /opt/scanopy/oidc.toml ]] && cp /opt/scanopy/oidc.toml /opt/scanopy.oidc.toml
|
||||||
msg_ok "Backed up configurations"
|
msg_ok "Backed up configurations"
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
||||||
|
|
||||||
ensure_dependencies pkg-config libssl-dev
|
ensure_dependencies pkg-config libssl-dev
|
||||||
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
|
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
|
||||||
@@ -61,22 +61,19 @@ function update_script() {
|
|||||||
$STD npm run build
|
$STD npm run build
|
||||||
msg_ok "Created frontend UI"
|
msg_ok "Created frontend UI"
|
||||||
|
|
||||||
msg_info "Building Scanopy Server (patience)"
|
msg_info "Building scanopy-server (patience)"
|
||||||
cd /opt/scanopy/backend
|
cd /opt/scanopy/backend
|
||||||
$STD cargo build --release --bin server
|
$STD cargo build --release --bin server
|
||||||
mv ./target/release/server /usr/bin/scanopy-server
|
mv ./target/release/server /usr/bin/scanopy-server
|
||||||
msg_ok "Built Scanopy Server"
|
msg_ok "Built scanopy-server"
|
||||||
|
|
||||||
if [[ -f /etc/systemd/system/scanopy-daemon.service ]]; then
|
[[ -f /etc/systemd/system/scanopy-daemon.service ]] &&
|
||||||
fetch_and_deploy_gh_release "Scanopy Daemon" "scanopy/scanopy" "singlefile" "latest" "/usr/local/bin" "scanopy-daemon-linux-amd64"
|
fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "singlefile" "latest" "/usr/local/bin" "scanopy-daemon-linux-amd64" &&
|
||||||
mv "/usr/local/bin/Scanopy Daemon" /usr/local/bin/scanopy-daemon
|
rm -f /usr/bin/scanopy-daemon ~/configure_daemon.sh &&
|
||||||
rm -f /usr/bin/scanopy-daemon ~/configure_daemon.sh
|
|
||||||
sed -i -e 's|usr/bin|usr/local/bin|' \
|
sed -i -e 's|usr/bin|usr/local/bin|' \
|
||||||
-e 's/push/daemon_poll/' \
|
-e 's/push/daemon_poll/' \
|
||||||
-e 's/pull/server_poll/' /etc/systemd/system/scanopy-daemon.service
|
-e 's/pull/server_poll/' /etc/systemd/system/scanopy-daemon.service &&
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
msg_ok "Updated Scanopy Daemon"
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Starting services"
|
msg_info "Starting services"
|
||||||
systemctl start scanopy-server
|
systemctl start scanopy-server
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
msg_info "Updating SQL Server 2022"
|
msg_info "Updating ${APP} LXC"
|
||||||
rm -f /etc/profile.d/debuginfod.sh /etc/profile.d/debuginfod.csh
|
|
||||||
$STD apt update
|
$STD apt update
|
||||||
$STD apt -y upgrade
|
$STD apt -y upgrade
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://www.microsoft.com/en-us/sql-server/sql-server-2025
|
|
||||||
|
|
||||||
APP="SQL Server 2025"
|
|
||||||
var_tags="${var_tags:-sql;database}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-10}"
|
|
||||||
var_os="${var_os:-ubuntu}"
|
|
||||||
var_version="${var_version:-24.04}"
|
|
||||||
var_unprivileged="${var_unprivileged:-0}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -d /opt/mssql ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
msg_info "Updating SQL Server 2025"
|
|
||||||
rm -f /etc/profile.d/debuginfod.sh /etc/profile.d/debuginfod.csh
|
|
||||||
$STD apt update
|
|
||||||
$STD apt -y upgrade
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
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 IP:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}${IP}:1433${CL}"
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated": "2026-02-05T06:22:20Z",
|
"generated": "2026-02-04T06:18:03Z",
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
{
|
||||||
"slug": "2fauth",
|
"slug": "2fauth",
|
||||||
@@ -221,9 +221,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "cronicle",
|
"slug": "cronicle",
|
||||||
"repo": "jhuckaby/Cronicle",
|
"repo": "jhuckaby/Cronicle",
|
||||||
"version": "v0.9.103",
|
"version": "v0.9.102",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-05T03:09:04Z"
|
"date": "2025-12-19T03:45:13Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "cryptpad",
|
"slug": "cryptpad",
|
||||||
@@ -256,9 +256,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "docmost",
|
"slug": "docmost",
|
||||||
"repo": "docmost/docmost",
|
"repo": "docmost/docmost",
|
||||||
"version": "v0.25.1",
|
"version": "v0.25.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T15:19:51Z"
|
"date": "2026-02-04T00:33:45Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "domain-locker",
|
"slug": "domain-locker",
|
||||||
@@ -445,9 +445,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "headscale",
|
"slug": "headscale",
|
||||||
"repo": "juanfont/headscale",
|
"repo": "juanfont/headscale",
|
||||||
"version": "v0.28.0",
|
"version": "v0.27.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T20:40:23Z"
|
"date": "2025-11-11T19:32:29Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "healthchecks",
|
"slug": "healthchecks",
|
||||||
@@ -494,9 +494,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "homepage",
|
"slug": "homepage",
|
||||||
"repo": "gethomepage/homepage",
|
"repo": "gethomepage/homepage",
|
||||||
"version": "v1.10.0",
|
"version": "v1.9.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-05T06:17:32Z"
|
"date": "2026-01-19T05:46:09Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "homer",
|
"slug": "homer",
|
||||||
@@ -515,9 +515,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "huntarr",
|
"slug": "huntarr",
|
||||||
"repo": "plexguide/Huntarr.io",
|
"repo": "plexguide/Huntarr.io",
|
||||||
"version": "9.2.0",
|
"version": "9.1.9.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-05T04:18:08Z"
|
"date": "2026-02-04T01:08:22Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "inspircd",
|
"slug": "inspircd",
|
||||||
@@ -536,16 +536,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "invoiceninja",
|
"slug": "invoiceninja",
|
||||||
"repo": "invoiceninja/invoiceninja",
|
"repo": "invoiceninja/invoiceninja",
|
||||||
"version": "v5.12.55",
|
"version": "v5.12.53",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-05T01:06:15Z"
|
"date": "2026-02-04T00:52:01Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "jackett",
|
"slug": "jackett",
|
||||||
"repo": "Jackett/Jackett",
|
"repo": "Jackett/Jackett",
|
||||||
"version": "v0.24.1032",
|
"version": "v0.24.1027",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-05T05:55:27Z"
|
"date": "2026-02-04T05:56:22Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "joplin-server",
|
"slug": "joplin-server",
|
||||||
@@ -746,9 +746,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "mealie",
|
"slug": "mealie",
|
||||||
"repo": "mealie-recipes/mealie",
|
"repo": "mealie-recipes/mealie",
|
||||||
"version": "v3.10.2",
|
"version": "v3.10.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T23:32:32Z"
|
"date": "2026-02-03T01:04:38Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "mediamanager",
|
"slug": "mediamanager",
|
||||||
@@ -781,9 +781,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "metube",
|
"slug": "metube",
|
||||||
"repo": "alexta69/metube",
|
"repo": "alexta69/metube",
|
||||||
"version": "2026.02.04",
|
"version": "2026.02.03",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T20:01:18Z"
|
"date": "2026-02-03T21:49:49Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "miniflux",
|
"slug": "miniflux",
|
||||||
@@ -1096,9 +1096,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "pulse",
|
"slug": "pulse",
|
||||||
"repo": "rcourtman/Pulse",
|
"repo": "rcourtman/Pulse",
|
||||||
"version": "v5.1.2",
|
"version": "v5.0.17",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-05T00:18:57Z"
|
"date": "2026-01-20T19:07:30Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "pve-scripts-local",
|
"slug": "pve-scripts-local",
|
||||||
@@ -1271,9 +1271,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "speedtest-tracker",
|
"slug": "speedtest-tracker",
|
||||||
"repo": "alexjustesen/speedtest-tracker",
|
"repo": "alexjustesen/speedtest-tracker",
|
||||||
"version": "v1.13.8",
|
"version": "v1.13.6",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T19:24:23Z"
|
"date": "2026-02-03T21:20:51Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "spoolman",
|
"slug": "spoolman",
|
||||||
@@ -1292,9 +1292,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "stirling-pdf",
|
"slug": "stirling-pdf",
|
||||||
"repo": "Stirling-Tools/Stirling-PDF",
|
"repo": "Stirling-Tools/Stirling-PDF",
|
||||||
"version": "v2.4.4",
|
"version": "v2.4.3",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-05T00:15:53Z"
|
"date": "2026-01-31T22:19:14Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "streamlink-webui",
|
"slug": "streamlink-webui",
|
||||||
@@ -1369,9 +1369,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "tianji",
|
"slug": "tianji",
|
||||||
"repo": "msgbyte/tianji",
|
"repo": "msgbyte/tianji",
|
||||||
"version": "v1.31.10",
|
"version": "v1.31.9",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T17:21:04Z"
|
"date": "2026-01-31T18:22:40Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "traccar",
|
"slug": "traccar",
|
||||||
@@ -1411,9 +1411,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "trip",
|
"slug": "trip",
|
||||||
"repo": "itskovacs/TRIP",
|
"repo": "itskovacs/TRIP",
|
||||||
"version": "1.38.1",
|
"version": "1.38.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-04T18:10:15Z"
|
"date": "2026-01-31T15:56:30Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "tududi",
|
"slug": "tududi",
|
||||||
@@ -1562,13 +1562,6 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-01-08T09:50:00Z"
|
"date": "2026-01-08T09:50:00Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"slug": "wishlist",
|
|
||||||
"repo": "cmintey/wishlist",
|
|
||||||
"version": "v0.59.0",
|
|
||||||
"pinned": false,
|
|
||||||
"date": "2026-01-19T16:42:14Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"slug": "wizarr",
|
"slug": "wizarr",
|
||||||
"repo": "wizarrrr/wizarr",
|
"repo": "wizarrrr/wizarr",
|
||||||
@@ -1576,13 +1569,6 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-12-09T14:30:23Z"
|
"date": "2025-12-09T14:30:23Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"slug": "writefreely",
|
|
||||||
"repo": "writefreely/writefreely",
|
|
||||||
"version": "v0.16.0",
|
|
||||||
"pinned": false,
|
|
||||||
"date": "2025-08-29T19:30:02Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"slug": "yt-dlp-webui",
|
"slug": "yt-dlp-webui",
|
||||||
"repo": "marcopiovanello/yt-dlp-web-ui",
|
"repo": "marcopiovanello/yt-dlp-web-ui",
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Immich Public Proxy",
|
|
||||||
"slug": "immich-public-proxy",
|
|
||||||
"categories": [
|
|
||||||
21
|
|
||||||
],
|
|
||||||
"date_created": "2026-02-04",
|
|
||||||
"type": "addon",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": false,
|
|
||||||
"interface_port": 3000,
|
|
||||||
"documentation": "https://github.com/alangrainger/immich-public-proxy/tree/main/docs",
|
|
||||||
"website": "https://github.com/alangrainger/immich-public-proxy",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/immich-public-proxy.webp",
|
|
||||||
"config_path": "/opt/immich-proxy/app/.env",
|
|
||||||
"description": "Share your Immich photos and albums in a safe way without exposing your Immich instance to the public.",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "tools/addon/immich-public-proxy.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": null,
|
|
||||||
"ram": null,
|
|
||||||
"hdd": null,
|
|
||||||
"os": null,
|
|
||||||
"version": null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": null,
|
|
||||||
"password": null
|
|
||||||
},
|
|
||||||
"notes": [
|
|
||||||
{
|
|
||||||
"text": "Requires Node.js 24+",
|
|
||||||
"type": "info"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Update with: update_immich-public-proxy",
|
|
||||||
"type": "info"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "SQL Server 2025",
|
|
||||||
"slug": "sqlserver2025",
|
|
||||||
"categories": [
|
|
||||||
8
|
|
||||||
],
|
|
||||||
"date_created": "2026-02-04",
|
|
||||||
"type": "ct",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": true,
|
|
||||||
"interface_port": 1433,
|
|
||||||
"documentation": "https://learn.microsoft.com/en-us/sql/sql-server/?view=sql-server-ver17",
|
|
||||||
"website": "https://www.microsoft.com/en-us/sql-server/sql-server-2025",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/microsoft-sql-server.webp",
|
|
||||||
"config_path": "",
|
|
||||||
"description": "Script to automatically set up a SQL Server 2025 installation with Ubuntu 24.04 support.",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "ct/sqlserver2025.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": 2,
|
|
||||||
"ram": 2048,
|
|
||||||
"hdd": 10,
|
|
||||||
"os": "Ubuntu",
|
|
||||||
"version": "24.04"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": null,
|
|
||||||
"password": null
|
|
||||||
},
|
|
||||||
"notes": [
|
|
||||||
{
|
|
||||||
"text": "If you choose not to run the installation setup, execute: `/opt/mssql/bin/mssql-conf setup` in LXC shell.",
|
|
||||||
"type": "info"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "You can setup the admin account 'SA' during installation",
|
|
||||||
"type": "info"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Make sure you disable the SA account if you intend to use this in production!",
|
|
||||||
"type": "warning"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Ubuntu 24.04 support requires SQL Server 2025 CU1 or later",
|
|
||||||
"type": "info"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
84
frontend/public/json/update-apps.json
Normal file
84
frontend/public/json/update-apps.json
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"name": "PVE LXC Apps Updater",
|
||||||
|
"slug": "update-apps",
|
||||||
|
"categories": [
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"date_created": "2025-02-04",
|
||||||
|
"type": "pve",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": null,
|
||||||
|
"documentation": "https://github.com/community-scripts/ProxmoxVE/discussions/11532",
|
||||||
|
"website": null,
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/proxmox.webp",
|
||||||
|
"config_path": "",
|
||||||
|
"description": "This script updates community-scripts managed LXC containers on a Proxmox VE node. It detects the installed service, verifies available update scripts, and applies updates interactively or unattended. Optionally, containers can be backed up before the update process. If additional build resources (CPU/RAM) are required, the script adjusts container resources temporarily and restores them after the update. Containers requiring a reboot will be listed at the end of the process.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "tools/pve/update-apps.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": null,
|
||||||
|
"ram": null,
|
||||||
|
"hdd": null,
|
||||||
|
"os": null,
|
||||||
|
"version": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": [
|
||||||
|
{
|
||||||
|
"text": "Execute within the Proxmox shell.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Full Guide can be found here: `https://github.com/community-scripts/ProxmoxVE/discussions/11532`",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Only containers with `community-script` or `proxmox-helper-scripts` tags are listed for update.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Optionally performs a vzdump backup before updating containers.",
|
||||||
|
"type": "warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "If required, the script will temporarily increase container CPU/RAM resources for the build process and restore them after completion.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "At the end of the update, containers requiring a reboot will be listed, and you may choose to reboot them directly.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Use `var_backup=yes|no` to enable/disable backup (skip prompt).",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Use `var_backup_storage=<name>` to set backup storage location.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Use `var_container=all|all_running|all_stopped|101,102,...` to select containers.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Use `var_unattended=yes|no` to run updates without interaction.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Use `var_skip_confirm=yes` to skip initial confirmation dialog.",
|
||||||
|
"type": "info"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "Use `var_auto_reboot=yes|no` to auto-reboot containers after update.",
|
||||||
|
"type": "info"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -23,34 +23,6 @@ import { Button } from "./ui/button";
|
|||||||
import { Badge } from "./ui/badge";
|
import { Badge } from "./ui/badge";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
function search(scripts: Script[], query: string): Script[] {
|
|
||||||
const queryLower = query.toLowerCase().trim();
|
|
||||||
const searchWords = queryLower.split(/\s+/).filter(Boolean);
|
|
||||||
|
|
||||||
return scripts
|
|
||||||
.map(script => {
|
|
||||||
const nameLower = script.name.toLowerCase();
|
|
||||||
const descriptionLower = (script.description || "").toLowerCase();
|
|
||||||
|
|
||||||
let score = 0;
|
|
||||||
|
|
||||||
for (const word of searchWords) {
|
|
||||||
if (nameLower.includes(word)) {
|
|
||||||
score += 10;
|
|
||||||
}
|
|
||||||
if (descriptionLower.includes(word)) {
|
|
||||||
score += 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { script, score };
|
|
||||||
})
|
|
||||||
.filter(({ score }) => score > 0)
|
|
||||||
.sort((a, b) => b.score - a.score)
|
|
||||||
.slice(0, 20)
|
|
||||||
.map(({ script }) => script);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function formattedBadge(type: string) {
|
export function formattedBadge(type: string) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "vm":
|
case "vm":
|
||||||
@@ -79,11 +51,9 @@ function getRandomScript(categories: Category[], previouslySelected: Set<string>
|
|||||||
}
|
}
|
||||||
|
|
||||||
function CommandMenu() {
|
function CommandMenu() {
|
||||||
const [query, setQuery] = React.useState("");
|
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const [links, setLinks] = React.useState<Category[]>([]);
|
const [links, setLinks] = React.useState<Category[]>([]);
|
||||||
const [isLoading, setIsLoading] = React.useState(false);
|
const [isLoading, setIsLoading] = React.useState(false);
|
||||||
const [results, setResults] = React.useState<Script[]>([]);
|
|
||||||
const [selectedScripts, setSelectedScripts] = React.useState<Set<string>>(new Set());
|
const [selectedScripts, setSelectedScripts] = React.useState<Set<string>>(new Set());
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -100,27 +70,6 @@ function CommandMenu() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (query.trim() === "") {
|
|
||||||
fetchSortedCategories();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const scriptMap = new Map<string, Script>();
|
|
||||||
|
|
||||||
for (const category of links) {
|
|
||||||
for (const script of category.scripts || []) {
|
|
||||||
if (!scriptMap.has(script.slug)) {
|
|
||||||
scriptMap.set(script.slug, script);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const uniqueScripts = Array.from(scriptMap.values());
|
|
||||||
const filteredResults = search(uniqueScripts, query);
|
|
||||||
setResults(filteredResults);
|
|
||||||
}
|
|
||||||
}, [query]);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const handleKeyDown = (e: KeyboardEvent) => {
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
||||||
@@ -248,20 +197,20 @@ function CommandMenu() {
|
|||||||
|
|
||||||
<CommandDialog
|
<CommandDialog
|
||||||
open={open}
|
open={open}
|
||||||
onOpenChange={(open) => {
|
onOpenChange={setOpen}
|
||||||
setOpen(open);
|
filter={(value: string, search: string) => {
|
||||||
if (open) {
|
const searchLower = search.toLowerCase().trim();
|
||||||
setQuery("");
|
if (!searchLower)
|
||||||
setResults([]);
|
return 1;
|
||||||
}
|
const valueLower = value.toLowerCase();
|
||||||
|
const searchWords = searchLower.split(/\s+/).filter(Boolean);
|
||||||
|
// All search words must appear somewhere in the value (name + description)
|
||||||
|
const allWordsMatch = searchWords.every((word: string) => valueLower.includes(word));
|
||||||
|
return allWordsMatch ? 1 : 0;
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DialogTitle className="sr-only">Search scripts</DialogTitle>
|
<DialogTitle className="sr-only">Search scripts</DialogTitle>
|
||||||
<CommandInput
|
<CommandInput placeholder="Search for a script..." />
|
||||||
placeholder="Search for a script..."
|
|
||||||
onValueChange={setQuery}
|
|
||||||
value={query}
|
|
||||||
/>
|
|
||||||
<CommandList>
|
<CommandList>
|
||||||
<CommandEmpty>
|
<CommandEmpty>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
@@ -284,10 +233,9 @@ function CommandMenu() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</CommandEmpty>
|
</CommandEmpty>
|
||||||
|
{Object.entries(uniqueScriptsByCategory).map(([categoryName, scripts]) => (
|
||||||
{results.length > 0 ? (
|
<CommandGroup key={`category:${categoryName}`} heading={categoryName}>
|
||||||
<CommandGroup heading="Search Results">
|
{scripts.map(script => (
|
||||||
{results.map(script => (
|
|
||||||
<CommandItem
|
<CommandItem
|
||||||
key={`script:${script.slug}`}
|
key={`script:${script.slug}`}
|
||||||
value={`${script.name} ${script.type} ${script.description || ""}`}
|
value={`${script.name} ${script.type} ${script.description || ""}`}
|
||||||
@@ -320,44 +268,7 @@ function CommandMenu() {
|
|||||||
</CommandItem>
|
</CommandItem>
|
||||||
))}
|
))}
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
) : ( // When no search results, show all scripts grouped by category
|
))}
|
||||||
Object.entries(uniqueScriptsByCategory).map(([categoryName, scripts]) => (
|
|
||||||
<CommandGroup key={`category:${categoryName}`} heading={categoryName}>
|
|
||||||
{scripts.map(script => (
|
|
||||||
<CommandItem
|
|
||||||
key={`script:${script.slug}`}
|
|
||||||
value={`${script.name} ${script.type} ${script.description || ""}`}
|
|
||||||
onSelect={() => {
|
|
||||||
setOpen(false);
|
|
||||||
router.push(`/scripts?id=${script.slug}`);
|
|
||||||
}}
|
|
||||||
tabIndex={0}
|
|
||||||
aria-label={`Open script ${script.name}`}
|
|
||||||
onKeyDown={(e) => {
|
|
||||||
if (e.key === "Enter" || e.key === " ") {
|
|
||||||
setOpen(false);
|
|
||||||
router.push(`/scripts?id=${script.slug}`);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="flex gap-2" onClick={() => setOpen(false)}>
|
|
||||||
<Image
|
|
||||||
src={script.logo || `/${basePath}/logo.png`}
|
|
||||||
onError={e => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
|
|
||||||
unoptimized
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
alt=""
|
|
||||||
className="h-5 w-5"
|
|
||||||
/>
|
|
||||||
<span>{script.name}</span>
|
|
||||||
<span>{formattedBadge(script.type)}</span>
|
|
||||||
</div>
|
|
||||||
</CommandItem>
|
|
||||||
))}
|
|
||||||
</CommandGroup>
|
|
||||||
))
|
|
||||||
)}
|
|
||||||
</CommandList>
|
</CommandList>
|
||||||
</CommandDialog>
|
</CommandDialog>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -13,44 +13,44 @@ setting_up_container
|
|||||||
network_check
|
network_check
|
||||||
update_os
|
update_os
|
||||||
|
|
||||||
if [ -d /dev/dri ]; then
|
echo ""
|
||||||
echo ""
|
echo ""
|
||||||
echo ""
|
echo -e "🤖 ${BL}Immich Machine Learning Options${CL}"
|
||||||
echo -e "🤖 ${BL}Immich Machine Learning Options${CL}"
|
echo "─────────────────────────────────────────"
|
||||||
echo "─────────────────────────────────────────"
|
echo "Please choose your machine-learning type:"
|
||||||
echo "Please choose your machine-learning type:"
|
echo ""
|
||||||
echo ""
|
echo " 1) CPU only (default)"
|
||||||
echo " 1) CPU only (default)"
|
echo " 2) Intel OpenVINO (requires GPU passthrough)"
|
||||||
echo " 2) Intel OpenVINO (requires GPU passthrough)"
|
echo ""
|
||||||
echo ""
|
|
||||||
|
|
||||||
read -r -p "${TAB3}Select machine-learning type [1]: " ML_TYPE
|
read -r -p "${TAB3}Select machine-learning type [1]: " ML_TYPE
|
||||||
ML_TYPE="${ML_TYPE:-1}"
|
ML_TYPE="${ML_TYPE:-1}"
|
||||||
if [[ "$ML_TYPE" == "2" ]]; then
|
if [[ "$ML_TYPE" == "2" ]]; then
|
||||||
msg_info "Installing OpenVINO dependencies"
|
msg_info "Installing OpenVINO dependencies"
|
||||||
touch ~/.openvino
|
touch ~/.openvino
|
||||||
$STD apt install -y --no-install-recommends patchelf
|
$STD apt install -y --no-install-recommends patchelf
|
||||||
tmp_dir=$(mktemp -d)
|
tmp_dir=$(mktemp -d)
|
||||||
$STD pushd "$tmp_dir"
|
$STD pushd "$tmp_dir"
|
||||||
curl -fsSLO https://raw.githubusercontent.com/immich-app/base-images/refs/heads/main/server/Dockerfile
|
curl -fsSLO https://raw.githubusercontent.com/immich-app/base-images/refs/heads/main/server/Dockerfile
|
||||||
readarray -t INTEL_URLS < <(
|
readarray -t INTEL_URLS < <(
|
||||||
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $2}'
|
sed -n "/intel-[igc|opencl]/p" ./Dockerfile | awk '{print $2}'
|
||||||
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
|
sed -n "/libigdgmm12/p" ./Dockerfile | awk '{print $3}'
|
||||||
)
|
)
|
||||||
for url in "${INTEL_URLS[@]}"; do
|
for url in "${INTEL_URLS[@]}"; do
|
||||||
curl -fsSLO "$url"
|
curl -fsSLO "$url"
|
||||||
done
|
done
|
||||||
$STD apt install -y ./libigdgmm12*.deb
|
$STD apt install -y ./libigdgmm12*.deb
|
||||||
rm ./libigdgmm12*.deb
|
rm ./libigdgmm12*.deb
|
||||||
$STD apt install -y ./*.deb
|
$STD apt install -y ./*.deb
|
||||||
$STD apt-mark hold libigdgmm12
|
$STD apt-mark hold libigdgmm12
|
||||||
$STD popd
|
$STD popd
|
||||||
rm -rf "$tmp_dir"
|
rm -rf "$tmp_dir"
|
||||||
dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version
|
dpkg-query -W -f='${Version}\n' intel-opencl-icd >~/.intel_version
|
||||||
msg_ok "Installed OpenVINO dependencies"
|
msg_ok "Installed OpenVINO dependencies"
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
setup_uv
|
||||||
|
|
||||||
msg_info "Installing dependencies"
|
msg_info "Installing dependencies"
|
||||||
$STD apt install --no-install-recommends -y \
|
$STD apt install --no-install-recommends -y \
|
||||||
git \
|
git \
|
||||||
@@ -144,7 +144,8 @@ msg_info "Installing packages from Debian Testing repo"
|
|||||||
$STD apt install -t testing --no-install-recommends -yqq libmimalloc3 libde265-dev
|
$STD apt install -t testing --no-install-recommends -yqq libmimalloc3 libde265-dev
|
||||||
msg_ok "Installed packages from Debian Testing repo"
|
msg_ok "Installed packages from Debian Testing repo"
|
||||||
|
|
||||||
setup_uv
|
PNPM_VERSION="$(curl -fsSL "https://raw.githubusercontent.com/immich-app/immich/refs/heads/main/package.json" | jq -r '.packageManager | split("@")[1]')"
|
||||||
|
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
|
||||||
PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
|
PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
|
||||||
|
|
||||||
VCHORD_RELEASE="0.5.3"
|
VCHORD_RELEASE="0.5.3"
|
||||||
@@ -289,9 +290,7 @@ ML_DIR="${APP_DIR}/machine-learning"
|
|||||||
GEO_DIR="${INSTALL_DIR}/geodata"
|
GEO_DIR="${INSTALL_DIR}/geodata"
|
||||||
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
|
mkdir -p {"${APP_DIR}","${UPLOAD_DIR}","${GEO_DIR}","${INSTALL_DIR}"/cache}
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v2.5.3" "$SRC_DIR"
|
fetch_and_deploy_gh_release "immich" "immich-app/immich" "tarball" "v2.5.2" "$SRC_DIR"
|
||||||
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1]' ${SRC_DIR}/package.json)"
|
|
||||||
NODE_VERSION="24" NODE_MODULE="pnpm@${PNPM_VERSION}" setup_nodejs
|
|
||||||
|
|
||||||
msg_info "Installing Immich (patience)"
|
msg_info "Installing Immich (patience)"
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ msg_ok "Installed Dependencies"
|
|||||||
PG_VERSION=17 setup_postgresql
|
PG_VERSION=17 setup_postgresql
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
PG_DB_NAME="scanopy_db" PG_DB_USER="scanopy" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
PG_DB_NAME="scanopy_db" PG_DB_USER="scanopy" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
||||||
fetch_and_deploy_gh_release "Scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
fetch_and_deploy_gh_release "scanopy" "scanopy/scanopy" "tarball" "latest" "/opt/scanopy"
|
||||||
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
|
TOOLCHAIN="$(grep "channel" /opt/scanopy/backend/rust-toolchain.toml | awk -F\" '{print $2}')"
|
||||||
RUST_TOOLCHAIN=$TOOLCHAIN setup_rust
|
RUST_TOOLCHAIN=$TOOLCHAIN setup_rust
|
||||||
|
|
||||||
@@ -35,11 +35,11 @@ $STD npm ci --no-fund --no-audit
|
|||||||
$STD npm run build
|
$STD npm run build
|
||||||
msg_ok "Created frontend UI"
|
msg_ok "Created frontend UI"
|
||||||
|
|
||||||
msg_info "Building Scanopy Server (patience)"
|
msg_info "Building scanopy-server (patience)"
|
||||||
cd /opt/scanopy/backend
|
cd /opt/scanopy/backend
|
||||||
$STD cargo build --release --bin server
|
$STD cargo build --release --bin server
|
||||||
mv ./target/release/server /usr/bin/scanopy-server
|
mv ./target/release/server /usr/bin/scanopy-server
|
||||||
msg_ok "Built Scanopy Server"
|
msg_ok "Built scanopy-server"
|
||||||
|
|
||||||
msg_info "Configuring server for first-run"
|
msg_info "Configuring server for first-run"
|
||||||
cat <<EOF >/opt/scanopy/.env
|
cat <<EOF >/opt/scanopy/.env
|
||||||
|
|||||||
@@ -14,32 +14,24 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y coreutils
|
$STD apt install -y \
|
||||||
|
coreutils
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
msg_info "Setting up SQL Server 2022 Repository"
|
msg_info "Setup SQL Server 2022"
|
||||||
setup_deb822_repo \
|
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc >/dev/null
|
||||||
"mssql-server-2022" \
|
curl -fsSL https://packages.microsoft.com/config/ubuntu/22.04/mssql-server-2022.list | tee /etc/apt/sources.list.d/mssql-server-2022.list >/dev/null
|
||||||
"https://packages.microsoft.com/keys/microsoft.asc" \
|
$STD apt-get update -y
|
||||||
"https://packages.microsoft.com/ubuntu/22.04/mssql-server-2022" \
|
$STD apt-get install -y mssql-server
|
||||||
"./" \
|
msg_ok "Setup Server 2022"
|
||||||
""
|
|
||||||
msg_ok "Repository configured"
|
|
||||||
|
|
||||||
msg_info "Installing SQL Server 2022"
|
|
||||||
$STD apt install -y mssql-server
|
|
||||||
msg_ok "Installed SQL Server 2022"
|
|
||||||
|
|
||||||
msg_info "Installing SQL Server Tools"
|
msg_info "Installing SQL Server Tools"
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
export ACCEPT_EULA=Y
|
export ACCEPT_EULA=Y
|
||||||
setup_deb822_repo \
|
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | tee /etc/apt/trusted.gpg.d/microsoft.asc >/dev/null
|
||||||
"mssql-release" \
|
curl -fsSL https://packages.microsoft.com/config/ubuntu/22.04/prod.list | tee /etc/apt/sources.list.d/mssql-release.list >/dev/null
|
||||||
"https://packages.microsoft.com/keys/microsoft.asc" \
|
$STD apt-get update
|
||||||
"https://packages.microsoft.com/ubuntu/22.04/prod" \
|
$STD apt-get install -y -qq \
|
||||||
"jammy" \
|
|
||||||
"main"
|
|
||||||
$STD apt-get install -y \
|
|
||||||
mssql-tools18 \
|
mssql-tools18 \
|
||||||
unixodbc-dev
|
unixodbc-dev
|
||||||
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >>~/.bash_profile
|
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >>~/.bash_profile
|
||||||
@@ -57,11 +49,6 @@ msg_info "Start Service"
|
|||||||
systemctl enable -q --now mssql-server
|
systemctl enable -q --now mssql-server
|
||||||
msg_ok "Service started"
|
msg_ok "Service started"
|
||||||
|
|
||||||
msg_info "Cleaning up"
|
|
||||||
rm -f /etc/profile.d/debuginfod.sh
|
|
||||||
rm -f /etc/profile.d/debuginfod.csh
|
|
||||||
msg_ok "Cleaned up"
|
|
||||||
|
|
||||||
motd_ssh
|
motd_ssh
|
||||||
customize
|
customize
|
||||||
cleanup_lxc
|
cleanup_lxc
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
#!/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://www.microsoft.com/en-us/sql-server/sql-server-2025
|
|
||||||
|
|
||||||
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 coreutils
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
msg_info "Setting up SQL Server 2025 Repository"
|
|
||||||
setup_deb822_repo \
|
|
||||||
"mssql-server-2025" \
|
|
||||||
"https://packages.microsoft.com/keys/microsoft.asc" \
|
|
||||||
"https://packages.microsoft.com/ubuntu/24.04/mssql-server-2025" \
|
|
||||||
"./" \
|
|
||||||
""
|
|
||||||
msg_ok "Repository configured"
|
|
||||||
|
|
||||||
msg_info "Installing SQL Server 2025"
|
|
||||||
$STD apt install -y mssql-server
|
|
||||||
msg_ok "Installed SQL Server 2025"
|
|
||||||
|
|
||||||
msg_info "Installing SQL Server Tools"
|
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
|
||||||
export ACCEPT_EULA=Y
|
|
||||||
setup_deb822_repo \
|
|
||||||
"mssql-release" \
|
|
||||||
"https://packages.microsoft.com/keys/microsoft.asc" \
|
|
||||||
"https://packages.microsoft.com/ubuntu/24.04/prod" \
|
|
||||||
"noble" \
|
|
||||||
"main"
|
|
||||||
$STD apt-get install -y \
|
|
||||||
mssql-tools18 \
|
|
||||||
unixodbc-dev
|
|
||||||
echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >>~/.bash_profile
|
|
||||||
source ~/.bash_profile
|
|
||||||
msg_ok "Installed SQL Server Tools"
|
|
||||||
|
|
||||||
read -r -p "${TAB3}Do you want to run the SQL Server setup now? (Later is also possible) <y/N>" prompt
|
|
||||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
/opt/mssql/bin/mssql-conf setup
|
|
||||||
else
|
|
||||||
msg_ok "Skipping SQL Server setup. You can run it later with '/opt/mssql/bin/mssql-conf setup'."
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Starting SQL Server Service"
|
|
||||||
systemctl enable -q --now mssql-server
|
|
||||||
msg_ok "Service started"
|
|
||||||
|
|
||||||
msg_info "Cleaning up"
|
|
||||||
rm -f /etc/profile.d/debuginfod.sh /etc/profile.d/debuginfod.csh
|
|
||||||
msg_ok "Cleaned up"
|
|
||||||
|
|
||||||
motd_ssh
|
|
||||||
customize
|
|
||||||
cleanup_lxc
|
|
||||||
@@ -28,210 +28,13 @@
|
|||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# These can be overridden before sourcing this library
|
# These can be overridden before sourcing this library
|
||||||
|
|
||||||
# Disable 'unbound variable' errors for this library (restored at end)
|
|
||||||
_OLD_SET_STATE=$(set +o | grep -E 'set -(e|u|o)')
|
|
||||||
set +u
|
|
||||||
|
|
||||||
CLOUDINIT_DEFAULT_USER="${CLOUDINIT_DEFAULT_USER:-root}"
|
CLOUDINIT_DEFAULT_USER="${CLOUDINIT_DEFAULT_USER:-root}"
|
||||||
CLOUDINIT_DNS_SERVERS="${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}"
|
CLOUDINIT_DNS_SERVERS="${CLOUDINIT_DNS_SERVERS:-1.1.1.1 8.8.8.8}"
|
||||||
CLOUDINIT_SEARCH_DOMAIN="${CLOUDINIT_SEARCH_DOMAIN:-local}"
|
CLOUDINIT_SEARCH_DOMAIN="${CLOUDINIT_SEARCH_DOMAIN:-local}"
|
||||||
CLOUDINIT_SSH_KEYS="${CLOUDINIT_SSH_KEYS:-}" # Empty by default - user must explicitly provide keys
|
CLOUDINIT_SSH_KEYS="${CLOUDINIT_SSH_KEYS:-/root/.ssh/authorized_keys}"
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 2: SSH KEY DISCOVERY AND SELECTION
|
# SECTION 2: HELPER FUNCTIONS
|
||||||
# ==============================================================================
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# _ci_ssh_extract_keys_from_file - Extracts valid SSH public keys from a file
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
function _ci_ssh_extract_keys_from_file() {
|
|
||||||
local file="$1"
|
|
||||||
[[ -f "$file" && -r "$file" ]] || return 0
|
|
||||||
grep -E '^(ssh-(rsa|ed25519|dss|ecdsa)|ecdsa-sha2-)' "$file" 2>/dev/null || true
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# _ci_ssh_discover_files - Scans standard paths for SSH keys
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
function _ci_ssh_discover_files() {
|
|
||||||
local -a cand=()
|
|
||||||
shopt -s nullglob
|
|
||||||
cand+=(/root/.ssh/authorized_keys /root/.ssh/authorized_keys2)
|
|
||||||
cand+=(/root/.ssh/*.pub)
|
|
||||||
cand+=(/etc/ssh/authorized_keys /etc/ssh/authorized_keys.d/*)
|
|
||||||
shopt -u nullglob
|
|
||||||
printf '%s\0' "${cand[@]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# _ci_ssh_build_choices - Builds whiptail checklist from SSH key files
|
|
||||||
#
|
|
||||||
# Sets: CI_SSH_CHOICES (array), CI_SSH_COUNT (int), CI_SSH_MAPFILE (path)
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
function _ci_ssh_build_choices() {
|
|
||||||
local -a files=("$@")
|
|
||||||
CI_SSH_CHOICES=()
|
|
||||||
CI_SSH_COUNT=0
|
|
||||||
CI_SSH_MAPFILE="$(mktemp)"
|
|
||||||
local id key typ fp cmt base
|
|
||||||
|
|
||||||
for f in "${files[@]}"; do
|
|
||||||
[[ -f "$f" && -r "$f" ]] || continue
|
|
||||||
base="$(basename -- "$f")"
|
|
||||||
# Skip known_hosts and private keys
|
|
||||||
case "$base" in
|
|
||||||
known_hosts | known_hosts.* | config) continue ;;
|
|
||||||
id_*) [[ "$f" != *.pub ]] && continue ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
while IFS= read -r key; do
|
|
||||||
[[ -n "$key" ]] || continue
|
|
||||||
|
|
||||||
typ=""
|
|
||||||
fp=""
|
|
||||||
cmt=""
|
|
||||||
read -r _typ _b64 _cmt <<<"$key"
|
|
||||||
typ="${_typ:-key}"
|
|
||||||
cmt="${_cmt:-}"
|
|
||||||
|
|
||||||
# Get fingerprint via ssh-keygen if available
|
|
||||||
if command -v ssh-keygen >/dev/null 2>&1; then
|
|
||||||
fp="$(printf '%s\n' "$key" | ssh-keygen -lf - 2>/dev/null | awk '{print $2}')"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Shorten long comments
|
|
||||||
[[ ${#cmt} -gt 40 ]] && cmt="${cmt:0:37}..."
|
|
||||||
|
|
||||||
CI_SSH_COUNT=$((CI_SSH_COUNT + 1))
|
|
||||||
id="K${CI_SSH_COUNT}"
|
|
||||||
echo "${id}|${key}" >>"$CI_SSH_MAPFILE"
|
|
||||||
CI_SSH_CHOICES+=("$id" "[$typ] ${fp:+$fp }${cmt:+$cmt }— ${base}" "OFF")
|
|
||||||
done < <(_ci_ssh_extract_keys_from_file "$f")
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# configure_cloudinit_ssh_keys - Interactive SSH key selection for Cloud-Init
|
|
||||||
#
|
|
||||||
# Usage: configure_cloudinit_ssh_keys
|
|
||||||
# Sets: CLOUDINIT_SSH_KEYS (path to temporary file with selected keys)
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
function configure_cloudinit_ssh_keys() {
|
|
||||||
local backtitle="Proxmox VE Helper Scripts"
|
|
||||||
local ssh_key_mode
|
|
||||||
|
|
||||||
# Create temp file for selected keys
|
|
||||||
CLOUDINIT_SSH_KEYS_TEMP="$(mktemp)"
|
|
||||||
: >"$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
|
|
||||||
# Discover keys and build choices
|
|
||||||
IFS=$'\0' read -r -d '' -a _def_files < <(_ci_ssh_discover_files && printf '\0')
|
|
||||||
_ci_ssh_build_choices "${_def_files[@]}"
|
|
||||||
local default_key_count="$CI_SSH_COUNT"
|
|
||||||
|
|
||||||
if [[ "$default_key_count" -gt 0 ]]; then
|
|
||||||
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
|
|
||||||
"Provision SSH keys for Cloud-Init VM:" 14 72 4 \
|
|
||||||
"found" "Select from detected keys (${default_key_count})" \
|
|
||||||
"manual" "Paste a single public key" \
|
|
||||||
"folder" "Scan another folder (path or glob)" \
|
|
||||||
"none" "No SSH keys (password auth only)" 3>&1 1>&2 2>&3) || return 1
|
|
||||||
else
|
|
||||||
ssh_key_mode=$(whiptail --backtitle "$backtitle" --title "SSH KEY SOURCE" --menu \
|
|
||||||
"No host keys detected. Choose:" 12 72 3 \
|
|
||||||
"manual" "Paste a single public key" \
|
|
||||||
"folder" "Scan another folder (path or glob)" \
|
|
||||||
"none" "No SSH keys (password auth only)" 3>&1 1>&2 2>&3) || return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$ssh_key_mode" in
|
|
||||||
found)
|
|
||||||
# Show checklist with individual keys
|
|
||||||
local selection
|
|
||||||
selection=$(whiptail --backtitle "$backtitle" --title "SELECT SSH KEYS" \
|
|
||||||
--checklist "Select one or more keys to import:" 20 140 10 "${CI_SSH_CHOICES[@]}" 3>&1 1>&2 2>&3) || return 1
|
|
||||||
|
|
||||||
for tag in $selection; do
|
|
||||||
tag="${tag%\"}"
|
|
||||||
tag="${tag#\"}"
|
|
||||||
local line
|
|
||||||
line=$(grep -E "^${tag}\|" "$CI_SSH_MAPFILE" | head -n1 | cut -d'|' -f2-)
|
|
||||||
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
done
|
|
||||||
local imported
|
|
||||||
imported=$(wc -l <"$CLOUDINIT_SSH_KEYS_TEMP")
|
|
||||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}${imported} key(s) selected${CL}"
|
|
||||||
;;
|
|
||||||
manual)
|
|
||||||
local pubkey
|
|
||||||
pubkey=$(whiptail --backtitle "$backtitle" --title "PASTE SSH PUBLIC KEY" \
|
|
||||||
--inputbox "Paste your SSH public key (ssh-rsa, ssh-ed25519, etc.):" 10 76 3>&1 1>&2 2>&3) || return 1
|
|
||||||
if [[ -n "$pubkey" ]]; then
|
|
||||||
echo "$pubkey" >"$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}1 key added manually${CL}"
|
|
||||||
else
|
|
||||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}none (empty input)${CL}"
|
|
||||||
CLOUDINIT_SSH_KEYS=""
|
|
||||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP" "$CI_SSH_MAPFILE" 2>/dev/null
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
folder)
|
|
||||||
local glob_path
|
|
||||||
glob_path=$(whiptail --backtitle "$backtitle" --title "SCAN FOLDER/GLOB" \
|
|
||||||
--inputbox "Enter a folder or glob to scan (e.g. /root/.ssh/*.pub):" 10 72 3>&1 1>&2 2>&3) || return 1
|
|
||||||
if [[ -n "$glob_path" ]]; then
|
|
||||||
shopt -s nullglob
|
|
||||||
local -a _scan_files=($glob_path)
|
|
||||||
shopt -u nullglob
|
|
||||||
if [[ "${#_scan_files[@]}" -gt 0 ]]; then
|
|
||||||
_ci_ssh_build_choices "${_scan_files[@]}"
|
|
||||||
if [[ "$CI_SSH_COUNT" -gt 0 ]]; then
|
|
||||||
local folder_selection
|
|
||||||
folder_selection=$(whiptail --backtitle "$backtitle" --title "SELECT FOLDER KEYS" \
|
|
||||||
--checklist "Select key(s) to import:" 20 140 10 "${CI_SSH_CHOICES[@]}" 3>&1 1>&2 2>&3) || return 1
|
|
||||||
for tag in $folder_selection; do
|
|
||||||
tag="${tag%\"}"
|
|
||||||
tag="${tag#\"}"
|
|
||||||
local line
|
|
||||||
line=$(grep -E "^${tag}\|" "$CI_SSH_MAPFILE" | head -n1 | cut -d'|' -f2-)
|
|
||||||
[[ -n "$line" ]] && printf '%s\n' "$line" >>"$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
done
|
|
||||||
local imported
|
|
||||||
imported=$(wc -l <"$CLOUDINIT_SSH_KEYS_TEMP")
|
|
||||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}${imported} key(s) from folder${CL}"
|
|
||||||
else
|
|
||||||
whiptail --backtitle "$backtitle" --msgbox "No keys found in: $glob_path" 8 60
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
whiptail --backtitle "$backtitle" --msgbox "Path/glob returned no files." 8 60
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
none | *)
|
|
||||||
echo -e "${ROOTSSH:- 🔑 }${BOLD}${DGN}SSH Keys: ${BGN}none (password auth only)${CL}"
|
|
||||||
CLOUDINIT_SSH_KEYS=""
|
|
||||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP" "$CI_SSH_MAPFILE" 2>/dev/null
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Cleanup mapfile
|
|
||||||
rm -f "$CI_SSH_MAPFILE" 2>/dev/null
|
|
||||||
|
|
||||||
# Set the variable for setup_cloud_init to use
|
|
||||||
if [[ -s "$CLOUDINIT_SSH_KEYS_TEMP" ]]; then
|
|
||||||
CLOUDINIT_SSH_KEYS="$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
else
|
|
||||||
CLOUDINIT_SSH_KEYS=""
|
|
||||||
rm -f "$CLOUDINIT_SSH_KEYS_TEMP"
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# SECTION 3: HELPER FUNCTIONS
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -341,10 +144,9 @@ function setup_cloud_init() {
|
|||||||
local cipassword=$(openssl rand -base64 16)
|
local cipassword=$(openssl rand -base64 16)
|
||||||
qm set "$vmid" --cipassword "$cipassword" >/dev/null
|
qm set "$vmid" --cipassword "$cipassword" >/dev/null
|
||||||
|
|
||||||
# Add SSH keys only if explicitly provided (not auto-imported from host)
|
# Add SSH keys if available
|
||||||
if [ -n "${CLOUDINIT_SSH_KEYS:-}" ] && [ -f "$CLOUDINIT_SSH_KEYS" ]; then
|
if [ -f "$CLOUDINIT_SSH_KEYS" ]; then
|
||||||
qm set "$vmid" --sshkeys "$CLOUDINIT_SSH_KEYS" >/dev/null 2>&1 || true
|
qm set "$vmid" --sshkeys "$CLOUDINIT_SSH_KEYS" >/dev/null 2>&1 || true
|
||||||
_ci_msg_info "SSH keys imported from: $CLOUDINIT_SSH_KEYS"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Configure network
|
# Configure network
|
||||||
@@ -657,11 +459,6 @@ export -f wait_for_cloud_init 2>/dev/null || true
|
|||||||
export -f validate_ip_cidr 2>/dev/null || true
|
export -f validate_ip_cidr 2>/dev/null || true
|
||||||
export -f validate_ip 2>/dev/null || true
|
export -f validate_ip 2>/dev/null || true
|
||||||
|
|
||||||
# Restore previous shell options if they were saved
|
|
||||||
if [ -n "${_OLD_SET_STATE:-}" ]; then
|
|
||||||
eval "$_OLD_SET_STATE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 7: EXAMPLES & DOCUMENTATION
|
# SECTION 7: EXAMPLES & DOCUMENTATION
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|||||||
@@ -1,264 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: vhsdream
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/alangrainger/immich-public-proxy
|
|
||||||
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
|
||||||
|
|
||||||
# Enable error handling
|
|
||||||
set -Eeuo pipefail
|
|
||||||
trap 'error_handler' ERR
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# CONFIGURATION
|
|
||||||
# ==============================================================================
|
|
||||||
APP="Immich Public Proxy"
|
|
||||||
APP_TYPE="addon"
|
|
||||||
INSTALL_PATH="/opt/immich-proxy"
|
|
||||||
CONFIG_PATH="/opt/immich-proxy/app"
|
|
||||||
DEFAULT_PORT=3000
|
|
||||||
|
|
||||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
|
||||||
load_functions
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# HEADER
|
|
||||||
# ==============================================================================
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
____ _ __ ____
|
|
||||||
/ _/___ ___ ____ ___ (_)____/ /_ / __ \_________ _ ____ __
|
|
||||||
/ // __ `__ \/ __ `__ \/ / ___/ __ \______/ /_/ / ___/ __ \| |/_/ / / /
|
|
||||||
_/ // / / / / / / / / / / / /__/ / / /_____/ ____/ / / /_/ /> </ /_/ /
|
|
||||||
/___/_/ /_/ /_/_/ /_/ /_/_/\___/_/ /_/ /_/ /_/ \____/_/|_|\__, /
|
|
||||||
/____/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# OS DETECTION
|
|
||||||
# ==============================================================================
|
|
||||||
if [[ -f "/etc/alpine-release" ]]; then
|
|
||||||
msg_error "Alpine is not supported for ${APP}. Use Debian."
|
|
||||||
exit 1
|
|
||||||
elif [[ -f "/etc/debian_version" ]]; then
|
|
||||||
OS="Debian"
|
|
||||||
SERVICE_PATH="/etc/systemd/system/immich-proxy.service"
|
|
||||||
else
|
|
||||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# UNINSTALL
|
|
||||||
# ==============================================================================
|
|
||||||
function uninstall() {
|
|
||||||
msg_info "Uninstalling ${APP}"
|
|
||||||
systemctl disable --now immich-proxy.service &>/dev/null || true
|
|
||||||
rm -f "$SERVICE_PATH"
|
|
||||||
rm -rf "$INSTALL_PATH"
|
|
||||||
rm -f "/usr/local/bin/update_immich-public-proxy"
|
|
||||||
rm -f "$HOME/.immichpublicproxy"
|
|
||||||
msg_ok "${APP} has been uninstalled"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# UPDATE
|
|
||||||
# ==============================================================================
|
|
||||||
function update() {
|
|
||||||
if check_for_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy"; then
|
|
||||||
msg_info "Stopping service"
|
|
||||||
systemctl stop immich-proxy.service &>/dev/null || true
|
|
||||||
msg_ok "Stopped service"
|
|
||||||
|
|
||||||
msg_info "Backing up configuration"
|
|
||||||
cp "$CONFIG_PATH"/.env /tmp/ipp.env.bak 2>/dev/null || true
|
|
||||||
cp "$CONFIG_PATH"/config.json /tmp/ipp.config.json.bak 2>/dev/null || true
|
|
||||||
msg_ok "Backed up configuration"
|
|
||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH"
|
|
||||||
|
|
||||||
msg_info "Restoring configuration"
|
|
||||||
cp /tmp/ipp.env.bak "$CONFIG_PATH"/.env 2>/dev/null || true
|
|
||||||
cp /tmp/ipp.config.json.bak "$CONFIG_PATH"/config.json 2>/dev/null || true
|
|
||||||
rm -f /tmp/ipp.*.bak
|
|
||||||
msg_ok "Restored configuration"
|
|
||||||
|
|
||||||
msg_info "Installing dependencies"
|
|
||||||
cd "$CONFIG_PATH"
|
|
||||||
$STD npm install
|
|
||||||
msg_ok "Installed dependencies"
|
|
||||||
|
|
||||||
msg_info "Building ${APP}"
|
|
||||||
$STD npm run build
|
|
||||||
msg_ok "Built ${APP}"
|
|
||||||
|
|
||||||
msg_info "Starting service"
|
|
||||||
systemctl start immich-proxy
|
|
||||||
msg_ok "Started service"
|
|
||||||
msg_ok "Updated successfully"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# INSTALL
|
|
||||||
# ==============================================================================
|
|
||||||
function install() {
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
|
||||||
|
|
||||||
# Force fresh download by removing version cache
|
|
||||||
rm -f "$HOME/.immichpublicproxy"
|
|
||||||
fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH"
|
|
||||||
|
|
||||||
msg_info "Installing dependencies"
|
|
||||||
cd "$CONFIG_PATH"
|
|
||||||
$STD npm install
|
|
||||||
msg_ok "Installed dependencies"
|
|
||||||
|
|
||||||
msg_info "Building ${APP}"
|
|
||||||
$STD npm run build
|
|
||||||
msg_ok "Built ${APP}"
|
|
||||||
|
|
||||||
MAX_ATTEMPTS=3
|
|
||||||
attempt=0
|
|
||||||
while true; do
|
|
||||||
attempt=$((attempt + 1))
|
|
||||||
read -rp "${TAB3}Enter your LOCAL Immich IP or domain (ex. 192.168.1.100 or immich.local.lan): " DOMAIN
|
|
||||||
if [[ -z "$DOMAIN" ]]; then
|
|
||||||
if ((attempt >= MAX_ATTEMPTS)); then
|
|
||||||
DOMAIN="${LOCAL_IP:-localhost}"
|
|
||||||
msg_warn "Using fallback: $DOMAIN"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
msg_warn "Domain cannot be empty! (Attempt $attempt/$MAX_ATTEMPTS)"
|
|
||||||
elif [[ "$DOMAIN" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
|
|
||||||
valid_ip=true
|
|
||||||
IFS='.' read -ra octets <<<"$DOMAIN"
|
|
||||||
for octet in "${octets[@]}"; do
|
|
||||||
if ((octet > 255)); then
|
|
||||||
valid_ip=false
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if $valid_ip; then
|
|
||||||
break
|
|
||||||
else
|
|
||||||
msg_warn "Invalid IP address!"
|
|
||||||
fi
|
|
||||||
elif [[ "$DOMAIN" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$ || "$DOMAIN" == "localhost" ]]; then
|
|
||||||
break
|
|
||||||
else
|
|
||||||
msg_warn "Invalid domain format!"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
msg_info "Creating configuration"
|
|
||||||
cat <<EOF >"$CONFIG_PATH"/.env
|
|
||||||
NODE_ENV=production
|
|
||||||
IMMICH_URL=http://${DOMAIN}:2283
|
|
||||||
EOF
|
|
||||||
chmod 600 "$CONFIG_PATH"/.env
|
|
||||||
msg_ok "Created configuration"
|
|
||||||
|
|
||||||
msg_info "Creating service"
|
|
||||||
cat <<EOF >"$SERVICE_PATH"
|
|
||||||
[Unit]
|
|
||||||
Description=Immich Public Proxy
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
User=root
|
|
||||||
WorkingDirectory=${INSTALL_PATH}
|
|
||||||
EnvironmentFile=${CONFIG_PATH}/.env
|
|
||||||
ExecStart=/usr/bin/node ${INSTALL_PATH}/app/server.js
|
|
||||||
Restart=always
|
|
||||||
RestartSec=10
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
systemctl enable -q --now immich-proxy
|
|
||||||
msg_ok "Created and started service"
|
|
||||||
|
|
||||||
# Create update script (simple wrapper that calls this addon with type=update)
|
|
||||||
msg_info "Creating update script"
|
|
||||||
cat <<'UPDATEEOF' >/usr/local/bin/update_immich-public-proxy
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
# Immich Public Proxy Update Script
|
|
||||||
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/immich-public-proxy.sh)"
|
|
||||||
UPDATEEOF
|
|
||||||
chmod +x /usr/local/bin/update_immich-public-proxy
|
|
||||||
msg_ok "Created update script (/usr/local/bin/update_immich-public-proxy)"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
msg_ok "${APP} is reachable at: ${BL}http://${LOCAL_IP}:${DEFAULT_PORT}${CL}"
|
|
||||||
echo ""
|
|
||||||
msg_warn "Additional configuration is available at '/opt/immich-proxy/app/config.json'"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# MAIN
|
|
||||||
# ==============================================================================
|
|
||||||
|
|
||||||
# Handle type=update (called from update script)
|
|
||||||
if [[ "${type:-}" == "update" ]]; then
|
|
||||||
header_info
|
|
||||||
if [[ -d "$INSTALL_PATH" && -f "$SERVICE_PATH" ]]; then
|
|
||||||
update
|
|
||||||
else
|
|
||||||
msg_error "${APP} is not installed. Nothing to update."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
header_info
|
|
||||||
get_lxc_ip
|
|
||||||
|
|
||||||
# Check if already installed
|
|
||||||
if [[ -d "$INSTALL_PATH" && -f "$SERVICE_PATH" ]]; then
|
|
||||||
msg_warn "${APP} is already installed."
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo -n "${TAB}Uninstall ${APP}? (y/N): "
|
|
||||||
read -r uninstall_prompt
|
|
||||||
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
uninstall
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -n "${TAB}Update ${APP}? (y/N): "
|
|
||||||
read -r update_prompt
|
|
||||||
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
update
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_warn "No action selected. Exiting."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fresh installation
|
|
||||||
msg_warn "${APP} is not installed."
|
|
||||||
echo ""
|
|
||||||
echo -e "${TAB}${INFO} This will install:"
|
|
||||||
echo -e "${TAB} - Node.js 24"
|
|
||||||
echo -e "${TAB} - Immich Public Proxy"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo -n "${TAB}Install ${APP}? (y/N): "
|
|
||||||
read -r install_prompt
|
|
||||||
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
install
|
|
||||||
else
|
|
||||||
msg_warn "Installation cancelled. Exiting."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
____ _ __ ____ __ ___ ____
|
|
||||||
/ _/___ ___ ____ ___ (_)____/ /_ / __ \__ __/ /_ / (_)____ / __ \_________ _ ____ __
|
|
||||||
/ // __ `__ \/ __ `__ \/ / ___/ __ \ / /_/ / / / / __ \/ / / ___/ / /_/ / ___/ __ \| |/_/ / / /
|
|
||||||
_/ // / / / / / / / / / / / /__/ / / / / ____/ /_/ / /_/ / / / /__ / ____/ / / /_/ /> </ /_/ /
|
|
||||||
/___/_/ /_/ /_/_/ /_/ /_/_/\___/_/ /_/ /_/ \__,_/_.___/_/_/\___/ /_/ /_/ \____/_/|_|\__, /
|
|
||||||
/____/
|
|
||||||
465
tools/pve/update-apps.sh
Normal file
465
tools/pve/update-apps.sh
Normal file
@@ -0,0 +1,465 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: BvdBerg01 | Co-Author: remz1337
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/refs/heads/main/misc/core.func)
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# CONFIGURATION VARIABLES
|
||||||
|
# Set these variables to skip interactive prompts (Whiptail dialogs)
|
||||||
|
# =============================================================================
|
||||||
|
# var_backup: Enable/disable backup before update
|
||||||
|
# Options: "yes" | "no" | "" (empty = interactive prompt)
|
||||||
|
var_backup="${var_backup:-}"
|
||||||
|
|
||||||
|
# var_backup_storage: Storage location for backups (only used if var_backup=yes)
|
||||||
|
# Options: Storage name from /etc/pve/storage.cfg (e.g., "local", "nas-backup")
|
||||||
|
# Leave empty for interactive selection
|
||||||
|
var_backup_storage="${var_backup_storage:-}"
|
||||||
|
|
||||||
|
# var_container: Which containers to update
|
||||||
|
# Options:
|
||||||
|
# - "all" : All containers with community-scripts tags
|
||||||
|
# - "all_running" : Only running containers with community-scripts tags
|
||||||
|
# - "all_stopped" : Only stopped containers with community-scripts tags
|
||||||
|
# - "101,102,109" : Comma-separated list of specific container IDs
|
||||||
|
# - "" : Interactive selection via Whiptail
|
||||||
|
var_container="${var_container:-}"
|
||||||
|
|
||||||
|
# var_unattended: Run updates without user interaction inside containers
|
||||||
|
# Options: "yes" | "no" | "" (empty = interactive prompt)
|
||||||
|
var_unattended="${var_unattended:-}"
|
||||||
|
|
||||||
|
# var_skip_confirm: Skip initial confirmation dialog
|
||||||
|
# Options: "yes" | "no" (default: no)
|
||||||
|
var_skip_confirm="${var_skip_confirm:-no}"
|
||||||
|
|
||||||
|
# var_auto_reboot: Automatically reboot containers that require it after update
|
||||||
|
# Options: "yes" | "no" | "" (empty = interactive prompt)
|
||||||
|
var_auto_reboot="${var_auto_reboot:-}"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# JSON CONFIG EXPORT
|
||||||
|
# Run with --export-config to output current configuration as JSON
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
function export_config_json() {
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
"var_backup": "${var_backup}",
|
||||||
|
"var_backup_storage": "${var_backup_storage}",
|
||||||
|
"var_container": "${var_container}",
|
||||||
|
"var_unattended": "${var_unattended}",
|
||||||
|
"var_skip_confirm": "${var_skip_confirm}",
|
||||||
|
"var_auto_reboot": "${var_auto_reboot}"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
function print_usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $(basename "$0") [OPTIONS]
|
||||||
|
|
||||||
|
Update LXC containers created with community-scripts.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help Show this help message
|
||||||
|
--export-config Export current configuration as JSON
|
||||||
|
|
||||||
|
Environment Variables:
|
||||||
|
var_backup Enable backup before update (yes/no)
|
||||||
|
var_backup_storage Storage location for backups
|
||||||
|
var_container Container selection (all/all_running/all_stopped/101,102,...)
|
||||||
|
var_unattended Run updates unattended (yes/no)
|
||||||
|
var_skip_confirm Skip initial confirmation (yes/no)
|
||||||
|
var_auto_reboot Auto-reboot containers if required (yes/no)
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
# Run interactively
|
||||||
|
$(basename "$0")
|
||||||
|
|
||||||
|
# Update all running containers unattended with backup
|
||||||
|
var_backup=yes var_backup_storage=local var_container=all_running var_unattended=yes var_skip_confirm=yes $(basename "$0")
|
||||||
|
|
||||||
|
# Update specific containers without backup
|
||||||
|
var_backup=no var_container=101,102,105 var_unattended=yes var_skip_confirm=yes $(basename "$0")
|
||||||
|
|
||||||
|
# Export current configuration
|
||||||
|
$(basename "$0") --export-config
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Handle command line arguments
|
||||||
|
case "${1:-}" in
|
||||||
|
--help|-h)
|
||||||
|
print_usage
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
--export-config)
|
||||||
|
export_config_json
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
function header_info {
|
||||||
|
clear
|
||||||
|
cat <<"EOF"
|
||||||
|
__ _ ________ __ __ __ __
|
||||||
|
/ / | |/ / ____/ / / / /___ ____/ /___ _/ /____
|
||||||
|
/ / | / / / / / / __ \/ __ / __ `/ __/ _ \
|
||||||
|
/ /___/ / /___ / /_/ / /_/ / /_/ / /_/ / /_/ __/
|
||||||
|
/_____/_/|_\____/ \____/ .___/\__,_/\__,_/\__/\___/
|
||||||
|
/_/
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
function detect_service() {
|
||||||
|
pushd $(mktemp -d) >/dev/null
|
||||||
|
pct pull "$1" /usr/bin/update update 2>/dev/null
|
||||||
|
service=$(cat update | sed 's|.*/ct/||g' | sed 's|\.sh).*||g')
|
||||||
|
popd >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
function backup_container() {
|
||||||
|
msg_info "Creating backup for container $1"
|
||||||
|
vzdump $1 --compress zstd --storage $STORAGE_CHOICE -notes-template "community-scripts backup updater" >/dev/null 2>&1
|
||||||
|
status=$?
|
||||||
|
|
||||||
|
if [ $status -eq 0 ]; then
|
||||||
|
msg_ok "Backup created"
|
||||||
|
else
|
||||||
|
msg_error "Backup failed for container $1"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_backup_storages() {
|
||||||
|
STORAGES=$(awk '
|
||||||
|
/^[a-z]+:/ {
|
||||||
|
if (name != "") {
|
||||||
|
if (has_backup || (!has_content && type == "dir")) print name
|
||||||
|
}
|
||||||
|
split($0, a, ":")
|
||||||
|
type = a[1]
|
||||||
|
name = a[2]
|
||||||
|
sub(/^ +/, "", name)
|
||||||
|
has_content = 0
|
||||||
|
has_backup = 0
|
||||||
|
}
|
||||||
|
/^ +content/ {
|
||||||
|
has_content = 1
|
||||||
|
if ($0 ~ /backup/) has_backup = 1
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
if (name != "") {
|
||||||
|
if (has_backup || (!has_content && type == "dir")) print name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' /etc/pve/storage.cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
header_info
|
||||||
|
|
||||||
|
# Skip confirmation if var_skip_confirm is set to yes
|
||||||
|
if [[ "$var_skip_confirm" != "yes" ]]; then
|
||||||
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC Container Update" --yesno "This will update LXC container. Proceed?" 10 58 || exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Loading all possible LXC containers from Proxmox VE. This may take a few seconds..."
|
||||||
|
NODE=$(hostname)
|
||||||
|
containers=$(pct list | tail -n +2 | awk '{print $0 " " $4}')
|
||||||
|
|
||||||
|
if [ -z "$containers" ]; then
|
||||||
|
whiptail --title "LXC Container Update" --msgbox "No LXC containers available!" 10 60
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
menu_items=()
|
||||||
|
FORMAT="%-10s %-15s %-10s"
|
||||||
|
TAGS="community-script|proxmox-helper-scripts"
|
||||||
|
|
||||||
|
while read -r container; do
|
||||||
|
container_id=$(echo $container | awk '{print $1}')
|
||||||
|
container_name=$(echo $container | awk '{print $2}')
|
||||||
|
container_status=$(echo $container | awk '{print $3}')
|
||||||
|
formatted_line=$(printf "$FORMAT" "$container_name" "$container_status")
|
||||||
|
if pct config "$container_id" | grep -qE "^tags:.*(${TAGS}).*"; then
|
||||||
|
menu_items+=("$container_id" "$formatted_line" "OFF")
|
||||||
|
fi
|
||||||
|
done <<<"$containers"
|
||||||
|
msg_ok "Loaded ${#menu_items[@]} containers"
|
||||||
|
|
||||||
|
# Determine container selection based on var_container
|
||||||
|
if [[ -n "$var_container" ]]; then
|
||||||
|
case "$var_container" in
|
||||||
|
all)
|
||||||
|
# Select all containers with matching tags
|
||||||
|
CHOICE=""
|
||||||
|
for ((i=0; i<${#menu_items[@]}; i+=3)); do
|
||||||
|
CHOICE="$CHOICE ${menu_items[$i]}"
|
||||||
|
done
|
||||||
|
CHOICE=$(echo "$CHOICE" | xargs)
|
||||||
|
;;
|
||||||
|
all_running)
|
||||||
|
# Select only running containers with matching tags
|
||||||
|
CHOICE=""
|
||||||
|
for ((i=0; i<${#menu_items[@]}; i+=3)); do
|
||||||
|
cid="${menu_items[$i]}"
|
||||||
|
if pct status "$cid" 2>/dev/null | grep -q "running"; then
|
||||||
|
CHOICE="$CHOICE $cid"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
CHOICE=$(echo "$CHOICE" | xargs)
|
||||||
|
;;
|
||||||
|
all_stopped)
|
||||||
|
# Select only stopped containers with matching tags
|
||||||
|
CHOICE=""
|
||||||
|
for ((i=0; i<${#menu_items[@]}; i+=3)); do
|
||||||
|
cid="${menu_items[$i]}"
|
||||||
|
if pct status "$cid" 2>/dev/null | grep -q "stopped"; then
|
||||||
|
CHOICE="$CHOICE $cid"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
CHOICE=$(echo "$CHOICE" | xargs)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Assume comma-separated list of container IDs
|
||||||
|
CHOICE=$(echo "$var_container" | tr ',' ' ')
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ -z "$CHOICE" ]]; then
|
||||||
|
msg_error "No containers matched the selection criteria: $var_container"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
msg_ok "Selected containers: $CHOICE"
|
||||||
|
else
|
||||||
|
CHOICE=$(whiptail --title "LXC Container Update" \
|
||||||
|
--checklist "Select LXC containers to update:" 25 60 13 \
|
||||||
|
"${menu_items[@]}" 3>&2 2>&1 1>&3 | tr -d '"')
|
||||||
|
|
||||||
|
if [ -z "$CHOICE" ]; then
|
||||||
|
whiptail --title "LXC Container Update" \
|
||||||
|
--msgbox "No containers selected!" 10 60
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
header_info
|
||||||
|
|
||||||
|
# Determine backup choice based on var_backup
|
||||||
|
if [[ -n "$var_backup" ]]; then
|
||||||
|
BACKUP_CHOICE="$var_backup"
|
||||||
|
else
|
||||||
|
BACKUP_CHOICE="no"
|
||||||
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC Container Update" --yesno "Do you want to backup your containers before update?" 10 58); then
|
||||||
|
BACKUP_CHOICE="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine unattended update based on var_unattended
|
||||||
|
if [[ -n "$var_unattended" ]]; then
|
||||||
|
UNATTENDED_UPDATE="$var_unattended"
|
||||||
|
else
|
||||||
|
UNATTENDED_UPDATE="no"
|
||||||
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "LXC Container Update" --yesno "Run updates unattended?" 10 58); then
|
||||||
|
UNATTENDED_UPDATE="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$BACKUP_CHOICE" == "yes" ]; then
|
||||||
|
get_backup_storages
|
||||||
|
|
||||||
|
if [ -z "$STORAGES" ]; then
|
||||||
|
msg_error "No storage with 'backup' support found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine storage based on var_backup_storage
|
||||||
|
if [[ -n "$var_backup_storage" ]]; then
|
||||||
|
# Validate that the specified storage exists and supports backups
|
||||||
|
if echo "$STORAGES" | grep -qw "$var_backup_storage"; then
|
||||||
|
STORAGE_CHOICE="$var_backup_storage"
|
||||||
|
msg_ok "Using backup storage: $STORAGE_CHOICE"
|
||||||
|
else
|
||||||
|
msg_error "Specified backup storage '$var_backup_storage' not found or doesn't support backups!"
|
||||||
|
msg_info "Available storages: $(echo $STORAGES | tr '\n' ' ')"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
MENU_ITEMS=()
|
||||||
|
for STORAGE in $STORAGES; do
|
||||||
|
MENU_ITEMS+=("$STORAGE" "")
|
||||||
|
done
|
||||||
|
|
||||||
|
STORAGE_CHOICE=$(whiptail --title "Select storage device" --menu "Select a storage device (Only storage devices with 'backup' support are listed):" 15 50 5 "${MENU_ITEMS[@]}" 3>&1 1>&2 2>&3)
|
||||||
|
|
||||||
|
if [ -z "$STORAGE_CHOICE" ]; then
|
||||||
|
msg_error "No storage selected!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
UPDATE_CMD="update;"
|
||||||
|
if [ "$UNATTENDED_UPDATE" == "yes" ]; then
|
||||||
|
UPDATE_CMD="export PHS_SILENT=1;update;"
|
||||||
|
fi
|
||||||
|
|
||||||
|
containers_needing_reboot=()
|
||||||
|
for container in $CHOICE; do
|
||||||
|
echo -e "${BL}[INFO]${CL} Updating container $container"
|
||||||
|
|
||||||
|
if [ "$BACKUP_CHOICE" == "yes" ]; then
|
||||||
|
backup_container $container
|
||||||
|
fi
|
||||||
|
|
||||||
|
os=$(pct config "$container" | awk '/^ostype/ {print $2}')
|
||||||
|
status=$(pct status $container)
|
||||||
|
template=$(pct config $container | grep -q "template:" && echo "true" || echo "false")
|
||||||
|
if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then
|
||||||
|
echo -e "${BL}[Info]${GN} Starting${BL} $container ${CL} \n"
|
||||||
|
pct start $container
|
||||||
|
echo -e "${BL}[Info]${GN} Waiting For${BL} $container${CL}${GN} To Start ${CL} \n"
|
||||||
|
sleep 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
#1) Detect service using the service name in the update command
|
||||||
|
detect_service $container
|
||||||
|
|
||||||
|
#1.1) If update script not detected, return
|
||||||
|
if [ -z "${service}" ]; then
|
||||||
|
echo -e "${YW}[WARN]${CL} Update script not found. Skipping to next container"
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
echo -e "${BL}[INFO]${CL} Detected service: ${GN}${service}${CL}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#2) Extract service build/update resource requirements from config/installation file
|
||||||
|
script=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/${service}.sh)
|
||||||
|
|
||||||
|
#2.1) Check if the script downloaded successfully
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo -e "${RD}[ERROR]${CL} Issue while downloading install script."
|
||||||
|
echo -e "${YW}[WARN]${CL} Unable to assess build resource requirements. Proceeding with current resources."
|
||||||
|
fi
|
||||||
|
|
||||||
|
config=$(pct config "$container")
|
||||||
|
build_cpu=$(echo "$script" | { grep -m 1 "var_cpu" || test $? = 1; } | sed 's|.*=||g' | sed 's|"||g' | sed 's|.*var_cpu:-||g' | sed 's|}||g')
|
||||||
|
build_ram=$(echo "$script" | { grep -m 1 "var_ram" || test $? = 1; } | sed 's|.*=||g' | sed 's|"||g' | sed 's|.*var_ram:-||g' | sed 's|}||g')
|
||||||
|
run_cpu=$(echo "$script" | { grep -m 1 "pct set \$CTID -cores" || test $? = 1; } | sed 's|.*cores ||g')
|
||||||
|
run_ram=$(echo "$script" | { grep -m 1 "pct set \$CTID -memory" || test $? = 1; } | sed 's|.*memory ||g')
|
||||||
|
current_cpu=$(echo "$config" | grep -m 1 "cores:" | sed 's|cores: ||g')
|
||||||
|
current_ram=$(echo "$config" | grep -m 1 "memory:" | sed 's|memory: ||g')
|
||||||
|
|
||||||
|
#Test if all values are valid (>0)
|
||||||
|
if [ -z "${run_cpu}" ] || [ "$run_cpu" -le 0 ]; then
|
||||||
|
#echo "No valid value found for run_cpu. Assuming same as current configuration."
|
||||||
|
run_cpu=$current_cpu
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${run_ram}" ] || [ "$run_ram" -le 0 ]; then
|
||||||
|
#echo "No valid value found for run_ram. Assuming same as current configuration."
|
||||||
|
run_ram=$current_ram
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${build_cpu}" ] || [ "$build_cpu" -le 0 ]; then
|
||||||
|
#echo "No valid value found for build_cpu. Assuming same as current configuration."
|
||||||
|
build_cpu=$current_cpu
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${build_ram}" ] || [ "$build_ram" -le 0 ]; then
|
||||||
|
#echo "No valid value found for build_ram. Assuming same as current configuration."
|
||||||
|
build_ram=$current_ram
|
||||||
|
fi
|
||||||
|
|
||||||
|
UPDATE_BUILD_RESOURCES=0
|
||||||
|
if [ "$build_cpu" -gt "$run_cpu" ] || [ "$build_ram" -gt "$run_ram" ]; then
|
||||||
|
UPDATE_BUILD_RESOURCES=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
#3) if build resources are different than run resources, then:
|
||||||
|
if [ "$UPDATE_BUILD_RESOURCES" -eq "1" ]; then
|
||||||
|
pct set "$container" --cores "$build_cpu" --memory "$build_ram"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#4) Update service, using the update command
|
||||||
|
case "$os" in
|
||||||
|
alpine) pct exec "$container" -- ash -c "$UPDATE_CMD" ;;
|
||||||
|
archlinux) pct exec "$container" -- bash -c "$UPDATE_CMD" ;;
|
||||||
|
fedora | rocky | centos | alma) pct exec "$container" -- bash -c "$UPDATE_CMD" ;;
|
||||||
|
ubuntu | debian | devuan) pct exec "$container" -- bash -c "$UPDATE_CMD" ;;
|
||||||
|
opensuse) pct exec "$container" -- bash -c "$UPDATE_CMD" ;;
|
||||||
|
esac
|
||||||
|
exit_code=$?
|
||||||
|
|
||||||
|
if [ "$template" == "false" ] && [ "$status" == "status: stopped" ]; then
|
||||||
|
echo -e "${BL}[Info]${GN} Shutting down${BL} $container ${CL} \n"
|
||||||
|
pct shutdown $container &
|
||||||
|
fi
|
||||||
|
|
||||||
|
#5) if build resources are different than run resources, then:
|
||||||
|
if [ "$UPDATE_BUILD_RESOURCES" -eq "1" ]; then
|
||||||
|
pct set "$container" --cores "$run_cpu" --memory "$run_ram"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if pct exec "$container" -- [ -e "/var/run/reboot-required" ]; then
|
||||||
|
# Get the container's hostname and add it to the list
|
||||||
|
container_hostname=$(pct exec "$container" hostname)
|
||||||
|
containers_needing_reboot+=("$container ($container_hostname)")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $exit_code -eq 0 ]; then
|
||||||
|
msg_ok "Updated container $container"
|
||||||
|
elif [ "$BACKUP_CHOICE" == "yes" ]; then
|
||||||
|
msg_info "Restoring LXC from backup"
|
||||||
|
pct stop $container
|
||||||
|
LXC_STORAGE=$(pct config $container | awk -F '[:,]' '/rootfs/ {print $2}')
|
||||||
|
pct restore $container /var/lib/vz/dump/vzdump-lxc-${container}-*.tar.zst --storage $LXC_STORAGE --force >/dev/null 2>&1
|
||||||
|
pct start $container
|
||||||
|
restorestatus=$?
|
||||||
|
if [ $restorestatus -eq 0 ]; then
|
||||||
|
msg_ok "Restored LXC from backup"
|
||||||
|
else
|
||||||
|
msg_error "Restored LXC from backup failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
msg_error "Update failed for container $container. Exiting"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
wait
|
||||||
|
header_info
|
||||||
|
echo -e "${GN}The process is complete, and the containers have been successfully updated.${CL}\n"
|
||||||
|
if [ "${#containers_needing_reboot[@]}" -gt 0 ]; then
|
||||||
|
echo -e "${RD}The following containers require a reboot:${CL}"
|
||||||
|
for container_name in "${containers_needing_reboot[@]}"; do
|
||||||
|
echo "$container_name"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Determine reboot choice based on var_auto_reboot
|
||||||
|
REBOOT_CHOICE="no"
|
||||||
|
if [[ -n "$var_auto_reboot" ]]; then
|
||||||
|
REBOOT_CHOICE="$var_auto_reboot"
|
||||||
|
else
|
||||||
|
echo -ne "${INFO} Do you wish to reboot these containers? <yes/No> "
|
||||||
|
read -r prompt
|
||||||
|
if [[ ${prompt,,} =~ ^(yes)$ ]]; then
|
||||||
|
REBOOT_CHOICE="yes"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$REBOOT_CHOICE" == "yes" ]]; then
|
||||||
|
echo -e "${CROSS}${HOLD} ${YWB}Rebooting containers.${CL}"
|
||||||
|
for container_name in "${containers_needing_reboot[@]}"; do
|
||||||
|
container=$(echo $container_name | cut -d " " -f 1)
|
||||||
|
pct reboot ${container}
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
730
vm/docker-vm.sh
730
vm/docker-vm.sh
@@ -1,45 +1,71 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: thost96 (thost96) | michelroegl-brunner | MickLesk
|
# Author: thost96 (thost96) | Co-Author: michelroegl-brunner
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVED/raw/main/LICENSE
|
# 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)
|
||||||
# Docker VM - Creates a Docker-ready Virtual Machine
|
|
||||||
# ==============================================================================
|
|
||||||
|
|
||||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/api.func) 2>/dev/null
|
function header_info() {
|
||||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/vm-core.func) 2>/dev/null
|
clear
|
||||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/cloud-init.func) 2>/dev/null || true
|
cat <<"EOF"
|
||||||
load_functions
|
____ __ _ ____ ___
|
||||||
|
/ __ \____ _____/ /_____ _____ | | / / |/ /
|
||||||
# ==============================================================================
|
/ / / / __ \/ ___/ //_/ _ \/ ___/ | | / / /|_/ /
|
||||||
# SCRIPT VARIABLES
|
/ /_/ / /_/ / /__/ ,< / __/ / | |/ / / / /
|
||||||
# ==============================================================================
|
/_____/\____/\___/_/|_|\___/_/ |___/_/ /_/
|
||||||
APP="Docker"
|
|
||||||
APP_TYPE="vm"
|
|
||||||
NSAPP="docker-vm"
|
|
||||||
var_os="debian"
|
|
||||||
var_version="13"
|
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
header_info
|
||||||
|
echo -e "\n Loading..."
|
||||||
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
|
GEN_MAC=02:$(openssl rand -hex 5 | awk '{print toupper($0)}' | sed 's/\(..\)/\1:/g; s/.$//')
|
||||||
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)"
|
||||||
METHOD=""
|
METHOD=""
|
||||||
|
NSAPP="docker-vm"
|
||||||
|
var_os="debian"
|
||||||
|
var_version="12"
|
||||||
DISK_SIZE="10G"
|
DISK_SIZE="10G"
|
||||||
USE_CLOUD_INIT="no"
|
|
||||||
OS_TYPE=""
|
|
||||||
OS_VERSION=""
|
|
||||||
THIN="discard=on,ssd=1,"
|
|
||||||
|
|
||||||
# ==============================================================================
|
YW=$(echo "\033[33m")
|
||||||
# ERROR HANDLING & CLEANUP
|
BL=$(echo "\033[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,"
|
||||||
set -e
|
set -e
|
||||||
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT
|
trap 'post_update_to_api "failed" "INTERRUPTED"' SIGINT
|
||||||
trap 'post_update_to_api "failed" "TERMINATED"' SIGTERM
|
trap 'post_update_to_api "failed" "TERMINATED"' SIGTERM
|
||||||
|
|
||||||
function error_handler() {
|
function error_handler() {
|
||||||
local exit_code="$?"
|
local exit_code="$?"
|
||||||
local line_number="$1"
|
local line_number="$1"
|
||||||
@@ -50,96 +76,140 @@ function error_handler() {
|
|||||||
cleanup_vmid
|
cleanup_vmid
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
function get_valid_nextid() {
|
||||||
# OS SELECTION FUNCTIONS
|
local try_id
|
||||||
# ==============================================================================
|
try_id=$(pvesh get /cluster/nextid)
|
||||||
function select_os() {
|
while true; do
|
||||||
if OS_CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SELECT OS" --radiolist \
|
if [ -f "/etc/pve/qemu-server/${try_id}.conf" ] || [ -f "/etc/pve/lxc/${try_id}.conf" ]; then
|
||||||
"Choose Operating System for Docker VM" 14 68 4 \
|
try_id=$((try_id + 1))
|
||||||
"debian13" "Debian 13 (Trixie) - Latest" ON \
|
continue
|
||||||
"debian12" "Debian 12 (Bookworm) - Stable" OFF \
|
|
||||||
"ubuntu2404" "Ubuntu 24.04 LTS (Noble)" OFF \
|
|
||||||
"ubuntu2204" "Ubuntu 22.04 LTS (Jammy)" OFF \
|
|
||||||
3>&1 1>&2 2>&3); then
|
|
||||||
case $OS_CHOICE in
|
|
||||||
debian13)
|
|
||||||
OS_TYPE="debian"
|
|
||||||
OS_VERSION="13"
|
|
||||||
OS_CODENAME="trixie"
|
|
||||||
OS_DISPLAY="Debian 13 (Trixie)"
|
|
||||||
;;
|
|
||||||
debian12)
|
|
||||||
OS_TYPE="debian"
|
|
||||||
OS_VERSION="12"
|
|
||||||
OS_CODENAME="bookworm"
|
|
||||||
OS_DISPLAY="Debian 12 (Bookworm)"
|
|
||||||
;;
|
|
||||||
ubuntu2404)
|
|
||||||
OS_TYPE="ubuntu"
|
|
||||||
OS_VERSION="24.04"
|
|
||||||
OS_CODENAME="noble"
|
|
||||||
OS_DISPLAY="Ubuntu 24.04 LTS"
|
|
||||||
;;
|
|
||||||
ubuntu2204)
|
|
||||||
OS_TYPE="ubuntu"
|
|
||||||
OS_VERSION="22.04"
|
|
||||||
OS_CODENAME="jammy"
|
|
||||||
OS_DISPLAY="Ubuntu 22.04 LTS"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo -e "${OS}${BOLD}${DGN}Operating System: ${BGN}${OS_DISPLAY}${CL}"
|
|
||||||
else
|
|
||||||
exit_script
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function select_cloud_init() {
|
|
||||||
if [ "$OS_TYPE" = "ubuntu" ]; then
|
|
||||||
USE_CLOUD_INIT="yes"
|
|
||||||
echo -e "${CLOUD:-${TAB}☁️${TAB}${CL}}${BOLD}${DGN}Cloud-Init: ${BGN}yes (Ubuntu requires Cloud-Init)${CL}"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "CLOUD-INIT" \
|
|
||||||
--yesno "Enable Cloud-Init for VM configuration?\n\nCloud-Init allows automatic configuration of:\n- User accounts and passwords\n- SSH keys\n- Network settings (DHCP/Static)\n- DNS configuration\n\nYou can also configure these settings later in Proxmox UI.\n\nNote: Debian without Cloud-Init will use nocloud image with console auto-login." 18 68); then
|
|
||||||
USE_CLOUD_INIT="yes"
|
|
||||||
echo -e "${CLOUD:-${TAB}☁️${TAB}${CL}}${BOLD}${DGN}Cloud-Init: ${BGN}yes${CL}"
|
|
||||||
else
|
|
||||||
USE_CLOUD_INIT="no"
|
|
||||||
echo -e "${CLOUD:-${TAB}☁️${TAB}${CL}}${BOLD}${DGN}Cloud-Init: ${BGN}no${CL}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_image_url() {
|
|
||||||
local arch=$(dpkg --print-architecture)
|
|
||||||
case $OS_TYPE in
|
|
||||||
debian)
|
|
||||||
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
|
||||||
echo "https://cloud.debian.org/images/cloud/${OS_CODENAME}/latest/debian-${OS_VERSION}-generic-${arch}.qcow2"
|
|
||||||
else
|
|
||||||
echo "https://cloud.debian.org/images/cloud/${OS_CODENAME}/latest/debian-${OS_VERSION}-nocloud-${arch}.qcow2"
|
|
||||||
fi
|
fi
|
||||||
;;
|
if lvs --noheadings -o lv_name | grep -qE "(^|[-_])${try_id}($|[-_])"; then
|
||||||
ubuntu)
|
try_id=$((try_id + 1))
|
||||||
echo "https://cloud-images.ubuntu.com/${OS_CODENAME}/current/${OS_CODENAME}-server-cloudimg-${arch}.img"
|
continue
|
||||||
;;
|
fi
|
||||||
esac
|
break
|
||||||
|
done
|
||||||
|
echo "$try_id"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
function cleanup_vmid() {
|
||||||
# SETTINGS FUNCTIONS
|
if qm status $VMID &>/dev/null; then
|
||||||
# ==============================================================================
|
qm stop $VMID &>/dev/null
|
||||||
function default_settings() {
|
qm destroy $VMID &>/dev/null
|
||||||
select_os
|
fi
|
||||||
select_cloud_init
|
}
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
popd >/dev/null
|
||||||
|
post_update_to_api "done" "none"
|
||||||
|
rm -rf $TEMP_DIR
|
||||||
|
}
|
||||||
|
|
||||||
|
TEMP_DIR=$(mktemp -d)
|
||||||
|
pushd $TEMP_DIR >/dev/null
|
||||||
|
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Docker VM" --yesno "This will create a New Docker VM. Proceed?" 10 58; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
header_info && echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
function msg_info() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -ne "${TAB}${YW}${HOLD}${msg}${HOLD}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function msg_ok() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${BFR}${CM}${GN}${msg}${CL}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function msg_error() {
|
||||||
|
local msg="$1"
|
||||||
|
echo -e "${BFR}${CROSS}${RD}${msg}${CL}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_root() {
|
||||||
|
if [[ "$(id -u)" -ne 0 || $(ps -o comm= -p $PPID) == "sudo" ]]; then
|
||||||
|
clear
|
||||||
|
msg_error "Please run this script as root."
|
||||||
|
echo -e "\nExiting..."
|
||||||
|
sleep 2
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
|
||||||
|
# Supported: Proxmox VE 8.0.x – 8.9.x, 9.0 and 9.1
|
||||||
|
pve_check() {
|
||||||
|
local PVE_VER
|
||||||
|
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
||||||
|
|
||||||
|
# Check for Proxmox VE 8.x: allow 8.0–8.9
|
||||||
|
if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then
|
||||||
|
local MINOR="${BASH_REMATCH[1]}"
|
||||||
|
if ((MINOR < 0 || MINOR > 9)); then
|
||||||
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
|
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for Proxmox VE 9.x: allow 9.0 and 9.1
|
||||||
|
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
|
||||||
|
local MINOR="${BASH_REMATCH[1]}"
|
||||||
|
if ((MINOR < 0 || MINOR > 1)); then
|
||||||
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
|
msg_error "Supported: Proxmox VE version 9.0 – 9.1"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# All other unsupported versions
|
||||||
|
msg_error "This version of Proxmox VE is not supported."
|
||||||
|
msg_error "Supported versions: Proxmox VE 8.0 – 8.x or 9.0 – 9.1"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function arch_check() {
|
||||||
|
if [ "$(dpkg --print-architecture)" != "amd64" ]; then
|
||||||
|
echo -e "\n ${INFO}${YWB}This script will not work with PiMox! \n"
|
||||||
|
echo -e "\n ${YWB}Visit https://github.com/asylumexp/Proxmox for ARM64 support. \n"
|
||||||
|
echo -e "Exiting..."
|
||||||
|
sleep 2
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function ssh_check() {
|
||||||
|
if command -v pveversion >/dev/null 2>&1; then
|
||||||
|
if [ -n "${SSH_CLIENT:+x}" ]; then
|
||||||
|
if whiptail --backtitle "Proxmox VE Helper Scripts" --defaultno --title "SSH DETECTED" --yesno "It's suggested to use the Proxmox shell instead of SSH, since SSH can create issues while gathering variables. Would you like to proceed with using SSH?" 10 62; then
|
||||||
|
echo "you've been warned"
|
||||||
|
else
|
||||||
|
clear
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function exit-script() {
|
||||||
|
clear
|
||||||
|
echo -e "\n${CROSS}${RD}User exited script${CL}\n"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
function default_settings() {
|
||||||
VMID=$(get_valid_nextid)
|
VMID=$(get_valid_nextid)
|
||||||
FORMAT=""
|
FORMAT=",efitype=4m"
|
||||||
MACHINE=" -machine q35"
|
MACHINE=""
|
||||||
DISK_CACHE=""
|
DISK_CACHE=""
|
||||||
DISK_SIZE="10G"
|
DISK_SIZE="10G"
|
||||||
HN="docker"
|
HN="docker"
|
||||||
CPU_TYPE=" -cpu host"
|
CPU_TYPE=""
|
||||||
CORE_COUNT="2"
|
CORE_COUNT="2"
|
||||||
RAM_SIZE="4096"
|
RAM_SIZE="4096"
|
||||||
BRG="vmbr0"
|
BRG="vmbr0"
|
||||||
@@ -148,13 +218,12 @@ function default_settings() {
|
|||||||
MTU=""
|
MTU=""
|
||||||
START_VM="yes"
|
START_VM="yes"
|
||||||
METHOD="default"
|
METHOD="default"
|
||||||
|
|
||||||
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
|
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}${VMID}${CL}"
|
||||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}Q35 (Modern)${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 Size: ${BGN}${DISK_SIZE}${CL}"
|
||||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Cache: ${BGN}None${CL}"
|
||||||
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}${HN}${CL}"
|
||||||
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}KVM64${CL}"
|
||||||
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
|
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}${CORE_COUNT}${CL}"
|
||||||
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
|
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}${RAM_SIZE}${CL}"
|
||||||
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}${BRG}${CL}"
|
||||||
@@ -162,22 +231,12 @@ function default_settings() {
|
|||||||
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}Default${CL}"
|
||||||
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}Default${CL}"
|
||||||
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
||||||
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above settings${CL}"
|
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above default settings${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function advanced_settings() {
|
function advanced_settings() {
|
||||||
select_os
|
|
||||||
select_cloud_init
|
|
||||||
|
|
||||||
# SSH Key selection for Cloud-Init VMs
|
|
||||||
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
|
||||||
configure_cloudinit_ssh_keys || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
METHOD="advanced"
|
METHOD="advanced"
|
||||||
[ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
|
[ -z "${VMID:-}" ] && VMID=$(get_valid_nextid)
|
||||||
|
|
||||||
# VM ID
|
|
||||||
while true; do
|
while true; do
|
||||||
if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $VMID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if VMID=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Virtual Machine ID" 8 58 $VMID --title "VIRTUAL MACHINE ID" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z "$VMID" ]; then
|
if [ -z "$VMID" ]; then
|
||||||
@@ -191,29 +250,27 @@ function advanced_settings() {
|
|||||||
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
|
echo -e "${CONTAINERID}${BOLD}${DGN}Virtual Machine ID: ${BGN}$VMID${CL}"
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Machine Type
|
|
||||||
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
|
if MACH=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "MACHINE TYPE" --radiolist --cancel-button Exit-Script "Choose Type" 10 58 2 \
|
||||||
"q35" "Q35 (Modern, PCIe)" ON \
|
"i440fx" "Machine i440fx" ON \
|
||||||
"i440fx" "i440fx (Legacy, PCI)" OFF \
|
"q35" "Machine q35" OFF \
|
||||||
3>&1 1>&2 2>&3); then
|
3>&1 1>&2 2>&3); then
|
||||||
if [ $MACH = q35 ]; then
|
if [ $MACH = q35 ]; then
|
||||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}Q35 (Modern)${CL}"
|
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
|
||||||
FORMAT=""
|
FORMAT=""
|
||||||
MACHINE=" -machine q35"
|
MACHINE=" -machine q35"
|
||||||
else
|
else
|
||||||
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}i440fx (Legacy)${CL}"
|
echo -e "${CONTAINERTYPE}${BOLD}${DGN}Machine Type: ${BGN}$MACH${CL}"
|
||||||
FORMAT=",efitype=4m"
|
FORMAT=",efitype=4m"
|
||||||
MACHINE=""
|
MACHINE=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Disk Size
|
|
||||||
if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "$DISK_SIZE" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if DISK_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Disk Size in GiB (e.g., 10, 20)" 8 58 "$DISK_SIZE" --title "DISK SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
|
DISK_SIZE=$(echo "$DISK_SIZE" | tr -d ' ')
|
||||||
if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
|
if [[ "$DISK_SIZE" =~ ^[0-9]+$ ]]; then
|
||||||
@@ -223,13 +280,12 @@ function advanced_settings() {
|
|||||||
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
|
echo -e "${DISKSIZE}${BOLD}${DGN}Disk Size: ${BGN}$DISK_SIZE${CL}"
|
||||||
else
|
else
|
||||||
echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
|
echo -e "${DISKSIZE}${BOLD}${RD}Invalid Disk Size. Please use a number (e.g., 10 or 10G).${CL}"
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Disk Cache
|
|
||||||
if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
if DISK_CACHE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "DISK CACHE" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
||||||
"0" "None (Default)" ON \
|
"0" "None (Default)" ON \
|
||||||
"1" "Write Through" OFF \
|
"1" "Write Through" OFF \
|
||||||
@@ -242,25 +298,24 @@ function advanced_settings() {
|
|||||||
DISK_CACHE=""
|
DISK_CACHE=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Hostname
|
|
||||||
if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 docker --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if VM_NAME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Hostname" 8 58 docker --title "HOSTNAME" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $VM_NAME ]; then
|
if [ -z $VM_NAME ]; then
|
||||||
HN="docker"
|
HN="docker"
|
||||||
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
||||||
else
|
else
|
||||||
HN=$(echo ${VM_NAME,,} | tr -d ' ')
|
HN=$(echo ${VM_NAME,,} | tr -d ' ')
|
||||||
|
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${HOSTNAME}${BOLD}${DGN}Hostname: ${BGN}$HN${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# CPU Model
|
|
||||||
if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
if CPU_TYPE1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "CPU MODEL" --radiolist "Choose" --cancel-button Exit-Script 10 58 2 \
|
||||||
"1" "Host (Recommended)" ON \
|
"0" "KVM64 (Default)" ON \
|
||||||
"0" "KVM64" OFF \
|
"1" "Host" OFF \
|
||||||
3>&1 1>&2 2>&3); then
|
3>&1 1>&2 2>&3); then
|
||||||
if [ $CPU_TYPE1 = "1" ]; then
|
if [ $CPU_TYPE1 = "1" ]; then
|
||||||
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
echo -e "${OS}${BOLD}${DGN}CPU Model: ${BGN}Host${CL}"
|
||||||
@@ -270,78 +325,80 @@ function advanced_settings() {
|
|||||||
CPU_TYPE=""
|
CPU_TYPE=""
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# CPU Cores
|
|
||||||
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if CORE_COUNT=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate CPU Cores" 8 58 2 --title "CORE COUNT" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $CORE_COUNT ]; then
|
if [ -z $CORE_COUNT ]; then
|
||||||
CORE_COUNT="2"
|
CORE_COUNT="2"
|
||||||
|
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
|
||||||
|
else
|
||||||
|
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${CPUCORE}${BOLD}${DGN}CPU Cores: ${BGN}$CORE_COUNT${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# RAM Size
|
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 RAM_SIZE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Allocate RAM in MiB" 8 58 4096 --title "RAM" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
|
||||||
if [ -z $RAM_SIZE ]; then
|
if [ -z $RAM_SIZE ]; then
|
||||||
RAM_SIZE="4096"
|
RAM_SIZE="2048"
|
||||||
|
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
|
||||||
|
else
|
||||||
|
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${RAMSIZE}${BOLD}${DGN}RAM Size: ${BGN}$RAM_SIZE${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Bridge
|
|
||||||
if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if BRG=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Bridge" 8 58 vmbr0 --title "BRIDGE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $BRG ]; then
|
if [ -z $BRG ]; then
|
||||||
BRG="vmbr0"
|
BRG="vmbr0"
|
||||||
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
||||||
|
else
|
||||||
|
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${BRIDGE}${BOLD}${DGN}Bridge: ${BGN}$BRG${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# MAC Address
|
|
||||||
if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if MAC1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a MAC Address" 8 58 $GEN_MAC --title "MAC ADDRESS" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $MAC1 ]; then
|
if [ -z $MAC1 ]; then
|
||||||
MAC="$GEN_MAC"
|
MAC="$GEN_MAC"
|
||||||
|
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
|
||||||
else
|
else
|
||||||
MAC="$MAC1"
|
MAC="$MAC1"
|
||||||
|
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC1${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${MACADDRESS}${BOLD}${DGN}MAC Address: ${BGN}$MAC${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# VLAN
|
if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan(leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if VLAN1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set a Vlan (leave blank for default)" 8 58 --title "VLAN" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
|
||||||
if [ -z $VLAN1 ]; then
|
if [ -z $VLAN1 ]; then
|
||||||
VLAN1="Default"
|
VLAN1="Default"
|
||||||
VLAN=""
|
VLAN=""
|
||||||
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
||||||
else
|
else
|
||||||
VLAN=",tag=$VLAN1"
|
VLAN=",tag=$VLAN1"
|
||||||
|
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${VLANTAG}${BOLD}${DGN}VLAN: ${BGN}$VLAN1${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# MTU
|
|
||||||
if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
if MTU1=$(whiptail --backtitle "Proxmox VE Helper Scripts" --inputbox "Set Interface MTU Size (leave blank for default)" 8 58 --title "MTU SIZE" --cancel-button Exit-Script 3>&1 1>&2 2>&3); then
|
||||||
if [ -z $MTU1 ]; then
|
if [ -z $MTU1 ]; then
|
||||||
MTU1="Default"
|
MTU1="Default"
|
||||||
MTU=""
|
MTU=""
|
||||||
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
||||||
else
|
else
|
||||||
MTU=",mtu=$MTU1"
|
MTU=",mtu=$MTU1"
|
||||||
|
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
||||||
fi
|
fi
|
||||||
echo -e "${DEFAULT}${BOLD}${DGN}Interface MTU Size: ${BGN}$MTU1${CL}"
|
|
||||||
else
|
else
|
||||||
exit_script
|
exit-script
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Start VM
|
|
||||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "START VIRTUAL MACHINE" --yesno "Start VM when completed?" 10 58); then
|
||||||
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
echo -e "${GATEWAY}${BOLD}${DGN}Start VM when completed: ${BGN}yes${CL}"
|
||||||
START_VM="yes"
|
START_VM="yes"
|
||||||
@@ -350,7 +407,6 @@ function advanced_settings() {
|
|||||||
START_VM="no"
|
START_VM="no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Confirm
|
|
||||||
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Docker VM?" --no-button Do-Over 10 58); then
|
if (whiptail --backtitle "Proxmox VE Helper Scripts" --title "ADVANCED SETTINGS COMPLETE" --yesno "Ready to create a Docker VM?" --no-button Do-Over 10 58); then
|
||||||
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above advanced settings${CL}"
|
echo -e "${CREATING}${BOLD}${DGN}Creating a Docker VM using the above advanced settings${CL}"
|
||||||
else
|
else
|
||||||
@@ -371,28 +427,13 @@ function start_script() {
|
|||||||
advanced_settings
|
advanced_settings
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# MAIN EXECUTION
|
|
||||||
# ==============================================================================
|
|
||||||
header_info
|
|
||||||
|
|
||||||
check_root
|
check_root
|
||||||
arch_check
|
arch_check
|
||||||
pve_check
|
pve_check
|
||||||
|
ssh_check
|
||||||
if whiptail --backtitle "Proxmox VE Helper Scripts" --title "Docker VM" --yesno "This will create a New Docker VM. Proceed?" 10 58; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
header_info && echo -e "${CROSS}${RD}User exited script${CL}\n" && exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
start_script
|
start_script
|
||||||
post_to_api_vm
|
post_to_api_vm
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# STORAGE SELECTION
|
|
||||||
# ==============================================================================
|
|
||||||
msg_info "Validating Storage"
|
msg_info "Validating Storage"
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
TAG=$(echo $line | awk '{print $1}')
|
TAG=$(echo $line | awk '{print $1}')
|
||||||
@@ -405,7 +446,6 @@ while read -r line; do
|
|||||||
fi
|
fi
|
||||||
STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
|
STORAGE_MENU+=("$TAG" "$ITEM" "OFF")
|
||||||
done < <(pvesm status -content images | awk 'NR>1')
|
done < <(pvesm status -content images | awk 'NR>1')
|
||||||
|
|
||||||
VALID=$(pvesm status -content images | awk 'NR>1')
|
VALID=$(pvesm status -content images | awk 'NR>1')
|
||||||
if [ -z "$VALID" ]; then
|
if [ -z "$VALID" ]; then
|
||||||
msg_error "Unable to detect a valid storage location."
|
msg_error "Unable to detect a valid storage location."
|
||||||
@@ -413,8 +453,6 @@ if [ -z "$VALID" ]; then
|
|||||||
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
|
elif [ $((${#STORAGE_MENU[@]} / 3)) -eq 1 ]; then
|
||||||
STORAGE=${STORAGE_MENU[0]}
|
STORAGE=${STORAGE_MENU[0]}
|
||||||
else
|
else
|
||||||
if [ -n "$SPINNER_PID" ] && ps -p $SPINNER_PID >/dev/null; then kill $SPINNER_PID >/dev/null; fi
|
|
||||||
printf "\e[?25h"
|
|
||||||
while [ -z "${STORAGE:+x}" ]; do
|
while [ -z "${STORAGE:+x}" ]; do
|
||||||
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
||||||
"Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
|
"Which storage pool would you like to use for ${HN}?\nTo make a selection, use the Spacebar.\n" \
|
||||||
@@ -424,288 +462,112 @@ else
|
|||||||
fi
|
fi
|
||||||
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
|
msg_ok "Using ${CL}${BL}$STORAGE${CL} ${GN}for Storage Location."
|
||||||
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
|
msg_ok "Virtual Machine ID is ${CL}${BL}$VMID${CL}."
|
||||||
|
msg_info "Retrieving the URL for the Debian 12 Qcow2 Disk Image"
|
||||||
# ==============================================================================
|
URL="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-$(dpkg --print-architecture).qcow2"
|
||||||
# PREREQUISITES
|
sleep 2
|
||||||
# ==============================================================================
|
|
||||||
if ! command -v virt-customize &>/dev/null; then
|
|
||||||
msg_info "Installing libguestfs-tools"
|
|
||||||
apt-get -qq update >/dev/null
|
|
||||||
apt-get -qq install libguestfs-tools lsb-release -y >/dev/null
|
|
||||||
apt-get -qq install dhcpcd-base -y >/dev/null 2>&1 || true
|
|
||||||
msg_ok "Installed libguestfs-tools"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# IMAGE DOWNLOAD
|
|
||||||
# ==============================================================================
|
|
||||||
msg_info "Retrieving the URL for the ${OS_DISPLAY} Qcow2 Disk Image"
|
|
||||||
URL=$(get_image_url)
|
|
||||||
CACHE_DIR="/var/lib/vz/template/cache"
|
|
||||||
CACHE_FILE="$CACHE_DIR/$(basename "$URL")"
|
|
||||||
mkdir -p "$CACHE_DIR"
|
|
||||||
msg_ok "${CL}${BL}${URL}${CL}"
|
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}"
|
||||||
|
|
||||||
if [[ ! -s "$CACHE_FILE" ]]; then
|
|
||||||
curl -f#SL -o "$CACHE_FILE" "$URL"
|
|
||||||
echo -en "\e[1A\e[0K"
|
|
||||||
msg_ok "Downloaded ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
|
|
||||||
else
|
|
||||||
msg_ok "Using cached image ${CL}${BL}$(basename "$CACHE_FILE")${CL}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# STORAGE TYPE DETECTION
|
|
||||||
# ==============================================================================
|
|
||||||
STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
|
STORAGE_TYPE=$(pvesm status -storage "$STORAGE" | awk 'NR>1 {print $2}')
|
||||||
case $STORAGE_TYPE in
|
case $STORAGE_TYPE in
|
||||||
nfs | dir)
|
nfs | dir)
|
||||||
DISK_EXT=".qcow2"
|
DISK_EXT=".qcow2"
|
||||||
DISK_REF="$VMID/"
|
DISK_REF="$VMID/"
|
||||||
DISK_IMPORT="--format qcow2"
|
DISK_IMPORT="-format qcow2"
|
||||||
THIN=""
|
THIN=""
|
||||||
;;
|
;;
|
||||||
btrfs)
|
btrfs)
|
||||||
DISK_EXT=".raw"
|
DISK_EXT=".raw"
|
||||||
DISK_REF="$VMID/"
|
DISK_REF="$VMID/"
|
||||||
DISK_IMPORT="--format raw"
|
DISK_IMPORT="-format raw"
|
||||||
FORMAT=",efitype=4m"
|
FORMAT=",efitype=4m"
|
||||||
THIN=""
|
THIN=""
|
||||||
;;
|
;;
|
||||||
*)
|
|
||||||
DISK_EXT=""
|
|
||||||
DISK_REF=""
|
|
||||||
DISK_IMPORT="--format raw"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
for i in {0,1}; do
|
||||||
# ==============================================================================
|
disk="DISK$i"
|
||||||
# IMAGE CUSTOMIZATION WITH DOCKER
|
eval DISK${i}=vm-${VMID}-disk-${i}${DISK_EXT:-}
|
||||||
# ==============================================================================
|
eval DISK${i}_REF=${STORAGE}:${DISK_REF:-}${!disk}
|
||||||
msg_info "Preparing ${OS_DISPLAY} image with Docker"
|
|
||||||
|
|
||||||
WORK_FILE=$(mktemp --suffix=.qcow2)
|
|
||||||
cp "$CACHE_FILE" "$WORK_FILE"
|
|
||||||
|
|
||||||
export LIBGUESTFS_BACKEND_SETTINGS=dns=8.8.8.8,1.1.1.1
|
|
||||||
|
|
||||||
DOCKER_PREINSTALLED="no"
|
|
||||||
|
|
||||||
# Install qemu-guest-agent and Docker during image customization
|
|
||||||
msg_info "Installing base packages in image"
|
|
||||||
if virt-customize -a "$WORK_FILE" --install qemu-guest-agent,curl,ca-certificates >/dev/null 2>&1; then
|
|
||||||
msg_ok "Installed base packages"
|
|
||||||
|
|
||||||
msg_info "Installing Docker (this may take 2-5 minutes)"
|
|
||||||
if virt-customize -q -a "$WORK_FILE" --run-command "curl -fsSL https://get.docker.com | sh" >/dev/null 2>&1 &&
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "systemctl enable docker" >/dev/null 2>&1; then
|
|
||||||
msg_ok "Installed Docker"
|
|
||||||
|
|
||||||
msg_info "Configuring Docker daemon"
|
|
||||||
# Optimize Docker daemon configuration
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "mkdir -p /etc/docker" >/dev/null 2>&1
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/docker/daemon.json << EOF
|
|
||||||
{
|
|
||||||
"storage-driver": "overlay2",
|
|
||||||
"log-driver": "json-file",
|
|
||||||
"log-opts": {
|
|
||||||
"max-size": "10m",
|
|
||||||
"max-file": "3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF' >/dev/null 2>&1
|
|
||||||
DOCKER_PREINSTALLED="yes"
|
|
||||||
msg_ok "Configured Docker daemon"
|
|
||||||
else
|
|
||||||
msg_ok "Docker will be installed on first boot"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
msg_ok "Packages will be installed on first boot"
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Finalizing image (hostname, SSH config)"
|
|
||||||
# Set hostname and prepare for unique machine-id
|
|
||||||
virt-customize -q -a "$WORK_FILE" --hostname "${HN}" >/dev/null 2>&1
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "truncate -s 0 /etc/machine-id" >/dev/null 2>&1
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "rm -f /var/lib/dbus/machine-id" >/dev/null 2>&1
|
|
||||||
|
|
||||||
# Configure SSH for Cloud-Init
|
|
||||||
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config" >/dev/null 2>&1 || true
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config" >/dev/null 2>&1 || true
|
|
||||||
else
|
|
||||||
# Configure auto-login for nocloud images (no Cloud-Init)
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "mkdir -p /etc/systemd/system/serial-getty@ttyS0.service.d" >/dev/null 2>&1 || true
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/systemd/system/serial-getty@ttyS0.service.d/autologin.conf << EOF
|
|
||||||
[Service]
|
|
||||||
ExecStart=
|
|
||||||
ExecStart=-/sbin/agetty --autologin root --noclear %I \$TERM
|
|
||||||
EOF' >/dev/null 2>&1 || true
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command "mkdir -p /etc/systemd/system/getty@tty1.service.d" >/dev/null 2>&1 || true
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/systemd/system/getty@tty1.service.d/autologin.conf << EOF
|
|
||||||
[Service]
|
|
||||||
ExecStart=
|
|
||||||
ExecStart=-/sbin/agetty --autologin root --noclear %I \$TERM
|
|
||||||
EOF' >/dev/null 2>&1 || true
|
|
||||||
fi
|
|
||||||
msg_ok "Finalized image"
|
|
||||||
|
|
||||||
# Create first-boot Docker install script (fallback if virt-customize failed)
|
|
||||||
if [ "$DOCKER_PREINSTALLED" = "no" ]; then
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /root/install-docker.sh << "DOCKERSCRIPT"
|
|
||||||
#!/bin/bash
|
|
||||||
exec > /var/log/install-docker.log 2>&1
|
|
||||||
echo "[$(date)] Starting Docker installation"
|
|
||||||
|
|
||||||
for i in {1..30}; do
|
|
||||||
ping -c 1 8.8.8.8 >/dev/null 2>&1 && break
|
|
||||||
sleep 2
|
|
||||||
done
|
done
|
||||||
|
|
||||||
apt-get update
|
if ! command -v virt-customize &>/dev/null; then
|
||||||
apt-get install -y qemu-guest-agent curl ca-certificates
|
msg_info "Installing Pre-Requisite libguestfs-tools onto Host"
|
||||||
curl -fsSL https://get.docker.com | sh
|
apt-get -qq update >/dev/null
|
||||||
systemctl enable docker
|
apt-get -qq install libguestfs-tools lsb-release -y >/dev/null
|
||||||
systemctl start docker
|
# Workaround for Proxmox VE 9.0 libguestfs issue
|
||||||
|
apt-get -qq install dhcpcd-base -y >/dev/null 2>&1 || true
|
||||||
mkdir -p /etc/docker
|
msg_ok "Installed libguestfs-tools successfully"
|
||||||
cat > /etc/docker/daemon.json << DAEMON
|
|
||||||
{
|
|
||||||
"storage-driver": "overlay2",
|
|
||||||
"log-driver": "json-file",
|
|
||||||
"log-opts": { "max-size": "10m", "max-file": "3" }
|
|
||||||
}
|
|
||||||
DAEMON
|
|
||||||
systemctl restart docker
|
|
||||||
|
|
||||||
touch /root/.docker-installed
|
|
||||||
echo "[$(date)] Docker installation completed"
|
|
||||||
DOCKERSCRIPT
|
|
||||||
chmod +x /root/install-docker.sh' >/dev/null 2>&1
|
|
||||||
|
|
||||||
virt-customize -q -a "$WORK_FILE" --run-command 'cat > /etc/systemd/system/install-docker.service << "DOCKERSERVICE"
|
|
||||||
[Unit]
|
|
||||||
Description=Install Docker on First Boot
|
|
||||||
After=network-online.target
|
|
||||||
Wants=network-online.target
|
|
||||||
ConditionPathExists=!/root/.docker-installed
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
ExecStart=/root/install-docker.sh
|
|
||||||
RemainAfterExit=yes
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
DOCKERSERVICE
|
|
||||||
systemctl enable install-docker.service' >/dev/null 2>&1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Resize disk to target size
|
msg_info "Adding Docker and Docker Compose Plugin to Debian 12 Qcow2 Disk Image"
|
||||||
msg_info "Resizing disk image to ${DISK_SIZE}"
|
virt-customize -q -a "${FILE}" --install qemu-guest-agent,apt-transport-https,ca-certificates,curl,gnupg,software-properties-common,lsb-release >/dev/null &&
|
||||||
qemu-img resize "$WORK_FILE" "${DISK_SIZE}" >/dev/null 2>&1
|
virt-customize -q -a "${FILE}" --run-command "mkdir -p /etc/apt/keyrings && curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg" >/dev/null &&
|
||||||
msg_ok "Resized disk image"
|
virt-customize -q -a "${FILE}" --run-command "echo 'deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable' > /etc/apt/sources.list.d/docker.list" >/dev/null &&
|
||||||
|
virt-customize -q -a "${FILE}" --run-command "apt-get update -qq && apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin" >/dev/null &&
|
||||||
|
virt-customize -q -a "${FILE}" --run-command "systemctl enable docker" >/dev/null &&
|
||||||
|
virt-customize -q -a "${FILE}" --hostname "${HN}" >/dev/null &&
|
||||||
|
virt-customize -q -a "${FILE}" --run-command "echo -n > /etc/machine-id" >/dev/null
|
||||||
|
msg_ok "Added Docker and Docker Compose Plugin to Debian 12 Qcow2 Disk Image successfully"
|
||||||
|
|
||||||
# ==============================================================================
|
msg_info "Expanding root partition to use full disk space"
|
||||||
# VM CREATION
|
qemu-img create -f qcow2 expanded.qcow2 ${DISK_SIZE} >/dev/null 2>&1
|
||||||
# ==============================================================================
|
virt-resize --expand /dev/sda1 ${FILE} expanded.qcow2 >/dev/null 2>&1
|
||||||
msg_info "Creating Docker VM shell"
|
mv expanded.qcow2 ${FILE} >/dev/null 2>&1
|
||||||
|
msg_ok "Expanded image to full size"
|
||||||
|
|
||||||
|
msg_info "Creating a Docker VM"
|
||||||
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
qm create $VMID -agent 1${MACHINE} -tablet 0 -localtime 1 -bios ovmf${CPU_TYPE} -cores $CORE_COUNT -memory $RAM_SIZE \
|
||||||
-name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci >/dev/null
|
-name $HN -tags community-script -net0 virtio,bridge=$BRG,macaddr=$MAC$VLAN$MTU -onboot 1 -ostype l26 -scsihw virtio-scsi-pci
|
||||||
|
pvesm alloc $STORAGE $VMID $DISK0 4M 1>&/dev/null
|
||||||
msg_ok "Created VM shell"
|
qm importdisk $VMID ${FILE} $STORAGE ${DISK_IMPORT:-} 1>&/dev/null
|
||||||
|
qm set $VMID \
|
||||||
# ==============================================================================
|
-efidisk0 ${DISK0_REF}${FORMAT} \
|
||||||
# DISK IMPORT
|
-scsi0 ${DISK1_REF},${DISK_CACHE}${THIN}size=${DISK_SIZE} \
|
||||||
# ==============================================================================
|
-boot order=scsi0 \
|
||||||
msg_info "Importing disk into storage ($STORAGE)"
|
-serial0 socket >/dev/null
|
||||||
|
qm resize $VMID scsi0 8G >/dev/null
|
||||||
if qm disk import --help >/dev/null 2>&1; then
|
|
||||||
IMPORT_CMD=(qm disk import)
|
|
||||||
else
|
|
||||||
IMPORT_CMD=(qm importdisk)
|
|
||||||
fi
|
|
||||||
|
|
||||||
IMPORT_OUT="$("${IMPORT_CMD[@]}" "$VMID" "$WORK_FILE" "$STORAGE" ${DISK_IMPORT:-} 2>&1 || true)"
|
|
||||||
DISK_REF_IMPORTED="$(printf '%s\n' "$IMPORT_OUT" | sed -n "s/.*successfully imported disk '\([^']\+\)'.*/\1/p" | tr -d "\r\"'")"
|
|
||||||
[[ -z "$DISK_REF_IMPORTED" ]] && DISK_REF_IMPORTED="$(pvesm list "$STORAGE" | awk -v id="$VMID" '$5 ~ ("vm-"id"-disk-") {print $1":"$5}' | sort | tail -n1)"
|
|
||||||
[[ -z "$DISK_REF_IMPORTED" ]] && {
|
|
||||||
msg_error "Unable to determine imported disk reference."
|
|
||||||
echo "$IMPORT_OUT"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_ok "Imported disk (${CL}${BL}${DISK_REF_IMPORTED}${CL})"
|
|
||||||
|
|
||||||
# Clean up work file
|
|
||||||
rm -f "$WORK_FILE"
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# VM CONFIGURATION
|
|
||||||
# ==============================================================================
|
|
||||||
msg_info "Attaching EFI and root disk"
|
|
||||||
|
|
||||||
qm set "$VMID" \
|
|
||||||
--efidisk0 "${STORAGE}:0,efitype=4m" \
|
|
||||||
--scsi0 "${DISK_REF_IMPORTED},${DISK_CACHE}${THIN%,}" \
|
|
||||||
--boot order=scsi0 \
|
|
||||||
--serial0 socket >/dev/null
|
|
||||||
|
|
||||||
qm set $VMID --agent enabled=1 >/dev/null
|
qm set $VMID --agent enabled=1 >/dev/null
|
||||||
|
|
||||||
msg_ok "Attached EFI and root disk"
|
DESCRIPTION=$(
|
||||||
|
cat <<EOF
|
||||||
|
<div align='center'>
|
||||||
|
<a href='https://Helper-Scripts.com' target='_blank' rel='noopener noreferrer'>
|
||||||
|
<img src='https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png' alt='Logo' style='width:81px;height:112px;'/>
|
||||||
|
</a>
|
||||||
|
|
||||||
# Set VM description
|
<h2 style='font-size: 24px; margin: 20px 0;'>Docker VM</h2>
|
||||||
set_description
|
|
||||||
|
|
||||||
# Cloud-Init configuration
|
<p style='margin: 16px 0;'>
|
||||||
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
<a href='https://ko-fi.com/community_scripts' target='_blank' rel='noopener noreferrer'>
|
||||||
msg_info "Configuring Cloud-Init"
|
<img src='https://img.shields.io/badge/☕-Buy us a coffee-blue' alt='spend Coffee' />
|
||||||
setup_cloud_init "$VMID" "$STORAGE" "$HN" "yes"
|
</a>
|
||||||
msg_ok "Cloud-Init configured"
|
</p>
|
||||||
fi
|
|
||||||
|
|
||||||
# Start VM
|
<span style='margin: 0 10px;'>
|
||||||
|
<i class="fa fa-github fa-fw" style="color: #f5f5f5;"></i>
|
||||||
|
<a href='https://github.com/community-scripts/ProxmoxVE' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>GitHub</a>
|
||||||
|
</span>
|
||||||
|
<span style='margin: 0 10px;'>
|
||||||
|
<i class="fa fa-comments fa-fw" style="color: #f5f5f5;"></i>
|
||||||
|
<a href='https://github.com/community-scripts/ProxmoxVE/discussions' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Discussions</a>
|
||||||
|
</span>
|
||||||
|
<span style='margin: 0 10px;'>
|
||||||
|
<i class="fa fa-exclamation-circle fa-fw" style="color: #f5f5f5;"></i>
|
||||||
|
<a href='https://github.com/community-scripts/ProxmoxVE/issues' target='_blank' rel='noopener noreferrer' style='text-decoration: none; color: #00617f;'>Issues</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
qm set $VMID -description "$DESCRIPTION" >/dev/null
|
||||||
|
|
||||||
|
msg_ok "Created a Docker VM ${CL}${BL}(${HN})"
|
||||||
if [ "$START_VM" == "yes" ]; then
|
if [ "$START_VM" == "yes" ]; then
|
||||||
msg_info "Starting Docker VM"
|
msg_info "Starting Docker VM"
|
||||||
qm start $VMID >/dev/null 2>&1
|
qm start $VMID
|
||||||
msg_ok "Started Docker VM"
|
msg_ok "Started Docker VM"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# FINAL OUTPUT
|
|
||||||
# ==============================================================================
|
|
||||||
VM_IP=""
|
|
||||||
if [ "$START_VM" == "yes" ]; then
|
|
||||||
set +e
|
|
||||||
for i in {1..10}; do
|
|
||||||
VM_IP=$(qm guest cmd "$VMID" network-get-interfaces 2>/dev/null |
|
|
||||||
jq -r '.[] | select(.name != "lo") | ."ip-addresses"[]? | select(."ip-address-type" == "ipv4") | ."ip-address"' 2>/dev/null |
|
|
||||||
grep -v "^127\." | head -1) || true
|
|
||||||
[ -n "$VM_IP" ] && break
|
|
||||||
sleep 3
|
|
||||||
done
|
|
||||||
set -e
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\n${INFO}${BOLD}${GN}Docker VM Configuration Summary:${CL}"
|
|
||||||
echo -e "${TAB}${DGN}VM ID: ${BGN}${VMID}${CL}"
|
|
||||||
echo -e "${TAB}${DGN}Hostname: ${BGN}${HN}${CL}"
|
|
||||||
echo -e "${TAB}${DGN}OS: ${BGN}${OS_DISPLAY}${CL}"
|
|
||||||
[ -n "$VM_IP" ] && echo -e "${TAB}${DGN}IP Address: ${BGN}${VM_IP}${CL}"
|
|
||||||
|
|
||||||
if [ "$DOCKER_PREINSTALLED" = "yes" ]; then
|
|
||||||
echo -e "${TAB}${DGN}Docker: ${BGN}Pre-installed (via get.docker.com)${CL}"
|
|
||||||
else
|
|
||||||
echo -e "${TAB}${DGN}Docker: ${BGN}Installing on first boot${CL}"
|
|
||||||
echo -e "${TAB}${YW}⚠️ Wait 2-3 minutes for installation to complete${CL}"
|
|
||||||
echo -e "${TAB}${YW}⚠️ Check progress: ${BL}cat /var/log/install-docker.log${CL}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$USE_CLOUD_INIT" = "yes" ]; then
|
|
||||||
display_cloud_init_info "$VMID" "$HN" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
post_update_to_api "done" "none"
|
post_update_to_api "done" "none"
|
||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
____ __
|
|
||||||
/ __ \____ _____/ /_____ _____
|
|
||||||
/ / / / __ \/ ___/ //_/ _ \/ ___/
|
|
||||||
/ /_/ / /_/ / /__/ ,< / __/ /
|
|
||||||
/_____/\____/\___/_/|_|\___/_/
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user