mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-07-20 21:05:06 +02:00
Compare commits
171 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d3b02777dc | |||
| 6f04a9787f | |||
| b889e8d05e | |||
| bd834f690a | |||
| a5a0b90643 | |||
| aa8352bfd5 | |||
| 3b8f57672e | |||
| 9028029ea0 | |||
| 0d3ee851d0 | |||
| 6408653564 | |||
| e925e29966 | |||
| 8505d28429 | |||
| f15e9c320b | |||
| 5b4e526329 | |||
| a61dc9c585 | |||
| f8cc69e244 | |||
| 1dba4eb2ee | |||
| fa9377cd45 | |||
| b6a8ca1a3a | |||
| 2c13cb6a38 | |||
| beeb497519 | |||
| 9ea82fa992 | |||
| d6cd545e98 | |||
| 31b7024997 | |||
| a6a608614f | |||
| 3042cd5cee | |||
| 026fd25e7a | |||
| e1ce55b547 | |||
| d81c9f3ed2 | |||
| b098501a37 | |||
| a1058256be | |||
| e425d9c02c | |||
| 0dbea508d3 | |||
| 787e27a4ac | |||
| 8f0083850e | |||
| 8f9c4eb13b | |||
| beacf9e43a | |||
| b2898debce | |||
| 8c7da1e036 | |||
| bbd5a3f522 | |||
| c07dc4a4c3 | |||
| e7f6a6d4cd | |||
| 3242b9a2d1 | |||
| 38ed344e0a | |||
| 658aad229a | |||
| eb5a5b2cb7 | |||
| 09c85021fc | |||
| 7f1b0ead93 | |||
| c24bba00de | |||
| 3f7228f9c6 | |||
| c0a327dad8 | |||
| 78990277f2 | |||
| 0b15e19500 | |||
| f75b0a8b0e | |||
| b5360882c9 | |||
| b2936ff9ce | |||
| 29552c6e2e | |||
| d2ecb9f44c | |||
| ec3c25c5f5 | |||
| b1259e3749 | |||
| ff192c4530 | |||
| e72f335b46 | |||
| 13d7bf6c78 | |||
| 2ab4a31dd1 | |||
| e7557c2355 | |||
| 79cee47df6 | |||
| b4dcdd4472 | |||
| 8f2b68ed7e | |||
| 853f5e868a | |||
| 7c7d40cfe3 | |||
| 373ae7e143 | |||
| abc31499a2 | |||
| 7bf45d5b66 | |||
| f119e8782a | |||
| 271df3c3fb | |||
| c991a7eccf | |||
| 5d4eff0493 | |||
| 3f90af2a21 | |||
| 55002839fb | |||
| a51e1f37f5 | |||
| 8655282c2d | |||
| e15db754a6 | |||
| 772430de7e | |||
| 04a84f5052 | |||
| 12dec08523 | |||
| 775f1a98c2 | |||
| 6d6d66eec6 | |||
| 9bb99c59c5 | |||
| d122341a47 | |||
| b9f26d66ed | |||
| c44789f5f6 | |||
| 5144f8d0cc | |||
| d23a2e64e7 | |||
| b36ad5c3a2 | |||
| 74a233b8b9 | |||
| 66eff7ee87 | |||
| 812267aedd | |||
| c759617379 | |||
| 75a1da273f | |||
| c99768869d | |||
| c52a69e8e5 | |||
| 2afea1239c | |||
| 07e31eb5bc | |||
| 80c4b04d83 | |||
| ed29bb6f62 | |||
| a5b839f91f | |||
| d4d482746b | |||
| 2bffa47924 | |||
| 108c9dcf43 | |||
| 0f37abff3c | |||
| 670d972cc1 | |||
| 9f8bc4b03d | |||
| 817ee347c7 | |||
| bb4e35f988 | |||
| 254e720b4f | |||
| 9055f4b34e | |||
| 3f5453b609 | |||
| e812206116 | |||
| 7f430e15bb | |||
| 9c586b94ab | |||
| ab3c9be482 | |||
| 103b420e30 | |||
| c039ab2e62 | |||
| 63f219f14f | |||
| 09ec7b3203 | |||
| 55ab97a020 | |||
| b7a002cae4 | |||
| 171b954c7c | |||
| 6f76cc043e | |||
| 5d57c328fb | |||
| da62724407 | |||
| dbe2c9eb97 | |||
| 3c5a848d7d | |||
| 1e3d0dedb3 | |||
| bcaadc4dbd | |||
| 666bdbd8c8 | |||
| 7596b95517 | |||
| 1521e131b5 | |||
| 734bb75b12 | |||
| d6d8d20c76 | |||
| 649e66ed2b | |||
| 81bb9c7d71 | |||
| ca082aedf0 | |||
| 1e7667e5f8 | |||
| f828e629b5 | |||
| 4a98e86db1 | |||
| 37b5242c21 | |||
| a1333222a8 | |||
| 12949bce6c | |||
| fae0aacf6d | |||
| fd20ed1bfc | |||
| eb3fb749df | |||
| f7fdf419b1 | |||
| 0a7bd0f37e | |||
| 48483c63b8 | |||
| 962c040f44 | |||
| c0b2c906fa | |||
| 96100474cc | |||
| 76335cefe8 | |||
| 8fbb4b1988 | |||
| c481c3e24e | |||
| dcd1eefdd4 | |||
| f1b2bd0486 | |||
| 42f6b3ccdd | |||
| ed9c80f805 | |||
| 0906341e95 | |||
| 618d578c35 | |||
| f137f8c894 | |||
| 98bedb6ccd | |||
| b958252441 | |||
| 92c4fb45a9 |
+40
-7
@@ -12,13 +12,17 @@ body:
|
|||||||
Requests may be closed if the application is out of scope, abandoned, too new, not publicly verifiable, or not suitable for a reliable Proxmox VE Helper-Scripts integration.
|
Requests may be closed if the application is out of scope, abandoned, too new, not publicly verifiable, or not suitable for a reliable Proxmox VE Helper-Scripts integration.
|
||||||
|
|
||||||
General requirements:
|
General requirements:
|
||||||
- The application should be self-hosted.
|
- The application must be self-hosted.
|
||||||
- The project should have an official public source repository.
|
- The project must have an official public source repository.
|
||||||
- The project should provide official releases, tags, or release tarballs.
|
- The project must provide official releases, tags, or release tarballs.
|
||||||
- The project should be actively maintained.
|
- The project must be actively maintained.
|
||||||
- The project should generally have at least 1,000 stars or a comparable public adoption signal.
|
- The official source repository must have at least 1,000 stars.
|
||||||
- The latest official release or tag should not be older than 6 months.
|
- The latest official release or tag must not be older than 6 months.
|
||||||
- The project itself should be at least 6 months old.
|
- The project itself must be at least 6 months old.
|
||||||
|
|
||||||
|
Projects that do not meet these requirements may be closed without further evaluation.
|
||||||
|
|
||||||
|
Exceptions to the 1,000-star requirement are rare and require a clearly verifiable, significant public adoption signal.
|
||||||
|
|
||||||
- type: input
|
- type: input
|
||||||
id: application-name
|
id: application-name
|
||||||
@@ -47,6 +51,35 @@ body:
|
|||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
## ⚠️ Project Eligibility
|
||||||
|
|
||||||
|
Before continuing, verify that the requested project meets the minimum requirements below.
|
||||||
|
|
||||||
|
**Projects with fewer than 1,000 stars are generally not eligible for a script request.**
|
||||||
|
|
||||||
|
Exceptions are only considered where there is a clearly verifiable, significant public adoption signal.
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: repository-stars
|
||||||
|
attributes:
|
||||||
|
label: Repository Stars
|
||||||
|
description: Enter the current number of stars of the official source repository.
|
||||||
|
placeholder: "e.g., 15,000"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: checkboxes
|
||||||
|
id: minimum-stars
|
||||||
|
attributes:
|
||||||
|
label: Minimum Adoption Requirement
|
||||||
|
description: Confirm that you have verified the project's public adoption.
|
||||||
|
options:
|
||||||
|
- label: The official source repository has at least 1,000 stars.
|
||||||
|
required: true
|
||||||
|
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: app-description
|
id: app-description
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
Generated
+261
@@ -1,3 +1,264 @@
|
|||||||
|
## 2026-07-18
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- core: add configurable host CA inheritance during bootstrap [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15840](https://github.com/community-scripts/ProxmoxVE/pull/15840))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- tools.func: Safe Delete Directorys & Update PYTHON_VERSION with setup_uv [@MickLesk](https://github.com/MickLesk) ([#15870](https://github.com/community-scripts/ProxmoxVE/pull/15870))
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- [tools.update-lxcs] feat: optional reporting success/failures to heathchecks.io (or others) [@sir106](https://github.com/sir106) ([#15701](https://github.com/community-scripts/ProxmoxVE/pull/15701))
|
||||||
|
|
||||||
|
## 2026-07-17
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Invidious ([#15824](https://github.com/community-scripts/ProxmoxVE/pull/15824))
|
||||||
|
- OxiCloud ([#15823](https://github.com/community-scripts/ProxmoxVE/pull/15823))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- webtrees: initialize database schema before admin user creation [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15837](https://github.com/community-scripts/ProxmoxVE/pull/15837))
|
||||||
|
- Fix DocuSeal missing Leptonica deps on install and update [@Copilot](https://github.com/Copilot) ([#15858](https://github.com/community-scripts/ProxmoxVE/pull/15858))
|
||||||
|
- apache-guacamole: detect installed extensions during update [@TowyTowy](https://github.com/TowyTowy) ([#15841](https://github.com/community-scripts/ProxmoxVE/pull/15841))
|
||||||
|
- CLIProxyAPI: fix update deleting config.yaml [@austinpilz](https://github.com/austinpilz) ([#15834](https://github.com/community-scripts/ProxmoxVE/pull/15834))
|
||||||
|
- esphome: install libusb-1.0-0 for ESP-IDF native builds [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15838](https://github.com/community-scripts/ProxmoxVE/pull/15838))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- AFFiNE: Bump to 0.27.0 [@MickLesk](https://github.com/MickLesk) ([#15848](https://github.com/community-scripts/ProxmoxVE/pull/15848))
|
||||||
|
- n8n: unpin / use latest release [@MickLesk](https://github.com/MickLesk) ([#15817](https://github.com/community-scripts/ProxmoxVE/pull/15817))
|
||||||
|
- Pin Opencloud to v7.3.0 [@vhsdream](https://github.com/vhsdream) ([#15826](https://github.com/community-scripts/ProxmoxVE/pull/15826))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- SFTPGo: Update APT Repo & Re-Enable Script [@MickLesk](https://github.com/MickLesk) ([#15829](https://github.com/community-scripts/ProxmoxVE/pull/15829))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- tools.func: enhance rbenv with profile updates / bundle in bashrc [@MickLesk](https://github.com/MickLesk) ([#15822](https://github.com/community-scripts/ProxmoxVE/pull/15822))
|
||||||
|
- feat(build.func): notify users when already on a pinned script version [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15819](https://github.com/community-scripts/ProxmoxVE/pull/15819))
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- MongoDB: Implement kernel version check and patch [@MickLesk](https://github.com/MickLesk) ([#15821](https://github.com/community-scripts/ProxmoxVE/pull/15821))
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- update-lxc: autoremove and autoclean after apt full-upgrade [@soupy-boy](https://github.com/soupy-boy) ([#15831](https://github.com/community-scripts/ProxmoxVE/pull/15831))
|
||||||
|
|
||||||
|
## 2026-07-16
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Sync-In ([#15812](https://github.com/community-scripts/ProxmoxVE/pull/15812))
|
||||||
|
- Beaverhabits ([#15813](https://github.com/community-scripts/ProxmoxVE/pull/15813))
|
||||||
|
- Notediscovery ([#15811](https://github.com/community-scripts/ProxmoxVE/pull/15811))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Pin Immich to v3.0.3 [@vhsdream](https://github.com/vhsdream) ([#15790](https://github.com/community-scripts/ProxmoxVE/pull/15790))
|
||||||
|
|
||||||
|
## 2026-07-15
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Nexterm ([#15688](https://github.com/community-scripts/ProxmoxVE/pull/15688))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- 2fauth: minor fixes for 8.0.0 [@MickLesk](https://github.com/MickLesk) ([#15795](https://github.com/community-scripts/ProxmoxVE/pull/15795))
|
||||||
|
- SnapOtter: refactor update process to prebuild [@MickLesk](https://github.com/MickLesk) ([#15797](https://github.com/community-scripts/ProxmoxVE/pull/15797))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- tools.func: default Docker setup to official repo [@MickLesk](https://github.com/MickLesk) ([#15794](https://github.com/community-scripts/ProxmoxVE/pull/15794))
|
||||||
|
|
||||||
|
## 2026-07-14
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Grav ([#15773](https://github.com/community-scripts/ProxmoxVE/pull/15773))
|
||||||
|
- Yuvomi ([#15772](https://github.com/community-scripts/ProxmoxVE/pull/15772))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Lychee: Preserve uploads and ownership during update [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15768](https://github.com/community-scripts/ProxmoxVE/pull/15768))
|
||||||
|
- Wanderer: Clean deploy and install plugins for v0.20.0 update [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15759](https://github.com/community-scripts/ProxmoxVE/pull/15759))
|
||||||
|
- FileFlows: Handle update API 401, force update, and Node install [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15766](https://github.com/community-scripts/ProxmoxVE/pull/15766))
|
||||||
|
- BirdNET-Go: Match new upstream release asset naming [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15758](https://github.com/community-scripts/ProxmoxVE/pull/15758))
|
||||||
|
- [Upstream Fix] Immich: Fix loader priority [@vhsdream](https://github.com/vhsdream) ([#15755](https://github.com/community-scripts/ProxmoxVE/pull/15755))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Bump OpenCloud version to v7.2.2 [@MickLesk](https://github.com/MickLesk) ([#15769](https://github.com/community-scripts/ProxmoxVE/pull/15769))
|
||||||
|
- Silverbullet: Add optional Runtime API install via Chromium [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15761](https://github.com/community-scripts/ProxmoxVE/pull/15761))
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- Pangolin: Bump to 1.20.0 | BREAKING: Switch to PostgreSQL [@MickLesk](https://github.com/MickLesk) ([#15682](https://github.com/community-scripts/ProxmoxVE/pull/15682))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- AFFiNE: Pin to v0.26.3 [@MickLesk](https://github.com/MickLesk) ([#15782](https://github.com/community-scripts/ProxmoxVE/pull/15782))
|
||||||
|
|
||||||
|
## 2026-07-13
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- LeafWiki ([#15748](https://github.com/community-scripts/ProxmoxVE/pull/15748))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix(hyperion): keep service running after container reboot [@TowyTowy](https://github.com/TowyTowy) ([#15653](https://github.com/community-scripts/ProxmoxVE/pull/15653))
|
||||||
|
- Change sign-in URL to admin URL in affine.sh [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15741](https://github.com/community-scripts/ProxmoxVE/pull/15741))
|
||||||
|
- immich: use actual PostgreSQL version for VectorChord package lookup [@mnavon](https://github.com/mnavon) ([#15705](https://github.com/community-scripts/ProxmoxVE/pull/15705))
|
||||||
|
- fix storyteller release selection for stable web tags [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15736](https://github.com/community-scripts/ProxmoxVE/pull/15736))
|
||||||
|
- Docmost: Fix update procedure [@MickLesk](https://github.com/MickLesk) ([#15732](https://github.com/community-scripts/ProxmoxVE/pull/15732))
|
||||||
|
- fix(shinobi): remove obsolete --unsafe-perm npm flag [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15730](https://github.com/community-scripts/ProxmoxVE/pull/15730))
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- reitti: update to v5 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15635](https://github.com/community-scripts/ProxmoxVE/pull/15635))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix(build.func): parse script status without jq dependency [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15729](https://github.com/community-scripts/ProxmoxVE/pull/15729))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- tools.func: some improvements (sql injection / command injection / guard) [@MickLesk](https://github.com/MickLesk) ([#15661](https://github.com/community-scripts/ProxmoxVE/pull/15661))
|
||||||
|
|
||||||
|
## 2026-07-12
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- AFFiNE ([#15690](https://github.com/community-scripts/ProxmoxVE/pull/15690))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- Immich: Bump version to 3.0.2 [@vhsdream](https://github.com/vhsdream) ([#15668](https://github.com/community-scripts/ProxmoxVE/pull/15668))
|
||||||
|
|
||||||
|
### ❔ Uncategorized
|
||||||
|
|
||||||
|
- fix(immich): correct Python indentation error in ct/immich.sh heredoc patch [@Copilot](https://github.com/Copilot) ([#15723](https://github.com/community-scripts/ProxmoxVE/pull/15723))
|
||||||
|
|
||||||
|
## 2026-07-11
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- LocalAGI ([#15687](https://github.com/community-scripts/ProxmoxVE/pull/15687))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- fix(adventurelog): allow pnpm build scripts so install/update doesn't abort [@TowyTowy](https://github.com/TowyTowy) ([#15681](https://github.com/community-scripts/ProxmoxVE/pull/15681))
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix(fileflows): install .NET 10 ASP.NET Core Runtime to match current release [@TowyTowy](https://github.com/TowyTowy) ([#15702](https://github.com/community-scripts/ProxmoxVE/pull/15702))
|
||||||
|
- Fix spacing on VLAN Input Box in haos-vm.sh [@pumrum](https://github.com/pumrum) ([#15696](https://github.com/community-scripts/ProxmoxVE/pull/15696))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- [tools.func]: Add function to handle deployment via GitLab release tags [@tremor021](https://github.com/tremor021) ([#15641](https://github.com/community-scripts/ProxmoxVE/pull/15641))
|
||||||
|
|
||||||
|
## 2026-07-10
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Squid ([#15605](https://github.com/community-scripts/ProxmoxVE/pull/15605))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Adapt to new artifact filename format for pocket id [@wollew](https://github.com/wollew) ([#15689](https://github.com/community-scripts/ProxmoxVE/pull/15689))
|
||||||
|
- Fireshare: Fix for install and upgrade to v1.7.3 [@tremor021](https://github.com/tremor021) ([#15673](https://github.com/community-scripts/ProxmoxVE/pull/15673))
|
||||||
|
- Endurain: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15674](https://github.com/community-scripts/ProxmoxVE/pull/15674))
|
||||||
|
|
||||||
|
## 2026-07-09
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- fix(pihole): repair Unbound DNS-over-TLS (DoT) forwarding config [@TowyTowy](https://github.com/TowyTowy) ([#15654](https://github.com/community-scripts/ProxmoxVE/pull/15654))
|
||||||
|
|
||||||
|
## 2026-07-08
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Opencloud: Bump version to 7.2.1 [@vhsdream](https://github.com/vhsdream) ([#15655](https://github.com/community-scripts/ProxmoxVE/pull/15655))
|
||||||
|
- BabyBuddy: Harden update script [@MickLesk](https://github.com/MickLesk) ([#15642](https://github.com/community-scripts/ProxmoxVE/pull/15642))
|
||||||
|
|
||||||
|
## 2026-07-07
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Forgejo-Runner ([#15046](https://github.com/community-scripts/ProxmoxVE/pull/15046))
|
||||||
|
|
||||||
|
## 2026-07-06
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- Fix alignment in various ct end messages [@tremor021](https://github.com/tremor021) ([#15632](https://github.com/community-scripts/ProxmoxVE/pull/15632))
|
||||||
|
- Immich: Update libvips to 8.18.4 [@vhsdream](https://github.com/vhsdream) ([#15619](https://github.com/community-scripts/ProxmoxVE/pull/15619))
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Wizarr: Build JS and CSS static assets [@vhsdream](https://github.com/vhsdream) ([#15634](https://github.com/community-scripts/ProxmoxVE/pull/15634))
|
||||||
|
- RustDesk Server: Update URL format in rustdeskserver.sh [@tremor021](https://github.com/tremor021) ([#15626](https://github.com/community-scripts/ProxmoxVE/pull/15626))
|
||||||
|
- attempt to port docker-vm to support arm64 [@asylumexp](https://github.com/asylumexp) ([#15611](https://github.com/community-scripts/ProxmoxVE/pull/15611))
|
||||||
|
- fix(plane): don't clobber global app var, breaking /usr/bin/update [@asylumexp](https://github.com/asylumexp) ([#15612](https://github.com/community-scripts/ProxmoxVE/pull/15612))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- cliproxyapi: point setup message at /management.html [@austinpilz](https://github.com/austinpilz) ([#15628](https://github.com/community-scripts/ProxmoxVE/pull/15628))
|
||||||
|
|
||||||
|
### 🗑️ Deleted Scripts
|
||||||
|
|
||||||
|
- Remove: FlowiseAI [@MickLesk](https://github.com/MickLesk) ([#15624](https://github.com/community-scripts/ProxmoxVE/pull/15624))
|
||||||
|
|
||||||
|
## 2026-07-05
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- excalidash ([#15604](https://github.com/community-scripts/ProxmoxVE/pull/15604))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix: homarr: cli [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15603](https://github.com/community-scripts/ProxmoxVE/pull/15603))
|
||||||
|
- immich: vacuum smart_search/face_search before VectorChord bump [@irishpadres](https://github.com/irishpadres) ([#15607](https://github.com/community-scripts/ProxmoxVE/pull/15607))
|
||||||
|
|
||||||
## 2026-07-04
|
## 2026-07-04
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|||||||
+163
@@ -0,0 +1,163 @@
|
|||||||
|
name: Close PRs Missing Template
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request_target:
|
||||||
|
branches: ["main"]
|
||||||
|
types: [opened, edited, reopened, synchronize, labeled]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate-pr-template:
|
||||||
|
if: github.repository == 'community-scripts/ProxmoxVE'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
issues: write
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- name: Close PR if it does not follow the PR template
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const pr = context.payload.pull_request;
|
||||||
|
const prNumber = pr.number;
|
||||||
|
const author = pr.user.login;
|
||||||
|
const owner = context.repo.owner;
|
||||||
|
const repo = context.repo.repo;
|
||||||
|
|
||||||
|
const allowedBots = [
|
||||||
|
"push-app-to-main[bot]",
|
||||||
|
"push-app-to-main",
|
||||||
|
"community-scripts-pr-app",
|
||||||
|
"github-actions[bot]",
|
||||||
|
"dependabot[bot]",
|
||||||
|
];
|
||||||
|
|
||||||
|
if (allowedBots.includes(author) || author.endsWith("[bot]")) {
|
||||||
|
core.info(`PR #${prNumber} by bot "${author}" — skipping template validation.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const association = pr.author_association;
|
||||||
|
const exemptAssociations = ["OWNER", "MEMBER", "COLLABORATOR"];
|
||||||
|
if (exemptAssociations.includes(association)) {
|
||||||
|
core.info(`PR #${prNumber} by ${association} "${author}" — skipping template validation.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const labels = pr.labels.map((label) => label.name);
|
||||||
|
const skipLabels = ["automated pr", "keep open"];
|
||||||
|
|
||||||
|
if (skipLabels.some((label) => labels.includes(label))) {
|
||||||
|
core.info(`PR #${prNumber} has a skip label (${labels.join(", ")}) — skipping template validation.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pr.draft) {
|
||||||
|
core.info(`PR #${prNumber} is a draft — skipping template validation.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = pr.body || "";
|
||||||
|
const failures = [];
|
||||||
|
|
||||||
|
const requiredSections = [
|
||||||
|
"## ✍️ Description",
|
||||||
|
"## ✅ Prerequisites",
|
||||||
|
"## 🛠️ Type of Change",
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const section of requiredSections) {
|
||||||
|
if (!body.includes(section)) {
|
||||||
|
failures.push(`Missing required section: \`${section}\``);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const descriptionMatch = body.match(
|
||||||
|
/## ✍️ Description\s*\n+([\s\S]*?)(?=\n## )/i
|
||||||
|
);
|
||||||
|
const description = (descriptionMatch?.[1] || "").trim();
|
||||||
|
if (!description) {
|
||||||
|
failures.push("The **Description** section is empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const prerequisiteCheckboxes = [
|
||||||
|
"**Self-review completed**",
|
||||||
|
"**Tested thoroughly**",
|
||||||
|
"**No security risks**",
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const checkbox of prerequisiteCheckboxes) {
|
||||||
|
const escaped = checkbox.replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1");
|
||||||
|
const regex = new RegExp(`- \\[(x|X)\\]\\s*${escaped}`, "i");
|
||||||
|
if (!regex.test(body)) {
|
||||||
|
failures.push(`Prerequisite not checked: ${checkbox}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const typeOfChangeCheckboxes = [
|
||||||
|
"🐞 **Bug fix**",
|
||||||
|
"✨ **New feature**",
|
||||||
|
"💥 **Breaking change**",
|
||||||
|
"🆕 **New script**",
|
||||||
|
"🌍 **Website update**",
|
||||||
|
"🔧 **Refactoring / Code Cleanup**",
|
||||||
|
"📝 **Documentation update**",
|
||||||
|
];
|
||||||
|
|
||||||
|
const hasTypeChecked = typeOfChangeCheckboxes.some((checkbox) => {
|
||||||
|
const escaped = checkbox.replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1");
|
||||||
|
const regex = new RegExp(`- \\[(x|X)\\]\\s*${escaped}`, "i");
|
||||||
|
return regex.test(body);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!hasTypeChecked) {
|
||||||
|
failures.push("At least one **Type of Change** checkbox must be checked.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures.length === 0) {
|
||||||
|
core.info(`PR #${prNumber} follows the PR template.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
core.info(`Closing PR #${prNumber} — template validation failed.`);
|
||||||
|
|
||||||
|
const templateUrl =
|
||||||
|
"https://github.com/community-scripts/ProxmoxVE/blob/main/.github/pull_request_template.md";
|
||||||
|
const failureList = failures.map((item) => `- ${item}`).join("\n");
|
||||||
|
|
||||||
|
const comment = [
|
||||||
|
`👋 Hi @${author},`,
|
||||||
|
``,
|
||||||
|
`This pull request was closed because it does not follow the [PR template](${templateUrl}).`,
|
||||||
|
``,
|
||||||
|
`Please fix the following and open a new PR (or reopen this one after updating the description):`,
|
||||||
|
``,
|
||||||
|
failureList,
|
||||||
|
``,
|
||||||
|
`> Use the template sections, fill in the description, check all prerequisite boxes, and select at least one type of change.`,
|
||||||
|
``,
|
||||||
|
`Maintainers can add the \`keep open\` label to exempt a PR from this check.`,
|
||||||
|
``,
|
||||||
|
`Thank you for contributing! 🙏`,
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: prNumber,
|
||||||
|
body: comment,
|
||||||
|
});
|
||||||
|
|
||||||
|
await github.rest.pulls.update({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
pull_number: prNumber,
|
||||||
|
state: "closed",
|
||||||
|
});
|
||||||
|
|
||||||
|
await github.rest.issues.addLabels({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: prNumber,
|
||||||
|
labels: ["missing pr template"],
|
||||||
|
});
|
||||||
+24
@@ -91,6 +91,30 @@ jobs:
|
|||||||
let skipped = 0;
|
let skipped = 0;
|
||||||
|
|
||||||
for (const branch of candidates) {
|
for (const branch of candidates) {
|
||||||
|
// A branch name can be reused after an earlier PR was merged. Never delete a
|
||||||
|
// branch while it is the head of a current open PR, even if it is also a
|
||||||
|
// candidate from an older merged PR.
|
||||||
|
try {
|
||||||
|
const { data: openPrs } = await github.rest.pulls.list({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
state: "open",
|
||||||
|
head: `${owner}:${branch}`,
|
||||||
|
per_page: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (openPrs.length > 0) {
|
||||||
|
console.log(`Skipped "${branch}" (head of open PR #${openPrs[0].number})`);
|
||||||
|
skipped++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Do not risk deleting a branch if GitHub cannot confirm it has no open PR.
|
||||||
|
console.log(`Failed to check open PRs for "${branch}": ${error.message}`);
|
||||||
|
skipped++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Confirm the branch still exists and isn't protected.
|
// Confirm the branch still exists and isn't protected.
|
||||||
let branchData;
|
let branchData;
|
||||||
try {
|
try {
|
||||||
|
|||||||
+254
-256
@@ -71,6 +71,12 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -87,7 +93,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h4>July (4 entries)</h4></summary>
|
<summary><h4>July (18 entries)</h4></summary>
|
||||||
|
|
||||||
[View July 2026 Changelog](.github/changelogs/2026/07.md)
|
[View July 2026 Changelog](.github/changelogs/2026/07.md)
|
||||||
|
|
||||||
@@ -499,6 +505,252 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## 2026-07-20
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- RomM: use backup helpers in update / clear folder [@MickLesk](https://github.com/MickLesk) ([#15915](https://github.com/community-scripts/ProxmoxVE/pull/15915))
|
||||||
|
- fix: vikunja: asset selection [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15929](https://github.com/community-scripts/ProxmoxVE/pull/15929))
|
||||||
|
- Zammad : bind Elasticsearch to 127.0.0.1 [@MickLesk](https://github.com/MickLesk) ([#15909](https://github.com/community-scripts/ProxmoxVE/pull/15909))
|
||||||
|
- Omada: fix package version extraction [@MickLesk](https://github.com/MickLesk) ([#15908](https://github.com/community-scripts/ProxmoxVE/pull/15908))
|
||||||
|
- fix(wanderer): use PocketBase-relative plugin symlink in unprivileged LXC [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15911](https://github.com/community-scripts/ProxmoxVE/pull/15911))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- AFFiNE: Bump version to v0.27.2 [@MickLesk](https://github.com/MickLesk) ([#15930](https://github.com/community-scripts/ProxmoxVE/pull/15930))
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- Gotify: Migration to v3 [@MickLesk](https://github.com/MickLesk) ([#15912](https://github.com/community-scripts/ProxmoxVE/pull/15912))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- core: refactor to single-reporter telemetry and better error_handling [@MickLesk](https://github.com/MickLesk) ([#15933](https://github.com/community-scripts/ProxmoxVE/pull/15933))
|
||||||
|
- tools.func: add support for extracting 7z archives [@MickLesk](https://github.com/MickLesk) ([#15919](https://github.com/community-scripts/ProxmoxVE/pull/15919))
|
||||||
|
- Meilisearch : use dumpless Meilisearch upgrades [@MickLesk](https://github.com/MickLesk) ([#15921](https://github.com/community-scripts/ProxmoxVE/pull/15921))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- core: Improve GPU detection and mapping logic [@MickLesk](https://github.com/MickLesk) ([#15918](https://github.com/community-scripts/ProxmoxVE/pull/15918))
|
||||||
|
|
||||||
|
## 2026-07-19
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- change trek repo to liketrek/TREK [@asylumexp](https://github.com/asylumexp) ([#15893](https://github.com/community-scripts/ProxmoxVE/pull/15893))
|
||||||
|
- update authentik to 2026.5.5 [@thieneret](https://github.com/thieneret) ([#15855](https://github.com/community-scripts/ProxmoxVE/pull/15855))
|
||||||
|
- [FIX] BookOrbit: add missing `restore_backup` during update [@vhsdream](https://github.com/vhsdream) ([#15881](https://github.com/community-scripts/ProxmoxVE/pull/15881))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- tools.func: centralize deploy tail + trap-based tmpdir cleanup [@MickLesk](https://github.com/MickLesk) ([#15872](https://github.com/community-scripts/ProxmoxVE/pull/15872))
|
||||||
|
- Update OPNsense from 26.1 to 26.7 [@tdn131](https://github.com/tdn131) ([#15895](https://github.com/community-scripts/ProxmoxVE/pull/15895))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- Revert "core: add configurable host CA inheritance during bootstrap" [@MickLesk](https://github.com/MickLesk) ([#15886](https://github.com/community-scripts/ProxmoxVE/pull/15886))
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix(build.func): expand glob in SSH key "Scan Folder/Glob" so it can find keys [@TowyTowy](https://github.com/TowyTowy) ([#15873](https://github.com/community-scripts/ProxmoxVE/pull/15873))
|
||||||
|
|
||||||
|
## 2026-07-18
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- core: add configurable host CA inheritance during bootstrap [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15840](https://github.com/community-scripts/ProxmoxVE/pull/15840))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- tools.func: Safe Delete Directorys & Update PYTHON_VERSION with setup_uv [@MickLesk](https://github.com/MickLesk) ([#15870](https://github.com/community-scripts/ProxmoxVE/pull/15870))
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- [tools.update-lxcs] feat: optional reporting success/failures to heathchecks.io (or others) [@sir106](https://github.com/sir106) ([#15701](https://github.com/community-scripts/ProxmoxVE/pull/15701))
|
||||||
|
|
||||||
|
## 2026-07-17
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Invidious ([#15824](https://github.com/community-scripts/ProxmoxVE/pull/15824))
|
||||||
|
- OxiCloud ([#15823](https://github.com/community-scripts/ProxmoxVE/pull/15823))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- webtrees: initialize database schema before admin user creation [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15837](https://github.com/community-scripts/ProxmoxVE/pull/15837))
|
||||||
|
- Fix DocuSeal missing Leptonica deps on install and update [@Copilot](https://github.com/Copilot) ([#15858](https://github.com/community-scripts/ProxmoxVE/pull/15858))
|
||||||
|
- apache-guacamole: detect installed extensions during update [@TowyTowy](https://github.com/TowyTowy) ([#15841](https://github.com/community-scripts/ProxmoxVE/pull/15841))
|
||||||
|
- CLIProxyAPI: fix update deleting config.yaml [@austinpilz](https://github.com/austinpilz) ([#15834](https://github.com/community-scripts/ProxmoxVE/pull/15834))
|
||||||
|
- esphome: install libusb-1.0-0 for ESP-IDF native builds [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15838](https://github.com/community-scripts/ProxmoxVE/pull/15838))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- AFFiNE: Bump to 0.27.0 [@MickLesk](https://github.com/MickLesk) ([#15848](https://github.com/community-scripts/ProxmoxVE/pull/15848))
|
||||||
|
- n8n: unpin / use latest release [@MickLesk](https://github.com/MickLesk) ([#15817](https://github.com/community-scripts/ProxmoxVE/pull/15817))
|
||||||
|
- Pin Opencloud to v7.3.0 [@vhsdream](https://github.com/vhsdream) ([#15826](https://github.com/community-scripts/ProxmoxVE/pull/15826))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- SFTPGo: Update APT Repo & Re-Enable Script [@MickLesk](https://github.com/MickLesk) ([#15829](https://github.com/community-scripts/ProxmoxVE/pull/15829))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- tools.func: enhance rbenv with profile updates / bundle in bashrc [@MickLesk](https://github.com/MickLesk) ([#15822](https://github.com/community-scripts/ProxmoxVE/pull/15822))
|
||||||
|
- feat(build.func): notify users when already on a pinned script version [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15819](https://github.com/community-scripts/ProxmoxVE/pull/15819))
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- MongoDB: Implement kernel version check and patch [@MickLesk](https://github.com/MickLesk) ([#15821](https://github.com/community-scripts/ProxmoxVE/pull/15821))
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- update-lxc: autoremove and autoclean after apt full-upgrade [@soupy-boy](https://github.com/soupy-boy) ([#15831](https://github.com/community-scripts/ProxmoxVE/pull/15831))
|
||||||
|
|
||||||
|
## 2026-07-16
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Sync-In ([#15812](https://github.com/community-scripts/ProxmoxVE/pull/15812))
|
||||||
|
- Beaverhabits ([#15813](https://github.com/community-scripts/ProxmoxVE/pull/15813))
|
||||||
|
- Notediscovery ([#15811](https://github.com/community-scripts/ProxmoxVE/pull/15811))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Pin Immich to v3.0.3 [@vhsdream](https://github.com/vhsdream) ([#15790](https://github.com/community-scripts/ProxmoxVE/pull/15790))
|
||||||
|
|
||||||
|
## 2026-07-15
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Nexterm ([#15688](https://github.com/community-scripts/ProxmoxVE/pull/15688))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- 2fauth: minor fixes for 8.0.0 [@MickLesk](https://github.com/MickLesk) ([#15795](https://github.com/community-scripts/ProxmoxVE/pull/15795))
|
||||||
|
- SnapOtter: refactor update process to prebuild [@MickLesk](https://github.com/MickLesk) ([#15797](https://github.com/community-scripts/ProxmoxVE/pull/15797))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- tools.func: default Docker setup to official repo [@MickLesk](https://github.com/MickLesk) ([#15794](https://github.com/community-scripts/ProxmoxVE/pull/15794))
|
||||||
|
|
||||||
|
## 2026-07-14
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Grav ([#15773](https://github.com/community-scripts/ProxmoxVE/pull/15773))
|
||||||
|
- Yuvomi ([#15772](https://github.com/community-scripts/ProxmoxVE/pull/15772))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Lychee: Preserve uploads and ownership during update [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15768](https://github.com/community-scripts/ProxmoxVE/pull/15768))
|
||||||
|
- Wanderer: Clean deploy and install plugins for v0.20.0 update [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15759](https://github.com/community-scripts/ProxmoxVE/pull/15759))
|
||||||
|
- FileFlows: Handle update API 401, force update, and Node install [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15766](https://github.com/community-scripts/ProxmoxVE/pull/15766))
|
||||||
|
- BirdNET-Go: Match new upstream release asset naming [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15758](https://github.com/community-scripts/ProxmoxVE/pull/15758))
|
||||||
|
- [Upstream Fix] Immich: Fix loader priority [@vhsdream](https://github.com/vhsdream) ([#15755](https://github.com/community-scripts/ProxmoxVE/pull/15755))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Bump OpenCloud version to v7.2.2 [@MickLesk](https://github.com/MickLesk) ([#15769](https://github.com/community-scripts/ProxmoxVE/pull/15769))
|
||||||
|
- Silverbullet: Add optional Runtime API install via Chromium [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15761](https://github.com/community-scripts/ProxmoxVE/pull/15761))
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- Pangolin: Bump to 1.20.0 | BREAKING: Switch to PostgreSQL [@MickLesk](https://github.com/MickLesk) ([#15682](https://github.com/community-scripts/ProxmoxVE/pull/15682))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- AFFiNE: Pin to v0.26.3 [@MickLesk](https://github.com/MickLesk) ([#15782](https://github.com/community-scripts/ProxmoxVE/pull/15782))
|
||||||
|
|
||||||
|
## 2026-07-13
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- LeafWiki ([#15748](https://github.com/community-scripts/ProxmoxVE/pull/15748))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix(hyperion): keep service running after container reboot [@TowyTowy](https://github.com/TowyTowy) ([#15653](https://github.com/community-scripts/ProxmoxVE/pull/15653))
|
||||||
|
- Change sign-in URL to admin URL in affine.sh [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15741](https://github.com/community-scripts/ProxmoxVE/pull/15741))
|
||||||
|
- immich: use actual PostgreSQL version for VectorChord package lookup [@mnavon](https://github.com/mnavon) ([#15705](https://github.com/community-scripts/ProxmoxVE/pull/15705))
|
||||||
|
- fix storyteller release selection for stable web tags [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15736](https://github.com/community-scripts/ProxmoxVE/pull/15736))
|
||||||
|
- Docmost: Fix update procedure [@MickLesk](https://github.com/MickLesk) ([#15732](https://github.com/community-scripts/ProxmoxVE/pull/15732))
|
||||||
|
- fix(shinobi): remove obsolete --unsafe-perm npm flag [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15730](https://github.com/community-scripts/ProxmoxVE/pull/15730))
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- reitti: update to v5 [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15635](https://github.com/community-scripts/ProxmoxVE/pull/15635))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix(build.func): parse script status without jq dependency [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15729](https://github.com/community-scripts/ProxmoxVE/pull/15729))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- tools.func: some improvements (sql injection / command injection / guard) [@MickLesk](https://github.com/MickLesk) ([#15661](https://github.com/community-scripts/ProxmoxVE/pull/15661))
|
||||||
|
|
||||||
|
## 2026-07-12
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- AFFiNE ([#15690](https://github.com/community-scripts/ProxmoxVE/pull/15690))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- Immich: Bump version to 3.0.2 [@vhsdream](https://github.com/vhsdream) ([#15668](https://github.com/community-scripts/ProxmoxVE/pull/15668))
|
||||||
|
|
||||||
|
### ❔ Uncategorized
|
||||||
|
|
||||||
|
- fix(immich): correct Python indentation error in ct/immich.sh heredoc patch [@Copilot](https://github.com/Copilot) ([#15723](https://github.com/community-scripts/ProxmoxVE/pull/15723))
|
||||||
|
|
||||||
|
## 2026-07-11
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- LocalAGI ([#15687](https://github.com/community-scripts/ProxmoxVE/pull/15687))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- fix(adventurelog): allow pnpm build scripts so install/update doesn't abort [@TowyTowy](https://github.com/TowyTowy) ([#15681](https://github.com/community-scripts/ProxmoxVE/pull/15681))
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix(fileflows): install .NET 10 ASP.NET Core Runtime to match current release [@TowyTowy](https://github.com/TowyTowy) ([#15702](https://github.com/community-scripts/ProxmoxVE/pull/15702))
|
||||||
|
- Fix spacing on VLAN Input Box in haos-vm.sh [@pumrum](https://github.com/pumrum) ([#15696](https://github.com/community-scripts/ProxmoxVE/pull/15696))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- [tools.func]: Add function to handle deployment via GitLab release tags [@tremor021](https://github.com/tremor021) ([#15641](https://github.com/community-scripts/ProxmoxVE/pull/15641))
|
||||||
|
|
||||||
## 2026-07-10
|
## 2026-07-10
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
@@ -509,6 +761,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Adapt to new artifact filename format for pocket id [@wollew](https://github.com/wollew) ([#15689](https://github.com/community-scripts/ProxmoxVE/pull/15689))
|
||||||
- Fireshare: Fix for install and upgrade to v1.7.3 [@tremor021](https://github.com/tremor021) ([#15673](https://github.com/community-scripts/ProxmoxVE/pull/15673))
|
- Fireshare: Fix for install and upgrade to v1.7.3 [@tremor021](https://github.com/tremor021) ([#15673](https://github.com/community-scripts/ProxmoxVE/pull/15673))
|
||||||
- Endurain: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15674](https://github.com/community-scripts/ProxmoxVE/pull/15674))
|
- Endurain: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15674](https://github.com/community-scripts/ProxmoxVE/pull/15674))
|
||||||
|
|
||||||
@@ -959,258 +1212,3 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
- chore(ct): sync coredns defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#15182](https://github.com/community-scripts/ProxmoxVE/pull/15182))
|
- chore(ct): sync coredns defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#15182](https://github.com/community-scripts/ProxmoxVE/pull/15182))
|
||||||
- chore(ct): sync gatus defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#15184](https://github.com/community-scripts/ProxmoxVE/pull/15184))
|
- chore(ct): sync gatus defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#15184](https://github.com/community-scripts/ProxmoxVE/pull/15184))
|
||||||
- chore(ct): sync bitmagnet defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#15183](https://github.com/community-scripts/ProxmoxVE/pull/15183))
|
- chore(ct): sync bitmagnet defaults with PocketBase [@github-actions[bot]](https://github.com/github-actions[bot]) ([#15183](https://github.com/community-scripts/ProxmoxVE/pull/15183))
|
||||||
|
|
||||||
## 2026-06-18
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- flowise: add deps / uv / python 3.11 [@MickLesk](https://github.com/MickLesk) ([#15177](https://github.com/community-scripts/ProxmoxVE/pull/15177))
|
|
||||||
|
|
||||||
- #### 💥 Breaking Changes
|
|
||||||
|
|
||||||
- refactor: crafty-controller [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15178](https://github.com/community-scripts/ProxmoxVE/pull/15178))
|
|
||||||
|
|
||||||
## 2026-06-17
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- kasm: fix release detection [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15151](https://github.com/community-scripts/ProxmoxVE/pull/15151))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- trek: update install and upgrade workflow for v3.1.0 [@MickLesk](https://github.com/MickLesk) ([#15165](https://github.com/community-scripts/ProxmoxVE/pull/15165))
|
|
||||||
|
|
||||||
- #### 💥 Breaking Changes
|
|
||||||
|
|
||||||
- TREK: Pin version [@tremor021](https://github.com/tremor021) ([#15156](https://github.com/community-scripts/ProxmoxVE/pull/15156))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- chore(paperless-ngx): pin version to prevent v3 update [@tomfrenzel](https://github.com/tomfrenzel) ([#15171](https://github.com/community-scripts/ProxmoxVE/pull/15171))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- immich public proxy: replace npm install with npm ci for consistent dependency installation [@MickLesk](https://github.com/MickLesk) ([#15166](https://github.com/community-scripts/ProxmoxVE/pull/15166))
|
|
||||||
|
|
||||||
## 2026-06-16
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Feishin ([#15130](https://github.com/community-scripts/ProxmoxVE/pull/15130))
|
|
||||||
- Kiwix ([#15131](https://github.com/community-scripts/ProxmoxVE/pull/15131))
|
|
||||||
- Add runtime status guard and deleted script stubs [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15125](https://github.com/community-scripts/ProxmoxVE/pull/15125))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- fix(degoog): use localhost for valkey url [@ethan-hgwr](https://github.com/ethan-hgwr) ([#15149](https://github.com/community-scripts/ProxmoxVE/pull/15149))
|
|
||||||
- Fix InvoiceShelf install/update Yarn package manager mismatch [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15141](https://github.com/community-scripts/ProxmoxVE/pull/15141))
|
|
||||||
- fix storyteller install failure with yarn 4 corepack [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15140](https://github.com/community-scripts/ProxmoxVE/pull/15140))
|
|
||||||
- fix: generate policy-compliant OpenObserve root password [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15137](https://github.com/community-scripts/ProxmoxVE/pull/15137))
|
|
||||||
|
|
||||||
## 2026-06-15
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Watcharr: Clean install on update [@tremor021](https://github.com/tremor021) ([#15119](https://github.com/community-scripts/ProxmoxVE/pull/15119))
|
|
||||||
- Vaultwarden: extend version check for VaultWarden update [@MickLesk](https://github.com/MickLesk) ([#15105](https://github.com/community-scripts/ProxmoxVE/pull/15105))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- degoog: add curl-impersonate to script [@MickLesk](https://github.com/MickLesk) ([#15117](https://github.com/community-scripts/ProxmoxVE/pull/15117))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- tools.func: extend mesa-vulkan-drivers and vulkan-tools to installation for ARC GPU's [@MickLesk](https://github.com/MickLesk) ([#15106](https://github.com/community-scripts/ProxmoxVE/pull/15106))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- core: improve mirror selection and error handling [@MickLesk](https://github.com/MickLesk) ([#15108](https://github.com/community-scripts/ProxmoxVE/pull/15108))
|
|
||||||
- core: implement gateway validation for DHCP and static networks [@MickLesk](https://github.com/MickLesk) ([#15107](https://github.com/community-scripts/ProxmoxVE/pull/15107))
|
|
||||||
|
|
||||||
## 2026-06-14
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Iinvoiceninja: fix nginx setup assets port [@MickLesk](https://github.com/MickLesk) ([#15090](https://github.com/community-scripts/ProxmoxVE/pull/15090))
|
|
||||||
- CheckMK: remove stale backup site before creating new backup during update [@MickLesk](https://github.com/MickLesk) ([#15088](https://github.com/community-scripts/ProxmoxVE/pull/15088))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Refactor: Implement backup functions for scripts C-D [@tremor021](https://github.com/tremor021) ([#15096](https://github.com/community-scripts/ProxmoxVE/pull/15096))
|
|
||||||
|
|
||||||
## 2026-06-13
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- BookOrbit ([#15080](https://github.com/community-scripts/ProxmoxVE/pull/15080))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- Update authentik version to 2026.5.3 [@thieneret](https://github.com/thieneret) ([#15093](https://github.com/community-scripts/ProxmoxVE/pull/15093))
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Immich: Update image-processing libraries [@vhsdream](https://github.com/vhsdream) ([#15082](https://github.com/community-scripts/ProxmoxVE/pull/15082))
|
|
||||||
- HomeBox: Support v0.26.0 [@tomfrenzel](https://github.com/tomfrenzel) ([#15086](https://github.com/community-scripts/ProxmoxVE/pull/15086))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Refactor: Implement backup functions for scripts A-B [@tremor021](https://github.com/tremor021) ([#15075](https://github.com/community-scripts/ProxmoxVE/pull/15075))
|
|
||||||
|
|
||||||
## 2026-06-12
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Twenty ([#15047](https://github.com/community-scripts/ProxmoxVE/pull/15047))
|
|
||||||
- Alpine-Cinny ([#15044](https://github.com/community-scripts/ProxmoxVE/pull/15044))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- [core] Implement backup and restore functions [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#15067](https://github.com/community-scripts/ProxmoxVE/pull/15067))
|
|
||||||
|
|
||||||
## 2026-06-11
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Clickhouse ([#15045](https://github.com/community-scripts/ProxmoxVE/pull/15045))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Manyfold: add new dependency [@MickLesk](https://github.com/MickLesk) ([#15040](https://github.com/community-scripts/ProxmoxVE/pull/15040))
|
|
||||||
- OpenArchiver: switch Rebuild Function [@MickLesk](https://github.com/MickLesk) ([#15042](https://github.com/community-scripts/ProxmoxVE/pull/15042))
|
|
||||||
- CLIProxyAPI: Save management password to creds file [@tremor021](https://github.com/tremor021) ([#15051](https://github.com/community-scripts/ProxmoxVE/pull/15051))
|
|
||||||
- Jotty: Fix wrong path test in config restore [@vhsdream](https://github.com/vhsdream) ([#15038](https://github.com/community-scripts/ProxmoxVE/pull/15038))
|
|
||||||
- Fix for cross-seed after node upgrade [@TorinFrancis](https://github.com/TorinFrancis) ([#15025](https://github.com/community-scripts/ProxmoxVE/pull/15025))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Alpine-Nextcloud: Upgrade PHP and dependencies in installation script [@MickLesk](https://github.com/MickLesk) ([#15039](https://github.com/community-scripts/ProxmoxVE/pull/15039))
|
|
||||||
- [arm64] porting stage 1: set script arm64 statuses to yes [@asylumexp](https://github.com/asylumexp) ([#15052](https://github.com/community-scripts/ProxmoxVE/pull/15052))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- misc scripts: add support for arm64 [@asylumexp](https://github.com/asylumexp) ([#12639](https://github.com/community-scripts/ProxmoxVE/pull/12639))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- [arm64] remove logic for custom debian arm64 template [@asylumexp](https://github.com/asylumexp) ([#15050](https://github.com/community-scripts/ProxmoxVE/pull/15050))
|
|
||||||
|
|
||||||
### 📚 Documentation
|
|
||||||
|
|
||||||
- (github): Revise script request template [@MickLesk](https://github.com/MickLesk) ([#15058](https://github.com/community-scripts/ProxmoxVE/pull/15058))
|
|
||||||
|
|
||||||
## 2026-06-10
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Baserow ([#14968](https://github.com/community-scripts/ProxmoxVE/pull/14968))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Koillection: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15033](https://github.com/community-scripts/ProxmoxVE/pull/15033))
|
|
||||||
|
|
||||||
## 2026-06-09
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- paperclip ([#14990](https://github.com/community-scripts/ProxmoxVE/pull/14990))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- endurain: Install pytz package during backend setup [@MickLesk](https://github.com/MickLesk) ([#15014](https://github.com/community-scripts/ProxmoxVE/pull/15014))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Refactor: Proxmox Backup Server - use deb822 [@MickLesk](https://github.com/MickLesk) ([#15013](https://github.com/community-scripts/ProxmoxVE/pull/15013))
|
|
||||||
|
|
||||||
## 2026-06-08
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- security: Fix HTTP to HTTPS for all package and repository downloads [@MickLesk](https://github.com/MickLesk) ([#15009](https://github.com/community-scripts/ProxmoxVE/pull/15009))
|
|
||||||
- homelable: preserve MCP server config across updates [@ferr079](https://github.com/ferr079) ([#14996](https://github.com/community-scripts/ProxmoxVE/pull/14996))
|
|
||||||
- changedetection: migrate Python install to uv venv [@ferr079](https://github.com/ferr079) ([#14995](https://github.com/community-scripts/ProxmoxVE/pull/14995))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Update Flowwiseai to node 24 [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#14999](https://github.com/community-scripts/ProxmoxVE/pull/14999))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- security: Fix MITM RCE vulnerability in microcode scripts (CVE) [@MickLesk](https://github.com/MickLesk) ([#15007](https://github.com/community-scripts/ProxmoxVE/pull/15007))
|
|
||||||
|
|
||||||
## 2026-06-07
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Immich: use actual installed PostgreSQL version for vchord package [@MickLesk](https://github.com/MickLesk) ([#14989](https://github.com/community-scripts/ProxmoxVE/pull/14989))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Navidrome: remove genereic filebrowser addon setup [@MickLesk](https://github.com/MickLesk) ([#14991](https://github.com/community-scripts/ProxmoxVE/pull/14991))
|
|
||||||
|
|
||||||
## 2026-06-06
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Spliit ([#14966](https://github.com/community-scripts/ProxmoxVE/pull/14966))
|
|
||||||
- Tolgee ([#14965](https://github.com/community-scripts/ProxmoxVE/pull/14965))
|
|
||||||
- XYOps ([#14967](https://github.com/community-scripts/ProxmoxVE/pull/14967))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Photoprism: Allow env variables with spaces [@Badintral](https://github.com/Badintral) ([#14969](https://github.com/community-scripts/ProxmoxVE/pull/14969))
|
|
||||||
|
|
||||||
## 2026-06-05
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- MatterJS-Server ([#14951](https://github.com/community-scripts/ProxmoxVE/pull/14951))
|
|
||||||
- CyberChef ([#14952](https://github.com/community-scripts/ProxmoxVE/pull/14952))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Jackett: Create missing .env file [@tremor021](https://github.com/tremor021) ([#14959](https://github.com/community-scripts/ProxmoxVE/pull/14959))
|
|
||||||
- OpenThread-BR: use systemd instead of init.d [@tomfrenzel](https://github.com/tomfrenzel) ([#14942](https://github.com/community-scripts/ProxmoxVE/pull/14942))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- AMD IGPU support [@Learath](https://github.com/Learath) ([#14944](https://github.com/community-scripts/ProxmoxVE/pull/14944))
|
|
||||||
|
|
||||||
- #### 💥 Breaking Changes
|
|
||||||
|
|
||||||
- update authentik to 2026.5.2 [@thieneret](https://github.com/thieneret) ([#14846](https://github.com/community-scripts/ProxmoxVE/pull/14846))
|
|
||||||
@@ -60,6 +60,7 @@ function update_script() {
|
|||||||
php artisan 2fauth:install
|
php artisan 2fauth:install
|
||||||
chown -R www-data: /opt/2fauth
|
chown -R www-data: /opt/2fauth
|
||||||
chmod -R 755 /opt/2fauth
|
chmod -R 755 /opt/2fauth
|
||||||
|
$STD php artisan 2fauth:fix-passport-key-permissions
|
||||||
$STD systemctl restart php8.4-fpm
|
$STD systemctl restart php8.4-fpm
|
||||||
$STD systemctl restart nginx
|
$STD systemctl restart nginx
|
||||||
msg_ok "Configured 2FAuth"
|
msg_ok "Configured 2FAuth"
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ function update_script() {
|
|||||||
$STD .venv/bin/python -m manage migrate
|
$STD .venv/bin/python -m manage migrate
|
||||||
|
|
||||||
cd /opt/adventurelog/frontend
|
cd /opt/adventurelog/frontend
|
||||||
|
grep -q "^dangerouslyAllowAllBuilds:" ./pnpm-workspace.yaml 2>/dev/null || echo "dangerouslyAllowAllBuilds: true" >>./pnpm-workspace.yaml
|
||||||
$STD pnpm i
|
$STD pnpm i
|
||||||
$STD pnpm build
|
$STD pnpm build
|
||||||
msg_ok "Updated AdventureLog"
|
msg_ok "Updated AdventureLog"
|
||||||
|
|||||||
+138
@@ -0,0 +1,138 @@
|
|||||||
|
#!/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://github.com/toeverything/AFFiNE
|
||||||
|
|
||||||
|
APP="AFFiNE"
|
||||||
|
var_tags="${var_tags:-knowledge;notes;workspace}"
|
||||||
|
var_cpu="${var_cpu:-4}"
|
||||||
|
var_ram="${var_ram:-8192}"
|
||||||
|
var_disk="${var_disk:-20}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-no}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/affine ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
RELEASE="v0.27.2"
|
||||||
|
if check_for_gh_release "affine_app" "toeverything/AFFiNE" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
|
||||||
|
msg_info "Stopping Services"
|
||||||
|
systemctl stop affine-web affine-worker
|
||||||
|
msg_ok "Stopped Services"
|
||||||
|
|
||||||
|
ensure_dependencies cmake
|
||||||
|
|
||||||
|
create_backup /opt/affine/.env /root/.affine/config /root/.affine/storage
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "affine_app" "toeverything/AFFiNE" "tarball" "${RELEASE}" "/opt/affine"
|
||||||
|
|
||||||
|
# Restore BEFORE the build: CLEAN_INSTALL wiped /opt/affine including .env,
|
||||||
|
# and the build below sources it
|
||||||
|
restore_backup
|
||||||
|
|
||||||
|
if [[ ! -f /opt/affine/.env ]]; then
|
||||||
|
msg_error "/opt/affine/.env is missing (lost by an earlier update). Recreate it before retrying — see the AFFiNE install script for the expected variables."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Rebuilding Application (Patience ~25 mins, don't close the console!)"
|
||||||
|
cd /opt/affine
|
||||||
|
source /root/.profile
|
||||||
|
export PATH="/root/.cargo/bin:/root/.rbenv/shims:$PATH"
|
||||||
|
|
||||||
|
set -a && source /opt/affine/.env && set +a
|
||||||
|
|
||||||
|
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||||
|
export VITE_CORE_COMMIT_SHA=$(cat ~/.affine_app)
|
||||||
|
|
||||||
|
# Initialize git repo (required for build process)
|
||||||
|
export HUSKY=0
|
||||||
|
$STD git init -q
|
||||||
|
$STD git config user.email "build@local"
|
||||||
|
$STD git config user.name "Build"
|
||||||
|
$STD git add -A
|
||||||
|
$STD git commit -q -m "update" --no-verify --allow-empty
|
||||||
|
|
||||||
|
# Force Turbo to run sequentially
|
||||||
|
mkdir -p /opt/affine/.turbo
|
||||||
|
cat <<TURBO >/opt/affine/.turbo/config.json
|
||||||
|
{
|
||||||
|
"concurrency": 1
|
||||||
|
}
|
||||||
|
TURBO
|
||||||
|
|
||||||
|
$STD corepack enable
|
||||||
|
$STD corepack prepare yarn@4.13.0 --activate
|
||||||
|
$STD yarn config set enableTelemetry 0
|
||||||
|
|
||||||
|
export NODE_OPTIONS="--max-old-space-size=2048"
|
||||||
|
$STD yarn install
|
||||||
|
$STD npm install -g typescript
|
||||||
|
|
||||||
|
$STD yarn affine @affine/native build
|
||||||
|
$STD yarn affine @affine/server-native build
|
||||||
|
|
||||||
|
# Create architecture-specific symlinks
|
||||||
|
ln -sf /opt/affine/packages/backend/native/server-native.node \
|
||||||
|
/opt/affine/packages/backend/native/server-native.x64.node
|
||||||
|
ln -sf /opt/affine/packages/backend/native/server-native.node \
|
||||||
|
/opt/affine/packages/backend/native/server-native.arm64.node
|
||||||
|
ln -sf /opt/affine/packages/backend/native/server-native.node \
|
||||||
|
/opt/affine/packages/backend/native/server-native.armv7.node
|
||||||
|
|
||||||
|
$STD yarn affine init
|
||||||
|
$STD yarn affine build -p @affine/reader
|
||||||
|
$STD yarn affine build -p @affine/server
|
||||||
|
|
||||||
|
export NODE_OPTIONS="--max-old-space-size=4096"
|
||||||
|
$STD yarn affine build -p @affine/web
|
||||||
|
$STD yarn affine build -p @affine/admin
|
||||||
|
|
||||||
|
# Copy web assets
|
||||||
|
mkdir -p /opt/affine/packages/backend/server/static
|
||||||
|
cp -r /opt/affine/packages/frontend/apps/web/dist/* /opt/affine/packages/backend/server/static/
|
||||||
|
mkdir -p /opt/affine/packages/backend/server/static/admin
|
||||||
|
cp -r /opt/affine/packages/frontend/admin/dist/* /opt/affine/packages/backend/server/static/admin/
|
||||||
|
|
||||||
|
# Mobile manifest placeholder
|
||||||
|
mkdir -p /opt/affine/packages/backend/server/static/mobile
|
||||||
|
echo '{"publicPath":"/","js":[],"css":[],"gitHash":"","description":""}' \
|
||||||
|
>/opt/affine/packages/backend/server/static/mobile/assets-manifest.json
|
||||||
|
|
||||||
|
# Run migrations
|
||||||
|
cd /opt/affine/packages/backend/server
|
||||||
|
set -a && source /opt/affine/.env && set +a
|
||||||
|
$STD node ./scripts/self-host-predeploy.js
|
||||||
|
|
||||||
|
msg_info "Starting Services"
|
||||||
|
systemctl start affine-web affine-worker
|
||||||
|
msg_ok "Started Services"
|
||||||
|
msg_ok "Updated Successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:3010/admin${CL}"
|
||||||
@@ -146,7 +146,7 @@ function update_script() {
|
|||||||
|
|
||||||
# Check and upgrade optional extensions
|
# Check and upgrade optional extensions
|
||||||
# TOTP Extension
|
# TOTP Extension
|
||||||
if [[ -f /etc/guacamole/extensions/guacamole-auth-totp-*.jar ]]; then
|
if compgen -G "/etc/guacamole/extensions/guacamole-auth-totp-*.jar" >/dev/null; then
|
||||||
msg_info "Updating TOTP Extension"
|
msg_info "Updating TOTP Extension"
|
||||||
rm -f /etc/guacamole/extensions/guacamole-auth-totp-*.jar
|
rm -f /etc/guacamole/extensions/guacamole-auth-totp-*.jar
|
||||||
curl_download "/tmp/guacamole-auth-totp.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-totp-${LATEST_SERVER}.tar.gz"
|
curl_download "/tmp/guacamole-auth-totp.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-totp-${LATEST_SERVER}.tar.gz"
|
||||||
@@ -158,7 +158,7 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# DUO Extension
|
# DUO Extension
|
||||||
if [[ -f /etc/guacamole/extensions/guacamole-auth-duo-*.jar ]]; then
|
if compgen -G "/etc/guacamole/extensions/guacamole-auth-duo-*.jar" >/dev/null; then
|
||||||
msg_info "Updating DUO Extension"
|
msg_info "Updating DUO Extension"
|
||||||
rm -f /etc/guacamole/extensions/guacamole-auth-duo-*.jar
|
rm -f /etc/guacamole/extensions/guacamole-auth-duo-*.jar
|
||||||
curl_download "/tmp/guacamole-auth-duo.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-duo-${LATEST_SERVER}.tar.gz"
|
curl_download "/tmp/guacamole-auth-duo.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-duo-${LATEST_SERVER}.tar.gz"
|
||||||
@@ -170,7 +170,7 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# LDAP Extension
|
# LDAP Extension
|
||||||
if [[ -f /etc/guacamole/extensions/guacamole-auth-ldap-*.jar ]]; then
|
if compgen -G "/etc/guacamole/extensions/guacamole-auth-ldap-*.jar" >/dev/null; then
|
||||||
msg_info "Updating LDAP Extension"
|
msg_info "Updating LDAP Extension"
|
||||||
rm -f /etc/guacamole/extensions/guacamole-auth-ldap-*.jar
|
rm -f /etc/guacamole/extensions/guacamole-auth-ldap-*.jar
|
||||||
curl_download "/tmp/guacamole-auth-ldap.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-ldap-${LATEST_SERVER}.tar.gz"
|
curl_download "/tmp/guacamole-auth-ldap.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-ldap-${LATEST_SERVER}.tar.gz"
|
||||||
@@ -182,7 +182,7 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Quick Connect Extension
|
# Quick Connect Extension
|
||||||
if [[ -f /etc/guacamole/extensions/guacamole-auth-quickconnect-*.jar ]]; then
|
if compgen -G "/etc/guacamole/extensions/guacamole-auth-quickconnect-*.jar" >/dev/null; then
|
||||||
msg_info "Updating Quick Connect Extension"
|
msg_info "Updating Quick Connect Extension"
|
||||||
rm -f /etc/guacamole/extensions/guacamole-auth-quickconnect-*.jar
|
rm -f /etc/guacamole/extensions/guacamole-auth-quickconnect-*.jar
|
||||||
curl_download "/tmp/guacamole-auth-quickconnect.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-quickconnect-${LATEST_SERVER}.tar.gz"
|
curl_download "/tmp/guacamole-auth-quickconnect.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-auth-quickconnect-${LATEST_SERVER}.tar.gz"
|
||||||
@@ -194,7 +194,7 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# History Recording Storage Extension
|
# History Recording Storage Extension
|
||||||
if [[ -f /etc/guacamole/extensions/guacamole-history-recording-storage-*.jar ]]; then
|
if compgen -G "/etc/guacamole/extensions/guacamole-history-recording-storage-*.jar" >/dev/null; then
|
||||||
msg_info "Updating History Recording Storage Extension"
|
msg_info "Updating History Recording Storage Extension"
|
||||||
rm -f /etc/guacamole/extensions/guacamole-history-recording-storage-*.jar
|
rm -f /etc/guacamole/extensions/guacamole-history-recording-storage-*.jar
|
||||||
curl_download "/tmp/guacamole-history-recording-storage.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-history-recording-storage-${LATEST_SERVER}.tar.gz"
|
curl_download "/tmp/guacamole-history-recording-storage.tar.gz" "https://downloads.apache.org/guacamole/${LATEST_SERVER}/binary/guacamole-history-recording-storage-${LATEST_SERVER}.tar.gz"
|
||||||
|
|||||||
+4
-3
@@ -38,13 +38,14 @@ function update_script() {
|
|||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
setup_go
|
setup_go
|
||||||
UV_PYTHON_INSTALL_DIR="/usr/local/bin" PYTHON_VERSION="3.14.3" setup_uv
|
$STD uv cache clean
|
||||||
|
UV_PYTHON_INSTALL_DIR="/usr/local/bin" PYTHON_VERSION="3.14.6" setup_uv
|
||||||
RUST_PROFILE="minimal" RUST_TOOLCHAIN="stable" setup_rust
|
RUST_PROFILE="minimal" RUST_TOOLCHAIN="stable" setup_rust
|
||||||
setup_yq
|
setup_yq
|
||||||
|
|
||||||
AUTHENTIK_VERSION="version/2026.5.3"
|
AUTHENTIK_VERSION="version/2026.5.5"
|
||||||
# Source: https://github.com/goauthentik/fips/blob/main/Makefile#L26
|
# Source: https://github.com/goauthentik/fips/blob/main/Makefile#L26
|
||||||
XMLSEC_VERSION="1.3.11"
|
XMLSEC_VERSION="1.3.12"
|
||||||
|
|
||||||
if check_for_gh_release "geoipupdate" "maxmind/geoipupdate"; then
|
if check_for_gh_release "geoipupdate" "maxmind/geoipupdate"; then
|
||||||
fetch_and_deploy_gh_release "geoipupdate" "maxmind/geoipupdate" "binary"
|
fetch_and_deploy_gh_release "geoipupdate" "maxmind/geoipupdate" "binary"
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#!/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://github.com/daya0576/beaverhabits
|
||||||
|
|
||||||
|
APP="BeaverHabits"
|
||||||
|
var_tags="${var_tags:-habits;tracking;productivity}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-1024}"
|
||||||
|
var_disk="${var_disk:-4}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/beaverhabits ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "beaverhabits" "daya0576/beaverhabits"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop beaverhabits
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
create_backup /opt/beaverhabits/.user
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "beaverhabits" "daya0576/beaverhabits" "tarball"
|
||||||
|
|
||||||
|
msg_info "Syncing Dependencies"
|
||||||
|
cd /opt/beaverhabits
|
||||||
|
$STD uv sync --no-dev
|
||||||
|
msg_ok "Synced Dependencies"
|
||||||
|
|
||||||
|
restore_backup
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start beaverhabits
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:8080/register{CL}"
|
||||||
+1
-1
@@ -37,7 +37,7 @@ function update_script() {
|
|||||||
systemctl stop birdnet
|
systemctl stop birdnet
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "birdnet" "tphakala/birdnet-go" "prebuild" "latest" "/opt/birdnet" "birdnet-go-linux-$(arch_resolve).tar.gz"
|
fetch_and_deploy_gh_release "birdnet" "tphakala/birdnet-go" "prebuild" "latest" "/opt/birdnet" "birdnet-go-linux-$(arch_resolve)*.tar.gz"
|
||||||
|
|
||||||
msg_info "Deploying Binary"
|
msg_info "Deploying Binary"
|
||||||
cp /opt/birdnet/birdnet-go /usr/local/bin/birdnet-go
|
cp /opt/birdnet/birdnet-go /usr/local/bin/birdnet-go
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ function update_script() {
|
|||||||
mkdir -p /opt/bookorbit/server/migrations
|
mkdir -p /opt/bookorbit/server/migrations
|
||||||
cp -r /opt/bookorbit/server/src/db/migrations/. /opt/bookorbit/server/migrations/
|
cp -r /opt/bookorbit/server/src/db/migrations/. /opt/bookorbit/server/migrations/
|
||||||
chmod +x /opt/bookorbit/server/bin/kepubify/*
|
chmod +x /opt/bookorbit/server/bin/kepubify/*
|
||||||
|
restore_backup
|
||||||
APP_VER=$(cat ~/.bookorbit)
|
APP_VER=$(cat ~/.bookorbit)
|
||||||
sed -i "s/^APP_VERSION=.*/APP_VERSION=v$APP_VER/" /opt/bookorbit/.env
|
sed -i "s/^APP_VERSION=.*/APP_VERSION=v$APP_VER/" /opt/bookorbit/.env
|
||||||
msg_ok "Rebuilt Application"
|
msg_ok "Rebuilt Application"
|
||||||
|
|||||||
@@ -36,8 +36,12 @@ function update_script() {
|
|||||||
systemctl stop cliproxyapi
|
systemctl stop cliproxyapi
|
||||||
msg_ok "Stopped CLIProxyAPI"
|
msg_ok "Stopped CLIProxyAPI"
|
||||||
|
|
||||||
|
create_backup /opt/cliproxyapi/config.yaml
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cliproxyapi" "router-for-me/CLIProxyAPI" "prebuild" "latest" "/opt/cliproxyapi" "CLIProxyAPI_*_linux_$(arch_resolve "amd64" "aarch64").tar.gz"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cliproxyapi" "router-for-me/CLIProxyAPI" "prebuild" "latest" "/opt/cliproxyapi" "CLIProxyAPI_*_linux_$(arch_resolve "amd64" "aarch64").tar.gz"
|
||||||
|
|
||||||
|
restore_backup
|
||||||
|
|
||||||
msg_info "Starting CLIProxyAPI"
|
msg_info "Starting CLIProxyAPI"
|
||||||
systemctl start cliproxyapi
|
systemctl start cliproxyapi
|
||||||
msg_ok "Started CLIProxyAPI"
|
msg_ok "Started CLIProxyAPI"
|
||||||
|
|||||||
+3
-2
@@ -39,7 +39,6 @@ function update_script() {
|
|||||||
|
|
||||||
create_backup /opt/docmost/.env \
|
create_backup /opt/docmost/.env \
|
||||||
/opt/docmost/data
|
/opt/docmost/data
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "docmost" "docmost/docmost" "tarball"
|
fetch_and_deploy_gh_release "docmost" "docmost/docmost" "tarball"
|
||||||
|
|
||||||
restore_backup
|
restore_backup
|
||||||
@@ -54,9 +53,11 @@ function update_script() {
|
|||||||
sed -i '/^@Module({$/i @Global()' /opt/docmost/apps/server/src/core/core.module.ts
|
sed -i '/^@Module({$/i @Global()' /opt/docmost/apps/server/src/core/core.module.ts
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
msg_info "Configuring Docmost"
|
||||||
|
cd /opt/docmost
|
||||||
$STD pnpm install --force
|
$STD pnpm install --force
|
||||||
$STD pnpm build
|
$STD pnpm build
|
||||||
msg_ok "Updated ${APP}"
|
msg_ok "Configured Docmost"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start docmost
|
systemctl start docmost
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ function update_script() {
|
|||||||
systemctl stop docuseal docuseal-sidekiq
|
systemctl stop docuseal docuseal-sidekiq
|
||||||
msg_ok "Stopped Services"
|
msg_ok "Stopped Services"
|
||||||
|
|
||||||
|
ensure_dependencies libleptonica-dev libleptonica6
|
||||||
|
|
||||||
create_backup /opt/docuseal/.env \
|
create_backup /opt/docuseal/.env \
|
||||||
/opt/docuseal/data
|
/opt/docuseal/data
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
ensure_dependencies libusb-1.0-0
|
||||||
|
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop esphome-device-builder 2>/dev/null || true
|
systemctl stop esphome-device-builder 2>/dev/null || true
|
||||||
|
|||||||
+60
-5
@@ -31,11 +31,50 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
update_available=$(curl -fsSL -X 'GET' "http://localhost:19200/api/status/update-available" -H 'accept: application/json' | jq .UpdateAvailable)
|
local proceed=false
|
||||||
|
|
||||||
|
if systemctl list-unit-files 'fileflows.service' --no-legend 2>/dev/null | grep -q '^fileflows\.service'; then
|
||||||
|
tmp=$(mktemp)
|
||||||
|
http_code=$(curl -sSL -X 'GET' "http://localhost:19200/api/status/update-available" -H 'accept: application/json' -o "$tmp" -w '%{http_code}' 2>/dev/null) || http_code="000"
|
||||||
|
if [[ "$http_code" == "200" ]]; then
|
||||||
|
update_available=$(jq -r '.UpdateAvailable // false' "$tmp" 2>/dev/null)
|
||||||
|
rm -f "$tmp"
|
||||||
if [[ "${update_available}" == "true" ]]; then
|
if [[ "${update_available}" == "true" ]]; then
|
||||||
|
proceed=true
|
||||||
|
else
|
||||||
|
msg_ok "No update required. ${APP} is already at latest version"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
rm -f "$tmp"
|
||||||
|
if [[ "$http_code" == "401" ]]; then
|
||||||
|
msg_warn "Could not check for updates: API returned 401 (security may be enabled)."
|
||||||
|
else
|
||||||
|
msg_warn "Could not check for updates: API unreachable (HTTP ${http_code})."
|
||||||
|
fi
|
||||||
|
if [[ "${FORCE_UPDATE:-}" == "1" ]]; then
|
||||||
|
proceed=true
|
||||||
|
else
|
||||||
|
read -r -p "${TAB3}Force update without version check? [y/N]: " CONFIRM
|
||||||
|
if [[ "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
||||||
|
proceed=true
|
||||||
|
else
|
||||||
|
msg_error "Update aborted."
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
proceed=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$proceed" != "true" ]]; then
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl --all stop 'fileflows*'
|
systemctl --all stop 'fileflows*'
|
||||||
msg_info "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
msg_info "Creating Backup"
|
msg_info "Creating Backup"
|
||||||
ls /opt/*.tar.gz &>/dev/null && rm -f /opt/*.tar.gz
|
ls /opt/*.tar.gz &>/dev/null && rm -f /opt/*.tar.gz
|
||||||
@@ -43,15 +82,31 @@ function update_script() {
|
|||||||
tar -czf "$backup_filename" -C /opt/fileflows Data
|
tar -czf "$backup_filename" -C /opt/fileflows Data
|
||||||
msg_ok "Backup Created"
|
msg_ok "Backup Created"
|
||||||
|
|
||||||
|
msg_info "Ensuring ASP.NET Core Runtime"
|
||||||
|
if [[ "$(arch_resolve)" == "arm64" ]]; then
|
||||||
|
if [[ ! -x /usr/lib/dotnet10/dotnet ]]; then
|
||||||
|
curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
|
||||||
|
$STD bash /tmp/dotnet-install.sh --channel 10.0 --runtime aspnetcore --install-dir /usr/lib/dotnet10
|
||||||
|
ln -sf /usr/lib/dotnet10/dotnet /usr/bin/dotnet
|
||||||
|
rm -f /tmp/dotnet-install.sh
|
||||||
|
fi
|
||||||
|
elif ! is_package_installed "aspnetcore-runtime-10.0"; then
|
||||||
|
$STD apt remove -y aspnetcore-runtime-8.0 aspnetcore-runtime-9.0 2>/dev/null || true
|
||||||
|
setup_deb822_repo \
|
||||||
|
"microsoft" \
|
||||||
|
"https://packages.microsoft.com/keys/microsoft-2025.asc" \
|
||||||
|
"https://packages.microsoft.com/debian/13/prod/" \
|
||||||
|
"trixie"
|
||||||
|
$STD apt install -y aspnetcore-runtime-10.0
|
||||||
|
fi
|
||||||
|
msg_ok "Ensured ASP.NET Core Runtime"
|
||||||
|
|
||||||
fetch_and_deploy_from_url "https://fileflows.com/downloads/zip" "/opt/fileflows"
|
fetch_and_deploy_from_url "https://fileflows.com/downloads/zip" "/opt/fileflows"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl --all start 'fileflows*'
|
systemctl --all start 'fileflows*'
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
else
|
|
||||||
msg_ok "No update required. ${APP} is already at latest version"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,30 @@ function update_script() {
|
|||||||
fetch_and_deploy_gh_release "gotify" "gotify/server" "prebuild" "latest" "/opt/gotify" "gotify-linux-$(arch_resolve).zip"
|
fetch_and_deploy_gh_release "gotify" "gotify/server" "prebuild" "latest" "/opt/gotify" "gotify-linux-$(arch_resolve).zip"
|
||||||
chmod +x /opt/gotify/gotify-linux-$(arch_resolve)
|
chmod +x /opt/gotify/gotify-linux-$(arch_resolve)
|
||||||
|
|
||||||
|
if [[ ! -f /opt/gotify/gotify-server.env ]]; then
|
||||||
|
gotify_old_config=""
|
||||||
|
for f in /opt/gotify/config.yml /etc/gotify/config.yml; do
|
||||||
|
[[ -f "$f" ]] && gotify_old_config="$f" && break
|
||||||
|
done
|
||||||
|
if [[ -n "$gotify_old_config" ]]; then
|
||||||
|
msg_info "Migrating ${gotify_old_config} to env format (Gotify 3.x)"
|
||||||
|
if /opt/gotify/gotify-linux-$(arch_resolve) migrate-config "$gotify_old_config" >/opt/gotify/gotify-server.env 2>/dev/null; then
|
||||||
|
mv "$gotify_old_config" "${gotify_old_config}.bak"
|
||||||
|
msg_ok "Migrated config to /opt/gotify/gotify-server.env (backup: ${gotify_old_config}.bak)"
|
||||||
|
else
|
||||||
|
rm -f /opt/gotify/gotify-server.env
|
||||||
|
msg_warn "Config migration failed — left ${gotify_old_config} in place, review manually"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep -qE '^ExecStart=.* serve' /etc/systemd/system/gotify.service 2>/dev/null; then
|
||||||
|
msg_info "Migrating service to serve subcommand (Gotify 3.x)"
|
||||||
|
sed -i -E 's|^(ExecStart=/opt/gotify/.*gotify-linux-[^ ]+)$|\1 serve|' /etc/systemd/system/gotify.service
|
||||||
|
systemctl daemon-reload
|
||||||
|
msg_ok "Migrated service to serve subcommand"
|
||||||
|
fi
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start gotify
|
systemctl start gotify
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
|
|||||||
+54
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: Raffaele (rafspiny)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://getgrav.org/
|
||||||
|
|
||||||
|
APP="Grav"
|
||||||
|
var_tags="${var_tags:-cms}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-2048}"
|
||||||
|
var_disk="${var_disk:-8}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-no}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d "/opt/grav" ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "grav" "getgrav/grav"; then
|
||||||
|
msg_info "Creating Backup"
|
||||||
|
cd /opt/grav
|
||||||
|
bin/grav backup -nq
|
||||||
|
msg_ok "Backup Created"
|
||||||
|
bin/gpm self-upgrade -y
|
||||||
|
cd -
|
||||||
|
chown -R www-data:www-data /opt/grav
|
||||||
|
msg_ok "Update Successful"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:80${CL}"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
___ _____________ _ ________
|
||||||
|
/ | / ____/ ____(_) | / / ____/
|
||||||
|
/ /| | / /_ / /_ / / |/ / __/
|
||||||
|
/ ___ |/ __/ / __/ / / /| / /___
|
||||||
|
/_/ |_/_/ /_/ /_/_/ |_/_____/
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
____ __ __ __ _ __
|
||||||
|
/ __ )___ ____ __ _____ _____/ / / /___ _/ /_ (_) /______
|
||||||
|
/ __ / _ \/ __ `/ | / / _ \/ ___/ /_/ / __ `/ __ \/ / __/ ___/
|
||||||
|
/ /_/ / __/ /_/ /| |/ / __/ / / __ / /_/ / /_/ / / /_(__ )
|
||||||
|
/_____/\___/\__,_/ |___/\___/_/ /_/ /_/\__,_/_.___/_/\__/____/
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
______
|
||||||
|
/ ____/________ __ __
|
||||||
|
/ / __/ ___/ __ `/ | / /
|
||||||
|
/ /_/ / / / /_/ /| |/ /
|
||||||
|
\____/_/ \__,_/ |___/
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
____ _ ___
|
||||||
|
/ _/___ _ __(_)___/ (_)___ __ _______
|
||||||
|
/ // __ \ | / / / __ / / __ \/ / / / ___/
|
||||||
|
_/ // / / / |/ / / /_/ / / /_/ / /_/ (__ )
|
||||||
|
/___/_/ /_/|___/_/\__,_/_/\____/\__,_/____/
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
__ _____ ___ __ _
|
||||||
|
/ / ___ ____ _/ __/ | / (_) /__(_)
|
||||||
|
/ / / _ \/ __ `/ /_ | | /| / / / //_/ /
|
||||||
|
/ /___/ __/ /_/ / __/ | |/ |/ / / ,< / /
|
||||||
|
/_____/\___/\__,_/_/ |__/|__/_/_/|_/_/
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
__ _____ __________
|
||||||
|
/ / ____ _________ _/ / | / ____/ _/
|
||||||
|
/ / / __ \/ ___/ __ `/ / /| |/ / __ / /
|
||||||
|
/ /___/ /_/ / /__/ /_/ / / ___ / /_/ // /
|
||||||
|
/_____/\____/\___/\__,_/_/_/ |_\____/___/
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
_ __ __
|
||||||
|
/ | / /__ _ __/ /____ _________ ___
|
||||||
|
/ |/ / _ \| |/_/ __/ _ \/ ___/ __ `__ \
|
||||||
|
/ /| / __/> </ /_/ __/ / / / / / / /
|
||||||
|
/_/ |_/\___/_/|_|\__/\___/_/ /_/ /_/ /_/
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
_ __ __ ____ _
|
||||||
|
/ | / /___ / /____ / __ \(_)_____________ _ _____ _______ __
|
||||||
|
/ |/ / __ \/ __/ _ \/ / / / / ___/ ___/ __ \ | / / _ \/ ___/ / / /
|
||||||
|
/ /| / /_/ / /_/ __/ /_/ / (__ ) /__/ /_/ / |/ / __/ / / /_/ /
|
||||||
|
/_/ |_/\____/\__/\___/_____/_/____/\___/\____/|___/\___/_/ \__, /
|
||||||
|
/____/
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
____ _ ________ __
|
||||||
|
/ __ \_ __(_) ____/ /___ __ ______/ /
|
||||||
|
/ / / / |/_/ / / / / __ \/ / / / __ /
|
||||||
|
/ /_/ /> </ / /___/ / /_/ / /_/ / /_/ /
|
||||||
|
\____/_/|_/_/\____/_/\____/\__,_/\__,_/
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
_____ _
|
||||||
|
/ ___/__ ______ _____ (_)___
|
||||||
|
\__ \/ / / / __ \/ ___/_____/ / __ \
|
||||||
|
___/ / /_/ / / / / /__/_____/ / / / /
|
||||||
|
/____/\__, /_/ /_/\___/ /_/_/ /_/
|
||||||
|
/____/
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
__ __ _
|
||||||
|
\ \/ /_ ___ ______ ____ ___ (_)
|
||||||
|
\ / / / / | / / __ \/ __ `__ \/ /
|
||||||
|
/ / /_/ /| |/ / /_/ / / / / / / /
|
||||||
|
/_/\__,_/ |___/\____/_/ /_/ /_/_/
|
||||||
|
|
||||||
+27
-3
@@ -110,7 +110,7 @@ EOF
|
|||||||
msg_ok "Image-processing libraries up to date"
|
msg_ok "Image-processing libraries up to date"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RELEASE="v3.0.1"
|
RELEASE="v3.0.3"
|
||||||
if check_for_gh_release "Immich" "immich-app/immich" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
|
if check_for_gh_release "Immich" "immich-app/immich" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
|
||||||
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
|
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
|
||||||
msg_info "Enabling Maintenance Mode"
|
msg_info "Enabling Maintenance Mode"
|
||||||
@@ -124,7 +124,9 @@ EOF
|
|||||||
systemctl stop immich-web
|
systemctl stop immich-web
|
||||||
systemctl stop immich-ml
|
systemctl stop immich-ml
|
||||||
msg_ok "Stopped Services"
|
msg_ok "Stopped Services"
|
||||||
VCHORD_RELEASE="1.0.0"
|
VCHORD_RELEASE="1.1.1"
|
||||||
|
PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | sort -V | tail -1)
|
||||||
|
PG_VERSION=${PG_VERSION:-16}
|
||||||
[[ -f ~/.vchord_version ]] && mv ~/.vchord_version ~/.vectorchord
|
[[ -f ~/.vchord_version ]] && mv ~/.vchord_version ~/.vectorchord
|
||||||
if check_for_gh_release "VectorChord" "tensorchord/VectorChord" "${VCHORD_RELEASE}" "updated together with Immich after testing"; then
|
if check_for_gh_release "VectorChord" "tensorchord/VectorChord" "${VCHORD_RELEASE}" "updated together with Immich after testing"; then
|
||||||
# dead tuples in smart_search/face_search make the REINDEX below fail with
|
# dead tuples in smart_search/face_search make the REINDEX below fail with
|
||||||
@@ -132,7 +134,7 @@ EOF
|
|||||||
# while still on the old extension version, a post-upgrade vacuum errors instead
|
# while still on the old extension version, a post-upgrade vacuum errors instead
|
||||||
$STD sudo -u postgres psql -d immich -c "VACUUM (ANALYZE) smart_search;"
|
$STD sudo -u postgres psql -d immich -c "VACUUM (ANALYZE) smart_search;"
|
||||||
$STD sudo -u postgres psql -d immich -c "VACUUM (ANALYZE) face_search;"
|
$STD sudo -u postgres psql -d immich -c "VACUUM (ANALYZE) face_search;"
|
||||||
fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-16-vchord_*_$(arch_resolve).deb"
|
fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-${PG_VERSION}-vchord_*_$(arch_resolve).deb"
|
||||||
systemctl restart postgresql
|
systemctl restart postgresql
|
||||||
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vector UPDATE;"
|
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vector UPDATE;"
|
||||||
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vchord UPDATE;"
|
$STD sudo -u postgres psql -d immich -c "ALTER EXTENSION vchord UPDATE;"
|
||||||
@@ -328,6 +330,27 @@ EOF
|
|||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# MickLesk temporary patch for HEIC thumbnail gen
|
||||||
|
msg_info "Patching media.repository.js"
|
||||||
|
MEDIA_REPO_JS="/opt/immich/app/dist/repositories/media.repository.js"
|
||||||
|
if [[ -f "$MEDIA_REPO_JS" ]]; then
|
||||||
|
python3 - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
p = Path('/opt/immich/app/dist/repositories/media.repository.js')
|
||||||
|
s = p.read_text()
|
||||||
|
old = "(0, sharp_1.default)(input).metadata()"
|
||||||
|
new = "(0, sharp_1.default)(input, { unlimited: true, limitInputPixels: false }).metadata()"
|
||||||
|
if new in s:
|
||||||
|
print('hotfix already there')
|
||||||
|
elif old in s:
|
||||||
|
p.write_text(s.replace(old, new, 1))
|
||||||
|
print('hotfix applied')
|
||||||
|
else:
|
||||||
|
print('pattern not found, skipped')
|
||||||
|
PY
|
||||||
|
fi
|
||||||
|
msg_ok "Patched media.repository.js"
|
||||||
|
|
||||||
# chown excluding upload dir contents (may be a mount with restricted permissions)
|
# chown excluding upload dir contents (may be a mount with restricted permissions)
|
||||||
chown immich:immich "$INSTALL_DIR"
|
chown immich:immich "$INSTALL_DIR"
|
||||||
find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 ! -name upload -exec chown -R immich:immich {} +
|
find "$INSTALL_DIR" -maxdepth 1 -mindepth 1 ! -name upload -exec chown -R immich:immich {} +
|
||||||
@@ -478,6 +501,7 @@ function compile_libvips() {
|
|||||||
$STD git clone https://github.com/libvips/libvips.git "$SOURCE"
|
$STD git clone https://github.com/libvips/libvips.git "$SOURCE"
|
||||||
cd "$SOURCE"
|
cd "$SOURCE"
|
||||||
$STD git reset --hard "$LIBVIPS_REVISION"
|
$STD git reset --hard "$LIBVIPS_REVISION"
|
||||||
|
$STD git apply "$BASE_DIR"/server/sources/libvips-patches/0001-put-other-loaders-ahead-of-dcrawload.patch
|
||||||
$STD meson setup build --buildtype=release --libdir=lib -Dintrospection=disabled -Dtiff=disabled
|
$STD meson setup build --buildtype=release --libdir=lib -Dintrospection=disabled -Dtiff=disabled
|
||||||
cd build
|
cd build
|
||||||
$STD ninja install
|
$STD ninja install
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: vhsdream
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/iv-org/invidious
|
||||||
|
|
||||||
|
APP="Invidious"
|
||||||
|
var_tags="${var_tags:-streaming}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-4096}"
|
||||||
|
var_disk="${var_disk:-20}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/invidious ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "Invidious" "iv-org/invidious"; then
|
||||||
|
msg_info "Stopping services"
|
||||||
|
$STD systemctl stop invidious-companion invidious
|
||||||
|
msg_ok "Stopped services"
|
||||||
|
|
||||||
|
create_backup /opt/invidious/config/config.yml
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Invidious" "iv-org/invidious" "tarball" "latest" "/opt/invidious"
|
||||||
|
if check_for_gh_release "Invidious-Companion" "iv-org/invidious-companion"; then
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Invidious-Companion" "iv-org/invidious-companion" "prebuild" "latest" "/opt/invidious-companion" "invidious_companion-$(arch_resolve x86_64 aarch64)-unknown-linux-gnu.tar.gz"
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Rebuilding Invidious"
|
||||||
|
cd /opt/invidious
|
||||||
|
INVIDIOUS_VERSION="$(cat ~/.invidious 2>/dev/null || echo "unknown")"
|
||||||
|
INVIDIOUS_VERSION="${INVIDIOUS_VERSION#v}"
|
||||||
|
sed -i \
|
||||||
|
-e "s~^\(\s*CURRENT_BRANCH\s*=\).*~\1 \"master\"~" \
|
||||||
|
-e "s~^\(\s*CURRENT_COMMIT\s*=\).*~\1 \"\"~" \
|
||||||
|
-e "s~^\(\s*CURRENT_VERSION\s*=\).*~\1 \"${INVIDIOUS_VERSION}\"~" \
|
||||||
|
-e "s~^\(\s*CURRENT_TAG\s*=\).*~\1 \"${INVIDIOUS_VERSION}\"~" \
|
||||||
|
-e "s~^\(\s*ASSET_COMMIT\s*=\).*~\1 \"\"~" \
|
||||||
|
src/invidious.cr
|
||||||
|
$STD make
|
||||||
|
msg_ok "Rebuilt Invidious"
|
||||||
|
|
||||||
|
restore_backup
|
||||||
|
|
||||||
|
msg_info "Starting services"
|
||||||
|
$STD systemctl start invidious invidious-companion
|
||||||
|
msg_ok "Started services"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#!/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://github.com/perber/leafwiki
|
||||||
|
|
||||||
|
APP="LeafWiki"
|
||||||
|
var_tags="${var_tags:-wiki;markdown;notes}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-512}"
|
||||||
|
var_disk="${var_disk:-4}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -f /usr/local/bin/leafwiki ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "leafwiki" "perber/leafwiki"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop leafwiki
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
create_backup /opt/leafwiki/data
|
||||||
|
fetch_and_deploy_gh_release "leafwiki" "perber/leafwiki" "singlefile" "latest" "/usr/local/bin" "leafwiki-v*-linux-$(arch_resolve)"
|
||||||
|
restore_backup
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start leafwiki
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:8080${CL}"
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#!/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: BillyOutlast
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/mudler/LocalAGI
|
||||||
|
|
||||||
|
APP="LocalAGI"
|
||||||
|
var_tags="${var_tags:-ai}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-4096}"
|
||||||
|
var_disk="${var_disk:-20}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-no}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
var_gpu="${var_gpu:-no}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/localagi ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "localagi" "mudler/LocalAGI"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop localagi
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
create_backup /opt/localagi/.env
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "localagi" "mudler/LocalAGI" "tarball" "latest" "/opt/localagi"
|
||||||
|
restore_backup
|
||||||
|
|
||||||
|
msg_info "Building LocalAGI"
|
||||||
|
cd /opt/localagi/webui/react-ui
|
||||||
|
$STD bun install
|
||||||
|
$STD bun run build
|
||||||
|
cd /opt/localagi
|
||||||
|
$STD go build -o /usr/local/bin/localagi
|
||||||
|
msg_ok "Updated LocalAGI successfully"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start localagi
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||||
+18
-13
@@ -31,33 +31,38 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "lychee" "LycheeOrg/Lychee"; then
|
if check_for_gh_release "lychee" "LycheeOrg/Lychee"; then
|
||||||
|
PHP_VER=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
|
||||||
|
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
systemctl stop caddy
|
systemctl stop caddy php${PHP_VER}-fpm
|
||||||
msg_ok "Stopped Services"
|
msg_ok "Stopped Services"
|
||||||
|
|
||||||
msg_info "Backing up Data"
|
create_backup /opt/lychee/.env \
|
||||||
cp /opt/lychee/.env /opt/lychee.env.bak
|
/opt/lychee/storage \
|
||||||
cp -r /opt/lychee/storage /opt/lychee_storage_backup
|
/opt/lychee/public/uploads \
|
||||||
msg_ok "Backed up Data"
|
/opt/lychee/public/dist
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "lychee" "LycheeOrg/Lychee" "prebuild" "latest" "/opt/lychee" "Lychee.zip"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "lychee" "LycheeOrg/Lychee" "prebuild" "latest" "/opt/lychee" "Lychee.zip"
|
||||||
|
|
||||||
msg_info "Restoring Data"
|
restore_backup
|
||||||
cp /opt/lychee.env.bak /opt/lychee/.env
|
|
||||||
rm -f /opt/lychee.env.bak
|
|
||||||
cp -r /opt/lychee_storage_backup/. /opt/lychee/storage
|
|
||||||
rm -rf /opt/lychee_storage_backup
|
|
||||||
msg_ok "Restored Data"
|
|
||||||
|
|
||||||
msg_info "Updating Application"
|
msg_info "Updating Application"
|
||||||
cd /opt/lychee
|
cd /opt/lychee
|
||||||
$STD php artisan migrate --force
|
$STD php artisan migrate --force
|
||||||
|
$STD php artisan config:clear
|
||||||
|
$STD php artisan cache:clear
|
||||||
$STD php artisan optimize:clear
|
$STD php artisan optimize:clear
|
||||||
chmod -R 775 /opt/lychee/storage /opt/lychee/bootstrap/cache
|
$STD php artisan optimize
|
||||||
|
chown -R www-data:www-data /opt/lychee
|
||||||
|
chmod -R 775 /opt/lychee/storage /opt/lychee/bootstrap/cache \
|
||||||
|
/opt/lychee/public/dist /opt/lychee/public/uploads
|
||||||
|
if [[ "${VERBOSE:-no}" = "yes" ]]; then
|
||||||
|
php artisan lychee:diagnostics || true
|
||||||
|
fi
|
||||||
msg_ok "Updated Application"
|
msg_ok "Updated Application"
|
||||||
|
|
||||||
msg_info "Starting Services"
|
msg_info "Starting Services"
|
||||||
systemctl start caddy
|
systemctl start caddy php${PHP_VER}-fpm
|
||||||
msg_ok "Started Services"
|
msg_ok "Started Services"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ EOF
|
|||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$STD npm install -g n8n@2.27.5
|
$STD npm install -g n8n@latest
|
||||||
systemctl restart n8n
|
systemctl restart n8n
|
||||||
msg_ok "Updated n8n"
|
msg_ok "Updated n8n"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ function update_script() {
|
|||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nametag" "mattogodoy/nametag" "tarball" "latest" "/opt/nametag"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nametag" "mattogodoy/nametag" "tarball" "latest" "/opt/nametag"
|
||||||
|
|
||||||
|
# Restore .env BEFORE the build: CLEAN_INSTALL wiped it and the build sources it
|
||||||
|
cp /opt/nametag.env.bak /opt/nametag/.env
|
||||||
|
|
||||||
msg_info "Rebuilding Application"
|
msg_info "Rebuilding Application"
|
||||||
cd /opt/nametag
|
cd /opt/nametag
|
||||||
$STD npm ci
|
$STD npm ci
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#!/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: Mathias Wagner (gnmyt)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://nexterm.dev/
|
||||||
|
|
||||||
|
APP="Nexterm"
|
||||||
|
var_tags="${var_tags:-server-management}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-2048}"
|
||||||
|
var_disk="${var_disk:-6}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -f /opt/nexterm/server/nexterm-server ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "nexterm-engine" "gnmyt/Nexterm"; then
|
||||||
|
msg_info "Stopping nexterm-engine"
|
||||||
|
systemctl stop nexterm-engine
|
||||||
|
msg_ok "Stopped nexterm-engine"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "nexterm-engine" "gnmyt/Nexterm" "prebuild" "latest" "/opt/nexterm/engine" "nexterm-engine-linux-$(arch_resolve "x64" "arm64").tar.gz"
|
||||||
|
|
||||||
|
msg_info "Starting nexterm-engine"
|
||||||
|
systemctl start nexterm-engine
|
||||||
|
msg_ok "Started nexterm-engine"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "nexterm-server" "gnmyt/Nexterm"; then
|
||||||
|
msg_info "Stopping nexterm-server"
|
||||||
|
systemctl stop nexterm-server
|
||||||
|
msg_ok "Stopped nexterm-server"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "nexterm-server" "gnmyt/Nexterm" "singlefile" "latest" "/opt/nexterm/server" "nexterm-server-linux-$(arch_resolve "x64" "arm64")"
|
||||||
|
|
||||||
|
msg_info "Starting nexterm-server"
|
||||||
|
systemctl start nexterm-server
|
||||||
|
msg_ok "Started nexterm-server"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:6989${CL}"
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#!/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://github.com/gamosoft/NoteDiscovery
|
||||||
|
|
||||||
|
APP="NoteDiscovery"
|
||||||
|
var_tags="${var_tags:-notes;wiki;knowledge-base}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-512}"
|
||||||
|
var_disk="${var_disk:-4}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/notediscovery ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "notediscovery" "gamosoft/NoteDiscovery"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop notediscovery
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
create_backup /opt/notediscovery/data /opt/notediscovery/config.yaml
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "notediscovery" "gamosoft/NoteDiscovery" "tarball"
|
||||||
|
|
||||||
|
msg_info "Syncing Dependencies"
|
||||||
|
cd /opt/notediscovery
|
||||||
|
$STD uv sync --no-dev
|
||||||
|
msg_ok "Synced Dependencies"
|
||||||
|
|
||||||
|
restore_backup
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start notediscovery
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:8000${CL}"
|
||||||
+1
-1
@@ -43,7 +43,7 @@ function update_script() {
|
|||||||
grep -o 'https://static\.tp-link\.com/upload/software/[^"]*linux_x64[^"]*\.deb' |
|
grep -o 'https://static\.tp-link\.com/upload/software/[^"]*linux_x64[^"]*\.deb' |
|
||||||
head -n1)
|
head -n1)
|
||||||
OMADA_PKG=$(basename "${OMADA_URL}")
|
OMADA_PKG=$(basename "${OMADA_URL}")
|
||||||
VERSION=$(sed -n 's/.*_v\([0-9.]*\)_.*_\([0-9]\{14\}\)\.deb$/\1-\2/p' <<<"${OMADA_PKG}")
|
VERSION=$(sed -n 's/.*_v\([0-9.]*\)_linux.*/\1/p' <<<"${OMADA_PKG}")
|
||||||
|
|
||||||
CURRENT_VERSION=$(cat $HOME/.omada 2>/dev/null || echo "0")
|
CURRENT_VERSION=$(cat $HOME/.omada 2>/dev/null || echo "0")
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RELEASE="v7.2.1"
|
RELEASE="v7.3.0"
|
||||||
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
|
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
|
||||||
msg_info "Stopping services"
|
msg_info "Stopping services"
|
||||||
systemctl stop opencloud opencloud-wopi
|
systemctl stop opencloud opencloud-wopi
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: vhsdream
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/DioCrafts/OxiCloud
|
||||||
|
|
||||||
|
APP="OxiCloud"
|
||||||
|
var_tags="${var_tags:-files;documents}"
|
||||||
|
var_cpu="${var_cpu:-4}"
|
||||||
|
var_ram="${var_ram:-6144}"
|
||||||
|
var_disk="${var_disk:-20}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/oxicloud ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "OxiCloud" "DioCrafts/OxiCloud"; then
|
||||||
|
msg_info "Stopping OxiCloud"
|
||||||
|
systemctl stop oxicloud
|
||||||
|
msg_ok "Stopped OxiCloud"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "OxiCloud" "DioCrafts/OxiCloud" "tarball" "latest" "/opt/oxicloud"
|
||||||
|
TOOLCHAIN="$(grep -oP 'FROM\s+rust:\K[0-9]+\.[0-9]+(\.[0-9]+)?' /opt/oxicloud/Dockerfile | head -1)"
|
||||||
|
RUST_TOOLCHAIN="${TOOLCHAIN:-stable}" setup_rust
|
||||||
|
|
||||||
|
msg_info "Building Frontend SPA"
|
||||||
|
cd /opt/oxicloud/frontend
|
||||||
|
$STD npm ci
|
||||||
|
$STD npm run build
|
||||||
|
msg_ok "Built Frontend SPA"
|
||||||
|
|
||||||
|
msg_info "Updating OxiCloud (Patience)"
|
||||||
|
set -a
|
||||||
|
source /etc/oxicloud/.env
|
||||||
|
set +a
|
||||||
|
cd /opt/oxicloud
|
||||||
|
export DATABASE_URL
|
||||||
|
export RUSTFLAGS="-C target-cpu=native"
|
||||||
|
RAM_MB=$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo)
|
||||||
|
CARGO_JOBS=$((RAM_MB / 2560))
|
||||||
|
[[ $CARGO_JOBS -lt 1 ]] && CARGO_JOBS=1
|
||||||
|
[[ $CARGO_JOBS -gt $(nproc) ]] && CARGO_JOBS=$(nproc)
|
||||||
|
$STD cargo build --release -j "$CARGO_JOBS" --bin oxicloud --bin migrate-nfc-filenames
|
||||||
|
mv target/release/oxicloud /usr/local/bin/oxicloud
|
||||||
|
mv target/release/migrate-nfc-filenames /usr/local/bin/migrate-nfc-filenames
|
||||||
|
chmod +x /usr/local/bin/oxicloud /usr/local/bin/migrate-nfc-filenames
|
||||||
|
rm -f /usr/bin/oxicloud
|
||||||
|
rm -rf /opt/oxicloud/static
|
||||||
|
mv /opt/oxicloud/static-dist /opt/oxicloud/static
|
||||||
|
rm -rf /opt/oxicloud/target /opt/oxicloud/frontend/node_modules
|
||||||
|
msg_ok "Updated OxiCloud"
|
||||||
|
|
||||||
|
msg_info "Starting OxiCloud"
|
||||||
|
systemctl start oxicloud
|
||||||
|
msg_ok "Started OxiCloud"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:8086${CL}"
|
||||||
+18
-21
@@ -6,7 +6,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
# Source: https://pangolin.net/ | Github: https://github.com/fosrl/pangolin
|
# Source: https://pangolin.net/ | Github: https://github.com/fosrl/pangolin
|
||||||
|
|
||||||
APP="Pangolin"
|
APP="Pangolin"
|
||||||
PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.18.4}"
|
PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.20.0}"
|
||||||
var_tags="${var_tags:-proxy}"
|
var_tags="${var_tags:-proxy}"
|
||||||
var_cpu="${var_cpu:-2}"
|
var_cpu="${var_cpu:-2}"
|
||||||
var_ram="${var_ram:-4096}"
|
var_ram="${var_ram:-4096}"
|
||||||
@@ -33,6 +33,15 @@ function update_script() {
|
|||||||
|
|
||||||
ensure_dependencies build-essential python3
|
ensure_dependencies build-essential python3
|
||||||
|
|
||||||
|
if ! command -v psql &>/dev/null; then
|
||||||
|
msg_error "This installation uses SQLite and cannot be upgraded to Pangolin ${PANGOLIN_VERSION}."
|
||||||
|
echo -e "${INFO}${YW}Starting with Pangolin 1.20.0, PostgreSQL is required as the database backend.${CL}"
|
||||||
|
echo -e "${INFO}${YW}An automatic migration of your existing SQLite data is not supported.${CL}"
|
||||||
|
echo -e "${INFO}${YW}Please create a new LXC with the Pangolin install script, which sets up PostgreSQL automatically.${CL}"
|
||||||
|
echo -e "${INFO}${YW}Your current data is preserved in this container and can be manually migrated if needed.${CL}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
|
|
||||||
if check_for_gh_release "pangolin" "fosrl/pangolin" "$PANGOLIN_VERSION" "Pinned to a tested release because Pangolin's schema changes have repeatedly broken unattended updates. To try a newer version at your own risk, run: 'export PANGOLIN_VERSION=<tag>' and re-run update. If it breaks, please open an issue at https://github.com/community-scripts/ProxmoxVE/issues with the error log."; then
|
if check_for_gh_release "pangolin" "fosrl/pangolin" "$PANGOLIN_VERSION" "Pinned to a tested release because Pangolin's schema changes have repeatedly broken unattended updates. To try a newer version at your own risk, run: 'export PANGOLIN_VERSION=<tag>' and re-run update. If it breaks, please open an issue at https://github.com/community-scripts/ProxmoxVE/issues with the error log."; then
|
||||||
@@ -41,13 +50,8 @@ function update_script() {
|
|||||||
systemctl stop gerbil
|
systemctl stop gerbil
|
||||||
msg_info "Service stopped"
|
msg_info "Service stopped"
|
||||||
|
|
||||||
msg_info "Creating backup"
|
DB_URL=$(sed -n 's/.*connection_string: "\(.*\)".*/\1/p' /opt/pangolin/config/config.yml)
|
||||||
tar -czf /opt/pangolin_config_backup.tar.gz -C /opt/pangolin config
|
create_backup /opt/pangolin/config
|
||||||
if [[ -f /opt/pangolin/config/db/db.sqlite ]]; then
|
|
||||||
cp -a /opt/pangolin/config/db/db.sqlite \
|
|
||||||
"/opt/pangolin/config/db/db.sqlite.pre-${PANGOLIN_VERSION}-$(date +%Y%m%d-%H%M%S).bak"
|
|
||||||
fi
|
|
||||||
msg_ok "Created backup"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VERSION"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VERSION"
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
|
||||||
@@ -55,23 +59,21 @@ function update_script() {
|
|||||||
msg_info "Updating Pangolin"
|
msg_info "Updating Pangolin"
|
||||||
cd /opt/pangolin
|
cd /opt/pangolin
|
||||||
$STD npm ci
|
$STD npm ci
|
||||||
$STD npm run set:sqlite
|
$STD npm run set:pg
|
||||||
$STD npm run set:oss
|
$STD npm run set:oss
|
||||||
rm -rf server/private
|
rm -rf server/private
|
||||||
$STD npm run db:generate
|
DATABASE_URL="$DB_URL" $STD npm run db:generate
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
$STD npm run build:cli
|
$STD npm run build:cli
|
||||||
cp -R .next/standalone ./
|
cp -R .next/standalone ./
|
||||||
|
cp -r server/migrations ./dist/init
|
||||||
chmod +x ./dist/cli.mjs
|
chmod +x ./dist/cli.mjs
|
||||||
cp server/db/names.json ./dist/names.json
|
cp server/db/names.json ./dist/names.json
|
||||||
cp server/db/ios_models.json ./dist/ios_models.json
|
cp server/db/ios_models.json ./dist/ios_models.json
|
||||||
cp server/db/mac_models.json ./dist/mac_models.json
|
cp server/db/mac_models.json ./dist/mac_models.json
|
||||||
msg_ok "Updated Pangolin"
|
msg_ok "Updated Pangolin"
|
||||||
|
|
||||||
msg_info "Restoring config"
|
restore_backup
|
||||||
tar -xzf /opt/pangolin_config_backup.tar.gz -C /opt/pangolin --overwrite
|
|
||||||
rm -f /opt/pangolin_config_backup.tar.gz
|
|
||||||
msg_ok "Restored config"
|
|
||||||
|
|
||||||
if ! grep -q '^ExecStartPre=/usr/bin/node dist/migrations.mjs' /etc/systemd/system/pangolin.service 2>/dev/null; then
|
if ! grep -q '^ExecStartPre=/usr/bin/node dist/migrations.mjs' /etc/systemd/system/pangolin.service 2>/dev/null; then
|
||||||
msg_info "Adding migration step to pangolin.service"
|
msg_info "Adding migration step to pangolin.service"
|
||||||
@@ -82,13 +84,8 @@ function update_script() {
|
|||||||
|
|
||||||
msg_info "Running database migrations"
|
msg_info "Running database migrations"
|
||||||
cd /opt/pangolin
|
cd /opt/pangolin
|
||||||
SQLITE_DB="/opt/pangolin/config/db/db.sqlite"
|
|
||||||
if [[ -f "$SQLITE_DB" ]]; then
|
|
||||||
if ! sqlite3 "$SQLITE_DB" ".tables" 2>/dev/null | tr ' ' '\n' | grep -qx "statusHistory"; then
|
|
||||||
sqlite3 "$SQLITE_DB" "DELETE FROM versionMigrations;" 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
ENVIRONMENT=prod $STD node dist/migrations.mjs
|
ENVIRONMENT=prod $STD node dist/migrations.mjs
|
||||||
|
|
||||||
msg_ok "Ran database migrations"
|
msg_ok "Ran database migrations"
|
||||||
|
|
||||||
msg_info "Updating Badger plugin version"
|
msg_info "Updating Badger plugin version"
|
||||||
@@ -112,4 +109,4 @@ description
|
|||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
echo -e "${GATEWAY}${BGN}https://<YOUR_PANGOLIN_URL>${CL}"
|
echo -e "${GATEWAY}${BGN}https://<YOUR_PANGOLIN_URL> or http://${IP}:3002${CL}"
|
||||||
|
|||||||
+1
-1
@@ -71,7 +71,7 @@ function update_script() {
|
|||||||
cp /opt/pocket-id/.env /opt/env
|
cp /opt/pocket-id/.env /opt/env
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "pocket-id" "pocket-id/pocket-id" "singlefile" "latest" "/opt/pocket-id/" "pocket-id-linux-$(arch_resolve)"
|
fetch_and_deploy_gh_release "pocket-id" "pocket-id/pocket-id" "singlefile" "latest" "/opt/pocket-id/" "pocket-id_linux_$(arch_resolve)"
|
||||||
mv /opt/env /opt/pocket-id/.env
|
mv /opt/env /opt/pocket-id/.env
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
|
|||||||
+4
-2
@@ -41,9 +41,12 @@ function update_script() {
|
|||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "postiz" "gitroomhq/postiz-app" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "postiz" "gitroomhq/postiz-app" "tarball"
|
||||||
|
|
||||||
|
# Restore BEFORE the build: CLEAN_INSTALL wiped /opt/postiz including .env,
|
||||||
|
# and the build below sources it
|
||||||
|
restore_backup
|
||||||
|
|
||||||
msg_info "Building Application"
|
msg_info "Building Application"
|
||||||
cd /opt/postiz
|
cd /opt/postiz
|
||||||
cp /opt/postiz_env.bak /opt/postiz/.env
|
|
||||||
set -a && source /opt/postiz/.env && set +a
|
set -a && source /opt/postiz/.env && set +a
|
||||||
export NODE_OPTIONS="--max-old-space-size=4096"
|
export NODE_OPTIONS="--max-old-space-size=4096"
|
||||||
$STD pnpm install
|
$STD pnpm install
|
||||||
@@ -57,7 +60,6 @@ function update_script() {
|
|||||||
msg_ok "Ran Database Migrations"
|
msg_ok "Ran Database Migrations"
|
||||||
|
|
||||||
mkdir -p /opt/postiz/uploads
|
mkdir -p /opt/postiz/uploads
|
||||||
restore_backup
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
msg_info "Starting Services"
|
||||||
systemctl start postiz-backend postiz-frontend postiz-orchestrator
|
systemctl start postiz-backend postiz-frontend postiz-orchestrator
|
||||||
|
|||||||
+77
-7
@@ -106,13 +106,6 @@ spring.servlet.multipart.max-file-size=5GB
|
|||||||
spring.servlet.multipart.max-request-size=5GB
|
spring.servlet.multipart.max-request-size=5GB
|
||||||
server.tomcat.max-part-count=100
|
server.tomcat.max-part-count=100
|
||||||
|
|
||||||
# Rqueue configuration
|
|
||||||
rqueue.web.enable=false
|
|
||||||
rqueue.job.enabled=false
|
|
||||||
rqueue.message.durability.in-terminal-state=0
|
|
||||||
rqueue.key.prefix=\${spring.cache.redis.key-prefix}
|
|
||||||
rqueue.message.converter.provider.class=com.dedicatedcode.reitti.config.RQueueCustomMessageConverter
|
|
||||||
|
|
||||||
# Application-specific settings
|
# Application-specific settings
|
||||||
reitti.server.advertise-uri=
|
reitti.server.advertise-uri=
|
||||||
|
|
||||||
@@ -168,6 +161,81 @@ PROPEOF
|
|||||||
msg_ok "Rewrote application.properties (backup: application.properties.bak)"
|
msg_ok "Rewrote application.properties (backup: application.properties.bak)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Migrate v4 -> v5: Remove Rqueue configuration (replaced by Quartz Scheduler)
|
||||||
|
if grep -q "^rqueue\." /opt/reitti/application.properties 2>/dev/null; then
|
||||||
|
msg_info "Migrating to v5: Removing Rqueue configuration"
|
||||||
|
sed -i '/^# Rqueue configuration$/d; /^rqueue\./d' /opt/reitti/application.properties
|
||||||
|
msg_ok "Removed Rqueue configuration"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Migrate v4 -> v5: Update application.properties and nginx tile cache for v5 compatibility
|
||||||
|
if grep -q "^reitti\.process-data\.schedule=" /opt/reitti/application.properties 2>/dev/null; then
|
||||||
|
msg_info "Migrating to v5: Updating application.properties"
|
||||||
|
sed -i '/^reitti\.process-data\.schedule=/d' /opt/reitti/application.properties
|
||||||
|
sed -i 's/^reitti\.import\.processing-idle-start-time=.*/reitti.import.grace-time-seconds=30/' /opt/reitti/application.properties
|
||||||
|
sed -i 's/^spring\.datasource\.hikari\.maximum-pool-size=20$/spring.datasource.hikari.maximum-pool-size=30/' /opt/reitti/application.properties
|
||||||
|
grep -q "devices" /opt/reitti/application.properties || \
|
||||||
|
sed -i 's/^spring\.cache\.cache-names=\(.*\)$/spring.cache.cache-names=\1,devices,mapStyles,mapStyleJson/' /opt/reitti/application.properties
|
||||||
|
grep -q "org.quartz.core.ErrorLogger" /opt/reitti/application.properties || \
|
||||||
|
sed -i '/^logging\.level\.com\.dedicatedcode\.reitti=/a logging.level.org.quartz.core.ErrorLogger=FATAL' /opt/reitti/application.properties
|
||||||
|
grep -q "^spring.servlet.multipart.resolve-lazily=" /opt/reitti/application.properties || \
|
||||||
|
sed -i '/^spring\.servlet\.multipart\.max-request-size=/a spring.servlet.multipart.resolve-lazily=true' /opt/reitti/application.properties
|
||||||
|
grep -q "^spring.mvc.async.request-timeout=" /opt/reitti/application.properties || \
|
||||||
|
echo "spring.mvc.async.request-timeout=600000" >>/opt/reitti/application.properties
|
||||||
|
if ! grep -q "^spring.quartz" /opt/reitti/application.properties; then
|
||||||
|
cat >>/opt/reitti/application.properties <<'QUARTZEOF'
|
||||||
|
|
||||||
|
# Quartz Scheduler configuration
|
||||||
|
spring.quartz.job-store-type=jdbc
|
||||||
|
spring.quartz.jdbc.initialize-schema=never
|
||||||
|
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
|
||||||
|
spring.quartz.properties.org.quartz.jobStore.isClustered=false
|
||||||
|
spring.quartz.properties.org.quartz.jobStore.tablePrefix=qrtz_
|
||||||
|
spring.quartz.properties.org.quartz.threadPool.threadCount=5
|
||||||
|
QUARTZEOF
|
||||||
|
fi
|
||||||
|
grep -q "^reitti.import.staging.cleanup.cron=" /opt/reitti/application.properties || \
|
||||||
|
echo "reitti.import.staging.cleanup.cron=0 0 4 * * *" >>/opt/reitti/application.properties
|
||||||
|
grep -q "^reitti.batching.max-batch-size=" /opt/reitti/application.properties || \
|
||||||
|
printf "reitti.batching.max-batch-size=100\nreitti.batching.max-wait-time=5\n" >>/opt/reitti/application.properties
|
||||||
|
grep -q "^reitti.jobs.cleanup.cron=" /opt/reitti/application.properties || \
|
||||||
|
printf "reitti.jobs.cleanup.cron=0 0 4 * * ?\nreitti.jobs.cleanup.max-age-hours=24\n" >>/opt/reitti/application.properties
|
||||||
|
grep -q "^reitti.db-janitor.schedule=" /opt/reitti/application.properties || \
|
||||||
|
echo "reitti.db-janitor.schedule=0 0 4 * * ?" >>/opt/reitti/application.properties
|
||||||
|
msg_ok "Updated application.properties for v5"
|
||||||
|
|
||||||
|
if [[ -f /etc/nginx/nginx.conf ]]; then
|
||||||
|
msg_info "Migrating to v5: Updating nginx tile cache configuration"
|
||||||
|
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.v5
|
||||||
|
cat >/etc/nginx/nginx.conf <<'NGINXEOF'
|
||||||
|
user www-data;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
http {
|
||||||
|
resolver 1.1.1.1 8.8.8.8 valid=30s ipv6=off;
|
||||||
|
proxy_cache_path /var/cache/nginx/tiles levels=1:2 keys_zone=tiles:10m max_size=1g inactive=30d use_temp_path=off;
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
location /custom/ {
|
||||||
|
set $upstream_url $http_x_reitti_upstream_url;
|
||||||
|
proxy_pass $upstream_url;
|
||||||
|
proxy_set_header Host $proxy_host;
|
||||||
|
proxy_set_header User-Agent "Reitti/1.0";
|
||||||
|
proxy_cache tiles;
|
||||||
|
proxy_cache_key $upstream_url;
|
||||||
|
proxy_cache_valid 200 30d;
|
||||||
|
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NGINXEOF
|
||||||
|
systemctl reload nginx
|
||||||
|
msg_ok "Updated nginx tile cache configuration"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "reitti" "dedicatedcode/reitti"; then
|
if check_for_gh_release "reitti" "dedicatedcode/reitti"; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop reitti
|
systemctl stop reitti
|
||||||
@@ -179,10 +247,12 @@ PROPEOF
|
|||||||
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "reitti" "dedicatedcode/reitti" "singlefile" "latest" "/opt/reitti" "reitti-app.jar"
|
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "reitti" "dedicatedcode/reitti" "singlefile" "latest" "/opt/reitti" "reitti-app.jar"
|
||||||
mv /opt/reitti/reitti-*.jar /opt/reitti/reitti.jar
|
mv /opt/reitti/reitti-*.jar /opt/reitti/reitti.jar
|
||||||
|
|
||||||
|
msg_warn "v5 runs a one-time database migration on first start (GPS points → device table). This may take several minutes on large datasets — do not interrupt the container."
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start reitti
|
systemctl start reitti
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
|
msg_warn "Post-upgrade: Verify each API token has a Device assigned in Settings → API Tokens. Tokens without a device cannot ingest location data in v5."
|
||||||
fi
|
fi
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-5
@@ -37,18 +37,29 @@ function update_script() {
|
|||||||
systemctl stop romm-backend romm-worker romm-scheduler romm-watcher
|
systemctl stop romm-backend romm-worker romm-scheduler romm-watcher
|
||||||
msg_ok "Stopped Services"
|
msg_ok "Stopped Services"
|
||||||
|
|
||||||
msg_info "Backing up configuration"
|
create_backup /opt/romm/.env
|
||||||
cp /opt/romm/.env /opt/romm/.env.backup
|
BACKUP_DIR=/opt/romm-players.backup create_backup \
|
||||||
msg_ok "Backed up configuration"
|
/opt/romm/frontend/dist/assets/emulatorjs \
|
||||||
|
/opt/romm/frontend/dist/assets/ruffle
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "romm" "rommapp/romm" "tarball" "latest" "/opt/romm"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "romm" "rommapp/romm" "tarball" "latest" "/opt/romm"
|
||||||
|
|
||||||
|
restore_backup
|
||||||
|
|
||||||
msg_info "Updating ROMM"
|
msg_info "Updating ROMM"
|
||||||
cp /opt/romm/.env.backup /opt/romm/.env
|
|
||||||
cd /opt/romm
|
cd /opt/romm
|
||||||
$STD uv sync --all-extras
|
$STD uv sync --all-extras
|
||||||
cd /opt/romm/backend
|
cd /opt/romm/backend
|
||||||
$STD uv run alembic upgrade head
|
$STD uv run alembic upgrade head
|
||||||
|
if [[ -f /opt/romm/backend/utils/rom_patcher/package.json ]]; then
|
||||||
|
cd /opt/romm/backend/utils/rom_patcher
|
||||||
|
$STD npm install --ignore-scripts --no-audit --no-fund
|
||||||
|
if [[ -d node_modules/rom-patcher/rom-patcher-js ]]; then
|
||||||
|
rm -rf rom-patcher-js
|
||||||
|
cp -r node_modules/rom-patcher/rom-patcher-js ./rom-patcher-js
|
||||||
|
fi
|
||||||
|
rm -rf node_modules
|
||||||
|
fi
|
||||||
cd /opt/romm/frontend
|
cd /opt/romm/frontend
|
||||||
$STD npm install
|
$STD npm install
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
@@ -73,6 +84,12 @@ function update_script() {
|
|||||||
msg_ok "Started Services"
|
msg_ok "Started Services"
|
||||||
msg_ok "Updated successfully"
|
msg_ok "Updated successfully"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "EmulatorJS" "EmulatorJS/EmulatorJS" "v4.2.3"; then
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "EmulatorJS" "EmulatorJS/EmulatorJS" "prebuild" "v4.2.3" "/opt/romm/frontend/dist/assets/emulatorjs" "4.2.3.7z"
|
||||||
|
systemctl restart romm-backend romm-worker romm-scheduler romm-watcher
|
||||||
|
msg_ok "Updated EmulatorJS successfully"
|
||||||
|
fi
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,12 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
setup_deb822_repo \
|
||||||
|
"sftpgo" \
|
||||||
|
"https://oss.sftpgo.com/apt/gpg.key" \
|
||||||
|
"https://oss.sftpgo.com/apt" \
|
||||||
|
"trixie"
|
||||||
|
|
||||||
msg_info "Updating SFTPGo"
|
msg_info "Updating SFTPGo"
|
||||||
$STD apt update
|
$STD apt update
|
||||||
$STD apt upgrade -y
|
$STD apt upgrade -y
|
||||||
|
|||||||
+51
-7
@@ -30,19 +30,63 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "snapotter" "snapotter-hq/SnapOtter"; then
|
NEEDS_V2_MIGRATION=false
|
||||||
|
grep -q '^DB_PATH=' /opt/snapotter_data/.env 2>/dev/null && NEEDS_V2_MIGRATION=true
|
||||||
|
UPDATE_AVAILABLE=false
|
||||||
|
check_for_gh_release "snapotter" "snapotter-hq/SnapOtter" && UPDATE_AVAILABLE=true
|
||||||
|
|
||||||
|
if [[ "$NEEDS_V2_MIGRATION" == true || "$UPDATE_AVAILABLE" == true ]]; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop snapotter
|
systemctl stop snapotter
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "snapotter" "snapotter-hq/SnapOtter" "tarball"
|
PG_VERSION="17" setup_postgresql
|
||||||
|
if ! sudo -u postgres psql -tAc "SELECT 1 FROM pg_database WHERE datname = 'snapotter'" | grep -qx '1'; then
|
||||||
|
PG_DB_NAME="snapotter" PG_DB_USER="snapotter" setup_postgresql_db
|
||||||
|
else
|
||||||
|
PG_DB_NAME="snapotter"
|
||||||
|
PG_DB_USER="snapotter"
|
||||||
|
PG_DB_PASS=$(sed -n 's|^DATABASE_URL=postgres://snapotter:\([^@]*\)@.*|\1|p' /opt/snapotter_data/.env | head -n1)
|
||||||
|
if [[ -z "$PG_DB_PASS" ]]; then
|
||||||
|
msg_error "SnapOtter's PostgreSQL database exists, but its password is not available in /opt/snapotter_data/.env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Installing Redis"
|
||||||
|
$STD apt install -y redis-server
|
||||||
|
if grep -q '^appendonly ' /etc/redis/redis.conf; then
|
||||||
|
sed -i 's/^appendonly .*/appendonly yes/' /etc/redis/redis.conf
|
||||||
|
else
|
||||||
|
echo 'appendonly yes' >>/etc/redis/redis.conf
|
||||||
|
fi
|
||||||
|
$STD systemctl enable --now redis-server
|
||||||
|
msg_ok "Installed Redis"
|
||||||
|
|
||||||
|
msg_info "Migrating SnapOtter Configuration"
|
||||||
|
sed -i '/^DB_PATH=/d; /^DATABASE_URL=/d; /^REDIS_URL=/d; /^SQLITE_MIGRATE_PATH=/d' /opt/snapotter_data/.env
|
||||||
|
cat <<EOF >>/opt/snapotter_data/.env
|
||||||
|
DATABASE_URL=postgres://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}
|
||||||
|
REDIS_URL=redis://127.0.0.1:6379
|
||||||
|
EOF
|
||||||
|
if [[ -f /opt/snapotter_data/snapotter.db ]]; then
|
||||||
|
echo 'SQLITE_MIGRATE_PATH=/opt/snapotter_data/snapotter.db' >>/opt/snapotter_data/.env
|
||||||
|
fi
|
||||||
|
if ! grep -q '^Requires=postgresql.service redis-server.service$' /etc/systemd/system/snapotter.service; then
|
||||||
|
sed -i '/^After=/c\After=network-online.target postgresql.service redis-server.service' /etc/systemd/system/snapotter.service
|
||||||
|
sed -i '/^\[Unit\]/a Wants=network-online.target\nRequires=postgresql.service redis-server.service' /etc/systemd/system/snapotter.service
|
||||||
|
fi
|
||||||
|
systemctl daemon-reload
|
||||||
|
msg_ok "Migrated SnapOtter Configuration"
|
||||||
|
|
||||||
|
if [[ "$UPDATE_AVAILABLE" == true ]]; then
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "snapotter" "snapotter-hq/SnapOtter" "prebuild" "latest" "/opt/snapotter" "snapotter-*-linux-amd64.tar.gz"
|
||||||
|
fi
|
||||||
|
|
||||||
msg_info "Updating SnapOtter"
|
msg_info "Updating SnapOtter"
|
||||||
cd /opt/snapotter
|
$STD uv python install 3.11
|
||||||
$STD npm pkg delete scripts.prepare
|
$STD uv venv --seed --python 3.11 /opt/snapotter_data/ai/venv
|
||||||
$STD pnpm install --frozen-lockfile
|
ln -sfn /opt/snapotter /app
|
||||||
$STD pnpm --filter @snapotter/web build
|
|
||||||
sed -i 's/mediapipe==0.10.21/mediapipe>=0.10.21/' /opt/snapotter/docker/feature-manifest.json
|
|
||||||
msg_ok "Updated SnapOtter"
|
msg_ok "Updated SnapOtter"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
|
|||||||
+2
-2
@@ -32,7 +32,7 @@ function update_script() {
|
|||||||
|
|
||||||
NODE_VERSION="24" NODE_MODULE="corepack,yarn" setup_nodejs
|
NODE_VERSION="24" NODE_MODULE="corepack,yarn" setup_nodejs
|
||||||
|
|
||||||
if check_for_gl_release "storyteller" "storyteller-platform/storyteller"; then
|
if check_for_gl_release "storyteller" "storyteller-platform/storyteller" "" "" "web-v2"; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop storyteller
|
systemctl stop storyteller
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
@@ -41,7 +41,7 @@ function update_script() {
|
|||||||
cp /opt/storyteller/.env /opt/storyteller_env.bak
|
cp /opt/storyteller/.env /opt/storyteller_env.bak
|
||||||
msg_ok "Backed up Data"
|
msg_ok "Backed up Data"
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller"
|
CLEAN_INSTALL=1 fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller" "" "web-v2"
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
msg_info "Restoring Configuration"
|
||||||
mv /opt/storyteller_env.bak /opt/storyteller/.env
|
mv /opt/storyteller_env.bak /opt/storyteller/.env
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#!/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://github.com/Sync-in/server
|
||||||
|
|
||||||
|
APP="Sync-in"
|
||||||
|
var_tags="${var_tags:-files;sync;collaboration}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-2048}"
|
||||||
|
var_disk="${var_disk:-20}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/sync-in/node_modules/@sync-in ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "sync-in" "Sync-in/server"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop sync-in
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
msg_info "Updating Sync-in"
|
||||||
|
$STD npm install --prefix /opt/sync-in "@sync-in/server@${CHECK_UPDATE_RELEASE#v}"
|
||||||
|
msg_ok "Updated Sync-in"
|
||||||
|
|
||||||
|
msg_info "Running Database Migrations"
|
||||||
|
cd /opt/sync-in
|
||||||
|
$STD npx sync-in-server migrate-db
|
||||||
|
msg_ok "Ran Database Migrations"
|
||||||
|
|
||||||
|
VERSION=$(node -pe "require('/opt/sync-in/node_modules/@sync-in/server/package.json').version" 2>/dev/null || echo "")
|
||||||
|
[[ -n "$VERSION" ]] && echo "$VERSION" >~/.sync-in
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start sync-in
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:8080${CL}"
|
||||||
+4
-4
@@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: MickLesk (CanbiZ)
|
# Author: MickLesk (CanbiZ)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/mauriceboe/TREK
|
# Source: https://github.com/liketrek/TREK
|
||||||
|
|
||||||
APP="TREK"
|
APP="TREK"
|
||||||
var_tags="${var_tags:-travel;planning;collaboration}"
|
var_tags="${var_tags:-travel;planning;collaboration}"
|
||||||
@@ -32,7 +32,7 @@ function update_script() {
|
|||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
|
|
||||||
if check_for_gh_release "trek" "mauriceboe/TREK"; then
|
if check_for_gh_release "trek" "liketrek/TREK"; then
|
||||||
MIGRATION=0
|
MIGRATION=0
|
||||||
grep -qF "ExecStart=/usr/bin/node --import tsx src/index.ts" \
|
grep -qF "ExecStart=/usr/bin/node --import tsx src/index.ts" \
|
||||||
/etc/systemd/system/trek.service && MIGRATION=1
|
/etc/systemd/system/trek.service && MIGRATION=1
|
||||||
@@ -47,7 +47,7 @@ function update_script() {
|
|||||||
/opt/trek/data \
|
/opt/trek/data \
|
||||||
/opt/trek/uploads
|
/opt/trek/uploads
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "trek" "mauriceboe/TREK" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "trek" "liketrek/TREK" "tarball"
|
||||||
|
|
||||||
msg_info "Building TREK"
|
msg_info "Building TREK"
|
||||||
cd /opt/trek
|
cd /opt/trek
|
||||||
@@ -79,7 +79,7 @@ function update_script() {
|
|||||||
cat <<EOF >/etc/systemd/system/trek.service
|
cat <<EOF >/etc/systemd/system/trek.service
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=TREK Travel Planner
|
Description=TREK Travel Planner
|
||||||
Documentation=https://github.com/mauriceboe/TREK
|
Documentation=https://github.com/liketrek/TREK
|
||||||
After=network-online.target
|
After=network-online.target
|
||||||
Wants=network-online.target
|
Wants=network-online.target
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,7 @@ function update_script() {
|
|||||||
systemctl stop vikunja
|
systemctl stop vikunja
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary"
|
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "latest" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
|
||||||
$STD systemctl daemon-reload
|
$STD systemctl daemon-reload
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
|
|||||||
+11
-2
@@ -30,12 +30,14 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "wanderer" "Flomp/wanderer"; then
|
if check_for_gh_release "wanderer" "open-wanderer/wanderer"; then
|
||||||
msg_info "Stopping service"
|
msg_info "Stopping service"
|
||||||
systemctl stop wanderer-web
|
systemctl stop wanderer-web
|
||||||
msg_ok "Stopped service"
|
msg_ok "Stopped service"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "wanderer" "open-wanderer/wanderer" "tarball" "latest" "/opt/wanderer/source"
|
create_backup /opt/wanderer/source/search
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "wanderer" "open-wanderer/wanderer" "tarball" "latest" "/opt/wanderer/source"
|
||||||
|
restore_backup
|
||||||
|
|
||||||
msg_info "Updating wanderer"
|
msg_info "Updating wanderer"
|
||||||
cd /opt/wanderer/source/db
|
cd /opt/wanderer/source/db
|
||||||
@@ -44,6 +46,13 @@ function update_script() {
|
|||||||
cd /opt/wanderer/source/web
|
cd /opt/wanderer/source/web
|
||||||
$STD npm ci
|
$STD npm ci
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
|
mkdir -p /opt/wanderer/data/plugins /opt/wanderer/source/db/data
|
||||||
|
[[ -e /opt/wanderer/source/db/data/plugins ]] || ln -sfn /opt/wanderer/data/plugins /opt/wanderer/source/db/data/plugins
|
||||||
|
msg_info "Installing wanderer plugins"
|
||||||
|
for plugin in hammerhead komoot strava; do
|
||||||
|
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "${CHECK_UPDATE_RELEASE:-latest}" "/opt/wanderer/data/plugins" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
|
||||||
|
done
|
||||||
|
msg_ok "Installed wanderer plugins"
|
||||||
msg_ok "Updated wanderer"
|
msg_ok "Updated wanderer"
|
||||||
|
|
||||||
msg_info "Starting service"
|
msg_info "Starting service"
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#!/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://github.com/ulsklyc/yuvomi
|
||||||
|
|
||||||
|
APP="Yuvomi"
|
||||||
|
var_tags="${var_tags:-family;planner;calendar}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-1024}"
|
||||||
|
var_disk="${var_disk:-8}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/yuvomi ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "yuvomi" "ulsklyc/yuvomi"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop yuvomi
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
create_backup /opt/yuvomi/data /opt/yuvomi/.env
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "yuvomi" "ulsklyc/yuvomi" "tarball"
|
||||||
|
|
||||||
|
msg_info "Installing Node.js Dependencies"
|
||||||
|
cd /opt/yuvomi
|
||||||
|
$STD npm ci --omit=dev
|
||||||
|
msg_ok "Installed Node.js Dependencies"
|
||||||
|
|
||||||
|
restore_backup
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start yuvomi
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||||
@@ -43,6 +43,7 @@ $STD php artisan migrate:refresh
|
|||||||
$STD php artisan passport:install -q -n
|
$STD php artisan passport:install -q -n
|
||||||
$STD php artisan storage:link
|
$STD php artisan storage:link
|
||||||
$STD php artisan config:cache
|
$STD php artisan config:cache
|
||||||
|
$STD php artisan 2fauth:fix-passport-key-permissions
|
||||||
chown -R www-data: /opt/2fauth
|
chown -R www-data: /opt/2fauth
|
||||||
chmod -R 755 /opt/2fauth
|
chmod -R 755 /opt/2fauth
|
||||||
msg_ok "Setup 2fauth"
|
msg_ok "Setup 2fauth"
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ BODY_SIZE_LIMIT=Infinity
|
|||||||
ORIGIN='http://$LOCAL_IP:3000'
|
ORIGIN='http://$LOCAL_IP:3000'
|
||||||
EOF
|
EOF
|
||||||
cd /opt/adventurelog/frontend
|
cd /opt/adventurelog/frontend
|
||||||
|
grep -q "^dangerouslyAllowAllBuilds:" ./pnpm-workspace.yaml 2>/dev/null || echo "dangerouslyAllowAllBuilds: true" >>./pnpm-workspace.yaml
|
||||||
$STD pnpm i
|
$STD pnpm i
|
||||||
$STD pnpm build
|
$STD pnpm build
|
||||||
msg_ok "Installed AdventureLog"
|
msg_ok "Installed AdventureLog"
|
||||||
|
|||||||
@@ -0,0 +1,217 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/toeverything/AFFiNE
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt install -y \
|
||||||
|
build-essential \
|
||||||
|
git \
|
||||||
|
pkg-config \
|
||||||
|
openssl \
|
||||||
|
libssl-dev \
|
||||||
|
libjemalloc2 \
|
||||||
|
redis-server \
|
||||||
|
nginx \
|
||||||
|
cmake
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
|
||||||
|
PG_DB_NAME="affine" PG_DB_USER="affine" setup_postgresql_db
|
||||||
|
NODE_VERSION="22" setup_nodejs
|
||||||
|
setup_rust
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "affine_app" "toeverything/AFFiNE" "tarball" "v0.27.2" "/opt/affine"
|
||||||
|
|
||||||
|
msg_info "Setting up Directories"
|
||||||
|
rm -rf /root/.affine
|
||||||
|
mkdir -p /root/.affine/{storage,config}
|
||||||
|
msg_ok "Set up Directories"
|
||||||
|
|
||||||
|
msg_info "Configuring Environment"
|
||||||
|
SECRET_KEY=$(openssl rand -hex 32)
|
||||||
|
cat <<EOF >/opt/affine/.env
|
||||||
|
NODE_ENV=production
|
||||||
|
AFFINE_SERVER_PORT=3010
|
||||||
|
AFFINE_SERVER_HOST=${LOCAL_IP}
|
||||||
|
AFFINE_SERVER_EXTERNAL_URL=http://${LOCAL_IP}
|
||||||
|
DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME}
|
||||||
|
REDIS_SERVER_HOST=localhost
|
||||||
|
REDIS_SERVER_PORT=6379
|
||||||
|
AFFINE_INDEXER_ENABLED=false
|
||||||
|
SECRET_KEY=${SECRET_KEY}
|
||||||
|
EOF
|
||||||
|
msg_ok "Configured Environment"
|
||||||
|
|
||||||
|
msg_info "Building AFFiNE (Patience)"
|
||||||
|
cd /opt/affine
|
||||||
|
source /root/.profile
|
||||||
|
export PATH="/root/.cargo/bin:$PATH"
|
||||||
|
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||||
|
export VITE_CORE_COMMIT_SHA=$(cat ~/.affine_app)
|
||||||
|
# # Initialize git repo (required for build process)
|
||||||
|
export HUSKY=0
|
||||||
|
$STD git init -q
|
||||||
|
$STD git config user.email "build@local"
|
||||||
|
$STD git config user.name "Build"
|
||||||
|
$STD git add -A
|
||||||
|
$STD git commit -q -m "update" --no-verify --allow-empty
|
||||||
|
mkdir -p /opt/affine/.turbo
|
||||||
|
cat <<TURBO >/opt/affine/.turbo/config.json
|
||||||
|
{
|
||||||
|
"concurrency": 1
|
||||||
|
}
|
||||||
|
TURBO
|
||||||
|
$STD corepack enable
|
||||||
|
$STD corepack prepare yarn@4.13.0 --activate
|
||||||
|
$STD yarn config set enableTelemetry 0
|
||||||
|
export NODE_OPTIONS="--max-old-space-size=4096"
|
||||||
|
export TSC_COMPILE_ON_ERROR=true
|
||||||
|
$STD yarn install
|
||||||
|
$STD npm install -g typescript
|
||||||
|
$STD yarn affine @affine/native build
|
||||||
|
$STD yarn affine @affine/server-native build
|
||||||
|
|
||||||
|
# Create architecture-specific symlinks for server-native
|
||||||
|
ln -sf /opt/affine/packages/backend/native/server-native.node \
|
||||||
|
/opt/affine/packages/backend/native/server-native.x64.node
|
||||||
|
ln -sf /opt/affine/packages/backend/native/server-native.node \
|
||||||
|
/opt/affine/packages/backend/native/server-native.arm64.node
|
||||||
|
ln -sf /opt/affine/packages/backend/native/server-native.node \
|
||||||
|
/opt/affine/packages/backend/native/server-native.armv7.node
|
||||||
|
|
||||||
|
$STD yarn affine init
|
||||||
|
$STD yarn affine build -p @affine/reader
|
||||||
|
$STD yarn affine build -p @affine/server
|
||||||
|
export NODE_OPTIONS="--max-old-space-size=4096"
|
||||||
|
$STD yarn affine build -p @affine/web
|
||||||
|
$STD yarn affine build -p @affine/admin
|
||||||
|
mkdir -p /opt/affine/packages/backend/server/static
|
||||||
|
cp -r /opt/affine/packages/frontend/apps/web/dist/* /opt/affine/packages/backend/server/static/
|
||||||
|
mkdir -p /opt/affine/packages/backend/server/static/admin
|
||||||
|
cp -r /opt/affine/packages/frontend/admin/dist/* /opt/affine/packages/backend/server/static/admin/
|
||||||
|
# Create empty mobile manifest (server expects it but we don't build mobile)
|
||||||
|
mkdir -p /opt/affine/packages/backend/server/static/mobile
|
||||||
|
cat <<'MANIFEST' >/opt/affine/packages/backend/server/static/mobile/assets-manifest.json
|
||||||
|
{"publicPath":"/","js":[],"css":[],"gitHash":"","description":""}
|
||||||
|
MANIFEST
|
||||||
|
msg_ok "Built AFFiNE"
|
||||||
|
|
||||||
|
msg_info "Running Initial Migration"
|
||||||
|
cd /opt/affine/packages/backend/server
|
||||||
|
set -a && source /opt/affine/.env && set +a
|
||||||
|
$STD node ./scripts/self-host-predeploy.js
|
||||||
|
msg_ok "Ran Initial Migration"
|
||||||
|
|
||||||
|
msg_info "Creating Services"
|
||||||
|
cat <<EOF >/etc/systemd/system/affine-web.service
|
||||||
|
[Unit]
|
||||||
|
Description=AFFiNE Web Server
|
||||||
|
After=network.target postgresql.service redis-server.service
|
||||||
|
Requires=postgresql.service redis-server.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/opt/affine/packages/backend/server
|
||||||
|
EnvironmentFile=/opt/affine/.env
|
||||||
|
Environment=LD_PRELOAD=libjemalloc.so.2
|
||||||
|
Environment=NODE_OPTIONS=--max-old-space-size=1024
|
||||||
|
ExecStart=/usr/bin/node ./dist/main.js
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF >/etc/systemd/system/affine-worker.service
|
||||||
|
[Unit]
|
||||||
|
Description=AFFiNE Background Worker
|
||||||
|
After=network.target postgresql.service redis-server.service
|
||||||
|
Requires=postgresql.service redis-server.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/opt/affine/packages/backend/server
|
||||||
|
EnvironmentFile=/opt/affine/.env
|
||||||
|
Environment=LD_PRELOAD=libjemalloc.so.2
|
||||||
|
Environment=NODE_OPTIONS=--max-old-space-size=1024
|
||||||
|
ExecStart=/usr/bin/node ./dist/main.js --worker
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl enable -q --now redis-server affine-web affine-worker
|
||||||
|
msg_ok "Created Services"
|
||||||
|
|
||||||
|
msg_info "Creating Admin User"
|
||||||
|
ADMIN_PASS=$(openssl rand -base64 12)
|
||||||
|
for i in {1..30}; do
|
||||||
|
if curl -s http://localhost:3010/info >/dev/null 2>&1; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
# Create admin via API
|
||||||
|
ADMIN_RESPONSE=$(curl -s -X POST http://localhost:3010/api/setup/create-admin-user \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"email\":\"admin@affine.local\",\"password\":\"${ADMIN_PASS}\"}")
|
||||||
|
if echo "$ADMIN_RESPONSE" | grep -q '"id"'; then
|
||||||
|
{
|
||||||
|
echo "AFFiNE Credentials"
|
||||||
|
echo "=================="
|
||||||
|
echo "Email: admin@affine.local"
|
||||||
|
echo "Password: ${ADMIN_PASS}"
|
||||||
|
} >~/affine.creds
|
||||||
|
msg_ok "Created Admin User"
|
||||||
|
else
|
||||||
|
msg_warn "Admin creation skipped (may already exist)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Configuring Nginx"
|
||||||
|
cat <<EOF >/etc/nginx/sites-available/affine.conf
|
||||||
|
upstream affine_backend {
|
||||||
|
server 127.0.0.1:3010;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://affine_backend;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host \$host;
|
||||||
|
proxy_set_header X-Real-IP \$remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||||
|
proxy_set_header Upgrade \$http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_buffering off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
ln -sf /etc/nginx/sites-available/affine.conf /etc/nginx/sites-enabled/
|
||||||
|
rm -f /etc/nginx/sites-enabled/default
|
||||||
|
systemctl enable -q --now nginx
|
||||||
|
msg_ok "Configured Nginx"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -54,12 +54,12 @@ NODE_VERSION="24" setup_nodejs
|
|||||||
setup_yq
|
setup_yq
|
||||||
setup_go
|
setup_go
|
||||||
RUST_PROFILE="minimal" RUST_TOOLCHAIN="stable" setup_rust
|
RUST_PROFILE="minimal" RUST_TOOLCHAIN="stable" setup_rust
|
||||||
UV_PYTHON_INSTALL_DIR="/usr/local/bin" PYTHON_VERSION="3.14.3" setup_uv
|
UV_PYTHON_INSTALL_DIR="/usr/local/bin" PYTHON_VERSION="3.14.6" setup_uv
|
||||||
PG_VERSION="17" setup_postgresql
|
PG_VERSION="17" setup_postgresql
|
||||||
PG_DB_NAME="authentik" PG_DB_USER="authentik" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
PG_DB_NAME="authentik" PG_DB_USER="authentik" PG_DB_GRANT_SUPERUSER="true" setup_postgresql_db
|
||||||
|
|
||||||
XMLSEC_VERSION="1.3.11"
|
XMLSEC_VERSION="1.3.12"
|
||||||
AUTHENTIK_VERSION="version/2026.5.3"
|
AUTHENTIK_VERSION="version/2026.5.5"
|
||||||
fetch_and_deploy_gh_release "xmlsec" "lsh123/xmlsec" "tarball" "${XMLSEC_VERSION}" "/opt/xmlsec"
|
fetch_and_deploy_gh_release "xmlsec" "lsh123/xmlsec" "tarball" "${XMLSEC_VERSION}" "/opt/xmlsec"
|
||||||
fetch_and_deploy_gh_release "authentik" "goauthentik/authentik" "tarball" "${AUTHENTIK_VERSION}" "/opt/authentik"
|
fetch_and_deploy_gh_release "authentik" "goauthentik/authentik" "tarball" "${AUTHENTIK_VERSION}" "/opt/authentik"
|
||||||
fetch_and_deploy_gh_release "geoipupdate" "maxmind/geoipupdate" "binary"
|
fetch_and_deploy_gh_release "geoipupdate" "maxmind/geoipupdate" "binary"
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/daya0576/beaverhabits
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
PYTHON_VERSION="3.14" setup_uv
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "beaverhabits" "daya0576/beaverhabits" "tarball"
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
cd /opt/beaverhabits
|
||||||
|
$STD uv sync --no-dev
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
msg_info "Configuring BeaverHabits"
|
||||||
|
mkdir -p /opt/beaverhabits/.user
|
||||||
|
msg_ok "Configured BeaverHabits"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/beaverhabits.service
|
||||||
|
[Unit]
|
||||||
|
Description=BeaverHabits Habit Tracker
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/beaverhabits
|
||||||
|
Environment=HABITS_STORAGE=USER_DISK
|
||||||
|
Environment=NICEGUI_STORAGE_PATH=/opt/beaverhabits/.user/.nicegui
|
||||||
|
ExecStart=/opt/beaverhabits/.venv/bin/gunicorn beaverhabits.main:app --bind 0.0.0.0:8080 -w 1 -k uvicorn_worker.UvicornWorker --max-requests 10000 --log-level info
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now beaverhabits
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -21,7 +21,7 @@ $STD apt install -y \
|
|||||||
ffmpeg
|
ffmpeg
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "birdnet" "tphakala/birdnet-go" "prebuild" "latest" "/opt/birdnet" "birdnet-go-linux-$(arch_resolve).tar.gz"
|
fetch_and_deploy_gh_release "birdnet" "tphakala/birdnet-go" "prebuild" "latest" "/opt/birdnet" "birdnet-go-linux-$(arch_resolve)*.tar.gz"
|
||||||
|
|
||||||
msg_info "Setting up BirdNET-Go"
|
msg_info "Setting up BirdNET-Go"
|
||||||
cp /opt/birdnet/birdnet-go /usr/local/bin/birdnet-go
|
cp /opt/birdnet/birdnet-go /usr/local/bin/birdnet-go
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ $STD apt install -y \
|
|||||||
libreadline-dev \
|
libreadline-dev \
|
||||||
zlib1g-dev \
|
zlib1g-dev \
|
||||||
libffi-dev \
|
libffi-dev \
|
||||||
|
libleptonica-dev \
|
||||||
|
libleptonica6 \
|
||||||
libvips42 \
|
libvips42 \
|
||||||
libvips-dev \
|
libvips-dev \
|
||||||
libheif1 \
|
libheif1 \
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y git
|
$STD apt install -y git \
|
||||||
|
libusb-1.0-0
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
PYTHON_VERSION="3.12" setup_uv
|
PYTHON_VERSION="3.12" setup_uv
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ msg_info "Installing ASP.NET Core Runtime"
|
|||||||
if [[ "$(arch_resolve)" == "arm64" ]]; then
|
if [[ "$(arch_resolve)" == "arm64" ]]; then
|
||||||
# packages.microsoft.com only ships amd64 debs for Debian; use dotnet-install on arm64
|
# packages.microsoft.com only ships amd64 debs for Debian; use dotnet-install on arm64
|
||||||
curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
|
curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
|
||||||
$STD bash /tmp/dotnet-install.sh --channel 8.0 --runtime aspnetcore --install-dir /usr/lib/dotnet8
|
$STD bash /tmp/dotnet-install.sh --channel 10.0 --runtime aspnetcore --install-dir /usr/lib/dotnet10
|
||||||
ln -sf /usr/lib/dotnet8/dotnet /usr/bin/dotnet
|
ln -sf /usr/lib/dotnet10/dotnet /usr/bin/dotnet
|
||||||
rm -f /tmp/dotnet-install.sh
|
rm -f /tmp/dotnet-install.sh
|
||||||
else
|
else
|
||||||
setup_deb822_repo \
|
setup_deb822_repo \
|
||||||
@@ -35,7 +35,7 @@ else
|
|||||||
"https://packages.microsoft.com/keys/microsoft-2025.asc" \
|
"https://packages.microsoft.com/keys/microsoft-2025.asc" \
|
||||||
"https://packages.microsoft.com/debian/13/prod/" \
|
"https://packages.microsoft.com/debian/13/prod/" \
|
||||||
"trixie"
|
"trixie"
|
||||||
$STD apt install -y aspnetcore-runtime-8.0
|
$STD apt install -y aspnetcore-runtime-10.0
|
||||||
fi
|
fi
|
||||||
msg_ok "Installed ASP.NET Core Runtime"
|
msg_ok "Installed ASP.NET Core Runtime"
|
||||||
|
|
||||||
@@ -55,9 +55,12 @@ if [[ "$install_server" =~ ^[Ss]$ ]]; then
|
|||||||
msg_ok "Installed FileFlows Server"
|
msg_ok "Installed FileFlows Server"
|
||||||
else
|
else
|
||||||
msg_info "Installing FileFlows Node"
|
msg_info "Installing FileFlows Node"
|
||||||
|
read -r -p "${TAB3}Enter FileFlows Server URL (e.g. http://192.168.1.10:19200): " server_url
|
||||||
|
while [[ -z "${server_url// /}" ]]; do
|
||||||
|
read -r -p "${TAB3}Enter FileFlows Server URL (e.g. http://192.168.1.10:19200): " server_url
|
||||||
|
done
|
||||||
cd /opt/fileflows/Node
|
cd /opt/fileflows/Node
|
||||||
$STD dotnet FileFlows.Node.dll
|
$STD dotnet FileFlows.Node.dll --server "$server_url" --systemd install --root true
|
||||||
$STD dotnet FileFlows.Node.dll --systemd install --root true
|
|
||||||
systemctl enable -q --now fileflows-node
|
systemctl enable -q --now fileflows-node
|
||||||
msg_ok "Installed FileFlows Node"
|
msg_ok "Installed FileFlows Node"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ After=network.target
|
|||||||
Type=simple
|
Type=simple
|
||||||
User=root
|
User=root
|
||||||
WorkingDirectory=/opt/gotify
|
WorkingDirectory=/opt/gotify
|
||||||
ExecStart=/opt/gotify/./gotify-linux-$(arch_resolve)
|
ExecStart=/opt/gotify/gotify-linux-$(arch_resolve) serve
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=3
|
RestartSec=3
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: Raffaele (rafspiny)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://getgrav.org/
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt install -y \
|
||||||
|
nginx \
|
||||||
|
logrotate
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
PHP_FPM="YES" setup_php
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "grav" "getgrav/grav" "prebuild" "latest" "/opt/grav" "grav-admin-v*zip"
|
||||||
|
chown -R www-data:www-data /opt/grav
|
||||||
|
|
||||||
|
msg_info "Configuring Nginx"
|
||||||
|
PHP_VER=$(php -r 'echo PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION;')
|
||||||
|
PHP_FPM_SOCK=$(find /run/php -maxdepth 1 -name "php*-fpm.sock" -type s | sort -V | tail -1)
|
||||||
|
unlink /etc/nginx/sites-enabled/default
|
||||||
|
rm -f /etc/nginx/sites-available/default
|
||||||
|
cat <<EOF >/etc/nginx/sites-available/grav
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name _;
|
||||||
|
root /opt/grav;
|
||||||
|
index index.html index.htm index.php;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files \$uri \$uri/ /index.html /index.htm /index.php\$is_args\$args;
|
||||||
|
}
|
||||||
|
|
||||||
|
## Begin - Security
|
||||||
|
location ~* /(\.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
|
||||||
|
location ~* /(system|vendor)/.*\.(txt|xml|md|html|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
|
||||||
|
location ~* /user/.*\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
|
||||||
|
location ~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) { return 403; }
|
||||||
|
## End - Security
|
||||||
|
|
||||||
|
## Begin - API
|
||||||
|
location ^~ /api/ {
|
||||||
|
try_files \$uri \$uri/ /index.php\$is_args\$args;
|
||||||
|
}
|
||||||
|
## End - API
|
||||||
|
|
||||||
|
# deny all direct access to these sensitive user folders, whatever the file type
|
||||||
|
location ~* /user/(accounts|config|env)/.*$ { return 403; }
|
||||||
|
# allow public media uploads under user/data to be served directly;
|
||||||
|
# this must come before the user/data deny so it wins the match
|
||||||
|
location ~* /user/data/.*\.(jpe?g|png|gif|webp|avif|bmp|ico|mp4|webm|ogg|ogv|mov|mp3|wav|m4a|flac|pdf)$ { try_files \$uri =404; }
|
||||||
|
# deny everything else under user/data
|
||||||
|
location ~* /user/data/.*$ { return 403; }
|
||||||
|
|
||||||
|
|
||||||
|
## Begin - Caching
|
||||||
|
location ~* ^/forms-basic-captcha-image.jpg$ {
|
||||||
|
try_files \$uri \$uri/ /index.php\$is_args\$args;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
|
||||||
|
expires 30d;
|
||||||
|
add_header Vary Accept-Encoding;
|
||||||
|
log_not_found off;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~* ^.+\.(?:css|cur|js|jpe?g|gif|htc|ico|png|html|xml|otf|ttf|eot|woff|woff2|svg)$ {
|
||||||
|
access_log off;
|
||||||
|
expires 30d;
|
||||||
|
add_header Cache-Control public;
|
||||||
|
tcp_nodelay off;
|
||||||
|
open_file_cache max=3000 inactive=120s;
|
||||||
|
open_file_cache_valid 45s;
|
||||||
|
open_file_cache_min_uses 2;
|
||||||
|
open_file_cache_errors off;
|
||||||
|
}
|
||||||
|
## End - Caching
|
||||||
|
|
||||||
|
location ~ ^(.+\.php)(.*)$ {
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(.*)$;
|
||||||
|
if (!-f \$document_root\$fastcgi_script_name) { return 404; }
|
||||||
|
fastcgi_pass unix:${PHP_FPM_SOCK};
|
||||||
|
fastcgi_index index.php;
|
||||||
|
include /etc/nginx/fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.ht {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
ln -sf /etc/nginx/sites-available/grav /etc/nginx/sites-enabled/grav
|
||||||
|
systemctl enable -q --now php${PHP_VER}-fpm
|
||||||
|
$STD nginx -t
|
||||||
|
systemctl enable -q --now nginx
|
||||||
|
$STD nginx -s reload
|
||||||
|
msg_ok "Configured Nginx"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -24,6 +24,12 @@ msg_ok "Set up Hyperion repository"
|
|||||||
|
|
||||||
msg_info "Installing Hyperion"
|
msg_info "Installing Hyperion"
|
||||||
$STD apt install -y hyperion
|
$STD apt install -y hyperion
|
||||||
|
mkdir -p /etc/systemd/system/hyperion@.service.d
|
||||||
|
cat <<EOF >/etc/systemd/system/hyperion@.service.d/override.conf
|
||||||
|
[Unit]
|
||||||
|
Requisite=
|
||||||
|
EOF
|
||||||
|
systemctl daemon-reload
|
||||||
systemctl enable -q --now hyperion@root
|
systemctl enable -q --now hyperion@root
|
||||||
msg_ok "Installed Hyperion"
|
msg_ok "Installed Hyperion"
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ PG_VERSION="16" PG_MODULES="pgvector" setup_postgresql
|
|||||||
ACTUAL_PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | sort -V | tail -1)
|
ACTUAL_PG_VERSION=$(ls /etc/postgresql/ 2>/dev/null | sort -V | tail -1)
|
||||||
ACTUAL_PG_VERSION=${ACTUAL_PG_VERSION:-16}
|
ACTUAL_PG_VERSION=${ACTUAL_PG_VERSION:-16}
|
||||||
|
|
||||||
VCHORD_RELEASE="1.0.0"
|
VCHORD_RELEASE="1.1.1"
|
||||||
fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-${ACTUAL_PG_VERSION}-vchord_*_$(arch_resolve).deb"
|
fetch_and_deploy_gh_release "VectorChord" "tensorchord/VectorChord" "binary" "${VCHORD_RELEASE}" "/tmp" "postgresql-${ACTUAL_PG_VERSION}-vchord_*_$(arch_resolve).deb"
|
||||||
|
|
||||||
sed -i "s/^#shared_preload.*/shared_preload_libraries = 'vchord.so'/" /etc/postgresql/${ACTUAL_PG_VERSION}/main/postgresql.conf
|
sed -i "s/^#shared_preload.*/shared_preload_libraries = 'vchord.so'/" /etc/postgresql/${ACTUAL_PG_VERSION}/main/postgresql.conf
|
||||||
@@ -286,6 +286,7 @@ LIBVIPS_REVISION="e01a4797cabe77d457fdfa7d776b7a7e7ca6d6a7"
|
|||||||
$STD git clone https://github.com/libvips/libvips.git "$SOURCE"
|
$STD git clone https://github.com/libvips/libvips.git "$SOURCE"
|
||||||
cd "$SOURCE"
|
cd "$SOURCE"
|
||||||
$STD git reset --hard "$LIBVIPS_REVISION"
|
$STD git reset --hard "$LIBVIPS_REVISION"
|
||||||
|
$STD git apply "$BASE_DIR"/server/sources/libvips-patches/0001-put-other-loaders-ahead-of-dcrawload.patch
|
||||||
$STD meson setup build --buildtype=release --libdir=lib -Dintrospection=disabled -Dtiff=disabled
|
$STD meson setup build --buildtype=release --libdir=lib -Dintrospection=disabled -Dtiff=disabled
|
||||||
cd build
|
cd build
|
||||||
$STD ninja install
|
$STD ninja install
|
||||||
@@ -311,7 +312,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" "v3.0.1" "$SRC_DIR"
|
fetch_and_deploy_gh_release "Immich" "immich-app/immich" "tarball" "v3.0.3" "$SRC_DIR"
|
||||||
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1] | split("+")[0]' ${SRC_DIR}/package.json)"
|
PNPM_VERSION="$(jq -r '.packageManager | split("@")[1] | split("+")[0]' ${SRC_DIR}/package.json)"
|
||||||
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||||
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
|
NODE_VERSION="24" NODE_MODULE="corepack" setup_nodejs
|
||||||
@@ -437,6 +438,27 @@ cd "$INSTALL_DIR"
|
|||||||
ln -s "$GEO_DIR" "$APP_DIR"
|
ln -s "$GEO_DIR" "$APP_DIR"
|
||||||
msg_ok "Installed GeoNames data"
|
msg_ok "Installed GeoNames data"
|
||||||
|
|
||||||
|
# MickLesk temporary patch for HEIC thumbnail gen
|
||||||
|
msg_info "Patching media.repository.js"
|
||||||
|
MEDIA_REPO_JS="/opt/immich/app/dist/repositories/media.repository.js"
|
||||||
|
if [[ -f "$MEDIA_REPO_JS" ]]; then
|
||||||
|
python3 - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
p = Path('/opt/immich/app/dist/repositories/media.repository.js')
|
||||||
|
s = p.read_text()
|
||||||
|
old = "(0, sharp_1.default)(input).metadata()"
|
||||||
|
new = "(0, sharp_1.default)(input, { unlimited: true, limitInputPixels: false }).metadata()"
|
||||||
|
if new in s:
|
||||||
|
print('hotfix already there')
|
||||||
|
elif old in s:
|
||||||
|
p.write_text(s.replace(old, new, 1))
|
||||||
|
print('hotfix applied')
|
||||||
|
else:
|
||||||
|
print('pattern not found, skipped')
|
||||||
|
PY
|
||||||
|
fi
|
||||||
|
msg_ok "Patched media.repository.js"
|
||||||
|
|
||||||
mkdir -p /var/log/immich
|
mkdir -p /var/log/immich
|
||||||
touch /var/log/immich/{web.log,ml.log}
|
touch /var/log/immich/{web.log,ml.log}
|
||||||
msg_ok "Installed Immich"
|
msg_ok "Installed Immich"
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
#!/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/iv-org/invidious
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt install -y \
|
||||||
|
build-essential \
|
||||||
|
git \
|
||||||
|
pkg-config \
|
||||||
|
libssl-dev \
|
||||||
|
libxml2-dev \
|
||||||
|
libyaml-dev \
|
||||||
|
libgmp-dev \
|
||||||
|
libreadline-dev \
|
||||||
|
librsvg2-bin \
|
||||||
|
libsqlite3-dev \
|
||||||
|
zlib1g-dev \
|
||||||
|
libpcre2-dev \
|
||||||
|
libevent-dev \
|
||||||
|
fonts-open-sans
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
if [[ "$(arch_resolve amd64 arm64)" == "amd64" ]]; then
|
||||||
|
setup_deb822_repo "crystal" "https://download.opensuse.org/repositories/devel:/languages:/crystal/Debian_13/Release.key" "https://download.opensuse.org/repositories/devel:/languages:/crystal/Debian_13/" "./"
|
||||||
|
$STD apt install -y crystal
|
||||||
|
else
|
||||||
|
fetch_and_deploy_gh_release "Crystal" "crystal-lang/crystal" "prebuild" "latest" "/opt/crystal" "crystal-*-linux-aarch64-bundled.tar.gz"
|
||||||
|
ln -sf /opt/crystal/bin/crystal /usr/local/bin/crystal
|
||||||
|
ln -sf /opt/crystal/bin/shards /usr/local/bin/shards
|
||||||
|
fi
|
||||||
|
|
||||||
|
PG_VERSION="17" setup_postgresql
|
||||||
|
PG_DB_NAME="invidious" PG_DB_USER="invidious" setup_postgresql_db
|
||||||
|
fetch_and_deploy_gh_release "Invidious" "iv-org/invidious" "tarball" "latest" "/opt/invidious"
|
||||||
|
fetch_and_deploy_gh_release "Invidious Companion" "iv-org/invidious-companion" "prebuild" "latest" "/opt/invidious-companion" "invidious_companion-$(arch_resolve x86_64 aarch64)-unknown-linux-gnu.tar.gz"
|
||||||
|
|
||||||
|
msg_info "Building Invidious"
|
||||||
|
cd /opt/invidious
|
||||||
|
INVIDIOUS_VERSION="$(cat ~/.invidious 2>/dev/null || echo "unknown")"
|
||||||
|
INVIDIOUS_VERSION="${INVIDIOUS_VERSION#v}"
|
||||||
|
sed -i \
|
||||||
|
-e "s~^\(\s*CURRENT_BRANCH\s*=\).*~\1 \"master\"~" \
|
||||||
|
-e "s~^\(\s*CURRENT_COMMIT\s*=\).*~\1 \"\"~" \
|
||||||
|
-e "s~^\(\s*CURRENT_VERSION\s*=\).*~\1 \"${INVIDIOUS_VERSION}\"~" \
|
||||||
|
-e "s~^\(\s*CURRENT_TAG\s*=\).*~\1 \"${INVIDIOUS_VERSION}\"~" \
|
||||||
|
-e "s~^\(\s*ASSET_COMMIT\s*=\).*~\1 \"\"~" \
|
||||||
|
src/invidious.cr
|
||||||
|
$STD make
|
||||||
|
msg_ok "Built Invidious"
|
||||||
|
|
||||||
|
msg_info "Configuring Invidious"
|
||||||
|
SECRET_KEY="$(openssl rand -hex 8)"
|
||||||
|
HMAC_KEY="$(openssl rand -hex 32)"
|
||||||
|
sed -e '\~^db:~,\~dbname:~d' \
|
||||||
|
-e "s~^#database_.*~database_url: postgres://${PG_DB_USER}:${PG_DB_PASS}@localhost:5432/${PG_DB_NAME}~" \
|
||||||
|
-e 's~^#check_tables.*~check_tables: true~' \
|
||||||
|
-e 's~^#invidious_companion:~invidious_companion:~' \
|
||||||
|
-e 's~^# - private_~ - private_~' \
|
||||||
|
-e "s~^#invidious_companion_key:.*~invidious_companion_key: \"${SECRET_KEY}\"~" \
|
||||||
|
-e "s~^hmac_key:.*~hmac_key: \"${HMAC_KEY}\"~" \
|
||||||
|
/opt/invidious/config/config.example.yml >/opt/invidious/config/config.yml
|
||||||
|
chmod 600 /opt/invidious/config/config.yml
|
||||||
|
|
||||||
|
cat <<EOF >/etc/logrotate.d/invidious.logrotate
|
||||||
|
/opt/invidious/invidious.log {
|
||||||
|
rotate 4
|
||||||
|
weekly
|
||||||
|
notifempty
|
||||||
|
missingok
|
||||||
|
compress
|
||||||
|
minsize 1048576
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
chmod 0644 /etc/logrotate.d/invidious.logrotate
|
||||||
|
msg_ok "Configured Invidious"
|
||||||
|
|
||||||
|
msg_info "Migrating database"
|
||||||
|
$STD ./invidious --migrate
|
||||||
|
msg_ok "Migrated database"
|
||||||
|
|
||||||
|
msg_info "Configuring services"
|
||||||
|
sed -e 's|^User=invidious|User=root|' \
|
||||||
|
-e 's|^Group=invidious|Group=root|' \
|
||||||
|
-e 's|/home/invidious/invidious|/opt/invidious|g' \
|
||||||
|
/opt/invidious/invidious.service >/etc/systemd/system/invidious.service
|
||||||
|
mkdir -p /var/tmp/youtubei.js
|
||||||
|
cat <<EOF >/etc/systemd/system/invidious-companion.service
|
||||||
|
[Unit]
|
||||||
|
Description=Invidious Companion
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/invidious-companion
|
||||||
|
Environment=SERVER_SECRET_KEY=${SECRET_KEY}
|
||||||
|
Environment=CACHE_DIRECTORY=/var/tmp/youtubei.js
|
||||||
|
ExecStart=/opt/invidious-companion/invidious_companion
|
||||||
|
Restart=always
|
||||||
|
RestartSec=2s
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl -q enable --now invidious invidious-companion
|
||||||
|
msg_ok "Configured services"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/perber/leafwiki
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "leafwiki" "perber/leafwiki" "singlefile" "latest" "/usr/local/bin" "leafwiki-v*-linux-$(arch_resolve)"
|
||||||
|
|
||||||
|
msg_info "Configuring LeafWiki"
|
||||||
|
mkdir -p /opt/leafwiki/data
|
||||||
|
mkdir -p /etc/leafwiki
|
||||||
|
JWT_SECRET=$(openssl rand -hex 32)
|
||||||
|
ADMIN_PASS=$(openssl rand -base64 12 | tr -dc 'a-zA-Z0-9' | head -c12)
|
||||||
|
cat <<EOF >/etc/leafwiki/.env
|
||||||
|
LEAFWIKI_DATA_DIR=/opt/leafwiki/data
|
||||||
|
LEAFWIKI_HOST=0.0.0.0
|
||||||
|
LEAFWIKI_PORT=8080
|
||||||
|
LEAFWIKI_JWT_SECRET=${JWT_SECRET}
|
||||||
|
LEAFWIKI_ADMIN_PASSWORD=${ADMIN_PASS}
|
||||||
|
LEAFWIKI_ALLOW_INSECURE=true
|
||||||
|
EOF
|
||||||
|
msg_ok "Configured LeafWiki"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/leafwiki.service
|
||||||
|
[Unit]
|
||||||
|
Description=LeafWiki
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
EnvironmentFile=/etc/leafwiki/.env
|
||||||
|
ExecStart=/usr/local/bin/leafwiki
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now leafwiki
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: BillyOutlast
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/mudler/LocalAGI
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
APP="LocalAGI"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt install -y build-essential
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
NODE_VERSION="24" setup_nodejs
|
||||||
|
setup_go
|
||||||
|
|
||||||
|
msg_info "Installing Bun"
|
||||||
|
export BUN_INSTALL="/root/.bun"
|
||||||
|
curl -fsSL https://bun.sh/install | $STD bash
|
||||||
|
ln -sf /root/.bun/bin/bun /usr/local/bin/bun
|
||||||
|
ln -sf /root/.bun/bin/bunx /usr/local/bin/bunx
|
||||||
|
msg_ok "Installed Bun"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "localagi" "mudler/LocalAGI" "tarball" "latest" "/opt/localagi"
|
||||||
|
|
||||||
|
msg_info "Configuring LocalAGI"
|
||||||
|
mkdir -p /opt/localagi/pool
|
||||||
|
cat <<'EOF' >/opt/localagi/.env
|
||||||
|
LOCALAGI_MODEL=gemma-3-4b-it-qat
|
||||||
|
LOCALAGI_MULTIMODAL_MODEL=moondream2-20250414
|
||||||
|
LOCALAGI_IMAGE_MODEL=sd-1.5-ggml
|
||||||
|
LOCALAGI_LLM_API_URL=http://127.0.0.1:11434/v1
|
||||||
|
LOCALAGI_STATE_DIR=/opt/localagi/pool
|
||||||
|
EOF
|
||||||
|
msg_ok "Configured LocalAGI"
|
||||||
|
|
||||||
|
msg_info "Setting up LocalAGI"
|
||||||
|
cd /opt/localagi/webui/react-ui
|
||||||
|
$STD bun install
|
||||||
|
$STD bun run build
|
||||||
|
cd /opt/localagi
|
||||||
|
$STD go build -o /usr/local/bin/localagi
|
||||||
|
msg_ok "Set up LocalAGI"
|
||||||
|
|
||||||
|
msg_info "Creating LocalAGI systemd service"
|
||||||
|
cat <<EOF >/etc/systemd/system/localagi.service
|
||||||
|
[Unit]
|
||||||
|
Description=LocalAGI
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=root
|
||||||
|
Type=simple
|
||||||
|
EnvironmentFile=/opt/localagi/.env
|
||||||
|
|
||||||
|
WorkingDirectory=/opt/localagi
|
||||||
|
ExecStart=/usr/local/bin/localagi
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now localagi
|
||||||
|
msg_ok "Created LocalAGI systemd service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -31,13 +31,14 @@ NODE_VERSION="24" NODE_MODULE="corepack,yarn" setup_nodejs
|
|||||||
|
|
||||||
fetch_and_deploy_gh_release "manyfold" "manyfold3d/manyfold" "tarball" "latest" "/opt/manyfold/app"
|
fetch_and_deploy_gh_release "manyfold" "manyfold3d/manyfold" "tarball" "latest" "/opt/manyfold/app"
|
||||||
|
|
||||||
|
useradd -m -s /usr/bin/bash manyfold
|
||||||
|
|
||||||
RUBY_INSTALL_VERSION=$(cat /opt/manyfold/app/.ruby-version)
|
RUBY_INSTALL_VERSION=$(cat /opt/manyfold/app/.ruby-version)
|
||||||
RUBY_VERSION=${RUBY_INSTALL_VERSION} RUBY_INSTALL_RAILS="true" HOME=/home/manyfold setup_ruby
|
RUBY_VERSION=${RUBY_INSTALL_VERSION} RUBY_INSTALL_RAILS="true" HOME=/home/manyfold setup_ruby
|
||||||
|
|
||||||
msg_info "Configuring Manyfold"
|
msg_info "Configuring Manyfold"
|
||||||
YARN_VERSION=$(grep '"packageManager":' /opt/manyfold/app/package.json | sed -E 's/.*"(yarn@[0-9\.]+)".*/\1/')
|
YARN_VERSION=$(grep '"packageManager":' /opt/manyfold/app/package.json | sed -E 's/.*"(yarn@[0-9\.]+)".*/\1/')
|
||||||
RELEASE=$(get_latest_github_release "manyfold3d/manyfold")
|
RELEASE=$(get_latest_github_release "manyfold3d/manyfold")
|
||||||
useradd -m -s /usr/bin/bash manyfold
|
|
||||||
cat <<EOF >/opt/manyfold/.env
|
cat <<EOF >/opt/manyfold/.env
|
||||||
export APP_VERSION=${RELEASE}
|
export APP_VERSION=${RELEASE}
|
||||||
export GUID=1002
|
export GUID=1002
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ update_os
|
|||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y \
|
$STD apt install -y \
|
||||||
build-essential \
|
build-essential \
|
||||||
python3 \
|
|
||||||
python3-setuptools \
|
python3-setuptools \
|
||||||
graphicsmagick
|
graphicsmagick
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
@@ -24,7 +23,7 @@ msg_ok "Installed Dependencies"
|
|||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
|
|
||||||
msg_info "Installing n8n (Patience)"
|
msg_info "Installing n8n (Patience)"
|
||||||
$STD npm install -g n8n@2.27.5
|
$STD npm install -g n8n@latest
|
||||||
msg_ok "Installed n8n"
|
msg_ok "Installed n8n"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: Mathias Wagner (gnmyt)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://nexterm.dev/
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "nexterm-engine" "gnmyt/Nexterm" "prebuild" "latest" "/opt/nexterm/engine" "nexterm-engine-linux-$(arch_resolve "x64" "arm64").tar.gz"
|
||||||
|
fetch_and_deploy_gh_release "nexterm-server" "gnmyt/Nexterm" "singlefile" "latest" "/opt/nexterm/server" "nexterm-server-linux-$(arch_resolve "x64" "arm64")"
|
||||||
|
|
||||||
|
msg_info "Configuring Nexterm"
|
||||||
|
LOCAL_ENGINE_TOKEN=$(tr -d '-' </proc/sys/kernel/random/uuid)$(tr -d '-' </proc/sys/kernel/random/uuid)
|
||||||
|
ENCRYPTION_KEY=$(tr -d '-' </proc/sys/kernel/random/uuid)$(tr -d '-' </proc/sys/kernel/random/uuid)
|
||||||
|
mkdir -p /etc/nexterm-engine /etc/nexterm-server /opt/nexterm/data
|
||||||
|
cat <<EOF >/etc/nexterm-engine/config.yaml
|
||||||
|
server_host: "127.0.0.1"
|
||||||
|
server_port: 7800
|
||||||
|
registration_token: "${LOCAL_ENGINE_TOKEN}"
|
||||||
|
tls: false
|
||||||
|
EOF
|
||||||
|
cat <<EOF >/etc/nexterm-server/server.env
|
||||||
|
NODE_ENV=production
|
||||||
|
SERVER_PORT=6989
|
||||||
|
LOCAL_ENGINE_TOKEN=${LOCAL_ENGINE_TOKEN}
|
||||||
|
ENCRYPTION_KEY=${ENCRYPTION_KEY}
|
||||||
|
EOF
|
||||||
|
chmod 0640 /etc/nexterm-engine/config.yaml /etc/nexterm-server/server.env
|
||||||
|
msg_ok "Configured Nexterm"
|
||||||
|
|
||||||
|
msg_info "Creating Services"
|
||||||
|
cat <<EOF >/etc/systemd/system/nexterm-server.service
|
||||||
|
[Unit]
|
||||||
|
Description=Nexterm Server
|
||||||
|
Documentation=https://docs.nexterm.dev/
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/nexterm/data
|
||||||
|
EnvironmentFile=/etc/nexterm-server/server.env
|
||||||
|
ExecStart=/opt/nexterm/server/nexterm-server
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
cat <<EOF >/etc/systemd/system/nexterm-engine.service
|
||||||
|
[Unit]
|
||||||
|
Description=Nexterm Engine
|
||||||
|
Documentation=https://docs.nexterm.dev/
|
||||||
|
After=network-online.target nexterm-server.service
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/etc/nexterm-engine
|
||||||
|
Environment=FREERDP_EXTENSION_PATH=/opt/nexterm/engine/lib/freerdp2
|
||||||
|
Environment=LD_LIBRARY_PATH=/opt/nexterm/engine/lib
|
||||||
|
ExecStart=/opt/nexterm/engine/nexterm-engine
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now nexterm-server
|
||||||
|
sleep 5
|
||||||
|
systemctl enable -q --now nexterm-engine
|
||||||
|
msg_ok "Created Services"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/gamosoft/NoteDiscovery
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
setup_uv
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "notediscovery" "gamosoft/NoteDiscovery" "tarball"
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
cd /opt/notediscovery
|
||||||
|
$STD uv sync --no-dev
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
msg_info "Configuring NoteDiscovery"
|
||||||
|
mkdir -p /opt/notediscovery/data
|
||||||
|
msg_ok "Configured NoteDiscovery"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/notediscovery.service
|
||||||
|
[Unit]
|
||||||
|
Description=NoteDiscovery Knowledge Base
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/notediscovery
|
||||||
|
ExecStart=/opt/notediscovery/.venv/bin/python /opt/notediscovery/run.py
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now notediscovery
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -42,7 +42,7 @@ OMADA_PKG=$(basename "${OMADA_URL}")
|
|||||||
curl_download "${OMADA_PKG}" "${OMADA_URL}"
|
curl_download "${OMADA_PKG}" "${OMADA_URL}"
|
||||||
$STD dpkg -i "${OMADA_PKG}"
|
$STD dpkg -i "${OMADA_PKG}"
|
||||||
rm -rf "${OMADA_PKG}"
|
rm -rf "${OMADA_PKG}"
|
||||||
VERSION=$(sed -n 's/.*_v\([0-9.]*\)_.*_\([0-9]\{14\}\)\.deb$/\1-\2/p' <<<"${OMADA_PKG}")
|
VERSION=$(sed -n 's/.*_v\([0-9.]*\)_linux.*/\1/p' <<<"${OMADA_PKG}")
|
||||||
echo "${VERSION}" >$HOME/.omada
|
echo "${VERSION}" >$HOME/.omada
|
||||||
msg_ok "Installed Omada Controller"
|
msg_ok "Installed Omada Controller"
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ $STD sudo -u cool coolconfig set-admin-password --user=admin --password="$COOLPA
|
|||||||
echo "$COOLPASS" >~/.coolpass
|
echo "$COOLPASS" >~/.coolpass
|
||||||
msg_ok "Installed Collabora Online"
|
msg_ok "Installed Collabora Online"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "v7.2.1" "/usr/bin" "opencloud-*-linux-$(arch_resolve)"
|
fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "v7.3.0" "/usr/bin" "opencloud-*-linux-$(arch_resolve)"
|
||||||
mv /usr/bin/OpenCloud /usr/bin/opencloud
|
mv /usr/bin/OpenCloud /usr/bin/opencloud
|
||||||
|
|
||||||
msg_info "Configuring OpenCloud"
|
msg_info "Configuring OpenCloud"
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
#!/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/DioCrafts/OxiCloud
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt install -y build-essential
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
NODE_VERSION="24" setup_nodejs
|
||||||
|
PG_VERSION="17" setup_postgresql
|
||||||
|
PG_DB_NAME="oxicloud" PG_DB_USER="oxicloud" setup_postgresql_db
|
||||||
|
fetch_and_deploy_gh_release "OxiCloud" "DioCrafts/OxiCloud" "tarball" "latest" "/opt/oxicloud"
|
||||||
|
TOOLCHAIN="$(grep -oP 'FROM\s+rust:\K[0-9]+\.[0-9]+(\.[0-9]+)?' /opt/oxicloud/Dockerfile | head -1)"
|
||||||
|
RUST_TOOLCHAIN="${TOOLCHAIN:-stable}" setup_rust
|
||||||
|
|
||||||
|
msg_info "Building Frontend SPA"
|
||||||
|
cd /opt/oxicloud/frontend
|
||||||
|
$STD npm ci
|
||||||
|
$STD npm run build
|
||||||
|
msg_ok "Built Frontend SPA"
|
||||||
|
|
||||||
|
msg_info "Building OxiCloud (Patience)"
|
||||||
|
cd /opt/oxicloud
|
||||||
|
export DATABASE_URL="postgres://${PG_DB_USER}:${PG_DB_PASS}@localhost/${PG_DB_NAME}"
|
||||||
|
export RUSTFLAGS="-C target-cpu=native"
|
||||||
|
RAM_MB=$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo)
|
||||||
|
CARGO_JOBS=$((RAM_MB / 2560))
|
||||||
|
[[ $CARGO_JOBS -lt 1 ]] && CARGO_JOBS=1
|
||||||
|
[[ $CARGO_JOBS -gt $(nproc) ]] && CARGO_JOBS=$(nproc)
|
||||||
|
$STD cargo build --release -j "$CARGO_JOBS" --bin oxicloud --bin migrate-nfc-filenames
|
||||||
|
mv target/release/oxicloud /usr/local/bin/oxicloud
|
||||||
|
mv target/release/migrate-nfc-filenames /usr/local/bin/migrate-nfc-filenames
|
||||||
|
rm -rf /opt/oxicloud/static
|
||||||
|
mv /opt/oxicloud/static-dist /opt/oxicloud/static
|
||||||
|
rm -rf /opt/oxicloud/target /opt/oxicloud/frontend/node_modules
|
||||||
|
msg_ok "Built OxiCloud"
|
||||||
|
|
||||||
|
msg_info "Configuring OxiCloud"
|
||||||
|
mkdir -p {/mnt/oxicloud,/etc/oxicloud}
|
||||||
|
sed -e 's|OXICLOUD_STORAGE_PATH=.*|OXICLOUD_STORAGE_PATH=/mnt/oxicloud|' \
|
||||||
|
-e 's|OXICLOUD_SERVER_HOST=.*|OXICLOUD_SERVER_HOST=0.0.0.0|' \
|
||||||
|
-e 's|OXICLOUD_STATIC_PATH=.*|OXICLOUD_STATIC_PATH=/opt/oxicloud/static|' \
|
||||||
|
-e "s|^#OXICLOUD_BASE_URL=.*|OXICLOUD_BASE_URL=http://${LOCAL_IP}:8086|" \
|
||||||
|
-e "s|OXICLOUD_DB_CONNECTION_STRING=.*|OXICLOUD_DB_CONNECTION_STRING=${DATABASE_URL}|" \
|
||||||
|
-e "s|^DATABASE_URL=.*|DATABASE_URL=${DATABASE_URL}|" \
|
||||||
|
-e "s|^#OXICLOUD_JWT_SECRET=.*|OXICLOUD_JWT_SECRET=$(openssl rand -hex 32)|" \
|
||||||
|
/opt/oxicloud/example.env >/etc/oxicloud/.env
|
||||||
|
chmod 600 /etc/oxicloud/.env
|
||||||
|
msg_ok "Configured OxiCloud"
|
||||||
|
|
||||||
|
msg_info "Creating OxiCloud Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/oxicloud.service
|
||||||
|
[Unit]
|
||||||
|
Description=OxiCloud Service
|
||||||
|
After=network.target postgresql.service
|
||||||
|
Requires=postgresql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/oxicloud
|
||||||
|
EnvironmentFile=/etc/oxicloud/.env
|
||||||
|
ExecStart=/usr/local/bin/oxicloud
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now oxicloud
|
||||||
|
msg_ok "Created OxiCloud Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -16,18 +16,19 @@ update_os
|
|||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y \
|
$STD apt install -y \
|
||||||
build-essential \
|
build-essential \
|
||||||
python3 \
|
|
||||||
sqlite3 \
|
|
||||||
iptables
|
iptables
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.18.4}"
|
PG_VERSION="17" setup_postgresql
|
||||||
|
PG_DB_NAME="pangolin" PG_DB_USER="pangolin" setup_postgresql_db
|
||||||
|
PANGOLIN_VERSION="${PANGOLIN_VERSION:-1.20.0}"
|
||||||
fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VERSION"
|
fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VERSION"
|
||||||
fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
|
fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
|
||||||
fetch_and_deploy_gh_release "traefik" "traefik/traefik" "prebuild" "latest" "/usr/bin" "traefik_v*_linux_$(arch_resolve).tar.gz"
|
fetch_and_deploy_gh_release "traefik" "traefik/traefik" "prebuild" "latest" "/usr/bin" "traefik_v*_linux_$(arch_resolve).tar.gz"
|
||||||
|
|
||||||
read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " pango_url
|
read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " pango_url
|
||||||
|
[[ "$pango_url" != https://* && "$pango_url" != http://* ]] && pango_url="https://${pango_url}"
|
||||||
read -rp "${TAB3}Enter your email address: " pango_email
|
read -rp "${TAB3}Enter your email address: " pango_email
|
||||||
|
|
||||||
msg_info "Setup Pangolin"
|
msg_info "Setup Pangolin"
|
||||||
@@ -36,13 +37,14 @@ BADGER_VERSION=$(get_latest_github_release "fosrl/badger" "false")
|
|||||||
cd /opt/pangolin
|
cd /opt/pangolin
|
||||||
mkdir -p /opt/pangolin/config/{traefik,db,letsencrypt,logs}
|
mkdir -p /opt/pangolin/config/{traefik,db,letsencrypt,logs}
|
||||||
$STD npm ci
|
$STD npm ci
|
||||||
$STD npm run set:sqlite
|
$STD npm run set:pg
|
||||||
$STD npm run set:oss
|
$STD npm run set:oss
|
||||||
rm -rf server/private
|
rm -rf server/private
|
||||||
$STD npm run db:generate
|
DATABASE_URL="postgresql://pangolin:${PG_DB_PASS}@localhost:5432/pangolin" $STD npm run db:generate
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
$STD npm run build:cli
|
$STD npm run build:cli
|
||||||
cp -R .next/standalone ./
|
cp -R .next/standalone ./
|
||||||
|
cp -r server/migrations ./dist/init
|
||||||
|
|
||||||
cat <<EOF >/usr/local/bin/pangctl
|
cat <<EOF >/usr/local/bin/pangctl
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
@@ -74,6 +76,9 @@ flags:
|
|||||||
require_email_verification: false
|
require_email_verification: false
|
||||||
disable_signup_without_invite: false
|
disable_signup_without_invite: false
|
||||||
disable_user_create_org: false
|
disable_user_create_org: false
|
||||||
|
|
||||||
|
postgres:
|
||||||
|
connection_string: "postgresql://pangolin:${PG_DB_PASS}@localhost:5432/pangolin"
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat <<EOF >/opt/pangolin/config/traefik/traefik_config.yml
|
cat <<EOF >/opt/pangolin/config/traefik/traefik_config.yml
|
||||||
@@ -181,7 +186,8 @@ http:
|
|||||||
servers:
|
servers:
|
||||||
- url: "http://$LOCAL_IP:3000"
|
- url: "http://$LOCAL_IP:3000"
|
||||||
EOF
|
EOF
|
||||||
$STD npm run db:push
|
export ENVIRONMENT=prod
|
||||||
|
$STD node dist/migrations.mjs
|
||||||
|
|
||||||
. /etc/os-release
|
. /etc/os-release
|
||||||
if [ "$VERSION_CODENAME" = "trixie" ]; then
|
if [ "$VERSION_CODENAME" = "trixie" ]; then
|
||||||
@@ -197,7 +203,8 @@ msg_info "Creating Services"
|
|||||||
cat <<EOF >/etc/systemd/system/pangolin.service
|
cat <<EOF >/etc/systemd/system/pangolin.service
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Pangolin Service
|
Description=Pangolin Service
|
||||||
After=network.target
|
After=network.target postgresql.service
|
||||||
|
Wants=postgresql.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
read -r -p "${TAB3}What public URL do you want to use (e.g. pocketid.mydomain.com)? " public_url
|
read -r -p "${TAB3}What public URL do you want to use (e.g. pocketid.mydomain.com)? " public_url
|
||||||
fetch_and_deploy_gh_release "pocket-id" "pocket-id/pocket-id" "singlefile" "latest" "/opt/pocket-id/" "pocket-id-linux-$(arch_resolve)"
|
fetch_and_deploy_gh_release "pocket-id" "pocket-id/pocket-id" "singlefile" "latest" "/opt/pocket-id/" "pocket-id_linux_$(arch_resolve)"
|
||||||
|
|
||||||
msg_info "Configuring Pocket ID"
|
msg_info "Configuring Pocket ID"
|
||||||
ENCRYPTION_KEY=$(openssl rand -base64 32)
|
ENCRYPTION_KEY=$(openssl rand -base64 32)
|
||||||
|
|||||||
+29
-15
@@ -30,27 +30,30 @@ mv /opt/reitti/reitti-*.jar /opt/reitti/reitti.jar
|
|||||||
|
|
||||||
msg_info "Installing Nginx Tile Cache"
|
msg_info "Installing Nginx Tile Cache"
|
||||||
mkdir -p /var/cache/nginx/tiles
|
mkdir -p /var/cache/nginx/tiles
|
||||||
cat <<EOF >/etc/nginx/nginx.conf
|
cat <<'NGINXEOF' >/etc/nginx/nginx.conf
|
||||||
user www-data;
|
user www-data;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
worker_connections 1024;
|
worker_connections 1024;
|
||||||
}
|
}
|
||||||
http {
|
http {
|
||||||
|
resolver 1.1.1.1 8.8.8.8 valid=30s ipv6=off;
|
||||||
proxy_cache_path /var/cache/nginx/tiles levels=1:2 keys_zone=tiles:10m max_size=1g inactive=30d use_temp_path=off;
|
proxy_cache_path /var/cache/nginx/tiles levels=1:2 keys_zone=tiles:10m max_size=1g inactive=30d use_temp_path=off;
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
location / {
|
location /custom/ {
|
||||||
proxy_pass https://tile.openstreetmap.org/;
|
set $upstream_url $http_x_reitti_upstream_url;
|
||||||
proxy_set_header Host tile.openstreetmap.org;
|
proxy_pass $upstream_url;
|
||||||
|
proxy_set_header Host $proxy_host;
|
||||||
proxy_set_header User-Agent "Reitti/1.0";
|
proxy_set_header User-Agent "Reitti/1.0";
|
||||||
proxy_cache tiles;
|
proxy_cache tiles;
|
||||||
|
proxy_cache_key $upstream_url;
|
||||||
proxy_cache_valid 200 30d;
|
proxy_cache_valid 200 30d;
|
||||||
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EOF
|
NGINXEOF
|
||||||
chown -R www-data:www-data /var/cache/nginx
|
chown -R www-data:www-data /var/cache/nginx
|
||||||
chmod -R 750 /var/cache/nginx
|
chmod -R 750 /var/cache/nginx
|
||||||
systemctl restart nginx
|
systemctl restart nginx
|
||||||
@@ -71,6 +74,7 @@ server.compression.mime-types=text/plain,application/json
|
|||||||
logging.level.root=INFO
|
logging.level.root=INFO
|
||||||
logging.level.org.hibernate.engine.jdbc.spi.SqlExceptionHelper=FATAL
|
logging.level.org.hibernate.engine.jdbc.spi.SqlExceptionHelper=FATAL
|
||||||
logging.level.com.dedicatedcode.reitti=INFO
|
logging.level.com.dedicatedcode.reitti=INFO
|
||||||
|
logging.level.org.quartz.core.ErrorLogger=FATAL
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
spring.messages.basename=messages
|
spring.messages.basename=messages
|
||||||
@@ -82,7 +86,7 @@ spring.messages.fallback-to-system-locale=false
|
|||||||
spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/$PG_DB_NAME
|
spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/$PG_DB_NAME
|
||||||
spring.datasource.username=$PG_DB_USER
|
spring.datasource.username=$PG_DB_USER
|
||||||
spring.datasource.password=$PG_DB_PASS
|
spring.datasource.password=$PG_DB_PASS
|
||||||
spring.datasource.hikari.maximum-pool-size=20
|
spring.datasource.hikari.maximum-pool-size=30
|
||||||
|
|
||||||
# Redis configuration
|
# Redis configuration
|
||||||
spring.data.redis.host=127.0.0.1
|
spring.data.redis.host=127.0.0.1
|
||||||
@@ -92,20 +96,23 @@ spring.data.redis.password=
|
|||||||
spring.data.redis.database=0
|
spring.data.redis.database=0
|
||||||
spring.cache.redis.key-prefix=
|
spring.cache.redis.key-prefix=
|
||||||
|
|
||||||
spring.cache.cache-names=processed-visits,significant-places,users,magic-links,configurations,transport-mode-configs,avatarThumbnails,avatarData,user-settings
|
spring.cache.cache-names=processed-visits,significant-places,users,magic-links,configurations,transport-mode-configs,avatarThumbnails,avatarData,user-settings,devices,mapStyles,mapStyleJson
|
||||||
spring.cache.redis.time-to-live=1d
|
spring.cache.redis.time-to-live=1d
|
||||||
|
|
||||||
# Upload configuration
|
# Upload configuration
|
||||||
spring.servlet.multipart.max-file-size=5GB
|
spring.servlet.multipart.max-file-size=5GB
|
||||||
spring.servlet.multipart.max-request-size=5GB
|
spring.servlet.multipart.max-request-size=5GB
|
||||||
|
spring.servlet.multipart.resolve-lazily=true
|
||||||
server.tomcat.max-part-count=100
|
server.tomcat.max-part-count=100
|
||||||
|
spring.mvc.async.request-timeout=600000
|
||||||
|
|
||||||
# Rqueue configuration
|
# Quartz Scheduler configuration
|
||||||
rqueue.web.enable=false
|
spring.quartz.job-store-type=jdbc
|
||||||
rqueue.job.enabled=false
|
spring.quartz.jdbc.initialize-schema=never
|
||||||
rqueue.message.durability.in-terminal-state=0
|
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
|
||||||
rqueue.key.prefix=\${spring.cache.redis.key-prefix}
|
spring.quartz.properties.org.quartz.jobStore.isClustered=false
|
||||||
rqueue.message.converter.provider.class=com.dedicatedcode.reitti.config.RQueueCustomMessageConverter
|
spring.quartz.properties.org.quartz.jobStore.tablePrefix=qrtz_
|
||||||
|
spring.quartz.properties.org.quartz.threadPool.threadCount=5
|
||||||
|
|
||||||
# Application-specific settings
|
# Application-specific settings
|
||||||
reitti.server.advertise-uri=
|
reitti.server.advertise-uri=
|
||||||
@@ -117,18 +124,25 @@ reitti.security.oidc.enabled=false
|
|||||||
reitti.security.oidc.registration.enabled=false
|
reitti.security.oidc.registration.enabled=false
|
||||||
|
|
||||||
reitti.import.batch-size=10000
|
reitti.import.batch-size=10000
|
||||||
reitti.import.processing-idle-start-time=10
|
reitti.import.grace-time-seconds=30
|
||||||
|
reitti.import.staging.cleanup.cron=0 0 4 * * *
|
||||||
|
|
||||||
|
reitti.batching.max-batch-size=100
|
||||||
|
reitti.batching.max-wait-time=5
|
||||||
|
|
||||||
reitti.geo-point-filter.max-speed-kmh=1000
|
reitti.geo-point-filter.max-speed-kmh=1000
|
||||||
reitti.geo-point-filter.max-accuracy-meters=100
|
reitti.geo-point-filter.max-accuracy-meters=100
|
||||||
reitti.geo-point-filter.history-lookback-hours=24
|
reitti.geo-point-filter.history-lookback-hours=24
|
||||||
reitti.geo-point-filter.window-size=50
|
reitti.geo-point-filter.window-size=50
|
||||||
|
|
||||||
reitti.process-data.schedule=0 */10 * * * *
|
|
||||||
reitti.process-data.refresh-views.schedule=0 0 4 * * *
|
reitti.process-data.refresh-views.schedule=0 0 4 * * *
|
||||||
reitti.imports.schedule=0 5/10 * * * *
|
reitti.imports.schedule=0 5/10 * * * *
|
||||||
reitti.imports.owntracks-recorder.schedule=\${reitti.imports.schedule}
|
reitti.imports.owntracks-recorder.schedule=\${reitti.imports.schedule}
|
||||||
|
|
||||||
|
reitti.jobs.cleanup.cron=0 0 4 * * ?
|
||||||
|
reitti.jobs.cleanup.max-age-hours=24
|
||||||
|
reitti.db-janitor.schedule=0 0 4 * * ?
|
||||||
|
|
||||||
# Geocoding service configuration
|
# Geocoding service configuration
|
||||||
reitti.geocoding.max-errors=10
|
reitti.geocoding.max-errors=10
|
||||||
reitti.geocoding.photon.base-url=
|
reitti.geocoding.photon.base-url=
|
||||||
|
|||||||
@@ -134,6 +134,8 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "romm" "rommapp/romm" "tarball"
|
fetch_and_deploy_gh_release "romm" "rommapp/romm" "tarball"
|
||||||
|
fetch_and_deploy_gh_release "ruffle" "ruffle-rs/ruffle" "prebuild" "latest" "/opt/romm/frontend/dist/assets/ruffle" "ruffle-*-web-selfhosted.zip"
|
||||||
|
fetch_and_deploy_gh_release "EmulatorJS" "EmulatorJS/EmulatorJS" "prebuild" "v4.2.3" "/opt/romm/frontend/dist/assets/emulatorjs" "4.2.3.7z"
|
||||||
|
|
||||||
msg_info "Creating environment file"
|
msg_info "Creating environment file"
|
||||||
sed -i 's/^supervised no/supervised systemd/' /etc/redis/redis.conf
|
sed -i 's/^supervised no/supervised systemd/' /etc/redis/redis.conf
|
||||||
@@ -159,6 +161,9 @@ ROMM_AUTH_SECRET_KEY=$AUTH_SECRET_KEY
|
|||||||
DISABLE_DOWNLOAD_ENDPOINT_AUTH=false
|
DISABLE_DOWNLOAD_ENDPOINT_AUTH=false
|
||||||
DISABLE_CSRF_PROTECTION=false
|
DISABLE_CSRF_PROTECTION=false
|
||||||
|
|
||||||
|
SCREENSCRAPER_DEV_ID=
|
||||||
|
SCREENSCRAPER_DEV_PASSWORD=
|
||||||
|
|
||||||
ENABLE_RESCAN_ON_FILESYSTEM_CHANGE=true
|
ENABLE_RESCAN_ON_FILESYSTEM_CHANGE=true
|
||||||
RESCAN_ON_FILESYSTEM_CHANGE_DELAY=5
|
RESCAN_ON_FILESYSTEM_CHANGE_DELAY=5
|
||||||
|
|
||||||
@@ -181,6 +186,18 @@ cd /opt/romm/backend
|
|||||||
$STD uv run alembic upgrade head
|
$STD uv run alembic upgrade head
|
||||||
msg_ok "Set up RomM Backend"
|
msg_ok "Set up RomM Backend"
|
||||||
|
|
||||||
|
if [[ -f /opt/romm/backend/utils/rom_patcher/package.json ]]; then
|
||||||
|
msg_info "Building ROM Patcher helper"
|
||||||
|
cd /opt/romm/backend/utils/rom_patcher
|
||||||
|
$STD npm install --ignore-scripts --no-audit --no-fund
|
||||||
|
if [[ -d node_modules/rom-patcher/rom-patcher-js ]]; then
|
||||||
|
rm -rf rom-patcher-js
|
||||||
|
cp -r node_modules/rom-patcher/rom-patcher-js ./rom-patcher-js
|
||||||
|
fi
|
||||||
|
rm -rf node_modules
|
||||||
|
msg_ok "Built ROM Patcher helper"
|
||||||
|
fi
|
||||||
|
|
||||||
msg_info "Setting up RomM Frontend"
|
msg_info "Setting up RomM Frontend"
|
||||||
cd /opt/romm/frontend
|
cd /opt/romm/frontend
|
||||||
$STD npm install
|
$STD npm install
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ msg_ok "Installed Dependencies"
|
|||||||
|
|
||||||
setup_deb822_repo \
|
setup_deb822_repo \
|
||||||
"sftpgo" \
|
"sftpgo" \
|
||||||
"https://ftp.osuosl.org/pub/sftpgo/apt/gpg.key" \
|
"https://oss.sftpgo.com/apt/gpg.key" \
|
||||||
"https://ftp.osuosl.org/pub/sftpgo/apt" \
|
"https://oss.sftpgo.com/apt" \
|
||||||
"trixie"
|
"trixie"
|
||||||
|
|
||||||
msg_info "Installing SFTPGo"
|
msg_info "Installing SFTPGo"
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ cronKey=$(head -c 1024 </dev/urandom | sha256sum | awk '{print substr($1,1,29)}'
|
|||||||
sed -i -e 's/Shinobi/'"$cronKey"'/g' conf.json
|
sed -i -e 's/Shinobi/'"$cronKey"'/g' conf.json
|
||||||
cp super.sample.json super.json
|
cp super.sample.json super.json
|
||||||
$STD npm i npm -g
|
$STD npm i npm -g
|
||||||
$STD npm install --unsafe-perm
|
$STD npm install
|
||||||
$STD npm install pm2@latest -g
|
$STD npm install pm2@latest -g
|
||||||
chmod -R 755 .
|
chmod -R 755 .
|
||||||
touch INSTALL/installed.txt
|
touch INSTALL/installed.txt
|
||||||
|
|||||||
@@ -16,6 +16,17 @@ update_os
|
|||||||
fetch_and_deploy_gh_release "silverbullet" "silverbulletmd/silverbullet" "prebuild" "latest" "/opt/silverbullet/bin" "silverbullet-server-linux-$(arch_resolve "x86_64" "aarch64").zip"
|
fetch_and_deploy_gh_release "silverbullet" "silverbulletmd/silverbullet" "prebuild" "latest" "/opt/silverbullet/bin" "silverbullet-server-linux-$(arch_resolve "x86_64" "aarch64").zip"
|
||||||
mkdir -p /opt/silverbullet/space
|
mkdir -p /opt/silverbullet/space
|
||||||
|
|
||||||
|
RUNTIME_API_ENV=""
|
||||||
|
read -rp "${TAB3}Enable Silverbullet Runtime API? Requires Chromium (~700MB). Uses ~200MB extra RAM. (y/N): " runtime_api_prompt
|
||||||
|
if [[ "${runtime_api_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
|
msg_info "Installing Chromium for Runtime API"
|
||||||
|
$STD apt install -y chromium
|
||||||
|
msg_ok "Installed Chromium for Runtime API"
|
||||||
|
RUNTIME_API_ENV=$'Environment=SB_CHROME_PATH=/usr/bin/chromium\nEnvironment=SB_CHROME_DATA_DIR=/opt/silverbullet/space/.chrome-data\n'
|
||||||
|
touch /opt/silverbullet/.runtime-api-enabled
|
||||||
|
msg_ok "Runtime API will be enabled"
|
||||||
|
fi
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
cat <<EOF >/etc/systemd/system/silverbullet.service
|
cat <<EOF >/etc/systemd/system/silverbullet.service
|
||||||
[Unit]
|
[Unit]
|
||||||
@@ -25,6 +36,7 @@ After=syslog.target network.target
|
|||||||
[Service]
|
[Service]
|
||||||
User=root
|
User=root
|
||||||
Type=simple
|
Type=simple
|
||||||
|
${RUNTIME_API_ENV}
|
||||||
ExecStart=/opt/silverbullet/bin/silverbullet --hostname 0.0.0.0 --port 3000 /opt/silverbullet/space
|
ExecStart=/opt/silverbullet/bin/silverbullet --hostname 0.0.0.0 --port 3000 /opt/silverbullet/space
|
||||||
WorkingDirectory=/opt/silverbullet
|
WorkingDirectory=/opt/silverbullet
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
|
|||||||
@@ -39,6 +39,19 @@ msg_ok "Installed Dependencies"
|
|||||||
|
|
||||||
PYTHON_VERSION="3.11" setup_uv
|
PYTHON_VERSION="3.11" setup_uv
|
||||||
NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs
|
NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs
|
||||||
|
PG_VERSION="17" setup_postgresql
|
||||||
|
PG_DB_NAME="snapotter" PG_DB_USER="snapotter" setup_postgresql_db
|
||||||
|
|
||||||
|
msg_info "Installing Redis"
|
||||||
|
$STD apt install -y redis-server
|
||||||
|
if grep -q '^appendonly ' /etc/redis/redis.conf; then
|
||||||
|
sed -i 's/^appendonly .*/appendonly yes/' /etc/redis/redis.conf
|
||||||
|
else
|
||||||
|
echo 'appendonly yes' >>/etc/redis/redis.conf
|
||||||
|
fi
|
||||||
|
$STD systemctl enable --now redis-server
|
||||||
|
msg_ok "Installed Redis"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "caire" "esimov/caire" "prebuild" "latest" "/usr/local/bin" "caire-*-linux-amd64.tar.gz"
|
fetch_and_deploy_gh_release "caire" "esimov/caire" "prebuild" "latest" "/usr/local/bin" "caire-*-linux-amd64.tar.gz"
|
||||||
fetch_and_deploy_gh_release "snapotter" "snapotter-hq/SnapOtter" "prebuild" "latest" "/opt/snapotter" "snapotter-*-linux-amd64.tar.gz"
|
fetch_and_deploy_gh_release "snapotter" "snapotter-hq/SnapOtter" "prebuild" "latest" "/opt/snapotter" "snapotter-*-linux-amd64.tar.gz"
|
||||||
|
|
||||||
@@ -61,7 +74,8 @@ mkdir -p /tmp/snapotter-workspace
|
|||||||
cat <<EOF >/opt/snapotter_data/.env
|
cat <<EOF >/opt/snapotter_data/.env
|
||||||
PORT=1349
|
PORT=1349
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
DB_PATH=/opt/snapotter_data/snapotter.db
|
DATABASE_URL=postgres://${PG_DB_USER}:${PG_DB_PASS}@127.0.0.1:5432/${PG_DB_NAME}
|
||||||
|
REDIS_URL=redis://127.0.0.1:6379
|
||||||
WORKSPACE_PATH=/tmp/snapotter-workspace
|
WORKSPACE_PATH=/tmp/snapotter-workspace
|
||||||
FILES_STORAGE_PATH=/opt/snapotter_data/files
|
FILES_STORAGE_PATH=/opt/snapotter_data/files
|
||||||
PYTHON_VENV_PATH=/opt/snapotter_data/ai/venv
|
PYTHON_VENV_PATH=/opt/snapotter_data/ai/venv
|
||||||
@@ -85,7 +99,9 @@ PNPM_BIN="$(command -v pnpm)"
|
|||||||
cat <<EOF >/etc/systemd/system/snapotter.service
|
cat <<EOF >/etc/systemd/system/snapotter.service
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=SnapOtter Service
|
Description=SnapOtter Service
|
||||||
After=network.target
|
Wants=network-online.target
|
||||||
|
After=network-online.target postgresql.service redis-server.service
|
||||||
|
Requires=postgresql.service redis-server.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
@@ -99,6 +115,7 @@ RestartSec=5
|
|||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
systemctl daemon-reload
|
||||||
systemctl enable -q --now snapotter
|
systemctl enable -q --now snapotter
|
||||||
msg_ok "Created Service"
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ NODE_VERSION="24" NODE_MODULE="corepack,yarn" setup_nodejs
|
|||||||
|
|
||||||
fetch_and_deploy_gh_release "readium" "readium/cli" "prebuild" "latest" "/opt/readium" "readium_linux_$(arch_resolve "x86_64" "arm64").tar.gz"
|
fetch_and_deploy_gh_release "readium" "readium/cli" "prebuild" "latest" "/opt/readium" "readium_linux_$(arch_resolve "x86_64" "arm64").tar.gz"
|
||||||
ln -sf /opt/readium/readium /usr/local/bin/readium
|
ln -sf /opt/readium/readium /usr/local/bin/readium
|
||||||
fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller"
|
fetch_and_deploy_gl_release "storyteller" "storyteller-platform/storyteller" "tarball" "latest" "/opt/storyteller" "" "web-v2"
|
||||||
|
|
||||||
msg_info "Setting up Storyteller"
|
msg_info "Setting up Storyteller"
|
||||||
cd /opt/storyteller
|
cd /opt/storyteller
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/Sync-in/server
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
NODE_VERSION="22" setup_nodejs
|
||||||
|
setup_mariadb
|
||||||
|
MARIADB_DB_NAME="sync_in" MARIADB_DB_USER="sync_in" setup_mariadb_db
|
||||||
|
|
||||||
|
msg_info "Installing Sync-in"
|
||||||
|
mkdir -p /opt/sync-in/data
|
||||||
|
$STD npm install --prefix /opt/sync-in @sync-in/server
|
||||||
|
msg_ok "Installed Sync-in"
|
||||||
|
|
||||||
|
msg_info "Configuring Sync-in"
|
||||||
|
ENCRYPT_KEY=$(openssl rand -hex 32)
|
||||||
|
ACCESS_SECRET=$(openssl rand -hex 32)
|
||||||
|
REFRESH_SECRET=$(openssl rand -hex 32)
|
||||||
|
cat <<EOF >/opt/sync-in/environment.yaml
|
||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
mysql:
|
||||||
|
url: 'mysql://${MARIADB_DB_USER}:${MARIADB_DB_PASS}@localhost:3306/${MARIADB_DB_NAME}'
|
||||||
|
auth:
|
||||||
|
encryptionKey: '${ENCRYPT_KEY}'
|
||||||
|
token:
|
||||||
|
access:
|
||||||
|
secret: '${ACCESS_SECRET}'
|
||||||
|
refresh:
|
||||||
|
secret: '${REFRESH_SECRET}'
|
||||||
|
applications:
|
||||||
|
files:
|
||||||
|
dataPath: '/opt/sync-in/data'
|
||||||
|
EOF
|
||||||
|
msg_ok "Configured Sync-in"
|
||||||
|
|
||||||
|
msg_info "Running Database Migrations"
|
||||||
|
cd /opt/sync-in
|
||||||
|
$STD npx sync-in-server migrate-db
|
||||||
|
msg_ok "Ran Database Migrations"
|
||||||
|
|
||||||
|
msg_info "Creating Admin User"
|
||||||
|
cd /opt/sync-in
|
||||||
|
$STD npx sync-in-server create-user
|
||||||
|
msg_ok "Created Admin User"
|
||||||
|
|
||||||
|
VERSION=$(node -pe "require('/opt/sync-in/node_modules/@sync-in/server/package.json').version" 2>/dev/null || echo "")
|
||||||
|
[[ -n "$VERSION" ]] && echo "$VERSION" >~/.sync-in
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/sync-in.service
|
||||||
|
[Unit]
|
||||||
|
Description=Sync-in Server
|
||||||
|
After=network.target mariadb.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/sync-in
|
||||||
|
ExecStart=/opt/sync-in/node_modules/.bin/sync-in-server start
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now sync-in
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: MickLesk (CanbiZ)
|
# Author: MickLesk (CanbiZ)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/mauriceboe/TREK
|
# Source: https://github.com/liketrek/TREK
|
||||||
|
|
||||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
color
|
color
|
||||||
@@ -20,7 +20,7 @@ $STD apt install -y \
|
|||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
fetch_and_deploy_gh_release "trek" "mauriceboe/TREK" "tarball"
|
fetch_and_deploy_gh_release "trek" "liketrek/TREK" "tarball"
|
||||||
|
|
||||||
msg_info "Setup TREK"
|
msg_info "Setup TREK"
|
||||||
cd /opt/trek
|
cd /opt/trek
|
||||||
@@ -78,7 +78,7 @@ msg_info "Creating Service"
|
|||||||
cat <<EOF >/etc/systemd/system/trek.service
|
cat <<EOF >/etc/systemd/system/trek.service
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=TREK Travel Planner
|
Description=TREK Travel Planner
|
||||||
Documentation=https://github.com/mauriceboe/TREK
|
Documentation=https://github.com/liketrek/TREK
|
||||||
After=network-online.target
|
After=network-online.target
|
||||||
Wants=network-online.target
|
Wants=network-online.target
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ setting_up_container
|
|||||||
network_check
|
network_check
|
||||||
update_os
|
update_os
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary"
|
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "latest" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
|
||||||
|
|
||||||
msg_info "Setting up Vikunja"
|
msg_info "Setting up Vikunja"
|
||||||
sed -i 's|^# \(service:\)|\1|' /etc/vikunja/config.yml
|
sed -i 's|^# \(service:\)|\1|' /etc/vikunja/config.yml
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ if [[ "$(arch_resolve)" == "arm64" ]]; then
|
|||||||
else
|
else
|
||||||
fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" "latest" "/opt/wanderer/source/search"
|
fetch_and_deploy_gh_release "meilisearch" "meilisearch/meilisearch" "binary" "latest" "/opt/wanderer/source/search"
|
||||||
fi
|
fi
|
||||||
mkdir -p /opt/wanderer/{source,data/pb_data,data/meili_data}
|
mkdir -p /opt/wanderer/{source,data/pb_data,data/meili_data,data/plugins}
|
||||||
fetch_and_deploy_gh_release "wanderer" "open-wanderer/wanderer" "tarball" "latest" "/opt/wanderer/source"
|
fetch_and_deploy_gh_release "wanderer" "open-wanderer/wanderer" "tarball" "latest" "/opt/wanderer/source"
|
||||||
|
mkdir -p /opt/wanderer/source/db/data
|
||||||
|
[[ -e /opt/wanderer/source/db/data/plugins ]] || ln -sfn /opt/wanderer/data/plugins /opt/wanderer/source/db/data/plugins
|
||||||
|
|
||||||
msg_info "Installing wanderer (patience)"
|
msg_info "Installing wanderer (patience)"
|
||||||
cd /opt/wanderer/source/db
|
cd /opt/wanderer/source/db
|
||||||
@@ -32,6 +34,12 @@ $STD npm ci
|
|||||||
$STD npm run build
|
$STD npm run build
|
||||||
msg_ok "Installed wanderer"
|
msg_ok "Installed wanderer"
|
||||||
|
|
||||||
|
msg_info "Installing wanderer plugins"
|
||||||
|
for plugin in hammerhead komoot strava; do
|
||||||
|
fetch_and_deploy_gh_release "wanderer-plugin-${plugin}" "open-wanderer/wanderer" "prebuild" "latest" "/opt/wanderer/data/plugins" "wanderer-plugin-${plugin}.tar.gz" || msg_warn "Failed to install wanderer plugin: ${plugin}"
|
||||||
|
done
|
||||||
|
msg_ok "Installed wanderer plugins"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
MEILI_KEY=$(openssl rand -hex 32)
|
MEILI_KEY=$(openssl rand -hex 32)
|
||||||
POCKETBASE_KEY=$(openssl rand -hex 16)
|
POCKETBASE_KEY=$(openssl rand -hex 16)
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ msg_ok "Configured Caddy"
|
|||||||
|
|
||||||
msg_info "Automating Webtrees Setup"
|
msg_info "Automating Webtrees Setup"
|
||||||
cd /opt/webtrees
|
cd /opt/webtrees
|
||||||
|
mkdir -p /opt/webtrees/data
|
||||||
|
chown -R www-data:www-data /opt/webtrees/data
|
||||||
WT_ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c15)
|
WT_ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c15)
|
||||||
$STD sudo -u www-data php /opt/webtrees/index.php config-ini \
|
$STD sudo -u www-data php /opt/webtrees/index.php config-ini \
|
||||||
--dbhost=127.0.0.1 \
|
--dbhost=127.0.0.1 \
|
||||||
@@ -56,6 +58,15 @@ $STD sudo -u www-data php /opt/webtrees/index.php config-ini \
|
|||||||
--dbname=webtrees \
|
--dbname=webtrees \
|
||||||
--tblpfx=wt_ \
|
--tblpfx=wt_ \
|
||||||
--base-url="http://${LOCAL_IP}"
|
--base-url="http://${LOCAL_IP}"
|
||||||
|
msg_info "Initializing Webtrees database schema"
|
||||||
|
for i in {1..15}; do
|
||||||
|
if curl -sf "http://127.0.0.1/" >/dev/null 2>&1; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
$STD mariadb -u webtrees -p"${MARIADB_DB_PASS}" -h 127.0.0.1 webtrees -e "SHOW TABLES LIKE 'wt_user';" | grep -q wt_user
|
||||||
|
msg_ok "Initialized Webtrees database schema"
|
||||||
$STD sudo -u www-data php /opt/webtrees/index.php user Admin \
|
$STD sudo -u www-data php /opt/webtrees/index.php user Admin \
|
||||||
--create \
|
--create \
|
||||||
--real-name="Administrator" \
|
--real-name="Administrator" \
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/ulsklyc/yuvomi
|
||||||
|
|
||||||
|
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 \
|
||||||
|
python3 \
|
||||||
|
make \
|
||||||
|
g++ \
|
||||||
|
libsqlcipher-dev
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
NODE_VERSION="22" setup_nodejs
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "yuvomi" "ulsklyc/yuvomi" "tarball"
|
||||||
|
|
||||||
|
msg_info "Installing Node.js Dependencies"
|
||||||
|
cd /opt/yuvomi
|
||||||
|
$STD npm ci --omit=dev
|
||||||
|
msg_ok "Installed Node.js Dependencies"
|
||||||
|
|
||||||
|
msg_info "Configuring Yuvomi"
|
||||||
|
mkdir -p /opt/yuvomi/data /opt/yuvomi/backups
|
||||||
|
SESSION_SECRET=$(openssl rand -hex 32)
|
||||||
|
DB_ENCRYPT_KEY=$(openssl rand -hex 32)
|
||||||
|
cat <<EOF >/opt/yuvomi/.env
|
||||||
|
PORT=3000
|
||||||
|
NODE_ENV=production
|
||||||
|
DB_PATH=/opt/yuvomi/data/yuvomi.db
|
||||||
|
DB_ENCRYPTION_KEY=${DB_ENCRYPT_KEY}
|
||||||
|
SESSION_SECRET=${SESSION_SECRET}
|
||||||
|
RATE_LIMIT_WINDOW_MS=60000
|
||||||
|
RATE_LIMIT_MAX_ATTEMPTS=5
|
||||||
|
RATE_LIMIT_BLOCK_DURATION_MS=900000
|
||||||
|
EOF
|
||||||
|
msg_ok "Configured Yuvomi"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/yuvomi.service
|
||||||
|
[Unit]
|
||||||
|
Description=Yuvomi Family Planner
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/yuvomi
|
||||||
|
EnvironmentFile=/opt/yuvomi/.env
|
||||||
|
ExecStart=/usr/bin/node server/index.js
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now yuvomi
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -31,7 +31,10 @@ $STD apt install -y elasticsearch
|
|||||||
sed -i 's/^#\{0,2\} *-Xms[0-9]*g.*/-Xms2g/' /etc/elasticsearch/jvm.options
|
sed -i 's/^#\{0,2\} *-Xms[0-9]*g.*/-Xms2g/' /etc/elasticsearch/jvm.options
|
||||||
sed -i 's/^#\{0,2\} *-Xmx[0-9]*g.*/-Xmx2g/' /etc/elasticsearch/jvm.options
|
sed -i 's/^#\{0,2\} *-Xmx[0-9]*g.*/-Xmx2g/' /etc/elasticsearch/jvm.options
|
||||||
cat <<EOF >/etc/elasticsearch/elasticsearch.yml
|
cat <<EOF >/etc/elasticsearch/elasticsearch.yml
|
||||||
|
path.data: /var/lib/elasticsearch
|
||||||
|
path.logs: /var/log/elasticsearch
|
||||||
discovery.type: single-node
|
discovery.type: single-node
|
||||||
|
network.host: 127.0.0.1
|
||||||
xpack.security.enabled: false
|
xpack.security.enabled: false
|
||||||
bootstrap.memory_lock: false
|
bootstrap.memory_lock: false
|
||||||
EOF
|
EOF
|
||||||
@@ -40,7 +43,7 @@ systemctl daemon-reload
|
|||||||
systemctl enable -q elasticsearch
|
systemctl enable -q elasticsearch
|
||||||
systemctl restart -q elasticsearch
|
systemctl restart -q elasticsearch
|
||||||
for i in $(seq 1 30); do
|
for i in $(seq 1 30); do
|
||||||
if curl -s http://localhost:9200 >/dev/null 2>&1; then
|
if curl -s http://127.0.0.1:9200 >/dev/null 2>&1; then
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
sleep 2
|
sleep 2
|
||||||
@@ -55,7 +58,7 @@ setup_deb822_repo \
|
|||||||
"$(get_os_info version_id)" \
|
"$(get_os_info version_id)" \
|
||||||
"main"
|
"main"
|
||||||
$STD apt install -y zammad
|
$STD apt install -y zammad
|
||||||
$STD zammad run rails r "Setting.set('es_url', 'http://localhost:9200')"
|
$STD zammad run rails r "Setting.set('es_url', 'http://127.0.0.1:9200')"
|
||||||
$STD zammad run rake zammad:searchindex:rebuild
|
$STD zammad run rake zammad:searchindex:rebuild
|
||||||
msg_ok "Installed Zammad"
|
msg_ok "Installed Zammad"
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,10 @@
|
|||||||
if ! command -v curl >/dev/null 2>&1; then
|
if ! command -v curl >/dev/null 2>&1; then
|
||||||
apk update && apk add curl >/dev/null 2>&1
|
apk update && apk add curl >/dev/null 2>&1
|
||||||
fi
|
fi
|
||||||
|
# Mark container context BEFORE error handling starts: error_handler/on_exit
|
||||||
|
# must write local failure artifacts instead of talking to the telemetry API
|
||||||
|
# (the host is the single telemetry reporter).
|
||||||
|
export TELEMETRY_CONTEXT="container"
|
||||||
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/core.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
load_functions
|
load_functions
|
||||||
@@ -41,7 +45,7 @@ post_progress_to_api() {
|
|||||||
|
|
||||||
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
|
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"${progress_status}\"}" &>/dev/null || true
|
-d "{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"${progress_status}\",\"platform\":\"${TELEMETRY_PLATFORM:-}\",\"repo_source\":\"${REPO_SOURCE:-}\",\"repo_slug\":\"${REPO_SLUG:-}\"}" &>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
# This function enables IPv6 if it's not disabled and sets verbose mode
|
# This function enables IPv6 if it's not disabled and sets verbose mode
|
||||||
|
|||||||
+546
-826
File diff suppressed because it is too large
Load Diff
+94
-34
@@ -3600,9 +3600,9 @@ configure_ssh_settings() {
|
|||||||
glob_path=$(whiptail --backtitle "$backtitle" \
|
glob_path=$(whiptail --backtitle "$backtitle" \
|
||||||
--inputbox "Enter a folder or glob to scan (e.g. /root/.ssh/*.pub)" 10 72 --title "Scan Folder/Glob" 3>&1 1>&2 2>&3)
|
--inputbox "Enter a folder or glob to scan (e.g. /root/.ssh/*.pub)" 10 72 --title "Scan Folder/Glob" 3>&1 1>&2 2>&3)
|
||||||
if [[ -n "$glob_path" ]]; then
|
if [[ -n "$glob_path" ]]; then
|
||||||
shopt -s nullglob
|
[[ -d "$glob_path" ]] && glob_path="${glob_path%/}/*"
|
||||||
read -r -a _scan_files <<<"$glob_path"
|
local -a _scan_files
|
||||||
shopt -u nullglob
|
mapfile -t _scan_files < <(compgen -G "$glob_path")
|
||||||
if [[ "${#_scan_files[@]}" -gt 0 ]]; then
|
if [[ "${#_scan_files[@]}" -gt 0 ]]; then
|
||||||
ssh_build_choices_from_files "${_scan_files[@]}"
|
ssh_build_choices_from_files "${_scan_files[@]}"
|
||||||
if [[ "$COUNT" -gt 0 ]]; then
|
if [[ "$COUNT" -gt 0 ]]; then
|
||||||
@@ -3753,30 +3753,32 @@ run_addon_updates() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
runtime_script_status_guard() {
|
runtime_script_status_guard() {
|
||||||
|
local mode="${1:-}"
|
||||||
local script_slug="${SCRIPT_SLUG:-${NSAPP:-}}"
|
local script_slug="${SCRIPT_SLUG:-${NSAPP:-}}"
|
||||||
script_slug="$(echo "$script_slug" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')"
|
script_slug="$(echo "$script_slug" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')"
|
||||||
[[ -z "$script_slug" ]] && return 0
|
[[ -z "$script_slug" ]] && return 0
|
||||||
|
|
||||||
local api_url="https://db.community-scripts.org/api/collections/script_scripts/records?filter=(slug='${script_slug}')&perPage=1&fields=slug,is_disabled,is_deleted,disable_message,deleted_message"
|
local api_url="https://db.community-scripts.org/api/collections/script_scripts/records?filter=(slug='${script_slug}')&perPage=1&fields=slug,is_disabled,is_deleted,disable_message,deleted_message,pinned_version,pin_reason"
|
||||||
local response
|
local response
|
||||||
if ! response=$(curl -fsSL --connect-timeout 2 --max-time 3 "$api_url" 2>/dev/null); then
|
if ! response=$(curl -fsSL --connect-timeout 2 --max-time 3 "$api_url" 2>/dev/null); then
|
||||||
msg_warn "Script status check is unavailable. Continuing without status verification."
|
msg_warn "Script status check is unavailable. Continuing without status verification."
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! command -v jq >/dev/null 2>&1; then
|
local is_deleted is_disabled deleted_message disable_message pinned_version pin_reason info_url
|
||||||
msg_warn "Missing jq for script status check. Continuing without status verification."
|
if printf '%s' "$response" | grep -qE '"items":[[:space:]]*\[[[:space:]]*\]'; then
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local has_record is_deleted is_disabled deleted_message disable_message info_url
|
# PocketBase returns a flat, fixed-field JSON blob; sed is enough here (no jq needed).
|
||||||
has_record=$(printf '%s' "$response" | jq -r '.items | length')
|
is_deleted=$(printf '%s' "$response" | sed -n 's/.*"is_deleted"[[:space:]]*:[[:space:]]*\(true\|false\).*/\1/p' | head -1)
|
||||||
[[ "$has_record" == "0" ]] && return 0
|
is_disabled=$(printf '%s' "$response" | sed -n 's/.*"is_disabled"[[:space:]]*:[[:space:]]*\(true\|false\).*/\1/p' | head -1)
|
||||||
|
deleted_message=$(printf '%s' "$response" | sed -n 's/.*"deleted_message"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
|
||||||
is_deleted=$(printf '%s' "$response" | jq -r '.items[0].is_deleted // false')
|
disable_message=$(printf '%s' "$response" | sed -n 's/.*"disable_message"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
|
||||||
is_disabled=$(printf '%s' "$response" | jq -r '.items[0].is_disabled // false')
|
pinned_version=$(printf '%s' "$response" | sed -n 's/.*"pinned_version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
|
||||||
deleted_message=$(printf '%s' "$response" | jq -r '.items[0].deleted_message // ""')
|
pin_reason=$(printf '%s' "$response" | sed -n 's/.*"pin_reason"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
|
||||||
disable_message=$(printf '%s' "$response" | jq -r '.items[0].disable_message // ""')
|
is_deleted=${is_deleted:-false}
|
||||||
|
is_disabled=${is_disabled:-false}
|
||||||
info_url="https://community-scripts.org/scripts/${script_slug}"
|
info_url="https://community-scripts.org/scripts/${script_slug}"
|
||||||
|
|
||||||
if [[ "$is_deleted" == "true" ]]; then
|
if [[ "$is_deleted" == "true" ]]; then
|
||||||
@@ -3806,6 +3808,26 @@ runtime_script_status_guard() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$mode" == "update" && -n "$pinned_version" && -n "${NSAPP:-}" ]]; then
|
||||||
|
local current_file="$HOME/.${NSAPP}"
|
||||||
|
if [[ -f "$current_file" ]]; then
|
||||||
|
local installed pinned_clean installed_clean
|
||||||
|
installed="$(<"$current_file")"
|
||||||
|
pinned_clean="$pinned_version"
|
||||||
|
installed_clean="$installed"
|
||||||
|
[[ "$pinned_clean" =~ ^v[0-9] ]] && pinned_clean="${pinned_clean:1}"
|
||||||
|
[[ "$installed_clean" =~ ^v[0-9] ]] && installed_clean="${installed_clean:1}"
|
||||||
|
if [[ "$installed_clean" == "$pinned_clean" ]]; then
|
||||||
|
if [[ -n "$pin_reason" ]]; then
|
||||||
|
msg_info "You are already on the pinned version (${pinned_version}). ${pin_reason}"
|
||||||
|
else
|
||||||
|
msg_info "You are already on the pinned version (${pinned_version}). No newer update is offered intentionally — please do not open an issue unless you see an actual error."
|
||||||
|
fi
|
||||||
|
msg_info "More info: ${info_url}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3821,7 +3843,7 @@ runtime_script_status_guard() {
|
|||||||
start() {
|
start() {
|
||||||
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/tools.func)
|
||||||
if command -v pveversion >/dev/null 2>&1; then
|
if command -v pveversion >/dev/null 2>&1; then
|
||||||
runtime_script_status_guard || return 0
|
runtime_script_status_guard install || return 0
|
||||||
install_script || return 0
|
install_script || return 0
|
||||||
return 0
|
return 0
|
||||||
elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then
|
elif [ ! -z ${PHS_SILENT+x} ] && [[ "${PHS_SILENT}" == "1" ]]; then
|
||||||
@@ -3829,7 +3851,7 @@ start() {
|
|||||||
set_std_mode
|
set_std_mode
|
||||||
ensure_profile_loaded
|
ensure_profile_loaded
|
||||||
get_lxc_ip
|
get_lxc_ip
|
||||||
runtime_script_status_guard || return 0
|
runtime_script_status_guard update || return 0
|
||||||
update_script
|
update_script
|
||||||
run_addon_updates
|
run_addon_updates
|
||||||
update_motd_ip
|
update_motd_ip
|
||||||
@@ -3840,7 +3862,7 @@ start() {
|
|||||||
set_std_mode
|
set_std_mode
|
||||||
ensure_profile_loaded
|
ensure_profile_loaded
|
||||||
get_lxc_ip
|
get_lxc_ip
|
||||||
runtime_script_status_guard || return 0
|
runtime_script_status_guard update || return 0
|
||||||
update_script
|
update_script
|
||||||
run_addon_updates
|
run_addon_updates
|
||||||
update_motd_ip
|
update_motd_ip
|
||||||
@@ -3870,7 +3892,7 @@ start() {
|
|||||||
esac
|
esac
|
||||||
ensure_profile_loaded
|
ensure_profile_loaded
|
||||||
get_lxc_ip
|
get_lxc_ip
|
||||||
runtime_script_status_guard || return 0
|
runtime_script_status_guard update || return 0
|
||||||
update_script
|
update_script
|
||||||
run_addon_updates
|
run_addon_updates
|
||||||
update_motd_ip
|
update_motd_ip
|
||||||
@@ -4050,6 +4072,11 @@ build_container() {
|
|||||||
export RANDOM_UUID="$RANDOM_UUID"
|
export RANDOM_UUID="$RANDOM_UUID"
|
||||||
export EXECUTION_ID="$EXECUTION_ID"
|
export EXECUTION_ID="$EXECUTION_ID"
|
||||||
export SESSION_ID="$SESSION_ID"
|
export SESSION_ID="$SESSION_ID"
|
||||||
|
# Repo attribution + platform for container-side progress pings (the
|
||||||
|
# container inherits the host's detection instead of re-detecting)
|
||||||
|
export REPO_SOURCE="${REPO_SOURCE:-}"
|
||||||
|
export REPO_SLUG="${REPO_SLUG:-}"
|
||||||
|
export TELEMETRY_PLATFORM="pve"
|
||||||
export CACHER="$APT_CACHER"
|
export CACHER="$APT_CACHER"
|
||||||
export CACHER_IP="$APT_CACHER_IP"
|
export CACHER_IP="$APT_CACHER_IP"
|
||||||
if [[ -n "${HTTP_PROXY:-}" ]]; then
|
if [[ -n "${HTTP_PROXY:-}" ]]; then
|
||||||
@@ -4211,27 +4238,31 @@ $PCT_OPTIONS_STRING"
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for Intel GPU - look for Intel vendor ID [8086]
|
# Map each DRI render/card node to its owning GPU via the PCI vendor ID
|
||||||
if grep -q "\[8086:" <<<"$pci_vga_info"; then
|
# exposed in sysfs (/sys/class/drm/<node>/device/vendor). This is required
|
||||||
msg_custom "🎮" "${BL}" "Detected Intel GPU"
|
# on multi-GPU hosts: globbing every /dev/dri node onto the first detected
|
||||||
|
# vendor would pass through *both* GPUs and skip the selection prompt.
|
||||||
if [[ -d /dev/dri ]]; then
|
if [[ -d /dev/dri ]]; then
|
||||||
for d in /dev/dri/renderD* /dev/dri/card*; do
|
for d in /dev/dri/renderD* /dev/dri/card*; do
|
||||||
[[ -e "$d" ]] && INTEL_DEVICES+=("$d")
|
[[ -e "$d" ]] || continue
|
||||||
|
local node vendor
|
||||||
|
node=$(basename "$d")
|
||||||
|
vendor=$(cat "/sys/class/drm/${node}/device/vendor" 2>/dev/null || true)
|
||||||
|
case "$vendor" in
|
||||||
|
0x8086) INTEL_DEVICES+=("$d") ;; # Intel
|
||||||
|
0x1002 | 0x1022) AMD_DEVICES+=("$d") ;; # AMD/ATI
|
||||||
|
0x10de) ;; # NVIDIA - handled via /dev/nvidia* below
|
||||||
|
*) msg_debug "Unmapped GPU vendor '${vendor:-unknown}' for $d" ;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for AMD GPU - look for AMD vendor IDs [1002] (AMD/ATI) or [1022] (AMD)
|
[[ ${#INTEL_DEVICES[@]} -gt 0 ]] && msg_custom "🎮" "${BL}" "Detected Intel GPU"
|
||||||
if grep -qE "\[1002:|\[1022:" <<<"$pci_vga_info"; then
|
[[ ${#AMD_DEVICES[@]} -gt 0 ]] && msg_custom "🎮" "${RD}" "Detected AMD GPU"
|
||||||
msg_custom "🎮" "${RD}" "Detected AMD GPU"
|
|
||||||
if [[ -d /dev/dri ]]; then
|
# AMD compute (ROCm) additionally needs /dev/kfd alongside the render nodes
|
||||||
# Only add if not already claimed by Intel
|
if [[ ${#AMD_DEVICES[@]} -gt 0 && -e /dev/kfd ]]; then
|
||||||
if [[ ${#INTEL_DEVICES[@]} -eq 0 ]]; then
|
AMD_DEVICES+=("/dev/kfd")
|
||||||
for d in /dev/dri/renderD* /dev/dri/card* /dev/kfd; do
|
|
||||||
[[ -e "$d" ]] && AMD_DEVICES+=("$d")
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for NVIDIA GPU - look for NVIDIA vendor ID [10de]
|
# Check for NVIDIA GPU - look for NVIDIA vendor ID [10de]
|
||||||
@@ -4869,6 +4900,16 @@ EOF
|
|||||||
# Point INSTALL_LOG to combined log so get_full_log() finds it
|
# Point INSTALL_LOG to combined log so get_full_log() finds it
|
||||||
INSTALL_LOG="$combined_log"
|
INSTALL_LOG="$combined_log"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Pull the structured error capture (.errinfo) from the container.
|
||||||
|
# It contains EXACTLY the output of the command that failed (written by
|
||||||
|
# silent()/error_handler inside the container) and is the primary source
|
||||||
|
# for the telemetry error trace - instead of a generic log tail.
|
||||||
|
local host_errinfo="/tmp/.errinfo-${SESSION_ID}"
|
||||||
|
if timeout 8 pct pull "$CTID" "/root/.install-${SESSION_ID}.log.errinfo" "$host_errinfo" 2>/dev/null && [[ -s "$host_errinfo" ]]; then
|
||||||
|
TELEMETRY_ERRINFO="$host_errinfo"
|
||||||
|
export TELEMETRY_ERRINFO
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Defense-in-depth: Ensure error handling stays disabled during recovery.
|
# Defense-in-depth: Ensure error handling stays disabled during recovery.
|
||||||
@@ -5144,6 +5185,8 @@ EOF
|
|||||||
echo -e " Verbose: ${GN}enabled${CL}"
|
echo -e " Verbose: ${GN}enabled${CL}"
|
||||||
echo ""
|
echo ""
|
||||||
msg_info "Restarting installation..."
|
msg_info "Restarting installation..."
|
||||||
|
# New telemetry execution for the retry (previous one keeps its "failed")
|
||||||
|
declare -f telemetry_new_attempt &>/dev/null && telemetry_new_attempt
|
||||||
# Re-run build_container
|
# Re-run build_container
|
||||||
build_container
|
build_container
|
||||||
return $?
|
return $?
|
||||||
@@ -5183,6 +5226,10 @@ EOF
|
|||||||
echo ""
|
echo ""
|
||||||
msg_info "Re-running installation script..."
|
msg_info "Re-running installation script..."
|
||||||
|
|
||||||
|
# New telemetry execution for the in-place retry
|
||||||
|
declare -f telemetry_new_attempt &>/dev/null && telemetry_new_attempt
|
||||||
|
declare -f post_to_api &>/dev/null && post_to_api 2>/dev/null || true
|
||||||
|
|
||||||
# Re-run install script in existing container (don't destroy/recreate)
|
# Re-run install script in existing container (don't destroy/recreate)
|
||||||
set +Eeuo pipefail
|
set +Eeuo pipefail
|
||||||
trap - ERR
|
trap - ERR
|
||||||
@@ -5246,6 +5293,7 @@ EOF
|
|||||||
echo -e " Verbose: ${GN}enabled${CL}"
|
echo -e " Verbose: ${GN}enabled${CL}"
|
||||||
echo ""
|
echo ""
|
||||||
msg_info "Restarting installation..."
|
msg_info "Restarting installation..."
|
||||||
|
declare -f telemetry_new_attempt &>/dev/null && telemetry_new_attempt
|
||||||
build_container
|
build_container
|
||||||
return $?
|
return $?
|
||||||
fi
|
fi
|
||||||
@@ -5275,6 +5323,7 @@ EOF
|
|||||||
echo -e " Verbose: ${GN}enabled${CL}"
|
echo -e " Verbose: ${GN}enabled${CL}"
|
||||||
echo ""
|
echo ""
|
||||||
msg_info "Restarting installation..."
|
msg_info "Restarting installation..."
|
||||||
|
declare -f telemetry_new_attempt &>/dev/null && telemetry_new_attempt
|
||||||
build_container
|
build_container
|
||||||
return $?
|
return $?
|
||||||
fi
|
fi
|
||||||
@@ -5299,6 +5348,7 @@ EOF
|
|||||||
echo -e " Verbose: ${GN}enabled${CL}"
|
echo -e " Verbose: ${GN}enabled${CL}"
|
||||||
echo ""
|
echo ""
|
||||||
msg_info "Restarting installation..."
|
msg_info "Restarting installation..."
|
||||||
|
declare -f telemetry_new_attempt &>/dev/null && telemetry_new_attempt
|
||||||
build_container
|
build_container
|
||||||
return $?
|
return $?
|
||||||
fi
|
fi
|
||||||
@@ -6973,6 +7023,16 @@ ensure_log_on_host() {
|
|||||||
rm -f "$temp_log"
|
rm -f "$temp_log"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
# Also pull the structured error capture (.errinfo) so the telemetry error
|
||||||
|
# trace shows the failing command's exact output (signal-exit paths reach
|
||||||
|
# this via on_exit before/instead of the recovery flow)
|
||||||
|
if [[ -z "${TELEMETRY_ERRINFO:-}" || ! -s "${TELEMETRY_ERRINFO:-}" ]]; then
|
||||||
|
local host_errinfo="/tmp/.errinfo-${SESSION_ID}"
|
||||||
|
if timeout 8 pct pull "$CTID" "/root/.install-${SESSION_ID}.log.errinfo" "$host_errinfo" 2>/dev/null && [[ -s "$host_errinfo" ]]; then
|
||||||
|
TELEMETRY_ERRINFO="$host_errinfo"
|
||||||
|
export TELEMETRY_ERRINFO
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if [[ -s "$combined_log" ]]; then
|
if [[ -s "$combined_log" ]]; then
|
||||||
INSTALL_LOG="$combined_log"
|
INSTALL_LOG="$combined_log"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -546,6 +546,12 @@ silent() {
|
|||||||
set +Eeuo pipefail
|
set +Eeuo pipefail
|
||||||
trap - ERR
|
trap - ERR
|
||||||
|
|
||||||
|
# Byte offset BEFORE the command runs - everything the log grows by is
|
||||||
|
# exactly this command's output (used for the .errinfo telemetry capture)
|
||||||
|
local start_bytes=0
|
||||||
|
[[ -f "$logfile" ]] && start_bytes=$(stat -c%s "$logfile" 2>/dev/null || echo 0)
|
||||||
|
[[ ! "$start_bytes" =~ ^[0-9]+$ ]] && start_bytes=0
|
||||||
|
|
||||||
"$@" >>"$logfile" 2>&1
|
"$@" >>"$logfile" 2>&1
|
||||||
local rc=$?
|
local rc=$?
|
||||||
|
|
||||||
@@ -567,12 +573,43 @@ silent() {
|
|||||||
export _SILENT_FAILED_LINE="$caller_line"
|
export _SILENT_FAILED_LINE="$caller_line"
|
||||||
export _SILENT_FAILED_LOG="$logfile"
|
export _SILENT_FAILED_LOG="$logfile"
|
||||||
|
|
||||||
|
# ── Structured error capture (.errinfo) for telemetry ──
|
||||||
|
# Extract exactly THIS command's output (from the recorded byte offset),
|
||||||
|
# strip ANSI/progress noise, keep the last 60 lines. The host builds the
|
||||||
|
# telemetry error trace from this file (pulled from the container on
|
||||||
|
# failure). Self-contained - containers don't source api.func.
|
||||||
|
{
|
||||||
|
local flat_cmd
|
||||||
|
flat_cmd=$(printf '%s' "$cmd" | tr '\n' ' ' | head -c 300)
|
||||||
|
echo "EXIT_CODE=${rc}"
|
||||||
|
echo "LINE=${caller_line}"
|
||||||
|
echo "COMMAND=${flat_cmd}"
|
||||||
|
echo "--- OUTPUT ---"
|
||||||
|
if [[ -s "$logfile" ]]; then
|
||||||
|
local segment
|
||||||
|
segment=$(tail -c +"$((start_bytes + 1))" "$logfile" 2>/dev/null |
|
||||||
|
sed 's/\r$//' |
|
||||||
|
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' |
|
||||||
|
grep -avE '^(Get:|Hit:|Ign:|Fetched |Reading package lists|Reading state information|Building dependency tree|Selecting previously|Preparing to unpack|Unpacking |Processing triggers for|\(Reading database|[0-9]+%[[:space:]]*\[)' |
|
||||||
|
grep -avE '^[[:space:]]*$' |
|
||||||
|
tail -n 60)
|
||||||
|
# If the noise filter swallowed everything, fall back to the raw tail
|
||||||
|
if [[ -z "$segment" ]]; then
|
||||||
|
segment=$(tail -c +"$((start_bytes + 1))" "$logfile" 2>/dev/null |
|
||||||
|
sed 's/\r$//' | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' | tail -n 60)
|
||||||
|
fi
|
||||||
|
printf '%s' "$segment" | head -c 10240
|
||||||
|
fi
|
||||||
|
} >"${logfile}.errinfo" 2>/dev/null || true
|
||||||
|
|
||||||
return "$rc"
|
return "$rc"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Clear stale flags on success (prevents false positives if a previous
|
# Clear stale flags on success (prevents false positives if a previous
|
||||||
# $STD cmd || true failed and a later non-silent command triggers error_handler)
|
# $STD cmd || true failed and a later non-silent command triggers error_handler)
|
||||||
unset _SILENT_FAILED_RC _SILENT_FAILED_CMD _SILENT_FAILED_LINE _SILENT_FAILED_LOG 2>/dev/null || true
|
unset _SILENT_FAILED_RC _SILENT_FAILED_CMD _SILENT_FAILED_LINE _SILENT_FAILED_LOG 2>/dev/null || true
|
||||||
|
# Also drop a stale .errinfo from a previously tolerated failure ($STD cmd || true)
|
||||||
|
rm -f "${logfile}.errinfo" 2>/dev/null || true
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|||||||
+177
-217
@@ -7,12 +7,17 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Provides comprehensive error handling and signal management for all scripts.
|
# Provides error handling and signal management for all scripts.
|
||||||
# Includes:
|
#
|
||||||
# - Exit code explanations (shell, package managers, databases, custom codes)
|
# TELEMETRY CONTRACT:
|
||||||
# - Error handler with detailed logging
|
# - HOST context: this file reports terminal statuses via post_update_to_api
|
||||||
# - Signal handlers (EXIT, INT, TERM)
|
# (full metadata + focused error trace).
|
||||||
# - Initialization function for trap setup
|
# - CONTAINER context: this file NEVER talks to the telemetry API. It writes
|
||||||
|
# two local artifacts that the host picks up after lxc-attach returns:
|
||||||
|
# /root/.install-<SESSION_ID>.failed → exit code (flag file)
|
||||||
|
# /root/.install-<SESSION_ID>.log.errinfo → structured error capture
|
||||||
|
# This guarantees the server only ever sees ONE terminal event per
|
||||||
|
# execution - the host's complete one.
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# source <(curl -fsSL .../error_handler.func)
|
# source <(curl -fsSL .../error_handler.func)
|
||||||
@@ -21,15 +26,14 @@
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 1: EXIT CODE EXPLANATIONS
|
# SECTION 1: EXIT CODE EXPLANATIONS (fallback)
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# explain_exit_code()
|
# explain_exit_code()
|
||||||
#
|
#
|
||||||
# - Canonical version is defined in api.func (sourced before this file)
|
# - Canonical version lives in api.func (sourced before this file on the host)
|
||||||
# - This section only provides a fallback if api.func was not loaded
|
# - This fallback covers the container context where api.func is not sourced
|
||||||
# - See api.func SECTION 1 for the authoritative exit code mappings
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
if ! declare -f explain_exit_code &>/dev/null; then
|
if ! declare -f explain_exit_code &>/dev/null; then
|
||||||
explain_exit_code() {
|
explain_exit_code() {
|
||||||
@@ -94,8 +98,6 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
|||||||
100) echo "APT: Package manager error (broken packages / dependency problems)" ;;
|
100) echo "APT: Package manager error (broken packages / dependency problems)" ;;
|
||||||
101) echo "APT: Configuration error (bad sources.list, malformed config)" ;;
|
101) echo "APT: Configuration error (bad sources.list, malformed config)" ;;
|
||||||
102) echo "APT: Lock held by another process (dpkg/apt still running)" ;;
|
102) echo "APT: Lock held by another process (dpkg/apt still running)" ;;
|
||||||
|
|
||||||
# --- Script Validation & Setup (103-123) ---
|
|
||||||
103) echo "Validation: Shell is not Bash" ;;
|
103) echo "Validation: Shell is not Bash" ;;
|
||||||
104) echo "Validation: Not running as root (or invoked via sudo)" ;;
|
104) echo "Validation: Not running as root (or invoked via sudo)" ;;
|
||||||
105) echo "Validation: Proxmox VE version not supported" ;;
|
105) echo "Validation: Proxmox VE version not supported" ;;
|
||||||
@@ -177,9 +179,8 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
|||||||
223) echo "Proxmox: Template not available after download" ;;
|
223) echo "Proxmox: Template not available after download" ;;
|
||||||
224) echo "Proxmox: PBS storage is for backups only" ;;
|
224) echo "Proxmox: PBS storage is for backups only" ;;
|
||||||
225) echo "Proxmox: No template available for OS/Version" ;;
|
225) echo "Proxmox: No template available for OS/Version" ;;
|
||||||
|
226) echo "Proxmox: VM disk import or post-creation setup failed" ;;
|
||||||
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
||||||
|
|
||||||
# --- Tools & Addon Scripts (232-238) ---
|
|
||||||
232) echo "Tools: Wrong execution environment (run on PVE host, not inside LXC)" ;;
|
232) echo "Tools: Wrong execution environment (run on PVE host, not inside LXC)" ;;
|
||||||
233) echo "Tools: Application not installed (update prerequisite missing)" ;;
|
233) echo "Tools: Application not installed (update prerequisite missing)" ;;
|
||||||
234) echo "Tools: No LXC containers found or available" ;;
|
234) echo "Tools: No LXC containers found or available" ;;
|
||||||
@@ -187,7 +188,6 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
|||||||
236) echo "Tools: Required hardware not detected" ;;
|
236) echo "Tools: Required hardware not detected" ;;
|
||||||
237) echo "Tools: Dependency package installation failed" ;;
|
237) echo "Tools: Dependency package installation failed" ;;
|
||||||
238) echo "Tools: OS or distribution not supported for this addon" ;;
|
238) echo "Tools: OS or distribution not supported for this addon" ;;
|
||||||
|
|
||||||
239) echo "npm/Node.js: Unexpected runtime error or dependency failure" ;;
|
239) echo "npm/Node.js: Unexpected runtime error or dependency failure" ;;
|
||||||
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
|
243) echo "Node.js: Out of memory (JavaScript heap out of memory)" ;;
|
||||||
245) echo "Node.js: Invalid command-line option" ;;
|
245) echo "Node.js: Invalid command-line option" ;;
|
||||||
@@ -195,14 +195,11 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
|||||||
247) echo "Node.js: Fatal internal error" ;;
|
247) echo "Node.js: Fatal internal error" ;;
|
||||||
248) echo "Node.js: Invalid C++ addon / N-API failure" ;;
|
248) echo "Node.js: Invalid C++ addon / N-API failure" ;;
|
||||||
249) echo "npm/pnpm/yarn: Unknown fatal error" ;;
|
249) echo "npm/pnpm/yarn: Unknown fatal error" ;;
|
||||||
|
|
||||||
# --- Application Install/Update Errors (250-254) ---
|
|
||||||
250) echo "App: Download failed or version not determined" ;;
|
250) echo "App: Download failed or version not determined" ;;
|
||||||
251) echo "App: File extraction failed (corrupt or incomplete archive)" ;;
|
251) echo "App: File extraction failed (corrupt or incomplete archive)" ;;
|
||||||
252) echo "App: Required file or resource not found" ;;
|
252) echo "App: Required file or resource not found" ;;
|
||||||
253) echo "App: Data migration required — update aborted" ;;
|
253) echo "App: Data migration required — update aborted" ;;
|
||||||
254) echo "App: User declined prompt or input timed out" ;;
|
254) echo "App: User declined prompt or input timed out" ;;
|
||||||
|
|
||||||
255) echo "DPKG: Fatal internal error" ;;
|
255) echo "DPKG: Fatal internal error" ;;
|
||||||
*) echo "Unknown error" ;;
|
*) echo "Unknown error" ;;
|
||||||
esac
|
esac
|
||||||
@@ -210,24 +207,98 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 2: ERROR HANDLERS
|
# SECTION 2: CONTEXT DETECTION & CONTAINER ARTIFACTS
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# _is_container_context()
|
||||||
|
#
|
||||||
|
# - Returns 0 (true) when running INSIDE the LXC container being installed
|
||||||
|
# - TELEMETRY_CONTEXT can override the heuristic ("host" / "container");
|
||||||
|
# install.func sets TELEMETRY_CONTEXT=container during bootstrap
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
_is_container_context() {
|
||||||
|
case "${TELEMETRY_CONTEXT:-}" in
|
||||||
|
container) return 0 ;;
|
||||||
|
host) return 1 ;;
|
||||||
|
esac
|
||||||
|
# Proxmox/Incus tooling exists only on the host
|
||||||
|
command -v pveversion &>/dev/null && return 1
|
||||||
|
command -v pct &>/dev/null && return 1
|
||||||
|
command -v incus &>/dev/null && return 1
|
||||||
|
# systemd-detect-virt reports lxc inside containers
|
||||||
|
if command -v systemd-detect-virt &>/dev/null; then
|
||||||
|
case "$(systemd-detect-virt -c 2>/dev/null)" in
|
||||||
|
lxc | lxc-libvirt | openvz) return 0 ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
# PCT_OSTYPE is exported into the install environment by the host
|
||||||
|
[[ -n "${PCT_OSTYPE:-}" ]] && return 0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# _container_write_failure()
|
||||||
|
#
|
||||||
|
# - Writes the failure artifacts inside the container for the host to pick up:
|
||||||
|
# * flag file with the exit code
|
||||||
|
# * .errinfo capture (if silent() has not already written a better one)
|
||||||
|
# * copy of the install log
|
||||||
|
# - This REPLACES any direct telemetry send from the container
|
||||||
|
# - Arguments: $1 = exit_code, $2 = command (optional), $3 = line (optional)
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
_container_write_failure() {
|
||||||
|
local exit_code="${1:-1}"
|
||||||
|
local command="${2:-}"
|
||||||
|
local line="${3:-}"
|
||||||
|
local sid="${SESSION_ID:-error}"
|
||||||
|
|
||||||
|
# Flag file with exit code (host reads this after lxc-attach returns)
|
||||||
|
echo "$exit_code" >"/root/.install-${sid}.failed" 2>/dev/null || true
|
||||||
|
|
||||||
|
# Keep the install log where the host expects it
|
||||||
|
if [[ -n "${INSTALL_LOG:-}" && -f "${INSTALL_LOG}" && "${INSTALL_LOG}" != "/root/.install-${sid}.log" ]]; then
|
||||||
|
cp "${INSTALL_LOG}" "/root/.install-${sid}.log" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Structured error capture (skip if silent() already wrote the exact
|
||||||
|
# output segment of the failing command - that one is always better).
|
||||||
|
# Self-contained: api.func is NOT sourced inside containers.
|
||||||
|
local errinfo="${INSTALL_LOG:-/root/.install-${sid}.log}.errinfo"
|
||||||
|
if [[ ! -s "$errinfo" ]]; then
|
||||||
|
local flat_cmd
|
||||||
|
flat_cmd=$(printf '%s' "${command:-unknown}" | tr '\n' ' ' | head -c 300)
|
||||||
|
{
|
||||||
|
echo "EXIT_CODE=${exit_code}"
|
||||||
|
echo "LINE=${line:-0}"
|
||||||
|
echo "COMMAND=${flat_cmd}"
|
||||||
|
echo "--- OUTPUT ---"
|
||||||
|
if [[ -n "${INSTALL_LOG:-}" && -s "${INSTALL_LOG}" ]]; then
|
||||||
|
tail -n 80 "${INSTALL_LOG}" 2>/dev/null |
|
||||||
|
sed 's/\r$//' |
|
||||||
|
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g' |
|
||||||
|
grep -avE '^(Get:|Hit:|Ign:|Fetched |Reading package lists|Reading state information|Building dependency tree|Selecting previously|Preparing to unpack|Unpacking |Processing triggers for|\(Reading database|[0-9]+%[[:space:]]*\[)' |
|
||||||
|
grep -avE '^[[:space:]]*$' |
|
||||||
|
tail -n 60 | head -c 10240
|
||||||
|
fi
|
||||||
|
} >"$errinfo" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# SECTION 3: ERROR HANDLER
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# error_handler()
|
# error_handler()
|
||||||
#
|
#
|
||||||
# - Main error handler triggered by ERR trap
|
# - Main error handler triggered by ERR trap
|
||||||
# - Arguments: exit_code, command, line_number
|
# - Displays error message with line number, exit code, explanation, command
|
||||||
# - Behavior:
|
# - Shows last 20 lines of the active log
|
||||||
# * Returns silently if exit_code is 0 (success)
|
# - Emits actionable hints for common failure patterns (OOM, APT, network...)
|
||||||
# * Sources explain_exit_code() for detailed error description
|
# - HOST: reports "failed" to telemetry (full payload via api.func)
|
||||||
# * Displays error message with:
|
# - CONTAINER: writes failure artifacts, sends nothing
|
||||||
# - Line number where error occurred
|
# - Exits with original exit code
|
||||||
# - Exit code with explanation
|
|
||||||
# - Command that failed
|
|
||||||
# * Shows last 20 lines of SILENT_LOGFILE if available
|
|
||||||
# * Copies log to container /root for later inspection
|
|
||||||
# * Exits with original exit code
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
error_handler() {
|
error_handler() {
|
||||||
local exit_code=${1:-$?}
|
local exit_code=${1:-$?}
|
||||||
@@ -237,12 +308,10 @@ error_handler() {
|
|||||||
command="${command//\$STD/}"
|
command="${command//\$STD/}"
|
||||||
|
|
||||||
# If error originated from silent(), use its captured metadata
|
# If error originated from silent(), use its captured metadata
|
||||||
# This provides the actual command and line number instead of "silent ..."
|
|
||||||
if [[ -n "${_SILENT_FAILED_RC:-}" ]]; then
|
if [[ -n "${_SILENT_FAILED_RC:-}" ]]; then
|
||||||
exit_code="$_SILENT_FAILED_RC"
|
exit_code="$_SILENT_FAILED_RC"
|
||||||
command="$_SILENT_FAILED_CMD"
|
command="$_SILENT_FAILED_CMD"
|
||||||
line_number="$_SILENT_FAILED_LINE"
|
line_number="$_SILENT_FAILED_LINE"
|
||||||
# Clear flags to prevent stale data on subsequent errors
|
|
||||||
unset _SILENT_FAILED_RC _SILENT_FAILED_CMD _SILENT_FAILED_LINE
|
unset _SILENT_FAILED_RC _SILENT_FAILED_CMD _SILENT_FAILED_LINE
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -250,8 +319,12 @@ error_handler() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Stop spinner and restore cursor FIRST — before any output
|
# Export the failure location so telemetry can include the "where"
|
||||||
# This prevents spinner text overlapping with error messages
|
FAILED_COMMAND="$command"
|
||||||
|
FAILED_LINE="$line_number"
|
||||||
|
export FAILED_COMMAND FAILED_LINE
|
||||||
|
|
||||||
|
# Stop spinner and restore cursor FIRST - before any output
|
||||||
if declare -f stop_spinner >/dev/null 2>&1; then
|
if declare -f stop_spinner >/dev/null 2>&1; then
|
||||||
stop_spinner 2>/dev/null || true
|
stop_spinner 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
@@ -259,18 +332,18 @@ error_handler() {
|
|||||||
|
|
||||||
local explanation
|
local explanation
|
||||||
explanation="$(explain_exit_code "$exit_code")"
|
explanation="$(explain_exit_code "$exit_code")"
|
||||||
|
if [[ "$explanation" == curl:* && ! "$command" =~ (^|[[:space:]])([^[:space:]]*/)?curl([[:space:]]|$) ]]; then
|
||||||
# ALWAYS report failure to API immediately - don't wait for container checks
|
explanation="Command failed with exit status ${exit_code}"
|
||||||
# This ensures we capture failures that occur before/after container exists
|
|
||||||
if declare -f post_update_to_api &>/dev/null; then
|
|
||||||
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
|
|
||||||
else
|
|
||||||
# Container context: post_update_to_api not available (api.func not sourced)
|
|
||||||
# Send status directly via curl so container failures are never lost
|
|
||||||
_send_abort_telemetry "$exit_code" 2>/dev/null || true
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Use msg_error if available, fallback to echo
|
# ── Telemetry / failure artifacts ──
|
||||||
|
if _is_container_context; then
|
||||||
|
_container_write_failure "$exit_code" "$command" "$line_number"
|
||||||
|
elif declare -f post_update_to_api &>/dev/null; then
|
||||||
|
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Display ──
|
||||||
if declare -f msg_error >/dev/null 2>&1; then
|
if declare -f msg_error >/dev/null 2>&1; then
|
||||||
msg_error "in line ${line_number}: exit code ${exit_code} (${explanation}): while executing command ${command}"
|
msg_error "in line ${line_number}: exit code ${exit_code} (${explanation}): while executing command ${command}"
|
||||||
else
|
else
|
||||||
@@ -288,8 +361,7 @@ error_handler() {
|
|||||||
} >>"$DEBUG_LOGFILE"
|
} >>"$DEBUG_LOGFILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get active log file (BUILD_LOG or INSTALL_LOG)
|
# Get active log file (prefer silent()'s logfile when available)
|
||||||
# Prefer silent()'s logfile when available (contains the actual command output)
|
|
||||||
local active_log=""
|
local active_log=""
|
||||||
if [[ -n "${_SILENT_FAILED_LOG:-}" && -s "${_SILENT_FAILED_LOG}" ]]; then
|
if [[ -n "${_SILENT_FAILED_LOG:-}" && -s "${_SILENT_FAILED_LOG}" ]]; then
|
||||||
active_log="$_SILENT_FAILED_LOG"
|
active_log="$_SILENT_FAILED_LOG"
|
||||||
@@ -300,21 +372,17 @@ error_handler() {
|
|||||||
active_log="$SILENT_LOGFILE"
|
active_log="$SILENT_LOGFILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If active_log points to a container-internal path that doesn't exist on host,
|
|
||||||
# fall back to BUILD_LOG (host-side log)
|
|
||||||
if [[ -n "$active_log" && ! -s "$active_log" && -n "${BUILD_LOG:-}" && -s "${BUILD_LOG}" ]]; then
|
if [[ -n "$active_log" && ! -s "$active_log" && -n "${BUILD_LOG:-}" && -s "${BUILD_LOG}" ]]; then
|
||||||
active_log="$BUILD_LOG"
|
active_log="$BUILD_LOG"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Show last log lines if available
|
|
||||||
if [[ -n "$active_log" && -s "$active_log" ]]; then
|
if [[ -n "$active_log" && -s "$active_log" ]]; then
|
||||||
echo -e "\n${TAB}--- Last 20 lines of log ---"
|
echo -e "\n${TAB}--- Last 20 lines of log ---"
|
||||||
tail -n 20 "$active_log"
|
tail -n 20 "$active_log"
|
||||||
echo -e "${TAB}-----------------------------------\n"
|
echo -e "${TAB}-----------------------------------\n"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Detect probable Node.js heap OOM and print actionable guidance.
|
# ── Node.js heap OOM detection with actionable guidance ──
|
||||||
# This avoids generic SIGABRT/SIGKILL confusion for frontend build failures.
|
|
||||||
local node_oom_detected="false"
|
local node_oom_detected="false"
|
||||||
local node_build_context="false"
|
local node_build_context="false"
|
||||||
if [[ "$command" =~ (npm|pnpm|yarn|node|vite|turbo) ]]; then
|
if [[ "$command" =~ (npm|pnpm|yarn|node|vite|turbo) ]]; then
|
||||||
@@ -331,7 +399,6 @@ error_handler() {
|
|||||||
if [[ "$node_oom_detected" == "true" ]] || { [[ "$node_build_context" == "true" ]] && [[ "$exit_code" =~ ^(134|137)$ ]]; }; then
|
if [[ "$node_oom_detected" == "true" ]] || { [[ "$node_build_context" == "true" ]] && [[ "$exit_code" =~ ^(134|137)$ ]]; }; then
|
||||||
local heap_hint_mb=""
|
local heap_hint_mb=""
|
||||||
|
|
||||||
# If explicitly configured, prefer the current value for troubleshooting output.
|
|
||||||
if [[ -n "${NODE_OPTIONS:-}" ]] && [[ "${NODE_OPTIONS}" =~ max-old-space-size=([0-9]+) ]]; then
|
if [[ -n "${NODE_OPTIONS:-}" ]] && [[ "${NODE_OPTIONS}" =~ max-old-space-size=([0-9]+) ]]; then
|
||||||
heap_hint_mb="${BASH_REMATCH[1]}"
|
heap_hint_mb="${BASH_REMATCH[1]}"
|
||||||
elif [[ -n "${var_ram:-}" ]] && [[ "${var_ram}" =~ ^[0-9]+$ ]]; then
|
elif [[ -n "${var_ram:-}" ]] && [[ "${var_ram}" =~ ^[0-9]+$ ]]; then
|
||||||
@@ -358,14 +425,13 @@ error_handler() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ── Log-pattern analysis: detect common failure causes and emit actionable hints ──
|
# ── Log-pattern analysis: actionable hints for common failure causes ──
|
||||||
if [[ -n "$active_log" && -s "$active_log" ]]; then
|
if [[ -n "$active_log" && -s "$active_log" ]]; then
|
||||||
local _log_tail
|
local _log_tail
|
||||||
_log_tail=$(tail -n 60 "$active_log" 2>/dev/null || true)
|
_log_tail=$(tail -n 60 "$active_log" 2>/dev/null || true)
|
||||||
|
|
||||||
# 1. APT/dpkg dependency conflict
|
# 1. APT/dpkg dependency conflict
|
||||||
if echo "$_log_tail" | grep -qE "Depends:|depends on.*but.*not installed|broken packages|unmet dep|dependency problems"; then
|
if echo "$_log_tail" | grep -qE "Depends:|depends on.*but.*not installed|broken packages|unmet dep|dependency problems"; then
|
||||||
# Check for PostgreSQL-specific version mismatch (most actionable)
|
|
||||||
local _pg_conflict
|
local _pg_conflict
|
||||||
_pg_conflict=$(echo "$_log_tail" | grep -oE 'postgresql-[0-9]+ but.*installed' | head -1 || true)
|
_pg_conflict=$(echo "$_log_tail" | grep -oE 'postgresql-[0-9]+ but.*installed' | head -1 || true)
|
||||||
if [[ -n "$_pg_conflict" ]]; then
|
if [[ -n "$_pg_conflict" ]]; then
|
||||||
@@ -386,7 +452,7 @@ error_handler() {
|
|||||||
msg_warn "Hint: A repository GPG key may be missing, expired, or the keyring file is not yet present (/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc etc.)."
|
msg_warn "Hint: A repository GPG key may be missing, expired, or the keyring file is not yet present (/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc etc.)."
|
||||||
msg_warn "Hint: Install the 'postgresql-common' package first, or re-add the repository with its correct signing key."
|
msg_warn "Hint: Install the 'postgresql-common' package first, or re-add the repository with its correct signing key."
|
||||||
fi
|
fi
|
||||||
# 3. Network / DNS failure during apt-get or curl
|
# 3. Network / DNS failure
|
||||||
elif echo "$_log_tail" | grep -qE "Could not resolve|Failed to fetch|Unable to connect|Name or service not known|Network is unreachable|curl.*resolve"; then
|
elif echo "$_log_tail" | grep -qE "Could not resolve|Failed to fetch|Unable to connect|Name or service not known|Network is unreachable|curl.*resolve"; then
|
||||||
if declare -f msg_warn >/dev/null 2>&1; then
|
if declare -f msg_warn >/dev/null 2>&1; then
|
||||||
msg_warn "Network or DNS failure detected."
|
msg_warn "Network or DNS failure detected."
|
||||||
@@ -407,17 +473,12 @@ error_handler() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Detect context: Container (INSTALL_LOG set + inside container /root) vs Host
|
# ── Context-specific cleanup ──
|
||||||
if [[ -n "${INSTALL_LOG:-}" && -f "${INSTALL_LOG:-}" && -d /root ]]; then
|
if _is_container_context; then
|
||||||
# CONTAINER CONTEXT: Copy log and create flag file for host
|
# Container: artifacts already written above; nothing more to do
|
||||||
local container_log="/root/.install-${SESSION_ID:-error}.log"
|
:
|
||||||
cp "${INSTALL_LOG}" "$container_log" 2>/dev/null || true
|
|
||||||
|
|
||||||
# Create error flag file with exit code for host detection
|
|
||||||
echo "$exit_code" >"/root/.install-${SESSION_ID:-error}.failed" 2>/dev/null || true
|
|
||||||
# Log path is shown by host as combined log - no need to show container path
|
|
||||||
else
|
else
|
||||||
# HOST CONTEXT: Show local log path and offer container cleanup
|
# HOST: show log path and offer container cleanup
|
||||||
if [[ -n "$active_log" && -s "$active_log" ]]; then
|
if [[ -n "$active_log" && -s "$active_log" ]]; then
|
||||||
if declare -f msg_custom >/dev/null 2>&1; then
|
if declare -f msg_custom >/dev/null 2>&1; then
|
||||||
msg_custom "📋" "${YW}" "Full log: ${active_log}"
|
msg_custom "📋" "${YW}" "Full log: ${active_log}"
|
||||||
@@ -435,7 +496,6 @@ error_handler() {
|
|||||||
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
|
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Read user response
|
|
||||||
local response=""
|
local response=""
|
||||||
if read -t 60 -r response; then
|
if read -t 60 -r response; then
|
||||||
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
|
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
|
||||||
@@ -476,12 +536,6 @@ error_handler() {
|
|||||||
echo -e "${GN}✔${CL} Container ${CTID} removed"
|
echo -e "${GN}✔${CL} Container ${CTID} removed"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Force one final status update attempt after cleanup
|
|
||||||
# This ensures status is updated even if the first attempt failed (e.g., HTTP 400)
|
|
||||||
if declare -f post_update_to_api &>/dev/null; then
|
|
||||||
post_update_to_api "failed" "$exit_code" "force"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -489,106 +543,33 @@ error_handler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 3: TELEMETRY & CLEANUP HELPERS FOR SIGNAL HANDLERS
|
# SECTION 4: TELEMETRY & CLEANUP HELPERS FOR SIGNAL HANDLERS
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# _send_abort_telemetry()
|
# _send_abort_telemetry() (compatibility name)
|
||||||
#
|
#
|
||||||
# - Sends failure/abort status to telemetry API
|
# - HOST: reports via post_update_to_api (signals map to "aborted" there)
|
||||||
# - Works in BOTH host context (post_update_to_api available) and
|
# - CONTAINER: writes failure artifacts instead of sending anything
|
||||||
# container context (only curl available, api.func not sourced)
|
|
||||||
# - Container context is critical: without this, container-side failures
|
|
||||||
# and signal exits are never reported, leaving records stuck in
|
|
||||||
# "installing" or "configuring" forever
|
|
||||||
# - Arguments: $1 = exit_code
|
# - Arguments: $1 = exit_code
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
_send_abort_telemetry() {
|
_send_abort_telemetry() {
|
||||||
local exit_code="${1:-1}"
|
local exit_code="${1:-1}"
|
||||||
# Try full API function first (host context - api.func sourced)
|
if _is_container_context; then
|
||||||
if declare -f post_update_to_api &>/dev/null; then
|
_container_write_failure "$exit_code"
|
||||||
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
# Fallback: direct curl (container context - api.func NOT sourced)
|
|
||||||
# This is the ONLY way containers can report failures to telemetry
|
|
||||||
command -v curl &>/dev/null || return 0
|
|
||||||
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
|
|
||||||
[[ -z "${RANDOM_UUID:-}" ]] && return 0
|
|
||||||
|
|
||||||
# Collect last 200 log lines for error diagnosis (best-effort)
|
|
||||||
# Container context has no get_full_log(), so we gather as much as possible
|
|
||||||
local error_text=""
|
|
||||||
local logfile=""
|
|
||||||
if [[ -n "${INSTALL_LOG:-}" && -s "${INSTALL_LOG}" ]]; then
|
|
||||||
logfile="${INSTALL_LOG}"
|
|
||||||
elif [[ -n "${SILENT_LOGFILE:-}" && -s "${SILENT_LOGFILE}" ]]; then
|
|
||||||
logfile="${SILENT_LOGFILE}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$logfile" ]]; then
|
|
||||||
error_text=$(tail -n 200 "$logfile" 2>/dev/null | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g; s/\\/\\\\/g; s/"/\\"/g; s/\r//g' | tr '\n' '|' | sed 's/|$//' | head -c 16384 | tr -d '\000-\010\013\014\016-\037\177') || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Prepend exit code explanation header (like build_error_string does on host)
|
|
||||||
local explanation=""
|
|
||||||
if declare -f explain_exit_code &>/dev/null; then
|
|
||||||
explanation=$(explain_exit_code "$exit_code" 2>/dev/null) || true
|
|
||||||
fi
|
|
||||||
if [[ -n "$explanation" && -n "$error_text" ]]; then
|
|
||||||
error_text="exit_code=${exit_code} | ${explanation}|---|${error_text}"
|
|
||||||
elif [[ -n "$explanation" && -z "$error_text" ]]; then
|
|
||||||
error_text="exit_code=${exit_code} | ${explanation}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Calculate duration if start time is available
|
|
||||||
local duration=""
|
|
||||||
if [[ -n "${DIAGNOSTICS_START_TIME:-}" ]]; then
|
|
||||||
duration=$(($(date +%s) - DIAGNOSTICS_START_TIME))
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Categorize error if function is available (may not be in minimal container context)
|
|
||||||
local error_category=""
|
|
||||||
if declare -f categorize_error &>/dev/null; then
|
|
||||||
error_category=$(categorize_error "$exit_code" 2>/dev/null) || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build JSON payload with error context
|
|
||||||
local payload
|
|
||||||
payload="{\"random_id\":\"${RANDOM_UUID}\",\"execution_id\":\"${EXECUTION_ID:-${RANDOM_UUID}}\",\"type\":\"${TELEMETRY_TYPE:-lxc}\",\"nsapp\":\"${NSAPP:-${app:-unknown}}\",\"status\":\"failed\",\"exit_code\":${exit_code}"
|
|
||||||
[[ -n "$error_text" ]] && payload="${payload},\"error\":\"${error_text}\""
|
|
||||||
[[ -n "$error_category" ]] && payload="${payload},\"error_category\":\"${error_category}\""
|
|
||||||
[[ -n "$duration" ]] && payload="${payload},\"duration\":${duration}"
|
|
||||||
payload="${payload}}"
|
|
||||||
|
|
||||||
local api_url="${TELEMETRY_URL:-https://telemetry.community-scripts.org/telemetry}"
|
|
||||||
|
|
||||||
# 2 attempts (retry once on failure) — original had no retry
|
|
||||||
local attempt
|
|
||||||
for attempt in 1 2; do
|
|
||||||
if curl -fsS -m 5 -X POST "$api_url" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "$payload" &>/dev/null; then
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
[[ $attempt -eq 1 ]] && sleep 1
|
if declare -f post_update_to_api &>/dev/null; then
|
||||||
done
|
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
|
||||||
|
fi
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# _stop_container_if_installing()
|
# _stop_container_if_installing()
|
||||||
#
|
#
|
||||||
# - Stops the LXC container if we're in the install phase
|
# - Stops the LXC container if we're in the install phase (host only)
|
||||||
# - Prevents orphaned container processes when the host exits due to a signal
|
# - Prevents orphaned container processes when the host exits due to a signal
|
||||||
# (SSH disconnect, Ctrl+C, SIGTERM) — without this, the container keeps
|
|
||||||
# running and may send "configuring" status AFTER the host already sent
|
|
||||||
# "failed", leaving records permanently stuck in "configuring"
|
|
||||||
# - Only acts when:
|
|
||||||
# * CONTAINER_INSTALLING flag is set (during lxc-attach in build_container)
|
|
||||||
# * CTID is set (container was created)
|
|
||||||
# * pct command is available (we're on the Proxmox host, not inside a container)
|
|
||||||
# - Does NOT destroy the container — just stops it for potential debugging
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
_stop_container_if_installing() {
|
_stop_container_if_installing() {
|
||||||
[[ "${CONTAINER_INSTALLING:-}" == "true" ]] || return 0
|
[[ "${CONTAINER_INSTALLING:-}" == "true" ]] || return 0
|
||||||
@@ -598,73 +579,67 @@ _stop_container_if_installing() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 4: SIGNAL HANDLERS
|
# SECTION 5: SIGNAL HANDLERS
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# on_exit()
|
# on_exit()
|
||||||
#
|
#
|
||||||
# - EXIT trap handler — runs on EVERY script termination
|
# - EXIT trap handler — runs on EVERY script termination
|
||||||
# - Catches orphaned "installing"/"configuring" records:
|
# - CONTAINER: ensures failure artifacts exist on non-zero exit (this also
|
||||||
# * If post_to_api sent "installing" but post_update_to_api never ran
|
# covers silent()'s direct `exit $rc`, which bypasses the ERR trap)
|
||||||
# * Reports final status to prevent records stuck forever
|
# - HOST: catches executions that never sent a final status:
|
||||||
# - Best-effort log collection for failed installs
|
# * non-zero exit → "failed" (signal codes map to "aborted")
|
||||||
# - Stops orphaned container processes on failure
|
# * zero exit with an "installing" record but no final → "aborted"
|
||||||
# - Cleans up lock files
|
# (e.g. user cancelled a whiptail dialog, script exited cleanly)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
on_exit() {
|
on_exit() {
|
||||||
local exit_code=$?
|
local exit_code=$?
|
||||||
|
|
||||||
# Report orphaned telemetry records
|
if _is_container_context; then
|
||||||
# Two scenarios handled:
|
|
||||||
# 1. POST_TO_API_DONE=true but POST_UPDATE_DONE=false: Record was created but
|
|
||||||
# never got a final status update → send abort/done now.
|
|
||||||
# 2. POST_TO_API_DONE=false but DIAGNOSTICS=yes: Initial post failed (server
|
|
||||||
# unreachable/timeout), but the server has fallback create-on-update logic,
|
|
||||||
# so a status update can still create the record. Worth one last try.
|
|
||||||
if [[ "${POST_UPDATE_DONE:-}" != "true" ]]; then
|
|
||||||
if [[ "${POST_TO_API_DONE:-}" == "true" || "${DIAGNOSTICS:-no}" == "yes" ]]; then
|
|
||||||
if [[ $exit_code -ne 0 ]]; then
|
if [[ $exit_code -ne 0 ]]; then
|
||||||
_send_abort_telemetry "$exit_code"
|
_container_write_failure "$exit_code" "${FAILED_COMMAND:-}" "${FAILED_LINE:-}"
|
||||||
elif [[ "${INSTALL_COMPLETE:-}" == "true" ]] && declare -f post_update_to_api >/dev/null 2>&1; then
|
|
||||||
# Only report success if the install was explicitly marked complete.
|
|
||||||
# Without this guard, early bailouts (e.g. user cancelled) with exit 0
|
|
||||||
# would be falsely reported as successful installations.
|
|
||||||
post_update_to_api "done" "0" 2>/dev/null || true
|
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
if [[ "${POST_UPDATE_DONE:-}" != "true" ]] && declare -f post_update_to_api >/dev/null 2>&1; then
|
||||||
|
if [[ $exit_code -ne 0 ]]; then
|
||||||
|
post_update_to_api "failed" "$exit_code" 2>/dev/null || true
|
||||||
|
elif [[ "${POST_TO_API_DONE:-}" == "true" ]]; then
|
||||||
|
# Clean exit but no success was ever reported: the user backed out
|
||||||
|
# somewhere. Report as aborted so the record doesn't stay "installing".
|
||||||
|
post_update_to_api "aborted" "0" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Best-effort log collection on failure (non-critical, telemetry already sent)
|
# Best-effort log collection on failure
|
||||||
if [[ $exit_code -ne 0 ]] && declare -f ensure_log_on_host >/dev/null 2>&1; then
|
if [[ $exit_code -ne 0 ]] && declare -f ensure_log_on_host >/dev/null 2>&1; then
|
||||||
ensure_log_on_host 2>/dev/null || true
|
ensure_log_on_host 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Stop orphaned container if we're in the install phase and exiting with error
|
# Stop orphaned container if we're in the install phase
|
||||||
if [[ $exit_code -ne 0 ]]; then
|
if [[ $exit_code -ne 0 ]]; then
|
||||||
_stop_container_if_installing
|
_stop_container_if_installing
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
[[ -n "${lockfile:-}" && -e "$lockfile" ]] && rm -f "$lockfile"
|
[[ -n "${lockfile:-}" && -e "$lockfile" ]] && rm -f "$lockfile"
|
||||||
exit "$exit_code"
|
exit "$exit_code"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# on_interrupt()
|
# on_interrupt() - SIGINT (Ctrl+C)
|
||||||
#
|
|
||||||
# - SIGINT (Ctrl+C) trap handler
|
|
||||||
# - Reports status FIRST (time-critical: container may be dying)
|
|
||||||
# - Stops orphaned container to prevent "configuring" ghost records
|
|
||||||
# - Exits with code 130 (128 + SIGINT=2)
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
on_interrupt() {
|
on_interrupt() {
|
||||||
# Stop spinner and restore cursor before any output
|
|
||||||
if declare -f stop_spinner >/dev/null 2>&1; then
|
if declare -f stop_spinner >/dev/null 2>&1; then
|
||||||
stop_spinner 2>/dev/null || true
|
stop_spinner 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
printf "\e[?25h" 2>/dev/null || true
|
printf "\e[?25h" 2>/dev/null || true
|
||||||
|
|
||||||
_send_abort_telemetry "130"
|
if _is_container_context; then
|
||||||
|
_container_write_failure "130"
|
||||||
|
elif declare -f post_update_to_api &>/dev/null; then
|
||||||
|
post_update_to_api "aborted" "130" 2>/dev/null || true
|
||||||
|
fi
|
||||||
_stop_container_if_installing
|
_stop_container_if_installing
|
||||||
if declare -f msg_error >/dev/null 2>&1; then
|
if declare -f msg_error >/dev/null 2>&1; then
|
||||||
msg_error "Interrupted by user (SIGINT)" 2>/dev/null || true
|
msg_error "Interrupted by user (SIGINT)" 2>/dev/null || true
|
||||||
@@ -675,21 +650,19 @@ on_interrupt() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# on_terminate()
|
# on_terminate() - SIGTERM
|
||||||
#
|
|
||||||
# - SIGTERM trap handler
|
|
||||||
# - Reports status FIRST (time-critical: process being killed)
|
|
||||||
# - Stops orphaned container to prevent "configuring" ghost records
|
|
||||||
# - Exits with code 143 (128 + SIGTERM=15)
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
on_terminate() {
|
on_terminate() {
|
||||||
# Stop spinner and restore cursor before any output
|
|
||||||
if declare -f stop_spinner >/dev/null 2>&1; then
|
if declare -f stop_spinner >/dev/null 2>&1; then
|
||||||
stop_spinner 2>/dev/null || true
|
stop_spinner 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
printf "\e[?25h" 2>/dev/null || true
|
printf "\e[?25h" 2>/dev/null || true
|
||||||
|
|
||||||
_send_abort_telemetry "143"
|
if _is_container_context; then
|
||||||
|
_container_write_failure "143"
|
||||||
|
elif declare -f post_update_to_api &>/dev/null; then
|
||||||
|
post_update_to_api "aborted" "143" 2>/dev/null || true
|
||||||
|
fi
|
||||||
_stop_container_if_installing
|
_stop_container_if_installing
|
||||||
if declare -f msg_error >/dev/null 2>&1; then
|
if declare -f msg_error >/dev/null 2>&1; then
|
||||||
msg_error "Terminated by signal (SIGTERM)" 2>/dev/null || true
|
msg_error "Terminated by signal (SIGTERM)" 2>/dev/null || true
|
||||||
@@ -700,45 +673,32 @@ on_terminate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# on_hangup()
|
# on_hangup() - SIGHUP (SSH disconnect, terminal closed)
|
||||||
#
|
|
||||||
# - SIGHUP trap handler (SSH disconnect, terminal closed)
|
|
||||||
# - CRITICAL: This was previously MISSING from catch_errors(), causing
|
|
||||||
# container processes to become orphans on SSH disconnect — the #1 cause
|
|
||||||
# of records stuck in "installing" and "configuring" states
|
|
||||||
# - Reports status via direct curl (terminal is already closed, no output)
|
|
||||||
# - Stops orphaned container to prevent ghost records
|
|
||||||
# - Exits with code 129 (128 + SIGHUP=1)
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
on_hangup() {
|
on_hangup() {
|
||||||
# Stop spinner (no cursor restore needed — terminal is already gone)
|
|
||||||
if declare -f stop_spinner >/dev/null 2>&1; then
|
if declare -f stop_spinner >/dev/null 2>&1; then
|
||||||
stop_spinner 2>/dev/null || true
|
stop_spinner 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_send_abort_telemetry "129"
|
if _is_container_context; then
|
||||||
|
_container_write_failure "129"
|
||||||
|
elif declare -f post_update_to_api &>/dev/null; then
|
||||||
|
post_update_to_api "aborted" "129" 2>/dev/null || true
|
||||||
|
fi
|
||||||
_stop_container_if_installing
|
_stop_container_if_installing
|
||||||
exit 129
|
exit 129
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 5: INITIALIZATION
|
# SECTION 6: INITIALIZATION
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# catch_errors()
|
# catch_errors()
|
||||||
#
|
#
|
||||||
# - Initializes error handling and signal traps
|
# - Initializes error handling and signal traps
|
||||||
# - Enables strict error handling:
|
# - set -Ee -o pipefail (+ set -u when STRICT_UNSET=1)
|
||||||
# * set -Ee: Exit on error, inherit ERR trap in functions
|
# - Traps: ERR → error_handler, EXIT → on_exit, INT/TERM/HUP → signal handlers
|
||||||
# * set -o pipefail: Pipeline fails if any command fails
|
|
||||||
# * set -u: (optional) Exit on undefined variable (if STRICT_UNSET=1)
|
|
||||||
# - Sets up traps:
|
|
||||||
# * ERR → error_handler (script errors)
|
|
||||||
# * EXIT → on_exit (any termination — cleanup + orphan detection)
|
|
||||||
# * INT → on_interrupt (Ctrl+C)
|
|
||||||
# * TERM → on_terminate (kill / systemd stop)
|
|
||||||
# * HUP → on_hangup (SSH disconnect / terminal closed)
|
|
||||||
# - Call this function early in every script
|
# - Call this function early in every script
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
catch_errors() {
|
catch_errors() {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user