mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-02-22 04:55:55 +01:00
Compare commits
2 Commits
fix-opnsen
...
fix/archli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ba93e85eea | ||
|
|
663bb828d0 |
216
.github/changelogs/2026/02.md
generated
vendored
216
.github/changelogs/2026/02.md
generated
vendored
@@ -1,219 +1,3 @@
|
|||||||
## 2026-02-14
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Increase disk allocation for OpenWebUI and Ollama to prevent installation failures [@Copilot](https://github.com/Copilot) ([#11920](https://github.com/community-scripts/ProxmoxVE/pull/11920))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- core: handle missing RAM speed in nested VMs [@MickLesk](https://github.com/MickLesk) ([#11913](https://github.com/community-scripts/ProxmoxVE/pull/11913))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- core: overwriteable app version [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11753](https://github.com/community-scripts/ProxmoxVE/pull/11753))
|
|
||||||
- core: validate container IDs cluster-wide across all nodes [@MickLesk](https://github.com/MickLesk) ([#11906](https://github.com/community-scripts/ProxmoxVE/pull/11906))
|
|
||||||
- core: improve error reporting with structured error strings and better categorization + output formatting [@MickLesk](https://github.com/MickLesk) ([#11907](https://github.com/community-scripts/ProxmoxVE/pull/11907))
|
|
||||||
- core: unified logging system with combined logs [@MickLesk](https://github.com/MickLesk) ([#11761](https://github.com/community-scripts/ProxmoxVE/pull/11761))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- lxc-updater: add patchmon aware [@failure101](https://github.com/failure101) ([#11905](https://github.com/community-scripts/ProxmoxVE/pull/11905))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### 📝 Script Information
|
|
||||||
|
|
||||||
- Disable UniFi script - APT packages no longer available [@Copilot](https://github.com/Copilot) ([#11898](https://github.com/community-scripts/ProxmoxVE/pull/11898))
|
|
||||||
|
|
||||||
## 2026-02-13
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- OpenWebUI: pin numba constraint [@MickLesk](https://github.com/MickLesk) ([#11874](https://github.com/community-scripts/ProxmoxVE/pull/11874))
|
|
||||||
- Planka: add migrate step to update function [@ZimmermannLeon](https://github.com/ZimmermannLeon) ([#11877](https://github.com/community-scripts/ProxmoxVE/pull/11877))
|
|
||||||
- Pangolin: switch sqlite-specific back to generic [@MickLesk](https://github.com/MickLesk) ([#11868](https://github.com/community-scripts/ProxmoxVE/pull/11868))
|
|
||||||
- [Hotfix] Jotty: Copy contents of config backup into /opt/jotty/config [@vhsdream](https://github.com/vhsdream) ([#11864](https://github.com/community-scripts/ProxmoxVE/pull/11864))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Refactor: Radicale [@vhsdream](https://github.com/vhsdream) ([#11850](https://github.com/community-scripts/ProxmoxVE/pull/11850))
|
|
||||||
- chore(donetick): add config entry for v0.1.73 [@tomfrenzel](https://github.com/tomfrenzel) ([#11872](https://github.com/community-scripts/ProxmoxVE/pull/11872))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- core: retry reporting with fallback payloads [@MickLesk](https://github.com/MickLesk) ([#11885](https://github.com/community-scripts/ProxmoxVE/pull/11885))
|
|
||||||
|
|
||||||
### 📡 API
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- error-handler: Implement json_escape and enhance error handling [@MickLesk](https://github.com/MickLesk) ([#11875](https://github.com/community-scripts/ProxmoxVE/pull/11875))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### 📝 Script Information
|
|
||||||
|
|
||||||
- SQLServer-2025: add PVE9/Kernel 6.x incompatibility warning [@MickLesk](https://github.com/MickLesk) ([#11829](https://github.com/community-scripts/ProxmoxVE/pull/11829))
|
|
||||||
|
|
||||||
## 2026-02-12
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- EMQX: increase disk to 6GB and add optional MQ disable prompt [@MickLesk](https://github.com/MickLesk) ([#11844](https://github.com/community-scripts/ProxmoxVE/pull/11844))
|
|
||||||
- Increased the Grafana container default disk size. [@shtefko](https://github.com/shtefko) ([#11840](https://github.com/community-scripts/ProxmoxVE/pull/11840))
|
|
||||||
- Pangolin: Update database generation command in install script [@tremor021](https://github.com/tremor021) ([#11825](https://github.com/community-scripts/ProxmoxVE/pull/11825))
|
|
||||||
- Deluge: add python3-setuptools as dep [@MickLesk](https://github.com/MickLesk) ([#11833](https://github.com/community-scripts/ProxmoxVE/pull/11833))
|
|
||||||
- Dispatcharr: migrate to uv sync [@MickLesk](https://github.com/MickLesk) ([#11831](https://github.com/community-scripts/ProxmoxVE/pull/11831))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- Archlinux-VM: fix LVM/LVM-thin storage and improve error reporting | VM's add correct exit_code for analytics [@MickLesk](https://github.com/MickLesk) ([#11842](https://github.com/community-scripts/ProxmoxVE/pull/11842))
|
|
||||||
- Debian13-VM: Optimize First Boot & add noCloud/Cloud Selection [@MickLesk](https://github.com/MickLesk) ([#11810](https://github.com/community-scripts/ProxmoxVE/pull/11810))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- tools.func: auto-detect binary vs armored GPG keys in setup_deb822_repo [@MickLesk](https://github.com/MickLesk) ([#11841](https://github.com/community-scripts/ProxmoxVE/pull/11841))
|
|
||||||
- core: remove old Go API and extend misc/api.func with new backend [@MickLesk](https://github.com/MickLesk) ([#11822](https://github.com/community-scripts/ProxmoxVE/pull/11822))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- error_handler: prevent stuck 'installing' status [@MickLesk](https://github.com/MickLesk) ([#11845](https://github.com/community-scripts/ProxmoxVE/pull/11845))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Tailscale: fix DNS check and keyrings directory issues [@MickLesk](https://github.com/MickLesk) ([#11837](https://github.com/community-scripts/ProxmoxVE/pull/11837))
|
|
||||||
|
|
||||||
## 2026-02-11
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Draw.io ([#11788](https://github.com/community-scripts/ProxmoxVE/pull/11788))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- dispatcharr: include port 9191 in success-message [@MickLesk](https://github.com/MickLesk) ([#11808](https://github.com/community-scripts/ProxmoxVE/pull/11808))
|
|
||||||
- fix: make donetick 0.1.71 compatible [@tomfrenzel](https://github.com/tomfrenzel) ([#11804](https://github.com/community-scripts/ProxmoxVE/pull/11804))
|
|
||||||
- Kasm: Support new version URL format without hash suffix [@MickLesk](https://github.com/MickLesk) ([#11787](https://github.com/community-scripts/ProxmoxVE/pull/11787))
|
|
||||||
- LibreTranslate: Remove Torch [@tremor021](https://github.com/tremor021) ([#11783](https://github.com/community-scripts/ProxmoxVE/pull/11783))
|
|
||||||
- Snowshare: fix update script [@TuroYT](https://github.com/TuroYT) ([#11726](https://github.com/community-scripts/ProxmoxVE/pull/11726))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- [Feature] OpenCloud: support PosixFS Collaborative Mode [@vhsdream](https://github.com/vhsdream) ([#11806](https://github.com/community-scripts/ProxmoxVE/pull/11806))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- core: respect EDITOR variable for config editing [@ls-root](https://github.com/ls-root) ([#11693](https://github.com/community-scripts/ProxmoxVE/pull/11693))
|
|
||||||
|
|
||||||
### 📚 Documentation
|
|
||||||
|
|
||||||
- Fix formatting in kutt.json notes section [@tiagodenoronha](https://github.com/tiagodenoronha) ([#11774](https://github.com/community-scripts/ProxmoxVE/pull/11774))
|
|
||||||
|
|
||||||
## 2026-02-10
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Immich: Pin version to 2.5.6 [@vhsdream](https://github.com/vhsdream) ([#11775](https://github.com/community-scripts/ProxmoxVE/pull/11775))
|
|
||||||
- Libretranslate: Fix setuptools [@tremor021](https://github.com/tremor021) ([#11772](https://github.com/community-scripts/ProxmoxVE/pull/11772))
|
|
||||||
- Element Synapse: prevent systemd invoke failure during apt install [@MickLesk](https://github.com/MickLesk) ([#11758](https://github.com/community-scripts/ProxmoxVE/pull/11758))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- Refactor: Slskd & Soularr [@vhsdream](https://github.com/vhsdream) ([#11674](https://github.com/community-scripts/ProxmoxVE/pull/11674))
|
|
||||||
|
|
||||||
### 🗑️ Deleted Scripts
|
|
||||||
|
|
||||||
- move paperless-exporter from LXC to addon ([#11737](https://github.com/community-scripts/ProxmoxVE/pull/11737))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- feat: improve storage parsing & add guestname [@carlosmaroot](https://github.com/carlosmaroot) ([#11752](https://github.com/community-scripts/ProxmoxVE/pull/11752))
|
|
||||||
|
|
||||||
### 📂 Github
|
|
||||||
|
|
||||||
- Github-Version Workflow: include addon scripts in extraction [@MickLesk](https://github.com/MickLesk) ([#11757](https://github.com/community-scripts/ProxmoxVE/pull/11757))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### 📝 Script Information
|
|
||||||
|
|
||||||
- Snowshare: fix typo in config file path on website [@BirdMakingStuff](https://github.com/BirdMakingStuff) ([#11754](https://github.com/community-scripts/ProxmoxVE/pull/11754))
|
|
||||||
|
|
||||||
## 2026-02-09
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- several scripts: add --clear to uv venv calls for uv 0.10 compatibility [@MickLesk](https://github.com/MickLesk) ([#11723](https://github.com/community-scripts/ProxmoxVE/pull/11723))
|
|
||||||
- Koillection: ensure setup_composer is in update script [@MickLesk](https://github.com/MickLesk) ([#11734](https://github.com/community-scripts/ProxmoxVE/pull/11734))
|
|
||||||
- PeaNUT: symlink server.js after update [@vhsdream](https://github.com/vhsdream) ([#11696](https://github.com/community-scripts/ProxmoxVE/pull/11696))
|
|
||||||
- Umlautadaptarr: use release appsettings.json instead of hardcoded copy [@MickLesk](https://github.com/MickLesk) ([#11725](https://github.com/community-scripts/ProxmoxVE/pull/11725))
|
|
||||||
- tracearr: prepare for next stable release [@durzo](https://github.com/durzo) ([#11673](https://github.com/community-scripts/ProxmoxVE/pull/11673))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- remove whiptail from update scripts for unattended update support [@MickLesk](https://github.com/MickLesk) ([#11712](https://github.com/community-scripts/ProxmoxVE/pull/11712))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Refactor: FileFlows [@tremor021](https://github.com/tremor021) ([#11108](https://github.com/community-scripts/ProxmoxVE/pull/11108))
|
|
||||||
- Refactor: wger [@MickLesk](https://github.com/MickLesk) ([#11722](https://github.com/community-scripts/ProxmoxVE/pull/11722))
|
|
||||||
- Nginx-UI: better User Handling | ACME [@MickLesk](https://github.com/MickLesk) ([#11715](https://github.com/community-scripts/ProxmoxVE/pull/11715))
|
|
||||||
- NginxProxymanager: use better-sqlite3 [@MickLesk](https://github.com/MickLesk) ([#11708](https://github.com/community-scripts/ProxmoxVE/pull/11708))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- hwaccel: add libmfx-gen1.2 to Intel Arc setup for QSV support [@MickLesk](https://github.com/MickLesk) ([#11707](https://github.com/community-scripts/ProxmoxVE/pull/11707))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- addons: ensure curl is installed before use [@MickLesk](https://github.com/MickLesk) ([#11718](https://github.com/community-scripts/ProxmoxVE/pull/11718))
|
|
||||||
- Netbird (addon): add systemd ordering to start after Docker [@MickLesk](https://github.com/MickLesk) ([#11716](https://github.com/community-scripts/ProxmoxVE/pull/11716))
|
|
||||||
|
|
||||||
### ❔ Uncategorized
|
|
||||||
|
|
||||||
- Bichon: Update website [@tremor021](https://github.com/tremor021) ([#11711](https://github.com/community-scripts/ProxmoxVE/pull/11711))
|
|
||||||
|
|
||||||
## 2026-02-08
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- feat(healthchecks): add sendalerts service [@Mika56](https://github.com/Mika56) ([#11694](https://github.com/community-scripts/ProxmoxVE/pull/11694))
|
|
||||||
- ComfyUI: Dynamic Fetch PyTorch Versions [@MickLesk](https://github.com/MickLesk) ([#11657](https://github.com/community-scripts/ProxmoxVE/pull/11657))
|
|
||||||
|
|
||||||
- #### 💥 Breaking Changes
|
|
||||||
|
|
||||||
- Semaphore: switch from Debian to Ubuntu 24.04 [@MickLesk](https://github.com/MickLesk) ([#11670](https://github.com/community-scripts/ProxmoxVE/pull/11670))
|
|
||||||
|
|
||||||
## 2026-02-07
|
## 2026-02-07
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
|
|||||||
3
.github/workflows/autolabeler.yml
generated
vendored
3
.github/workflows/autolabeler.yml
generated
vendored
@@ -100,8 +100,7 @@ jobs:
|
|||||||
// If it's an update script PR with json changes and a content label, skip adding website/json
|
// If it's an update script PR with json changes and a content label, skip adding website/json
|
||||||
// The PR should be categorized as update script with the content label
|
// The PR should be categorized as update script with the content label
|
||||||
if (!(hasUpdateScript && hasJson && hasContentLabel)) {
|
if (!(hasUpdateScript && hasJson && hasContentLabel)) {
|
||||||
labelsToAdd.add("website");
|
labelsToAdd.add(hasJson ? "json" : "website");
|
||||||
if (hasJson) labelsToAdd.add("json");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
350
CHANGELOG.md
350
CHANGELOG.md
@@ -15,9 +15,6 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h2>📜 History</h2></summary>
|
<summary><h2>📜 History</h2></summary>
|
||||||
|
|
||||||
@@ -27,7 +24,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h4>February (14 entries)</h4></summary>
|
<summary><h4>February (7 entries)</h4></summary>
|
||||||
|
|
||||||
[View February 2026 Changelog](.github/changelogs/2026/02.md)
|
[View February 2026 Changelog](.github/changelogs/2026/02.md)
|
||||||
|
|
||||||
@@ -404,209 +401,26 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## 2026-02-18
|
|
||||||
|
|
||||||
## 2026-02-17
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Databasus ([#12018](https://github.com/community-scripts/ProxmoxVE/pull/12018))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- [Hotfix] Cleanuparr: backup config before update [@vhsdream](https://github.com/vhsdream) ([#12039](https://github.com/community-scripts/ProxmoxVE/pull/12039))
|
|
||||||
- fix: pterodactyl-panel add symlink [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11997](https://github.com/community-scripts/ProxmoxVE/pull/11997))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- core: call get_lxc_ip in start() before updates [@MickLesk](https://github.com/MickLesk) ([#12015](https://github.com/community-scripts/ProxmoxVE/pull/12015))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- tools/pve: add data analytics / formatting / linting [@MickLesk](https://github.com/MickLesk) ([#12034](https://github.com/community-scripts/ProxmoxVE/pull/12034))
|
|
||||||
- core: smart recovery for failed installs | extend exit_codes [@MickLesk](https://github.com/MickLesk) ([#11221](https://github.com/community-scripts/ProxmoxVE/pull/11221))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- core: error-handler improvements | better exit_code handling | better tools.func source check [@MickLesk](https://github.com/MickLesk) ([#12019](https://github.com/community-scripts/ProxmoxVE/pull/12019))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Immich Public Proxy: centralize and fix systemd service creation [@MickLesk](https://github.com/MickLesk) ([#12025](https://github.com/community-scripts/ProxmoxVE/pull/12025))
|
|
||||||
|
|
||||||
### 📚 Documentation
|
|
||||||
|
|
||||||
- fix contribution/setup-fork [@andreasabeck](https://github.com/andreasabeck) ([#12047](https://github.com/community-scripts/ProxmoxVE/pull/12047))
|
|
||||||
|
|
||||||
## 2026-02-16
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- RomM ([#11987](https://github.com/community-scripts/ProxmoxVE/pull/11987))
|
|
||||||
- LinkDing ([#11976](https://github.com/community-scripts/ProxmoxVE/pull/11976))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- Opencloud: Pin version to 5.1.0 [@vhsdream](https://github.com/vhsdream) ([#12004](https://github.com/community-scripts/ProxmoxVE/pull/12004))
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Tududi: Fix sed command for DB_FILE configuration [@tremor021](https://github.com/tremor021) ([#11988](https://github.com/community-scripts/ProxmoxVE/pull/11988))
|
|
||||||
- slskd: fix exit position [@MickLesk](https://github.com/MickLesk) ([#11963](https://github.com/community-scripts/ProxmoxVE/pull/11963))
|
|
||||||
- cryptpad: restore config earlier and run onlyoffice upgrade [@MickLesk](https://github.com/MickLesk) ([#11964](https://github.com/community-scripts/ProxmoxVE/pull/11964))
|
|
||||||
- jellyseerr/overseerr: Migrate update script to Seerr; prompt rerun [@MickLesk](https://github.com/MickLesk) ([#11965](https://github.com/community-scripts/ProxmoxVE/pull/11965))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- core/vm's: ensure script state is sent on script exit [@MickLesk](https://github.com/MickLesk) ([#11991](https://github.com/community-scripts/ProxmoxVE/pull/11991))
|
|
||||||
- Vaultwarden: export VW_VERSION as version number [@MickLesk](https://github.com/MickLesk) ([#11966](https://github.com/community-scripts/ProxmoxVE/pull/11966))
|
|
||||||
- Zabbix: Improve zabbix-agent service detection [@MickLesk](https://github.com/MickLesk) ([#11968](https://github.com/community-scripts/ProxmoxVE/pull/11968))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- tools.func: ensure /usr/local/bin PATH persists for pct enter sessions [@MickLesk](https://github.com/MickLesk) ([#11970](https://github.com/community-scripts/ProxmoxVE/pull/11970))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- core: remove duplicate error handler from alpine-install.func [@MickLesk](https://github.com/MickLesk) ([#11971](https://github.com/community-scripts/ProxmoxVE/pull/11971))
|
|
||||||
|
|
||||||
### 📂 Github
|
|
||||||
|
|
||||||
- github: add "website" label if "json" changed [@MickLesk](https://github.com/MickLesk) ([#11975](https://github.com/community-scripts/ProxmoxVE/pull/11975))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### 📝 Script Information
|
|
||||||
|
|
||||||
- Update Wishlist LXC webpage to include reverse proxy info [@summoningpixels](https://github.com/summoningpixels) ([#11973](https://github.com/community-scripts/ProxmoxVE/pull/11973))
|
|
||||||
- Update OpenCloud LXC webpage to include services ports [@summoningpixels](https://github.com/summoningpixels) ([#11969](https://github.com/community-scripts/ProxmoxVE/pull/11969))
|
|
||||||
|
|
||||||
## 2026-02-15
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- ebusd ([#11942](https://github.com/community-scripts/ProxmoxVE/pull/11942))
|
|
||||||
- add: seer script and migrations [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11930](https://github.com/community-scripts/ProxmoxVE/pull/11930))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Fix seerr URL in jellyseerr script [@lucacome](https://github.com/lucacome) ([#11951](https://github.com/community-scripts/ProxmoxVE/pull/11951))
|
|
||||||
- Fix jellyseer and overseer script replacement [@lucacome](https://github.com/lucacome) ([#11949](https://github.com/community-scripts/ProxmoxVE/pull/11949))
|
|
||||||
- Tautulli: Add setuptools < 81 [@tremor021](https://github.com/tremor021) ([#11943](https://github.com/community-scripts/ProxmoxVE/pull/11943))
|
|
||||||
|
|
||||||
- #### 💥 Breaking Changes
|
|
||||||
|
|
||||||
- Refactor: Patchmon [@vhsdream](https://github.com/vhsdream) ([#11888](https://github.com/community-scripts/ProxmoxVE/pull/11888))
|
|
||||||
|
|
||||||
## 2026-02-14
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Increase disk allocation for OpenWebUI and Ollama to prevent installation failures [@Copilot](https://github.com/Copilot) ([#11920](https://github.com/community-scripts/ProxmoxVE/pull/11920))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- core: handle missing RAM speed in nested VMs [@MickLesk](https://github.com/MickLesk) ([#11913](https://github.com/community-scripts/ProxmoxVE/pull/11913))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- core: overwriteable app version [@CrazyWolf13](https://github.com/CrazyWolf13) ([#11753](https://github.com/community-scripts/ProxmoxVE/pull/11753))
|
|
||||||
- core: validate container IDs cluster-wide across all nodes [@MickLesk](https://github.com/MickLesk) ([#11906](https://github.com/community-scripts/ProxmoxVE/pull/11906))
|
|
||||||
- core: improve error reporting with structured error strings and better categorization + output formatting [@MickLesk](https://github.com/MickLesk) ([#11907](https://github.com/community-scripts/ProxmoxVE/pull/11907))
|
|
||||||
- core: unified logging system with combined logs [@MickLesk](https://github.com/MickLesk) ([#11761](https://github.com/community-scripts/ProxmoxVE/pull/11761))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- lxc-updater: add patchmon aware [@failure101](https://github.com/failure101) ([#11905](https://github.com/community-scripts/ProxmoxVE/pull/11905))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### 📝 Script Information
|
|
||||||
|
|
||||||
- Disable UniFi script - APT packages no longer available [@Copilot](https://github.com/Copilot) ([#11898](https://github.com/community-scripts/ProxmoxVE/pull/11898))
|
|
||||||
|
|
||||||
## 2026-02-13
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- OpenWebUI: pin numba constraint [@MickLesk](https://github.com/MickLesk) ([#11874](https://github.com/community-scripts/ProxmoxVE/pull/11874))
|
|
||||||
- Planka: add migrate step to update function [@ZimmermannLeon](https://github.com/ZimmermannLeon) ([#11877](https://github.com/community-scripts/ProxmoxVE/pull/11877))
|
|
||||||
- Pangolin: switch sqlite-specific back to generic [@MickLesk](https://github.com/MickLesk) ([#11868](https://github.com/community-scripts/ProxmoxVE/pull/11868))
|
|
||||||
- [Hotfix] Jotty: Copy contents of config backup into /opt/jotty/config [@vhsdream](https://github.com/vhsdream) ([#11864](https://github.com/community-scripts/ProxmoxVE/pull/11864))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- Refactor: Radicale [@vhsdream](https://github.com/vhsdream) ([#11850](https://github.com/community-scripts/ProxmoxVE/pull/11850))
|
|
||||||
- chore(donetick): add config entry for v0.1.73 [@tomfrenzel](https://github.com/tomfrenzel) ([#11872](https://github.com/community-scripts/ProxmoxVE/pull/11872))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- core: retry reporting with fallback payloads [@MickLesk](https://github.com/MickLesk) ([#11885](https://github.com/community-scripts/ProxmoxVE/pull/11885))
|
|
||||||
|
|
||||||
### 📡 API
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- error-handler: Implement json_escape and enhance error handling [@MickLesk](https://github.com/MickLesk) ([#11875](https://github.com/community-scripts/ProxmoxVE/pull/11875))
|
|
||||||
|
|
||||||
### 🌐 Website
|
|
||||||
|
|
||||||
- #### 📝 Script Information
|
|
||||||
|
|
||||||
- SQLServer-2025: add PVE9/Kernel 6.x incompatibility warning [@MickLesk](https://github.com/MickLesk) ([#11829](https://github.com/community-scripts/ProxmoxVE/pull/11829))
|
|
||||||
|
|
||||||
## 2026-02-12
|
## 2026-02-12
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
- EMQX: increase disk to 6GB and add optional MQ disable prompt [@MickLesk](https://github.com/MickLesk) ([#11844](https://github.com/community-scripts/ProxmoxVE/pull/11844))
|
|
||||||
- Increased the Grafana container default disk size. [@shtefko](https://github.com/shtefko) ([#11840](https://github.com/community-scripts/ProxmoxVE/pull/11840))
|
|
||||||
- Pangolin: Update database generation command in install script [@tremor021](https://github.com/tremor021) ([#11825](https://github.com/community-scripts/ProxmoxVE/pull/11825))
|
|
||||||
- Deluge: add python3-setuptools as dep [@MickLesk](https://github.com/MickLesk) ([#11833](https://github.com/community-scripts/ProxmoxVE/pull/11833))
|
- Deluge: add python3-setuptools as dep [@MickLesk](https://github.com/MickLesk) ([#11833](https://github.com/community-scripts/ProxmoxVE/pull/11833))
|
||||||
- Dispatcharr: migrate to uv sync [@MickLesk](https://github.com/MickLesk) ([#11831](https://github.com/community-scripts/ProxmoxVE/pull/11831))
|
- Dispatcharr: migrate to uv sync [@MickLesk](https://github.com/MickLesk) ([#11831](https://github.com/community-scripts/ProxmoxVE/pull/11831))
|
||||||
|
- Pangolin: Update database generation command in install script [@tremor021](https://github.com/tremor021) ([#11825](https://github.com/community-scripts/ProxmoxVE/pull/11825))
|
||||||
|
|
||||||
- #### ✨ New Features
|
- #### ✨ New Features
|
||||||
|
|
||||||
- Archlinux-VM: fix LVM/LVM-thin storage and improve error reporting | VM's add correct exit_code for analytics [@MickLesk](https://github.com/MickLesk) ([#11842](https://github.com/community-scripts/ProxmoxVE/pull/11842))
|
|
||||||
- Debian13-VM: Optimize First Boot & add noCloud/Cloud Selection [@MickLesk](https://github.com/MickLesk) ([#11810](https://github.com/community-scripts/ProxmoxVE/pull/11810))
|
- Debian13-VM: Optimize First Boot & add noCloud/Cloud Selection [@MickLesk](https://github.com/MickLesk) ([#11810](https://github.com/community-scripts/ProxmoxVE/pull/11810))
|
||||||
|
|
||||||
### 💾 Core
|
### 💾 Core
|
||||||
|
|
||||||
- #### ✨ New Features
|
- #### ✨ New Features
|
||||||
|
|
||||||
- tools.func: auto-detect binary vs armored GPG keys in setup_deb822_repo [@MickLesk](https://github.com/MickLesk) ([#11841](https://github.com/community-scripts/ProxmoxVE/pull/11841))
|
|
||||||
- core: remove old Go API and extend misc/api.func with new backend [@MickLesk](https://github.com/MickLesk) ([#11822](https://github.com/community-scripts/ProxmoxVE/pull/11822))
|
- core: remove old Go API and extend misc/api.func with new backend [@MickLesk](https://github.com/MickLesk) ([#11822](https://github.com/community-scripts/ProxmoxVE/pull/11822))
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- error_handler: prevent stuck 'installing' status [@MickLesk](https://github.com/MickLesk) ([#11845](https://github.com/community-scripts/ProxmoxVE/pull/11845))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Tailscale: fix DNS check and keyrings directory issues [@MickLesk](https://github.com/MickLesk) ([#11837](https://github.com/community-scripts/ProxmoxVE/pull/11837))
|
|
||||||
|
|
||||||
## 2026-02-11
|
## 2026-02-11
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
@@ -1459,4 +1273,162 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
### ❔ Uncategorized
|
### ❔ Uncategorized
|
||||||
|
|
||||||
- qui: fix: category [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10847](https://github.com/community-scripts/ProxmoxVE/pull/10847))
|
- qui: fix: category [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10847](https://github.com/community-scripts/ProxmoxVE/pull/10847))
|
||||||
|
|
||||||
|
## 2026-01-15
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Qui ([#10829](https://github.com/community-scripts/ProxmoxVE/pull/10829))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Refactor: FreshRSS + Bump to Debian 13 [@MickLesk](https://github.com/MickLesk) ([#10824](https://github.com/community-scripts/ProxmoxVE/pull/10824))
|
||||||
|
|
||||||
|
## 2026-01-14
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Kutt ([#10812](https://github.com/community-scripts/ProxmoxVE/pull/10812))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Switch Ollama install to .tar.zst and add zstd dependency [@MickLesk](https://github.com/MickLesk) ([#10814](https://github.com/community-scripts/ProxmoxVE/pull/10814))
|
||||||
|
- Immich: Install libde265-dev from Debian Testing [@vhsdream](https://github.com/vhsdream) ([#10810](https://github.com/community-scripts/ProxmoxVE/pull/10810))
|
||||||
|
- nginxproxymanager: allow updates now the build is fixed [@durzo](https://github.com/durzo) ([#10796](https://github.com/community-scripts/ProxmoxVE/pull/10796))
|
||||||
|
- Fixed Apache Guacamole installer [@horvatbenjamin](https://github.com/horvatbenjamin) ([#10798](https://github.com/community-scripts/ProxmoxVE/pull/10798))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- core: Improve NVIDIA GPU setup (5000x Series) [@MickLesk](https://github.com/MickLesk) ([#10807](https://github.com/community-scripts/ProxmoxVE/pull/10807))
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- Fix whiptail dialog hanging in Proxmox web console [@comk22](https://github.com/comk22) ([#10794](https://github.com/community-scripts/ProxmoxVE/pull/10794))
|
||||||
|
|
||||||
|
### 🌐 Website
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Add search filtering to CommandDialog for improved script search functionality [@BramSuurdje](https://github.com/BramSuurdje) ([#10800](https://github.com/community-scripts/ProxmoxVE/pull/10800))
|
||||||
|
|
||||||
|
## 2026-01-13
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Investbrain ([#10774](https://github.com/community-scripts/ProxmoxVE/pull/10774))
|
||||||
|
- Fladder ([#10768](https://github.com/community-scripts/ProxmoxVE/pull/10768))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Immich: Fix Intel version check; install legacy Intel packages during new install [@vhsdream](https://github.com/vhsdream) ([#10787](https://github.com/community-scripts/ProxmoxVE/pull/10787))
|
||||||
|
- Openwrt: Remove default VLAN for LAN [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#10782](https://github.com/community-scripts/ProxmoxVE/pull/10782))
|
||||||
|
- Refactor: Joplin Server [@tremor021](https://github.com/tremor021) ([#10769](https://github.com/community-scripts/ProxmoxVE/pull/10769))
|
||||||
|
- Fix Zammad nginx configuration causing installation failure [@Copilot](https://github.com/Copilot) ([#10757](https://github.com/community-scripts/ProxmoxVE/pull/10757))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Backrest: Bump to Trixie [@tremor021](https://github.com/tremor021) ([#10758](https://github.com/community-scripts/ProxmoxVE/pull/10758))
|
||||||
|
- Refactor: Caddy [@tremor021](https://github.com/tremor021) ([#10759](https://github.com/community-scripts/ProxmoxVE/pull/10759))
|
||||||
|
- Refactor: Leantime [@tremor021](https://github.com/tremor021) ([#10760](https://github.com/community-scripts/ProxmoxVE/pull/10760))
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- update_lxcs.sh: Add the option to skip stopped LXC [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#10783](https://github.com/community-scripts/ProxmoxVE/pull/10783))
|
||||||
|
|
||||||
|
## 2026-01-12
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Jellystat ([#10628](https://github.com/community-scripts/ProxmoxVE/pull/10628))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- InfluxSB: fix If / fi [@chrnie](https://github.com/chrnie) ([#10753](https://github.com/community-scripts/ProxmoxVE/pull/10753))
|
||||||
|
- Cockpit: Downgrade to Debian 12 Bookworm (45Drives Issue) [@MickLesk](https://github.com/MickLesk) ([#10717](https://github.com/community-scripts/ProxmoxVE/pull/10717))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- InfluxDB: add setup for influxdb v3 [@victorlap](https://github.com/victorlap) ([#10736](https://github.com/community-scripts/ProxmoxVE/pull/10736))
|
||||||
|
- Apache Guacamole: add schema upgrades and extension updates [@MickLesk](https://github.com/MickLesk) ([#10746](https://github.com/community-scripts/ProxmoxVE/pull/10746))
|
||||||
|
- Apache Tomcat: update support and refactor install script + debian 13 [@MickLesk](https://github.com/MickLesk) ([#10739](https://github.com/community-scripts/ProxmoxVE/pull/10739))
|
||||||
|
- Apache Guacamole: Function Bump + update_script [@MickLesk](https://github.com/MickLesk) ([#10728](https://github.com/community-scripts/ProxmoxVE/pull/10728))
|
||||||
|
- Apache CouchDB: bump to debian 13 and add update support [@MickLesk](https://github.com/MickLesk) ([#10721](https://github.com/community-scripts/ProxmoxVE/pull/10721))
|
||||||
|
- Apache Cassandra: bump to debian 13 and add update support [@MickLesk](https://github.com/MickLesk) ([#10720](https://github.com/community-scripts/ProxmoxVE/pull/10720))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Refactor: Booklore [@MickLesk](https://github.com/MickLesk) ([#10742](https://github.com/community-scripts/ProxmoxVE/pull/10742))
|
||||||
|
- Bump Argus to Debian 13 [@MickLesk](https://github.com/MickLesk) ([#10718](https://github.com/community-scripts/ProxmoxVE/pull/10718))
|
||||||
|
- Refactor Docker/Dockge & Bump to Debian 13 [@MickLesk](https://github.com/MickLesk) ([#10719](https://github.com/community-scripts/ProxmoxVE/pull/10719))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- core: remove duplicated pve_version in advanced installs [@MickLesk](https://github.com/MickLesk) ([#10743](https://github.com/community-scripts/ProxmoxVE/pull/10743))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- core: add storage validation & fix GB/MB display [@MickLesk](https://github.com/MickLesk) ([#10745](https://github.com/community-scripts/ProxmoxVE/pull/10745))
|
||||||
|
- core: validate container ID before pct create to prevent failures [@MickLesk](https://github.com/MickLesk) ([#10729](https://github.com/community-scripts/ProxmoxVE/pull/10729))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Enforce non-interactive apt mode in DB setup scripts [@MickLesk](https://github.com/MickLesk) ([#10714](https://github.com/community-scripts/ProxmoxVE/pull/10714))
|
||||||
|
|
||||||
|
## 2026-01-11
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Fix Invoice Ninja Error 500 by restoring file ownership after artisan commands [@Copilot](https://github.com/Copilot) ([#10709](https://github.com/community-scripts/ProxmoxVE/pull/10709))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Refactor: Infisical [@tremor021](https://github.com/tremor021) ([#10693](https://github.com/community-scripts/ProxmoxVE/pull/10693))
|
||||||
|
- Refactor: HortusFox [@tremor021](https://github.com/tremor021) ([#10697](https://github.com/community-scripts/ProxmoxVE/pull/10697))
|
||||||
|
- Refactor: Homer [@tremor021](https://github.com/tremor021) ([#10698](https://github.com/community-scripts/ProxmoxVE/pull/10698))
|
||||||
|
|
||||||
|
## 2026-01-10
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- [Endurain] Increase default RAM from 2048 to 4096 [@FutureCow](https://github.com/FutureCow) ([#10690](https://github.com/community-scripts/ProxmoxVE/pull/10690))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- tools.func: hwaccel - make beignet-opencl-icd optional for legacy Intel GPUs [@MickLesk](https://github.com/MickLesk) ([#10677](https://github.com/community-scripts/ProxmoxVE/pull/10677))
|
||||||
|
|
||||||
|
## 2026-01-09
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Jenkins: Fix application repository setup [@tremor021](https://github.com/tremor021) ([#10671](https://github.com/community-scripts/ProxmoxVE/pull/10671))
|
||||||
|
- deCONZ: Fix sources check in update script [@tremor021](https://github.com/tremor021) ([#10664](https://github.com/community-scripts/ProxmoxVE/pull/10664))
|
||||||
|
- Remove '--cpu' option from ExecStart command [@sethgregory](https://github.com/sethgregory) ([#10659](https://github.com/community-scripts/ProxmoxVE/pull/10659))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 💥 Breaking Changes
|
||||||
|
|
||||||
|
- fix: setup_mariadb hangs on [@CrazyWolf13](https://github.com/CrazyWolf13) ([#10672](https://github.com/community-scripts/ProxmoxVE/pull/10672))
|
||||||
@@ -9,7 +9,7 @@ APP="Alpine-Grafana"
|
|||||||
var_tags="${var_tags:-alpine;monitoring}"
|
var_tags="${var_tags:-alpine;monitoring}"
|
||||||
var_cpu="${var_cpu:-1}"
|
var_cpu="${var_cpu:-1}"
|
||||||
var_ram="${var_ram:-256}"
|
var_ram="${var_ram:-256}"
|
||||||
var_disk="${var_disk:-2}"
|
var_disk="${var_disk:-1}"
|
||||||
var_os="${var_os:-alpine}"
|
var_os="${var_os:-alpine}"
|
||||||
var_version="${var_version:-3.23}"
|
var_version="${var_version:-3.23}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9.]*[0-9]\).*/\1/p' | awk 'NR==1')
|
set +o pipefail && RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9.]*[0-9]\).*/\1/p' | head -1) && set -o pipefail
|
||||||
|
|
||||||
if [ "${RELEASE}" != "$(cat ~/.teamspeak-server)" ] || [ ! -f ~/.teamspeak-server ]; then
|
if [ "${RELEASE}" != "$(cat ~/.teamspeak-server)" ] || [ ! -f ~/.teamspeak-server ]; then
|
||||||
msg_info "Updating ${APP} LXC"
|
msg_info "Updating ${APP} LXC"
|
||||||
|
|||||||
@@ -32,17 +32,8 @@ function update_script() {
|
|||||||
systemctl stop cleanuparr
|
systemctl stop cleanuparr
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
msg_info "Backing up config"
|
|
||||||
cp -r /opt/cleanuparr/config /opt/cleanuparr_config_backup
|
|
||||||
msg_ok "Backed up config"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Cleanuparr" "Cleanuparr/Cleanuparr" "prebuild" "latest" "/opt/cleanuparr" "*linux-amd64.zip"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Cleanuparr" "Cleanuparr/Cleanuparr" "prebuild" "latest" "/opt/cleanuparr" "*linux-amd64.zip"
|
||||||
|
|
||||||
msg_info "Restoring config"
|
|
||||||
[[ -d /opt/cleanuparr/config ]] && rm -rf /opt/cleanuparr/config
|
|
||||||
mv /opt/cleanuparr_config_backup /opt/cleanuparr/config
|
|
||||||
msg_ok "Restored config"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start cleanuparr
|
systemctl start cleanuparr
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
|
|||||||
@@ -39,20 +39,17 @@ function update_script() {
|
|||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cryptpad" "cryptpad/cryptpad" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cryptpad" "cryptpad/cryptpad" "tarball"
|
||||||
|
|
||||||
msg_info "Restoring configuration"
|
|
||||||
mv /opt/config.js /opt/cryptpad/config/
|
|
||||||
msg_ok "Configuration restored"
|
|
||||||
|
|
||||||
msg_info "Updating CryptaPad"
|
msg_info "Updating CryptaPad"
|
||||||
cd /opt/cryptpad
|
cd /opt/cryptpad
|
||||||
$STD npm ci
|
$STD npm ci
|
||||||
$STD npm run install:components
|
$STD npm run install:components
|
||||||
if [ -f "/opt/cryptpad/install-onlyoffice.sh" ]; then
|
|
||||||
$STD bash /opt/cryptpad/install-onlyoffice.sh --accept-license
|
|
||||||
fi
|
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
msg_ok "Updated CryptaPad"
|
msg_ok "Updated CryptaPad"
|
||||||
|
|
||||||
|
msg_info "Restoring configuration"
|
||||||
|
mv /opt/config.js /opt/cryptpad/config/
|
||||||
|
msg_ok "Configuration restored"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start cryptpad
|
systemctl start cryptpad
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/databasus/databasus
|
|
||||||
|
|
||||||
APP="Databasus"
|
|
||||||
var_tags="${var_tags:-backup;postgresql;database}"
|
|
||||||
var_cpu="${var_cpu:-2}"
|
|
||||||
var_ram="${var_ram:-2048}"
|
|
||||||
var_disk="${var_disk:-8}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -f /opt/databasus/databasus ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "databasus" "databasus/databasus"; then
|
|
||||||
msg_info "Stopping Databasus"
|
|
||||||
$STD systemctl stop databasus
|
|
||||||
msg_ok "Stopped Databasus"
|
|
||||||
|
|
||||||
msg_info "Backing up Configuration"
|
|
||||||
cp /opt/databasus/.env /opt/databasus.env.bak
|
|
||||||
msg_ok "Backed up Configuration"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "databasus" "databasus/databasus" "tarball" "latest" "/opt/databasus"
|
|
||||||
|
|
||||||
msg_info "Updating Databasus"
|
|
||||||
cd /opt/databasus/frontend
|
|
||||||
$STD npm ci
|
|
||||||
$STD npm run build
|
|
||||||
cd /opt/databasus/backend
|
|
||||||
$STD go mod download
|
|
||||||
$STD /root/go/bin/swag init -g cmd/main.go -o swagger
|
|
||||||
$STD env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o databasus ./cmd/main.go
|
|
||||||
mv /opt/databasus/backend/databasus /opt/databasus/databasus
|
|
||||||
cp -r /opt/databasus/frontend/dist/* /opt/databasus/ui/build/
|
|
||||||
cp -r /opt/databasus/backend/migrations /opt/databasus/
|
|
||||||
chown -R postgres:postgres /opt/databasus
|
|
||||||
msg_ok "Updated Databasus"
|
|
||||||
|
|
||||||
msg_info "Restoring Configuration"
|
|
||||||
cp /opt/databasus.env.bak /opt/databasus/.env
|
|
||||||
rm -f /opt/databasus.env.bak
|
|
||||||
chown postgres:postgres /opt/databasus/.env
|
|
||||||
msg_ok "Restored Configuration"
|
|
||||||
|
|
||||||
msg_info "Starting Databasus"
|
|
||||||
$STD systemctl start databasus
|
|
||||||
msg_ok "Started Databasus"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
|
||||||
@@ -42,8 +42,7 @@ function update_script() {
|
|||||||
|
|
||||||
msg_info "Restoring Configurations"
|
msg_info "Restoring Configurations"
|
||||||
mv /opt/selfhosted.yaml /opt/donetick/config
|
mv /opt/selfhosted.yaml /opt/donetick/config
|
||||||
grep -q 'http://localhost"$' /opt/donetick/config/selfhosted.yaml || sed -i '/https:\/\/localhost"$/a\ - "http://localhost"' /opt/donetick/config/selfhosted.yaml
|
sed -i '/capacitor:\/\/localhost/d' /opt/donetick/config/selfhosted.yaml
|
||||||
grep -q 'capacitor://localhost' /opt/donetick/config/selfhosted.yaml || sed -i '/http:\/\/localhost"$/a\ - "capacitor://localhost"' /opt/donetick/config/selfhosted.yaml
|
|
||||||
mv /opt/donetick.db /opt/donetick
|
mv /opt/donetick.db /opt/donetick
|
||||||
msg_ok "Restored Configurations"
|
msg_ok "Restored Configurations"
|
||||||
|
|
||||||
|
|||||||
50
ct/ebusd.sh
50
ct/ebusd.sh
@@ -1,50 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: Joerg Heinemann (heinemannj)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/john30/ebusd
|
|
||||||
|
|
||||||
APP="ebusd"
|
|
||||||
var_tags="${var_tags:-automation}"
|
|
||||||
var_cpu="${var_cpu:-1}"
|
|
||||||
var_ram="${var_ram:-512}"
|
|
||||||
var_disk="${var_disk:-2}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
if [[ ! -f /etc/default/ebusd ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
if check_for_gh_release "ebusd" "john30/ebusd"; then
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop ebusd
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "ebusd" "john30/ebusd" "binary" "latest" "/opt/ebusd" "ebusd-*_amd64-trixie_mqtt1.deb"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start ebusd
|
|
||||||
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}"
|
|
||||||
@@ -9,7 +9,7 @@ APP="EMQX"
|
|||||||
var_tags="${var_tags:-mqtt}"
|
var_tags="${var_tags:-mqtt}"
|
||||||
var_cpu="${var_cpu:-2}"
|
var_cpu="${var_cpu:-2}"
|
||||||
var_ram="${var_ram:-1024}"
|
var_ram="${var_ram:-1024}"
|
||||||
var_disk="${var_disk:-6}"
|
var_disk="${var_disk:-4}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-13}"
|
var_version="${var_version:-13}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ APP="Grafana"
|
|||||||
var_tags="${var_tags:-monitoring;visualization}"
|
var_tags="${var_tags:-monitoring;visualization}"
|
||||||
var_cpu="${var_cpu:-1}"
|
var_cpu="${var_cpu:-1}"
|
||||||
var_ram="${var_ram:-512}"
|
var_ram="${var_ram:-512}"
|
||||||
var_disk="${var_disk:-4}"
|
var_disk="${var_disk:-2}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-13}"
|
var_version="${var_version:-13}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
____ __ __
|
|
||||||
/ __ \____ _/ /_____ _/ /_ ____ ________ _______
|
|
||||||
/ / / / __ `/ __/ __ `/ __ \/ __ `/ ___/ / / / ___/
|
|
||||||
/ /_/ / /_/ / /_/ /_/ / /_/ / /_/ (__ ) /_/ (__ )
|
|
||||||
/_____/\__,_/\__/\__,_/_.___/\__,_/____/\__,_/____/
|
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
__ __
|
|
||||||
___ / /_ __ ___________/ /
|
|
||||||
/ _ \/ __ \/ / / / ___/ __ /
|
|
||||||
/ __/ /_/ / /_/ (__ ) /_/ /
|
|
||||||
\___/_.___/\__,_/____/\__,_/
|
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
___ __ ___
|
|
||||||
/ (_)___ / /______/ (_)___ ____ _
|
|
||||||
/ / / __ \/ //_/ __ / / __ \/ __ `/
|
|
||||||
/ / / / / / ,< / /_/ / / / / / /_/ /
|
|
||||||
/_/_/_/ /_/_/|_|\__,_/_/_/ /_/\__, /
|
|
||||||
/____/
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
____ __ ___
|
|
||||||
/ __ \____ ____ ___ / |/ /
|
|
||||||
/ /_/ / __ \/ __ `__ \/ /|_/ /
|
|
||||||
/ _, _/ /_/ / / / / / / / / /
|
|
||||||
/_/ |_|\____/_/ /_/ /_/_/ /_/
|
|
||||||
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
_____
|
|
||||||
/ ___/___ ___ __________
|
|
||||||
\__ \/ _ \/ _ \/ ___/ ___/
|
|
||||||
___/ / __/ __/ / / /
|
|
||||||
/____/\___/\___/_/ /_/
|
|
||||||
|
|
||||||
@@ -29,48 +29,47 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f "/opt/jellyseerr/package.json" ]] && [[ "$(grep -m1 '"version"' /opt/jellyseerr/package.json | awk -F'"' '{print $4}')" == "2.7.3" ]]; then
|
if [ "$(node -v | cut -c2-3)" -ne 22 ]; then
|
||||||
echo
|
msg_info "Updating Node.js Repository"
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" >/etc/apt/sources.list.d/nodesource.list
|
||||||
echo "Jellyseerr v2.7.3 detected."
|
msg_ok "Updating Node.js Repository"
|
||||||
echo
|
|
||||||
echo "Seerr is the new unified Jellyseerr and Overseerr."
|
|
||||||
echo "More info: https://docs.seerr.dev/blog/seerr-release"
|
|
||||||
echo
|
|
||||||
read -rp "Do you want to migrate to Seerr now? (y/N): " MIGRATE
|
|
||||||
echo
|
|
||||||
if [[ ! "$MIGRATE" =~ ^[Yy]$ ]]; then
|
|
||||||
msg_info "Migration cancelled. Exiting."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Switching update script to Seerr"
|
msg_info "Updating Packages"
|
||||||
cat <<'EOF' >/usr/bin/update
|
$STD apt-get update
|
||||||
#!/usr/bin/env bash
|
$STD apt-get -y upgrade
|
||||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/seerr.sh)"
|
msg_ok "Updating Packages"
|
||||||
EOF
|
fi
|
||||||
chmod +x /usr/bin/update
|
|
||||||
msg_ok "Switched update script to Seerr"
|
cd /opt/jellyseerr
|
||||||
msg_warn "Please type 'update' again to complete the migration"
|
output=$(git pull --no-rebase)
|
||||||
exit
|
|
||||||
|
pnpm_current=$(pnpm --version 2>/dev/null)
|
||||||
|
pnpm_desired=$(grep -Po '"pnpm":\s*"\K[^"]+' /opt/jellyseerr/package.json)
|
||||||
|
|
||||||
|
if [ -z "$pnpm_current" ]; then
|
||||||
|
msg_error "pnpm not found. Installing version $pnpm_desired..."
|
||||||
|
NODE_VERSION="22" NODE_MODULE="pnpm@$pnpm_desired" setup_nodejs
|
||||||
|
elif ! node -e "const semver = require('semver'); process.exit(semver.satisfies('$pnpm_current', '$pnpm_desired') ? 0 : 1)"; then
|
||||||
|
msg_error "Updating pnpm from version $pnpm_current to $pnpm_desired..."
|
||||||
|
NODE_VERSION="22" NODE_MODULE="pnpm@$pnpm_desired" setup_nodejs
|
||||||
|
else
|
||||||
|
msg_ok "pnpm is already installed and satisfies version $pnpm_desired."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Updating Jellyseerr"
|
msg_info "Updating Jellyseerr"
|
||||||
cd /opt/jellyseerr
|
|
||||||
systemctl stop jellyseerr
|
|
||||||
output=$(git pull --no-rebase)
|
|
||||||
pnpm_desired=$(grep -Po '"pnpm":\s*"\K[^"]+' /opt/jellyseerr/package.json)
|
|
||||||
NODE_VERSION="22" NODE_MODULE="pnpm@$pnpm_desired" setup_nodejs
|
|
||||||
if echo "$output" | grep -q "Already up to date."; then
|
if echo "$output" | grep -q "Already up to date."; then
|
||||||
msg_ok "$APP is already up to date."
|
msg_ok "$APP is already up to date."
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
systemctl stop jellyseerr
|
||||||
rm -rf dist .next node_modules
|
rm -rf dist .next node_modules
|
||||||
export CYPRESS_INSTALL_BINARY=0
|
export CYPRESS_INSTALL_BINARY=0
|
||||||
cd /opt/jellyseerr
|
cd /opt/jellyseerr
|
||||||
$STD pnpm install --frozen-lockfile
|
$STD pnpm install --frozen-lockfile
|
||||||
export NODE_OPTIONS="--max-old-space-size=3072"
|
export NODE_OPTIONS="--max-old-space-size=3072"
|
||||||
$STD pnpm build
|
$STD pnpm build
|
||||||
|
|
||||||
cat <<EOF >/etc/systemd/system/jellyseerr.service
|
cat <<EOF >/etc/systemd/system/jellyseerr.service
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=jellyseerr Service
|
Description=jellyseerr Service
|
||||||
@@ -86,6 +85,7 @@ ExecStart=/usr/bin/node dist/index.js
|
|||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl start jellyseerr
|
systemctl start jellyseerr
|
||||||
msg_ok "Updated Jellyseerr"
|
msg_ok "Updated Jellyseerr"
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ function update_script() {
|
|||||||
msg_info "Restoring configuration & data"
|
msg_info "Restoring configuration & data"
|
||||||
mv /opt/app.env /opt/jotty/.env
|
mv /opt/app.env /opt/jotty/.env
|
||||||
[[ -d /opt/data ]] && mv /opt/data /opt/jotty/data
|
[[ -d /opt/data ]] && mv /opt/data /opt/jotty/data
|
||||||
[[ -d /opt/jotty/config ]] && cp -a /opt/config/* /opt/jotty/config && rm -rf /opt/config
|
[[ -d /opt/jotty/config ]] && mv /opt/config/* /opt/jotty/config
|
||||||
msg_ok "Restored configuration & data"
|
msg_ok "Restored configuration & data"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (MickLesk)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://linkding.link/
|
|
||||||
|
|
||||||
APP="linkding"
|
|
||||||
var_tags="${var_tags:-bookmarks;management}"
|
|
||||||
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_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/linkding ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "linkding" "sissbruecker/linkding"; then
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop nginx linkding linkding-tasks
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
msg_info "Backing up Data"
|
|
||||||
cp -r /opt/linkding/data /opt/linkding_data_backup
|
|
||||||
cp /opt/linkding/.env /opt/linkding_env_backup
|
|
||||||
msg_ok "Backed up Data"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "linkding" "sissbruecker/linkding"
|
|
||||||
|
|
||||||
msg_info "Restoring Data"
|
|
||||||
cp -r /opt/linkding_data_backup/. /opt/linkding/data
|
|
||||||
cp /opt/linkding_env_backup /opt/linkding/.env
|
|
||||||
rm -rf /opt/linkding_data_backup /opt/linkding_env_backup
|
|
||||||
ln -sf /usr/lib/x86_64-linux-gnu/mod_icu.so /opt/linkding/libicu.so
|
|
||||||
msg_ok "Restored Data"
|
|
||||||
|
|
||||||
msg_info "Updating LinkDing"
|
|
||||||
cd /opt/linkding
|
|
||||||
rm -f bookmarks/settings/dev.py
|
|
||||||
touch bookmarks/settings/custom.py
|
|
||||||
$STD npm ci
|
|
||||||
$STD npm run build
|
|
||||||
$STD uv sync --no-dev --frozen
|
|
||||||
$STD uv pip install gunicorn
|
|
||||||
set -a && source /opt/linkding/.env && set +a
|
|
||||||
$STD /opt/linkding/.venv/bin/python manage.py migrate
|
|
||||||
$STD /opt/linkding/.venv/bin/python manage.py collectstatic --no-input
|
|
||||||
msg_ok "Updated LinkDing"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start nginx linkding linkding-tasks
|
|
||||||
msg_ok "Started Services"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed Successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9090${CL}"
|
|
||||||
@@ -9,7 +9,7 @@ APP="Ollama"
|
|||||||
var_tags="${var_tags:-ai}"
|
var_tags="${var_tags:-ai}"
|
||||||
var_cpu="${var_cpu:-4}"
|
var_cpu="${var_cpu:-4}"
|
||||||
var_ram="${var_ram:-4096}"
|
var_ram="${var_ram:-4096}"
|
||||||
var_disk="${var_disk:-40}"
|
var_disk="${var_disk:-35}"
|
||||||
var_os="${var_os:-ubuntu}"
|
var_os="${var_os:-ubuntu}"
|
||||||
var_version="${var_version:-24.04}"
|
var_version="${var_version:-24.04}"
|
||||||
var_gpu="${var_gpu:-yes}"
|
var_gpu="${var_gpu:-yes}"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RELEASE="v5.1.0"
|
RELEASE="v5.0.2"
|
||||||
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}"; then
|
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}"; then
|
||||||
msg_info "Stopping services"
|
msg_info "Stopping services"
|
||||||
systemctl stop opencloud opencloud-wopi
|
systemctl stop opencloud opencloud-wopi
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ APP="Open WebUI"
|
|||||||
var_tags="${var_tags:-ai;interface}"
|
var_tags="${var_tags:-ai;interface}"
|
||||||
var_cpu="${var_cpu:-4}"
|
var_cpu="${var_cpu:-4}"
|
||||||
var_ram="${var_ram:-8192}"
|
var_ram="${var_ram:-8192}"
|
||||||
var_disk="${var_disk:-50}"
|
var_disk="${var_disk:-25}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-13}"
|
var_version="${var_version:-13}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
@@ -44,7 +44,7 @@ function update_script() {
|
|||||||
|
|
||||||
msg_info "Installing uv-based Open-WebUI"
|
msg_info "Installing uv-based Open-WebUI"
|
||||||
PYTHON_VERSION="3.12" setup_uv
|
PYTHON_VERSION="3.12" setup_uv
|
||||||
$STD uv tool install --python 3.12 --constraint <(echo "numba>=0.60") open-webui[all]
|
$STD uv tool install --python 3.12 open-webui[all]
|
||||||
msg_ok "Installed uv-based Open-WebUI"
|
msg_ok "Installed uv-based Open-WebUI"
|
||||||
|
|
||||||
msg_info "Restoring data"
|
msg_info "Restoring data"
|
||||||
@@ -126,7 +126,7 @@ EOF
|
|||||||
|
|
||||||
msg_info "Updating Open WebUI via uv"
|
msg_info "Updating Open WebUI via uv"
|
||||||
PYTHON_VERSION="3.12" setup_uv
|
PYTHON_VERSION="3.12" setup_uv
|
||||||
$STD uv tool install --force --python 3.12 --constraint <(echo "numba>=0.60") open-webui[all]
|
$STD uv tool upgrade --python 3.12 open-webui[all]
|
||||||
systemctl restart open-webui
|
systemctl restart open-webui
|
||||||
msg_ok "Updated Open WebUI"
|
msg_ok "Updated Open WebUI"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
|
|||||||
@@ -27,33 +27,6 @@ function update_script() {
|
|||||||
msg_error "No ${APP} Installation Found!"
|
msg_error "No ${APP} Installation Found!"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f "$HOME/.overseerr" ]] && [[ "$(cat "$HOME/.overseerr")" == "1.34.0" ]]; then
|
|
||||||
echo
|
|
||||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
||||||
echo "Overseerr v1.34.0 detected."
|
|
||||||
echo
|
|
||||||
echo "Seerr is the new unified Jellyseerr and Overseerr."
|
|
||||||
echo "More info: https://docs.seerr.dev/blog/seerr-release"
|
|
||||||
echo
|
|
||||||
read -rp "Do you want to migrate to Seerr now? (y/N): " MIGRATE
|
|
||||||
echo
|
|
||||||
if [[ ! "$MIGRATE" =~ ^[Yy]$ ]]; then
|
|
||||||
msg_info "Migration cancelled. Exiting."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Switching update script to Seerr"
|
|
||||||
cat <<'EOF' >/usr/bin/update
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/seerr.sh)"
|
|
||||||
EOF
|
|
||||||
chmod +x /usr/bin/update
|
|
||||||
msg_ok "Switched update script to Seerr"
|
|
||||||
msg_warn "Please type 'update' again to complete the migration"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "overseerr" "sct/overseerr"; then
|
if check_for_gh_release "overseerr" "sct/overseerr"; then
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop overseerr
|
systemctl stop overseerr
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ function update_script() {
|
|||||||
$STD npm run db:generate
|
$STD npm run db:generate
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
$STD npm run build:cli
|
$STD npm run build:cli
|
||||||
$STD npm run db:push
|
$STD npm run db:sqlite:push
|
||||||
cp -R .next/standalone ./
|
cp -R .next/standalone ./
|
||||||
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
|
||||||
|
|||||||
@@ -43,40 +43,22 @@ function update_script() {
|
|||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "latest" "/opt/patchmon"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "latest" "/opt/patchmon"
|
||||||
|
|
||||||
msg_info "Updating PatchMon"
|
msg_info "Updating PatchMon"
|
||||||
VERSION=$(get_latest_github_release "PatchMon/PatchMon")
|
|
||||||
PROTO="$(sed -n '/SERVER_PROTOCOL/s/[^=]*=//p' /opt/backend.env)"
|
|
||||||
HOST="$(sed -n '/SERVER_HOST/s/[^=]*=//p' /opt/backend.env)"
|
|
||||||
[[ "${PROTO:-http}" == "http" ]] && PORT=":3001"
|
|
||||||
sed -i 's/PORT=3399/PORT=3001/' /opt/backend.env
|
|
||||||
sed -i -e "s/VERSION=.*/VERSION=$VERSION/" \
|
|
||||||
-e "\|VITE_API_URL=|s|http.*|${PROTO:-http}://${HOST:-$LOCAL_IP}${PORT:-}/api/v1|" /opt/frontend.env
|
|
||||||
export NODE_ENV=production
|
|
||||||
cd /opt/patchmon
|
cd /opt/patchmon
|
||||||
|
export NODE_ENV=production
|
||||||
|
$STD npm install --no-audit --no-fund --no-save --ignore-scripts
|
||||||
|
cd /opt/patchmon/backend
|
||||||
$STD npm install --no-audit --no-fund --no-save --ignore-scripts
|
$STD npm install --no-audit --no-fund --no-save --ignore-scripts
|
||||||
cd /opt/patchmon/frontend
|
cd /opt/patchmon/frontend
|
||||||
mv /opt/frontend.env /opt/patchmon/frontend/.env
|
$STD npm install --include=dev --no-audit --no-fund --no-save --ignore-scripts
|
||||||
$STD npm install --no-audit --no-fund --no-save --ignore-scripts --include=dev
|
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
cd /opt/patchmon/backend
|
cd /opt/patchmon/backend
|
||||||
mv /opt/backend.env /opt/patchmon/backend/.env
|
mv /opt/backend.env /opt/patchmon/backend/.env
|
||||||
$STD npm run db:generate
|
mv /opt/frontend.env /opt/patchmon/frontend/.env
|
||||||
$STD npx prisma migrate deploy
|
$STD npx prisma migrate deploy
|
||||||
cp /opt/patchmon/docker/nginx.conf.template /etc/nginx/sites-available/patchmon.conf
|
$STD npx prisma generate
|
||||||
sed -i -e 's|proxy_pass .*|proxy_pass http://127.0.0.1:3001;|' \
|
|
||||||
-e '\|try_files |i\ root /opt/patchmon/frontend/dist;' \
|
|
||||||
-e 's|alias.*|alias /opt/patchmon/frontend/dist/assets;|' \
|
|
||||||
-e '\|expires 1y|i\ root /opt/patchmon/frontend/dist;' /etc/nginx/sites-available/patchmon.conf
|
|
||||||
ln -sf /etc/nginx/sites-available/patchmon.conf /etc/nginx/sites-enabled/
|
|
||||||
rm -f /etc/nginx/sites-enabled/default
|
|
||||||
$STD nginx -t
|
|
||||||
systemctl restart nginx
|
|
||||||
msg_ok "Updated PatchMon"
|
msg_ok "Updated PatchMon"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
if grep -q '/usr/bin/node' /etc/systemd/system/patchmon-server.service; then
|
|
||||||
sed -i 's|ExecStart=.*|ExecStart=/usr/bin/npm run start|' /etc/systemd/system/patchmon-server.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
fi
|
|
||||||
systemctl start patchmon-server
|
systemctl start patchmon-server
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
@@ -91,4 +73,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 "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
||||||
|
|||||||
@@ -61,12 +61,6 @@ function update_script() {
|
|||||||
rm -rf "$BK"
|
rm -rf "$BK"
|
||||||
msg_ok "Restored data"
|
msg_ok "Restored data"
|
||||||
|
|
||||||
msg_ok "Migrate Database"
|
|
||||||
cd /opt/planka
|
|
||||||
$STD npm run db:upgrade
|
|
||||||
$STD npm run db:migrate
|
|
||||||
msg_ok "Migrated Database"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start planka
|
systemctl start planka
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
|
|||||||
@@ -71,7 +71,6 @@ EOF
|
|||||||
$STD php artisan migrate --seed --force --no-interaction
|
$STD php artisan migrate --seed --force --no-interaction
|
||||||
chown -R www-data:www-data /opt/pterodactyl-panel/*
|
chown -R www-data:www-data /opt/pterodactyl-panel/*
|
||||||
chmod -R 755 /opt/pterodactyl-panel/storage /opt/pterodactyl-panel/bootstrap/cache/
|
chmod -R 755 /opt/pterodactyl-panel/storage /opt/pterodactyl-panel/bootstrap/cache/
|
||||||
ln -s /opt/pterodactyl-panel /var/www/pterodactyl
|
|
||||||
rm -rf "/opt/pterodactyl-panel/panel.tar.gz"
|
rm -rf "/opt/pterodactyl-panel/panel.tar.gz"
|
||||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||||
msg_ok "Updated $APP to v${RELEASE}"
|
msg_ok "Updated $APP to v${RELEASE}"
|
||||||
|
|||||||
@@ -28,55 +28,16 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if check_for_gh_release "Radicale" "Kozea/Radicale"; then
|
msg_info "Updating ${APP}"
|
||||||
msg_info "Stopping service"
|
$STD python3 -m venv /opt/radicale
|
||||||
systemctl stop radicale
|
source /opt/radicale/bin/activate
|
||||||
msg_ok "Stopped service"
|
$STD python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
|
||||||
|
msg_ok "Updated ${APP}"
|
||||||
|
|
||||||
msg_info "Backing up users file"
|
msg_info "Starting Service"
|
||||||
cp /opt/radicale/users /opt/radicale_users_backup
|
systemctl enable -q --now radicale
|
||||||
msg_ok "Backed up users file"
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
PYTHON_VERSION="3.13" setup_uv
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Radicale" "Kozea/Radicale" "tarball" "latest" "/opt/radicale"
|
|
||||||
|
|
||||||
msg_info "Restoring users file"
|
|
||||||
rm -f /opt/radicale/users
|
|
||||||
mv /opt/radicale_users_backup /opt/radicale/users
|
|
||||||
msg_ok "Restored users file"
|
|
||||||
|
|
||||||
if grep -q 'start.sh' /etc/systemd/system/radicale.service; then
|
|
||||||
sed -i -e '/^Description/i[Unit]' \
|
|
||||||
-e '\|^ExecStart|iWorkingDirectory=/opt/radicale' \
|
|
||||||
-e 's|^ExecStart=.*|ExecStart=/usr/local/bin/uv run -m radicale --config /etc/radicale/config|' /etc/systemd/system/radicale.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
fi
|
|
||||||
if [[ ! -f /etc/radicale/config ]]; then
|
|
||||||
msg_info "Migrating to config file (/etc/radicale/config)"
|
|
||||||
mkdir -p /etc/radicale
|
|
||||||
cat <<EOF >/etc/radicale/config
|
|
||||||
[server]
|
|
||||||
hosts = 0.0.0.0:5232
|
|
||||||
|
|
||||||
[auth]
|
|
||||||
type = htpasswd
|
|
||||||
htpasswd_filename = /opt/radicale/users
|
|
||||||
htpasswd_encryption = sha512
|
|
||||||
|
|
||||||
[storage]
|
|
||||||
type = multifilesystem
|
|
||||||
filesystem_folder = /var/lib/radicale/collections
|
|
||||||
|
|
||||||
[web]
|
|
||||||
type = internal
|
|
||||||
EOF
|
|
||||||
msg_ok "Migrated to config (/etc/radicale/config)"
|
|
||||||
fi
|
|
||||||
msg_info "Starting service"
|
|
||||||
systemctl start radicale
|
|
||||||
msg_ok "Started service"
|
|
||||||
msg_ok "Updated Successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
74
ct/romm.sh
74
ct/romm.sh
@@ -1,74 +0,0 @@
|
|||||||
#!/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: MickLesk (CanbiZ) | DevelopmentCats | AlphaLawless
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://romm.app
|
|
||||||
|
|
||||||
APP="RomM"
|
|
||||||
var_tags="${var_tags:-emulation}"
|
|
||||||
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_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/romm ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
if check_for_gh_release "romm" "rommapp/romm"; then
|
|
||||||
msg_info "Stopping Services"
|
|
||||||
systemctl stop romm-backend romm-worker romm-scheduler romm-watcher
|
|
||||||
msg_ok "Stopped Services"
|
|
||||||
|
|
||||||
msg_info "Backing up configuration"
|
|
||||||
cp /opt/romm/.env /opt/romm/.env.backup
|
|
||||||
msg_ok "Backed up configuration"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "romm" "rommapp/romm" "tarball" "latest" "/opt/romm"
|
|
||||||
|
|
||||||
msg_info "Updating ROMM"
|
|
||||||
cp /opt/romm/.env.backup /opt/romm/.env
|
|
||||||
cd /opt/romm
|
|
||||||
$STD uv sync --all-extras
|
|
||||||
cd /opt/romm/backend
|
|
||||||
$STD uv run alembic upgrade head
|
|
||||||
cd /opt/romm/frontend
|
|
||||||
$STD npm install
|
|
||||||
$STD npm run build
|
|
||||||
# Merge static assets into dist folder
|
|
||||||
cp -rf /opt/romm/frontend/assets/* /opt/romm/frontend/dist/assets/
|
|
||||||
mkdir -p /opt/romm/frontend/dist/assets/romm
|
|
||||||
ln -sfn /var/lib/romm/resources /opt/romm/frontend/dist/assets/romm/resources
|
|
||||||
ln -sfn /var/lib/romm/assets /opt/romm/frontend/dist/assets/romm/assets
|
|
||||||
msg_ok "Updated ROMM"
|
|
||||||
|
|
||||||
msg_info "Starting Services"
|
|
||||||
systemctl start romm-backend romm-worker romm-scheduler romm-watcher
|
|
||||||
msg_ok "Started Services"
|
|
||||||
msg_ok "Updated successfully"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
|
||||||
165
ct/seerr.sh
165
ct/seerr.sh
@@ -1,165 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: CrazyWolf13
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://docs.seerr.dev/
|
|
||||||
|
|
||||||
APP="Seerr"
|
|
||||||
var_tags="${var_tags:-media}"
|
|
||||||
var_cpu="${var_cpu:-4}"
|
|
||||||
var_ram="${var_ram:-4096}"
|
|
||||||
var_disk="${var_disk:-12}"
|
|
||||||
var_os="${var_os:-debian}"
|
|
||||||
var_version="${var_version:-13}"
|
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
|
||||||
|
|
||||||
header_info "$APP"
|
|
||||||
variables
|
|
||||||
color
|
|
||||||
catch_errors
|
|
||||||
|
|
||||||
function update_script() {
|
|
||||||
header_info
|
|
||||||
check_container_storage
|
|
||||||
check_container_resources
|
|
||||||
|
|
||||||
if [[ ! -d /opt/seerr && ! -d /opt/jellyseerr && ! -d /opt/overseerr ]]; then
|
|
||||||
msg_error "No ${APP} Installation Found!"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Start Migration from Jellyseerr
|
|
||||||
if [[ -f /etc/systemd/system/jellyseerr.service ]]; then
|
|
||||||
msg_info "Stopping Jellyseerr"
|
|
||||||
$STD systemctl stop jellyseerr || true
|
|
||||||
$STD systemctl disable jellyseerr || true
|
|
||||||
[ -f /etc/systemd/system/jellyseerr.service ] && rm -f /etc/systemd/system/jellyseerr.service
|
|
||||||
msg_ok "Stopped Jellyseerr"
|
|
||||||
|
|
||||||
msg_info "Creating Backup (Patience)"
|
|
||||||
tar -czf /opt/jellyseerr_backup_$(date +%Y%m%d_%H%M%S).tar.gz -C /opt jellyseerr
|
|
||||||
msg_ok "Created Backup"
|
|
||||||
|
|
||||||
msg_info "Migrating Jellyseerr to seerr"
|
|
||||||
[ -d /opt/jellyseerr ] && mv /opt/jellyseerr /opt/seerr
|
|
||||||
[ -d /etc/jellyseerr ] && mv /etc/jellyseerr /etc/seerr
|
|
||||||
[ -f /etc/seerr/jellyseerr.conf ] && mv /etc/seerr/jellyseerr.conf /etc/seerr/seerr.conf
|
|
||||||
cat <<EOF >/etc/systemd/system/seerr.service
|
|
||||||
[Unit]
|
|
||||||
Description=Seerr Service
|
|
||||||
Wants=network-online.target
|
|
||||||
After=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
EnvironmentFile=/etc/seerr/seerr.conf
|
|
||||||
Environment=NODE_ENV=production
|
|
||||||
Type=exec
|
|
||||||
Restart=on-failure
|
|
||||||
WorkingDirectory=/opt/seerr
|
|
||||||
ExecStart=/usr/bin/node dist/index.js
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl enable -q --now seerr
|
|
||||||
msg_ok "Migrated Jellyserr to Seerr"
|
|
||||||
fi
|
|
||||||
# END Jellyseerr Migration
|
|
||||||
|
|
||||||
# Start Migration from Overseerr
|
|
||||||
if [[ -f /etc/systemd/system/overseerr.service ]]; then
|
|
||||||
msg_info "Stopping Overseerr"
|
|
||||||
$STD systemctl stop overseerr || true
|
|
||||||
$STD systemctl disable overseerr || true
|
|
||||||
[ -f /etc/systemd/system/overseerr.service ] && rm -f /etc/systemd/system/overseerr.service
|
|
||||||
msg_ok "Stopped Overseerr"
|
|
||||||
|
|
||||||
msg_info "Creating Backup (Patience)"
|
|
||||||
tar -czf /opt/overseerr_backup_$(date +%Y%m%d_%H%M%S).tar.gz -C /opt overseerr
|
|
||||||
msg_ok "Created Backup"
|
|
||||||
|
|
||||||
msg_info "Migrating Overseerr to seerr"
|
|
||||||
[ -d /opt/overseerr ] && mv /opt/overseerr /opt/seerr
|
|
||||||
mkdir -p /etc/seerr
|
|
||||||
cat <<EOF >/etc/seerr/seerr.conf
|
|
||||||
## Seerr's default port is 5055, if you want to use both, change this.
|
|
||||||
## specify on which port to listen
|
|
||||||
PORT=5055
|
|
||||||
|
|
||||||
## specify on which interface to listen, by default seerr listens on all interfaces
|
|
||||||
#HOST=127.0.0.1
|
|
||||||
|
|
||||||
## Uncomment if you want to force Node.js to resolve IPv4 before IPv6 (advanced users only)
|
|
||||||
# FORCE_IPV4_FIRST=true
|
|
||||||
EOF
|
|
||||||
cat <<EOF >/etc/systemd/system/seerr.service
|
|
||||||
[Unit]
|
|
||||||
Description=Seerr Service
|
|
||||||
Wants=network-online.target
|
|
||||||
After=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
EnvironmentFile=/etc/seerr/seerr.conf
|
|
||||||
Environment=NODE_ENV=production
|
|
||||||
Type=exec
|
|
||||||
Restart=on-failure
|
|
||||||
WorkingDirectory=/opt/seerr
|
|
||||||
ExecStart=/usr/bin/node dist/index.js
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl enable -q --now seerr
|
|
||||||
msg_ok "Migrated Overseerr to Seerr"
|
|
||||||
fi
|
|
||||||
# END Overseerr Migration
|
|
||||||
|
|
||||||
if check_for_gh_release "seerr" "seerr-team/seerr"; then
|
|
||||||
msg_info "Stopping Service"
|
|
||||||
systemctl stop seerr
|
|
||||||
msg_ok "Stopped Service"
|
|
||||||
|
|
||||||
msg_info "Creating Backup"
|
|
||||||
cp -a /opt/seerr/config /opt/seerr_backup
|
|
||||||
msg_ok "Created Backup"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "seerr" "seerr-team/seerr" "tarball"
|
|
||||||
|
|
||||||
msg_info "Updating PNPM Version"
|
|
||||||
pnpm_desired=$(grep -Po '"pnpm":\s*"\K[^"]+' /opt/seerr/package.json)
|
|
||||||
NODE_VERSION="22" NODE_MODULE="pnpm@$pnpm_desired" setup_nodejs
|
|
||||||
msg_ok "Updated PNPM Version"
|
|
||||||
|
|
||||||
msg_info "Updating Seerr"
|
|
||||||
cd /opt/seerr
|
|
||||||
rm -rf dist .next node_modules
|
|
||||||
export CYPRESS_INSTALL_BINARY=0
|
|
||||||
$STD pnpm install --frozen-lockfile
|
|
||||||
export NODE_OPTIONS="--max-old-space-size=3072"
|
|
||||||
$STD pnpm build
|
|
||||||
msg_ok "Updated Seerr"
|
|
||||||
|
|
||||||
msg_info "Restoring Backup"
|
|
||||||
rm -rf /opt/seerr/config
|
|
||||||
mv /opt/seerr_backup /opt/seerr/config
|
|
||||||
msg_ok "Restored Backup"
|
|
||||||
|
|
||||||
msg_info "Starting Service"
|
|
||||||
systemctl start seerr
|
|
||||||
msg_ok "Started Service"
|
|
||||||
msg_ok "Updated successfully!"
|
|
||||||
fi
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
start
|
|
||||||
build_container
|
|
||||||
description
|
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
|
||||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
|
||||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
|
||||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:5055${CL}"
|
|
||||||
@@ -83,7 +83,6 @@ function update_script() {
|
|||||||
msg_ok "Started Soularr Timer"
|
msg_ok "Started Soularr Timer"
|
||||||
msg_ok "Updated Soularr successfully!"
|
msg_ok "Updated Soularr successfully!"
|
||||||
fi
|
fi
|
||||||
exit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start
|
start
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ function update_script() {
|
|||||||
|
|
||||||
msg_info "Updating VaultWarden to $VAULT (Patience)"
|
msg_info "Updating VaultWarden to $VAULT (Patience)"
|
||||||
cd /tmp/vaultwarden-src
|
cd /tmp/vaultwarden-src
|
||||||
VW_VERSION="$VAULT"
|
|
||||||
export VW_VERSION
|
|
||||||
$STD cargo build --features "sqlite,mysql,postgresql" --release
|
$STD cargo build --features "sqlite,mysql,postgresql" --release
|
||||||
if [[ -f /usr/bin/vaultwarden ]]; then
|
if [[ -f /usr/bin/vaultwarden ]]; then
|
||||||
cp target/release/vaultwarden /usr/bin/
|
cp target/release/vaultwarden /usr/bin/
|
||||||
|
|||||||
15
ct/zabbix.sh
15
ct/zabbix.sh
@@ -35,18 +35,15 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if systemctl cat zabbix-agent2.service &>/dev/null; then
|
if systemctl list-unit-files | grep -q zabbix-agent2.service; then
|
||||||
AGENT_SERVICE="zabbix-agent2"
|
AGENT_SERVICE="zabbix-agent2"
|
||||||
elif systemctl cat zabbix-agent.service &>/dev/null; then
|
|
||||||
AGENT_SERVICE="zabbix-agent"
|
|
||||||
else
|
else
|
||||||
AGENT_SERVICE=""
|
AGENT_SERVICE="zabbix-agent"
|
||||||
msg_warn "No Zabbix Agent service found, skipping agent actions"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
systemctl stop zabbix-server
|
systemctl stop zabbix-server
|
||||||
[[ -n "$AGENT_SERVICE" ]] && systemctl stop "$AGENT_SERVICE"
|
systemctl stop "$AGENT_SERVICE"
|
||||||
msg_ok "Stopped Services"
|
msg_ok "Stopped Services"
|
||||||
|
|
||||||
read -rp "Choose Zabbix version [1] 7.0 LTS [2] 7.4 (Latest Stable) [3] Latest available (default: 2): " ZABBIX_CHOICE
|
read -rp "Choose Zabbix version [1] 7.0 LTS [2] 7.4 (Latest Stable) [3] Latest available (default: 2): " ZABBIX_CHOICE
|
||||||
@@ -86,13 +83,13 @@ function update_script() {
|
|||||||
|
|
||||||
$STD apt install --only-upgrade zabbix-server-pgsql zabbix-frontend-php php8.4-pgsql
|
$STD apt install --only-upgrade zabbix-server-pgsql zabbix-frontend-php php8.4-pgsql
|
||||||
|
|
||||||
if [[ "$AGENT_SERVICE" == "zabbix-agent2" ]]; then
|
if [ "$AGENT_SERVICE" = "zabbix-agent2" ]; then
|
||||||
$STD apt install --only-upgrade zabbix-agent2 zabbix-agent2-plugin-postgresql
|
$STD apt install --only-upgrade zabbix-agent2 zabbix-agent2-plugin-postgresql
|
||||||
if [ -f /etc/zabbix/zabbix_agent2.d/plugins.d/nvidia.conf ]; then
|
if [ -f /etc/zabbix/zabbix_agent2.d/plugins.d/nvidia.conf ]; then
|
||||||
sed -i 's|^Plugins.NVIDIA.System.Path=.*|# Plugins.NVIDIA.System.Path=/usr/libexec/zabbix/zabbix-agent2-plugin-nvidia-gpu|' \
|
sed -i 's|^Plugins.NVIDIA.System.Path=.*|# Plugins.NVIDIA.System.Path=/usr/libexec/zabbix/zabbix-agent2-plugin-nvidia-gpu|' \
|
||||||
/etc/zabbix/zabbix_agent2.d/plugins.d/nvidia.conf
|
/etc/zabbix/zabbix_agent2.d/plugins.d/nvidia.conf
|
||||||
fi
|
fi
|
||||||
elif [[ "$AGENT_SERVICE" == "zabbix-agent" ]]; then
|
else
|
||||||
$STD apt install --only-upgrade zabbix-agent
|
$STD apt install --only-upgrade zabbix-agent
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -108,7 +105,7 @@ function update_script() {
|
|||||||
|
|
||||||
msg_info "Starting Services"
|
msg_info "Starting Services"
|
||||||
systemctl start zabbix-server
|
systemctl start zabbix-server
|
||||||
[[ -n "$AGENT_SERVICE" ]] && systemctl start "$AGENT_SERVICE"
|
systemctl start "$AGENT_SERVICE"
|
||||||
systemctl restart apache2
|
systemctl restart apache2
|
||||||
msg_ok "Started Services"
|
msg_ok "Started Services"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ update_links() {
|
|||||||
# Find all files containing the old repo reference
|
# Find all files containing the old repo reference
|
||||||
while IFS= read -r file; do
|
while IFS= read -r file; do
|
||||||
# Count occurrences
|
# Count occurrences
|
||||||
local count=$(grep -E -c "(github.com|githubusercontent.com)/$old_repo/$old_name" "$file" 2>/dev/null || echo 0)
|
local count=$(grep -c "github.com/$old_repo/$old_name" "$file" 2>/dev/null || echo 0)
|
||||||
|
|
||||||
if [[ $count -gt 0 ]]; then
|
if [[ $count -gt 0 ]]; then
|
||||||
# Backup original
|
# Backup original
|
||||||
@@ -143,16 +143,16 @@ update_links() {
|
|||||||
# Replace links - use different sed syntax for BSD/macOS vs GNU sed
|
# Replace links - use different sed syntax for BSD/macOS vs GNU sed
|
||||||
if sed --version &>/dev/null 2>&1; then
|
if sed --version &>/dev/null 2>&1; then
|
||||||
# GNU sed
|
# GNU sed
|
||||||
sed -E -i "s@(github.com|githubusercontent.com)/$old_repo/$old_name@\\1/$new_owner/$new_repo@g" "$file"
|
sed -i "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file"
|
||||||
else
|
else
|
||||||
# BSD sed (macOS)
|
# BSD sed (macOS)
|
||||||
sed -E -i '' "s@(github.com|githubusercontent.com)/$old_repo/$old_name@\\1/$new_owner/$new_repo@g" "$file"
|
sed -i '' "s|github.com/$old_repo/$old_name|github.com/$new_owner/$new_repo|g" "$file"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
((files_updated++))
|
((files_updated++))
|
||||||
print_success "Updated $file ($count links)"
|
print_success "Updated $file ($count links)"
|
||||||
fi
|
fi
|
||||||
done < <(find "$search_path" -type f \( -name "*.md" -o -name "*.sh" -o -name "*.func" -o -name "*.json" \) -not -path "*/.git/*" 2>/dev/null | xargs grep -E -l "(github.com|githubusercontent.com)/$old_repo/$old_name" 2>/dev/null)
|
done < <(find "$search_path" -type f \( -name "*.md" -o -name "*.sh" -o -name "*.func" -o -name "*.json" \) -not -path "*/.git/*" 2>/dev/null | xargs grep -l "github.com/$old_repo/$old_name" 2>/dev/null)
|
||||||
|
|
||||||
return $files_updated
|
return $files_updated
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Databasus",
|
|
||||||
"slug": "databasus",
|
|
||||||
"categories": [
|
|
||||||
7
|
|
||||||
],
|
|
||||||
"date_created": "2026-02-17",
|
|
||||||
"type": "ct",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": false,
|
|
||||||
"interface_port": 80,
|
|
||||||
"documentation": "https://github.com/databasus/databasus",
|
|
||||||
"website": "https://github.com/databasus/databasus",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/databasus.webp",
|
|
||||||
"config_path": "/opt/databasus/.env",
|
|
||||||
"description": "Free, open source and self-hosted solution for automated PostgreSQL backups. With multiple storage options, notifications, scheduling, and a beautiful web interface for managing database backups across multiple PostgreSQL instances.",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "ct/databasus.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": 2,
|
|
||||||
"ram": 2048,
|
|
||||||
"hdd": 8,
|
|
||||||
"os": "Debian",
|
|
||||||
"version": "13"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": "admin@localhost",
|
|
||||||
"password": "See /root/databasus.creds"
|
|
||||||
},
|
|
||||||
"notes": [
|
|
||||||
{
|
|
||||||
"text": "Supports PostgreSQL versions 12-18 with cloud and self-hosted instances",
|
|
||||||
"type": "info"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"text": "Features: Scheduled backups, multiple storage providers, notifications, encryption",
|
|
||||||
"type": "info"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "ebusd",
|
|
||||||
"slug": "ebusd",
|
|
||||||
"categories": [
|
|
||||||
16
|
|
||||||
],
|
|
||||||
"date_created": "2026-02-15",
|
|
||||||
"type": "ct",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": false,
|
|
||||||
"interface_port": null,
|
|
||||||
"documentation": "https://github.com/john30/ebusd/wiki",
|
|
||||||
"website": "https://github.com/john30/ebusd",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/ebusd.webp",
|
|
||||||
"config_path": "/etc/default/ebusd",
|
|
||||||
"description": "ebusd is a daemon for handling communication with eBUS devices connected to a 2-wire `energy bus` used by numerous heating systems.",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "ct/ebusd.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": 1,
|
|
||||||
"ram": 512,
|
|
||||||
"hdd": 2,
|
|
||||||
"os": "debian",
|
|
||||||
"version": "13"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": "root",
|
|
||||||
"password": null
|
|
||||||
},
|
|
||||||
"notes": [
|
|
||||||
{
|
|
||||||
"text": "For required post installation actions, checkout: `https://github.com/community-scripts/ProxmoxVE/discussions/11352`",
|
|
||||||
"type": "info"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 2,
|
"cpu": 2,
|
||||||
"ram": 1024,
|
"ram": 1024,
|
||||||
"hdd": 6,
|
"hdd": 4,
|
||||||
"os": "debian",
|
"os": "debian",
|
||||||
"version": "13"
|
"version": "13"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated": "2026-02-18T06:25:03Z",
|
"generated": "2026-02-12T12:15:15Z",
|
||||||
"versions": [
|
"versions": [
|
||||||
{
|
{
|
||||||
"slug": "2fauth",
|
"slug": "2fauth",
|
||||||
@@ -67,9 +67,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "autobrr",
|
"slug": "autobrr",
|
||||||
"repo": "autobrr/autobrr",
|
"repo": "autobrr/autobrr",
|
||||||
"version": "v1.73.0",
|
"version": "v1.72.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T16:37:28Z"
|
"date": "2026-01-30T12:57:58Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "autocaliweb",
|
"slug": "autocaliweb",
|
||||||
@@ -116,9 +116,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "bentopdf",
|
"slug": "bentopdf",
|
||||||
"repo": "alam00000/bentopdf",
|
"repo": "alam00000/bentopdf",
|
||||||
"version": "v2.2.1",
|
"version": "v2.2.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-14T16:33:47Z"
|
"date": "2026-02-09T07:07:40Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "beszel",
|
"slug": "beszel",
|
||||||
@@ -158,9 +158,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "bookstack",
|
"slug": "bookstack",
|
||||||
"repo": "BookStackApp/BookStack",
|
"repo": "BookStackApp/BookStack",
|
||||||
"version": "v25.12.5",
|
"version": "v25.12.3",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T18:42:47Z"
|
"date": "2026-01-29T15:29:25Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "byparr",
|
"slug": "byparr",
|
||||||
@@ -193,23 +193,23 @@
|
|||||||
{
|
{
|
||||||
"slug": "cleanuparr",
|
"slug": "cleanuparr",
|
||||||
"repo": "Cleanuparr/Cleanuparr",
|
"repo": "Cleanuparr/Cleanuparr",
|
||||||
"version": "v2.6.3",
|
"version": "v2.5.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T22:41:25Z"
|
"date": "2026-01-11T00:46:17Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "cloudreve",
|
"slug": "cloudreve",
|
||||||
"repo": "cloudreve/cloudreve",
|
"repo": "cloudreve/cloudreve",
|
||||||
"version": "4.14.1",
|
"version": "4.13.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T01:39:24Z"
|
"date": "2026-02-05T12:53:24Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "comfyui",
|
"slug": "comfyui",
|
||||||
"repo": "comfyanonymous/ComfyUI",
|
"repo": "comfyanonymous/ComfyUI",
|
||||||
"version": "v0.14.2",
|
"version": "v0.13.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-18T06:12:02Z"
|
"date": "2026-02-10T20:27:38Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "commafeed",
|
"slug": "commafeed",
|
||||||
@@ -221,9 +221,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "configarr",
|
"slug": "configarr",
|
||||||
"repo": "raydak-labs/configarr",
|
"repo": "raydak-labs/configarr",
|
||||||
"version": "v1.21.0",
|
"version": "v1.20.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T22:59:07Z"
|
"date": "2026-01-10T21:25:47Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "convertx",
|
"slug": "convertx",
|
||||||
@@ -253,19 +253,12 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-11T15:39:05Z"
|
"date": "2026-02-11T15:39:05Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"slug": "databasus",
|
|
||||||
"repo": "databasus/databasus",
|
|
||||||
"version": "v3.14.0",
|
|
||||||
"pinned": false,
|
|
||||||
"date": "2026-02-17T17:18:34Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"slug": "dawarich",
|
"slug": "dawarich",
|
||||||
"repo": "Freika/dawarich",
|
"repo": "Freika/dawarich",
|
||||||
"version": "1.2.0",
|
"version": "1.1.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T22:33:56Z"
|
"date": "2026-02-08T14:42:45Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "discopanel",
|
"slug": "discopanel",
|
||||||
@@ -291,9 +284,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "domain-locker",
|
"slug": "domain-locker",
|
||||||
"repo": "Lissy93/domain-locker",
|
"repo": "Lissy93/domain-locker",
|
||||||
"version": "v0.1.4",
|
"version": "v0.1.3",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-14T07:41:29Z"
|
"date": "2026-02-11T10:03:32Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "domain-monitor",
|
"slug": "domain-monitor",
|
||||||
@@ -305,9 +298,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "donetick",
|
"slug": "donetick",
|
||||||
"repo": "donetick/donetick",
|
"repo": "donetick/donetick",
|
||||||
"version": "v0.1.74",
|
"version": "v0.1.71",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-14T23:21:45Z"
|
"date": "2026-02-11T06:01:13Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "drawio",
|
"slug": "drawio",
|
||||||
@@ -323,13 +316,6 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-01-06T12:05:40Z"
|
"date": "2026-01-06T12:05:40Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"slug": "ebusd",
|
|
||||||
"repo": "john30/ebusd",
|
|
||||||
"version": "26.1",
|
|
||||||
"pinned": false,
|
|
||||||
"date": "2026-02-09T06:09:24Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"slug": "elementsynapse",
|
"slug": "elementsynapse",
|
||||||
"repo": "etkecc/synapse-admin",
|
"repo": "etkecc/synapse-admin",
|
||||||
@@ -368,9 +354,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "firefly",
|
"slug": "firefly",
|
||||||
"repo": "firefly-iii/firefly-iii",
|
"repo": "firefly-iii/firefly-iii",
|
||||||
"version": "v6.4.22",
|
"version": "v6.4.18",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T18:43:08Z"
|
"date": "2026-02-08T07:28:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "fladder",
|
"slug": "fladder",
|
||||||
@@ -417,9 +403,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "ghostfolio",
|
"slug": "ghostfolio",
|
||||||
"repo": "ghostfolio/ghostfolio",
|
"repo": "ghostfolio/ghostfolio",
|
||||||
"version": "2.239.0",
|
"version": "2.237.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T09:51:16Z"
|
"date": "2026-02-08T13:59:53Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "gitea",
|
"slug": "gitea",
|
||||||
@@ -459,9 +445,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "gotify",
|
"slug": "gotify",
|
||||||
"repo": "gotify/server",
|
"repo": "gotify/server",
|
||||||
"version": "v2.9.0",
|
"version": "v2.8.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T15:22:31Z"
|
"date": "2026-01-02T11:56:16Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "grist",
|
"slug": "grist",
|
||||||
@@ -522,9 +508,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "homarr",
|
"slug": "homarr",
|
||||||
"repo": "homarr-labs/homarr",
|
"repo": "homarr-labs/homarr",
|
||||||
"version": "v1.53.1",
|
"version": "v1.53.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T19:47:11Z"
|
"date": "2026-02-06T19:42:58Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "homebox",
|
"slug": "homebox",
|
||||||
@@ -557,16 +543,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "huntarr",
|
"slug": "huntarr",
|
||||||
"repo": "plexguide/Huntarr.io",
|
"repo": "plexguide/Huntarr.io",
|
||||||
"version": "9.3.3",
|
"version": "9.2.4",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-18T02:35:29Z"
|
"date": "2026-02-12T08:31:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "immich-public-proxy",
|
"slug": "immich-public-proxy",
|
||||||
"repo": "alangrainger/immich-public-proxy",
|
"repo": "alangrainger/immich-public-proxy",
|
||||||
"version": "v1.15.3",
|
"version": "v1.15.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T22:54:27Z"
|
"date": "2026-01-26T08:04:27Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "inspircd",
|
"slug": "inspircd",
|
||||||
@@ -585,16 +571,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "invoiceninja",
|
"slug": "invoiceninja",
|
||||||
"repo": "invoiceninja/invoiceninja",
|
"repo": "invoiceninja/invoiceninja",
|
||||||
"version": "v5.12.63",
|
"version": "v5.12.57",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-18T00:32:09Z"
|
"date": "2026-02-11T23:08:56Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "jackett",
|
"slug": "jackett",
|
||||||
"repo": "Jackett/Jackett",
|
"repo": "Jackett/Jackett",
|
||||||
"version": "v0.24.1147",
|
"version": "v0.24.1098",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-18T05:54:19Z"
|
"date": "2026-02-12T05:56:25Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "jellystat",
|
"slug": "jellystat",
|
||||||
@@ -648,9 +634,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "kimai",
|
"slug": "kimai",
|
||||||
"repo": "kimai/kimai",
|
"repo": "kimai/kimai",
|
||||||
"version": "2.49.0",
|
"version": "2.48.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T20:40:19Z"
|
"date": "2026-01-31T18:10:59Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "kitchenowl",
|
"slug": "kitchenowl",
|
||||||
@@ -704,16 +690,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "leantime",
|
"slug": "leantime",
|
||||||
"repo": "Leantime/leantime",
|
"repo": "Leantime/leantime",
|
||||||
"version": "v3.7.0",
|
"version": "v3.6.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-18T00:02:31Z"
|
"date": "2026-01-29T16:37:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "librenms",
|
"slug": "librenms",
|
||||||
"repo": "librenms/librenms",
|
"repo": "librenms/librenms",
|
||||||
"version": "26.2.0",
|
"version": "26.1.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T12:15:13Z"
|
"date": "2026-01-12T23:26:02Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "librespeed-rust",
|
"slug": "librespeed-rust",
|
||||||
@@ -736,19 +722,12 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-11-16T22:40:18Z"
|
"date": "2025-11-16T22:40:18Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"slug": "linkding",
|
|
||||||
"repo": "sissbruecker/linkding",
|
|
||||||
"version": "v1.45.0",
|
|
||||||
"pinned": false,
|
|
||||||
"date": "2026-01-06T20:31:04Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"slug": "linkstack",
|
"slug": "linkstack",
|
||||||
"repo": "linkstackorg/linkstack",
|
"repo": "linkstackorg/linkstack",
|
||||||
"version": "v4.8.6",
|
"version": "v4.8.5",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T16:53:47Z"
|
"date": "2026-01-26T18:46:52Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "linkwarden",
|
"slug": "linkwarden",
|
||||||
@@ -788,9 +767,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "mail-archiver",
|
"slug": "mail-archiver",
|
||||||
"repo": "s1t5/mail-archiver",
|
"repo": "s1t5/mail-archiver",
|
||||||
"version": "2602.2",
|
"version": "2602.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T09:46:52Z"
|
"date": "2026-02-11T06:23:11Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "managemydamnlife",
|
"slug": "managemydamnlife",
|
||||||
@@ -809,9 +788,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "mealie",
|
"slug": "mealie",
|
||||||
"repo": "mealie-recipes/mealie",
|
"repo": "mealie-recipes/mealie",
|
||||||
"version": "v3.11.0",
|
"version": "v3.10.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T04:13:35Z"
|
"date": "2026-02-04T23:32:32Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "mediamanager",
|
"slug": "mediamanager",
|
||||||
@@ -844,16 +823,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "metube",
|
"slug": "metube",
|
||||||
"repo": "alexta69/metube",
|
"repo": "alexta69/metube",
|
||||||
"version": "2026.02.14",
|
"version": "2026.02.08",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-14T07:49:11Z"
|
"date": "2026-02-08T17:01:37Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "miniflux",
|
"slug": "miniflux",
|
||||||
"repo": "miniflux/v2",
|
"repo": "miniflux/v2",
|
||||||
"version": "2.2.17",
|
"version": "2.2.16",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T20:30:17Z"
|
"date": "2026-01-07T03:26:27Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "monica",
|
"slug": "monica",
|
||||||
@@ -893,9 +872,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "netbox",
|
"slug": "netbox",
|
||||||
"repo": "netbox-community/netbox",
|
"repo": "netbox-community/netbox",
|
||||||
"version": "v4.5.3",
|
"version": "v4.5.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T15:39:18Z"
|
"date": "2026-02-03T13:54:26Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "nextcloud-exporter",
|
"slug": "nextcloud-exporter",
|
||||||
@@ -907,9 +886,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "nginx-ui",
|
"slug": "nginx-ui",
|
||||||
"repo": "0xJacky/nginx-ui",
|
"repo": "0xJacky/nginx-ui",
|
||||||
"version": "v2.3.3",
|
"version": "v2.3.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T00:58:14Z"
|
"date": "2025-12-09T09:47:15Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "nightscout",
|
"slug": "nightscout",
|
||||||
@@ -963,9 +942,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "opencloud",
|
"slug": "opencloud",
|
||||||
"repo": "opencloud-eu/opencloud",
|
"repo": "opencloud-eu/opencloud",
|
||||||
"version": "v5.1.0",
|
"version": "v5.0.2",
|
||||||
"pinned": true,
|
"pinned": true,
|
||||||
"date": "2026-02-16T15:04:28Z"
|
"date": "2026-02-05T16:29:01Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "opengist",
|
"slug": "opengist",
|
||||||
@@ -977,16 +956,23 @@
|
|||||||
{
|
{
|
||||||
"slug": "ots",
|
"slug": "ots",
|
||||||
"repo": "Luzifer/ots",
|
"repo": "Luzifer/ots",
|
||||||
"version": "v1.21.1",
|
"version": "v1.21.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T12:12:23Z"
|
"date": "2026-01-19T23:21:29Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "outline",
|
"slug": "outline",
|
||||||
"repo": "outline/outline",
|
"repo": "outline/outline",
|
||||||
"version": "v1.5.0",
|
"version": "v1.4.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T18:04:16Z"
|
"date": "2026-01-27T23:43:03Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"slug": "overseerr",
|
||||||
|
"repo": "sct/overseerr",
|
||||||
|
"version": "v1.34.0",
|
||||||
|
"pinned": false,
|
||||||
|
"date": "2025-03-26T08:48:34Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "owncast",
|
"slug": "owncast",
|
||||||
@@ -1012,9 +998,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "pangolin",
|
"slug": "pangolin",
|
||||||
"repo": "fosrl/pangolin",
|
"repo": "fosrl/pangolin",
|
||||||
"version": "1.15.4",
|
"version": "1.15.3",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T23:01:29Z"
|
"date": "2026-02-12T06:10:19Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "paperless-ai",
|
"slug": "paperless-ai",
|
||||||
@@ -1026,23 +1012,23 @@
|
|||||||
{
|
{
|
||||||
"slug": "paperless-gpt",
|
"slug": "paperless-gpt",
|
||||||
"repo": "icereed/paperless-gpt",
|
"repo": "icereed/paperless-gpt",
|
||||||
"version": "v0.25.0",
|
"version": "v0.24.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T08:31:48Z"
|
"date": "2026-01-14T21:28:09Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "paperless-ngx",
|
"slug": "paperless-ngx",
|
||||||
"repo": "paperless-ngx/paperless-ngx",
|
"repo": "paperless-ngx/paperless-ngx",
|
||||||
"version": "v2.20.7",
|
"version": "v2.20.6",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T16:52:23Z"
|
"date": "2026-01-31T07:30:27Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "patchmon",
|
"slug": "patchmon",
|
||||||
"repo": "PatchMon/PatchMon",
|
"repo": "PatchMon/PatchMon",
|
||||||
"version": "v1.4.1",
|
"version": "v1.3.7",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T18:00:13Z"
|
"date": "2025-12-25T11:08:14Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "paymenter",
|
"slug": "paymenter",
|
||||||
@@ -1068,9 +1054,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "pelican-wings",
|
"slug": "pelican-wings",
|
||||||
"repo": "pelican-dev/wings",
|
"repo": "pelican-dev/wings",
|
||||||
"version": "v1.0.0-beta24",
|
"version": "v1.0.0-beta23",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T16:09:56Z"
|
"date": "2026-02-09T22:10:26Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "pf2etools",
|
"slug": "pf2etools",
|
||||||
@@ -1096,9 +1082,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "planka",
|
"slug": "planka",
|
||||||
"repo": "plankanban/planka",
|
"repo": "plankanban/planka",
|
||||||
"version": "v2.0.1",
|
"version": "v2.0.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T15:26:55Z"
|
"date": "2026-02-11T13:50:10Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "plant-it",
|
"slug": "plant-it",
|
||||||
@@ -1110,9 +1096,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "pocketbase",
|
"slug": "pocketbase",
|
||||||
"repo": "pocketbase/pocketbase",
|
"repo": "pocketbase/pocketbase",
|
||||||
"version": "v0.36.4",
|
"version": "v0.36.2",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T08:02:51Z"
|
"date": "2026-02-01T08:12:42Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "pocketid",
|
"slug": "pocketid",
|
||||||
@@ -1233,19 +1219,12 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-11-16T22:39:01Z"
|
"date": "2025-11-16T22:39:01Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"slug": "radicale",
|
|
||||||
"repo": "Kozea/Radicale",
|
|
||||||
"version": "v3.6.0",
|
|
||||||
"pinned": false,
|
|
||||||
"date": "2026-01-10T06:56:46Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"slug": "rclone",
|
"slug": "rclone",
|
||||||
"repo": "rclone/rclone",
|
"repo": "rclone/rclone",
|
||||||
"version": "v1.73.1",
|
"version": "v1.73.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T18:27:21Z"
|
"date": "2026-01-30T22:12:03Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "rdtclient",
|
"slug": "rdtclient",
|
||||||
@@ -1282,13 +1261,6 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-03-28T13:00:23Z"
|
"date": "2025-03-28T13:00:23Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"slug": "romm",
|
|
||||||
"repo": "RetroAchievements/RALibretro",
|
|
||||||
"version": "1.8.2",
|
|
||||||
"pinned": false,
|
|
||||||
"date": "2026-01-23T17:03:31Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"slug": "rustdeskserver",
|
"slug": "rustdeskserver",
|
||||||
"repo": "rustdesk/rustdesk-server",
|
"repo": "rustdesk/rustdesk-server",
|
||||||
@@ -1320,9 +1292,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "scraparr",
|
"slug": "scraparr",
|
||||||
"repo": "thecfu/scraparr",
|
"repo": "thecfu/scraparr",
|
||||||
"version": "v3.0.3",
|
"version": "v3.0.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-12T14:20:56Z"
|
"date": "2026-02-11T17:42:23Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "seelf",
|
"slug": "seelf",
|
||||||
@@ -1331,19 +1303,12 @@
|
|||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2025-03-08T10:49:04Z"
|
"date": "2025-03-08T10:49:04Z"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"slug": "seerr",
|
|
||||||
"repo": "seerr-team/seerr",
|
|
||||||
"version": "v3.0.1",
|
|
||||||
"pinned": false,
|
|
||||||
"date": "2026-02-14T19:30:24Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"slug": "semaphore",
|
"slug": "semaphore",
|
||||||
"repo": "semaphoreui/semaphore",
|
"repo": "semaphoreui/semaphore",
|
||||||
"version": "v2.17.5",
|
"version": "v2.16.51",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T18:20:38Z"
|
"date": "2026-01-12T16:26:38Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "shelfmark",
|
"slug": "shelfmark",
|
||||||
@@ -1369,9 +1334,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "slskd",
|
"slug": "slskd",
|
||||||
"repo": "slskd/slskd",
|
"repo": "slskd/slskd",
|
||||||
"version": "0.24.4",
|
"version": "0.24.3",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T16:50:17Z"
|
"date": "2026-01-15T14:40:15Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "snipeit",
|
"slug": "snipeit",
|
||||||
@@ -1418,9 +1383,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "stirling-pdf",
|
"slug": "stirling-pdf",
|
||||||
"repo": "Stirling-Tools/Stirling-PDF",
|
"repo": "Stirling-Tools/Stirling-PDF",
|
||||||
"version": "v2.5.0",
|
"version": "v2.4.6",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T22:58:17Z"
|
"date": "2026-02-12T00:01:19Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "streamlink-webui",
|
"slug": "streamlink-webui",
|
||||||
@@ -1439,9 +1404,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "tandoor",
|
"slug": "tandoor",
|
||||||
"repo": "TandoorRecipes/recipes",
|
"repo": "TandoorRecipes/recipes",
|
||||||
"version": "2.5.3",
|
"version": "2.5.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-14T12:42:14Z"
|
"date": "2026-02-08T13:23:02Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "tasmoadmin",
|
"slug": "tasmoadmin",
|
||||||
@@ -1453,9 +1418,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "tautulli",
|
"slug": "tautulli",
|
||||||
"repo": "Tautulli/Tautulli",
|
"repo": "Tautulli/Tautulli",
|
||||||
"version": "v2.16.1",
|
"version": "v2.16.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T20:40:37Z"
|
"date": "2025-09-09T01:05:45Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "teddycloud",
|
"slug": "teddycloud",
|
||||||
@@ -1467,9 +1432,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "termix",
|
"slug": "termix",
|
||||||
"repo": "Termix-SSH/Termix",
|
"repo": "Termix-SSH/Termix",
|
||||||
"version": "release-1.11.1-tag",
|
"version": "release-1.11.0-tag",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T04:49:16Z"
|
"date": "2026-01-25T02:09:52Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "the-lounge",
|
"slug": "the-lounge",
|
||||||
@@ -1495,9 +1460,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "tianji",
|
"slug": "tianji",
|
||||||
"repo": "msgbyte/tianji",
|
"repo": "msgbyte/tianji",
|
||||||
"version": "v1.31.13",
|
"version": "v1.31.10",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T16:30:09Z"
|
"date": "2026-02-04T17:21:04Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "traccar",
|
"slug": "traccar",
|
||||||
@@ -1509,9 +1474,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "tracearr",
|
"slug": "tracearr",
|
||||||
"repo": "connorgallopo/Tracearr",
|
"repo": "connorgallopo/Tracearr",
|
||||||
"version": "v1.4.18",
|
"version": "v1.4.17",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T19:55:40Z"
|
"date": "2026-02-11T01:33:21Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "tracktor",
|
"slug": "tracktor",
|
||||||
@@ -1544,16 +1509,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "tududi",
|
"slug": "tududi",
|
||||||
"repo": "chrisvel/tududi",
|
"repo": "chrisvel/tududi",
|
||||||
"version": "v0.88.5",
|
"version": "v0.88.4",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T13:54:14Z"
|
"date": "2026-01-20T15:11:58Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "tunarr",
|
"slug": "tunarr",
|
||||||
"repo": "chrisbenincasa/tunarr",
|
"repo": "chrisbenincasa/tunarr",
|
||||||
"version": "v1.1.14",
|
"version": "v1.1.12",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-17T18:26:17Z"
|
"date": "2026-02-03T20:19:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "uhf",
|
"slug": "uhf",
|
||||||
@@ -1586,16 +1551,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "upsnap",
|
"slug": "upsnap",
|
||||||
"repo": "seriousm4x/UpSnap",
|
"repo": "seriousm4x/UpSnap",
|
||||||
"version": "5.2.8",
|
"version": "5.2.7",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T00:02:37Z"
|
"date": "2026-01-07T23:48:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "uptimekuma",
|
"slug": "uptimekuma",
|
||||||
"repo": "louislam/uptime-kuma",
|
"repo": "louislam/uptime-kuma",
|
||||||
"version": "2.1.1",
|
"version": "2.1.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-13T16:07:33Z"
|
"date": "2026-02-07T02:31:49Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "vaultwarden",
|
"slug": "vaultwarden",
|
||||||
@@ -1635,9 +1600,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "wanderer",
|
"slug": "wanderer",
|
||||||
"repo": "meilisearch/meilisearch",
|
"repo": "meilisearch/meilisearch",
|
||||||
"version": "v1.35.1",
|
"version": "v1.35.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T17:01:17Z"
|
"date": "2026-02-02T09:57:03Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "warracker",
|
"slug": "warracker",
|
||||||
@@ -1726,9 +1691,9 @@
|
|||||||
{
|
{
|
||||||
"slug": "yubal",
|
"slug": "yubal",
|
||||||
"repo": "guillevc/yubal",
|
"repo": "guillevc/yubal",
|
||||||
"version": "v0.6.0",
|
"version": "v0.5.0",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T17:47:56Z"
|
"date": "2026-02-09T22:11:32Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "zigbee2mqtt",
|
"slug": "zigbee2mqtt",
|
||||||
@@ -1747,16 +1712,16 @@
|
|||||||
{
|
{
|
||||||
"slug": "zitadel",
|
"slug": "zitadel",
|
||||||
"repo": "zitadel/zitadel",
|
"repo": "zitadel/zitadel",
|
||||||
"version": "v4.11.0",
|
"version": "v4.10.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-16T09:48:38Z"
|
"date": "2026-01-30T06:52:53Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "zoraxy",
|
"slug": "zoraxy",
|
||||||
"repo": "tobychui/zoraxy",
|
"repo": "tobychui/zoraxy",
|
||||||
"version": "v3.3.2-rc1",
|
"version": "v3.3.1",
|
||||||
"pinned": false,
|
"pinned": false,
|
||||||
"date": "2026-02-15T02:16:17Z"
|
"date": "2026-01-28T13:52:02Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"slug": "zwave-js-ui",
|
"slug": "zwave-js-ui",
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 1,
|
"cpu": 1,
|
||||||
"ram": 512,
|
"ram": 512,
|
||||||
"hdd": 4,
|
"hdd": 2,
|
||||||
"os": "debian",
|
"os": "debian",
|
||||||
"version": "13"
|
"version": "13"
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 1,
|
"cpu": 1,
|
||||||
"ram": 256,
|
"ram": 256,
|
||||||
"hdd": 2,
|
"hdd": 1,
|
||||||
"os": "alpine",
|
"os": "alpine",
|
||||||
"version": "3.23"
|
"version": "3.23"
|
||||||
}
|
}
|
||||||
|
|||||||
35
frontend/public/json/jellyseerr.json
Normal file
35
frontend/public/json/jellyseerr.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "Jellyseerr",
|
||||||
|
"slug": "jellyseerr",
|
||||||
|
"categories": [
|
||||||
|
14
|
||||||
|
],
|
||||||
|
"date_created": "2024-05-02",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": 5055,
|
||||||
|
"documentation": "https://docs.jellyseerr.dev/",
|
||||||
|
"website": "https://github.com/Fallenbagel/jellyseerr",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/jellyseerr.webp",
|
||||||
|
"config_path": "/etc/jellyseerr/jellyseerr.conf",
|
||||||
|
"description": "Jellyseerr is a free and open source software application for managing requests for your media library. It is a a fork of Overseerr built to bring support for Jellyfin & Emby media servers.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/jellyseerr.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 4,
|
||||||
|
"ram": 4096,
|
||||||
|
"hdd": 8,
|
||||||
|
"os": "debian",
|
||||||
|
"version": "12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": []
|
||||||
|
}
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "linkding",
|
|
||||||
"slug": "linkding",
|
|
||||||
"categories": [
|
|
||||||
12
|
|
||||||
],
|
|
||||||
"date_created": "2026-02-16",
|
|
||||||
"type": "ct",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": false,
|
|
||||||
"interface_port": 9090,
|
|
||||||
"documentation": "https://linkding.link/",
|
|
||||||
"website": "https://linkding.link/",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/linkding.webp",
|
|
||||||
"config_path": "/opt/linkding/.env",
|
|
||||||
"description": "linkding is a self-hosted bookmark manager that is designed to be minimal, fast, and easy to set up. It features a clean UI, tag-based organization, bulk editing, Markdown notes, read it later functionality, sharing, REST API, and browser extensions for Firefox and Chrome.",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "ct/linkding.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": 2,
|
|
||||||
"ram": 1024,
|
|
||||||
"hdd": 4,
|
|
||||||
"os": "Debian",
|
|
||||||
"version": "13"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": "admin",
|
|
||||||
"password": null
|
|
||||||
},
|
|
||||||
"notes": [
|
|
||||||
{
|
|
||||||
"text": "Admin credentials are stored in /opt/linkding/.env",
|
|
||||||
"type": "info"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 4,
|
"cpu": 4,
|
||||||
"ram": 4096,
|
"ram": 4096,
|
||||||
"hdd": 40,
|
"hdd": 35,
|
||||||
"os": "Ubuntu",
|
"os": "Ubuntu",
|
||||||
"version": "24.04"
|
"version": "24.04"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
},
|
},
|
||||||
"notes": [
|
"notes": [
|
||||||
{
|
{
|
||||||
"text": "Valid TLS certificates and fully-qualified domain names behind a reverse proxy (Caddy) for 3 services - OpenCloud (port: 9200), Collabora (port: 9980), and WOPI (port: 9300) are **REQUIRED**",
|
"text": "Valid TLS certificates and fully-qualified domain names behind a reverse proxy (Caddy) for 3 services - OpenCloud, Collabora, and WOPI are **REQUIRED**",
|
||||||
"type": "warning"
|
"type": "warning"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 4,
|
"cpu": 4,
|
||||||
"ram": 8192,
|
"ram": 8192,
|
||||||
"hdd": 50,
|
"hdd": 25,
|
||||||
"os": "debian",
|
"os": "debian",
|
||||||
"version": "13"
|
"version": "13"
|
||||||
}
|
}
|
||||||
|
|||||||
35
frontend/public/json/overseerr.json
Normal file
35
frontend/public/json/overseerr.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "Overseerr",
|
||||||
|
"slug": "overseerr",
|
||||||
|
"categories": [
|
||||||
|
14
|
||||||
|
],
|
||||||
|
"date_created": "2024-05-02",
|
||||||
|
"type": "ct",
|
||||||
|
"updateable": true,
|
||||||
|
"privileged": false,
|
||||||
|
"interface_port": 5055,
|
||||||
|
"documentation": "https://docs.overseerr.dev/",
|
||||||
|
"website": "https://overseerr.dev/",
|
||||||
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/overseerr.webp",
|
||||||
|
"config_path": "/opt/overseerr/config/settings.json",
|
||||||
|
"description": "Overseerr is a request management and media discovery tool built to work with your existing Plex ecosystem.",
|
||||||
|
"install_methods": [
|
||||||
|
{
|
||||||
|
"type": "default",
|
||||||
|
"script": "ct/overseerr.sh",
|
||||||
|
"resources": {
|
||||||
|
"cpu": 2,
|
||||||
|
"ram": 4096,
|
||||||
|
"hdd": 8,
|
||||||
|
"os": "debian",
|
||||||
|
"version": "13"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default_credentials": {
|
||||||
|
"username": null,
|
||||||
|
"password": null
|
||||||
|
},
|
||||||
|
"notes": []
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
"type": "ct",
|
"type": "ct",
|
||||||
"updateable": true,
|
"updateable": true,
|
||||||
"privileged": false,
|
"privileged": false,
|
||||||
"interface_port": 3000,
|
"interface_port": 3399,
|
||||||
"documentation": "https://docs.patchmon.net",
|
"documentation": "https://docs.patchmon.net",
|
||||||
"website": "https://patchmon.net",
|
"website": "https://patchmon.net",
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/patchmon.webp",
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/patchmon.webp",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
"documentation": "https://radicale.org/master.html#documentation-1",
|
"documentation": "https://radicale.org/master.html#documentation-1",
|
||||||
"website": "https://radicale.org/",
|
"website": "https://radicale.org/",
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/radicale.webp",
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/radicale.webp",
|
||||||
"config_path": "/etc/radicale/config",
|
"config_path": "/etc/radicale/config or ~/.config/radicale/config",
|
||||||
"description": "Radicale is a small but powerful CalDAV (calendars, to-do lists) and CardDAV (contacts)",
|
"description": "Radicale is a small but powerful CalDAV (calendars, to-do lists) and CardDAV (contacts)",
|
||||||
"install_methods": [
|
"install_methods": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "RomM",
|
|
||||||
"slug": "romm",
|
|
||||||
"categories": [
|
|
||||||
24
|
|
||||||
],
|
|
||||||
"date_created": "2026-02-16",
|
|
||||||
"type": "ct",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": false,
|
|
||||||
"interface_port": 80,
|
|
||||||
"documentation": "https://docs.romm.app/latest/",
|
|
||||||
"website": "https://romm.app/",
|
|
||||||
"config_path": "/opt/romm/.env",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/romm.webp",
|
|
||||||
"description": "RomM (ROM Manager) allows you to scan, enrich, browse and play your game collection with a clean and responsive interface. Support for multiple platforms, various naming schemes, and custom tags.",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "ct/romm.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": 2,
|
|
||||||
"ram": 4096,
|
|
||||||
"hdd": 20,
|
|
||||||
"os": "debian",
|
|
||||||
"version": "13"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": null,
|
|
||||||
"password": null
|
|
||||||
},
|
|
||||||
"notes": []
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "Seerr",
|
|
||||||
"slug": "seerr",
|
|
||||||
"categories": [
|
|
||||||
13
|
|
||||||
],
|
|
||||||
"date_created": "2026-02-15",
|
|
||||||
"type": "ct",
|
|
||||||
"updateable": true,
|
|
||||||
"privileged": false,
|
|
||||||
"interface_port": 5055,
|
|
||||||
"documentation": "https://docs.seerr.dev/",
|
|
||||||
"website": "https://seerr.dev/",
|
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/seerr.webp",
|
|
||||||
"config_path": "/etc/seerr/seerr.conf",
|
|
||||||
"description": "Open-source media request and discovery manager for Jellyfin, Plex, and Emby. Unified version of Overseerr and Jellyseerr.",
|
|
||||||
"install_methods": [
|
|
||||||
{
|
|
||||||
"type": "default",
|
|
||||||
"script": "ct/seerr.sh",
|
|
||||||
"resources": {
|
|
||||||
"cpu": 4,
|
|
||||||
"ram": 4096,
|
|
||||||
"hdd": 12,
|
|
||||||
"os": "Debian",
|
|
||||||
"version": "13"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default_credentials": {
|
|
||||||
"username": null,
|
|
||||||
"password": null
|
|
||||||
},
|
|
||||||
"notes": []
|
|
||||||
}
|
|
||||||
@@ -32,10 +32,6 @@
|
|||||||
"password": null
|
"password": null
|
||||||
},
|
},
|
||||||
"notes": [
|
"notes": [
|
||||||
{
|
|
||||||
"text": "SQL Server (2025) SQLPAL is incompatible with Proxmox VE 9 (Kernel 6.12+) in LXC containers. Use a VM instead or the SQL-Server 2022 LXC.",
|
|
||||||
"type": "warning"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"text": "If you choose not to run the installation setup, execute: `/opt/mssql/bin/mssql-conf setup` in LXC shell.",
|
"text": "If you choose not to run the installation setup, execute: `/opt/mssql/bin/mssql-conf setup` in LXC shell.",
|
||||||
"type": "info"
|
"type": "info"
|
||||||
|
|||||||
@@ -14,8 +14,6 @@
|
|||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/ubiquiti-unifi.webp",
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/ubiquiti-unifi.webp",
|
||||||
"config_path": "",
|
"config_path": "",
|
||||||
"description": "UniFi Network Server is a software that helps manage and monitor UniFi networks (Wi-Fi, Ethernet, etc.) by providing an intuitive user interface and advanced features. It allows network administrators to configure, monitor, and upgrade network devices, as well as view network statistics, client devices, and historical events. The aim of the application is to make the management of UniFi networks easier and more efficient.",
|
"description": "UniFi Network Server is a software that helps manage and monitor UniFi networks (Wi-Fi, Ethernet, etc.) by providing an intuitive user interface and advanced features. It allows network administrators to configure, monitor, and upgrade network devices, as well as view network statistics, client devices, and historical events. The aim of the application is to make the management of UniFi networks easier and more efficient.",
|
||||||
"disable": true,
|
|
||||||
"disable_description": "This script is disabled because UniFi no longer delivers APT packages for Debian systems. The installation relies on APT repositories that are no longer maintained or available. For more details, see: https://github.com/community-scripts/ProxmoxVE/issues/11876",
|
|
||||||
"install_methods": [
|
"install_methods": [
|
||||||
{
|
{
|
||||||
"type": "default",
|
"type": "default",
|
||||||
|
|||||||
@@ -1,40 +1,35 @@
|
|||||||
{
|
{
|
||||||
"name": "Wishlist",
|
"name": "Wishlist",
|
||||||
"slug": "wishlist",
|
"slug": "wishlist",
|
||||||
"categories": [
|
"categories": [
|
||||||
12
|
12
|
||||||
],
|
],
|
||||||
"date_created": "2026-02-04",
|
"date_created": "2026-02-04",
|
||||||
"type": "ct",
|
"type": "ct",
|
||||||
"updateable": true,
|
"updateable": true,
|
||||||
"privileged": false,
|
"privileged": false,
|
||||||
"interface_port": 3280,
|
"interface_port": 3280,
|
||||||
"documentation": "https://github.com/cmintey/wishlist/blob/main/README.md#getting-started",
|
"documentation": "https://github.com/cmintey/wishlist/blob/main/README.md#getting-started",
|
||||||
"website": "https://github.com/cmintey/wishlist",
|
"config_path": "/opt/wishlist/.env",
|
||||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/cmintey-wishlist.webp",
|
"website": "https://github.com/cmintey/wishlist",
|
||||||
"config_path": "/opt/wishlist/.env",
|
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/cmintey-wishlist.webp",
|
||||||
"description": "Wishlist is a self-hosted wishlist application that you can share with your friends and family. You no longer have to wonder what to get your family for the holidays, simply check their wishlist and claim any available item!",
|
"description": "Wishlist is a self-hosted wishlist application that you can share with your friends and family. You no longer have to wonder what to get your family for the holidays, simply check their wishlist and claim any available item!",
|
||||||
"install_methods": [
|
"install_methods": [
|
||||||
{
|
{
|
||||||
"type": "default",
|
"type": "default",
|
||||||
"script": "ct/wishlist.sh",
|
"script": "ct/wishlist.sh",
|
||||||
"resources": {
|
"resources": {
|
||||||
"cpu": 2,
|
"cpu": 2,
|
||||||
"ram": 2048,
|
"ram": 2048,
|
||||||
"hdd": 5,
|
"hdd": 5,
|
||||||
"os": "Debian",
|
"os": "Debian",
|
||||||
"version": "13"
|
"version": "13"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"default_credentials": {
|
"default_credentials": {
|
||||||
"username": null,
|
"username": null,
|
||||||
"password": null
|
"password": null
|
||||||
},
|
},
|
||||||
"notes": [
|
"notes": []
|
||||||
{
|
|
||||||
"text": "When using a reverse proxy with this script, please edit the`ORIGIN` value in `/opt/wishlist/.env` to point to your new URL, otherwise creating an admin account or logging in will not work.",
|
|
||||||
"type": "info"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ $STD apk add --no-cache \
|
|||||||
libc6-compat
|
libc6-compat
|
||||||
msg_ok "Installed dependencies"
|
msg_ok "Installed dependencies"
|
||||||
|
|
||||||
RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9.]*[0-9]\).*/\1/p' | awk 'NR==1')
|
RELEASE=$(curl -fsSL https://teamspeak.com/en/downloads/#server | sed -n 's/.*teamspeak3-server_linux_amd64-\([0-9.]*[0-9]\).*/\1/p' | head -1)
|
||||||
msg_info "Installing Teamspeak Server v${RELEASE}"
|
msg_info "Installing Teamspeak Server v${RELEASE}"
|
||||||
mkdir -p /opt/teamspeak-server
|
mkdir -p /opt/teamspeak-server
|
||||||
cd /opt/teamspeak-server
|
cd /opt/teamspeak-server
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ msg_info "Setup CryptPad"
|
|||||||
cd /opt/cryptpad
|
cd /opt/cryptpad
|
||||||
$STD npm ci
|
$STD npm ci
|
||||||
$STD npm run install:components
|
$STD npm run install:components
|
||||||
if [[ "$onlyoffice" =~ ^[Yy]$ ]]; then
|
$STD npm run build
|
||||||
$STD bash -c "./install-onlyoffice.sh --accept-license"
|
|
||||||
fi
|
|
||||||
cp config/config.example.js config/config.js
|
cp config/config.example.js config/config.js
|
||||||
sed -i "51s/localhost/${LOCAL_IP}/g" /opt/cryptpad/config/config.js
|
sed -i "51s/localhost/${LOCAL_IP}/g" /opt/cryptpad/config/config.js
|
||||||
sed -i "80s#//httpAddress: 'localhost'#httpAddress: '0.0.0.0'#g" /opt/cryptpad/config/config.js
|
sed -i "80s#//httpAddress: 'localhost'#httpAddress: '0.0.0.0'#g" /opt/cryptpad/config/config.js
|
||||||
$STD npm run build
|
if [[ "$onlyoffice" =~ ^[Yy]$ ]]; then
|
||||||
|
$STD bash -c "./install-onlyoffice.sh --accept-license"
|
||||||
|
fi
|
||||||
msg_ok "Setup CryptPad"
|
msg_ok "Setup CryptPad"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
|
|||||||
@@ -1,171 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/databasus/databasus
|
|
||||||
|
|
||||||
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 \
|
|
||||||
valkey
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
PG_VERSION="17" setup_postgresql
|
|
||||||
setup_go
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "databasus" "databasus/databasus" "tarball" "latest" "/opt/databasus"
|
|
||||||
|
|
||||||
msg_info "Building Databasus (Patience)"
|
|
||||||
cd /opt/databasus/frontend
|
|
||||||
$STD npm ci
|
|
||||||
$STD npm run build
|
|
||||||
cd /opt/databasus/backend
|
|
||||||
$STD go mod tidy
|
|
||||||
$STD go mod download
|
|
||||||
$STD go install github.com/swaggo/swag/cmd/swag@latest
|
|
||||||
$STD /root/go/bin/swag init -g cmd/main.go -o swagger
|
|
||||||
$STD env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o databasus ./cmd/main.go
|
|
||||||
mv /opt/databasus/backend/databasus /opt/databasus/databasus
|
|
||||||
mkdir -p /databasus-data/{pgdata,temp,backups,data,logs}
|
|
||||||
mkdir -p /opt/databasus/ui/build
|
|
||||||
mkdir -p /opt/databasus/migrations
|
|
||||||
cp -r /opt/databasus/frontend/dist/* /opt/databasus/ui/build/
|
|
||||||
cp -r /opt/databasus/backend/migrations/* /opt/databasus/migrations/
|
|
||||||
chown -R postgres:postgres /databasus-data
|
|
||||||
msg_ok "Built Databasus"
|
|
||||||
|
|
||||||
msg_info "Configuring Databasus"
|
|
||||||
JWT_SECRET=$(openssl rand -hex 32)
|
|
||||||
ENCRYPTION_KEY=$(openssl rand -hex 32)
|
|
||||||
# Create PostgreSQL version symlinks for compatibility
|
|
||||||
for v in 12 13 14 15 16 18; do
|
|
||||||
ln -sf /usr/lib/postgresql/17 /usr/lib/postgresql/$v
|
|
||||||
done
|
|
||||||
# Install goose for migrations
|
|
||||||
$STD go install github.com/pressly/goose/v3/cmd/goose@latest
|
|
||||||
ln -sf /root/go/bin/goose /usr/local/bin/goose
|
|
||||||
cat <<EOF >/opt/databasus/.env
|
|
||||||
# Environment
|
|
||||||
ENV_MODE=production
|
|
||||||
|
|
||||||
# Server
|
|
||||||
SERVER_PORT=4005
|
|
||||||
SERVER_HOST=0.0.0.0
|
|
||||||
|
|
||||||
# Database
|
|
||||||
DATABASE_DSN=host=localhost user=postgres password=postgres dbname=databasus port=5432 sslmode=disable
|
|
||||||
DATABASE_URL=postgres://postgres:postgres@localhost:5432/databasus?sslmode=disable
|
|
||||||
|
|
||||||
# Migrations
|
|
||||||
GOOSE_DRIVER=postgres
|
|
||||||
GOOSE_DBSTRING=postgres://postgres:postgres@localhost:5432/databasus?sslmode=disable
|
|
||||||
GOOSE_MIGRATION_DIR=/opt/databasus/migrations
|
|
||||||
|
|
||||||
# Valkey (Redis-compatible cache)
|
|
||||||
VALKEY_HOST=localhost
|
|
||||||
VALKEY_PORT=6379
|
|
||||||
|
|
||||||
# Security
|
|
||||||
JWT_SECRET=${JWT_SECRET}
|
|
||||||
ENCRYPTION_KEY=${ENCRYPTION_KEY}
|
|
||||||
|
|
||||||
# Paths
|
|
||||||
DATA_DIR=/databasus-data/data
|
|
||||||
BACKUP_DIR=/databasus-data/backups
|
|
||||||
LOG_DIR=/databasus-data/logs
|
|
||||||
EOF
|
|
||||||
chown postgres:postgres /opt/databasus/.env
|
|
||||||
chmod 600 /opt/databasus/.env
|
|
||||||
msg_ok "Configured Databasus"
|
|
||||||
|
|
||||||
msg_info "Configuring Valkey"
|
|
||||||
cat <<EOF >/etc/valkey/valkey.conf
|
|
||||||
port 6379
|
|
||||||
bind 127.0.0.1
|
|
||||||
protected-mode yes
|
|
||||||
save ""
|
|
||||||
maxmemory 256mb
|
|
||||||
maxmemory-policy allkeys-lru
|
|
||||||
EOF
|
|
||||||
systemctl enable -q --now valkey-server
|
|
||||||
systemctl restart valkey-server
|
|
||||||
msg_ok "Configured Valkey"
|
|
||||||
|
|
||||||
msg_info "Creating Database"
|
|
||||||
# Configure PostgreSQL to allow local password auth for databasus
|
|
||||||
PG_HBA="/etc/postgresql/17/main/pg_hba.conf"
|
|
||||||
if ! grep -q "databasus" "$PG_HBA"; then
|
|
||||||
sed -i '/^local\s*all\s*all/i local databasus postgres trust' "$PG_HBA"
|
|
||||||
sed -i '/^host\s*all\s*all\s*127/i host databasus postgres 127.0.0.1/32 trust' "$PG_HBA"
|
|
||||||
systemctl reload postgresql
|
|
||||||
fi
|
|
||||||
$STD sudo -u postgres psql -c "CREATE DATABASE databasus;" 2>/dev/null || true
|
|
||||||
$STD sudo -u postgres psql -c "ALTER USER postgres WITH SUPERUSER CREATEROLE CREATEDB;" 2>/dev/null || true
|
|
||||||
msg_ok "Created Database"
|
|
||||||
|
|
||||||
msg_info "Creating Databasus Service"
|
|
||||||
cat <<EOF >/etc/systemd/system/databasus.service
|
|
||||||
[Unit]
|
|
||||||
Description=Databasus - Database Backup Management
|
|
||||||
After=network.target postgresql.service valkey.service
|
|
||||||
Requires=postgresql.service valkey.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
WorkingDirectory=/opt/databasus
|
|
||||||
EnvironmentFile=/opt/databasus/.env
|
|
||||||
ExecStart=/opt/databasus/databasus
|
|
||||||
Restart=always
|
|
||||||
RestartSec=5
|
|
||||||
StandardOutput=journal
|
|
||||||
StandardError=journal
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
$STD systemctl daemon-reload
|
|
||||||
$STD systemctl enable -q --now databasus
|
|
||||||
msg_ok "Created Databasus Service"
|
|
||||||
|
|
||||||
msg_info "Configuring Nginx"
|
|
||||||
cat <<EOF >/etc/nginx/sites-available/databasus
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:4005;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade \$http_upgrade;
|
|
||||||
proxy_set_header Connection 'upgrade';
|
|
||||||
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_cache_bypass \$http_upgrade;
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_read_timeout 86400s;
|
|
||||||
proxy_send_timeout 86400s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
ln -sf /etc/nginx/sites-available/databasus /etc/nginx/sites-enabled/databasus
|
|
||||||
rm -f /etc/nginx/sites-enabled/default
|
|
||||||
$STD nginx -t
|
|
||||||
$STD systemctl enable -q --now nginx
|
|
||||||
$STD systemctl reload nginx
|
|
||||||
msg_ok "Configured Nginx"
|
|
||||||
|
|
||||||
motd_ssh
|
|
||||||
customize
|
|
||||||
cleanup_lxc
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: Joerg Heinemann (heinemannj)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://github.com/john30/ebusd
|
|
||||||
|
|
||||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
|
||||||
color
|
|
||||||
verb_ip6
|
|
||||||
catch_errors
|
|
||||||
setting_up_container
|
|
||||||
network_check
|
|
||||||
update_os
|
|
||||||
|
|
||||||
msg_info "Installing ebusd"
|
|
||||||
fetch_and_deploy_gh_release "ebusd" "john30/ebusd" "binary" "latest" "" "ebusd-*_amd64-trixie_mqtt1.deb"
|
|
||||||
systemctl enable -q ebusd
|
|
||||||
msg_ok "Installed ebusd"
|
|
||||||
|
|
||||||
motd_ssh
|
|
||||||
customize
|
|
||||||
cleanup_lxc
|
|
||||||
@@ -38,18 +38,6 @@ rm -f "$DEB_FILE"
|
|||||||
echo "$LATEST_VERSION" >~/.emqx
|
echo "$LATEST_VERSION" >~/.emqx
|
||||||
msg_ok "Installed EMQX"
|
msg_ok "Installed EMQX"
|
||||||
|
|
||||||
read -r -p "${TAB3}Would you like to disable the EMQX MQ feature? (reduces disk/CPU usage) <y/N> " prompt
|
|
||||||
if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_info "Disabling EMQX MQ feature"
|
|
||||||
mkdir -p /etc/emqx
|
|
||||||
if ! grep -q "^mq.enable" /etc/emqx/emqx.conf 2>/dev/null; then
|
|
||||||
echo "mq.enable = false" >>/etc/emqx/emqx.conf
|
|
||||||
else
|
|
||||||
sed -i 's/^mq.enable.*/mq.enable = false/' /etc/emqx/emqx.conf
|
|
||||||
fi
|
|
||||||
msg_ok "Disabled EMQX MQ feature"
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Starting EMQX service"
|
msg_info "Starting EMQX service"
|
||||||
$STD systemctl enable -q --now emqx
|
$STD systemctl enable -q --now emqx
|
||||||
msg_ok "Enabled EMQX service"
|
msg_ok "Enabled EMQX service"
|
||||||
|
|||||||
64
install/jellyseerr-install.sh
Normal file
64
install/jellyseerr-install.sh
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 tteck
|
||||||
|
# Author: tteck (tteckster)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://docs.jellyseerr.dev/
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt-get install -y \
|
||||||
|
git \
|
||||||
|
build-essential
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
git clone -q https://github.com/Fallenbagel/jellyseerr.git /opt/jellyseerr
|
||||||
|
cd /opt/jellyseerr
|
||||||
|
$STD git checkout main
|
||||||
|
|
||||||
|
pnpm_desired=$(grep -Po '"pnpm":\s*"\K[^"]+' /opt/jellyseerr/package.json)
|
||||||
|
NODE_VERSION="22" NODE_MODULE="pnpm@$pnpm_desired" setup_nodejs
|
||||||
|
|
||||||
|
msg_info "Installing Jellyseerr (Patience)"
|
||||||
|
export CYPRESS_INSTALL_BINARY=0
|
||||||
|
cd /opt/jellyseerr
|
||||||
|
$STD pnpm install --frozen-lockfile
|
||||||
|
export NODE_OPTIONS="--max-old-space-size=3072"
|
||||||
|
$STD pnpm build
|
||||||
|
mkdir -p /etc/jellyseerr/
|
||||||
|
cat <<EOF >/etc/jellyseerr/jellyseerr.conf
|
||||||
|
PORT=5055
|
||||||
|
# HOST=0.0.0.0
|
||||||
|
# JELLYFIN_TYPE=emby
|
||||||
|
EOF
|
||||||
|
msg_ok "Installed Jellyseerr"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/jellyseerr.service
|
||||||
|
[Unit]
|
||||||
|
Description=jellyseerr Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
EnvironmentFile=/etc/jellyseerr/jellyseerr.conf
|
||||||
|
Environment=NODE_ENV=production
|
||||||
|
Type=exec
|
||||||
|
WorkingDirectory=/opt/jellyseerr
|
||||||
|
ExecStart=/usr/bin/node dist/index.js
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now jellyseerr
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (MickLesk)
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://linkding.link/
|
|
||||||
|
|
||||||
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 \
|
|
||||||
pkg-config \
|
|
||||||
python3-dev \
|
|
||||||
nginx \
|
|
||||||
libpq-dev \
|
|
||||||
libicu-dev \
|
|
||||||
libsqlite3-dev \
|
|
||||||
libffi-dev
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
NODE_VERSION="22" setup_nodejs
|
|
||||||
setup_uv
|
|
||||||
fetch_and_deploy_gh_release "linkding" "sissbruecker/linkding"
|
|
||||||
|
|
||||||
msg_info "Building Frontend"
|
|
||||||
cd /opt/linkding
|
|
||||||
$STD npm ci
|
|
||||||
$STD npm run build
|
|
||||||
ln -sf /usr/lib/x86_64-linux-gnu/mod_icu.so /opt/linkding/libicu.so
|
|
||||||
msg_ok "Built Frontend"
|
|
||||||
|
|
||||||
msg_info "Setting up LinkDing"
|
|
||||||
rm -f bookmarks/settings/dev.py
|
|
||||||
touch bookmarks/settings/custom.py
|
|
||||||
$STD uv sync --no-dev --frozen
|
|
||||||
$STD uv pip install gunicorn
|
|
||||||
mkdir -p data/{favicons,previews,assets}
|
|
||||||
ADMIN_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
|
|
||||||
cat <<EOF >/opt/linkding/.env
|
|
||||||
LD_SUPERUSER_NAME=admin
|
|
||||||
LD_SUPERUSER_PASSWORD=${ADMIN_PASS}
|
|
||||||
LD_CSRF_TRUSTED_ORIGINS=http://${LOCAL_IP}:9090
|
|
||||||
EOF
|
|
||||||
set -a && source /opt/linkding/.env && set +a
|
|
||||||
$STD /opt/linkding/.venv/bin/python manage.py generate_secret_key
|
|
||||||
$STD /opt/linkding/.venv/bin/python manage.py migrate
|
|
||||||
$STD /opt/linkding/.venv/bin/python manage.py enable_wal
|
|
||||||
$STD /opt/linkding/.venv/bin/python manage.py create_initial_superuser
|
|
||||||
$STD /opt/linkding/.venv/bin/python manage.py collectstatic --no-input
|
|
||||||
msg_ok "Set up LinkDing"
|
|
||||||
|
|
||||||
msg_info "Creating Services"
|
|
||||||
cat <<EOF >/etc/systemd/system/linkding.service
|
|
||||||
[Unit]
|
|
||||||
Description=linkding Bookmark Manager
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
User=root
|
|
||||||
WorkingDirectory=/opt/linkding
|
|
||||||
EnvironmentFile=/opt/linkding/.env
|
|
||||||
ExecStart=/opt/linkding/.venv/bin/gunicorn \
|
|
||||||
--bind 127.0.0.1:8000 \
|
|
||||||
--workers 3 \
|
|
||||||
--threads 2 \
|
|
||||||
--timeout 120 \
|
|
||||||
bookmarks.wsgi:application
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
cat <<EOF >/etc/systemd/system/linkding-tasks.service
|
|
||||||
[Unit]
|
|
||||||
Description=linkding Background Tasks
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
User=root
|
|
||||||
WorkingDirectory=/opt/linkding
|
|
||||||
EnvironmentFile=/opt/linkding/.env
|
|
||||||
ExecStart=/opt/linkding/.venv/bin/python manage.py run_huey
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
cat <<'EOF' >/etc/nginx/sites-available/linkding
|
|
||||||
server {
|
|
||||||
listen 9090;
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
client_max_body_size 20M;
|
|
||||||
|
|
||||||
location /static/ {
|
|
||||||
alias /opt/linkding/static/;
|
|
||||||
expires 30d;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:8000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
$STD rm -f /etc/nginx/sites-enabled/default
|
|
||||||
$STD ln -sf /etc/nginx/sites-available/linkding /etc/nginx/sites-enabled/linkding
|
|
||||||
systemctl enable -q --now nginx linkding linkding-tasks
|
|
||||||
systemctl restart nginx
|
|
||||||
msg_ok "Created Services"
|
|
||||||
|
|
||||||
motd_ssh
|
|
||||||
customize
|
|
||||||
cleanup_lxc
|
|
||||||
@@ -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" "v5.1.0" "/usr/bin" "opencloud-*-linux-amd64"
|
fetch_and_deploy_gh_release "opencloud" "opencloud-eu/opencloud" "singlefile" "v5.0.2" "/usr/bin" "opencloud-*-linux-amd64"
|
||||||
|
|
||||||
msg_info "Configuring OpenCloud"
|
msg_info "Configuring OpenCloud"
|
||||||
DATA_DIR="/var/lib/opencloud"
|
DATA_DIR="/var/lib/opencloud"
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ setup_hwaccel
|
|||||||
PYTHON_VERSION="3.12" setup_uv
|
PYTHON_VERSION="3.12" setup_uv
|
||||||
|
|
||||||
msg_info "Installing Open WebUI"
|
msg_info "Installing Open WebUI"
|
||||||
$STD uv tool install --python 3.12 --constraint <(echo "numba>=0.60") open-webui[all]
|
$STD uv tool install --python 3.12 open-webui[all]
|
||||||
msg_ok "Installed Open WebUI"
|
msg_ok "Installed Open WebUI"
|
||||||
|
|
||||||
read -r -p "${TAB3}Would you like to add Ollama? <y/N> " prompt
|
read -r -p "${TAB3}Would you like to add Ollama? <y/N> " prompt
|
||||||
|
|||||||
44
install/overseerr-install.sh
Normal file
44
install/overseerr-install.sh
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 tteck
|
||||||
|
# Author: tteck (tteckster)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://overseerr.dev/
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
NODE_VERSION="22" NODE_MODULE="yarn@latest" setup_nodejs
|
||||||
|
fetch_and_deploy_gh_release "overseerr" "sct/overseerr" "tarball"
|
||||||
|
|
||||||
|
msg_info "Configuring Overseerr (Patience)"
|
||||||
|
cd /opt/overseerr
|
||||||
|
$STD yarn install
|
||||||
|
$STD yarn build
|
||||||
|
msg_ok "Configured Overseerr"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/overseerr.service
|
||||||
|
[Unit]
|
||||||
|
Description=Overseerr Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=exec
|
||||||
|
WorkingDirectory=/opt/overseerr
|
||||||
|
ExecStart=/usr/bin/yarn start
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now overseerr
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -36,7 +36,7 @@ $STD npm ci
|
|||||||
$STD npm run set:sqlite
|
$STD npm run set:sqlite
|
||||||
$STD npm run set:oss
|
$STD npm run set:oss
|
||||||
rm -rf server/private
|
rm -rf server/private
|
||||||
$STD npm run db:generate
|
$STD npm run db:sqlite: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 ./
|
||||||
@@ -178,7 +178,7 @@ http:
|
|||||||
servers:
|
servers:
|
||||||
- url: "http://$LOCAL_IP:3000"
|
- url: "http://$LOCAL_IP:3000"
|
||||||
EOF
|
EOF
|
||||||
$STD npm run db:push
|
$STD npm run db:sqlite:push
|
||||||
|
|
||||||
. /etc/os-release
|
. /etc/os-release
|
||||||
if [ "$VERSION_CODENAME" = "trixie" ]; then
|
if [ "$VERSION_CODENAME" = "trixie" ]; then
|
||||||
|
|||||||
@@ -27,42 +27,162 @@ PG_DB_NAME="patchmon_db" PG_DB_USER="patchmon_usr" setup_postgresql_db
|
|||||||
fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "latest" "/opt/patchmon"
|
fetch_and_deploy_gh_release "PatchMon" "PatchMon/PatchMon" "tarball" "latest" "/opt/patchmon"
|
||||||
|
|
||||||
msg_info "Configuring PatchMon"
|
msg_info "Configuring PatchMon"
|
||||||
VERSION=$(get_latest_github_release "PatchMon/PatchMon")
|
|
||||||
export NODE_ENV=production
|
|
||||||
cd /opt/patchmon
|
cd /opt/patchmon
|
||||||
|
export NODE_ENV=production
|
||||||
|
$STD npm install --no-audit --no-fund --no-save --ignore-scripts
|
||||||
|
cd /opt/patchmon/backend
|
||||||
$STD npm install --no-audit --no-fund --no-save --ignore-scripts
|
$STD npm install --no-audit --no-fund --no-save --ignore-scripts
|
||||||
|
|
||||||
cd /opt/patchmon/frontend
|
cd /opt/patchmon/frontend
|
||||||
cat <<EOF >./.env
|
$STD npm install --include=dev --no-audit --no-fund --no-save --ignore-scripts
|
||||||
VITE_API_URL=http://${LOCAL_IP}:3001/api/v1
|
|
||||||
VITE_APP_NAME=PatchMon
|
|
||||||
VITE_APP_VERSION=${VERSION}
|
|
||||||
EOF
|
|
||||||
$STD npm install --no-audit --no-fund --no-save --ignore-scripts --include=dev
|
|
||||||
$STD npm run build
|
$STD npm run build
|
||||||
|
JWT_SECRET="$(openssl rand -base64 64 | tr -d "=+/" | cut -c1-50)"
|
||||||
|
cat <<EOF >/opt/patchmon/backend/.env
|
||||||
|
# Database Configuration
|
||||||
|
DATABASE_URL="postgresql://$PG_DB_USER:$PG_DB_PASS@localhost:5432/$PG_DB_NAME"
|
||||||
|
PY_THRESHOLD=3M_DB_CONN_MAX_ATTEMPTS=30
|
||||||
|
PM_DB_CONN_WAIT_INTERVAL=2
|
||||||
|
|
||||||
JWT_SECRET="$(openssl rand -hex 64)"
|
# JWT Configuration
|
||||||
mv /opt/patchmon/backend/env.example /opt/patchmon/backend/.env
|
JWT_SECRET="$JWT_SECRET"
|
||||||
sed -i -e "s|DATABASE_URL=.*|DATABASE_URL=\"postgresql://$PG_DB_USER:$PG_DB_PASS@localhost:5432/$PG_DB_NAME\"|" \
|
JWT_EXPIRES_IN=1h
|
||||||
-e "/JWT_SECRET/s/[=$].*/=$JWT_SECRET/" \
|
JWT_REFRESH_EXPIRES_IN=7d
|
||||||
-e "\|CORS_ORIGIN|s|localhost|$LOCAL_IP|" \
|
|
||||||
-e "/PORT=3001/aSERVER_PROTOCOL=http \\
|
# Server Configuration
|
||||||
SERVER_HOST=$LOCAL_IP \\
|
PORT=3399
|
||||||
SERVER_PORT=3000" \
|
NODE_ENV=production
|
||||||
-e '/_ENV=production/aTRUST_PROXY=1' \
|
|
||||||
-e '/REDIS_USER=.*/,+1d' /opt/patchmon/backend/.env
|
# API Configuration
|
||||||
|
API_VERSION=v1
|
||||||
|
|
||||||
|
# CORS Configuration
|
||||||
|
CORS_ORIGIN="http://$LOCAL_IP"
|
||||||
|
|
||||||
|
# Session Configuration
|
||||||
|
SESSION_INACTIVITY_TIMEOUT_MINUTES=30
|
||||||
|
|
||||||
|
# User Configuration
|
||||||
|
DEFAULT_USER_ROLE=user
|
||||||
|
|
||||||
|
# Rate Limiting (times in milliseconds)
|
||||||
|
RATE_LIMIT_WINDOW_MS=900000
|
||||||
|
RATE_LIMIT_MAX=5000
|
||||||
|
AUTH_RATE_LIMIT_WINDOW_MS=600000
|
||||||
|
AUTH_RATE_LIMIT_MAX=500
|
||||||
|
AGENT_RATE_LIMIT_WINDOW_MS=60000
|
||||||
|
AGENT_RATE_LIMIT_MAX=1000
|
||||||
|
|
||||||
|
# Redis Configuration
|
||||||
|
REDIS_HOST=localhost
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
LOG_LEVEL=info
|
||||||
|
ENABLE_LOGGING=true
|
||||||
|
|
||||||
|
# TFA Configuration
|
||||||
|
TFA_REMEMBER_ME_EXPIRES_IN=30d
|
||||||
|
TFA_MAX_REMEMBER_SESSIONS=5
|
||||||
|
TFA_SUSPICIOUS_ACTIVITY_THRESHOLD=3
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<EOF >/opt/patchmon/frontend/.env
|
||||||
|
VITE_API_URL=http://$LOCAL_IP/api/v1
|
||||||
|
VITE_APP_NAME=PatchMon
|
||||||
|
VITE_APP_VERSION=1.3.0
|
||||||
|
EOF
|
||||||
|
|
||||||
cd /opt/patchmon/backend
|
cd /opt/patchmon/backend
|
||||||
$STD npm run db:generate
|
|
||||||
$STD npx prisma migrate deploy
|
$STD npx prisma migrate deploy
|
||||||
|
$STD npx prisma generate
|
||||||
msg_ok "Configured PatchMon"
|
msg_ok "Configured PatchMon"
|
||||||
|
|
||||||
msg_info "Configuring Nginx"
|
msg_info "Configuring Nginx"
|
||||||
cp /opt/patchmon/docker/nginx.conf.template /etc/nginx/sites-available/patchmon.conf
|
cat <<EOF >/etc/nginx/sites-available/patchmon.conf
|
||||||
sed -i -e 's|proxy_pass .*|proxy_pass http://127.0.0.1:3001;|' \
|
map \$http_x_forwarded_proto \$proxy_corrected_scheme {
|
||||||
-e '\|try_files |i\ root /opt/patchmon/frontend/dist;' \
|
default \$scheme; # Fallback to Nginx's actual connection scheme if no X-Forwarded-Proto header was set
|
||||||
-e 's|alias.*|alias /opt/patchmon/frontend/dist/assets;|' \
|
https https; # If X-Forwarded-Proto is 'https', use 'https'
|
||||||
-e '\|expires 1y|i\ root /opt/patchmon/frontend/dist;' /etc/nginx/sites-available/patchmon.conf
|
http http; # If X-Forwarded-Proto is 'http', use 'http'
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
# Listen on both IPv4 and IPv6 (with all hostnames)
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Frame-Options DENY always;
|
||||||
|
add_header X-Content-Type-Options nosniff always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||||
|
|
||||||
|
# Frontend
|
||||||
|
location / {
|
||||||
|
root /opt/patchmon/frontend/dist;
|
||||||
|
try_files \$uri \$uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Bull Board proxy
|
||||||
|
location /bullboard {
|
||||||
|
proxy_pass http://127.0.0.1:3399;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade \$http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
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 \$proxy_corrected_scheme;
|
||||||
|
proxy_set_header X-Forwarded-Host \$host;
|
||||||
|
proxy_set_header Cookie \$http_cookie;
|
||||||
|
proxy_cache_bypass \$http_upgrade;
|
||||||
|
proxy_read_timeout 300s;
|
||||||
|
proxy_connect_timeout 75s;
|
||||||
|
|
||||||
|
# Enable cookie passthrough
|
||||||
|
proxy_pass_header Set-Cookie;
|
||||||
|
proxy_cookie_path / /;
|
||||||
|
|
||||||
|
# Preserve original client IP
|
||||||
|
proxy_set_header X-Original-Forwarded-For \$http_x_forwarded_for;
|
||||||
|
if (\$request_method = 'OPTIONS') {
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# API proxy
|
||||||
|
location /api/ {
|
||||||
|
proxy_pass http://127.0.0.1:3399;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade \$http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
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 \$proxy_corrected_scheme;
|
||||||
|
proxy_cache_bypass \$http_upgrade;
|
||||||
|
proxy_read_timeout 300s;
|
||||||
|
proxy_connect_timeout 75s;
|
||||||
|
|
||||||
|
# Preserve original client IP
|
||||||
|
proxy_set_header X-Original-Forwarded-For \$http_x_forwarded_for;
|
||||||
|
if (\$request_method = 'OPTIONS') {
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Static assets caching (exclude Bull Board assets)
|
||||||
|
location ~* ^/(?!bullboard).*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||||
|
root /opt/patchmon/frontend/dist;
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /health {
|
||||||
|
proxy_pass http://127.0.0.1:3399/health;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
ln -sf /etc/nginx/sites-available/patchmon.conf /etc/nginx/sites-enabled/
|
ln -sf /etc/nginx/sites-available/patchmon.conf /etc/nginx/sites-enabled/
|
||||||
rm -f /etc/nginx/sites-enabled/default
|
rm -f /etc/nginx/sites-enabled/default
|
||||||
$STD nginx -t
|
$STD nginx -t
|
||||||
@@ -78,7 +198,7 @@ After=network.target postgresql.service
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
WorkingDirectory=/opt/patchmon/backend
|
WorkingDirectory=/opt/patchmon/backend
|
||||||
ExecStart=/usr/bin/npm run start
|
ExecStart=/usr/bin/node src/server.js
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=10
|
RestartSec=10
|
||||||
Environment=NODE_ENV=production
|
Environment=NODE_ENV=production
|
||||||
@@ -95,6 +215,57 @@ EOF
|
|||||||
systemctl enable -q --now patchmon-server
|
systemctl enable -q --now patchmon-server
|
||||||
msg_ok "Created and started service"
|
msg_ok "Created and started service"
|
||||||
|
|
||||||
|
msg_info "Updating settings"
|
||||||
|
cat <<EOF >/opt/patchmon/backend/update-settings.js
|
||||||
|
const { PrismaClient } = require('@prisma/client');
|
||||||
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
async function updateSettings() {
|
||||||
|
try {
|
||||||
|
const existingSettings = await prisma.settings.findFirst();
|
||||||
|
|
||||||
|
const settingsData = {
|
||||||
|
id: uuidv4(),
|
||||||
|
server_url: 'http://$LOCAL_IP',
|
||||||
|
server_protocol: 'http',
|
||||||
|
server_host: '$LOCAL_IP',
|
||||||
|
server_port: 3399,
|
||||||
|
update_interval: 60,
|
||||||
|
auto_update: true,
|
||||||
|
signup_enabled: false,
|
||||||
|
ignore_ssl_self_signed: false,
|
||||||
|
updated_at: new Date()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (existingSettings) {
|
||||||
|
// Update existing settings
|
||||||
|
await prisma.settings.update({
|
||||||
|
where: { id: existingSettings.id },
|
||||||
|
data: settingsData
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Create new settings record
|
||||||
|
await prisma.settings.create({
|
||||||
|
data: settingsData
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('✅ Database settings updated successfully');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Error updating settings:', error.message);
|
||||||
|
process.exit(1);
|
||||||
|
} finally {
|
||||||
|
await prisma.\$disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSettings();
|
||||||
|
EOF
|
||||||
|
cd /opt/patchmon/backend
|
||||||
|
$STD node update-settings.js
|
||||||
|
msg_ok "Settings updated successfully"
|
||||||
|
|
||||||
motd_ssh
|
motd_ssh
|
||||||
customize
|
customize
|
||||||
cleanup_lxc
|
cleanup_lxc
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ $STD php artisan p:user:make --no-interaction --admin=1 --email "$ADMIN_EMAIL" -
|
|||||||
echo "* * * * * php /opt/pterodactyl-panel/artisan schedule:run >> /dev/null 2>&1" | crontab -u www-data -
|
echo "* * * * * php /opt/pterodactyl-panel/artisan schedule:run >> /dev/null 2>&1" | crontab -u www-data -
|
||||||
chown -R www-data:www-data /opt/pterodactyl-panel/*
|
chown -R www-data:www-data /opt/pterodactyl-panel/*
|
||||||
chmod -R 755 /opt/pterodactyl-panel/storage/* /opt/pterodactyl-panel/bootstrap/cache/
|
chmod -R 755 /opt/pterodactyl-panel/storage/* /opt/pterodactyl-panel/bootstrap/cache/
|
||||||
ln -s /opt/pterodactyl-panel /var/www/pterodactyl
|
|
||||||
{
|
{
|
||||||
echo ""
|
echo ""
|
||||||
echo "pterodactyl Admin Username: admin"
|
echo "pterodactyl Admin Username: admin"
|
||||||
|
|||||||
@@ -14,51 +14,42 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y apache2-utils
|
$STD apt install -y \
|
||||||
|
apache2-utils \
|
||||||
|
python3-pip \
|
||||||
|
python3-venv
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
PYTHON_VERSION="3.13" setup_uv
|
|
||||||
fetch_and_deploy_gh_release "Radicale" "Kozea/Radicale" "tarball" "latest" "/opt/radicale"
|
|
||||||
|
|
||||||
msg_info "Setting up Radicale"
|
msg_info "Setting up Radicale"
|
||||||
cd /opt/radicale
|
python3 -m venv /opt/radicale
|
||||||
|
source /opt/radicale/bin/activate
|
||||||
|
$STD python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
|
||||||
RNDPASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
RNDPASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||||
$STD htpasswd -c -b -5 /opt/radicale/users admin "$RNDPASS"
|
$STD htpasswd -c -b -5 /opt/radicale/users admin $RNDPASS
|
||||||
{
|
{
|
||||||
echo "Radicale Credentials"
|
echo "Radicale Credentials"
|
||||||
echo "Admin User: admin"
|
echo "Admin User: admin"
|
||||||
echo "Admin Password: $RNDPASS"
|
echo "Admin Password: $RNDPASS"
|
||||||
} >>~/radicale.creds
|
} >>~/radicale.creds
|
||||||
|
msg_ok "Done setting up Radicale"
|
||||||
|
|
||||||
mkdir -p /etc/radicale
|
msg_info "Setup Service"
|
||||||
cat <<EOF >/etc/radicale/config
|
|
||||||
[server]
|
|
||||||
hosts = 0.0.0.0:5232
|
|
||||||
|
|
||||||
[auth]
|
cat <<EOF >/opt/radicale/start.sh
|
||||||
type = htpasswd
|
#!/usr/bin/env bash
|
||||||
htpasswd_filename = /opt/radicale/users
|
source /opt/radicale/bin/activate
|
||||||
htpasswd_encryption = sha512
|
python3 -m radicale --storage-filesystem-folder=/var/lib/radicale/collections --hosts 0.0.0.0:5232 --auth-type htpasswd --auth-htpasswd-filename /opt/radicale/users --auth-htpasswd-encryption sha512
|
||||||
|
|
||||||
[storage]
|
|
||||||
type = multifilesystem
|
|
||||||
filesystem_folder = /var/lib/radicale/collections
|
|
||||||
|
|
||||||
[web]
|
|
||||||
type = internal
|
|
||||||
EOF
|
EOF
|
||||||
msg_ok "Set up Radicale"
|
|
||||||
|
|
||||||
msg_info "Creating Service"
|
chmod +x /opt/radicale/start.sh
|
||||||
|
|
||||||
cat <<EOF >/etc/systemd/system/radicale.service
|
cat <<EOF >/etc/systemd/system/radicale.service
|
||||||
[Unit]
|
|
||||||
Description=A simple CalDAV (calendar) and CardDAV (contact) server
|
Description=A simple CalDAV (calendar) and CardDAV (contact) server
|
||||||
After=network.target
|
After=network.target
|
||||||
Requires=network.target
|
Requires=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
WorkingDirectory=/opt/radicale
|
ExecStart=/opt/radicale/start.sh
|
||||||
ExecStart=/usr/local/bin/uv run -m radicale --config /etc/radicale/config
|
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
# User=radicale
|
# User=radicale
|
||||||
# Deny other users access to the calendar data
|
# Deny other users access to the calendar data
|
||||||
|
|||||||
@@ -1,344 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: MickLesk (CanbiZ) | DevelopmentCats | AlphaLawless
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://romm.app
|
|
||||||
|
|
||||||
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 \
|
|
||||||
acl \
|
|
||||||
git \
|
|
||||||
build-essential \
|
|
||||||
libssl-dev \
|
|
||||||
libffi-dev \
|
|
||||||
libmagic-dev \
|
|
||||||
python3-dev \
|
|
||||||
python3-pip \
|
|
||||||
python3-venv \
|
|
||||||
libmariadb3 \
|
|
||||||
libmariadb-dev \
|
|
||||||
libpq-dev \
|
|
||||||
libbz2-dev \
|
|
||||||
libreadline-dev \
|
|
||||||
libsqlite3-dev \
|
|
||||||
zlib1g-dev \
|
|
||||||
liblzma-dev \
|
|
||||||
libncurses5-dev \
|
|
||||||
libncursesw5-dev \
|
|
||||||
redis-server \
|
|
||||||
redis-tools \
|
|
||||||
p7zip-full \
|
|
||||||
tzdata \
|
|
||||||
nginx
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
PYTHON_VERSION="3.13" setup_uv
|
|
||||||
NODE_VERSION="22" setup_nodejs
|
|
||||||
setup_mariadb
|
|
||||||
MARIADB_DB_NAME="romm" MARIADB_DB_USER="romm" setup_mariadb_db
|
|
||||||
|
|
||||||
msg_info "Creating directories"
|
|
||||||
mkdir -p /opt/romm \
|
|
||||||
/var/lib/romm/config \
|
|
||||||
/var/lib/romm/resources \
|
|
||||||
/var/lib/romm/assets/{saves,states,screenshots} \
|
|
||||||
/var/lib/romm/library/roms \
|
|
||||||
/var/lib/romm/library/bios
|
|
||||||
msg_ok "Created directories"
|
|
||||||
|
|
||||||
msg_info "Creating configuration file"
|
|
||||||
cat <<'EOF' >/var/lib/romm/config/config.yml
|
|
||||||
# RomM Configuration File
|
|
||||||
# Documentation: https://docs.romm.app/latest/Getting-Started/Configuration-File/
|
|
||||||
# Only uncomment the lines you want to use/modify
|
|
||||||
|
|
||||||
# exclude:
|
|
||||||
# platforms:
|
|
||||||
# - excluded_folder_a
|
|
||||||
# roms:
|
|
||||||
# single_file:
|
|
||||||
# extensions:
|
|
||||||
# - xml
|
|
||||||
# - txt
|
|
||||||
# names:
|
|
||||||
# - '._*'
|
|
||||||
# - '*.nfo'
|
|
||||||
# multi_file:
|
|
||||||
# names:
|
|
||||||
# - downloaded_media
|
|
||||||
# - media
|
|
||||||
|
|
||||||
# system:
|
|
||||||
# platforms:
|
|
||||||
# gc: ngc
|
|
||||||
# ps1: psx
|
|
||||||
|
|
||||||
# The folder name where your roms are located (relative to library path)
|
|
||||||
# filesystem:
|
|
||||||
# roms_folder: 'roms'
|
|
||||||
|
|
||||||
# scan:
|
|
||||||
# priority:
|
|
||||||
# metadata:
|
|
||||||
# - "igdb"
|
|
||||||
# - "moby"
|
|
||||||
# - "ss"
|
|
||||||
# - "ra"
|
|
||||||
# artwork:
|
|
||||||
# - "igdb"
|
|
||||||
# - "moby"
|
|
||||||
# - "ss"
|
|
||||||
# region:
|
|
||||||
# - "us"
|
|
||||||
# - "eu"
|
|
||||||
# - "jp"
|
|
||||||
# language:
|
|
||||||
# - "en"
|
|
||||||
# media:
|
|
||||||
# - box2d
|
|
||||||
# - box3d
|
|
||||||
# - screenshot
|
|
||||||
# - manual
|
|
||||||
|
|
||||||
# emulatorjs:
|
|
||||||
# debug: false
|
|
||||||
# cache_limit: null
|
|
||||||
EOF
|
|
||||||
chmod 644 /var/lib/romm/config/config.yml
|
|
||||||
msg_ok "Created configuration file"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "RAHasher" "RetroAchievements/RALibretro" "prebuild" "latest" "/opt/RALibretro" "RAHasher-x64-Linux-*.zip"
|
|
||||||
cp /opt/RALibretro/RAHasher /usr/bin/RAHasher
|
|
||||||
chmod +x /usr/bin/RAHasher
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "romm" "rommapp/romm"
|
|
||||||
|
|
||||||
msg_info "Creating environment file"
|
|
||||||
sed -i 's/^supervised no/supervised systemd/' /etc/redis/redis.conf
|
|
||||||
systemctl restart redis-server
|
|
||||||
systemctl enable -q --now redis-server
|
|
||||||
AUTH_SECRET_KEY=$(openssl rand -hex 32)
|
|
||||||
|
|
||||||
cat <<EOF >/opt/romm/.env
|
|
||||||
ROMM_BASE_PATH=/var/lib/romm
|
|
||||||
ROMM_CONFIG_PATH=/var/lib/romm/config/config.yml
|
|
||||||
WEB_CONCURRENCY=4
|
|
||||||
|
|
||||||
DB_HOST=127.0.0.1
|
|
||||||
DB_PORT=3306
|
|
||||||
DB_NAME=$MARIADB_DB_NAME
|
|
||||||
DB_USER=$MARIADB_DB_USER
|
|
||||||
DB_PASSWD=$MARIADB_DB_PASS
|
|
||||||
|
|
||||||
REDIS_HOST=127.0.0.1
|
|
||||||
REDIS_PORT=6379
|
|
||||||
|
|
||||||
ROMM_AUTH_SECRET_KEY=$AUTH_SECRET_KEY
|
|
||||||
DISABLE_DOWNLOAD_ENDPOINT_AUTH=false
|
|
||||||
DISABLE_CSRF_PROTECTION=false
|
|
||||||
|
|
||||||
ENABLE_RESCAN_ON_FILESYSTEM_CHANGE=true
|
|
||||||
RESCAN_ON_FILESYSTEM_CHANGE_DELAY=5
|
|
||||||
|
|
||||||
ENABLE_SCHEDULED_RESCAN=true
|
|
||||||
SCHEDULED_RESCAN_CRON=0 3 * * *
|
|
||||||
ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB=true
|
|
||||||
SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON=0 4 * * *
|
|
||||||
|
|
||||||
LOGLEVEL=INFO
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod 600 /opt/romm/.env
|
|
||||||
msg_ok "Created environment file"
|
|
||||||
|
|
||||||
msg_info "Setting up RomM Backend"
|
|
||||||
cd /opt/romm
|
|
||||||
export UV_CONCURRENT_DOWNLOADS=1
|
|
||||||
$STD uv sync --all-extras
|
|
||||||
cd /opt/romm/backend
|
|
||||||
$STD uv run alembic upgrade head
|
|
||||||
msg_ok "Set up RomM Backend"
|
|
||||||
|
|
||||||
msg_info "Setting up RomM Frontend"
|
|
||||||
cd /opt/romm/frontend
|
|
||||||
$STD npm install
|
|
||||||
$STD npm run build
|
|
||||||
|
|
||||||
cp -rf /opt/romm/frontend/assets/* /opt/romm/frontend/dist/assets/
|
|
||||||
|
|
||||||
mkdir -p /opt/romm/frontend/dist/assets/romm
|
|
||||||
ln -sfn /var/lib/romm/resources /opt/romm/frontend/dist/assets/romm/resources
|
|
||||||
ln -sfn /var/lib/romm/assets /opt/romm/frontend/dist/assets/romm/assets
|
|
||||||
msg_ok "Set up RomM Frontend"
|
|
||||||
|
|
||||||
msg_info "Configuring Nginx"
|
|
||||||
cat <<'EOF' >/etc/nginx/sites-available/romm
|
|
||||||
upstream romm_backend {
|
|
||||||
server 127.0.0.1:5000;
|
|
||||||
}
|
|
||||||
|
|
||||||
map $http_upgrade $connection_upgrade {
|
|
||||||
default upgrade;
|
|
||||||
'' close;
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name _;
|
|
||||||
root /opt/romm/frontend/dist;
|
|
||||||
client_max_body_size 0;
|
|
||||||
|
|
||||||
# Frontend SPA
|
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Static assets
|
|
||||||
location /assets {
|
|
||||||
alias /opt/romm/frontend/dist/assets;
|
|
||||||
try_files $uri $uri/ =404;
|
|
||||||
expires 1y;
|
|
||||||
add_header Cache-Control "public, immutable";
|
|
||||||
}
|
|
||||||
|
|
||||||
# EmulatorJS player - requires COOP/COEP headers for SharedArrayBuffer
|
|
||||||
location ~ ^/rom/.*/ejs$ {
|
|
||||||
add_header Cross-Origin-Embedder-Policy "require-corp";
|
|
||||||
add_header Cross-Origin-Opener-Policy "same-origin";
|
|
||||||
try_files $uri /index.html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Backend API
|
|
||||||
location /api {
|
|
||||||
proxy_pass http://romm_backend;
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_request_buffering off;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
# WebSocket and Netplay
|
|
||||||
location ~ ^/(ws|netplay) {
|
|
||||||
proxy_pass http://romm_backend;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection $connection_upgrade;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_read_timeout 86400;
|
|
||||||
}
|
|
||||||
|
|
||||||
# OpenAPI docs
|
|
||||||
location = /openapi.json {
|
|
||||||
proxy_pass http://romm_backend;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Internal library file serving
|
|
||||||
location /library/ {
|
|
||||||
internal;
|
|
||||||
alias /var/lib/romm/library/;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
rm -f /etc/nginx/sites-enabled/default
|
|
||||||
ln -sf /etc/nginx/sites-available/romm /etc/nginx/sites-enabled/romm
|
|
||||||
systemctl restart nginx
|
|
||||||
systemctl enable -q --now nginx
|
|
||||||
msg_ok "Configured Nginx"
|
|
||||||
|
|
||||||
msg_info "Creating Services"
|
|
||||||
cat <<EOF >/etc/systemd/system/romm-backend.service
|
|
||||||
[Unit]
|
|
||||||
Description=RomM Backend
|
|
||||||
After=network.target mariadb.service redis-server.service
|
|
||||||
Requires=mariadb.service redis-server.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
WorkingDirectory=/opt/romm/backend
|
|
||||||
EnvironmentFile=/opt/romm/.env
|
|
||||||
Environment="PYTHONPATH=/opt/romm"
|
|
||||||
ExecStart=/opt/romm/.venv/bin/python main.py
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<EOF >/etc/systemd/system/romm-worker.service
|
|
||||||
[Unit]
|
|
||||||
Description=RomM RQ Worker
|
|
||||||
After=network.target mariadb.service redis-server.service romm-backend.service
|
|
||||||
Requires=mariadb.service redis-server.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
WorkingDirectory=/opt/romm/backend
|
|
||||||
EnvironmentFile=/opt/romm/.env
|
|
||||||
Environment="PYTHONPATH=/opt/romm/backend"
|
|
||||||
ExecStart=/opt/romm/.venv/bin/rq worker --path /opt/romm/backend --url redis://127.0.0.1:6379/0 high default low
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<EOF >/etc/systemd/system/romm-scheduler.service
|
|
||||||
[Unit]
|
|
||||||
Description=RomM RQ Scheduler
|
|
||||||
After=network.target mariadb.service redis-server.service romm-backend.service
|
|
||||||
Requires=mariadb.service redis-server.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
WorkingDirectory=/opt/romm/backend
|
|
||||||
EnvironmentFile=/opt/romm/.env
|
|
||||||
Environment="PYTHONPATH=/opt/romm/backend"
|
|
||||||
Environment="RQ_REDIS_HOST=127.0.0.1"
|
|
||||||
Environment="RQ_REDIS_PORT=6379"
|
|
||||||
ExecStart=/opt/romm/.venv/bin/rqscheduler --path /opt/romm/backend
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<EOF >/etc/systemd/system/romm-watcher.service
|
|
||||||
[Unit]
|
|
||||||
Description=RomM Filesystem Watcher
|
|
||||||
After=network.target romm-backend.service
|
|
||||||
Requires=romm-backend.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
WorkingDirectory=/opt/romm/backend
|
|
||||||
EnvironmentFile=/opt/romm/.env
|
|
||||||
Environment="PYTHONPATH=/opt/romm/backend"
|
|
||||||
ExecStart=/opt/romm/.venv/bin/watchfiles --target-type command '/opt/romm/.venv/bin/python watcher.py' /var/lib/romm/library
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=5
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
systemctl enable -q --now romm-backend romm-worker romm-scheduler romm-watcher
|
|
||||||
msg_ok "Created Services"
|
|
||||||
|
|
||||||
motd_ssh
|
|
||||||
customize
|
|
||||||
cleanup_lxc
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
|
||||||
# Author: CrazyWolf13
|
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
# Source: https://docs.seerr.dev/
|
|
||||||
|
|
||||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
|
||||||
color
|
|
||||||
verb_ip6
|
|
||||||
catch_errors
|
|
||||||
setting_up_container
|
|
||||||
network_check
|
|
||||||
update_os
|
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
|
||||||
$STD apt-get install -y build-essential
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "seerr" "seerr-team/seerr" "tarball"
|
|
||||||
pnpm_desired=$(grep -Po '"pnpm":\s*"\K[^"]+' /opt/seerr/package.json)
|
|
||||||
NODE_VERSION="22" NODE_MODULE="pnpm@$pnpm_desired" setup_nodejs
|
|
||||||
|
|
||||||
msg_info "Installing Seerr (Patience)"
|
|
||||||
export CYPRESS_INSTALL_BINARY=0
|
|
||||||
cd /opt/seerr
|
|
||||||
$STD pnpm install --frozen-lockfile
|
|
||||||
export NODE_OPTIONS="--max-old-space-size=3072"
|
|
||||||
$STD pnpm build
|
|
||||||
mkdir -p /etc/seerr/
|
|
||||||
cat <<EOF >/etc/seerr/seerr.conf
|
|
||||||
## Seerr's default port is 5055, if you want to use both, change this.
|
|
||||||
## specify on which port to listen
|
|
||||||
PORT=5055
|
|
||||||
|
|
||||||
## specify on which interface to listen, by default seerr listens on all interfaces
|
|
||||||
HOST=0.0.0.0
|
|
||||||
|
|
||||||
## Uncomment if you want to force Node.js to resolve IPv4 before IPv6 (advanced users only)
|
|
||||||
# FORCE_IPV4_FIRST=true
|
|
||||||
EOF
|
|
||||||
msg_ok "Installed Seerr"
|
|
||||||
|
|
||||||
msg_info "Creating Service"
|
|
||||||
cat <<EOF >/etc/systemd/system/seerr.service
|
|
||||||
[Unit]
|
|
||||||
Description=Seerr Service
|
|
||||||
Wants=network-online.target
|
|
||||||
After=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
EnvironmentFile=/etc/seerr/seerr.conf
|
|
||||||
Environment=NODE_ENV=production
|
|
||||||
Type=exec
|
|
||||||
Restart=on-failure
|
|
||||||
WorkingDirectory=/opt/seerr
|
|
||||||
ExecStart=/usr/bin/node dist/index.js
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
systemctl enable -q --now seerr
|
|
||||||
msg_ok "Created Service"
|
|
||||||
|
|
||||||
motd_ssh
|
|
||||||
customize
|
|
||||||
cleanup_lxc
|
|
||||||
@@ -29,7 +29,6 @@ $STD uv venv --clear
|
|||||||
$STD source /opt/Tautulli/.venv/bin/activate
|
$STD source /opt/Tautulli/.venv/bin/activate
|
||||||
$STD uv pip install -r requirements.txt
|
$STD uv pip install -r requirements.txt
|
||||||
$STD uv pip install pyopenssl
|
$STD uv pip install pyopenssl
|
||||||
$STD uv pip install "setuptools<81"
|
|
||||||
msg_ok "Installed Tautulli"
|
msg_ok "Installed Tautulli"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ SECRET="$(openssl rand -hex 64)"
|
|||||||
sed -e '/^NODE_ENV=/s/=.*$/=production/' \
|
sed -e '/^NODE_ENV=/s/=.*$/=production/' \
|
||||||
-e 's/^TUDUDI_USER/# TUDUDI_USER/g' \
|
-e 's/^TUDUDI_USER/# TUDUDI_USER/g' \
|
||||||
-e "/_SECRET=/s/=.*$/=${SECRET}/" \
|
-e "/_SECRET=/s/=.*$/=${SECRET}/" \
|
||||||
-e '/^# DB_FILE=/s/^# //' \
|
-e "/^# DB_FILE/s/^# //; \
|
||||||
-e "s|^DB_FILE=.*|DB_FILE=${DB_LOCATION}/production.sqlite3|" \
|
\|DB_FILE|s|/path.*$|${DB_LOCATION}/production.sqlite3|" \
|
||||||
-e "/^# TUDUDI_ALLOWED/s/^# //; \
|
-e "/^# TUDUDI_ALLOWED/s/^# //; \
|
||||||
\|_ORIGINS=|s|=.*$|=<your tududi IP or FDQN>|" \
|
\|_ORIGINS=|s|=.*$|=<your tududi IP or FDQN>|" \
|
||||||
-e "/^# TUDUDI_UPLOAD/s/^# //; \
|
-e "/^# TUDUDI_UPLOAD/s/^# //; \
|
||||||
|
|||||||
@@ -15,18 +15,16 @@ update_os
|
|||||||
|
|
||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y apt-transport-https
|
$STD apt install -y apt-transport-https
|
||||||
curl -fsSL "https://dl.ui.com/unifi/unifi-repo.gpg" -o "/usr/share/keyrings/unifi-repo.gpg"
|
|
||||||
cat <<EOF | sudo tee /etc/apt/sources.list.d/100-ubnt-unifi.sources >/dev/null
|
|
||||||
Types: deb
|
|
||||||
URIs: https://www.ui.com/downloads/unifi/debian
|
|
||||||
Suites: stable
|
|
||||||
Components: ubiquiti
|
|
||||||
Architectures: amd64
|
|
||||||
Signed-By: /usr/share/keyrings/unifi-repo.gpg
|
|
||||||
EOF
|
|
||||||
$STD apt update
|
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
setup_deb822_repo \
|
||||||
|
"unifi" \
|
||||||
|
"https://dl.ui.com/unifi/unifi-repo.gpg" \
|
||||||
|
"https://www.ui.com/downloads/unifi/debian" \
|
||||||
|
"stable" \
|
||||||
|
"ubiquiti" \
|
||||||
|
"amd64"
|
||||||
|
|
||||||
JAVA_VERSION="21" setup_java
|
JAVA_VERSION="21" setup_java
|
||||||
|
|
||||||
if lscpu | grep -q 'avx'; then
|
if lscpu | grep -q 'avx'; then
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ fetch_and_deploy_gh_release "vaultwarden" "dani-garcia/vaultwarden" "tarball" "l
|
|||||||
|
|
||||||
msg_info "Building Vaultwarden (Patience)"
|
msg_info "Building Vaultwarden (Patience)"
|
||||||
cd /tmp/vaultwarden-src
|
cd /tmp/vaultwarden-src
|
||||||
VW_VERSION=$(get_latest_github_release "dani-garcia/vaultwarden")
|
|
||||||
export VW_VERSION
|
|
||||||
$STD cargo build --features "sqlite,mysql,postgresql" --release
|
$STD cargo build --features "sqlite,mysql,postgresql" --release
|
||||||
msg_ok "Built Vaultwarden"
|
msg_ok "Built Vaultwarden"
|
||||||
|
|
||||||
|
|||||||
@@ -14,25 +14,6 @@ catch_errors
|
|||||||
# Get LXC IP address (must be called INSIDE container, after network is up)
|
# Get LXC IP address (must be called INSIDE container, after network is up)
|
||||||
get_lxc_ip
|
get_lxc_ip
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# post_progress_to_api()
|
|
||||||
#
|
|
||||||
# - Lightweight progress ping from inside the container
|
|
||||||
# - Updates the existing telemetry record status from "installing" to "configuring"
|
|
||||||
# - Signals that the installation is actively progressing (not stuck)
|
|
||||||
# - Fire-and-forget: never blocks or fails the script
|
|
||||||
# - Only executes if DIAGNOSTICS=yes and RANDOM_UUID is set
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
post_progress_to_api() {
|
|
||||||
command -v curl &>/dev/null || return 0
|
|
||||||
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
|
|
||||||
[[ -z "${RANDOM_UUID:-}" ]] && return 0
|
|
||||||
|
|
||||||
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"random_id\":\"${RANDOM_UUID}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/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
|
||||||
verb_ip6() {
|
verb_ip6() {
|
||||||
set_std_mode # Set STD mode based on VERBOSE
|
set_std_mode # Set STD mode based on VERBOSE
|
||||||
@@ -53,6 +34,42 @@ EOF
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set -Eeuo pipefail
|
||||||
|
trap 'error_handler $? $LINENO "$BASH_COMMAND"' ERR
|
||||||
|
trap on_exit EXIT
|
||||||
|
trap on_interrupt INT
|
||||||
|
trap on_terminate TERM
|
||||||
|
|
||||||
|
error_handler() {
|
||||||
|
local exit_code="$1"
|
||||||
|
local line_number="$2"
|
||||||
|
local command="$3"
|
||||||
|
|
||||||
|
if [[ "$exit_code" -eq 0 ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf "\e[?25h"
|
||||||
|
echo -e "\n${RD}[ERROR]${CL} in line ${RD}$line_number${CL}: exit code ${RD}$exit_code${CL}: while executing command ${YW}$command${CL}\n"
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_exit() {
|
||||||
|
local exit_code="$?"
|
||||||
|
[[ -n "${lockfile:-}" && -e "$lockfile" ]] && rm -f "$lockfile"
|
||||||
|
exit "$exit_code"
|
||||||
|
}
|
||||||
|
|
||||||
|
on_interrupt() {
|
||||||
|
echo -e "\n${RD}Interrupted by user (SIGINT)${CL}"
|
||||||
|
exit 130
|
||||||
|
}
|
||||||
|
|
||||||
|
on_terminate() {
|
||||||
|
echo -e "\n${RD}Terminated by signal (SIGTERM)${CL}"
|
||||||
|
exit 143
|
||||||
|
}
|
||||||
|
|
||||||
# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection
|
# This function sets up the Container OS by generating the locale, setting the timezone, and checking the network connection
|
||||||
setting_up_container() {
|
setting_up_container() {
|
||||||
msg_info "Setting up Container OS"
|
msg_info "Setting up Container OS"
|
||||||
@@ -72,7 +89,6 @@ setting_up_container() {
|
|||||||
fi
|
fi
|
||||||
msg_ok "Set up Container OS"
|
msg_ok "Set up Container OS"
|
||||||
msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}"
|
msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}"
|
||||||
post_progress_to_api
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected
|
# This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected
|
||||||
@@ -105,18 +121,8 @@ network_check() {
|
|||||||
update_os() {
|
update_os() {
|
||||||
msg_info "Updating Container OS"
|
msg_info "Updating Container OS"
|
||||||
$STD apk -U upgrade
|
$STD apk -U upgrade
|
||||||
local tools_content
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || {
|
|
||||||
msg_error "Failed to download tools.func"
|
|
||||||
exit 6
|
|
||||||
}
|
|
||||||
source /dev/stdin <<<"$tools_content"
|
|
||||||
if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then
|
|
||||||
msg_error "tools.func loaded but incomplete — missing expected functions"
|
|
||||||
exit 6
|
|
||||||
fi
|
|
||||||
msg_ok "Updated Container OS"
|
msg_ok "Updated Container OS"
|
||||||
post_progress_to_api
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# This function modifies the message of the day (motd) and SSH settings
|
# This function modifies the message of the day (motd) and SSH settings
|
||||||
|
|||||||
@@ -34,19 +34,11 @@ net_resolves() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ensure_usr_local_bin_persist() {
|
ensure_usr_local_bin_persist() {
|
||||||
# Login shells: /etc/profile.d/
|
|
||||||
local PROFILE_FILE="/etc/profile.d/10-localbin.sh"
|
local PROFILE_FILE="/etc/profile.d/10-localbin.sh"
|
||||||
if [ ! -f "$PROFILE_FILE" ]; then
|
if [ ! -f "$PROFILE_FILE" ]; then
|
||||||
echo 'case ":$PATH:" in *:/usr/local/bin:*) ;; *) export PATH="/usr/local/bin:$PATH";; esac' >"$PROFILE_FILE"
|
echo 'case ":$PATH:" in *:/usr/local/bin:*) ;; *) export PATH="/usr/local/bin:$PATH";; esac' >"$PROFILE_FILE"
|
||||||
chmod +x "$PROFILE_FILE"
|
chmod +x "$PROFILE_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Non-login shells (pct enter): /root/.profile and /root/.bashrc
|
|
||||||
for rc_file in /root/.profile /root/.bashrc; do
|
|
||||||
if [ -f "$rc_file" ] && ! grep -q '/usr/local/bin' "$rc_file"; then
|
|
||||||
echo 'export PATH="/usr/local/bin:$PATH"' >>"$rc_file"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
download_with_progress() {
|
download_with_progress() {
|
||||||
|
|||||||
407
misc/api.func
407
misc/api.func
@@ -91,8 +91,8 @@ detect_repo_source() {
|
|||||||
community-scripts/ProxmoxVED) REPO_SOURCE="ProxmoxVED" ;;
|
community-scripts/ProxmoxVED) REPO_SOURCE="ProxmoxVED" ;;
|
||||||
"")
|
"")
|
||||||
# No URL detected — use hardcoded fallback
|
# No URL detected — use hardcoded fallback
|
||||||
# This value must match the repo: ProxmoxVE for production, ProxmoxVED for dev
|
# CI sed transforms this on promotion: ProxmoxVED → ProxmoxVE
|
||||||
REPO_SOURCE="ProxmoxVE"
|
REPO_SOURCE="ProxmoxVED"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Fork or unknown repo
|
# Fork or unknown repo
|
||||||
@@ -117,17 +117,16 @@ detect_repo_source
|
|||||||
# - Canonical source of truth for ALL exit code mappings
|
# - Canonical source of truth for ALL exit code mappings
|
||||||
# - Used by both api.func (telemetry) and error_handler.func (error display)
|
# - Used by both api.func (telemetry) and error_handler.func (error display)
|
||||||
# - Supports:
|
# - Supports:
|
||||||
# * Generic/Shell errors (1-3, 10, 124-132, 134, 137, 139, 141, 143-146)
|
# * Generic/Shell errors (1, 2, 124, 126-130, 134, 137, 139, 141, 143)
|
||||||
# * curl/wget errors (4-8, 16, 18, 22-28, 30, 32-36, 39, 44-48, 51-52, 55-57, 59, 61, 63, 75, 78-79, 92, 95)
|
# * curl/wget errors (6, 7, 22, 28, 35)
|
||||||
# * Package manager errors (APT, DPKG: 100-102, 255)
|
# * Package manager errors (APT, DPKG: 100-102, 255)
|
||||||
# * BSD sysexits (64-78)
|
|
||||||
# * Systemd/Service errors (150-154)
|
# * Systemd/Service errors (150-154)
|
||||||
# * Python/pip/uv errors (160-162)
|
# * Python/pip/uv errors (160-162)
|
||||||
# * PostgreSQL errors (170-173)
|
# * PostgreSQL errors (170-173)
|
||||||
# * MySQL/MariaDB errors (180-183)
|
# * MySQL/MariaDB errors (180-183)
|
||||||
# * MongoDB errors (190-193)
|
# * MongoDB errors (190-193)
|
||||||
# * Proxmox custom codes (200-231)
|
# * Proxmox custom codes (200-231)
|
||||||
# * Node.js/npm errors (239, 243, 245-249)
|
# * Node.js/npm errors (243, 245-249)
|
||||||
# - Returns description string for given exit code
|
# - Returns description string for given exit code
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
explain_exit_code() {
|
explain_exit_code() {
|
||||||
@@ -136,87 +135,30 @@ explain_exit_code() {
|
|||||||
# --- Generic / Shell ---
|
# --- Generic / Shell ---
|
||||||
1) echo "General error / Operation not permitted" ;;
|
1) echo "General error / Operation not permitted" ;;
|
||||||
2) echo "Misuse of shell builtins (e.g. syntax error)" ;;
|
2) echo "Misuse of shell builtins (e.g. syntax error)" ;;
|
||||||
3) echo "General syntax or argument error" ;;
|
|
||||||
10) echo "Docker / privileged mode required (unsupported environment)" ;;
|
|
||||||
|
|
||||||
# --- curl / wget errors (commonly seen in downloads) ---
|
# --- curl / wget errors (commonly seen in downloads) ---
|
||||||
4) echo "curl: Feature not supported or protocol error" ;;
|
|
||||||
5) echo "curl: Could not resolve proxy" ;;
|
|
||||||
6) echo "curl: DNS resolution failed (could not resolve host)" ;;
|
6) echo "curl: DNS resolution failed (could not resolve host)" ;;
|
||||||
7) echo "curl: Failed to connect (network unreachable / host down)" ;;
|
7) echo "curl: Failed to connect (network unreachable / host down)" ;;
|
||||||
8) echo "curl: Server reply error (FTP/SFTP or apk untrusted key)" ;;
|
|
||||||
16) echo "curl: HTTP/2 framing layer error" ;;
|
|
||||||
18) echo "curl: Partial file (transfer not completed)" ;;
|
|
||||||
22) echo "curl: HTTP error returned (404, 429, 500+)" ;;
|
22) echo "curl: HTTP error returned (404, 429, 500+)" ;;
|
||||||
23) echo "curl: Write error (disk full or permissions)" ;;
|
|
||||||
24) echo "curl: Write to local file failed" ;;
|
|
||||||
25) echo "curl: Upload failed" ;;
|
|
||||||
26) echo "curl: Read error on local file (I/O)" ;;
|
|
||||||
27) echo "curl: Out of memory (memory allocation failed)" ;;
|
|
||||||
28) echo "curl: Operation timeout (network slow or server not responding)" ;;
|
28) echo "curl: Operation timeout (network slow or server not responding)" ;;
|
||||||
30) echo "curl: FTP port command failed" ;;
|
|
||||||
32) echo "curl: FTP SIZE command failed" ;;
|
|
||||||
33) echo "curl: HTTP range error" ;;
|
|
||||||
34) echo "curl: HTTP post error" ;;
|
|
||||||
35) echo "curl: SSL/TLS handshake failed (certificate error)" ;;
|
35) echo "curl: SSL/TLS handshake failed (certificate error)" ;;
|
||||||
36) echo "curl: FTP bad download resume" ;;
|
|
||||||
39) echo "curl: LDAP search failed" ;;
|
|
||||||
44) echo "curl: Internal error (bad function call order)" ;;
|
|
||||||
45) echo "curl: Interface error (failed to bind to specified interface)" ;;
|
|
||||||
46) echo "curl: Bad password entered" ;;
|
|
||||||
47) echo "curl: Too many redirects" ;;
|
|
||||||
48) echo "curl: Unknown command line option specified" ;;
|
|
||||||
51) echo "curl: SSL peer certificate or SSH host key verification failed" ;;
|
|
||||||
52) echo "curl: Empty reply from server (got nothing)" ;;
|
|
||||||
55) echo "curl: Failed sending network data" ;;
|
|
||||||
56) echo "curl: Receive error (connection reset by peer)" ;;
|
|
||||||
57) echo "curl: Unrecoverable poll/select error (system I/O failure)" ;;
|
|
||||||
59) echo "curl: Couldn't use specified SSL cipher" ;;
|
|
||||||
61) echo "curl: Bad/unrecognized transfer encoding" ;;
|
|
||||||
63) echo "curl: Maximum file size exceeded" ;;
|
|
||||||
75) echo "Temporary failure (retry later)" ;;
|
|
||||||
78) echo "curl: Remote file not found (404 on FTP/file)" ;;
|
|
||||||
79) echo "curl: SSH session error (key exchange/auth failed)" ;;
|
|
||||||
92) echo "curl: HTTP/2 stream error (protocol violation)" ;;
|
|
||||||
95) echo "curl: HTTP/3 layer error" ;;
|
|
||||||
|
|
||||||
# --- Package manager / APT / DPKG ---
|
# --- Package manager / APT / DPKG ---
|
||||||
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)" ;;
|
||||||
|
|
||||||
# --- BSD sysexits.h (64-78) ---
|
|
||||||
64) echo "Usage error (wrong arguments)" ;;
|
|
||||||
65) echo "Data format error (bad input data)" ;;
|
|
||||||
66) echo "Input file not found (cannot open input)" ;;
|
|
||||||
67) echo "User not found (addressee unknown)" ;;
|
|
||||||
68) echo "Host not found (hostname unknown)" ;;
|
|
||||||
69) echo "Service unavailable" ;;
|
|
||||||
70) echo "Internal software error" ;;
|
|
||||||
71) echo "System error (OS-level failure)" ;;
|
|
||||||
72) echo "Critical OS file missing" ;;
|
|
||||||
73) echo "Cannot create output file" ;;
|
|
||||||
74) echo "I/O error" ;;
|
|
||||||
76) echo "Remote protocol error" ;;
|
|
||||||
77) echo "Permission denied" ;;
|
|
||||||
|
|
||||||
# --- Common shell/system errors ---
|
# --- Common shell/system errors ---
|
||||||
124) echo "Command timed out (timeout command)" ;;
|
124) echo "Command timed out (timeout command)" ;;
|
||||||
125) echo "Command failed to start (Docker daemon or execution error)" ;;
|
|
||||||
126) echo "Command invoked cannot execute (permission problem?)" ;;
|
126) echo "Command invoked cannot execute (permission problem?)" ;;
|
||||||
127) echo "Command not found" ;;
|
127) echo "Command not found" ;;
|
||||||
128) echo "Invalid argument to exit" ;;
|
128) echo "Invalid argument to exit" ;;
|
||||||
129) echo "Killed by SIGHUP (terminal closed / hangup)" ;;
|
130) echo "Terminated by Ctrl+C (SIGINT)" ;;
|
||||||
130) echo "Aborted by user (SIGINT)" ;;
|
|
||||||
131) echo "Killed by SIGQUIT (core dumped)" ;;
|
|
||||||
132) echo "Killed by SIGILL (illegal CPU instruction)" ;;
|
|
||||||
134) echo "Process aborted (SIGABRT - possibly Node.js heap overflow)" ;;
|
134) echo "Process aborted (SIGABRT - possibly Node.js heap overflow)" ;;
|
||||||
137) echo "Killed (SIGKILL / Out of memory?)" ;;
|
137) echo "Killed (SIGKILL / Out of memory?)" ;;
|
||||||
139) echo "Segmentation fault (core dumped)" ;;
|
139) echo "Segmentation fault (core dumped)" ;;
|
||||||
141) echo "Broken pipe (SIGPIPE - output closed prematurely)" ;;
|
141) echo "Broken pipe (SIGPIPE - output closed prematurely)" ;;
|
||||||
143) echo "Terminated (SIGTERM)" ;;
|
143) echo "Terminated (SIGTERM)" ;;
|
||||||
144) echo "Killed by signal 16 (SIGUSR1 / SIGSTKFLT)" ;;
|
|
||||||
146) echo "Killed by signal 18 (SIGTSTP)" ;;
|
|
||||||
|
|
||||||
# --- Systemd / Service errors (150-154) ---
|
# --- Systemd / Service errors (150-154) ---
|
||||||
150) echo "Systemd: Service failed to start" ;;
|
150) echo "Systemd: Service failed to start" ;;
|
||||||
@@ -224,6 +166,7 @@ explain_exit_code() {
|
|||||||
152) echo "Permission denied (EACCES)" ;;
|
152) echo "Permission denied (EACCES)" ;;
|
||||||
153) echo "Build/compile failed (make/gcc/cmake)" ;;
|
153) echo "Build/compile failed (make/gcc/cmake)" ;;
|
||||||
154) echo "Node.js: Native addon build failed (node-gyp)" ;;
|
154) echo "Node.js: Native addon build failed (node-gyp)" ;;
|
||||||
|
|
||||||
# --- Python / pip / uv (160-162) ---
|
# --- Python / pip / uv (160-162) ---
|
||||||
160) echo "Python: Virtualenv / uv environment missing or broken" ;;
|
160) echo "Python: Virtualenv / uv environment missing or broken" ;;
|
||||||
161) echo "Python: Dependency resolution failed" ;;
|
161) echo "Python: Dependency resolution failed" ;;
|
||||||
@@ -274,8 +217,7 @@ explain_exit_code() {
|
|||||||
225) echo "Proxmox: No template available for OS/Version" ;;
|
225) echo "Proxmox: No template available for OS/Version" ;;
|
||||||
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
||||||
|
|
||||||
# --- Node.js / npm / pnpm / yarn (239-249) ---
|
# --- Node.js / npm / pnpm / yarn (243-249) ---
|
||||||
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" ;;
|
||||||
246) echo "Node.js: Internal JavaScript Parse Error" ;;
|
246) echo "Node.js: Internal JavaScript Parse Error" ;;
|
||||||
@@ -291,91 +233,6 @@ explain_exit_code() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# json_escape()
|
|
||||||
#
|
|
||||||
# - Escapes a string for safe JSON embedding
|
|
||||||
# - Strips ANSI escape sequences and non-printable control characters
|
|
||||||
# - Handles backslashes, quotes, newlines, tabs, and carriage returns
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
json_escape() {
|
|
||||||
local s="$1"
|
|
||||||
# Strip ANSI escape sequences (color codes etc.)
|
|
||||||
s=$(printf '%s' "$s" | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g')
|
|
||||||
s=${s//\\/\\\\}
|
|
||||||
s=${s//"/\\"/}
|
|
||||||
s=${s//$'\n'/\\n}
|
|
||||||
s=${s//$'\r'/}
|
|
||||||
s=${s//$'\t'/\\t}
|
|
||||||
# Remove any remaining control characters (0x00-0x1F except those already handled)
|
|
||||||
s=$(printf '%s' "$s" | tr -d '\000-\010\013\014\016-\037')
|
|
||||||
printf '%s' "$s"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# get_error_text()
|
|
||||||
#
|
|
||||||
# - Returns last 20 lines of the active log (INSTALL_LOG or BUILD_LOG)
|
|
||||||
# - Falls back to combined log or BUILD_LOG if primary is not accessible
|
|
||||||
# - Handles container paths that don't exist on the host
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
get_error_text() {
|
|
||||||
local logfile=""
|
|
||||||
if declare -f get_active_logfile >/dev/null 2>&1; then
|
|
||||||
logfile=$(get_active_logfile)
|
|
||||||
elif [[ -n "${INSTALL_LOG:-}" ]]; then
|
|
||||||
logfile="$INSTALL_LOG"
|
|
||||||
elif [[ -n "${BUILD_LOG:-}" ]]; then
|
|
||||||
logfile="$BUILD_LOG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If logfile is inside container (e.g. /root/.install-*), try the host copy
|
|
||||||
if [[ -n "$logfile" && ! -s "$logfile" ]]; then
|
|
||||||
# Try combined log: /tmp/<app>-<CTID>-<SESSION_ID>.log
|
|
||||||
if [[ -n "${CTID:-}" && -n "${SESSION_ID:-}" ]]; then
|
|
||||||
local combined_log="/tmp/${NSAPP:-lxc}-${CTID}-${SESSION_ID}.log"
|
|
||||||
if [[ -s "$combined_log" ]]; then
|
|
||||||
logfile="$combined_log"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Also try BUILD_LOG as fallback if primary log is empty/missing
|
|
||||||
if [[ -z "$logfile" || ! -s "$logfile" ]] && [[ -n "${BUILD_LOG:-}" && -s "${BUILD_LOG}" ]]; then
|
|
||||||
logfile="$BUILD_LOG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "$logfile" && -s "$logfile" ]]; then
|
|
||||||
tail -n 20 "$logfile" 2>/dev/null | sed 's/\r$//' | sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# build_error_string()
|
|
||||||
#
|
|
||||||
# - Builds a structured error string for telemetry reporting
|
|
||||||
# - Format: "exit_code=<N> | <explanation>\n---\n<last 20 log lines>"
|
|
||||||
# - If no log lines available, returns just the explanation
|
|
||||||
# - Arguments:
|
|
||||||
# * $1: exit_code (numeric)
|
|
||||||
# * $2: log_text (optional, output from get_error_text)
|
|
||||||
# - Returns structured error string via stdout
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
build_error_string() {
|
|
||||||
local exit_code="${1:-1}"
|
|
||||||
local log_text="${2:-}"
|
|
||||||
local explanation
|
|
||||||
explanation=$(explain_exit_code "$exit_code")
|
|
||||||
|
|
||||||
if [[ -n "$log_text" ]]; then
|
|
||||||
# Structured format: header + separator + log lines
|
|
||||||
printf 'exit_code=%s | %s\n---\n%s' "$exit_code" "$explanation" "$log_text"
|
|
||||||
else
|
|
||||||
# No log available - just the explanation with exit code
|
|
||||||
printf 'exit_code=%s | %s' "$exit_code" "$explanation"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 2: TELEMETRY FUNCTIONS
|
# SECTION 2: TELEMETRY FUNCTIONS
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -458,19 +315,18 @@ detect_cpu() {
|
|||||||
# - Detects RAM speed using dmidecode
|
# - Detects RAM speed using dmidecode
|
||||||
# - Sets RAM_SPEED global (e.g., "4800" for DDR5-4800)
|
# - Sets RAM_SPEED global (e.g., "4800" for DDR5-4800)
|
||||||
# - Requires root access for dmidecode
|
# - Requires root access for dmidecode
|
||||||
# - Returns empty if not available or if speed is "Unknown" (nested VMs)
|
# - Returns empty if not available
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
detect_ram() {
|
detect_ram() {
|
||||||
RAM_SPEED=""
|
RAM_SPEED=""
|
||||||
|
|
||||||
if command -v dmidecode &>/dev/null; then
|
if command -v dmidecode &>/dev/null; then
|
||||||
# Get configured memory speed (actual running speed)
|
# Get configured memory speed (actual running speed)
|
||||||
# Use || true to handle "Unknown" values in nested VMs (no numeric match)
|
RAM_SPEED=$(dmidecode -t memory 2>/dev/null | grep -m1 "Configured Memory Speed:" | grep -oE "[0-9]+" | head -1)
|
||||||
RAM_SPEED=$(dmidecode -t memory 2>/dev/null | grep -m1 "Configured Memory Speed:" | grep -oE "[0-9]+" | head -1) || true
|
|
||||||
|
|
||||||
# Fallback to Speed: if Configured not available
|
# Fallback to Speed: if Configured not available
|
||||||
if [[ -z "$RAM_SPEED" ]]; then
|
if [[ -z "$RAM_SPEED" ]]; then
|
||||||
RAM_SPEED=$(dmidecode -t memory 2>/dev/null | grep -m1 "Speed:" | grep -oE "[0-9]+" | head -1) || true
|
RAM_SPEED=$(dmidecode -t memory 2>/dev/null | grep -m1 "Speed:" | grep -oE "[0-9]+" | head -1)
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -529,8 +385,7 @@ post_to_api() {
|
|||||||
detect_gpu
|
detect_gpu
|
||||||
fi
|
fi
|
||||||
local gpu_vendor="${GPU_VENDOR:-unknown}"
|
local gpu_vendor="${GPU_VENDOR:-unknown}"
|
||||||
local gpu_model
|
local gpu_model="${GPU_MODEL:-}"
|
||||||
gpu_model=$(json_escape "${GPU_MODEL:-}")
|
|
||||||
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
|
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
|
||||||
|
|
||||||
# Detect CPU if not already set
|
# Detect CPU if not already set
|
||||||
@@ -538,8 +393,7 @@ post_to_api() {
|
|||||||
detect_cpu
|
detect_cpu
|
||||||
fi
|
fi
|
||||||
local cpu_vendor="${CPU_VENDOR:-unknown}"
|
local cpu_vendor="${CPU_VENDOR:-unknown}"
|
||||||
local cpu_model
|
local cpu_model="${CPU_MODEL:-}"
|
||||||
cpu_model=$(json_escape "${CPU_MODEL:-}")
|
|
||||||
|
|
||||||
# Detect RAM if not already set
|
# Detect RAM if not already set
|
||||||
if [[ -z "${RAM_SPEED:-}" ]]; then
|
if [[ -z "${RAM_SPEED:-}" ]]; then
|
||||||
@@ -630,8 +484,7 @@ post_to_api_vm() {
|
|||||||
detect_gpu
|
detect_gpu
|
||||||
fi
|
fi
|
||||||
local gpu_vendor="${GPU_VENDOR:-unknown}"
|
local gpu_vendor="${GPU_VENDOR:-unknown}"
|
||||||
local gpu_model
|
local gpu_model="${GPU_MODEL:-}"
|
||||||
gpu_model=$(json_escape "${GPU_MODEL:-}")
|
|
||||||
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
|
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
|
||||||
|
|
||||||
# Detect CPU if not already set
|
# Detect CPU if not already set
|
||||||
@@ -639,8 +492,7 @@ post_to_api_vm() {
|
|||||||
detect_cpu
|
detect_cpu
|
||||||
fi
|
fi
|
||||||
local cpu_vendor="${CPU_VENDOR:-unknown}"
|
local cpu_vendor="${CPU_VENDOR:-unknown}"
|
||||||
local cpu_model
|
local cpu_model="${CPU_MODEL:-}"
|
||||||
cpu_model=$(json_escape "${CPU_MODEL:-}")
|
|
||||||
|
|
||||||
# Detect RAM if not already set
|
# Detect RAM if not already set
|
||||||
if [[ -z "${RAM_SPEED:-}" ]]; then
|
if [[ -z "${RAM_SPEED:-}" ]]; then
|
||||||
@@ -682,8 +534,6 @@ EOF
|
|||||||
curl -fsS -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
curl -fsS -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$JSON_PAYLOAD" &>/dev/null || true
|
-d "$JSON_PAYLOAD" &>/dev/null || true
|
||||||
|
|
||||||
POST_TO_API_DONE=true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -705,12 +555,9 @@ post_update_to_api() {
|
|||||||
# Silent fail - telemetry should never break scripts
|
# Silent fail - telemetry should never break scripts
|
||||||
command -v curl &>/dev/null || return 0
|
command -v curl &>/dev/null || return 0
|
||||||
|
|
||||||
# Support "force" mode (3rd arg) to bypass duplicate check for retries after cleanup
|
# Prevent duplicate submissions
|
||||||
local force="${3:-}"
|
|
||||||
POST_UPDATE_DONE=${POST_UPDATE_DONE:-false}
|
POST_UPDATE_DONE=${POST_UPDATE_DONE:-false}
|
||||||
if [[ "$POST_UPDATE_DONE" == "true" && "$force" != "force" ]]; then
|
[[ "$POST_UPDATE_DONE" == "true" ]] && return 0
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
|
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
|
||||||
[[ -z "${RANDOM_UUID:-}" ]] && return 0
|
[[ -z "${RANDOM_UUID:-}" ]] && return 0
|
||||||
@@ -721,14 +568,12 @@ post_update_to_api() {
|
|||||||
|
|
||||||
# Get GPU info (if detected)
|
# Get GPU info (if detected)
|
||||||
local gpu_vendor="${GPU_VENDOR:-unknown}"
|
local gpu_vendor="${GPU_VENDOR:-unknown}"
|
||||||
local gpu_model
|
local gpu_model="${GPU_MODEL:-}"
|
||||||
gpu_model=$(json_escape "${GPU_MODEL:-}")
|
|
||||||
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
|
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
|
||||||
|
|
||||||
# Get CPU info (if detected)
|
# Get CPU info (if detected)
|
||||||
local cpu_vendor="${CPU_VENDOR:-unknown}"
|
local cpu_vendor="${CPU_VENDOR:-unknown}"
|
||||||
local cpu_model
|
local cpu_model="${CPU_MODEL:-}"
|
||||||
cpu_model=$(json_escape "${CPU_MODEL:-}")
|
|
||||||
|
|
||||||
# Get RAM info (if detected)
|
# Get RAM info (if detected)
|
||||||
local ram_speed="${RAM_SPEED:-}"
|
local ram_speed="${RAM_SPEED:-}"
|
||||||
@@ -750,20 +595,13 @@ post_update_to_api() {
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
# For failed/unknown status, resolve exit code and error description
|
# For failed/unknown status, resolve exit code and error description
|
||||||
local short_error=""
|
|
||||||
if [[ "$pb_status" == "failed" ]] || [[ "$pb_status" == "unknown" ]]; then
|
if [[ "$pb_status" == "failed" ]] || [[ "$pb_status" == "unknown" ]]; then
|
||||||
if [[ "$raw_exit_code" =~ ^[0-9]+$ ]]; then
|
if [[ "$raw_exit_code" =~ ^[0-9]+$ ]]; then
|
||||||
exit_code="$raw_exit_code"
|
exit_code="$raw_exit_code"
|
||||||
else
|
else
|
||||||
exit_code=1
|
exit_code=1
|
||||||
fi
|
fi
|
||||||
# Get log lines and build structured error string
|
error=$(explain_exit_code "$exit_code")
|
||||||
local error_text=""
|
|
||||||
error_text=$(get_error_text)
|
|
||||||
local full_error
|
|
||||||
full_error=$(build_error_string "$exit_code" "$error_text")
|
|
||||||
error=$(json_escape "$full_error")
|
|
||||||
short_error=$(json_escape "$(explain_exit_code "$exit_code")")
|
|
||||||
error_category=$(categorize_error "$exit_code")
|
error_category=$(categorize_error "$exit_code")
|
||||||
[[ -z "$error" ]] && error="Unknown error"
|
[[ -z "$error" ]] && error="Unknown error"
|
||||||
fi
|
fi
|
||||||
@@ -780,9 +618,8 @@ post_update_to_api() {
|
|||||||
pve_version=$(pveversion 2>/dev/null | awk -F'[/ ]' '{print $2}') || true
|
pve_version=$(pveversion 2>/dev/null | awk -F'[/ ]' '{print $2}') || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local http_code=""
|
# Full payload including all fields - allows record creation if initial call failed
|
||||||
|
# The Go service will find the record by random_id and PATCH, or create if not found
|
||||||
# ── Attempt 1: Full payload with complete error text ──
|
|
||||||
local JSON_PAYLOAD
|
local JSON_PAYLOAD
|
||||||
JSON_PAYLOAD=$(
|
JSON_PAYLOAD=$(
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
@@ -814,80 +651,11 @@ post_update_to_api() {
|
|||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
# Fire-and-forget: never block, never fail
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "$JSON_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
|
|
||||||
|
|
||||||
if [[ "$http_code" =~ ^2[0-9]{2}$ ]]; then
|
|
||||||
POST_UPDATE_DONE=true
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ── Attempt 2: Short error text (no full log) ──
|
|
||||||
sleep 1
|
|
||||||
local RETRY_PAYLOAD
|
|
||||||
RETRY_PAYLOAD=$(
|
|
||||||
cat <<EOF
|
|
||||||
{
|
|
||||||
"random_id": "${RANDOM_UUID}",
|
|
||||||
"type": "${TELEMETRY_TYPE:-lxc}",
|
|
||||||
"nsapp": "${NSAPP:-unknown}",
|
|
||||||
"status": "${pb_status}",
|
|
||||||
"ct_type": ${CT_TYPE:-1},
|
|
||||||
"disk_size": ${DISK_SIZE:-0},
|
|
||||||
"core_count": ${CORE_COUNT:-0},
|
|
||||||
"ram_size": ${RAM_SIZE:-0},
|
|
||||||
"os_type": "${var_os:-}",
|
|
||||||
"os_version": "${var_version:-}",
|
|
||||||
"pve_version": "${pve_version}",
|
|
||||||
"method": "${METHOD:-default}",
|
|
||||||
"exit_code": ${exit_code},
|
|
||||||
"error": "${short_error}",
|
|
||||||
"error_category": "${error_category}",
|
|
||||||
"install_duration": ${duration},
|
|
||||||
"cpu_vendor": "${cpu_vendor}",
|
|
||||||
"cpu_model": "${cpu_model}",
|
|
||||||
"gpu_vendor": "${gpu_vendor}",
|
|
||||||
"gpu_model": "${gpu_model}",
|
|
||||||
"gpu_passthrough": "${gpu_passthrough}",
|
|
||||||
"ram_speed": "${ram_speed}",
|
|
||||||
"repo_source": "${REPO_SOURCE}"
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "$RETRY_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
|
|
||||||
|
|
||||||
if [[ "$http_code" =~ ^2[0-9]{2}$ ]]; then
|
|
||||||
POST_UPDATE_DONE=true
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ── Attempt 3: Minimal payload (bare minimum to set status) ──
|
|
||||||
sleep 2
|
|
||||||
local MINIMAL_PAYLOAD
|
|
||||||
MINIMAL_PAYLOAD=$(
|
|
||||||
cat <<EOF
|
|
||||||
{
|
|
||||||
"random_id": "${RANDOM_UUID}",
|
|
||||||
"type": "${TELEMETRY_TYPE:-lxc}",
|
|
||||||
"nsapp": "${NSAPP:-unknown}",
|
|
||||||
"status": "${pb_status}",
|
|
||||||
"exit_code": ${exit_code},
|
|
||||||
"error": "${short_error}",
|
|
||||||
"error_category": "${error_category}",
|
|
||||||
"install_duration": ${duration}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
)
|
|
||||||
|
|
||||||
curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$MINIMAL_PAYLOAD" -o /dev/null 2>/dev/null || true
|
-d "$JSON_PAYLOAD" -o /dev/null 2>&1 || true
|
||||||
|
|
||||||
# Tried 3 times - mark as done regardless to prevent infinite loops
|
|
||||||
POST_UPDATE_DONE=true
|
POST_UPDATE_DONE=true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -905,55 +673,28 @@ EOF
|
|||||||
categorize_error() {
|
categorize_error() {
|
||||||
local code="$1"
|
local code="$1"
|
||||||
case "$code" in
|
case "$code" in
|
||||||
# Network errors (curl/wget)
|
# Network errors
|
||||||
6 | 7 | 22 | 35) echo "network" ;;
|
6 | 7 | 22 | 28 | 35) echo "network" ;;
|
||||||
|
|
||||||
# Docker / Privileged mode required
|
# Storage errors
|
||||||
10) echo "config" ;;
|
214 | 217 | 219) echo "storage" ;;
|
||||||
|
|
||||||
# Timeout errors
|
# Dependency/Package errors
|
||||||
28 | 124 | 211) echo "timeout" ;;
|
100 | 101 | 102 | 127 | 160 | 161 | 162) echo "dependency" ;;
|
||||||
|
|
||||||
# Storage errors (Proxmox storage)
|
|
||||||
214 | 217 | 219 | 224) echo "storage" ;;
|
|
||||||
|
|
||||||
# Dependency/Package errors (APT, DPKG, pip, commands)
|
|
||||||
100 | 101 | 102 | 127 | 160 | 161 | 162 | 255) echo "dependency" ;;
|
|
||||||
|
|
||||||
# Permission errors
|
# Permission errors
|
||||||
126 | 152) echo "permission" ;;
|
126 | 152) echo "permission" ;;
|
||||||
|
|
||||||
# Configuration errors (Proxmox config, invalid args)
|
# Timeout errors
|
||||||
128 | 203 | 204 | 205 | 206 | 207 | 208) echo "config" ;;
|
124 | 28 | 211) echo "timeout" ;;
|
||||||
|
|
||||||
# Proxmox container/template errors
|
# Configuration errors
|
||||||
200 | 209 | 210 | 212 | 213 | 215 | 216 | 218 | 220 | 221 | 222 | 223 | 225 | 231) echo "proxmox" ;;
|
203 | 204 | 205 | 206 | 207 | 208) echo "config" ;;
|
||||||
|
|
||||||
# Service/Systemd errors
|
# Resource errors (OOM, etc)
|
||||||
150 | 151 | 153 | 154) echo "service" ;;
|
137 | 134) echo "resource" ;;
|
||||||
|
|
||||||
# Database errors (PostgreSQL, MySQL, MongoDB)
|
# Default
|
||||||
170 | 171 | 172 | 173 | 180 | 181 | 182 | 183 | 190 | 191 | 192 | 193) echo "database" ;;
|
|
||||||
|
|
||||||
# Node.js / JavaScript runtime errors
|
|
||||||
243 | 245 | 246 | 247 | 248 | 249) echo "runtime" ;;
|
|
||||||
|
|
||||||
# Python environment errors
|
|
||||||
# (already covered: 160-162 under dependency)
|
|
||||||
|
|
||||||
# Aborted by user
|
|
||||||
130) echo "aborted" ;;
|
|
||||||
|
|
||||||
# Resource errors (OOM, SIGKILL, SIGABRT)
|
|
||||||
134 | 137) echo "resource" ;;
|
|
||||||
|
|
||||||
# Signal/Process errors (SIGTERM, SIGPIPE, SIGSEGV)
|
|
||||||
139 | 141 | 143) echo "signal" ;;
|
|
||||||
|
|
||||||
# Shell errors (general error, syntax error)
|
|
||||||
1 | 2) echo "shell" ;;
|
|
||||||
|
|
||||||
# Default - truly unknown
|
|
||||||
*) echo "unknown" ;;
|
*) echo "unknown" ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
@@ -985,62 +726,6 @@ get_install_duration() {
|
|||||||
echo $((now - INSTALL_START_TIME))
|
echo $((now - INSTALL_START_TIME))
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# _telemetry_report_exit()
|
|
||||||
#
|
|
||||||
# - Internal handler called by EXIT trap set in init_tool_telemetry()
|
|
||||||
# - Determines success/failure from exit code and reports via appropriate API
|
|
||||||
# - Arguments:
|
|
||||||
# * $1: exit_code from the script
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
_telemetry_report_exit() {
|
|
||||||
local ec="${1:-0}"
|
|
||||||
local status="success"
|
|
||||||
[[ "$ec" -ne 0 ]] && status="failed"
|
|
||||||
|
|
||||||
# Lazy name resolution: use explicit name, fall back to $APP, then "unknown"
|
|
||||||
local name="${TELEMETRY_TOOL_NAME:-${APP:-unknown}}"
|
|
||||||
|
|
||||||
if [[ "${TELEMETRY_TOOL_TYPE:-tool}" == "addon" ]]; then
|
|
||||||
post_addon_to_api "$name" "$status" "$ec"
|
|
||||||
else
|
|
||||||
post_tool_to_api "$name" "$status" "$ec"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# init_tool_telemetry()
|
|
||||||
#
|
|
||||||
# - One-line telemetry setup for tools/addon scripts
|
|
||||||
# - Reads DIAGNOSTICS from /usr/local/community-scripts/diagnostics
|
|
||||||
# - Starts install timer for duration tracking
|
|
||||||
# - Sets EXIT trap to automatically report success/failure on script exit
|
|
||||||
# - Arguments:
|
|
||||||
# * $1: tool_name (optional, falls back to $APP at exit time)
|
|
||||||
# * $2: type ("tool" for PVE host scripts, "addon" for container addons)
|
|
||||||
# - Usage:
|
|
||||||
# source <(curl -fsSL .../misc/api.func) 2>/dev/null || true
|
|
||||||
# init_tool_telemetry "post-pve-install" "tool"
|
|
||||||
# init_tool_telemetry "" "addon" # uses $APP at exit time
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
init_tool_telemetry() {
|
|
||||||
local name="${1:-}"
|
|
||||||
local type="${2:-tool}"
|
|
||||||
|
|
||||||
[[ -n "$name" ]] && TELEMETRY_TOOL_NAME="$name"
|
|
||||||
TELEMETRY_TOOL_TYPE="$type"
|
|
||||||
|
|
||||||
# Read diagnostics opt-in/opt-out
|
|
||||||
if [[ -f /usr/local/community-scripts/diagnostics ]]; then
|
|
||||||
DIAGNOSTICS=$(grep -i "^DIAGNOSTICS=" /usr/local/community-scripts/diagnostics 2>/dev/null | awk -F'=' '{print $2}') || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
start_install_timer
|
|
||||||
|
|
||||||
# EXIT trap: automatically report telemetry when script ends
|
|
||||||
trap '_telemetry_report_exit "$?"' EXIT
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# post_tool_to_api()
|
# post_tool_to_api()
|
||||||
#
|
#
|
||||||
@@ -1070,11 +755,7 @@ post_tool_to_api() {
|
|||||||
|
|
||||||
if [[ "$status" == "failed" ]]; then
|
if [[ "$status" == "failed" ]]; then
|
||||||
[[ ! "$exit_code" =~ ^[0-9]+$ ]] && exit_code=1
|
[[ ! "$exit_code" =~ ^[0-9]+$ ]] && exit_code=1
|
||||||
local error_text=""
|
error=$(explain_exit_code "$exit_code")
|
||||||
error_text=$(get_error_text)
|
|
||||||
local full_error
|
|
||||||
full_error=$(build_error_string "$exit_code" "$error_text")
|
|
||||||
error=$(json_escape "$full_error")
|
|
||||||
error_category=$(categorize_error "$exit_code")
|
error_category=$(categorize_error "$exit_code")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1135,11 +816,7 @@ post_addon_to_api() {
|
|||||||
|
|
||||||
if [[ "$status" == "failed" ]]; then
|
if [[ "$status" == "failed" ]]; then
|
||||||
[[ ! "$exit_code" =~ ^[0-9]+$ ]] && exit_code=1
|
[[ ! "$exit_code" =~ ^[0-9]+$ ]] && exit_code=1
|
||||||
local error_text=""
|
error=$(explain_exit_code "$exit_code")
|
||||||
error_text=$(get_error_text)
|
|
||||||
local full_error
|
|
||||||
full_error=$(build_error_string "$exit_code" "$error_text")
|
|
||||||
error=$(json_escape "$full_error")
|
|
||||||
error_category=$(categorize_error "$exit_code")
|
error_category=$(categorize_error "$exit_code")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -1232,11 +909,7 @@ post_update_to_api_extended() {
|
|||||||
else
|
else
|
||||||
exit_code=1
|
exit_code=1
|
||||||
fi
|
fi
|
||||||
local error_text=""
|
error=$(explain_exit_code "$exit_code")
|
||||||
error_text=$(get_error_text)
|
|
||||||
local full_error
|
|
||||||
full_error=$(build_error_string "$exit_code" "$error_text")
|
|
||||||
error=$(json_escape "$full_error")
|
|
||||||
error_category=$(categorize_error "$exit_code")
|
error_category=$(categorize_error "$exit_code")
|
||||||
[[ -z "$error" ]] && error="Unknown error"
|
[[ -z "$error" ]] && error="Unknown error"
|
||||||
fi
|
fi
|
||||||
|
|||||||
844
misc/build.func
844
misc/build.func
File diff suppressed because it is too large
Load Diff
652
misc/core.func
652
misc/core.func
@@ -115,7 +115,7 @@ icons() {
|
|||||||
BRIDGE="${TAB}🌉${TAB}${CL}"
|
BRIDGE="${TAB}🌉${TAB}${CL}"
|
||||||
NETWORK="${TAB}📡${TAB}${CL}"
|
NETWORK="${TAB}📡${TAB}${CL}"
|
||||||
GATEWAY="${TAB}🌐${TAB}${CL}"
|
GATEWAY="${TAB}🌐${TAB}${CL}"
|
||||||
ICON_DISABLEIPV6="${TAB}🚫${TAB}${CL}"
|
DISABLEIPV6="${TAB}🚫${TAB}${CL}"
|
||||||
DEFAULT="${TAB}⚙️${TAB}${CL}"
|
DEFAULT="${TAB}⚙️${TAB}${CL}"
|
||||||
MACADDRESS="${TAB}🔗${TAB}${CL}"
|
MACADDRESS="${TAB}🔗${TAB}${CL}"
|
||||||
VLANTAG="${TAB}🏷️${TAB}${CL}"
|
VLANTAG="${TAB}🏷️${TAB}${CL}"
|
||||||
@@ -413,69 +413,6 @@ get_active_logfile() {
|
|||||||
# Legacy compatibility: SILENT_LOGFILE points to active log
|
# Legacy compatibility: SILENT_LOGFILE points to active log
|
||||||
SILENT_LOGFILE="$(get_active_logfile)"
|
SILENT_LOGFILE="$(get_active_logfile)"
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# strip_ansi()
|
|
||||||
#
|
|
||||||
# - Removes ANSI escape sequences from input text
|
|
||||||
# - Used to clean colored output for log files
|
|
||||||
# - Handles both piped input and arguments
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
strip_ansi() {
|
|
||||||
if [[ $# -gt 0 ]]; then
|
|
||||||
echo -e "$*" | sed 's/\x1b\[[0-9;]*m//g; s/\x1b\[[0-9;]*[a-zA-Z]//g'
|
|
||||||
else
|
|
||||||
sed 's/\x1b\[[0-9;]*m//g; s/\x1b\[[0-9;]*[a-zA-Z]//g'
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# log_msg()
|
|
||||||
#
|
|
||||||
# - Writes message to active log file without ANSI codes
|
|
||||||
# - Adds timestamp prefix for log correlation
|
|
||||||
# - Creates log file if it doesn't exist
|
|
||||||
# - Arguments: message text (can include ANSI codes, will be stripped)
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
log_msg() {
|
|
||||||
local msg="$*"
|
|
||||||
local logfile
|
|
||||||
logfile="$(get_active_logfile)"
|
|
||||||
|
|
||||||
[[ -z "$msg" ]] && return
|
|
||||||
[[ -z "$logfile" ]] && return
|
|
||||||
|
|
||||||
# Ensure log directory exists
|
|
||||||
mkdir -p "$(dirname "$logfile")" 2>/dev/null || true
|
|
||||||
|
|
||||||
# Strip ANSI codes and write with timestamp
|
|
||||||
local clean_msg
|
|
||||||
clean_msg=$(strip_ansi "$msg")
|
|
||||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $clean_msg" >>"$logfile"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# log_section()
|
|
||||||
#
|
|
||||||
# - Writes a section header to the log file
|
|
||||||
# - Used for separating different phases of installation
|
|
||||||
# - Arguments: section name
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
log_section() {
|
|
||||||
local section="$1"
|
|
||||||
local logfile
|
|
||||||
logfile="$(get_active_logfile)"
|
|
||||||
|
|
||||||
[[ -z "$logfile" ]] && return
|
|
||||||
mkdir -p "$(dirname "$logfile")" 2>/dev/null || true
|
|
||||||
|
|
||||||
{
|
|
||||||
echo ""
|
|
||||||
echo "================================================================================"
|
|
||||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $section"
|
|
||||||
echo "================================================================================"
|
|
||||||
} >>"$logfile"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# silent()
|
# silent()
|
||||||
#
|
#
|
||||||
@@ -522,9 +459,15 @@ silent() {
|
|||||||
msg_custom "→" "${YWB}" "${cmd}"
|
msg_custom "→" "${YWB}" "${cmd}"
|
||||||
|
|
||||||
if [[ -s "$logfile" ]]; then
|
if [[ -s "$logfile" ]]; then
|
||||||
echo -e "\n${TAB}--- Last 10 lines of log ---"
|
local log_lines=$(wc -l <"$logfile")
|
||||||
|
echo "--- Last 10 lines of silent log ---"
|
||||||
tail -n 10 "$logfile"
|
tail -n 10 "$logfile"
|
||||||
echo -e "${TAB}-----------------------------------\n"
|
echo "-----------------------------------"
|
||||||
|
|
||||||
|
# Show how to view full log if there are more lines
|
||||||
|
if [[ $log_lines -gt 10 ]]; then
|
||||||
|
msg_custom "📋" "${YW}" "View full log (${log_lines} lines): ${logfile}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit "$rc"
|
exit "$rc"
|
||||||
@@ -545,7 +488,7 @@ spinner() {
|
|||||||
local i=0
|
local i=0
|
||||||
while true; do
|
while true; do
|
||||||
local index=$((i++ % ${#chars[@]}))
|
local index=$((i++ % ${#chars[@]}))
|
||||||
printf "\r\033[2K%s %b" "${CS_YWB}${chars[$index]}${CS_CL}" "${CS_YWB}${msg}${CS_CL}"
|
printf "\r\033[2K%s %b" "${CS_YWB}${TAB}${chars[$index]}${TAB}${CS_CL}" "${CS_YWB}${msg}${CS_CL}"
|
||||||
sleep 0.1
|
sleep 0.1
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
@@ -612,9 +555,6 @@ msg_info() {
|
|||||||
[[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return
|
[[ -n "${MSG_INFO_SHOWN["$msg"]+x}" ]] && return
|
||||||
MSG_INFO_SHOWN["$msg"]=1
|
MSG_INFO_SHOWN["$msg"]=1
|
||||||
|
|
||||||
# Log to file
|
|
||||||
log_msg "[INFO] $msg"
|
|
||||||
|
|
||||||
stop_spinner
|
stop_spinner
|
||||||
SPINNER_MSG="$msg"
|
SPINNER_MSG="$msg"
|
||||||
|
|
||||||
@@ -658,10 +598,7 @@ msg_ok() {
|
|||||||
stop_spinner
|
stop_spinner
|
||||||
clear_line
|
clear_line
|
||||||
echo -e "$CM ${GN}${msg}${CL}"
|
echo -e "$CM ${GN}${msg}${CL}"
|
||||||
log_msg "[OK] $msg"
|
unset MSG_INFO_SHOWN["$msg"]
|
||||||
local sanitized_msg
|
|
||||||
sanitized_msg=$(printf '%s' "$msg" | sed 's/\x1b\[[0-9;]*m//g; s/[^a-zA-Z0-9_]/_/g')
|
|
||||||
unset 'MSG_INFO_SHOWN['"$sanitized_msg"']' 2>/dev/null || true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -676,7 +613,6 @@ msg_error() {
|
|||||||
stop_spinner
|
stop_spinner
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${BFR:-}${CROSS:-✖️} ${RD}${msg}${CL}" >&2
|
echo -e "${BFR:-}${CROSS:-✖️} ${RD}${msg}${CL}" >&2
|
||||||
log_msg "[ERROR] $msg"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -691,7 +627,6 @@ msg_warn() {
|
|||||||
stop_spinner
|
stop_spinner
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${BFR:-}${INFO:-ℹ️} ${YWB}${msg}${CL}" >&2
|
echo -e "${BFR:-}${INFO:-ℹ️} ${YWB}${msg}${CL}" >&2
|
||||||
log_msg "[WARN] $msg"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -709,7 +644,6 @@ msg_custom() {
|
|||||||
[[ -z "$msg" ]] && return
|
[[ -z "$msg" ]] && return
|
||||||
stop_spinner
|
stop_spinner
|
||||||
echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}"
|
echo -e "${BFR:-} ${symbol} ${color}${msg}${CL:-\e[0m}"
|
||||||
log_msg "$msg"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -874,562 +808,6 @@ is_verbose_mode() {
|
|||||||
[[ "$verbose" != "no" || ! -t 2 ]]
|
[[ "$verbose" != "no" || ! -t 2 ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# is_unattended()
|
|
||||||
#
|
|
||||||
# - Detects if script is running in unattended/non-interactive mode
|
|
||||||
# - Checks MODE variable first (primary method)
|
|
||||||
# - Falls back to legacy flags (PHS_SILENT, var_unattended)
|
|
||||||
# - Returns 0 (true) if unattended, 1 (false) otherwise
|
|
||||||
# - Used by prompt functions to auto-apply defaults
|
|
||||||
#
|
|
||||||
# Modes that are unattended:
|
|
||||||
# - default (1) : Use script defaults, no prompts
|
|
||||||
# - mydefaults (3) : Use user's default.vars, no prompts
|
|
||||||
# - appdefaults (4) : Use app-specific defaults, no prompts
|
|
||||||
#
|
|
||||||
# Modes that are interactive:
|
|
||||||
# - advanced (2) : Full wizard with all options
|
|
||||||
#
|
|
||||||
# Note: Even in advanced mode, install scripts run unattended because
|
|
||||||
# all values are already collected during the wizard phase.
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
is_unattended() {
|
|
||||||
# Primary: Check MODE variable (case-insensitive)
|
|
||||||
local mode="${MODE:-${mode:-}}"
|
|
||||||
mode="${mode,,}" # lowercase
|
|
||||||
|
|
||||||
case "$mode" in
|
|
||||||
default | 1)
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
mydefaults | userdefaults | 3)
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
appdefaults | 4)
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
advanced | 2)
|
|
||||||
# Advanced mode is interactive ONLY during wizard
|
|
||||||
# Inside container (install scripts), it should be unattended
|
|
||||||
# Check if we're inside a container (no pveversion command)
|
|
||||||
if ! command -v pveversion &>/dev/null; then
|
|
||||||
# We're inside the container - all values already collected
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
# On host during wizard - interactive
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Legacy fallbacks for compatibility
|
|
||||||
[[ "${PHS_SILENT:-0}" == "1" ]] && return 0
|
|
||||||
[[ "${var_unattended:-}" =~ ^(yes|true|1)$ ]] && return 0
|
|
||||||
[[ "${UNATTENDED:-}" =~ ^(yes|true|1)$ ]] && return 0
|
|
||||||
|
|
||||||
# No TTY available = unattended
|
|
||||||
[[ ! -t 0 ]] && return 0
|
|
||||||
|
|
||||||
# Default: interactive
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# show_missing_values_warning()
|
|
||||||
#
|
|
||||||
# - Displays a summary of required values that used fallback defaults
|
|
||||||
# - Should be called at the end of install scripts
|
|
||||||
# - Only shows warning if MISSING_REQUIRED_VALUES array has entries
|
|
||||||
# - Provides clear guidance on what needs manual configuration
|
|
||||||
#
|
|
||||||
# Global:
|
|
||||||
# MISSING_REQUIRED_VALUES - Array of variable names that need configuration
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
# # At end of install script:
|
|
||||||
# show_missing_values_warning
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
show_missing_values_warning() {
|
|
||||||
if [[ ${#MISSING_REQUIRED_VALUES[@]} -gt 0 ]]; then
|
|
||||||
echo ""
|
|
||||||
echo -e "${YW}╔════════════════════════════════════════════════════════════╗${CL}"
|
|
||||||
echo -e "${YW}║ ⚠️ MANUAL CONFIGURATION REQUIRED ║${CL}"
|
|
||||||
echo -e "${YW}╠════════════════════════════════════════════════════════════╣${CL}"
|
|
||||||
echo -e "${YW}║ The following values were not provided and need to be ║${CL}"
|
|
||||||
echo -e "${YW}║ configured manually for the service to work properly: ║${CL}"
|
|
||||||
echo -e "${YW}╟────────────────────────────────────────────────────────────╢${CL}"
|
|
||||||
for val in "${MISSING_REQUIRED_VALUES[@]}"; do
|
|
||||||
printf "${YW}║${CL} • %-56s ${YW}║${CL}\n" "$val"
|
|
||||||
done
|
|
||||||
echo -e "${YW}╟────────────────────────────────────────────────────────────╢${CL}"
|
|
||||||
echo -e "${YW}║ Check the service configuration files or environment ║${CL}"
|
|
||||||
echo -e "${YW}║ variables and update the placeholder values. ║${CL}"
|
|
||||||
echo -e "${YW}╚════════════════════════════════════════════════════════════╝${CL}"
|
|
||||||
echo ""
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# prompt_confirm()
|
|
||||||
#
|
|
||||||
# - Prompts user for yes/no confirmation with timeout and unattended support
|
|
||||||
# - In unattended mode: immediately returns default value
|
|
||||||
# - In interactive mode: waits for user input with configurable timeout
|
|
||||||
# - After timeout: auto-applies default value
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# $1 - Prompt message (required)
|
|
||||||
# $2 - Default value: "y" or "n" (optional, default: "n")
|
|
||||||
# $3 - Timeout in seconds (optional, default: 60)
|
|
||||||
#
|
|
||||||
# Returns:
|
|
||||||
# 0 - User confirmed (yes)
|
|
||||||
# 1 - User declined (no) or timeout with default "n"
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
# if prompt_confirm "Proceed with installation?" "y" 30; then
|
|
||||||
# echo "Installing..."
|
|
||||||
# fi
|
|
||||||
#
|
|
||||||
# # Unattended: prompt_confirm will use default without waiting
|
|
||||||
# var_unattended=yes
|
|
||||||
# prompt_confirm "Delete files?" "n" && echo "Deleting" || echo "Skipped"
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
prompt_confirm() {
|
|
||||||
local message="${1:-Confirm?}"
|
|
||||||
local default="${2:-n}"
|
|
||||||
local timeout="${3:-60}"
|
|
||||||
local response
|
|
||||||
|
|
||||||
# Normalize default to lowercase
|
|
||||||
default="${default,,}"
|
|
||||||
[[ "$default" != "y" ]] && default="n"
|
|
||||||
|
|
||||||
# Build prompt hint
|
|
||||||
local hint
|
|
||||||
if [[ "$default" == "y" ]]; then
|
|
||||||
hint="[Y/n]"
|
|
||||||
else
|
|
||||||
hint="[y/N]"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Unattended mode: apply default immediately
|
|
||||||
if is_unattended; then
|
|
||||||
if [[ "$default" == "y" ]]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if running in a TTY
|
|
||||||
if [[ ! -t 0 ]]; then
|
|
||||||
# Not a TTY, use default
|
|
||||||
if [[ "$default" == "y" ]]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Interactive prompt with timeout
|
|
||||||
echo -en "${YW}${message} ${hint} (auto-${default} in ${timeout}s): ${CL}"
|
|
||||||
|
|
||||||
if read -t "$timeout" -r response; then
|
|
||||||
# User provided input
|
|
||||||
response="${response,,}" # lowercase
|
|
||||||
case "$response" in
|
|
||||||
y | yes)
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
n | no)
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
"")
|
|
||||||
# Empty response, use default
|
|
||||||
if [[ "$default" == "y" ]]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# Invalid input, use default
|
|
||||||
echo -e "${YW}Invalid response, using default: ${default}${CL}"
|
|
||||||
if [[ "$default" == "y" ]]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
# Timeout occurred
|
|
||||||
echo "" # Newline after timeout
|
|
||||||
echo -e "${YW}Timeout - auto-selecting: ${default}${CL}"
|
|
||||||
if [[ "$default" == "y" ]]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# prompt_input()
|
|
||||||
#
|
|
||||||
# - Prompts user for text input with timeout and unattended support
|
|
||||||
# - In unattended mode: immediately returns default value
|
|
||||||
# - In interactive mode: waits for user input with configurable timeout
|
|
||||||
# - After timeout: auto-applies default value
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# $1 - Prompt message (required)
|
|
||||||
# $2 - Default value (optional, default: "")
|
|
||||||
# $3 - Timeout in seconds (optional, default: 60)
|
|
||||||
#
|
|
||||||
# Output:
|
|
||||||
# Prints the user input or default value to stdout
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
# username=$(prompt_input "Enter username:" "admin" 30)
|
|
||||||
# echo "Using username: $username"
|
|
||||||
#
|
|
||||||
# # With validation
|
|
||||||
# while true; do
|
|
||||||
# port=$(prompt_input "Enter port:" "8080" 30)
|
|
||||||
# [[ "$port" =~ ^[0-9]+$ ]] && break
|
|
||||||
# echo "Invalid port number"
|
|
||||||
# done
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
prompt_input() {
|
|
||||||
local message="${1:-Enter value:}"
|
|
||||||
local default="${2:-}"
|
|
||||||
local timeout="${3:-60}"
|
|
||||||
local response
|
|
||||||
|
|
||||||
# Build display default hint
|
|
||||||
local hint=""
|
|
||||||
[[ -n "$default" ]] && hint=" (default: ${default})"
|
|
||||||
|
|
||||||
# Unattended mode: return default immediately
|
|
||||||
if is_unattended; then
|
|
||||||
echo "$default"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if running in a TTY
|
|
||||||
if [[ ! -t 0 ]]; then
|
|
||||||
# Not a TTY, use default
|
|
||||||
echo "$default"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Interactive prompt with timeout
|
|
||||||
echo -en "${YW}${message}${hint} (auto-default in ${timeout}s): ${CL}" >&2
|
|
||||||
|
|
||||||
if read -t "$timeout" -r response; then
|
|
||||||
# User provided input (or pressed Enter for empty)
|
|
||||||
if [[ -n "$response" ]]; then
|
|
||||||
echo "$response"
|
|
||||||
else
|
|
||||||
echo "$default"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Timeout occurred
|
|
||||||
echo "" >&2 # Newline after timeout
|
|
||||||
echo -e "${YW}Timeout - using default: ${default}${CL}" >&2
|
|
||||||
echo "$default"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# prompt_input_required()
|
|
||||||
#
|
|
||||||
# - Prompts user for REQUIRED text input with fallback support
|
|
||||||
# - In unattended mode: Uses fallback value if no env var set (with warning)
|
|
||||||
# - In interactive mode: loops until user provides non-empty input
|
|
||||||
# - Tracks missing required values for end-of-script summary
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# $1 - Prompt message (required)
|
|
||||||
# $2 - Fallback/example value for unattended mode (optional)
|
|
||||||
# $3 - Timeout in seconds (optional, default: 120)
|
|
||||||
# $4 - Environment variable name hint for error messages (optional)
|
|
||||||
#
|
|
||||||
# Output:
|
|
||||||
# Prints the user input or fallback value to stdout
|
|
||||||
#
|
|
||||||
# Returns:
|
|
||||||
# 0 - Success (value provided or fallback used)
|
|
||||||
# 1 - Failed (interactive timeout without input)
|
|
||||||
#
|
|
||||||
# Global:
|
|
||||||
# MISSING_REQUIRED_VALUES - Array tracking fields that used fallbacks
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
# # With fallback - script continues even in unattended mode
|
|
||||||
# token=$(prompt_input_required "Enter API Token:" "YOUR_TOKEN_HERE" 60 "var_api_token")
|
|
||||||
#
|
|
||||||
# # Check at end of script if any values need manual configuration
|
|
||||||
# if [[ ${#MISSING_REQUIRED_VALUES[@]} -gt 0 ]]; then
|
|
||||||
# msg_warn "Please configure: ${MISSING_REQUIRED_VALUES[*]}"
|
|
||||||
# fi
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# Global array to track missing required values
|
|
||||||
declare -g -a MISSING_REQUIRED_VALUES=()
|
|
||||||
|
|
||||||
prompt_input_required() {
|
|
||||||
local message="${1:-Enter required value:}"
|
|
||||||
local fallback="${2:-CHANGE_ME}"
|
|
||||||
local timeout="${3:-120}"
|
|
||||||
local env_var_hint="${4:-}"
|
|
||||||
local response=""
|
|
||||||
|
|
||||||
# Check if value is already set via environment variable (if hint provided)
|
|
||||||
if [[ -n "$env_var_hint" ]]; then
|
|
||||||
local env_value="${!env_var_hint:-}"
|
|
||||||
if [[ -n "$env_value" ]]; then
|
|
||||||
echo "$env_value"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Unattended mode: use fallback with warning
|
|
||||||
if is_unattended; then
|
|
||||||
if [[ -n "$env_var_hint" ]]; then
|
|
||||||
echo -e "${YW}⚠ Required value '${env_var_hint}' not set - using fallback: ${fallback}${CL}" >&2
|
|
||||||
MISSING_REQUIRED_VALUES+=("$env_var_hint")
|
|
||||||
else
|
|
||||||
echo -e "${YW}⚠ Required value not provided - using fallback: ${fallback}${CL}" >&2
|
|
||||||
MISSING_REQUIRED_VALUES+=("(unnamed)")
|
|
||||||
fi
|
|
||||||
echo "$fallback"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if running in a TTY
|
|
||||||
if [[ ! -t 0 ]]; then
|
|
||||||
echo -e "${YW}⚠ Not interactive - using fallback: ${fallback}${CL}" >&2
|
|
||||||
MISSING_REQUIRED_VALUES+=("${env_var_hint:-unnamed}")
|
|
||||||
echo "$fallback"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Interactive prompt - loop until non-empty input or use fallback on timeout
|
|
||||||
local attempts=0
|
|
||||||
while [[ -z "$response" ]]; do
|
|
||||||
attempts=$((attempts + 1))
|
|
||||||
|
|
||||||
if [[ $attempts -gt 3 ]]; then
|
|
||||||
echo -e "${YW}Too many empty inputs - using fallback: ${fallback}${CL}" >&2
|
|
||||||
MISSING_REQUIRED_VALUES+=("${env_var_hint:-manual_input}")
|
|
||||||
echo "$fallback"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -en "${YW}${message} (required, timeout ${timeout}s): ${CL}" >&2
|
|
||||||
|
|
||||||
if read -t "$timeout" -r response; then
|
|
||||||
if [[ -z "$response" ]]; then
|
|
||||||
echo -e "${YW}This field is required. Please enter a value. (attempt ${attempts}/3)${CL}" >&2
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Timeout occurred - use fallback
|
|
||||||
echo "" >&2
|
|
||||||
echo -e "${YW}Timeout - using fallback value: ${fallback}${CL}" >&2
|
|
||||||
MISSING_REQUIRED_VALUES+=("${env_var_hint:-timeout}")
|
|
||||||
echo "$fallback"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "$response"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# prompt_select()
|
|
||||||
#
|
|
||||||
# - Prompts user to select from a list of options with timeout support
|
|
||||||
# - In unattended mode: immediately returns default selection
|
|
||||||
# - In interactive mode: displays numbered menu and waits for choice
|
|
||||||
# - After timeout: auto-applies default selection
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# $1 - Prompt message (required)
|
|
||||||
# $2 - Default option number, 1-based (optional, default: 1)
|
|
||||||
# $3 - Timeout in seconds (optional, default: 60)
|
|
||||||
# $4+ - Options to display (required, at least 2)
|
|
||||||
#
|
|
||||||
# Output:
|
|
||||||
# Prints the selected option value to stdout
|
|
||||||
#
|
|
||||||
# Returns:
|
|
||||||
# 0 - Success
|
|
||||||
# 1 - No options provided or invalid state
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
# choice=$(prompt_select "Select database:" 1 30 "PostgreSQL" "MySQL" "SQLite")
|
|
||||||
# echo "Selected: $choice"
|
|
||||||
#
|
|
||||||
# # With array
|
|
||||||
# options=("Option A" "Option B" "Option C")
|
|
||||||
# selected=$(prompt_select "Choose:" 2 60 "${options[@]}")
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
prompt_select() {
|
|
||||||
local message="${1:-Select option:}"
|
|
||||||
local default="${2:-1}"
|
|
||||||
local timeout="${3:-60}"
|
|
||||||
shift 3
|
|
||||||
|
|
||||||
local options=("$@")
|
|
||||||
local num_options=${#options[@]}
|
|
||||||
|
|
||||||
# Validate options
|
|
||||||
if [[ $num_options -eq 0 ]]; then
|
|
||||||
echo "" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Validate default
|
|
||||||
if [[ ! "$default" =~ ^[0-9]+$ ]] || [[ "$default" -lt 1 ]] || [[ "$default" -gt "$num_options" ]]; then
|
|
||||||
default=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Unattended mode: return default immediately
|
|
||||||
if is_unattended; then
|
|
||||||
echo "${options[$((default - 1))]}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if running in a TTY
|
|
||||||
if [[ ! -t 0 ]]; then
|
|
||||||
echo "${options[$((default - 1))]}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Display menu
|
|
||||||
echo -e "${YW}${message}${CL}" >&2
|
|
||||||
local i
|
|
||||||
for i in "${!options[@]}"; do
|
|
||||||
local num=$((i + 1))
|
|
||||||
if [[ $num -eq $default ]]; then
|
|
||||||
echo -e " ${GN}${num})${CL} ${options[$i]} ${YW}(default)${CL}" >&2
|
|
||||||
else
|
|
||||||
echo -e " ${GN}${num})${CL} ${options[$i]}" >&2
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Interactive prompt with timeout
|
|
||||||
echo -en "${YW}Select [1-${num_options}] (auto-select ${default} in ${timeout}s): ${CL}" >&2
|
|
||||||
|
|
||||||
local response
|
|
||||||
if read -t "$timeout" -r response; then
|
|
||||||
if [[ -z "$response" ]]; then
|
|
||||||
# Empty response, use default
|
|
||||||
echo "${options[$((default - 1))]}"
|
|
||||||
elif [[ "$response" =~ ^[0-9]+$ ]] && [[ "$response" -ge 1 ]] && [[ "$response" -le "$num_options" ]]; then
|
|
||||||
# Valid selection
|
|
||||||
echo "${options[$((response - 1))]}"
|
|
||||||
else
|
|
||||||
# Invalid input, use default
|
|
||||||
echo -e "${YW}Invalid selection, using default: ${options[$((default - 1))]}${CL}" >&2
|
|
||||||
echo "${options[$((default - 1))]}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Timeout occurred
|
|
||||||
echo "" >&2 # Newline after timeout
|
|
||||||
echo -e "${YW}Timeout - auto-selecting: ${options[$((default - 1))]}${CL}" >&2
|
|
||||||
echo "${options[$((default - 1))]}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# prompt_password()
|
|
||||||
#
|
|
||||||
# - Prompts user for password input with hidden characters
|
|
||||||
# - In unattended mode: returns default or generates random password
|
|
||||||
# - Supports auto-generation of secure passwords
|
|
||||||
# - After timeout: generates random password if allowed
|
|
||||||
#
|
|
||||||
# Arguments:
|
|
||||||
# $1 - Prompt message (required)
|
|
||||||
# $2 - Default value or "generate" for auto-generation (optional)
|
|
||||||
# $3 - Timeout in seconds (optional, default: 60)
|
|
||||||
# $4 - Minimum length for validation (optional, default: 0 = no minimum)
|
|
||||||
#
|
|
||||||
# Output:
|
|
||||||
# Prints the password to stdout
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
# password=$(prompt_password "Enter password:" "generate" 30 8)
|
|
||||||
# echo "Password set"
|
|
||||||
#
|
|
||||||
# # Require user input (no default)
|
|
||||||
# db_pass=$(prompt_password "Database password:" "" 60 12)
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
prompt_password() {
|
|
||||||
local message="${1:-Enter password:}"
|
|
||||||
local default="${2:-}"
|
|
||||||
local timeout="${3:-60}"
|
|
||||||
local min_length="${4:-0}"
|
|
||||||
local response
|
|
||||||
|
|
||||||
# Generate random password if requested
|
|
||||||
local generated=""
|
|
||||||
if [[ "$default" == "generate" ]]; then
|
|
||||||
generated=$(openssl rand -base64 16 2>/dev/null | tr -dc 'a-zA-Z0-9' | head -c 16)
|
|
||||||
[[ -z "$generated" ]] && generated=$(head /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 16)
|
|
||||||
default="$generated"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Unattended mode: return default immediately
|
|
||||||
if is_unattended; then
|
|
||||||
echo "$default"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if running in a TTY
|
|
||||||
if [[ ! -t 0 ]]; then
|
|
||||||
echo "$default"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build hint
|
|
||||||
local hint=""
|
|
||||||
if [[ -n "$generated" ]]; then
|
|
||||||
hint=" (Enter for auto-generated)"
|
|
||||||
elif [[ -n "$default" ]]; then
|
|
||||||
hint=" (Enter for default)"
|
|
||||||
fi
|
|
||||||
[[ "$min_length" -gt 0 ]] && hint="${hint} [min ${min_length} chars]"
|
|
||||||
|
|
||||||
# Interactive prompt with timeout (silent input)
|
|
||||||
echo -en "${YW}${message}${hint} (timeout ${timeout}s): ${CL}" >&2
|
|
||||||
|
|
||||||
if read -t "$timeout" -rs response; then
|
|
||||||
echo "" >&2 # Newline after hidden input
|
|
||||||
if [[ -n "$response" ]]; then
|
|
||||||
# Validate minimum length
|
|
||||||
if [[ "$min_length" -gt 0 ]] && [[ ${#response} -lt "$min_length" ]]; then
|
|
||||||
echo -e "${YW}Password too short (min ${min_length}), using default${CL}" >&2
|
|
||||||
echo "$default"
|
|
||||||
else
|
|
||||||
echo "$response"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "$default"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Timeout occurred
|
|
||||||
echo "" >&2 # Newline after timeout
|
|
||||||
echo -e "${YW}Timeout - using generated password${CL}" >&2
|
|
||||||
echo "$default"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 6: CLEANUP & MAINTENANCE
|
# SECTION 6: CLEANUP & MAINTENANCE
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -1518,13 +896,15 @@ check_or_create_swap() {
|
|||||||
|
|
||||||
msg_error "No active swap detected"
|
msg_error "No active swap detected"
|
||||||
|
|
||||||
if ! prompt_confirm "Do you want to create a swap file?" "n" 60; then
|
read -p "Do you want to create a swap file? [y/N]: " create_swap
|
||||||
|
create_swap="${create_swap,,}" # to lowercase
|
||||||
|
|
||||||
|
if [[ "$create_swap" != "y" && "$create_swap" != "yes" ]]; then
|
||||||
msg_info "Skipping swap file creation"
|
msg_info "Skipping swap file creation"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local swap_size_mb
|
read -p "Enter swap size in MB (e.g., 2048 for 2GB): " swap_size_mb
|
||||||
swap_size_mb=$(prompt_input "Enter swap size in MB (e.g., 2048 for 2GB):" "2048" 60)
|
|
||||||
if ! [[ "$swap_size_mb" =~ ^[0-9]+$ ]]; then
|
if ! [[ "$swap_size_mb" =~ ^[0-9]+$ ]]; then
|
||||||
msg_error "Invalid size input. Aborting."
|
msg_error "Invalid size input. Aborting."
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -37,79 +37,24 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
|||||||
case "$code" in
|
case "$code" in
|
||||||
1) echo "General error / Operation not permitted" ;;
|
1) echo "General error / Operation not permitted" ;;
|
||||||
2) echo "Misuse of shell builtins (e.g. syntax error)" ;;
|
2) echo "Misuse of shell builtins (e.g. syntax error)" ;;
|
||||||
3) echo "General syntax or argument error" ;;
|
|
||||||
10) echo "Docker / privileged mode required (unsupported environment)" ;;
|
|
||||||
4) echo "curl: Feature not supported or protocol error" ;;
|
|
||||||
5) echo "curl: Could not resolve proxy" ;;
|
|
||||||
6) echo "curl: DNS resolution failed (could not resolve host)" ;;
|
6) echo "curl: DNS resolution failed (could not resolve host)" ;;
|
||||||
7) echo "curl: Failed to connect (network unreachable / host down)" ;;
|
7) echo "curl: Failed to connect (network unreachable / host down)" ;;
|
||||||
8) echo "curl: Server reply error (FTP/SFTP or apk untrusted key)" ;;
|
|
||||||
16) echo "curl: HTTP/2 framing layer error" ;;
|
|
||||||
18) echo "curl: Partial file (transfer not completed)" ;;
|
|
||||||
22) echo "curl: HTTP error returned (404, 429, 500+)" ;;
|
22) echo "curl: HTTP error returned (404, 429, 500+)" ;;
|
||||||
23) echo "curl: Write error (disk full or permissions)" ;;
|
|
||||||
24) echo "curl: Write to local file failed" ;;
|
|
||||||
25) echo "curl: Upload failed" ;;
|
|
||||||
26) echo "curl: Read error on local file (I/O)" ;;
|
|
||||||
27) echo "curl: Out of memory (memory allocation failed)" ;;
|
|
||||||
28) echo "curl: Operation timeout (network slow or server not responding)" ;;
|
28) echo "curl: Operation timeout (network slow or server not responding)" ;;
|
||||||
30) echo "curl: FTP port command failed" ;;
|
|
||||||
32) echo "curl: FTP SIZE command failed" ;;
|
|
||||||
33) echo "curl: HTTP range error" ;;
|
|
||||||
34) echo "curl: HTTP post error" ;;
|
|
||||||
35) echo "curl: SSL/TLS handshake failed (certificate error)" ;;
|
35) echo "curl: SSL/TLS handshake failed (certificate error)" ;;
|
||||||
36) echo "curl: FTP bad download resume" ;;
|
|
||||||
39) echo "curl: LDAP search failed" ;;
|
|
||||||
44) echo "curl: Internal error (bad function call order)" ;;
|
|
||||||
45) echo "curl: Interface error (failed to bind to specified interface)" ;;
|
|
||||||
46) echo "curl: Bad password entered" ;;
|
|
||||||
47) echo "curl: Too many redirects" ;;
|
|
||||||
48) echo "curl: Unknown command line option specified" ;;
|
|
||||||
51) echo "curl: SSL peer certificate or SSH host key verification failed" ;;
|
|
||||||
52) echo "curl: Empty reply from server (got nothing)" ;;
|
|
||||||
55) echo "curl: Failed sending network data" ;;
|
|
||||||
56) echo "curl: Receive error (connection reset by peer)" ;;
|
|
||||||
57) echo "curl: Unrecoverable poll/select error (system I/O failure)" ;;
|
|
||||||
59) echo "curl: Couldn't use specified SSL cipher" ;;
|
|
||||||
61) echo "curl: Bad/unrecognized transfer encoding" ;;
|
|
||||||
63) echo "curl: Maximum file size exceeded" ;;
|
|
||||||
75) echo "Temporary failure (retry later)" ;;
|
|
||||||
78) echo "curl: Remote file not found (404 on FTP/file)" ;;
|
|
||||||
79) echo "curl: SSH session error (key exchange/auth failed)" ;;
|
|
||||||
92) echo "curl: HTTP/2 stream error (protocol violation)" ;;
|
|
||||||
95) echo "curl: HTTP/3 layer error" ;;
|
|
||||||
64) echo "Usage error (wrong arguments)" ;;
|
|
||||||
65) echo "Data format error (bad input data)" ;;
|
|
||||||
66) echo "Input file not found (cannot open input)" ;;
|
|
||||||
67) echo "User not found (addressee unknown)" ;;
|
|
||||||
68) echo "Host not found (hostname unknown)" ;;
|
|
||||||
69) echo "Service unavailable" ;;
|
|
||||||
70) echo "Internal software error" ;;
|
|
||||||
71) echo "System error (OS-level failure)" ;;
|
|
||||||
72) echo "Critical OS file missing" ;;
|
|
||||||
73) echo "Cannot create output file" ;;
|
|
||||||
74) echo "I/O error" ;;
|
|
||||||
76) echo "Remote protocol error" ;;
|
|
||||||
77) echo "Permission denied" ;;
|
|
||||||
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)" ;;
|
||||||
124) echo "Command timed out (timeout command)" ;;
|
124) echo "Command timed out (timeout command)" ;;
|
||||||
125) echo "Command failed to start (Docker daemon or execution error)" ;;
|
|
||||||
126) echo "Command invoked cannot execute (permission problem?)" ;;
|
126) echo "Command invoked cannot execute (permission problem?)" ;;
|
||||||
127) echo "Command not found" ;;
|
127) echo "Command not found" ;;
|
||||||
128) echo "Invalid argument to exit" ;;
|
128) echo "Invalid argument to exit" ;;
|
||||||
129) echo "Killed by SIGHUP (terminal closed / hangup)" ;;
|
130) echo "Terminated by Ctrl+C (SIGINT)" ;;
|
||||||
130) echo "Aborted by user (SIGINT)" ;;
|
|
||||||
131) echo "Killed by SIGQUIT (core dumped)" ;;
|
|
||||||
132) echo "Killed by SIGILL (illegal CPU instruction)" ;;
|
|
||||||
134) echo "Process aborted (SIGABRT - possibly Node.js heap overflow)" ;;
|
134) echo "Process aborted (SIGABRT - possibly Node.js heap overflow)" ;;
|
||||||
137) echo "Killed (SIGKILL / Out of memory?)" ;;
|
137) echo "Killed (SIGKILL / Out of memory?)" ;;
|
||||||
139) echo "Segmentation fault (core dumped)" ;;
|
139) echo "Segmentation fault (core dumped)" ;;
|
||||||
141) echo "Broken pipe (SIGPIPE - output closed prematurely)" ;;
|
141) echo "Broken pipe (SIGPIPE - output closed prematurely)" ;;
|
||||||
143) echo "Terminated (SIGTERM)" ;;
|
143) echo "Terminated (SIGTERM)" ;;
|
||||||
144) echo "Killed by signal 16 (SIGUSR1 / SIGSTKFLT)" ;;
|
|
||||||
146) echo "Killed by signal 18 (SIGTSTP)" ;;
|
|
||||||
150) echo "Systemd: Service failed to start" ;;
|
150) echo "Systemd: Service failed to start" ;;
|
||||||
151) echo "Systemd: Service unit not found" ;;
|
151) echo "Systemd: Service unit not found" ;;
|
||||||
152) echo "Permission denied (EACCES)" ;;
|
152) echo "Permission denied (EACCES)" ;;
|
||||||
@@ -155,7 +100,6 @@ if ! declare -f explain_exit_code &>/dev/null; then
|
|||||||
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" ;;
|
||||||
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
231) echo "Proxmox: LXC stack upgrade failed" ;;
|
||||||
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" ;;
|
||||||
246) echo "Node.js: Internal JavaScript Parse Error" ;;
|
246) echo "Node.js: Internal JavaScript Parse Error" ;;
|
||||||
@@ -231,9 +175,9 @@ error_handler() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
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 "--- Last 20 lines of silent log ---"
|
||||||
tail -n 20 "$active_log"
|
tail -n 20 "$active_log"
|
||||||
echo -e "${TAB}-----------------------------------\n"
|
echo "-----------------------------------"
|
||||||
|
|
||||||
# Detect context: Container (INSTALL_LOG set + /root exists) vs Host (BUILD_LOG)
|
# Detect context: Container (INSTALL_LOG set + /root exists) vs Host (BUILD_LOG)
|
||||||
if [[ -n "${INSTALL_LOG:-}" && -d /root ]]; then
|
if [[ -n "${INSTALL_LOG:-}" && -d /root ]]; then
|
||||||
@@ -260,56 +204,23 @@ error_handler() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
if declare -f msg_custom >/dev/null 2>&1; then
|
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
|
||||||
echo -en "${TAB}❓${TAB}${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
|
|
||||||
else
|
|
||||||
echo -en "${YW}Remove broken container ${CTID}? (Y/n) [auto-remove in 60s]: ${CL}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
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
|
||||||
echo ""
|
echo -e "\n${YW}Removing container ${CTID}${CL}"
|
||||||
if declare -f msg_info >/dev/null 2>&1; then
|
|
||||||
msg_info "Removing container ${CTID}"
|
|
||||||
else
|
|
||||||
echo -e "${YW}Removing container ${CTID}${CL}"
|
|
||||||
fi
|
|
||||||
pct stop "$CTID" &>/dev/null || true
|
pct stop "$CTID" &>/dev/null || true
|
||||||
pct destroy "$CTID" &>/dev/null || true
|
pct destroy "$CTID" &>/dev/null || true
|
||||||
if declare -f msg_ok >/dev/null 2>&1; then
|
echo -e "${GN}✔${CL} Container ${CTID} removed"
|
||||||
msg_ok "Container ${CTID} removed"
|
|
||||||
else
|
|
||||||
echo -e "${GN}✔${CL} Container ${CTID} removed"
|
|
||||||
fi
|
|
||||||
elif [[ "$response" =~ ^[Nn]$ ]]; then
|
elif [[ "$response" =~ ^[Nn]$ ]]; then
|
||||||
echo ""
|
echo -e "\n${YW}Container ${CTID} kept for debugging${CL}"
|
||||||
if declare -f msg_warn >/dev/null 2>&1; then
|
|
||||||
msg_warn "Container ${CTID} kept for debugging"
|
|
||||||
else
|
|
||||||
echo -e "${YW}Container ${CTID} kept for debugging${CL}"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Timeout - auto-remove
|
# Timeout - auto-remove
|
||||||
echo ""
|
echo -e "\n${YW}No response - auto-removing container${CL}"
|
||||||
if declare -f msg_info >/dev/null 2>&1; then
|
|
||||||
msg_info "No response - removing container ${CTID}"
|
|
||||||
else
|
|
||||||
echo -e "${YW}No response - removing container ${CTID}${CL}"
|
|
||||||
fi
|
|
||||||
pct stop "$CTID" &>/dev/null || true
|
pct stop "$CTID" &>/dev/null || true
|
||||||
pct destroy "$CTID" &>/dev/null || true
|
pct destroy "$CTID" &>/dev/null || true
|
||||||
if declare -f msg_ok >/dev/null 2>&1; then
|
echo -e "${GN}✔${CL} Container ${CTID} removed"
|
||||||
msg_ok "Container ${CTID} removed"
|
|
||||||
else
|
|
||||||
echo -e "${GN}✔${CL} Container ${CTID} removed"
|
|
||||||
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
|
fi
|
||||||
@@ -332,22 +243,6 @@ error_handler() {
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
on_exit() {
|
on_exit() {
|
||||||
local exit_code=$?
|
local exit_code=$?
|
||||||
# Report orphaned "installing" records to telemetry API
|
|
||||||
# Catches ALL exit paths: errors (non-zero), signals, AND clean exits where
|
|
||||||
# post_to_api was called ("installing" sent) but post_update_to_api was never called
|
|
||||||
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
|
|
||||||
if declare -f post_update_to_api >/dev/null 2>&1; then
|
|
||||||
# Ensure log is accessible on host before reporting
|
|
||||||
if declare -f ensure_log_on_host >/dev/null 2>&1; then
|
|
||||||
ensure_log_on_host
|
|
||||||
fi
|
|
||||||
if [[ $exit_code -ne 0 ]]; then
|
|
||||||
post_update_to_api "failed" "$exit_code"
|
|
||||||
else
|
|
||||||
post_update_to_api "failed" "1"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
[[ -n "${lockfile:-}" && -e "$lockfile" ]] && rm -f "$lockfile"
|
[[ -n "${lockfile:-}" && -e "$lockfile" ]] && rm -f "$lockfile"
|
||||||
exit "$exit_code"
|
exit "$exit_code"
|
||||||
}
|
}
|
||||||
@@ -360,14 +255,6 @@ on_exit() {
|
|||||||
# - Exits with code 130 (128 + SIGINT=2)
|
# - Exits with code 130 (128 + SIGINT=2)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
on_interrupt() {
|
on_interrupt() {
|
||||||
# Ensure log is accessible on host before reporting
|
|
||||||
if declare -f ensure_log_on_host >/dev/null 2>&1; then
|
|
||||||
ensure_log_on_host
|
|
||||||
fi
|
|
||||||
# Report interruption to telemetry API (prevents stuck "installing" records)
|
|
||||||
if declare -f post_update_to_api >/dev/null 2>&1; then
|
|
||||||
post_update_to_api "failed" "130"
|
|
||||||
fi
|
|
||||||
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)"
|
msg_error "Interrupted by user (SIGINT)"
|
||||||
else
|
else
|
||||||
@@ -385,14 +272,6 @@ on_interrupt() {
|
|||||||
# - Triggered by external process termination
|
# - Triggered by external process termination
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
on_terminate() {
|
on_terminate() {
|
||||||
# Ensure log is accessible on host before reporting
|
|
||||||
if declare -f ensure_log_on_host >/dev/null 2>&1; then
|
|
||||||
ensure_log_on_host
|
|
||||||
fi
|
|
||||||
# Report termination to telemetry API (prevents stuck "installing" records)
|
|
||||||
if declare -f post_update_to_api >/dev/null 2>&1; then
|
|
||||||
post_update_to_api "failed" "143"
|
|
||||||
fi
|
|
||||||
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)"
|
msg_error "Terminated by signal (SIGTERM)"
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -40,25 +40,6 @@ catch_errors
|
|||||||
# Get LXC IP address (must be called INSIDE container, after network is up)
|
# Get LXC IP address (must be called INSIDE container, after network is up)
|
||||||
get_lxc_ip
|
get_lxc_ip
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# post_progress_to_api()
|
|
||||||
#
|
|
||||||
# - Lightweight progress ping from inside the container
|
|
||||||
# - Updates the existing telemetry record status from "installing" to "configuring"
|
|
||||||
# - Signals that the installation is actively progressing (not stuck)
|
|
||||||
# - Fire-and-forget: never blocks or fails the script
|
|
||||||
# - Only executes if DIAGNOSTICS=yes and RANDOM_UUID is set
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
post_progress_to_api() {
|
|
||||||
command -v curl &>/dev/null || return 0
|
|
||||||
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
|
|
||||||
[[ -z "${RANDOM_UUID:-}" ]] && return 0
|
|
||||||
|
|
||||||
curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"random_id\":\"${RANDOM_UUID}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/dev/null || true
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# SECTION 2: NETWORK & CONNECTIVITY
|
# SECTION 2: NETWORK & CONNECTIVITY
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -122,7 +103,6 @@ setting_up_container() {
|
|||||||
msg_ok "Set up Container OS"
|
msg_ok "Set up Container OS"
|
||||||
#msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)"
|
#msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)"
|
||||||
msg_ok "Network Connected: ${BL}$(hostname -I)"
|
msg_ok "Network Connected: ${BL}$(hostname -I)"
|
||||||
post_progress_to_api
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -192,7 +172,7 @@ network_check() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler $LINENO "$BASH_COMMAND"' ERR
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -226,18 +206,8 @@ EOF
|
|||||||
$STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade
|
$STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade
|
||||||
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED
|
||||||
msg_ok "Updated Container OS"
|
msg_ok "Updated Container OS"
|
||||||
post_progress_to_api
|
|
||||||
|
|
||||||
local tools_content
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || {
|
|
||||||
msg_error "Failed to download tools.func"
|
|
||||||
exit 6
|
|
||||||
}
|
|
||||||
source /dev/stdin <<<"$tools_content"
|
|
||||||
if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then
|
|
||||||
msg_error "tools.func loaded but incomplete — missing expected functions"
|
|
||||||
exit 6
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|||||||
@@ -465,7 +465,6 @@ manage_tool_repository() {
|
|||||||
msg_error "Failed to download MongoDB GPG key"
|
msg_error "Failed to download MongoDB GPG key"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
chmod 644 "/etc/apt/keyrings/mongodb-server-${version}.gpg"
|
|
||||||
|
|
||||||
# Setup repository
|
# Setup repository
|
||||||
local distro_codename
|
local distro_codename
|
||||||
@@ -1295,33 +1294,12 @@ setup_deb822_repo() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Import GPG key (auto-detect binary vs ASCII-armored format)
|
# Import GPG
|
||||||
local tmp_gpg
|
curl -fsSL "$gpg_url" | gpg --dearmor --yes -o "/etc/apt/keyrings/${name}.gpg" || {
|
||||||
tmp_gpg=$(mktemp) || return 1
|
msg_error "Failed to import GPG key for ${name}"
|
||||||
curl -fsSL "$gpg_url" -o "$tmp_gpg" || {
|
|
||||||
msg_error "Failed to download GPG key for ${name}"
|
|
||||||
rm -f "$tmp_gpg"
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if grep -q "BEGIN PGP" "$tmp_gpg" 2>/dev/null; then
|
|
||||||
# ASCII-armored — dearmor to binary
|
|
||||||
gpg --dearmor --yes -o "/etc/apt/keyrings/${name}.gpg" < "$tmp_gpg" || {
|
|
||||||
msg_error "Failed to dearmor GPG key for ${name}"
|
|
||||||
rm -f "$tmp_gpg"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
else
|
|
||||||
# Already in binary GPG format — copy directly
|
|
||||||
cp "$tmp_gpg" "/etc/apt/keyrings/${name}.gpg" || {
|
|
||||||
msg_error "Failed to install GPG key for ${name}"
|
|
||||||
rm -f "$tmp_gpg"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
rm -f "$tmp_gpg"
|
|
||||||
chmod 644 "/etc/apt/keyrings/${name}.gpg"
|
|
||||||
|
|
||||||
# Write deb822
|
# Write deb822
|
||||||
{
|
{
|
||||||
echo "Types: deb"
|
echo "Types: deb"
|
||||||
@@ -1851,26 +1829,16 @@ function download_with_progress() {
|
|||||||
# Ensures /usr/local/bin is permanently in system PATH.
|
# Ensures /usr/local/bin is permanently in system PATH.
|
||||||
#
|
#
|
||||||
# Description:
|
# Description:
|
||||||
# - Adds to /etc/profile.d for login shells (SSH, noVNC)
|
# - Adds to /etc/profile.d if not present
|
||||||
# - Adds to /root/.bashrc for non-login shells (pct enter)
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
function ensure_usr_local_bin_persist() {
|
function ensure_usr_local_bin_persist() {
|
||||||
# Skip on Proxmox host
|
|
||||||
command -v pveversion &>/dev/null && return
|
|
||||||
|
|
||||||
# Login shells: /etc/profile.d/
|
|
||||||
local PROFILE_FILE="/etc/profile.d/custom_path.sh"
|
local PROFILE_FILE="/etc/profile.d/custom_path.sh"
|
||||||
if [[ ! -f "$PROFILE_FILE" ]]; then
|
|
||||||
|
if [[ ! -f "$PROFILE_FILE" ]] && ! command -v pveversion &>/dev/null; then
|
||||||
echo 'export PATH="/usr/local/bin:$PATH"' >"$PROFILE_FILE"
|
echo 'export PATH="/usr/local/bin:$PATH"' >"$PROFILE_FILE"
|
||||||
chmod +x "$PROFILE_FILE"
|
chmod +x "$PROFILE_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Non-login shells (pct enter): /root/.bashrc
|
|
||||||
local BASHRC="/root/.bashrc"
|
|
||||||
if [[ -f "$BASHRC" ]] && ! grep -q '/usr/local/bin' "$BASHRC"; then
|
|
||||||
echo 'export PATH="/usr/local/bin:$PATH"' >>"$BASHRC"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -1923,7 +1891,7 @@ function fetch_and_deploy_codeberg_release() {
|
|||||||
local app="$1"
|
local app="$1"
|
||||||
local repo="$2"
|
local repo="$2"
|
||||||
local mode="${3:-tarball}" # tarball | binary | prebuild | singlefile | tag
|
local mode="${3:-tarball}" # tarball | binary | prebuild | singlefile | tag
|
||||||
local version="${var_appversion:-${4:-latest}}"
|
local version="${4:-latest}"
|
||||||
local target="${5:-/opt/$app}"
|
local target="${5:-/opt/$app}"
|
||||||
local asset_pattern="${6:-}"
|
local asset_pattern="${6:-}"
|
||||||
|
|
||||||
@@ -2453,7 +2421,7 @@ function fetch_and_deploy_gh_release() {
|
|||||||
local app="$1"
|
local app="$1"
|
||||||
local repo="$2"
|
local repo="$2"
|
||||||
local mode="${3:-tarball}" # tarball | binary | prebuild | singlefile
|
local mode="${3:-tarball}" # tarball | binary | prebuild | singlefile
|
||||||
local version="${var_appversion:-${4:-latest}}"
|
local version="${4:-latest}"
|
||||||
local target="${5:-/opt/$app}"
|
local target="${5:-/opt/$app}"
|
||||||
local asset_pattern="${6:-}"
|
local asset_pattern="${6:-}"
|
||||||
|
|
||||||
|
|||||||
@@ -207,9 +207,15 @@ silent() {
|
|||||||
msg_custom "→" "${YWB}" "${cmd}"
|
msg_custom "→" "${YWB}" "${cmd}"
|
||||||
|
|
||||||
if [[ -s "$logfile" ]]; then
|
if [[ -s "$logfile" ]]; then
|
||||||
echo -e "\n${TAB}--- Last 10 lines of log ---"
|
local log_lines=$(wc -l <"$logfile")
|
||||||
|
echo "--- Last 10 lines of log ---"
|
||||||
tail -n 10 "$logfile"
|
tail -n 10 "$logfile"
|
||||||
echo -e "${TAB}----------------------------\n"
|
echo "----------------------------"
|
||||||
|
|
||||||
|
# Show how to view full log if there are more lines
|
||||||
|
if [[ $log_lines -gt 10 ]]; then
|
||||||
|
msg_custom "📋" "${YW}" "View full log (${log_lines} lines): ${logfile}"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit "$rc"
|
exit "$rc"
|
||||||
@@ -529,21 +535,9 @@ cleanup_vmid() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
local exit_code=$?
|
|
||||||
if [[ "$(dirs -p | wc -l)" -gt 1 ]]; then
|
if [[ "$(dirs -p | wc -l)" -gt 1 ]]; then
|
||||||
popd >/dev/null || true
|
popd >/dev/null || true
|
||||||
fi
|
fi
|
||||||
# Report final telemetry status if post_to_api_vm was called but no update was sent
|
|
||||||
if [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then
|
|
||||||
if declare -f post_update_to_api >/dev/null 2>&1; then
|
|
||||||
if [[ $exit_code -ne 0 ]]; then
|
|
||||||
post_update_to_api "failed" "$exit_code"
|
|
||||||
else
|
|
||||||
# Exited cleanly but description()/success was never called — shouldn't happen
|
|
||||||
post_update_to_api "failed" "1"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check_root() {
|
check_root() {
|
||||||
|
|||||||
@@ -19,11 +19,6 @@ EOF
|
|||||||
}
|
}
|
||||||
header_info
|
header_info
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-netbird-lxc" "tool"
|
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)?" yn
|
read -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)?" yn
|
||||||
case $yn in
|
case $yn in
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ function msg_info() { echo -e " \e[1;36m➤\e[0m $1"; }
|
|||||||
function msg_ok() { echo -e " \e[1;32m✔\e[0m $1"; }
|
function msg_ok() { echo -e " \e[1;32m✔\e[0m $1"; }
|
||||||
function msg_error() { echo -e " \e[1;31m✖\e[0m $1"; }
|
function msg_error() { echo -e " \e[1;31m✖\e[0m $1"; }
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-tailscale-lxc" "tool"
|
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
if ! command -v pveversion &>/dev/null; then
|
if ! command -v pveversion &>/dev/null; then
|
||||||
@@ -79,37 +75,14 @@ pct exec "$CTID" -- bash -c '
|
|||||||
set -e
|
set -e
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
# Source os-release properly (handles quoted values)
|
ID=$(grep "^ID=" /etc/os-release | cut -d"=" -f2)
|
||||||
source /etc/os-release
|
VER=$(grep "^VERSION_CODENAME=" /etc/os-release | cut -d"=" -f2)
|
||||||
|
|
||||||
# Fallback if DNS is poisoned or blocked
|
# fallback if DNS is poisoned or blocked
|
||||||
ORIG_RESOLV="/etc/resolv.conf"
|
ORIG_RESOLV="/etc/resolv.conf"
|
||||||
BACKUP_RESOLV="/tmp/resolv.conf.backup"
|
BACKUP_RESOLV="/tmp/resolv.conf.backup"
|
||||||
|
|
||||||
# Check DNS resolution using multiple methods (dig may not be installed)
|
if ! dig +short pkgs.tailscale.com | grep -qvE "^127\.|^0\.0\.0\.0$"; then
|
||||||
dns_check_failed=true
|
|
||||||
if command -v dig &>/dev/null; then
|
|
||||||
if dig +short pkgs.tailscale.com 2>/dev/null | grep -qvE "^127\.|^0\.0\.0\.0$|^$"; then
|
|
||||||
dns_check_failed=false
|
|
||||||
fi
|
|
||||||
elif command -v host &>/dev/null; then
|
|
||||||
if host pkgs.tailscale.com 2>/dev/null | grep -q "has address"; then
|
|
||||||
dns_check_failed=false
|
|
||||||
fi
|
|
||||||
elif command -v nslookup &>/dev/null; then
|
|
||||||
if nslookup pkgs.tailscale.com 2>/dev/null | grep -q "Address:"; then
|
|
||||||
dns_check_failed=false
|
|
||||||
fi
|
|
||||||
elif command -v getent &>/dev/null; then
|
|
||||||
if getent hosts pkgs.tailscale.com &>/dev/null; then
|
|
||||||
dns_check_failed=false
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# No DNS tools available, try curl directly and assume DNS works
|
|
||||||
dns_check_failed=false
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $dns_check_failed; then
|
|
||||||
echo "[INFO] DNS resolution for pkgs.tailscale.com failed (blocked or redirected)."
|
echo "[INFO] DNS resolution for pkgs.tailscale.com failed (blocked or redirected)."
|
||||||
echo "[INFO] Temporarily overriding /etc/resolv.conf with Cloudflare DNS (1.1.1.1)"
|
echo "[INFO] Temporarily overriding /etc/resolv.conf with Cloudflare DNS (1.1.1.1)"
|
||||||
cp "$ORIG_RESOLV" "$BACKUP_RESOLV"
|
cp "$ORIG_RESOLV" "$BACKUP_RESOLV"
|
||||||
@@ -119,22 +92,17 @@ fi
|
|||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
echo "[INFO] curl not found, installing..."
|
echo "[INFO] curl not found, installing..."
|
||||||
apt-get update -qq
|
apt-get update -qq
|
||||||
apt update -qq
|
apt-get install -y curl >/dev/null
|
||||||
apt install -y curl >/dev/null
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure keyrings directory exists
|
curl -fsSL https://pkgs.tailscale.com/stable/${ID}/${VER}.noarmor.gpg \
|
||||||
mkdir -p /usr/share/keyrings
|
|
||||||
|
|
||||||
curl -fsSL "https://pkgs.tailscale.com/stable/${ID}/${VERSION_CODENAME}.noarmor.gpg" \
|
|
||||||
| tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
|
| tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
|
||||||
|
|
||||||
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${ID} ${VERSION_CODENAME} main" \
|
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${ID} ${VER} main" \
|
||||||
>/etc/apt/sources.list.d/tailscale.list
|
>/etc/apt/sources.list.d/tailscale.list
|
||||||
|
|
||||||
apt-get update -qq
|
apt-get update -qq
|
||||||
apt update -qq
|
apt-get install -y tailscale >/dev/null
|
||||||
apt install -y tailscale >/dev/null
|
|
||||||
|
|
||||||
if [[ -f /tmp/resolv.conf.backup ]]; then
|
if [[ -f /tmp/resolv.conf.backup ]]; then
|
||||||
echo "[INFO] Restoring original /etc/resolv.conf"
|
echo "[INFO] Restoring original /etc/resolv.conf"
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ fi
|
|||||||
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/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
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/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
@@ -30,7 +29,6 @@ DEFAULT_PORT=8080
|
|||||||
|
|
||||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# HEADER
|
# HEADER
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ function msg() {
|
|||||||
local TEXT="$1"
|
local TEXT="$1"
|
||||||
echo -e "$TEXT"
|
echo -e "$TEXT"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "all-templates" "tool"
|
|
||||||
|
|
||||||
function validate_container_id() {
|
function validate_container_id() {
|
||||||
local ctid="$1"
|
local ctid="$1"
|
||||||
# Check if ID is numeric
|
# Check if ID is numeric
|
||||||
|
|||||||
@@ -28,11 +28,6 @@ HOLD="-"
|
|||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
APP="Coder Code Server"
|
APP="Coder Code Server"
|
||||||
hostname="$(hostname)"
|
hostname="$(hostname)"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "coder-code-server" "addon"
|
|
||||||
|
|
||||||
set -o errexit
|
set -o errexit
|
||||||
set -o errtrace
|
set -o errtrace
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|||||||
@@ -13,13 +13,11 @@ fi
|
|||||||
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/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
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/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|||||||
@@ -17,11 +17,6 @@ HOLD="-"
|
|||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
APP="CrowdSec"
|
APP="CrowdSec"
|
||||||
hostname="$(hostname)"
|
hostname="$(hostname)"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "crowdsec" "addon"
|
|
||||||
|
|
||||||
set -o errexit
|
set -o errexit
|
||||||
set -o errtrace
|
set -o errtrace
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|||||||
@@ -32,10 +32,6 @@ DEFAULT_PORT=8080
|
|||||||
SRC_DIR="/"
|
SRC_DIR="/"
|
||||||
TMP_BIN="/tmp/filebrowser.$$"
|
TMP_BIN="/tmp/filebrowser.$$"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "filebrowser-quantum" "addon"
|
|
||||||
|
|
||||||
# Get primary IP
|
# Get primary IP
|
||||||
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
||||||
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
|
||||||
function header_info {
|
function header_info {
|
||||||
clear
|
clear
|
||||||
cat <<"EOF"
|
cat <<"EOF"
|
||||||
_______ __ ____
|
_______ __ ____
|
||||||
/ ____(_) /__ / __ )_________ _ __________ _____
|
/ ____(_) /__ / __ )_________ _ __________ _____
|
||||||
/ /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/
|
/ /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/
|
||||||
@@ -29,10 +29,6 @@ INSTALL_PATH="/usr/local/bin/filebrowser"
|
|||||||
DB_PATH="/usr/local/community-scripts/filebrowser.db"
|
DB_PATH="/usr/local/community-scripts/filebrowser.db"
|
||||||
DEFAULT_PORT=8080
|
DEFAULT_PORT=8080
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "filebrowser" "addon"
|
|
||||||
|
|
||||||
# Get first non-loopback IP & Detect primary network interface dynamically
|
# Get first non-loopback IP & Detect primary network interface dynamically
|
||||||
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
||||||
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
||||||
@@ -42,65 +38,65 @@ IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n
|
|||||||
|
|
||||||
# Detect OS
|
# Detect OS
|
||||||
if [[ -f "/etc/alpine-release" ]]; then
|
if [[ -f "/etc/alpine-release" ]]; then
|
||||||
OS="Alpine"
|
OS="Alpine"
|
||||||
SERVICE_PATH="/etc/init.d/filebrowser"
|
SERVICE_PATH="/etc/init.d/filebrowser"
|
||||||
PKG_MANAGER="apk add --no-cache"
|
PKG_MANAGER="apk add --no-cache"
|
||||||
elif [[ -f "/etc/debian_version" ]]; then
|
elif [[ -f "/etc/debian_version" ]]; then
|
||||||
OS="Debian"
|
OS="Debian"
|
||||||
SERVICE_PATH="/etc/systemd/system/filebrowser.service"
|
SERVICE_PATH="/etc/systemd/system/filebrowser.service"
|
||||||
PKG_MANAGER="apt-get install -y"
|
PKG_MANAGER="apt-get install -y"
|
||||||
else
|
else
|
||||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
function msg_info() {
|
function msg_info() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${INFO} ${YW}${msg}...${CL}"
|
echo -e "${INFO} ${YW}${msg}...${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function msg_ok() {
|
function msg_ok() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${CM} ${GN}${msg}${CL}"
|
echo -e "${CM} ${GN}${msg}${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function msg_error() {
|
function msg_error() {
|
||||||
local msg="$1"
|
local msg="$1"
|
||||||
echo -e "${CROSS} ${RD}${msg}${CL}"
|
echo -e "${CROSS} ${RD}${msg}${CL}"
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ -f "$INSTALL_PATH" ]; then
|
if [ -f "$INSTALL_PATH" ]; then
|
||||||
echo -e "${YW}⚠️ ${APP} is already installed.${CL}"
|
echo -e "${YW}⚠️ ${APP} is already installed.${CL}"
|
||||||
read -r -p "Would you like to uninstall ${APP}? (y/N): " uninstall_prompt
|
read -r -p "Would you like to uninstall ${APP}? (y/N): " uninstall_prompt
|
||||||
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Uninstalling ${APP}"
|
msg_info "Uninstalling ${APP}"
|
||||||
if [[ "$OS" == "Debian" ]]; then
|
if [[ "$OS" == "Debian" ]]; then
|
||||||
systemctl disable --now filebrowser.service &>/dev/null
|
systemctl disable --now filebrowser.service &>/dev/null
|
||||||
rm -f "$SERVICE_PATH"
|
rm -f "$SERVICE_PATH"
|
||||||
else
|
else
|
||||||
rc-service filebrowser stop &>/dev/null
|
rc-service filebrowser stop &>/dev/null
|
||||||
rc-update del filebrowser &>/dev/null
|
rc-update del filebrowser &>/dev/null
|
||||||
rm -f "$SERVICE_PATH"
|
rm -f "$SERVICE_PATH"
|
||||||
|
fi
|
||||||
|
rm -f "$INSTALL_PATH" "$DB_PATH"
|
||||||
|
msg_ok "${APP} has been uninstalled."
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
rm -f "$INSTALL_PATH" "$DB_PATH"
|
|
||||||
msg_ok "${APP} has been uninstalled."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
read -r -p "Would you like to update ${APP}? (y/N): " update_prompt
|
read -r -p "Would you like to update ${APP}? (y/N): " update_prompt
|
||||||
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Updating ${APP}"
|
msg_info "Updating ${APP}"
|
||||||
if ! command -v curl &>/dev/null; then $PKG_MANAGER curl &>/dev/null; fi
|
if ! command -v curl &>/dev/null; then $PKG_MANAGER curl &>/dev/null; fi
|
||||||
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
|
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
|
||||||
chmod +x "$INSTALL_PATH"
|
chmod +x "$INSTALL_PATH"
|
||||||
msg_ok "Updated ${APP}"
|
msg_ok "Updated ${APP}"
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}"
|
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${YW}⚠️ ${APP} is not installed.${CL}"
|
echo -e "${YW}⚠️ ${APP} is not installed.${CL}"
|
||||||
@@ -109,43 +105,43 @@ PORT=${PORT:-$DEFAULT_PORT}
|
|||||||
|
|
||||||
read -r -p "Would you like to install ${APP}? (y/n): " install_prompt
|
read -r -p "Would you like to install ${APP}? (y/n): " install_prompt
|
||||||
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Installing ${APP} on ${OS}"
|
msg_info "Installing ${APP} on ${OS}"
|
||||||
$PKG_MANAGER wget tar curl &>/dev/null
|
$PKG_MANAGER wget tar curl &>/dev/null
|
||||||
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
|
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
|
||||||
chmod +x "$INSTALL_PATH"
|
chmod +x "$INSTALL_PATH"
|
||||||
msg_ok "Installed ${APP}"
|
msg_ok "Installed ${APP}"
|
||||||
|
|
||||||
msg_info "Creating FileBrowser directory"
|
msg_info "Creating FileBrowser directory"
|
||||||
mkdir -p /usr/local/community-scripts
|
mkdir -p /usr/local/community-scripts
|
||||||
chown root:root /usr/local/community-scripts
|
chown root:root /usr/local/community-scripts
|
||||||
chmod 755 /usr/local/community-scripts
|
chmod 755 /usr/local/community-scripts
|
||||||
touch "$DB_PATH"
|
touch "$DB_PATH"
|
||||||
chown root:root "$DB_PATH"
|
chown root:root "$DB_PATH"
|
||||||
chmod 644 "$DB_PATH"
|
chmod 644 "$DB_PATH"
|
||||||
msg_ok "Directory created successfully"
|
msg_ok "Directory created successfully"
|
||||||
|
|
||||||
read -r -p "Would you like to use No Authentication? (y/N): " auth_prompt
|
read -r -p "Would you like to use No Authentication? (y/N): " auth_prompt
|
||||||
if [[ "${auth_prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${auth_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Configuring No Authentication"
|
msg_info "Configuring No Authentication"
|
||||||
cd /usr/local/community-scripts
|
cd /usr/local/community-scripts
|
||||||
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
||||||
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
||||||
filebrowser config init --auth.method=noauth &>/dev/null
|
filebrowser config init --auth.method=noauth &>/dev/null
|
||||||
filebrowser config set --auth.method=noauth &>/dev/null
|
filebrowser config set --auth.method=noauth &>/dev/null
|
||||||
filebrowser users add ID 1 --perm.admin &>/dev/null
|
filebrowser users add ID 1 --perm.admin &>/dev/null
|
||||||
msg_ok "No Authentication configured"
|
msg_ok "No Authentication configured"
|
||||||
else
|
else
|
||||||
msg_info "Setting up default authentication"
|
msg_info "Setting up default authentication"
|
||||||
cd /usr/local/community-scripts
|
cd /usr/local/community-scripts
|
||||||
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
||||||
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
||||||
filebrowser users add admin helper-scripts.com --perm.admin --database "$DB_PATH" &>/dev/null
|
filebrowser users add admin helper-scripts.com --perm.admin --database "$DB_PATH" &>/dev/null
|
||||||
msg_ok "Default authentication configured (admin:helper-scripts.com)"
|
msg_ok "Default authentication configured (admin:helper-scripts.com)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Creating service"
|
msg_info "Creating service"
|
||||||
if [[ "$OS" == "Debian" ]]; then
|
if [[ "$OS" == "Debian" ]]; then
|
||||||
cat <<EOF >"$SERVICE_PATH"
|
cat <<EOF >"$SERVICE_PATH"
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Filebrowser
|
Description=Filebrowser
|
||||||
After=network-online.target
|
After=network-online.target
|
||||||
@@ -161,9 +157,9 @@ Restart=always
|
|||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
systemctl enable -q --now filebrowser
|
systemctl enable -q --now filebrowser
|
||||||
else
|
else
|
||||||
cat <<EOF >"$SERVICE_PATH"
|
cat <<EOF >"$SERVICE_PATH"
|
||||||
#!/sbin/openrc-run
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
command="/usr/local/bin/filebrowser"
|
command="/usr/local/bin/filebrowser"
|
||||||
@@ -176,14 +172,14 @@ depend() {
|
|||||||
need net
|
need net
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
chmod +x "$SERVICE_PATH"
|
chmod +x "$SERVICE_PATH"
|
||||||
rc-update add filebrowser default &>/dev/null
|
rc-update add filebrowser default &>/dev/null
|
||||||
rc-service filebrowser start &>/dev/null
|
rc-service filebrowser start &>/dev/null
|
||||||
fi
|
fi
|
||||||
msg_ok "Service created successfully"
|
msg_ok "Service created successfully"
|
||||||
|
|
||||||
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://$IP:$PORT${CL}"
|
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://$IP:$PORT${CL}"
|
||||||
else
|
else
|
||||||
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
|
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -30,10 +30,6 @@ function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
|
|||||||
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
|
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
|
||||||
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
|
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "glances" "addon"
|
|
||||||
|
|
||||||
get_lxc_ip() {
|
get_lxc_ip() {
|
||||||
if command -v hostname >/dev/null 2>&1 && hostname -I 2>/dev/null; then
|
if command -v hostname >/dev/null 2>&1 && hostname -I 2>/dev/null; then
|
||||||
hostname -I | awk '{print $1}'
|
hostname -I | awk '{print $1}'
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ fi
|
|||||||
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/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
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/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
@@ -30,7 +29,6 @@ DEFAULT_PORT=3000
|
|||||||
|
|
||||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# HEADER
|
# HEADER
|
||||||
@@ -106,10 +104,6 @@ function update() {
|
|||||||
$STD npm run build
|
$STD npm run build
|
||||||
msg_ok "Built ${APP}"
|
msg_ok "Built ${APP}"
|
||||||
|
|
||||||
msg_info "Updating service"
|
|
||||||
create_service
|
|
||||||
msg_ok "Updated service"
|
|
||||||
|
|
||||||
msg_info "Starting service"
|
msg_info "Starting service"
|
||||||
systemctl start immich-proxy
|
systemctl start immich-proxy
|
||||||
msg_ok "Started service"
|
msg_ok "Started service"
|
||||||
@@ -118,27 +112,6 @@ function update() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function create_service() {
|
|
||||||
cat <<EOF >"$SERVICE_PATH"
|
|
||||||
[Unit]
|
|
||||||
Description=Immich Public Proxy
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
User=root
|
|
||||||
WorkingDirectory=${INSTALL_PATH}/app
|
|
||||||
EnvironmentFile=${CONFIG_PATH}/.env
|
|
||||||
ExecStart=/usr/bin/node ${INSTALL_PATH}/app/dist/index.js
|
|
||||||
Restart=always
|
|
||||||
RestartSec=10
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
systemctl daemon-reload
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# INSTALL
|
# INSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -200,7 +173,23 @@ EOF
|
|||||||
msg_ok "Created configuration"
|
msg_ok "Created configuration"
|
||||||
|
|
||||||
msg_info "Creating service"
|
msg_info "Creating service"
|
||||||
create_service
|
cat <<EOF >"$SERVICE_PATH"
|
||||||
|
[Unit]
|
||||||
|
Description=Immich Public Proxy
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=${INSTALL_PATH}
|
||||||
|
EnvironmentFile=${CONFIG_PATH}/.env
|
||||||
|
ExecStart=/usr/bin/node ${INSTALL_PATH}/app/server.js
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
systemctl enable -q --now immich-proxy
|
systemctl enable -q --now immich-proxy
|
||||||
msg_ok "Created and started service"
|
msg_ok "Created and started service"
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ fi
|
|||||||
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/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
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/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
@@ -30,7 +29,6 @@ DEFAULT_PORT=3000
|
|||||||
|
|
||||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# HEADER
|
# HEADER
|
||||||
|
|||||||
@@ -26,11 +26,6 @@ BFR="\\r\\033[K"
|
|||||||
HOLD="-"
|
HOLD="-"
|
||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
silent() { "$@" >/dev/null 2>&1; }
|
silent() { "$@" >/dev/null 2>&1; }
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "netdata" "tool"
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
header_info
|
header_info
|
||||||
echo "Loading..."
|
echo "Loading..."
|
||||||
|
|||||||
@@ -13,13 +13,11 @@ fi
|
|||||||
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/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
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/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|||||||
@@ -27,11 +27,6 @@ HOLD="-"
|
|||||||
CM="${GN}✓${CL}"
|
CM="${GN}✓${CL}"
|
||||||
APP="OliveTin"
|
APP="OliveTin"
|
||||||
hostname="$(hostname)"
|
hostname="$(hostname)"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "olivetin" "addon"
|
|
||||||
|
|
||||||
set-e
|
set-e
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ APP="phpMyAdmin"
|
|||||||
INSTALL_DIR_DEBIAN="/var/www/html/phpMyAdmin"
|
INSTALL_DIR_DEBIAN="/var/www/html/phpMyAdmin"
|
||||||
INSTALL_DIR_ALPINE="/usr/share/phpmyadmin"
|
INSTALL_DIR_ALPINE="/usr/share/phpmyadmin"
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
|
||||||
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "phpmyadmin" "addon"
|
|
||||||
|
|
||||||
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
||||||
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
||||||
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
|
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
|
||||||
|
|||||||
@@ -13,13 +13,11 @@ fi
|
|||||||
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/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
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/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|||||||
@@ -8,13 +8,11 @@
|
|||||||
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/tools.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
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/api.func) 2>/dev/null || true
|
|
||||||
|
|
||||||
# Enable error handling
|
# Enable error handling
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user