mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-08-10 22:59:16 +02:00
Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 27190a1fcc | |||
| ec74ef5be6 | |||
| 6ae19c8a22 | |||
| d734d2204f | |||
| 43e3f5215d | |||
| 3ed946390f | |||
| 4626ec8845 | |||
| 579c1b6b26 | |||
| 5264fc5897 | |||
| 6063f0747d | |||
| 5374826753 | |||
| b32071de43 | |||
| af10e10f20 | |||
| ad09299de7 | |||
| 5f71caac5b | |||
| 87db412709 | |||
| 83ad1c972d | |||
| d11d3156db | |||
| 773b46c969 | |||
| d87e59f626 | |||
| d69579d477 | |||
| 8386465a92 | |||
| bcec3c405a | |||
| 4c8f5bd1f0 | |||
| d87fef0892 | |||
| 5d14989682 | |||
| a296ccfc7e | |||
| f0fc577d79 | |||
| fbd9d24966 | |||
| 347e0e6ff0 | |||
| 4adea9666e | |||
| 1d94e50601 | |||
| 0092fa8b54 | |||
| e00d4c6e51 | |||
| c1d5bfdb83 | |||
| 33de14e45c | |||
| 156f5ae16f | |||
| 7100e1679e | |||
| 63e4ea1396 | |||
| 63a91c8d93 | |||
| 590d638094 | |||
| fb1d670158 | |||
| 5ddc4a2a41 | |||
| 448a080970 | |||
| c45c3f3a6c | |||
| 12f228da1c | |||
| ecd115c279 | |||
| 288a130fe7 | |||
| d53486c86e | |||
| 4f80c217fc | |||
| f4afdfcd0c | |||
| 3865f855f0 | |||
| 94da6eeb83 | |||
| 078a76f263 | |||
| 58d819b2f4 | |||
| 1c03d0506c | |||
| 27f66a8016 | |||
| e3e29667c6 | |||
| 3921f03b73 | |||
| 1336b44a26 | |||
| 419f9e397e | |||
| fcbaedf7d8 | |||
| 4eb022fceb | |||
| 6f4d3b4841 | |||
| a4f893eb7c | |||
| 44589819d1 | |||
| 33bfae30e0 | |||
| 3fa516f94b | |||
| 26abc114fd | |||
| 5202ffcea2 | |||
| 86d67affa3 | |||
| e489c7f00b | |||
| 9df4cca7e8 | |||
| f219707efd | |||
| 77eece6f40 | |||
| 7b168d4986 | |||
| 64ae6241eb | |||
| 3ef8dc8312 | |||
| 53df629af3 | |||
| 5271863a59 | |||
| 468dba3f24 | |||
| 09e9918b8a | |||
| 64cd328363 | |||
| 6d63e3e476 | |||
| 3a846721ec | |||
| ac866bf816 | |||
| 5d202e2a4a | |||
| 888dfae126 | |||
| 60e8ed77c4 | |||
| cf942fb445 | |||
| 0c24310e90 | |||
| 336cdda47d | |||
| 268a6957a7 | |||
| e21a11c190 | |||
| 9debedc386 | |||
| 64448c0ded |
Generated
+139
@@ -1,3 +1,142 @@
|
|||||||
|
## 2026-08-08
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Ignis ([#16330](https://github.com/community-scripts/ProxmoxVE/pull/16330))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- core - setup_nodejs: bypass npm allowScripts policy globally on npm >=11 [@MickLesk](https://github.com/MickLesk) ([#16280](https://github.com/community-scripts/ProxmoxVE/pull/16280))
|
||||||
|
|
||||||
|
## 2026-08-07
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- NetworkOptimizer ([#16328](https://github.com/community-scripts/ProxmoxVE/pull/16328))
|
||||||
|
- Orb ([#16329](https://github.com/community-scripts/ProxmoxVE/pull/16329))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- HortusFox: start applying db migrations [@tomfrenzel](https://github.com/tomfrenzel) ([#16324](https://github.com/community-scripts/ProxmoxVE/pull/16324))
|
||||||
|
- Docker: report container updates instead of prompting, stop auto-updating Portainer Agent, fix addon detection of legacy Portainer [@MickLesk](https://github.com/MickLesk) ([#16298](https://github.com/community-scripts/ProxmoxVE/pull/16298))
|
||||||
|
- Immich: retry mise install on transient npm download failures [@MickLesk](https://github.com/MickLesk) ([#16301](https://github.com/community-scripts/ProxmoxVE/pull/16301))
|
||||||
|
- changedetection: remove msttcorefonts to fix install hang [@austinpilz](https://github.com/austinpilz) ([#16319](https://github.com/community-scripts/ProxmoxVE/pull/16319))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- core: extend new vars and pocketbase values [@MickLesk](https://github.com/MickLesk) ([#16313](https://github.com/community-scripts/ProxmoxVE/pull/16313))
|
||||||
|
|
||||||
|
## 2026-08-06
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- paperless: change update abort message (endless spinner) [@MickLesk](https://github.com/MickLesk) ([#16299](https://github.com/community-scripts/ProxmoxVE/pull/16299))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Vikunja: remove version pin, v2.5.0 fixes the systemd syscall filter crash [@MickLesk](https://github.com/MickLesk) ([#16300](https://github.com/community-scripts/ProxmoxVE/pull/16300))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- build.func: filter templates by host architecture during search [@MickLesk](https://github.com/MickLesk) ([#16302](https://github.com/community-scripts/ProxmoxVE/pull/16302))
|
||||||
|
|
||||||
|
## 2026-08-05
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- NextcloudPI: Bump to Debian Trixie & Tweak broken SSH [@MickLesk](https://github.com/MickLesk) ([#15957](https://github.com/community-scripts/ProxmoxVE/pull/15957))
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix(monitor-all): reduce polling CPU overhead [@jomplox](https://github.com/jomplox) ([#15907](https://github.com/community-scripts/ProxmoxVE/pull/15907))
|
||||||
|
|
||||||
|
## 2026-08-04
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Hister ([#16259](https://github.com/community-scripts/ProxmoxVE/pull/16259))
|
||||||
|
- Obsidian-LiveSync ([#16233](https://github.com/community-scripts/ProxmoxVE/pull/16233))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Actual Budget: allow native module install scripts under npm 11 (Node24) [@MickLesk](https://github.com/MickLesk) ([#16277](https://github.com/community-scripts/ProxmoxVE/pull/16277))
|
||||||
|
- Heimdall-Dashboard: run full composer install on update, force production env [@MickLesk](https://github.com/MickLesk) ([#16278](https://github.com/community-scripts/ProxmoxVE/pull/16278))
|
||||||
|
- xyOps: rebuild xySat satellite during update [@MickLesk](https://github.com/MickLesk) ([#16279](https://github.com/community-scripts/ProxmoxVE/pull/16279))
|
||||||
|
- HAOS: remove non-ASCII dash from CPU model dialog text [@MickLesk](https://github.com/MickLesk) ([#16276](https://github.com/community-scripts/ProxmoxVE/pull/16276))
|
||||||
|
- fix: back up Termix db/data so the update stops destroying encryption keys [@LukeGus](https://github.com/LukeGus) ([#16275](https://github.com/community-scripts/ProxmoxVE/pull/16275))
|
||||||
|
- passwordpusher: dynamically read Ruby version from .ruby-version file [@Copilot](https://github.com/Copilot) ([#16242](https://github.com/community-scripts/ProxmoxVE/pull/16242))
|
||||||
|
- fix(salt): write version cache to ~/.salt, not /~.salt [@TowyTowy](https://github.com/TowyTowy) ([#16265](https://github.com/community-scripts/ProxmoxVE/pull/16265))
|
||||||
|
- AFFiNE: fix version and build type reported by the app itself [@MickLesk](https://github.com/MickLesk) ([#16251](https://github.com/community-scripts/ProxmoxVE/pull/16251))
|
||||||
|
- Passbolt: fetch GPG key from Passbolt's own host instead of the flaky keyserver [@MickLesk](https://github.com/MickLesk) ([#16248](https://github.com/community-scripts/ProxmoxVE/pull/16248))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Opencloud: Pin version to 7.4.0 [@vhsdream](https://github.com/vhsdream) ([#16257](https://github.com/community-scripts/ProxmoxVE/pull/16257))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Bump NodeJS Versions of several scripts [@MickLesk](https://github.com/MickLesk) ([#16230](https://github.com/community-scripts/ProxmoxVE/pull/16230))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- tools.func: never delete ubuntu.sources (or other distro base sources) as orphaned [@MickLesk](https://github.com/MickLesk) ([#16250](https://github.com/community-scripts/ProxmoxVE/pull/16250))
|
||||||
|
- tools.func: complete a stale/partial backup manifest instead of trusting it as-is [@MickLesk](https://github.com/MickLesk) ([#16252](https://github.com/community-scripts/ProxmoxVE/pull/16252))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Refactor: harmonize tools/addon and move boilerplate into core.func [@MickLesk](https://github.com/MickLesk) ([#16202](https://github.com/community-scripts/ProxmoxVE/pull/16202))
|
||||||
|
|
||||||
|
## 2026-08-03
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Correction to link in Paperless-NGX update script [@jsspen](https://github.com/jsspen) ([#16241](https://github.com/community-scripts/ProxmoxVE/pull/16241))
|
||||||
|
- fix restore env in split pro [@johanngrobe](https://github.com/johanngrobe) ([#16228](https://github.com/community-scripts/ProxmoxVE/pull/16228))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- core: read all interactive prompts from /dev/tty, drain leftover input on read failure (hotfix) [@MickLesk](https://github.com/MickLesk) ([#16235](https://github.com/community-scripts/ProxmoxVE/pull/16235))
|
||||||
|
|
||||||
|
## 2026-08-02
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Portainer as Addon [@MickLesk](https://github.com/MickLesk) ([#16200](https://github.com/community-scripts/ProxmoxVE/pull/16200))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- LibreNMS: Ensure ipmitool dependency is installed [@tremor021](https://github.com/tremor021) ([#16219](https://github.com/community-scripts/ProxmoxVE/pull/16219))
|
||||||
|
- Bitfocus Companion: add libatomic1 dependency [@tremor021](https://github.com/tremor021) ([#16212](https://github.com/community-scripts/ProxmoxVE/pull/16212))
|
||||||
|
- fix(dispatcharr): add recordings and dvr queues to celery worker [@eXistC](https://github.com/eXistC) ([#16204](https://github.com/community-scripts/ProxmoxVE/pull/16204))
|
||||||
|
- add retry for uv - same as immich [@asylumexp](https://github.com/asylumexp) ([#16203](https://github.com/community-scripts/ProxmoxVE/pull/16203))
|
||||||
|
- Fix for cross-seed node version regression [@TorinFrancis](https://github.com/TorinFrancis) ([#16209](https://github.com/community-scripts/ProxmoxVE/pull/16209))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- chore: remove portainer setup from several scripts (moved to addon) [@MickLesk](https://github.com/MickLesk) ([#16201](https://github.com/community-scripts/ProxmoxVE/pull/16201))
|
||||||
|
|
||||||
## 2026-08-01
|
## 2026-08-01
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
### 🚀 Updated Scripts
|
||||||
|
|||||||
+2
@@ -6,6 +6,8 @@ on:
|
|||||||
- main
|
- main
|
||||||
paths:
|
paths:
|
||||||
- "ct/**.sh"
|
- "ct/**.sh"
|
||||||
|
- "tools/**.sh"
|
||||||
|
- "vm/**.sh"
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
Generated
+18
-2
@@ -314,12 +314,17 @@ jobs:
|
|||||||
// ── Allow-lists (mirror the slash bot) ─────────────────────────────
|
// ── Allow-lists (mirror the slash bot) ─────────────────────────────
|
||||||
const ALLOWED_FIELDS = {
|
const ALLOWED_FIELDS = {
|
||||||
name: 'string', description: 'string', logo: 'string', documentation: 'string',
|
name: 'string', description: 'string', logo: 'string', documentation: 'string',
|
||||||
website: 'string', project_url: 'string', github: 'string', config_path: 'string',
|
website: 'string', project_url: 'string', repository: 'string', config_path: 'string',
|
||||||
tags: 'string', port: 'number', default_user: 'nullable_string', default_passwd: 'nullable_string',
|
tags: 'string', port: 'number', default_user: 'nullable_string', default_passwd: 'nullable_string',
|
||||||
unprivileged: 'number', updateable: 'boolean', privileged: 'boolean', has_arm: 'boolean',
|
unprivileged: 'number', updateable: 'boolean', privileged: 'boolean',
|
||||||
|
architectures: 'select_list', platforms: 'select_list',
|
||||||
is_dev: 'boolean', is_disabled: 'boolean', disable_message: 'string',
|
is_dev: 'boolean', is_disabled: 'boolean', disable_message: 'string',
|
||||||
is_deleted: 'boolean', deleted_message: 'string'
|
is_deleted: 'boolean', deleted_message: 'string'
|
||||||
};
|
};
|
||||||
|
const SELECT_VALUES = {
|
||||||
|
architectures: ['amd64', 'arm64'],
|
||||||
|
platforms: ['pve', 'incus'],
|
||||||
|
};
|
||||||
const FIELD_TO_CT_VAR = { tags: 'var_tags', unprivileged: 'var_unprivileged' };
|
const FIELD_TO_CT_VAR = { tags: 'var_tags', unprivileged: 'var_unprivileged' };
|
||||||
const RESOURCE_KEYS = { cpu: 'number', ram: 'number', hdd: 'number', os: 'string', version: 'string' };
|
const RESOURCE_KEYS = { cpu: 'number', ram: 'number', hdd: 'number', os: 'string', version: 'string' };
|
||||||
const METHOD_KEYS = { config_path: 'string', script: 'string' };
|
const METHOD_KEYS = { config_path: 'string', script: 'string' };
|
||||||
@@ -339,6 +344,17 @@ jobs:
|
|||||||
if (isNaN(n)) return { error: '`' + key + '` must be a number' };
|
if (isNaN(n)) return { error: '`' + key + '` must be a number' };
|
||||||
return { value: n };
|
return { value: n };
|
||||||
}
|
}
|
||||||
|
if (type === 'select_list') {
|
||||||
|
// architectures/platforms are multi-selects over a closed set,
|
||||||
|
// so an unknown value is rejected rather than stored. The model
|
||||||
|
// may hand back an array or a comma-separated string.
|
||||||
|
const allowed = SELECT_VALUES[key] || [];
|
||||||
|
const raw = Array.isArray(rawVal) ? rawVal : String(rawVal == null ? '' : rawVal).split(',');
|
||||||
|
const values = raw.map(function (v) { return String(v).trim(); }).filter(Boolean);
|
||||||
|
const bad = values.filter(function (v) { return allowed.indexOf(v) === -1; });
|
||||||
|
if (bad.length > 0) return { error: '`' + key + '` accepts ' + allowed.join(', ') + ' — got: ' + bad.join(', ') };
|
||||||
|
return { value: values };
|
||||||
|
}
|
||||||
if (type === 'nullable_string') return { value: rawVal === '' || rawVal == null ? null : String(rawVal) };
|
if (type === 'nullable_string') return { value: rawVal === '' || rawVal == null ? null : String(rawVal) };
|
||||||
return { value: String(rawVal) };
|
return { value: String(rawVal) };
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+25
-6
@@ -323,9 +323,10 @@ jobs:
|
|||||||
'/pocketbase <slug> method remove <type>\n' +
|
'/pocketbase <slug> method remove <type>\n' +
|
||||||
'```\n' +
|
'```\n' +
|
||||||
'Method fields: `cpu` `ram` `hdd` `os` `version` `config_path` `script`\n\n' +
|
'Method fields: `cpu` `ram` `hdd` `os` `version` `config_path` `script`\n\n' +
|
||||||
'**Editable fields:** `name` `description` `logo` `documentation` `website` `project_url` `github` ' +
|
'**Editable fields:** `name` `description` `logo` `documentation` `website` `project_url` `repository` ' +
|
||||||
'`config_path` `port` `default_user` `default_passwd` ' +
|
'`config_path` `port` `default_user` `default_passwd` ' +
|
||||||
'`updateable` `privileged` `has_arm` `is_dev` ' +
|
'`updateable` `privileged` `is_dev` ' +
|
||||||
|
'`architectures` (amd64,arm64) `platforms` (pve,incus) ' +
|
||||||
'`is_disabled` `disable_message` `is_deleted` `deleted_message`';
|
'`is_disabled` `disable_message` `is_deleted` `deleted_message`';
|
||||||
|
|
||||||
if (!withoutCmd) {
|
if (!withoutCmd) {
|
||||||
@@ -504,7 +505,8 @@ jobs:
|
|||||||
out.push('- **Port:** ' + (record.port != null ? '`' + record.port + '`' : '—'));
|
out.push('- **Port:** ' + (record.port != null ? '`' + record.port + '`' : '—'));
|
||||||
out.push('- **Updateable:** ' + (record.updateable ? 'Yes' : 'No'));
|
out.push('- **Updateable:** ' + (record.updateable ? 'Yes' : 'No'));
|
||||||
out.push('- **Privileged:** ' + (record.privileged ? 'Yes' : 'No'));
|
out.push('- **Privileged:** ' + (record.privileged ? 'Yes' : 'No'));
|
||||||
out.push('- **ARM:** ' + (record.has_arm ? 'Yes' : 'No'));
|
out.push('- **Architectures:** ' + ((record.architectures || []).join(', ') || 'amd64'));
|
||||||
|
out.push('- **Platforms:** ' + ((record.platforms || []).join(', ') || 'pve'));
|
||||||
if (record.is_dev) out.push('- **Dev:** Yes');
|
if (record.is_dev) out.push('- **Dev:** Yes');
|
||||||
if (record.is_disabled) out.push('- **Disabled:** Yes' + (record.disable_message ? ' — ' + record.disable_message : ''));
|
if (record.is_disabled) out.push('- **Disabled:** Yes' + (record.disable_message ? ' — ' + record.disable_message : ''));
|
||||||
if (record.is_deleted) out.push('- **Deleted:** Yes' + (record.deleted_message ? ' — ' + record.deleted_message : ''));
|
if (record.is_deleted) out.push('- **Deleted:** Yes' + (record.deleted_message ? ' — ' + record.deleted_message : ''));
|
||||||
@@ -838,7 +840,7 @@ jobs:
|
|||||||
const fieldName = setMatch[1].toLowerCase();
|
const fieldName = setMatch[1].toLowerCase();
|
||||||
const SET_ALLOWED = {
|
const SET_ALLOWED = {
|
||||||
name: 'string', description: 'string', logo: 'string',
|
name: 'string', description: 'string', logo: 'string',
|
||||||
documentation: 'string', website: 'string', project_url: 'string', github: 'string',
|
documentation: 'string', website: 'string', project_url: 'string', repository: 'string',
|
||||||
config_path: 'string', disable_message: 'string', deleted_message: 'string'
|
config_path: 'string', disable_message: 'string', deleted_message: 'string'
|
||||||
};
|
};
|
||||||
if (!SET_ALLOWED[fieldName]) {
|
if (!SET_ALLOWED[fieldName]) {
|
||||||
@@ -888,7 +890,7 @@ jobs:
|
|||||||
documentation: 'string',
|
documentation: 'string',
|
||||||
website: 'string',
|
website: 'string',
|
||||||
project_url: 'string',
|
project_url: 'string',
|
||||||
github: 'string',
|
repository: 'string',
|
||||||
config_path: 'string',
|
config_path: 'string',
|
||||||
tags: 'string',
|
tags: 'string',
|
||||||
port: 'number',
|
port: 'number',
|
||||||
@@ -897,7 +899,8 @@ jobs:
|
|||||||
unprivileged: 'number',
|
unprivileged: 'number',
|
||||||
updateable: 'boolean',
|
updateable: 'boolean',
|
||||||
privileged: 'boolean',
|
privileged: 'boolean',
|
||||||
has_arm: 'boolean',
|
architectures: 'select_list',
|
||||||
|
platforms: 'select_list',
|
||||||
is_dev: 'boolean',
|
is_dev: 'boolean',
|
||||||
is_disabled: 'boolean',
|
is_disabled: 'boolean',
|
||||||
disable_message: 'string',
|
disable_message: 'string',
|
||||||
@@ -924,6 +927,10 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cast values to correct types
|
// Cast values to correct types
|
||||||
|
const SELECT_VALUES = {
|
||||||
|
architectures: ['amd64', 'arm64'],
|
||||||
|
platforms: ['pve', 'incus'],
|
||||||
|
};
|
||||||
const payload = {};
|
const payload = {};
|
||||||
for (const [key, rawVal] of Object.entries(parsedFields)) {
|
for (const [key, rawVal] of Object.entries(parsedFields)) {
|
||||||
const type = ALLOWED_FIELDS[key];
|
const type = ALLOWED_FIELDS[key];
|
||||||
@@ -943,6 +950,18 @@ jobs:
|
|||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
payload[key] = n;
|
payload[key] = n;
|
||||||
|
} else if (type === 'select_list') {
|
||||||
|
// architectures/platforms are multi-selects over a closed set,
|
||||||
|
// so an unknown value is rejected rather than stored.
|
||||||
|
const allowed = SELECT_VALUES[key] || [];
|
||||||
|
const values = rawVal.split(',').map(function (v) { return v.trim(); }).filter(Boolean);
|
||||||
|
const bad = values.filter(function (v) { return allowed.indexOf(v) === -1; });
|
||||||
|
if (bad.length > 0) {
|
||||||
|
await addReaction('-1');
|
||||||
|
await postComment('❌ **PocketBase Bot**: `' + key + '` accepts ' + allowed.join(', ') + ' — got: `' + bad.join(', ') + '`');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
payload[key] = values;
|
||||||
} else if (type === 'nullable_string') {
|
} else if (type === 'nullable_string') {
|
||||||
payload[key] = rawVal === '' ? null : rawVal;
|
payload[key] = rawVal === '' ? null : rawVal;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+13
-1
@@ -179,7 +179,19 @@ jobs:
|
|||||||
if (resolvedType) payload.type = resolvedType;
|
if (resolvedType) payload.type = resolvedType;
|
||||||
var resolvedCats = (data.categories || []).map(function(n) { return categoryNameToPbId[categoryIdToName[n]]; }).filter(Boolean);
|
var resolvedCats = (data.categories || []).map(function(n) { return categoryNameToPbId[categoryIdToName[n]]; }).filter(Boolean);
|
||||||
if (resolvedCats.length) payload.categories = resolvedCats;
|
if (resolvedCats.length) payload.categories = resolvedCats;
|
||||||
if (data.has_arm !== undefined) payload.has_arm = data.has_arm === true || data.has_arm === 'true';
|
// architectures replaces has_arm: a boolean could say "also ARM" but
|
||||||
|
// not "ARM only" or "amd64 only". A record written before the field
|
||||||
|
// existed is read through the old key so nothing silently drops.
|
||||||
|
if (Array.isArray(data.architectures)) {
|
||||||
|
payload.architectures = data.architectures.filter(function (a) { return a === 'amd64' || a === 'arm64'; });
|
||||||
|
} else if (data.has_arm !== undefined) {
|
||||||
|
payload.architectures = (data.has_arm === true || data.has_arm === 'true') ? ['amd64', 'arm64'] : ['amd64'];
|
||||||
|
}
|
||||||
|
if (Array.isArray(data.platforms)) {
|
||||||
|
payload.platforms = data.platforms.filter(function (p) { return p === 'pve' || p === 'incus'; });
|
||||||
|
}
|
||||||
|
if (Array.isArray(data.app_vars)) payload.app_vars = data.app_vars;
|
||||||
|
if (data.repository !== undefined) payload.repository = data.repository;
|
||||||
if (data.version !== undefined) payload.version = data.version;
|
if (data.version !== undefined) payload.version = data.version;
|
||||||
if (data.changelog !== undefined) payload.changelog = data.changelog;
|
if (data.changelog !== undefined) payload.changelog = data.changelog;
|
||||||
if (data.screenshots !== undefined) payload.screenshots = data.screenshots;
|
if (data.screenshots !== undefined) payload.screenshots = data.screenshots;
|
||||||
|
|||||||
+3
-1
@@ -24,7 +24,9 @@ generate_headers() {
|
|||||||
|
|
||||||
app_name=$(grep -oP '^APP="\K[^"]+' "$script" 2>/dev/null)
|
app_name=$(grep -oP '^APP="\K[^"]+' "$script" 2>/dev/null)
|
||||||
if [[ -n "$app_name" ]]; then
|
if [[ -n "$app_name" ]]; then
|
||||||
output_file="${headers_dir}/$(basename "${script%.*}")"
|
# core.func/vm-core.func look the header up as "${APP,,}" without spaces,
|
||||||
|
# so the generated file has to be named after APP - not after the script.
|
||||||
|
output_file="${headers_dir}/$(echo "${app_name,,}" | tr -d ' ')"
|
||||||
figlet_output=$(figlet -w 500 -f slant "$app_name")
|
figlet_output=$(figlet -w 500 -f slant "$app_name")
|
||||||
if [[ -n "$figlet_output" ]]; then
|
if [[ -n "$figlet_output" ]]; then
|
||||||
echo "$figlet_output" >"$output_file"
|
echo "$figlet_output" >"$output_file"
|
||||||
|
|||||||
+153
-92
@@ -86,6 +86,9 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -99,7 +102,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><h4>August (1 entries)</h4></summary>
|
<summary><h4>August (8 entries)</h4></summary>
|
||||||
|
|
||||||
[View August 2026 Changelog](.github/changelogs/2026/08.md)
|
[View August 2026 Changelog](.github/changelogs/2026/08.md)
|
||||||
|
|
||||||
@@ -518,6 +521,154 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## 2026-08-10
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- post-pdm-install ([#16368](https://github.com/community-scripts/ProxmoxVE/pull/16368))
|
||||||
|
|
||||||
|
## 2026-08-09
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Fix: CouchDB Erlang cookie breaks vm.args (use hex) [@fudianchn](https://github.com/fudianchn) ([#16361](https://github.com/community-scripts/ProxmoxVE/pull/16361))
|
||||||
|
- SparkyFitness: Install Git for frontend builds [@MickLesk](https://github.com/MickLesk) ([#16352](https://github.com/community-scripts/ProxmoxVE/pull/16352))
|
||||||
|
- Byparr: Use invisible-playwright browser setup [@MickLesk](https://github.com/MickLesk) ([#16353](https://github.com/community-scripts/ProxmoxVE/pull/16353))
|
||||||
|
- Crafty Controller: Restore ownership after updates [@MickLesk](https://github.com/MickLesk) ([#16354](https://github.com/community-scripts/ProxmoxVE/pull/16354))
|
||||||
|
- Webtrees: Fix schema check in silent mode [@MickLesk](https://github.com/MickLesk) ([#16355](https://github.com/community-scripts/ProxmoxVE/pull/16355))
|
||||||
|
- SigNoz: Allow legacy metadata schema on ClickHouse 26 [@MickLesk](https://github.com/MickLesk) ([#16356](https://github.com/community-scripts/ProxmoxVE/pull/16356))
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Portainer: Update existing CE and BE installations [@MickLesk](https://github.com/MickLesk) ([#16357](https://github.com/community-scripts/ProxmoxVE/pull/16357))
|
||||||
|
|
||||||
|
### 📚 Documentation
|
||||||
|
|
||||||
|
- github: update Star History links and image sources [@MickLesk](https://github.com/MickLesk) ([#16367](https://github.com/community-scripts/ProxmoxVE/pull/16367))
|
||||||
|
|
||||||
|
## 2026-08-08
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Ignis ([#16330](https://github.com/community-scripts/ProxmoxVE/pull/16330))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- core - setup_nodejs: bypass npm allowScripts policy globally on npm >=11 [@MickLesk](https://github.com/MickLesk) ([#16280](https://github.com/community-scripts/ProxmoxVE/pull/16280))
|
||||||
|
|
||||||
|
## 2026-08-07
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- NetworkOptimizer ([#16328](https://github.com/community-scripts/ProxmoxVE/pull/16328))
|
||||||
|
- Orb ([#16329](https://github.com/community-scripts/ProxmoxVE/pull/16329))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- HortusFox: start applying db migrations [@tomfrenzel](https://github.com/tomfrenzel) ([#16324](https://github.com/community-scripts/ProxmoxVE/pull/16324))
|
||||||
|
- Docker: report container updates instead of prompting, stop auto-updating Portainer Agent, fix addon detection of legacy Portainer [@MickLesk](https://github.com/MickLesk) ([#16298](https://github.com/community-scripts/ProxmoxVE/pull/16298))
|
||||||
|
- Immich: retry mise install on transient npm download failures [@MickLesk](https://github.com/MickLesk) ([#16301](https://github.com/community-scripts/ProxmoxVE/pull/16301))
|
||||||
|
- changedetection: remove msttcorefonts to fix install hang [@austinpilz](https://github.com/austinpilz) ([#16319](https://github.com/community-scripts/ProxmoxVE/pull/16319))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- core: extend new vars and pocketbase values [@MickLesk](https://github.com/MickLesk) ([#16313](https://github.com/community-scripts/ProxmoxVE/pull/16313))
|
||||||
|
|
||||||
|
## 2026-08-06
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- paperless: change update abort message (endless spinner) [@MickLesk](https://github.com/MickLesk) ([#16299](https://github.com/community-scripts/ProxmoxVE/pull/16299))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Vikunja: remove version pin, v2.5.0 fixes the systemd syscall filter crash [@MickLesk](https://github.com/MickLesk) ([#16300](https://github.com/community-scripts/ProxmoxVE/pull/16300))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- build.func: filter templates by host architecture during search [@MickLesk](https://github.com/MickLesk) ([#16302](https://github.com/community-scripts/ProxmoxVE/pull/16302))
|
||||||
|
|
||||||
|
## 2026-08-05
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- NextcloudPI: Bump to Debian Trixie & Tweak broken SSH [@MickLesk](https://github.com/MickLesk) ([#15957](https://github.com/community-scripts/ProxmoxVE/pull/15957))
|
||||||
|
|
||||||
|
### 🧰 Tools
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- fix(monitor-all): reduce polling CPU overhead [@jomplox](https://github.com/jomplox) ([#15907](https://github.com/community-scripts/ProxmoxVE/pull/15907))
|
||||||
|
|
||||||
|
## 2026-08-04
|
||||||
|
|
||||||
|
### 🆕 New Scripts
|
||||||
|
|
||||||
|
- Hister ([#16259](https://github.com/community-scripts/ProxmoxVE/pull/16259))
|
||||||
|
- Obsidian-LiveSync ([#16233](https://github.com/community-scripts/ProxmoxVE/pull/16233))
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Actual Budget: allow native module install scripts under npm 11 (Node24) [@MickLesk](https://github.com/MickLesk) ([#16277](https://github.com/community-scripts/ProxmoxVE/pull/16277))
|
||||||
|
- Heimdall-Dashboard: run full composer install on update, force production env [@MickLesk](https://github.com/MickLesk) ([#16278](https://github.com/community-scripts/ProxmoxVE/pull/16278))
|
||||||
|
- xyOps: rebuild xySat satellite during update [@MickLesk](https://github.com/MickLesk) ([#16279](https://github.com/community-scripts/ProxmoxVE/pull/16279))
|
||||||
|
- HAOS: remove non-ASCII dash from CPU model dialog text [@MickLesk](https://github.com/MickLesk) ([#16276](https://github.com/community-scripts/ProxmoxVE/pull/16276))
|
||||||
|
- fix: back up Termix db/data so the update stops destroying encryption keys [@LukeGus](https://github.com/LukeGus) ([#16275](https://github.com/community-scripts/ProxmoxVE/pull/16275))
|
||||||
|
- passwordpusher: dynamically read Ruby version from .ruby-version file [@Copilot](https://github.com/Copilot) ([#16242](https://github.com/community-scripts/ProxmoxVE/pull/16242))
|
||||||
|
- fix(salt): write version cache to ~/.salt, not /~.salt [@TowyTowy](https://github.com/TowyTowy) ([#16265](https://github.com/community-scripts/ProxmoxVE/pull/16265))
|
||||||
|
- AFFiNE: fix version and build type reported by the app itself [@MickLesk](https://github.com/MickLesk) ([#16251](https://github.com/community-scripts/ProxmoxVE/pull/16251))
|
||||||
|
- Passbolt: fetch GPG key from Passbolt's own host instead of the flaky keyserver [@MickLesk](https://github.com/MickLesk) ([#16248](https://github.com/community-scripts/ProxmoxVE/pull/16248))
|
||||||
|
|
||||||
|
- #### ✨ New Features
|
||||||
|
|
||||||
|
- Opencloud: Pin version to 7.4.0 [@vhsdream](https://github.com/vhsdream) ([#16257](https://github.com/community-scripts/ProxmoxVE/pull/16257))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Bump NodeJS Versions of several scripts [@MickLesk](https://github.com/MickLesk) ([#16230](https://github.com/community-scripts/ProxmoxVE/pull/16230))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- tools.func: never delete ubuntu.sources (or other distro base sources) as orphaned [@MickLesk](https://github.com/MickLesk) ([#16250](https://github.com/community-scripts/ProxmoxVE/pull/16250))
|
||||||
|
- tools.func: complete a stale/partial backup manifest instead of trusting it as-is [@MickLesk](https://github.com/MickLesk) ([#16252](https://github.com/community-scripts/ProxmoxVE/pull/16252))
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- Refactor: harmonize tools/addon and move boilerplate into core.func [@MickLesk](https://github.com/MickLesk) ([#16202](https://github.com/community-scripts/ProxmoxVE/pull/16202))
|
||||||
|
|
||||||
|
## 2026-08-03
|
||||||
|
|
||||||
|
### 🚀 Updated Scripts
|
||||||
|
|
||||||
|
- #### 🐞 Bug Fixes
|
||||||
|
|
||||||
|
- Correction to link in Paperless-NGX update script [@jsspen](https://github.com/jsspen) ([#16241](https://github.com/community-scripts/ProxmoxVE/pull/16241))
|
||||||
|
- fix restore env in split pro [@johanngrobe](https://github.com/johanngrobe) ([#16228](https://github.com/community-scripts/ProxmoxVE/pull/16228))
|
||||||
|
|
||||||
|
### 💾 Core
|
||||||
|
|
||||||
|
- #### 🔧 Refactor
|
||||||
|
|
||||||
|
- core: read all interactive prompts from /dev/tty, drain leftover input on read failure (hotfix) [@MickLesk](https://github.com/MickLesk) ([#16235](https://github.com/community-scripts/ProxmoxVE/pull/16235))
|
||||||
|
|
||||||
## 2026-08-02
|
## 2026-08-02
|
||||||
|
|
||||||
### 🆕 New Scripts
|
### 🆕 New Scripts
|
||||||
@@ -1047,94 +1198,4 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
|||||||
|
|
||||||
- Adapt to new artifact filename format for pocket id [@wollew](https://github.com/wollew) ([#15689](https://github.com/community-scripts/ProxmoxVE/pull/15689))
|
- Adapt to new artifact filename format for pocket id [@wollew](https://github.com/wollew) ([#15689](https://github.com/community-scripts/ProxmoxVE/pull/15689))
|
||||||
- Fireshare: Fix for install and upgrade to v1.7.3 [@tremor021](https://github.com/tremor021) ([#15673](https://github.com/community-scripts/ProxmoxVE/pull/15673))
|
- Fireshare: Fix for install and upgrade to v1.7.3 [@tremor021](https://github.com/tremor021) ([#15673](https://github.com/community-scripts/ProxmoxVE/pull/15673))
|
||||||
- Endurain: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15674](https://github.com/community-scripts/ProxmoxVE/pull/15674))
|
- Endurain: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15674](https://github.com/community-scripts/ProxmoxVE/pull/15674))
|
||||||
|
|
||||||
## 2026-07-09
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- fix(pihole): repair Unbound DNS-over-TLS (DoT) forwarding config [@TowyTowy](https://github.com/TowyTowy) ([#15654](https://github.com/community-scripts/ProxmoxVE/pull/15654))
|
|
||||||
|
|
||||||
## 2026-07-08
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Opencloud: Bump version to 7.2.1 [@vhsdream](https://github.com/vhsdream) ([#15655](https://github.com/community-scripts/ProxmoxVE/pull/15655))
|
|
||||||
- BabyBuddy: Harden update script [@MickLesk](https://github.com/MickLesk) ([#15642](https://github.com/community-scripts/ProxmoxVE/pull/15642))
|
|
||||||
|
|
||||||
## 2026-07-07
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- Forgejo-Runner ([#15046](https://github.com/community-scripts/ProxmoxVE/pull/15046))
|
|
||||||
|
|
||||||
## 2026-07-06
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- Fix alignment in various ct end messages [@tremor021](https://github.com/tremor021) ([#15632](https://github.com/community-scripts/ProxmoxVE/pull/15632))
|
|
||||||
- Immich: Update libvips to 8.18.4 [@vhsdream](https://github.com/vhsdream) ([#15619](https://github.com/community-scripts/ProxmoxVE/pull/15619))
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Wizarr: Build JS and CSS static assets [@vhsdream](https://github.com/vhsdream) ([#15634](https://github.com/community-scripts/ProxmoxVE/pull/15634))
|
|
||||||
- RustDesk Server: Update URL format in rustdeskserver.sh [@tremor021](https://github.com/tremor021) ([#15626](https://github.com/community-scripts/ProxmoxVE/pull/15626))
|
|
||||||
- attempt to port docker-vm to support arm64 [@asylumexp](https://github.com/asylumexp) ([#15611](https://github.com/community-scripts/ProxmoxVE/pull/15611))
|
|
||||||
- fix(plane): don't clobber global app var, breaking /usr/bin/update [@asylumexp](https://github.com/asylumexp) ([#15612](https://github.com/community-scripts/ProxmoxVE/pull/15612))
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- cliproxyapi: point setup message at /management.html [@austinpilz](https://github.com/austinpilz) ([#15628](https://github.com/community-scripts/ProxmoxVE/pull/15628))
|
|
||||||
|
|
||||||
### 🗑️ Deleted Scripts
|
|
||||||
|
|
||||||
- Remove: FlowiseAI [@MickLesk](https://github.com/MickLesk) ([#15624](https://github.com/community-scripts/ProxmoxVE/pull/15624))
|
|
||||||
|
|
||||||
## 2026-07-05
|
|
||||||
|
|
||||||
### 🆕 New Scripts
|
|
||||||
|
|
||||||
- excalidash ([#15604](https://github.com/community-scripts/ProxmoxVE/pull/15604))
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- fix: homarr: cli [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15603](https://github.com/community-scripts/ProxmoxVE/pull/15603))
|
|
||||||
- immich: vacuum smart_search/face_search before VectorChord bump [@irishpadres](https://github.com/irishpadres) ([#15607](https://github.com/community-scripts/ProxmoxVE/pull/15607))
|
|
||||||
|
|
||||||
## 2026-07-04
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Element Synapse: Fix heredoc syntax in elementsynapse-install.sh [@tremor021](https://github.com/tremor021) ([#15594](https://github.com/community-scripts/ProxmoxVE/pull/15594))
|
|
||||||
- Twenty: Fix backup restore [@tremor021](https://github.com/tremor021) ([#15586](https://github.com/community-scripts/ProxmoxVE/pull/15586))
|
|
||||||
- fix(endurain): update frontend dist path after upstream restructure [@joaovitoriasilva](https://github.com/joaovitoriasilva) ([#15590](https://github.com/community-scripts/ProxmoxVE/pull/15590))
|
|
||||||
|
|
||||||
## 2026-07-03
|
|
||||||
|
|
||||||
### 🚀 Updated Scripts
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Immich: handle mise monorepo_root rename correctly | bump to 3.0.1 [@MickLesk](https://github.com/MickLesk) ([#15557](https://github.com/community-scripts/ProxmoxVE/pull/15557))
|
|
||||||
|
|
||||||
- #### ✨ New Features
|
|
||||||
|
|
||||||
- Opencloud: bump to v7.2.0 [@vhsdream](https://github.com/vhsdream) ([#15575](https://github.com/community-scripts/ProxmoxVE/pull/15575))
|
|
||||||
|
|
||||||
### 💾 Core
|
|
||||||
|
|
||||||
- #### 🔧 Refactor
|
|
||||||
|
|
||||||
- tools.func: fix corepack/pnpm install flow in setup_nodejs [@MickLesk](https://github.com/MickLesk) ([#15579](https://github.com/community-scripts/ProxmoxVE/pull/15579))
|
|
||||||
|
|
||||||
### 🧰 Tools
|
|
||||||
|
|
||||||
- #### 🐞 Bug Fixes
|
|
||||||
|
|
||||||
- Removed deprecated parameter in Filebrowser Quantum configuration [@alpargatagazer](https://github.com/alpargatagazer) ([#15573](https://github.com/community-scripts/ProxmoxVE/pull/15573))
|
|
||||||
@@ -103,6 +103,55 @@ Key rules at a glance:
|
|||||||
- Quote all variables: `"$VAR"` not `$VAR`
|
- Quote all variables: `"$VAR"` not `$VAR`
|
||||||
- Use lowercase variable names
|
- Use lowercase variable names
|
||||||
- Do not hardcode credentials or sensitive values
|
- Do not hardcode credentials or sensitive values
|
||||||
|
- Never prompt without an escape hatch — see below
|
||||||
|
|
||||||
|
### Answering a prompt up front
|
||||||
|
|
||||||
|
An install script that only asks cannot be deployed unattended. Read the
|
||||||
|
variable first and prompt only when it is unset:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
if [[ -z "${var_admin_user:-}" ]]; then
|
||||||
|
read -r -p "${TAB3}Admin username: " var_admin_user
|
||||||
|
fi
|
||||||
|
var_admin_user="${var_admin_user:-admin}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Name them `var_<something>`, the same namespace the container variables use.
|
||||||
|
`install/forgejo-runner-install.sh`, `install/pangolin-install.sh`, and `install/docker-install.sh` all
|
||||||
|
follow this.
|
||||||
|
|
||||||
|
The variable also has to be exported from `ct/<app>.sh`, or it never reaches
|
||||||
|
the container — `lxc-attach` carries the caller's environment, but only for
|
||||||
|
what was actually exported:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export var_admin_user="${var_admin_user:-}"
|
||||||
|
```
|
||||||
|
|
||||||
|
Declare them on the script's PocketBase record in `app_vars` so the website's
|
||||||
|
generator can offer them as fields:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"app_vars": [
|
||||||
|
{
|
||||||
|
"name": "var_admin_user",
|
||||||
|
"label": "Admin Username",
|
||||||
|
"type": "text",
|
||||||
|
"default": "admin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "var_admin_pass",
|
||||||
|
"label": "Admin Password",
|
||||||
|
"type": "password",
|
||||||
|
"secret": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
`type` is one of `text`, `password`, `number`, `boolean` (`yes`/`no`) or
|
||||||
|
`select` (with `options`). Mark anything credential-like `secret` — the
|
||||||
|
generator keeps those out of shareable links and out of the on-screen summary.
|
||||||
|
|
||||||
Full standards and examples: **[community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution)**
|
Full standards and examples: **[community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution)**
|
||||||
|
|
||||||
|
|||||||
@@ -171,11 +171,21 @@ This project runs on community contributions. Whether you want to write new scri
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://star-history.com/#community-scripts/ProxmoxVE&Date">
|
<a href="https://www.star-history.com/?repos=community-scripts%2FProxmoxVE&type=date&legend=top-left">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date&theme=dark" />
|
<source
|
||||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" />
|
media="(prefers-color-scheme: dark)"
|
||||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" width="700" />
|
srcset="https://api.star-history.com/chart?repos=community-scripts/ProxmoxVE&type=date&theme=dark&legend=top-left&sealed_token=-lUy2KH6pJryUyLCbiWRwFz3ilXMDFVFHm0lJcqh-Hl5e0QNNKjINNcXzULhaZVpBugN_TDaxOawEAuzwBc5Sjqa2mCRw9K6TdCioKRDsS_qXUwhkLQSCMRSg1schCdl4rQD8qEj7PWBjin-fyHnDm7NnM6akZp59jndG7qV7PrvG8nLBgDIuuA-wAI3"
|
||||||
|
/>
|
||||||
|
<source
|
||||||
|
media="(prefers-color-scheme: light)"
|
||||||
|
srcset="https://api.star-history.com/chart?repos=community-scripts/ProxmoxVE&type=date&legend=top-left&sealed_token=-lUy2KH6pJryUyLCbiWRwFz3ilXMDFVFHm0lJcqh-Hl5e0QNNKjINNcXzULhaZVpBugN_TDaxOawEAuzwBc5Sjqa2mCRw9K6TdCioKRDsS_qXUwhkLQSCMRSg1schCdl4rQD8qEj7PWBjin-fyHnDm7NnM6akZp59jndG7qV7PrvG8nLBgDIuuA-wAI3"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
alt="Star History Chart"
|
||||||
|
src="https://api.star-history.com/chart?repos=community-scripts/ProxmoxVE&type=date&legend=top-left&sealed_token=-lUy2KH6pJryUyLCbiWRwFz3ilXMDFVFHm0lJcqh-Hl5e0QNNKjINNcXzULhaZVpBugN_TDaxOawEAuzwBc5Sjqa2mCRw9K6TdCioKRDsS_qXUwhkLQSCMRSg1schCdl4rQD8qEj7PWBjin-fyHnDm7NnM6akZp59jndG7qV7PrvG8nLBgDIuuA-wAI3"
|
||||||
|
width="700"
|
||||||
|
/>
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
+3
-1
@@ -30,7 +30,7 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
NODE_VERSION="22" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
RELEASE=$(get_latest_github_release "actualbudget/actual")
|
RELEASE=$(get_latest_github_release "actualbudget/actual")
|
||||||
if [[ -f /opt/actualbudget-data/config.json ]]; then
|
if [[ -f /opt/actualbudget-data/config.json ]]; then
|
||||||
if check_for_gh_release "actualbudget" "actualbudget/actual"; then
|
if check_for_gh_release "actualbudget" "actualbudget/actual"; then
|
||||||
@@ -39,7 +39,9 @@ function update_script() {
|
|||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
msg_info "Updating Actual Budget to ${RELEASE}"
|
msg_info "Updating Actual Budget to ${RELEASE}"
|
||||||
|
$STD npm config set allow-scripts=bcrypt,better-sqlite3,argon2 --location=global
|
||||||
$STD npm update -g @actual-app/sync-server
|
$STD npm update -g @actual-app/sync-server
|
||||||
|
$STD npm rebuild -g
|
||||||
echo "${RELEASE}" >~/.actualbudget
|
echo "${RELEASE}" >~/.actualbudget
|
||||||
msg_ok "Updated Actual Budget to ${RELEASE}"
|
msg_ok "Updated Actual Budget to ${RELEASE}"
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ TURBO
|
|||||||
|
|
||||||
export NODE_OPTIONS="--max-old-space-size=2048"
|
export NODE_OPTIONS="--max-old-space-size=2048"
|
||||||
$STD yarn install
|
$STD yarn install
|
||||||
|
$STD bash ./scripts/set-version.sh "$(cat ~/.affine_app)"
|
||||||
|
export BUILD_TYPE=stable
|
||||||
$STD npm install -g typescript
|
$STD npm install -g typescript
|
||||||
|
|
||||||
$STD yarn affine @affine/native build
|
$STD yarn affine @affine/native build
|
||||||
|
|||||||
+1
-1
@@ -81,7 +81,7 @@ function update_script() {
|
|||||||
msg_info "Configuring Byparr"
|
msg_info "Configuring Byparr"
|
||||||
cd /opt/Byparr
|
cd /opt/Byparr
|
||||||
$STD uv sync --link-mode copy
|
$STD uv sync --link-mode copy
|
||||||
$STD uv run camoufox fetch
|
$STD uv run python -m invisible_playwright fetch
|
||||||
msg_ok "Configured Byparr"
|
msg_ok "Configured Byparr"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ function update_script() {
|
|||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gl_release "Crafty-Controller" "crafty-controller/crafty-4" "tarball" "latest" "/opt/crafty-controller/crafty/crafty-4"
|
CLEAN_INSTALL=1 fetch_and_deploy_gl_release "Crafty-Controller" "crafty-controller/crafty-4" "tarball" "latest" "/opt/crafty-controller/crafty/crafty-4"
|
||||||
|
|
||||||
|
chown -R crafty:crafty /opt/crafty-controller
|
||||||
restore_backup
|
restore_backup
|
||||||
|
|
||||||
msg_info "Updating TemurinJDK"
|
msg_info "Updating TemurinJDK"
|
||||||
@@ -53,7 +54,6 @@ function update_script() {
|
|||||||
msg_ok "Updated TemurinJDK"
|
msg_ok "Updated TemurinJDK"
|
||||||
|
|
||||||
msg_info "Updating Python dependencies"
|
msg_info "Updating Python dependencies"
|
||||||
chown -R crafty:crafty /opt/crafty-controller
|
|
||||||
cd /opt/crafty-controller/crafty/crafty-4
|
cd /opt/crafty-controller/crafty/crafty-4
|
||||||
$STD sudo -u crafty bash -c '
|
$STD sudo -u crafty bash -c '
|
||||||
source /opt/crafty-controller/crafty/.venv/bin/activate
|
source /opt/crafty-controller/crafty/.venv/bin/activate
|
||||||
|
|||||||
@@ -42,20 +42,6 @@ function update_script() {
|
|||||||
echo -e "${TAB}${TAB}${GN}bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/portainer.sh)\"${CL}"
|
echo -e "${TAB}${TAB}${GN}bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/portainer.sh)\"${CL}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if docker ps -a --format '{{.Names}}' | grep -q '^portainer_agent$'; then
|
|
||||||
msg_info "Updating Portainer Agent"
|
|
||||||
$STD docker pull portainer/agent:latest
|
|
||||||
$STD docker stop portainer_agent
|
|
||||||
$STD docker rm portainer_agent
|
|
||||||
$STD docker run -d \
|
|
||||||
-p 9001:9001 \
|
|
||||||
--name=portainer_agent \
|
|
||||||
--restart=always \
|
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
|
|
||||||
portainer/agent
|
|
||||||
msg_ok "Updated Portainer Agent"
|
|
||||||
fi
|
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ var_nesting="${var_nesting:-1}"
|
|||||||
var_keyctl="${var_keyctl:-1}"
|
var_keyctl="${var_keyctl:-1}"
|
||||||
|
|
||||||
export var_forgejo_instance="${var_forgejo_instance:-}"
|
export var_forgejo_instance="${var_forgejo_instance:-}"
|
||||||
|
export var_forgejo_runner_uuid="${var_forgejo_runner_uuid:-}"
|
||||||
export var_forgejo_runner_token="${var_forgejo_runner_token:-}"
|
export var_forgejo_runner_token="${var_forgejo_runner_token:-}"
|
||||||
export var_runner_labels="${var_runner_labels:-}"
|
export var_runner_labels="${var_runner_labels:-}"
|
||||||
|
|
||||||
@@ -64,6 +65,10 @@ if [[ -n "${mode:-}" ]]; then
|
|||||||
msg_error "var_forgejo_instance is required for unattended installs."
|
msg_error "var_forgejo_instance is required for unattended installs."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [[ -z "${var_forgejo_runner_uuid:-}" ]]; then
|
||||||
|
msg_error "var_forgejo_runner_uuid is required for unattended installs."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
if [[ -z "${var_forgejo_runner_token:-}" ]]; then
|
if [[ -z "${var_forgejo_runner_token:-}" ]]; then
|
||||||
msg_error "var_forgejo_runner_token is required for unattended installs."
|
msg_error "var_forgejo_runner_token is required for unattended installs."
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#!/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://about.gitlab.com/
|
||||||
|
|
||||||
|
APP="GitLab"
|
||||||
|
var_tags="${var_tags:-git;devtools}"
|
||||||
|
var_cpu="${var_cpu:-4}"
|
||||||
|
var_ram="${var_ram:-8192}"
|
||||||
|
var_disk="${var_disk:-40}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
#var_arm64="${var_arm64:-no}" # unset = ask the user; set yes/no only when verified
|
||||||
|
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/gitlab ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Updating GitLab (Patience)"
|
||||||
|
$STD apt update
|
||||||
|
$STD apt install -y gitlab-ce
|
||||||
|
msg_ok "Updated GitLab"
|
||||||
|
|
||||||
|
msg_info "Reconfiguring GitLab (Patience)"
|
||||||
|
$STD gitlab-ctl reconfigure
|
||||||
|
msg_ok "Reconfigured GitLab"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}${CL}"
|
||||||
|
echo -e "${INFO}${YW}The initial root password is valid for 24 hours:${CL}"
|
||||||
|
echo -e "${TAB}${DEFAULT}${BGN}cat /etc/gitlab/initial_root_password${CL}"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
_______ __ __ __
|
||||||
|
/ ____(_) /_/ / ____ _/ /_
|
||||||
|
/ / __/ / __/ / / __ `/ __ \
|
||||||
|
/ /_/ / / /_/ /___/ /_/ / /_/ /
|
||||||
|
\____/_/\__/_____/\__,_/_.___/
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
__ ___ __
|
||||||
|
/ / / (_)____/ /____ _____
|
||||||
|
/ /_/ / / ___/ __/ _ \/ ___/
|
||||||
|
/ __ / (__ ) /_/ __/ /
|
||||||
|
/_/ /_/_/____/\__/\___/_/
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
____ _
|
||||||
|
/ _/___ _____ (_)____
|
||||||
|
/ // __ `/ __ \/ / ___/
|
||||||
|
_/ // /_/ / / / / (__ )
|
||||||
|
/___/\__, /_/ /_/_/____/
|
||||||
|
/____/
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
_____
|
|
||||||
/ ___/_________ _____ ____ ____ __ __
|
|
||||||
\__ \/ ___/ __ `/ __ \/ __ \/ __ \/ / / /
|
|
||||||
___/ / /__/ /_/ / / / / /_/ / /_/ / /_/ /
|
|
||||||
/____/\___/\__,_/_/ /_/\____/ .___/\__, /
|
|
||||||
/_/ /____/
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
_ __ __ __ ____ __ _ _
|
||||||
|
/ | / /__ / /__ ______ _____/ /__/ __ \____ / /_(_)___ ___ (_)___ ___ _____
|
||||||
|
/ |/ / _ \/ __/ | /| / / __ \/ ___/ //_/ / / / __ \/ __/ / __ `__ \/ /_ / / _ \/ ___/
|
||||||
|
/ /| / __/ /_ | |/ |/ / /_/ / / / ,< / /_/ / /_/ / /_/ / / / / / / / / /_/ __/ /
|
||||||
|
/_/ |_/\___/\__/ |__/|__/\____/_/ /_/|_|\____/ .___/\__/_/_/ /_/ /_/_/ /___/\___/_/
|
||||||
|
/_/
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
____ __ _ ___ __ _ _____
|
||||||
|
/ __ \/ /_ _____(_)___/ (_)___ _____ / / (_) _____ / ___/__ ______ _____
|
||||||
|
/ / / / __ \/ ___/ / __ / / __ `/ __ \______/ / / / | / / _ \\__ \/ / / / __ \/ ___/
|
||||||
|
/ /_/ / /_/ (__ ) / /_/ / / /_/ / / / /_____/ /___/ /| |/ / __/__/ / /_/ / / / / /__
|
||||||
|
\____/_.___/____/_/\__,_/_/\__,_/_/ /_/ /_____/_/ |___/\___/____/\__, /_/ /_/\___/
|
||||||
|
/____/
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
____ __
|
||||||
|
/ __ \_____/ /_
|
||||||
|
/ / / / ___/ __ \
|
||||||
|
/ /_/ / / / /_/ /
|
||||||
|
\____/_/ /_.___/
|
||||||
|
|
||||||
@@ -46,8 +46,11 @@ function update_script() {
|
|||||||
|
|
||||||
msg_info "Updating Heimdall-Dashboard"
|
msg_info "Updating Heimdall-Dashboard"
|
||||||
cd /opt/Heimdall
|
cd /opt/Heimdall
|
||||||
|
sed -i 's/^APP_ENV=.*/APP_ENV=production/' .env
|
||||||
|
rm -f bootstrap/cache/*.php
|
||||||
export COMPOSER_ALLOW_SUPERUSER=1
|
export COMPOSER_ALLOW_SUPERUSER=1
|
||||||
$STD composer dump-autoload
|
$STD composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
|
||||||
|
$STD php artisan optimize:clear
|
||||||
msg_ok "Updated Heimdall-Dashboard"
|
msg_ok "Updated Heimdall-Dashboard"
|
||||||
|
|
||||||
msg_info "Restoring Data"
|
msg_info "Restoring Data"
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
#!/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/asciimoo/hister
|
||||||
|
|
||||||
|
APP="Hister"
|
||||||
|
var_tags="${var_tags:-search;browser-history;personal}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-1024}"
|
||||||
|
var_disk="${var_disk:-20}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -f /usr/local/bin/hister ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "hister" "asciimoo/hister"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop hister
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "hister" "asciimoo/hister" "singlefile" "latest" "/usr/local/bin" "hister_*_linux_$(arch_resolve)"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start hister
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:4433${CL}"
|
||||||
+36
-9
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: MickLesk (CanbiZ)
|
# Author: MickLesk (CanbiZ) | Co-Author: Tom Frenzel (tomfrenzel)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/danielbrendel/hortusfox-web
|
# Source: https://github.com/danielbrendel/hortusfox-web
|
||||||
|
|
||||||
@@ -34,29 +34,56 @@ function update_script() {
|
|||||||
systemctl stop apache2
|
systemctl stop apache2
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
msg_info "Backing up current HortusFox installation"
|
cd /opt/hortusfox
|
||||||
cd /opt
|
if [[ ! -s app/migrations/migrations.list ]]; then
|
||||||
mv /opt/hortusfox/ /opt/hortusfox-backup
|
msg_info "Rebuilding HortusFox migration history"
|
||||||
msg_ok "Backed up current HortusFox installation"
|
local database_tables
|
||||||
|
database_tables="$(mariadb -u root -D hortusfox -NBe "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE();")"
|
||||||
|
: >app/migrations/migrations.list
|
||||||
|
local migration migration_file table_name
|
||||||
|
for migration in app/migrations/*.php; do
|
||||||
|
migration_file="${migration##*/}"
|
||||||
|
table_name="${migration_file%.php}"
|
||||||
|
if [[ "$migration_file" == "VersionModel.php" ]] || grep -Fxq "$table_name" <<<"$database_tables"; then
|
||||||
|
php -r 'echo hash("sha512", $argv[1]), PHP_EOL;' -- "$migration_file" >>app/migrations/migrations.list
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
msg_ok "Rebuilt HortusFox migration history"
|
||||||
|
fi
|
||||||
|
if [[ ! -f app/migrations/verhist.json && -f ~/.hortusfox ]]; then
|
||||||
|
printf '["%s"]\n' "$(<~/.hortusfox)" >app/migrations/verhist.json
|
||||||
|
fi
|
||||||
|
|
||||||
|
create_backup \
|
||||||
|
/opt/hortusfox/.env \
|
||||||
|
/opt/hortusfox/app/migrations/migrations.list \
|
||||||
|
/opt/hortusfox/app/migrations/verhist.json \
|
||||||
|
/opt/hortusfox/public/img \
|
||||||
|
/opt/hortusfox/public/attachments \
|
||||||
|
/opt/hortusfox/public/backup \
|
||||||
|
/opt/hortusfox/public/exports \
|
||||||
|
/opt/hortusfox/public/snd \
|
||||||
|
/opt/hortusfox/public/themes
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "hortusfox" "danielbrendel/hortusfox-web" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "hortusfox" "danielbrendel/hortusfox-web" "tarball"
|
||||||
|
restore_backup
|
||||||
|
|
||||||
msg_info "Updating HortusFox"
|
msg_info "Updating HortusFox"
|
||||||
cd /opt/hortusfox
|
cd /opt/hortusfox
|
||||||
cp /opt/hortusfox-backup/.env /opt/hortusfox/.env
|
|
||||||
cp -a /opt/hortusfox-backup/public/img/. /opt/hortusfox/public/img/
|
|
||||||
export COMPOSER_ALLOW_SUPERUSER=1
|
export COMPOSER_ALLOW_SUPERUSER=1
|
||||||
$STD composer install --no-dev --optimize-autoloader
|
$STD composer install --no-dev --optimize-autoloader
|
||||||
|
$STD php asatru migrate:list
|
||||||
$STD php asatru migrate:upgrade
|
$STD php asatru migrate:upgrade
|
||||||
$STD php asatru plants:attributes
|
|
||||||
$STD php asatru calendar:classes
|
$STD php asatru calendar:classes
|
||||||
|
$STD php asatru plants:attributes
|
||||||
|
$STD php asatru aquashell:config
|
||||||
chown -R www-data:www-data /opt/hortusfox
|
chown -R www-data:www-data /opt/hortusfox
|
||||||
rm -r /opt/hortusfox-backup
|
|
||||||
msg_ok "Updated HortusFox"
|
msg_ok "Updated HortusFox"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start apache2
|
systemctl start apache2
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
|
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
fi
|
fi
|
||||||
exit
|
exit
|
||||||
|
|||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
#!/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/Nystik-gh/ignis
|
||||||
|
|
||||||
|
APP="Ignis"
|
||||||
|
var_tags="${var_tags:-notes;obsidian}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-4096}"
|
||||||
|
var_disk="${var_disk:-10}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/ignis ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "ignis" "Nystik-gh/ignis"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop ignis
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "ignis" "Nystik-gh/ignis" "tarball"
|
||||||
|
|
||||||
|
msg_info "Building Ignis"
|
||||||
|
cd /opt/ignis
|
||||||
|
export NODE_OPTIONS="--max-old-space-size=4096"
|
||||||
|
export IGNIS_BUILD="$(cat ~/.ignis)"
|
||||||
|
$STD npm ci --ignore-scripts
|
||||||
|
$STD npm run build
|
||||||
|
$STD npm install -g @electron/asar
|
||||||
|
msg_ok "Built Ignis"
|
||||||
|
|
||||||
|
msg_info "Checking Obsidian Web Assets"
|
||||||
|
OBSIDIAN_VERSION=$(grep -oP 'OBSIDIAN_VERSION=\K[0-9.]+' /opt/ignis/apps/ignis-server/Dockerfile | head -n1)
|
||||||
|
[[ -z "$OBSIDIAN_VERSION" ]] && OBSIDIAN_VERSION="$(cat /opt/ignis_data/obsidian.version 2>/dev/null)"
|
||||||
|
if [[ -n "$OBSIDIAN_VERSION" && "$OBSIDIAN_VERSION" != "$(cat /opt/ignis_data/obsidian.version 2>/dev/null)" ]]; then
|
||||||
|
rm -rf /opt/ignis_data/obsidian-app
|
||||||
|
mkdir -p /opt/ignis_data/obsidian-app
|
||||||
|
curl -fsSL -o /tmp/obsidian.asar.gz "https://github.com/obsidianmd/obsidian-releases/releases/download/v${OBSIDIAN_VERSION}/obsidian-${OBSIDIAN_VERSION}.asar.gz"
|
||||||
|
gunzip -f /tmp/obsidian.asar.gz
|
||||||
|
$STD asar extract /tmp/obsidian.asar /opt/ignis_data/obsidian-app
|
||||||
|
rm -f /tmp/obsidian.asar
|
||||||
|
echo "${OBSIDIAN_VERSION}" >/opt/ignis_data/obsidian.version
|
||||||
|
fi
|
||||||
|
msg_ok "Checked Obsidian Web Assets"
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start ignis
|
||||||
|
systemctl reload nginx
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}https://${IP}${CL}"
|
||||||
+10
-1
@@ -214,7 +214,16 @@ EOF
|
|||||||
cd "$SRC_DIR"
|
cd "$SRC_DIR"
|
||||||
export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml
|
export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml
|
||||||
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg
|
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg
|
||||||
$STD mise install
|
mise_ok=0
|
||||||
|
for i in 1 2 3; do
|
||||||
|
$STD mise install && {
|
||||||
|
mise_ok=1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
msg_warn "mise install failed (attempt $i/3) - retrying"
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
[[ "$mise_ok" -eq 1 ]] || exit 1
|
||||||
export PATH="$(mise bin-paths 2>/dev/null | tr '\n' ':')$PATH"
|
export PATH="$(mise bin-paths 2>/dev/null | tr '\n' ':')$PATH"
|
||||||
if ! command -v extism-js >/dev/null 2>&1; then
|
if ! command -v extism-js >/dev/null 2>&1; then
|
||||||
# extism-js ships as a bare gzip-compressed single binary (.gz) that
|
# extism-js ships as a bare gzip-compressed single binary (.gz) that
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#!/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/Ozark-Connect/NetworkOptimizer
|
||||||
|
|
||||||
|
APP="NetworkOptimizer"
|
||||||
|
var_tags="${var_tags:-network;monitoring;unifi}"
|
||||||
|
var_cpu="${var_cpu:-2}"
|
||||||
|
var_ram="${var_ram:-4096}"
|
||||||
|
var_disk="${var_disk:-12}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -d /opt/networkoptimizer ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check_for_gh_release "networkoptimizer" "Ozark-Connect/NetworkOptimizer"; then
|
||||||
|
msg_info "Stopping Service"
|
||||||
|
systemctl stop networkoptimizer
|
||||||
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
create_backup /opt/networkoptimizer/networkoptimizer.env
|
||||||
|
|
||||||
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "networkoptimizer" "Ozark-Connect/NetworkOptimizer" "tarball"
|
||||||
|
|
||||||
|
msg_info "Rebuilding NetworkOptimizer"
|
||||||
|
RID="linux-x64"
|
||||||
|
[[ "$(dpkg --print-architecture)" == "arm64" ]] && RID="linux-arm64"
|
||||||
|
cd /opt/networkoptimizer
|
||||||
|
$STD dotnet publish src/NetworkOptimizer.Web -c Release -r "$RID" --self-contained -o /opt/networkoptimizer/publish
|
||||||
|
chmod +x /opt/networkoptimizer/publish/NetworkOptimizer.Web
|
||||||
|
mkdir -p /opt/networkoptimizer/publish/tools
|
||||||
|
cd /opt/networkoptimizer/src/uwnspeedtest
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $STD go build -trimpath -ldflags "-s -w" -o /opt/networkoptimizer/publish/tools/uwnspeedtest-linux-arm64 .
|
||||||
|
msg_ok "Rebuilt NetworkOptimizer"
|
||||||
|
|
||||||
|
restore_backup
|
||||||
|
|
||||||
|
msg_info "Starting Service"
|
||||||
|
systemctl start networkoptimizer
|
||||||
|
msg_ok "Started Service"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
fi
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:8042${CL}"
|
||||||
+1
-1
@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
|
|||||||
var_ram="${var_ram:-2048}"
|
var_ram="${var_ram:-2048}"
|
||||||
var_disk="${var_disk:-8}"
|
var_disk="${var_disk:-8}"
|
||||||
var_os="${var_os:-debian}"
|
var_os="${var_os:-debian}"
|
||||||
var_version="${var_version:-12}"
|
var_version="${var_version:-13}"
|
||||||
var_arm64="${var_arm64:-yes}"
|
var_arm64="${var_arm64:-yes}"
|
||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#!/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/vrtmrz/obsidian-livesync | https://couchdb.apache.org/
|
||||||
|
|
||||||
|
APP="Obsidian-LiveSync"
|
||||||
|
var_tags="${var_tags:-documents;notes}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-1024}"
|
||||||
|
var_disk="${var_disk:-8}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if [[ ! -f /opt/couchdb/etc/local.d/obsidian-livesync.ini ]]; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Stopping CouchDB"
|
||||||
|
systemctl stop couchdb
|
||||||
|
msg_ok "Stopped CouchDB"
|
||||||
|
|
||||||
|
create_backup /var/lib/couchdb /opt/couchdb/etc/local.d/obsidian-livesync.ini /opt/obsidian-livesync/.env
|
||||||
|
|
||||||
|
msg_info "Updating Container OS"
|
||||||
|
$STD apt update
|
||||||
|
$STD apt upgrade -y
|
||||||
|
msg_ok "Updated Container OS"
|
||||||
|
|
||||||
|
systemctl stop couchdb
|
||||||
|
restore_backup
|
||||||
|
|
||||||
|
msg_info "Starting CouchDB"
|
||||||
|
systemctl start couchdb
|
||||||
|
msg_ok "Started CouchDB"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${INFO}${YW}Configure the Self-hosted LiveSync plugin with the credentials in /opt/obsidian-livesync/.env${CL}"
|
||||||
|
echo -e "${GATEWAY}${BGN}http://${IP}:5984/_utils/${CL}"
|
||||||
@@ -43,6 +43,8 @@ function update_script() {
|
|||||||
fi
|
fi
|
||||||
msg_ok "New version available: ${LATEST}"
|
msg_ok "New version available: ${LATEST}"
|
||||||
|
|
||||||
|
NODE_VERSION="26" setup_nodejs
|
||||||
|
|
||||||
msg_info "Stopping Service"
|
msg_info "Stopping Service"
|
||||||
systemctl stop omniroute
|
systemctl stop omniroute
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RELEASE="v7.3.0"
|
RELEASE="v7.4.0"
|
||||||
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
|
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
|
||||||
msg_info "Stopping services"
|
msg_info "Stopping services"
|
||||||
systemctl stop opencloud opencloud-wopi
|
systemctl stop opencloud opencloud-wopi
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#!/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: angusmaul
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://orb.net/
|
||||||
|
|
||||||
|
APP="Orb"
|
||||||
|
var_tags="${var_tags:-network;monitoring}"
|
||||||
|
var_cpu="${var_cpu:-1}"
|
||||||
|
var_ram="${var_ram:-512}"
|
||||||
|
var_disk="${var_disk:-4}"
|
||||||
|
var_os="${var_os:-debian}"
|
||||||
|
var_version="${var_version:-13}"
|
||||||
|
var_arm64="${var_arm64:-yes}"
|
||||||
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
|
|
||||||
|
header_info "$APP"
|
||||||
|
variables
|
||||||
|
color
|
||||||
|
catch_errors
|
||||||
|
|
||||||
|
function update_script() {
|
||||||
|
header_info
|
||||||
|
check_container_storage
|
||||||
|
check_container_resources
|
||||||
|
|
||||||
|
if ! dpkg -s orb >/dev/null 2>&1; then
|
||||||
|
msg_error "No ${APP} Installation Found!"
|
||||||
|
exit 233
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_info "Updating Orb"
|
||||||
|
$STD apt update
|
||||||
|
$STD apt install -y --only-upgrade orb
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
build_container
|
||||||
|
description
|
||||||
|
|
||||||
|
msg_ok "Completed Successfully!\n"
|
||||||
|
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}To link the sensor to your orb account run:${CL}"
|
||||||
|
echo -e "${TAB}${GATEWAY}${BGN}pct exec ${CTID} -- runuser -u orb -- orb link${CL}"
|
||||||
@@ -17,6 +17,9 @@ var_arm64="${var_arm64:-yes}"
|
|||||||
var_unprivileged="${var_unprivileged:-1}"
|
var_unprivileged="${var_unprivileged:-1}"
|
||||||
var_tun="${var_tun:-1}"
|
var_tun="${var_tun:-1}"
|
||||||
|
|
||||||
|
export var_pangolin_url="${var_pangolin_url:-}"
|
||||||
|
export var_pangolin_email="${var_pangolin_email:-}"
|
||||||
|
|
||||||
header_info "$APP"
|
header_info "$APP"
|
||||||
variables
|
variables
|
||||||
color
|
color
|
||||||
|
|||||||
+2
-2
@@ -42,7 +42,7 @@ function update_script() {
|
|||||||
echo -e ""
|
echo -e ""
|
||||||
msg_custom "🔄" "Migration required to new data structure (/opt/paperless_data/)"
|
msg_custom "🔄" "Migration required to new data structure (/opt/paperless_data/)"
|
||||||
msg_custom "📖" "Please follow the migration guide:"
|
msg_custom "📖" "Please follow the migration guide:"
|
||||||
echo -e "${GATEWAY}${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/9223${CL}"
|
echo -e "${GATEWAY}${BGN}https://github.com/community-scripts/ProxmoxVE/pull/9223${CL}"
|
||||||
echo -e ""
|
echo -e ""
|
||||||
msg_custom "⚠️" "Update aborted. Please migrate your data first."
|
msg_custom "⚠️" "Update aborted. Please migrate your data first."
|
||||||
exit 253
|
exit 253
|
||||||
@@ -65,7 +65,7 @@ function update_script() {
|
|||||||
read -rp "Do you want to continue with the update? (y/N): " MIGRATE
|
read -rp "Do you want to continue with the update? (y/N): " MIGRATE
|
||||||
echo
|
echo
|
||||||
if [[ ! "$MIGRATE" =~ ^[Yy]$ ]]; then
|
if [[ ! "$MIGRATE" =~ ^[Yy]$ ]]; then
|
||||||
msg_info "Update aborted. Decrypt all documents before upgrading to v3."
|
msg_custom "⚠️" "Update aborted. Decrypt all documents before upgrading to v3."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ function update_script() {
|
|||||||
create_backup /opt/passwordpusher/storage /opt/passwordpusher/.env.production
|
create_backup /opt/passwordpusher/storage /opt/passwordpusher/.env.production
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "passwordpusher" "pglombardo/PasswordPusher" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "passwordpusher" "pglombardo/PasswordPusher" "tarball"
|
||||||
|
RUBY_VERSION="$(cat /opt/passwordpusher/.ruby-version)" RUBY_INSTALL_RAILS="false" setup_ruby
|
||||||
|
|
||||||
msg_info "Installing Gem Dependencies"
|
msg_info "Installing Gem Dependencies"
|
||||||
cd /opt/passwordpusher
|
cd /opt/passwordpusher
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ function update_script() {
|
|||||||
sed -i "s/^\(Pin: version \).*/\1${RELEASE}/" /etc/apt/preferences.d/salt-pin-1001
|
sed -i "s/^\(Pin: version \).*/\1${RELEASE}/" /etc/apt/preferences.d/salt-pin-1001
|
||||||
$STD apt update
|
$STD apt update
|
||||||
$STD apt upgrade -y
|
$STD apt upgrade -y
|
||||||
echo "${RELEASE}" >/~.salt
|
echo "${RELEASE}" >~/.salt
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
fi
|
fi
|
||||||
exit
|
exit
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ function update_script() {
|
|||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
ensure_dependencies git
|
||||||
if check_for_gh_release "sparkyfitness" "CodeWithCJ/SparkyFitness"; then
|
if check_for_gh_release "sparkyfitness" "CodeWithCJ/SparkyFitness"; then
|
||||||
msg_info "Stopping Services"
|
msg_info "Stopping Services"
|
||||||
systemctl stop sparkyfitness-server nginx
|
systemctl stop sparkyfitness-server nginx
|
||||||
|
|||||||
+3
-5
@@ -35,18 +35,16 @@ function update_script() {
|
|||||||
systemctl stop split-pro
|
systemctl stop split-pro
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
msg_info "Backing up Data"
|
create_backup /opt/split-pro/.env
|
||||||
cp /opt/split-pro/.env /opt/split-pro.env
|
|
||||||
msg_ok "Backed up Data"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "split-pro" "oss-apps/split-pro" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "split-pro" "oss-apps/split-pro" "tarball"
|
||||||
|
|
||||||
|
restore_backup
|
||||||
|
|
||||||
msg_info "Building Application"
|
msg_info "Building Application"
|
||||||
cd /opt/split-pro
|
cd /opt/split-pro
|
||||||
$STD pnpm install --frozen-lockfile
|
$STD pnpm install --frozen-lockfile
|
||||||
$STD pnpm build
|
$STD pnpm build
|
||||||
cp /opt/split-pro.env /opt/split-pro/.env
|
|
||||||
rm -f /opt/split-pro.env
|
|
||||||
ln -sf /opt/split-pro_data/uploads /opt/split-pro/uploads
|
ln -sf /opt/split-pro_data/uploads /opt/split-pro/uploads
|
||||||
$STD pnpm exec prisma migrate deploy
|
$STD pnpm exec prisma migrate deploy
|
||||||
msg_ok "Built Application"
|
msg_ok "Built Application"
|
||||||
|
|||||||
+38
-10
@@ -112,14 +112,33 @@ EOF
|
|||||||
msg_ok "Stopped Termix"
|
msg_ok "Stopped Termix"
|
||||||
|
|
||||||
msg_info "Migrating Configuration"
|
msg_info "Migrating Configuration"
|
||||||
if [[ ! -f /opt/termix/.env ]]; then
|
mkdir -p /opt/termix/db/data
|
||||||
cat <<EOF >/opt/termix/.env
|
|
||||||
|
if [[ -f /opt/termix/data/db.sqlite.encrypted && ! -f /opt/termix/db/data/db.sqlite.encrypted ]]; then
|
||||||
|
cp -a /opt/termix/data/db.sqlite.encrypted /opt/termix/db/data/db.sqlite.encrypted
|
||||||
|
[[ -f /opt/termix/data/db.sqlite.encrypted.meta ]] &&
|
||||||
|
cp -a /opt/termix/data/db.sqlite.encrypted.meta /opt/termix/db/data/db.sqlite.encrypted.meta
|
||||||
|
[[ -f /opt/termix/data/db.sqlite ]] &&
|
||||||
|
cp -a /opt/termix/data/db.sqlite /opt/termix/db/data/db.sqlite
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f /opt/termix/data/.env && ! -f /opt/termix/db/data/.env ]]; then
|
||||||
|
cp -a /opt/termix/data/.env /opt/termix/db/data/.env
|
||||||
|
fi
|
||||||
|
|
||||||
|
for sub in ssl session_logs session_recordings acme-webroot certbot uploads; do
|
||||||
|
if [[ -d /opt/termix/data/$sub && ! -d /opt/termix/db/data/$sub ]]; then
|
||||||
|
cp -a "/opt/termix/data/$sub" "/opt/termix/db/data/$sub"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
cat <<EOF >/opt/termix/.env
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
DATA_DIR=/opt/termix/data
|
DATA_DIR=/opt/termix/db/data
|
||||||
GUACD_HOST=127.0.0.1
|
GUACD_HOST=127.0.0.1
|
||||||
GUACD_PORT=4822
|
GUACD_PORT=4822
|
||||||
EOF
|
EOF
|
||||||
fi
|
|
||||||
if ! grep -q "EnvironmentFile" /etc/systemd/system/termix.service 2>/dev/null; then
|
if ! grep -q "EnvironmentFile" /etc/systemd/system/termix.service 2>/dev/null; then
|
||||||
cat <<EOF >/etc/systemd/system/termix.service
|
cat <<EOF >/etc/systemd/system/termix.service
|
||||||
[Unit]
|
[Unit]
|
||||||
@@ -143,7 +162,11 @@ EOF
|
|||||||
fi
|
fi
|
||||||
msg_ok "Migrated Configuration"
|
msg_ok "Migrated Configuration"
|
||||||
|
|
||||||
create_backup /opt/termix/data /opt/termix/uploads
|
create_backup \
|
||||||
|
/opt/termix/db/data \
|
||||||
|
/opt/termix/data \
|
||||||
|
/opt/termix/uploads \
|
||||||
|
/opt/termix/.env
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "termix" "Termix-SSH/Termix" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "termix" "Termix-SSH/Termix" "tarball"
|
||||||
|
|
||||||
@@ -158,10 +181,10 @@ EOF
|
|||||||
/opt/termix/db/data
|
/opt/termix/db/data
|
||||||
msg_ok "Recreated Directories"
|
msg_ok "Recreated Directories"
|
||||||
|
|
||||||
if [[ -f /opt/termix/data/db.sqlite.encrypted && ! -f /opt/termix/db/data/db.sqlite.encrypted ]]; then
|
if [[ -f /opt/termix/db/data/db.sqlite.encrypted && ! -f /opt/termix/db/data/.env ]]; then
|
||||||
msg_info "Migrating Database to new layout"
|
msg_error "Encrypted database restored without its keys (/opt/termix/db/data/.env is missing)"
|
||||||
cp -a /opt/termix/data/db.sqlite.encrypted /opt/termix/db/data/db.sqlite.encrypted
|
msg_custom "🛟" "Restore the container from a backup and report this at https://github.com/community-scripts/ProxmoxVE/issues"
|
||||||
msg_ok "Migrated Database to new layout"
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Building Frontend"
|
msg_info "Building Frontend"
|
||||||
@@ -237,7 +260,12 @@ EOF
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Starting Termix"
|
msg_info "Starting Termix"
|
||||||
systemctl start termix
|
systemctl daemon-reload
|
||||||
|
if ! systemctl start termix; then
|
||||||
|
msg_error "Termix failed to start"
|
||||||
|
journalctl -u termix -n 30 --no-pager || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
msg_ok "Started Termix"
|
msg_ok "Started Termix"
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
fi
|
fi
|
||||||
|
|||||||
+2
-3
@@ -46,8 +46,7 @@ function update_script() {
|
|||||||
[[ "$CONFIRM2" =~ ^[yY]$ ]] || exit 0
|
[[ "$CONFIRM2" =~ ^[yY]$ ]] || exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
RELEASE="v2.3.0"
|
if check_for_gh_release "vikunja" "go-vikunja/vikunja"; then
|
||||||
if check_for_gh_release "vikunja" "go-vikunja/vikunja" "${RELEASE}" "v2.4.0 is killed at startup by the systemd SystemCallFilter shipped in the .deb (upstream go-vikunja/vikunja#3252); pinned until a fixed release is out"; then
|
|
||||||
echo
|
echo
|
||||||
msg_warn "The package update may include config file changes."
|
msg_warn "The package update may include config file changes."
|
||||||
echo -e "${TAB}${YW}How do you want to handle /etc/vikunja/config.yml?${CL}"
|
echo -e "${TAB}${YW}How do you want to handle /etc/vikunja/config.yml?${CL}"
|
||||||
@@ -66,7 +65,7 @@ function update_script() {
|
|||||||
systemctl stop vikunja
|
systemctl stop vikunja
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "${RELEASE}" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
|
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "latest" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
|
||||||
$STD systemctl daemon-reload
|
$STD systemctl daemon-reload
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ function update_script() {
|
|||||||
systemctl stop watcharr
|
systemctl stop watcharr
|
||||||
msg_ok "Stopped Service"
|
msg_ok "Stopped Service"
|
||||||
|
|
||||||
|
NODE_VERSION="24" setup_nodejs
|
||||||
|
|
||||||
create_backup /opt/watcharr/server/data
|
create_backup /opt/watcharr/server/data
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "watcharr" "sbondCo/Watcharr" "tarball"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "watcharr" "sbondCo/Watcharr" "tarball"
|
||||||
restore_backup
|
restore_backup
|
||||||
|
|||||||
@@ -48,6 +48,13 @@ function update_script() {
|
|||||||
chmod 644 /opt/xyops/node_modules/useragent-ng/lib/regexps.js
|
chmod 644 /opt/xyops/node_modules/useragent-ng/lib/regexps.js
|
||||||
msg_ok "Rebuilt Application"
|
msg_ok "Rebuilt Application"
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "xysat" "pixlcore/xysat" "tarball" "latest" "/opt/xyops/satellite"
|
||||||
|
|
||||||
|
msg_info "Building xySat Satellite"
|
||||||
|
cd /opt/xyops/satellite
|
||||||
|
$STD npm install
|
||||||
|
msg_ok "Built xySat Satellite"
|
||||||
|
|
||||||
msg_info "Starting Service"
|
msg_info "Starting Service"
|
||||||
systemctl start xyops
|
systemctl start xyops
|
||||||
msg_ok "Started Service"
|
msg_ok "Started Service"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ $STD apt install -y \
|
|||||||
g++
|
g++
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
NODE_VERSION="22" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
create_self_signed_cert
|
create_self_signed_cert
|
||||||
|
|
||||||
msg_info "Installing Actual Budget"
|
msg_info "Installing Actual Budget"
|
||||||
@@ -51,6 +51,7 @@ cat <<EOF >/opt/actualbudget-data/config.json
|
|||||||
EOF
|
EOF
|
||||||
mkdir -p /opt/actualbudget
|
mkdir -p /opt/actualbudget
|
||||||
cd /opt/actualbudget
|
cd /opt/actualbudget
|
||||||
|
$STD npm config set allow-scripts=bcrypt,better-sqlite3,argon2 --location=global
|
||||||
$STD npm install --location=global @actual-app/sync-server
|
$STD npm install --location=global @actual-app/sync-server
|
||||||
echo "${RELEASE}" >~/.actualbudget
|
echo "${RELEASE}" >~/.actualbudget
|
||||||
msg_ok "Installed Actual Budget"
|
msg_ok "Installed Actual Budget"
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ $STD yarn config set enableTelemetry 0
|
|||||||
export NODE_OPTIONS="--max-old-space-size=4096"
|
export NODE_OPTIONS="--max-old-space-size=4096"
|
||||||
export TSC_COMPILE_ON_ERROR=true
|
export TSC_COMPILE_ON_ERROR=true
|
||||||
$STD yarn install
|
$STD yarn install
|
||||||
|
$STD bash ./scripts/set-version.sh "$(cat ~/.affine_app)"
|
||||||
|
export BUILD_TYPE=stable
|
||||||
$STD npm install -g typescript
|
$STD npm install -g typescript
|
||||||
$STD yarn affine @affine/native build
|
$STD yarn affine @affine/native build
|
||||||
$STD yarn affine @affine/server-native build
|
$STD yarn affine @affine/server-native build
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
msg_info "Installing Apache CouchDB"
|
msg_info "Installing Apache CouchDB"
|
||||||
ERLANG_COOKIE=$(openssl rand -base64 32)
|
ERLANG_COOKIE=$(openssl rand -hex 32)
|
||||||
ADMIN_PASS="$(openssl rand -base64 18 | cut -c1-13)"
|
ADMIN_PASS="$(openssl rand -base64 18 | cut -c1-13)"
|
||||||
debconf-set-selections <<<"couchdb couchdb/cookie string $ERLANG_COOKIE"
|
debconf-set-selections <<<"couchdb couchdb/cookie string $ERLANG_COOKIE"
|
||||||
debconf-set-selections <<<"couchdb couchdb/mode select standalone"
|
debconf-set-selections <<<"couchdb couchdb/mode select standalone"
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ fetch_and_deploy_gh_release "Byparr" "ThePhaseless/Byparr" "tarball" "latest"
|
|||||||
msg_info "Configuring Byparr"
|
msg_info "Configuring Byparr"
|
||||||
cd /opt/Byparr
|
cd /opt/Byparr
|
||||||
$STD uv sync --link-mode copy
|
$STD uv sync --link-mode copy
|
||||||
$STD uv run camoufox fetch
|
$STD uv run python -m invisible_playwright fetch
|
||||||
msg_ok "Configured Byparr"
|
msg_ok "Configured Byparr"
|
||||||
|
|
||||||
msg_info "Creating Service"
|
msg_info "Creating Service"
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ $STD apt-get install -y \
|
|||||||
fonts-kacst fonts-liberation \
|
fonts-kacst fonts-liberation \
|
||||||
fonts-noto-cjk \
|
fonts-noto-cjk \
|
||||||
fonts-noto-color-emoji \
|
fonts-noto-color-emoji \
|
||||||
msttcorefonts \
|
|
||||||
fonts-roboto \
|
fonts-roboto \
|
||||||
fonts-thai-tlwg \
|
fonts-thai-tlwg \
|
||||||
fonts-wqy-zenhei
|
fonts-wqy-zenhei
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://about.gitlab.com/
|
||||||
|
|
||||||
|
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 \
|
||||||
|
openssh-server \
|
||||||
|
perl \
|
||||||
|
tzdata
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
setup_deb822_repo \
|
||||||
|
"gitlab-ce" \
|
||||||
|
"https://packages.gitlab.com/gitlab/gitlab-ce/gpgkey" \
|
||||||
|
"https://packages.gitlab.com/gitlab/gitlab-ce/debian" \
|
||||||
|
"$(get_os_info codename)" \
|
||||||
|
"main"
|
||||||
|
|
||||||
|
msg_info "Configuring GitLab"
|
||||||
|
mkdir -p /etc/gitlab
|
||||||
|
cat <<EOF >/etc/gitlab/gitlab.rb
|
||||||
|
external_url 'http://${LOCAL_IP}'
|
||||||
|
|
||||||
|
# Omnibus runs 'sysctl -e --system' during reconfigure, which fails in an
|
||||||
|
# unprivileged LXC because most kernel keys are not writable.
|
||||||
|
package['modify_kernel_parameters'] = false
|
||||||
|
EOF
|
||||||
|
msg_ok "Configured GitLab"
|
||||||
|
|
||||||
|
msg_info "Installing GitLab CE (Patience)"
|
||||||
|
$STD apt install -y gitlab-ce
|
||||||
|
msg_ok "Installed GitLab CE"
|
||||||
|
|
||||||
|
msg_info "Reconfiguring GitLab (Patience)"
|
||||||
|
$STD gitlab-ctl reconfigure
|
||||||
|
msg_ok "Reconfigured GitLab"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -24,6 +24,7 @@ fetch_and_deploy_gh_release "Heimdall" "linuxserver/Heimdall" "tarball"
|
|||||||
msg_info "Setting up Heimdall-Dashboard"
|
msg_info "Setting up Heimdall-Dashboard"
|
||||||
cd /opt/Heimdall
|
cd /opt/Heimdall
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
|
sed -i 's/^APP_ENV=.*/APP_ENV=production/' .env
|
||||||
$STD php artisan key:generate
|
$STD php artisan key:generate
|
||||||
msg_ok "Setup Heimdall-Dashboard"
|
msg_ok "Setup Heimdall-Dashboard"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: MickLesk (CanbiZ)
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://github.com/asciimoo/hister
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "hister" "asciimoo/hister" "singlefile" "latest" "/usr/local/bin" "hister_*_linux_$(arch_resolve)"
|
||||||
|
|
||||||
|
msg_info "Configuring Hister"
|
||||||
|
mkdir -p /opt/hister/data /etc/hister
|
||||||
|
LOCAL_IP=$(hostname -I | awk '{print $1}')
|
||||||
|
cat <<EOF >/etc/hister/config.yaml
|
||||||
|
app:
|
||||||
|
directory: '/opt/hister/data'
|
||||||
|
server:
|
||||||
|
address: '0.0.0.0:4433'
|
||||||
|
base_url: 'http://${LOCAL_IP}:4433'
|
||||||
|
EOF
|
||||||
|
msg_ok "Configured Hister"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/hister.service
|
||||||
|
[Unit]
|
||||||
|
Description=Hister Search Engine
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
ExecStart=/usr/local/bin/hister listen --config /etc/hister/config.yaml
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now hister
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 community-scripts ORG
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
# Author: MickLesk (CanbiZ)
|
# Author: MickLesk (CanbiZ) | Co-Author: Tom Frenzel (tomfrenzel)
|
||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/danielbrendel/hortusfox-web
|
# Source: https://github.com/danielbrendel/hortusfox-web
|
||||||
|
|
||||||
@@ -36,12 +36,15 @@ msg_ok "Composer dependencies installed"
|
|||||||
|
|
||||||
msg_info "Running DB migration"
|
msg_info "Running DB migration"
|
||||||
$STD php asatru migrate:fresh
|
$STD php asatru migrate:fresh
|
||||||
|
HORTUSFOX_VERSION="$(<~/.hortusfox)"
|
||||||
|
printf '["%s"]\n' "$HORTUSFOX_VERSION" >/opt/hortusfox/app/migrations/verhist.json
|
||||||
msg_ok "Migration finished"
|
msg_ok "Migration finished"
|
||||||
|
|
||||||
msg_info "Setting up HortusFox"
|
msg_info "Setting up HortusFox"
|
||||||
$STD mariadb -u root -D $MARIADB_DB_NAME -e "INSERT IGNORE INTO AppModel (workspace, language, created_at) VALUES ('Default Workspace', 'en', NOW());"
|
$STD mariadb -u root -D $MARIADB_DB_NAME -e "INSERT IGNORE INTO AppModel (workspace, language, created_at) VALUES ('Default Workspace', 'en', NOW());"
|
||||||
$STD php asatru plants:attributes
|
|
||||||
$STD php asatru calendar:classes
|
$STD php asatru calendar:classes
|
||||||
|
$STD php asatru plants:attributes
|
||||||
|
$STD php asatru aquashell:config
|
||||||
ADMIN_EMAIL="admin@example.com"
|
ADMIN_EMAIL="admin@example.com"
|
||||||
ADMIN_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)"
|
ADMIN_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)"
|
||||||
ADMIN_HASH=$(php -r "echo password_hash('$ADMIN_PASS', PASSWORD_BCRYPT);")
|
ADMIN_HASH=$(php -r "echo password_hash('$ADMIN_PASS', PASSWORD_BCRYPT);")
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
#!/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/Nystik-gh/ignis
|
||||||
|
|
||||||
|
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
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
NODE_VERSION="22" setup_nodejs
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "ignis" "Nystik-gh/ignis" "tarball"
|
||||||
|
|
||||||
|
msg_info "Building Ignis"
|
||||||
|
cd /opt/ignis
|
||||||
|
export NODE_OPTIONS="--max-old-space-size=4096"
|
||||||
|
export IGNIS_BUILD="$(cat ~/.ignis)"
|
||||||
|
$STD npm ci --ignore-scripts
|
||||||
|
$STD npm run build
|
||||||
|
$STD npm install -g @electron/asar
|
||||||
|
msg_ok "Built Ignis"
|
||||||
|
|
||||||
|
msg_info "Downloading Obsidian Web Assets"
|
||||||
|
mkdir -p /opt/ignis_data/{obsidian-app,vaults,data}
|
||||||
|
OBSIDIAN_VERSION=$(grep -oP 'OBSIDIAN_VERSION=\K[0-9.]+' /opt/ignis/apps/ignis-server/Dockerfile | head -n1)
|
||||||
|
[[ -z "$OBSIDIAN_VERSION" ]] && OBSIDIAN_VERSION="1.12.7"
|
||||||
|
curl -fsSL -o /tmp/obsidian.asar.gz "https://github.com/obsidianmd/obsidian-releases/releases/download/v${OBSIDIAN_VERSION}/obsidian-${OBSIDIAN_VERSION}.asar.gz"
|
||||||
|
gunzip -f /tmp/obsidian.asar.gz
|
||||||
|
$STD asar extract /tmp/obsidian.asar /opt/ignis_data/obsidian-app
|
||||||
|
rm -f /tmp/obsidian.asar
|
||||||
|
echo "${OBSIDIAN_VERSION}" >/opt/ignis_data/obsidian.version
|
||||||
|
msg_ok "Downloaded Obsidian Web Assets"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/ignis.service
|
||||||
|
[Unit]
|
||||||
|
Description=Ignis (Obsidian in the browser)
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/ignis
|
||||||
|
Environment=NODE_ENV=production
|
||||||
|
Environment=PORT=8080
|
||||||
|
Environment=VAULT_ROOT=/opt/ignis_data/vaults
|
||||||
|
Environment=DATA_ROOT=/opt/ignis_data/data
|
||||||
|
Environment=OBSIDIAN_ASSETS_PATH=/opt/ignis_data/obsidian-app
|
||||||
|
Environment=AUTO_CREATE_DEFAULT=true
|
||||||
|
ExecStart=/usr/bin/node /opt/ignis/apps/ignis-server/server/index.js
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now ignis
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
msg_info "Generating Self-Signed Certificate"
|
||||||
|
create_self_signed_cert "ignis"
|
||||||
|
msg_ok "Generated Self-Signed Certificate"
|
||||||
|
|
||||||
|
msg_info "Configuring Nginx"
|
||||||
|
cat <<'EOF' >/etc/nginx/sites-available/ignis.conf
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
server_name _;
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 443 ssl default_server;
|
||||||
|
http2 on;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
ssl_certificate /etc/ssl/ignis/ignis.crt;
|
||||||
|
ssl_certificate_key /etc/ssl/ignis/ignis.key;
|
||||||
|
|
||||||
|
client_max_body_size 1024m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:8080;
|
||||||
|
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_read_timeout 3600s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
ln -sf /etc/nginx/sites-available/ignis.conf /etc/nginx/sites-enabled/ignis.conf
|
||||||
|
rm -f /etc/nginx/sites-enabled/default
|
||||||
|
systemctl restart nginx
|
||||||
|
msg_ok "Configured Nginx"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -355,7 +355,16 @@ cp LICENSE "$APP_DIR"
|
|||||||
cd "$SRC_DIR"
|
cd "$SRC_DIR"
|
||||||
export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml
|
export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml
|
||||||
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg
|
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg
|
||||||
$STD mise install
|
mise_ok=0
|
||||||
|
for i in 1 2 3; do
|
||||||
|
$STD mise install && {
|
||||||
|
mise_ok=1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
msg_warn "mise install failed (attempt $i/3) - retrying"
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
[[ "$mise_ok" -eq 1 ]] || exit 1
|
||||||
export PATH="$(mise bin-paths 2>/dev/null | tr '\n' ':')$PATH"
|
export PATH="$(mise bin-paths 2>/dev/null | tr '\n' ':')$PATH"
|
||||||
if ! command -v extism-js >/dev/null 2>&1; then
|
if ! command -v extism-js >/dev/null 2>&1; then
|
||||||
# extism-js is published as a bare gzip-compressed single binary (.gz), which
|
# extism-js is published as a bare gzip-compressed single binary (.gz), which
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#!/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/Ozark-Connect/NetworkOptimizer
|
||||||
|
|
||||||
|
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 \
|
||||||
|
git \
|
||||||
|
sshpass \
|
||||||
|
iperf3
|
||||||
|
setup_deb822_repo \
|
||||||
|
"microsoft" \
|
||||||
|
"https://packages.microsoft.com/keys/microsoft-2025.asc" \
|
||||||
|
"https://packages.microsoft.com/debian/13/prod/" \
|
||||||
|
"trixie"
|
||||||
|
$STD apt install -y dotnet-sdk-10.0
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
setup_go
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "networkoptimizer" "Ozark-Connect/NetworkOptimizer" "tarball"
|
||||||
|
|
||||||
|
msg_info "Building NetworkOptimizer"
|
||||||
|
RID="linux-x64"
|
||||||
|
[[ "$(dpkg --print-architecture)" == "arm64" ]] && RID="linux-arm64"
|
||||||
|
cd /opt/networkoptimizer
|
||||||
|
export MinVerVersionOverride="$(cat ~/.networkoptimizer)"
|
||||||
|
$STD dotnet publish src/NetworkOptimizer.Web -c Release -r "$RID" --self-contained -o /opt/networkoptimizer/publish
|
||||||
|
chmod +x /opt/networkoptimizer/publish/NetworkOptimizer.Web
|
||||||
|
msg_ok "Built NetworkOptimizer"
|
||||||
|
|
||||||
|
msg_info "Building Gateway Speed Test Binary"
|
||||||
|
mkdir -p /opt/networkoptimizer/publish/tools
|
||||||
|
cd /opt/networkoptimizer/src/uwnspeedtest
|
||||||
|
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $STD go build -trimpath -ldflags "-s -w" -o /opt/networkoptimizer/publish/tools/uwnspeedtest-linux-arm64 .
|
||||||
|
msg_ok "Built Gateway Speed Test Binary"
|
||||||
|
|
||||||
|
msg_info "Configuring NetworkOptimizer"
|
||||||
|
cat <<EOF >/opt/networkoptimizer/networkoptimizer.env
|
||||||
|
ASPNETCORE_URLS=http://*:8042
|
||||||
|
HOST_IP=${LOCAL_IP}
|
||||||
|
Iperf3Server__Enabled=true
|
||||||
|
EOF
|
||||||
|
msg_ok "Configured NetworkOptimizer"
|
||||||
|
|
||||||
|
msg_info "Creating Service"
|
||||||
|
cat <<EOF >/etc/systemd/system/networkoptimizer.service
|
||||||
|
[Unit]
|
||||||
|
Description=NetworkOptimizer
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/networkoptimizer/publish
|
||||||
|
EnvironmentFile=/opt/networkoptimizer/networkoptimizer.env
|
||||||
|
ExecStart=/opt/networkoptimizer/publish/NetworkOptimizer.Web
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
systemctl enable -q --now networkoptimizer
|
||||||
|
msg_ok "Created Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -24,6 +24,16 @@ if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
|||||||
exit 10
|
exit 10
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
msg_info "Making ssh.service reloads behave like restarts"
|
||||||
|
mkdir -p /etc/systemd/system/ssh.service.d
|
||||||
|
cat <<'EOF' >/etc/systemd/system/ssh.service.d/reload-as-restart.conf
|
||||||
|
[Service]
|
||||||
|
ExecReload=
|
||||||
|
ExecReload=/usr/bin/systemd-run --no-block --quiet /bin/systemctl restart ssh.service
|
||||||
|
EOF
|
||||||
|
systemctl daemon-reload
|
||||||
|
msg_ok "Made ssh.service reloads behave like restarts"
|
||||||
|
|
||||||
msg_info "Installing NextCloudPi (Patience)"
|
msg_info "Installing NextCloudPi (Patience)"
|
||||||
$STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh)
|
$STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh)
|
||||||
msg_ok "Installed NextCloudPi"
|
msg_ok "Installed NextCloudPi"
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#!/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/vrtmrz/obsidian-livesync | https://couchdb.apache.org/
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
setup_deb822_repo \
|
||||||
|
"couchdb" \
|
||||||
|
"https://couchdb.apache.org/repo/keys.asc" \
|
||||||
|
"https://apache.jfrog.io/artifactory/couchdb-deb/" \
|
||||||
|
"$(get_os_info codename)" \
|
||||||
|
"main"
|
||||||
|
|
||||||
|
msg_info "Installing CouchDB"
|
||||||
|
COUCHDB_ADMIN_USER="admin"
|
||||||
|
COUCHDB_PASSWORD="$(openssl rand -hex 24)"
|
||||||
|
COUCHDB_COOKIE="$(openssl rand -hex 16)"
|
||||||
|
|
||||||
|
cat <<EOF | debconf-set-selections
|
||||||
|
couchdb couchdb/mode select standalone
|
||||||
|
couchdb couchdb/mode seen true
|
||||||
|
couchdb couchdb/bindaddress string 0.0.0.0
|
||||||
|
couchdb couchdb/bindaddress seen true
|
||||||
|
couchdb couchdb/cookie string ${COUCHDB_COOKIE}
|
||||||
|
couchdb couchdb/cookie seen true
|
||||||
|
couchdb couchdb/adminpass password ${COUCHDB_PASSWORD}
|
||||||
|
couchdb couchdb/adminpass seen true
|
||||||
|
couchdb couchdb/adminpass_again password ${COUCHDB_PASSWORD}
|
||||||
|
couchdb couchdb/adminpass_again seen true
|
||||||
|
EOF
|
||||||
|
DEBIAN_FRONTEND=noninteractive $STD apt-get install -y couchdb
|
||||||
|
|
||||||
|
cat <<EOF >/root/.couchdb.credentials
|
||||||
|
COUCHDB_ADMIN_USER="${COUCHDB_ADMIN_USER}"
|
||||||
|
COUCHDB_ADMIN_PASSWORD="${COUCHDB_PASSWORD}"
|
||||||
|
COUCHDB_COOKIE="${COUCHDB_COOKIE}"
|
||||||
|
EOF
|
||||||
|
msg_ok "Installed CouchDB"
|
||||||
|
|
||||||
|
msg_info "Configuring CouchDB"
|
||||||
|
mkdir -p /opt/couchdb/etc/local.d /opt/obsidian-livesync
|
||||||
|
cat <<EOF >/opt/couchdb/etc/local.d/obsidian-livesync.ini
|
||||||
|
[couchdb]
|
||||||
|
single_node = true
|
||||||
|
max_document_size = 50000000
|
||||||
|
|
||||||
|
[admins]
|
||||||
|
admin = ${COUCHDB_PASSWORD}
|
||||||
|
|
||||||
|
[chttpd]
|
||||||
|
bind_address = 0.0.0.0
|
||||||
|
port = 5984
|
||||||
|
max_http_request_size = 4294967296
|
||||||
|
|
||||||
|
[chttpd_auth]
|
||||||
|
require_valid_user = true
|
||||||
|
|
||||||
|
[httpd]
|
||||||
|
enable_cors = true
|
||||||
|
WWW-Authenticate = Basic realm="couchdb"
|
||||||
|
|
||||||
|
[cors]
|
||||||
|
credentials = true
|
||||||
|
origins = app://obsidian.md,capacitor://localhost,http://localhost
|
||||||
|
headers = accept, authorization, content-type, origin, referer
|
||||||
|
methods = GET, PUT, POST, HEAD, DELETE
|
||||||
|
max_age = 3600
|
||||||
|
EOF
|
||||||
|
cat <<EOF >/opt/obsidian-livesync/.env
|
||||||
|
COUCHDB_URL=http://${LOCAL_IP}:5984
|
||||||
|
COUCHDB_USER=admin
|
||||||
|
COUCHDB_PASSWORD=${COUCHDB_PASSWORD}
|
||||||
|
COUCHDB_DATABASE=obsidiannotes
|
||||||
|
EOF
|
||||||
|
chmod 600 /opt/obsidian-livesync/.env
|
||||||
|
msg_ok "Configured CouchDB"
|
||||||
|
|
||||||
|
msg_info "Creating LiveSync Database"
|
||||||
|
systemctl enable -q couchdb
|
||||||
|
systemctl restart couchdb
|
||||||
|
for _ in {1..30}; do
|
||||||
|
curl -fsS -u "admin:${COUCHDB_PASSWORD}" -X PUT http://127.0.0.1:5984/obsidiannotes >/dev/null 2>&1 && break
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
msg_ok "Created LiveSync Database"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -13,7 +13,7 @@ setting_up_container
|
|||||||
network_check
|
network_check
|
||||||
update_os
|
update_os
|
||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="26" setup_nodejs
|
||||||
|
|
||||||
msg_info "Installing OmniRoute"
|
msg_info "Installing OmniRoute"
|
||||||
$STD npm install -g omniroute@latest
|
$STD npm install -g omniroute@latest
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ $STD sudo -u cool coolconfig set-admin-password --user=admin --password="$COOLPA
|
|||||||
echo "$COOLPASS" >~/.coolpass
|
echo "$COOLPASS" >~/.coolpass
|
||||||
msg_ok "Installed Collabora Online"
|
msg_ok "Installed Collabora Online"
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "v7.3.0" "/usr/bin" "opencloud-*-linux-$(arch_resolve)"
|
fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "v7.4.0" "/usr/bin" "opencloud-*-linux-$(arch_resolve)"
|
||||||
mv /usr/bin/OpenCloud /usr/bin/opencloud
|
mv /usr/bin/OpenCloud /usr/bin/opencloud
|
||||||
|
|
||||||
msg_info "Configuring OpenCloud"
|
msg_info "Configuring OpenCloud"
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Copyright (c) 2021-2026 community-scripts ORG
|
||||||
|
# Author: angusmaul
|
||||||
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
|
# Source: https://orb.net/
|
||||||
|
|
||||||
|
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||||
|
color
|
||||||
|
verb_ip6
|
||||||
|
catch_errors
|
||||||
|
setting_up_container
|
||||||
|
network_check
|
||||||
|
update_os
|
||||||
|
|
||||||
|
setup_deb822_repo \
|
||||||
|
"orb" \
|
||||||
|
"https://pkgs.orb.net/stable/debian/orbforge.noarmor.gpg" \
|
||||||
|
"https://pkgs.orb.net/stable/debian" \
|
||||||
|
"orb" \
|
||||||
|
"main"
|
||||||
|
|
||||||
|
msg_info "Installing Orb"
|
||||||
|
$STD apt install -y orb
|
||||||
|
msg_ok "Installed Orb"
|
||||||
|
|
||||||
|
msg_info "Enabling Service"
|
||||||
|
systemctl enable -q --now orb
|
||||||
|
msg_ok "Enabled Service"
|
||||||
|
|
||||||
|
motd_ssh
|
||||||
|
customize
|
||||||
|
cleanup_lxc
|
||||||
@@ -27,9 +27,18 @@ fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VER
|
|||||||
fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
|
fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
|
||||||
fetch_and_deploy_gh_release "traefik" "traefik/traefik" "prebuild" "latest" "/usr/bin" "traefik_v*_linux_$(arch_resolve).tar.gz"
|
fetch_and_deploy_gh_release "traefik" "traefik/traefik" "prebuild" "latest" "/usr/bin" "traefik_v*_linux_$(arch_resolve).tar.gz"
|
||||||
|
|
||||||
read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " pango_url
|
# Read the variable first and prompt only when it is unset, so the install can
|
||||||
|
# be supplied up front. Same convention as install/forgejo-runner-install.sh.
|
||||||
|
pango_url="${var_pangolin_url:-}"
|
||||||
|
if [[ -z "$pango_url" ]]; then
|
||||||
|
read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " pango_url
|
||||||
|
fi
|
||||||
[[ "$pango_url" != https://* && "$pango_url" != http://* ]] && pango_url="https://${pango_url}"
|
[[ "$pango_url" != https://* && "$pango_url" != http://* ]] && pango_url="https://${pango_url}"
|
||||||
read -rp "${TAB3}Enter your email address: " pango_email
|
|
||||||
|
pango_email="${var_pangolin_email:-}"
|
||||||
|
if [[ -z "$pango_email" ]]; then
|
||||||
|
read -rp "${TAB3}Enter your email address: " pango_email
|
||||||
|
fi
|
||||||
|
|
||||||
msg_info "Setup Pangolin"
|
msg_info "Setup Pangolin"
|
||||||
SECRET_KEY=$(openssl rand -base64 48 | tr -dc 'A-Za-z0-9' | head -c 32)
|
SECRET_KEY=$(openssl rand -base64 48 | tr -dc 'A-Za-z0-9' | head -c 32)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ create_self_signed_cert
|
|||||||
|
|
||||||
setup_deb822_repo \
|
setup_deb822_repo \
|
||||||
"passbolt" \
|
"passbolt" \
|
||||||
"https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x3D1A0346C8E1802F774AEF21DE8B853FC155581D" \
|
"https://download.passbolt.com/pub.key" \
|
||||||
"https://download.passbolt.com/ce/debian" \
|
"https://download.passbolt.com/ce/debian" \
|
||||||
"buster" \
|
"buster" \
|
||||||
"stable"
|
"stable"
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ $STD apt install -y \
|
|||||||
pkg-config
|
pkg-config
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
RUBY_VERSION="4.0.5" RUBY_INSTALL_RAILS="false" setup_ruby
|
|
||||||
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
|
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
|
||||||
export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "passwordpusher" "pglombardo/PasswordPusher" "tarball"
|
fetch_and_deploy_gh_release "passwordpusher" "pglombardo/PasswordPusher" "tarball"
|
||||||
|
|
||||||
|
RUBY_VERSION="$(cat /opt/passwordpusher/.ruby-version)" RUBY_INSTALL_RAILS="false" setup_ruby
|
||||||
|
export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"
|
||||||
|
|
||||||
msg_info "Installing Gem Dependencies"
|
msg_info "Installing Gem Dependencies"
|
||||||
cd /opt/passwordpusher
|
cd /opt/passwordpusher
|
||||||
$STD bundle config set --local without 'development test'
|
$STD bundle config set --local without 'development test'
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ Pin: version ${RELEASE}
|
|||||||
Pin-Priority: 1001
|
Pin-Priority: 1001
|
||||||
EOF
|
EOF
|
||||||
$STD apt install -y salt-master
|
$STD apt install -y salt-master
|
||||||
echo "${RELEASE}" >/~.salt
|
echo "${RELEASE}" >~/.salt
|
||||||
msg_ok "Installed Salt"
|
msg_ok "Installed Salt"
|
||||||
|
|
||||||
motd_ssh
|
motd_ssh
|
||||||
|
|||||||
@@ -103,6 +103,9 @@ cat <<EOF >/etc/clickhouse-server/config.d/cluster.xml
|
|||||||
<shard>01</shard>
|
<shard>01</shard>
|
||||||
<replica>01</replica>
|
<replica>01</replica>
|
||||||
</macros>
|
</macros>
|
||||||
|
<merge_tree>
|
||||||
|
<allow_dimensions_outside_sorting_key>1</allow_dimensions_outside_sorting_key>
|
||||||
|
</merge_tree>
|
||||||
</clickhouse>
|
</clickhouse>
|
||||||
EOF
|
EOF
|
||||||
systemctl enable -q --now clickhouse-server
|
systemctl enable -q --now clickhouse-server
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ network_check
|
|||||||
update_os
|
update_os
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
msg_info "Installing Dependencies"
|
||||||
$STD apt install -y nginx
|
$STD apt install -y git nginx
|
||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
PG_VERSION="18" setup_postgresql
|
PG_VERSION="18" setup_postgresql
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ EOF
|
|||||||
|
|
||||||
cat <<EOF >/opt/termix/.env
|
cat <<EOF >/opt/termix/.env
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
DATA_DIR=/opt/termix/data
|
DATA_DIR=/opt/termix/db/data
|
||||||
GUACD_HOST=127.0.0.1
|
GUACD_HOST=127.0.0.1
|
||||||
GUACD_PORT=4822
|
GUACD_PORT=4822
|
||||||
EOF
|
EOF
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ setting_up_container
|
|||||||
network_check
|
network_check
|
||||||
update_os
|
update_os
|
||||||
|
|
||||||
RELEASE="v2.3.0"
|
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "latest" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
|
||||||
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "${RELEASE}" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
|
|
||||||
|
|
||||||
msg_info "Setting up Vikunja"
|
msg_info "Setting up Vikunja"
|
||||||
sed -i 's|^# \(service:\)|\1|' /etc/vikunja/config.yml
|
sed -i 's|^# \(service:\)|\1|' /etc/vikunja/config.yml
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ $STD apt install -y gcc
|
|||||||
msg_ok "Installed Dependencies"
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
setup_go
|
setup_go
|
||||||
NODE_VERSION="22" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
fetch_and_deploy_gh_release "watcharr" "sbondCo/Watcharr" "tarball"
|
fetch_and_deploy_gh_release "watcharr" "sbondCo/Watcharr" "tarball"
|
||||||
|
|
||||||
msg_info "Setup Watcharr"
|
msg_info "Setup Watcharr"
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ for i in {1..15}; do
|
|||||||
fi
|
fi
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
$STD mariadb -u webtrees -p"${MARIADB_DB_PASS}" -h 127.0.0.1 webtrees -e "SHOW TABLES LIKE 'wt_user';" | grep -q wt_user
|
mariadb -u webtrees -p"${MARIADB_DB_PASS}" -h 127.0.0.1 webtrees -e "SHOW TABLES LIKE 'wt_user';" | grep -q wt_user
|
||||||
msg_ok "Initialized Webtrees database schema"
|
msg_ok "Initialized Webtrees database schema"
|
||||||
$STD sudo -u www-data php /opt/webtrees/index.php user Admin \
|
$STD sudo -u www-data php /opt/webtrees/index.php user Admin \
|
||||||
--create \
|
--create \
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ network_check() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $ipv4_connected == false ]]; then
|
if [[ $ipv4_connected == false ]]; then
|
||||||
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt
|
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt </dev/tty
|
||||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||||
else
|
else
|
||||||
|
|||||||
+18
-13
@@ -922,8 +922,10 @@ choose_and_set_storage_for_file() {
|
|||||||
_list_os_versions() {
|
_list_os_versions() {
|
||||||
local ostype="${1:-}"
|
local ostype="${1:-}"
|
||||||
[[ -n "$ostype" ]] || return 0
|
[[ -n "$ostype" ]] || return 0
|
||||||
|
local arch
|
||||||
|
arch="$(dpkg --print-architecture 2>/dev/null || echo amd64)"
|
||||||
pveam available -section system 2>/dev/null |
|
pveam available -section system 2>/dev/null |
|
||||||
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
|
grep -E "_${arch}\.(tar\.zst|tar\.xz|tar\.gz)([[:space:]]|$)" |
|
||||||
awk '{print $2}' |
|
awk '{print $2}' |
|
||||||
sed -nE "s/^${ostype}-([0-9]+(\.[0-9]+)?).*/\1/p" |
|
sed -nE "s/^${ostype}-([0-9]+(\.[0-9]+)?).*/\1/p" |
|
||||||
sort -u -V || true
|
sort -u -V || true
|
||||||
@@ -936,8 +938,10 @@ _list_os_versions() {
|
|||||||
_list_templates() {
|
_list_templates() {
|
||||||
local search="${1:-}" pattern="${2:-}"
|
local search="${1:-}" pattern="${2:-}"
|
||||||
[[ -n "$search" ]] || return 0
|
[[ -n "$search" ]] || return 0
|
||||||
|
local arch
|
||||||
|
arch="$(dpkg --print-architecture 2>/dev/null || echo amd64)"
|
||||||
pveam available -section system 2>/dev/null |
|
pveam available -section system 2>/dev/null |
|
||||||
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' |
|
grep -E "_${arch}\.(tar\.zst|tar\.xz|tar\.gz)([[:space:]]|$)" |
|
||||||
awk '{print $2}' |
|
awk '{print $2}' |
|
||||||
grep -E "^${search}.*${pattern}" |
|
grep -E "^${search}.*${pattern}" |
|
||||||
sort -t - -k 2 -V || true
|
sort -t - -k 2 -V || true
|
||||||
@@ -3917,7 +3921,7 @@ run_addon_updates() {
|
|||||||
name="${a##*/update_}"
|
name="${a##*/update_}"
|
||||||
printf 'Do you also want to update addon "%s"? (y/N) [60s]: ' "$name"
|
printf 'Do you also want to update addon "%s"? (y/N) [60s]: ' "$name"
|
||||||
ans=""
|
ans=""
|
||||||
if read -r -t 60 ans; then :; else echo; fi
|
if read -r -t 60 ans </dev/tty; then :; else echo; fi
|
||||||
case "${ans,,}" in
|
case "${ans,,}" in
|
||||||
y | yes)
|
y | yes)
|
||||||
bash "$a" || msg_warn "Addon update for $name failed (rc=$?)"
|
bash "$a" || msg_warn "Addon update for $name failed (rc=$?)"
|
||||||
@@ -5200,15 +5204,11 @@ EOF
|
|||||||
# TSTP = Ctrl+Z, TTIN = bg read from tty, TTOU = bg write to tty (tostop)
|
# TSTP = Ctrl+Z, TTIN = bg read from tty, TTOU = bg write to tty (tostop)
|
||||||
trap '' TSTP TTIN TTOU
|
trap '' TSTP TTIN TTOU
|
||||||
|
|
||||||
# lxc-attach takes the controlling terminal while the install runs and does
|
# lxc-attach left us in a background process group - claim the terminal back
|
||||||
# not hand it back, leaving us in a background process group. Reading from
|
# before we print anything. Note this does NOT hold: the log collection
|
||||||
# the terminal then returns EIO instead of blocking, because SIGTTIN is
|
# below uses pct pull/exec, which take it away again, so every interactive
|
||||||
# ignored above - so every recovery prompt fails before the user can answer.
|
# prompt has to reclaim it again right before its read.
|
||||||
# Redirecting to /dev/tty does not help: the rule applies to the terminal,
|
reclaim_tty
|
||||||
# not the file descriptor. Claim the foreground group back; SIGTTOU is
|
|
||||||
# ignored too, so tcsetpgrp() succeeds instead of stopping us. No-op when we
|
|
||||||
# already are in the foreground. perl is a hard dependency of Proxmox VE.
|
|
||||||
perl -e 'use POSIX; open(my $t, "+<", "/dev/tty") or exit 1; POSIX::tcsetpgrp(fileno($t), getpgrp()) or exit 1;' 2>/dev/null || true
|
|
||||||
|
|
||||||
msg_error "Installation failed in container ${CTID} (exit code: ${install_exit_code})"
|
msg_error "Installation failed in container ${CTID} (exit code: ${install_exit_code})"
|
||||||
|
|
||||||
@@ -5338,6 +5338,7 @@ EOF
|
|||||||
pct enter "$CTID"
|
pct enter "$CTID"
|
||||||
echo ""
|
echo ""
|
||||||
echo -en "${YW}Container ${CTID} still running. Remove now? (y/N): ${CL}"
|
echo -en "${YW}Container ${CTID} still running. Remove now? (y/N): ${CL}"
|
||||||
|
reclaim_tty
|
||||||
if read -r response </dev/tty && [[ "$response" =~ ^[Yy]$ ]]; then
|
if read -r response </dev/tty && [[ "$response" =~ ^[Yy]$ ]]; then
|
||||||
pct stop "$CTID" &>/dev/null || true
|
pct stop "$CTID" &>/dev/null || true
|
||||||
pct destroy "$CTID" &>/dev/null || true
|
pct destroy "$CTID" &>/dev/null || true
|
||||||
@@ -5497,6 +5498,7 @@ EOF
|
|||||||
|
|
||||||
local response=""
|
local response=""
|
||||||
local read_rc
|
local read_rc
|
||||||
|
reclaim_tty
|
||||||
read -t 60 -r response </dev/tty
|
read -t 60 -r response </dev/tty
|
||||||
read_rc=$?
|
read_rc=$?
|
||||||
if [[ $read_rc -eq 0 ]]; then
|
if [[ $read_rc -eq 0 ]]; then
|
||||||
@@ -5729,6 +5731,7 @@ EOF
|
|||||||
# read itself failed (e.g. broken/closed stdin, I/O error) rather than
|
# read itself failed (e.g. broken/closed stdin, I/O error) rather than
|
||||||
# timing out - don't guess and destroy the container on a read we
|
# timing out - don't guess and destroy the container on a read we
|
||||||
# couldn't actually capture; keep it since that's the reversible choice.
|
# couldn't actually capture; keep it since that's the reversible choice.
|
||||||
|
while read -r -t 0.1 -n 1 _ </dev/tty 2>/dev/null; do :; done
|
||||||
echo ""
|
echo ""
|
||||||
msg_error "Could not read your response (stdin error) - keeping container ${CTID} for safety."
|
msg_error "Could not read your response (stdin error) - keeping container ${CTID} for safety."
|
||||||
msg_error "Remove it manually if not needed: pct destroy ${CTID}"
|
msg_error "Remove it manually if not needed: pct destroy ${CTID}"
|
||||||
@@ -5760,6 +5763,7 @@ destroy_lxc() {
|
|||||||
trap 'echo; msg_error "Aborted by user (SIGINT/SIGQUIT)"; return 130' INT QUIT
|
trap 'echo; msg_error "Aborted by user (SIGINT/SIGQUIT)"; return 130' INT QUIT
|
||||||
|
|
||||||
local prompt
|
local prompt
|
||||||
|
reclaim_tty
|
||||||
if ! read -rp "Remove this Container? <y/N> " prompt </dev/tty; then
|
if ! read -rp "Remove this Container? <y/N> " prompt </dev/tty; then
|
||||||
# read returns non-zero on Ctrl-D/ESC
|
# read returns non-zero on Ctrl-D/ESC
|
||||||
msg_error "Aborted input (Ctrl-D/ESC)"
|
msg_error "Aborted input (Ctrl-D/ESC)"
|
||||||
@@ -6721,7 +6725,8 @@ create_lxc_container() {
|
|||||||
# Step 1: Check local templates first (instant)
|
# Step 1: Check local templates first (instant)
|
||||||
mapfile -t LOCAL_TEMPLATES < <(
|
mapfile -t LOCAL_TEMPLATES < <(
|
||||||
pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
|
pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
|
||||||
awk -v search="${TEMPLATE_SEARCH}" -v pattern="${TEMPLATE_PATTERN}" '$1 ~ search && $1 ~ pattern {print $1}' |
|
awk -v search="${TEMPLATE_SEARCH}" -v pattern="${TEMPLATE_PATTERN}" -v arch="${ARCH}" \
|
||||||
|
'$1 ~ search && $1 ~ pattern && $1 ~ ("_" arch "\\.(tar\\.zst|tar\\.xz|tar\\.gz)$") {print $1}' |
|
||||||
sed 's|.*/||' | sort -t - -k 2 -V
|
sed 's|.*/||' | sort -t - -k 2 -V
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+110
-7
@@ -299,6 +299,72 @@ root_check() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# on_pve_host()
|
||||||
|
#
|
||||||
|
# - Returns 0 when executed on a Proxmox VE node, 1 otherwise
|
||||||
|
# - Cheap probe used by the guards below; never exits on its own
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
on_pve_host() {
|
||||||
|
command -v pveversion &>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# require_pve_host()
|
||||||
|
#
|
||||||
|
# - Guard for tools that drive the node itself (pct/pveam/pvesm/pvesh/qm)
|
||||||
|
# - Aborts when not on a PVE node, then validates the PVE version
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
require_pve_host() {
|
||||||
|
if ! on_pve_host; then
|
||||||
|
msg_error "${APP:-This script} must be run on the Proxmox VE host."
|
||||||
|
msg_error "Proxmox tooling (pct/pveam/pvesm/qm) is not available here."
|
||||||
|
exit 232
|
||||||
|
fi
|
||||||
|
pve_check
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# confirm_not_pve_host()
|
||||||
|
#
|
||||||
|
# - Guard for tools that belong inside an LXC/VM but would technically run
|
||||||
|
# on the node as well
|
||||||
|
# - Warns and asks for confirmation instead of hard-failing
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
confirm_not_pve_host() {
|
||||||
|
on_pve_host || return 0
|
||||||
|
|
||||||
|
msg_error "Running on the Proxmox VE host is NOT recommended!"
|
||||||
|
msg_error "${APP:-This script} is meant to be executed inside an LXC container."
|
||||||
|
echo ""
|
||||||
|
echo -n "${TAB:- }Continue anyway? (y/N): "
|
||||||
|
local confirm
|
||||||
|
read -r confirm
|
||||||
|
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||||
|
msg_warn "Aborted. Please run this inside an LXC container."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
msg_warn "Proceeding on the Proxmox VE host at your own risk!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# require_debian_like()
|
||||||
|
#
|
||||||
|
# - Guard for addons that have no Alpine code path
|
||||||
|
# - Aborts early instead of failing halfway through with apt/systemd errors
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
require_debian_like() {
|
||||||
|
if is_alpine; then
|
||||||
|
msg_error "${APP:-This script} does not support Alpine Linux."
|
||||||
|
msg_error "Please use a Debian or Ubuntu based LXC container."
|
||||||
|
exit 238
|
||||||
|
fi
|
||||||
|
if ! command -v apt-get &>/dev/null; then
|
||||||
|
msg_error "${APP:-This script} requires a Debian or Ubuntu based system."
|
||||||
|
exit 238
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# pve_check()
|
# pve_check()
|
||||||
#
|
#
|
||||||
@@ -308,6 +374,10 @@ root_check() {
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
pve_check() {
|
pve_check() {
|
||||||
local PVE_VER
|
local PVE_VER
|
||||||
|
if ! on_pve_host; then
|
||||||
|
msg_error "${APP:-This script} must be run on the Proxmox VE host."
|
||||||
|
exit 232
|
||||||
|
fi
|
||||||
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
||||||
|
|
||||||
# Check for Proxmox VE 8.x: allow 8.0–8.9
|
# Check for Proxmox VE 8.x: allow 8.0–8.9
|
||||||
@@ -754,7 +824,7 @@ msg_info() {
|
|||||||
# Pause mode: Wait for Enter after each step
|
# Pause mode: Wait for Enter after each step
|
||||||
if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then
|
if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then
|
||||||
echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2
|
echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2
|
||||||
read -r
|
read -r </dev/tty
|
||||||
fi
|
fi
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
@@ -769,7 +839,7 @@ msg_info() {
|
|||||||
if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then
|
if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then
|
||||||
stop_spinner
|
stop_spinner
|
||||||
echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2
|
echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2
|
||||||
read -r
|
read -r </dev/tty
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -972,6 +1042,39 @@ ensure_tput() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# reclaim_tty()
|
||||||
|
#
|
||||||
|
# - Reclaims the controlling terminal's foreground process group
|
||||||
|
# - lxc-attach takes the terminal and does not hand it back, leaving us in a
|
||||||
|
# background process group. Reading from the terminal then returns EIO
|
||||||
|
# instead of blocking, because SIGTTIN is ignored during recovery - so the
|
||||||
|
# prompt fails before the user can answer and their keystroke leaks into the
|
||||||
|
# parent shell. Redirecting to /dev/tty does not help: the rule applies to
|
||||||
|
# the terminal, not to the file descriptor.
|
||||||
|
# - pct exec/pull/enter use lxc-attach internally, so the terminal can be taken
|
||||||
|
# away again at any point. Call this immediately before each interactive
|
||||||
|
# read, not once after the install.
|
||||||
|
# - SIGTTOU is ignored inside perl so tcsetpgrp() succeeds instead of stopping
|
||||||
|
# us. No-op when we already are in the foreground or there is no terminal.
|
||||||
|
# perl is a hard dependency of Proxmox VE.
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
reclaim_tty() {
|
||||||
|
command -v perl >/dev/null 2>&1 || return 0
|
||||||
|
[[ -e /dev/tty ]] || return 0
|
||||||
|
|
||||||
|
local pgid
|
||||||
|
pgid=$(ps -o pgid= -p $$ 2>/dev/null | tr -d ' ') || true
|
||||||
|
|
||||||
|
perl -e '
|
||||||
|
use POSIX;
|
||||||
|
$SIG{TTOU} = "IGNORE";
|
||||||
|
my $pgid = $ARGV[0] || POSIX::getpgrp();
|
||||||
|
open(my $t, "+<", "/dev/tty") or exit 1;
|
||||||
|
POSIX::tcsetpgrp(fileno($t), $pgid) or exit 1;
|
||||||
|
' "${pgid:-0}" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# is_alpine()
|
# is_alpine()
|
||||||
#
|
#
|
||||||
@@ -1217,7 +1320,7 @@ prompt_confirm() {
|
|||||||
# Interactive prompt with timeout
|
# Interactive prompt with timeout
|
||||||
echo -en "${YW}${message} ${hint} (auto-${default} in ${timeout}s): ${CL}"
|
echo -en "${YW}${message} ${hint} (auto-${default} in ${timeout}s): ${CL}"
|
||||||
|
|
||||||
if read -t "$timeout" -r response; then
|
if read -t "$timeout" -r response </dev/tty; then
|
||||||
# User provided input
|
# User provided input
|
||||||
response="${response,,}" # lowercase
|
response="${response,,}" # lowercase
|
||||||
case "$response" in
|
case "$response" in
|
||||||
@@ -1310,7 +1413,7 @@ prompt_input() {
|
|||||||
# Interactive prompt with timeout
|
# Interactive prompt with timeout
|
||||||
echo -en "${YW}${message}${hint} (auto-default in ${timeout}s): ${CL}" >&2
|
echo -en "${YW}${message}${hint} (auto-default in ${timeout}s): ${CL}" >&2
|
||||||
|
|
||||||
if read -t "$timeout" -r response; then
|
if read -t "$timeout" -r response </dev/tty; then
|
||||||
# User provided input (or pressed Enter for empty)
|
# User provided input (or pressed Enter for empty)
|
||||||
if [[ -n "$response" ]]; then
|
if [[ -n "$response" ]]; then
|
||||||
echo "$response"
|
echo "$response"
|
||||||
@@ -1412,7 +1515,7 @@ prompt_input_required() {
|
|||||||
|
|
||||||
echo -en "${YW}${message} (required, timeout ${timeout}s): ${CL}" >&2
|
echo -en "${YW}${message} (required, timeout ${timeout}s): ${CL}" >&2
|
||||||
|
|
||||||
if read -t "$timeout" -r response; then
|
if read -t "$timeout" -r response </dev/tty; then
|
||||||
if [[ -z "$response" ]]; then
|
if [[ -z "$response" ]]; then
|
||||||
echo -e "${YW}This field is required. Please enter a value. (attempt ${attempts}/3)${CL}" >&2
|
echo -e "${YW}This field is required. Please enter a value. (attempt ${attempts}/3)${CL}" >&2
|
||||||
fi
|
fi
|
||||||
@@ -1507,7 +1610,7 @@ prompt_select() {
|
|||||||
echo -en "${YW}Select [1-${num_options}] (auto-select ${default} in ${timeout}s): ${CL}" >&2
|
echo -en "${YW}Select [1-${num_options}] (auto-select ${default} in ${timeout}s): ${CL}" >&2
|
||||||
|
|
||||||
local response
|
local response
|
||||||
if read -t "$timeout" -r response; then
|
if read -t "$timeout" -r response </dev/tty; then
|
||||||
if [[ -z "$response" ]]; then
|
if [[ -z "$response" ]]; then
|
||||||
# Empty response, use default
|
# Empty response, use default
|
||||||
echo "${options[$((default - 1))]}"
|
echo "${options[$((default - 1))]}"
|
||||||
@@ -1590,7 +1693,7 @@ prompt_password() {
|
|||||||
# Interactive prompt with timeout (silent input)
|
# Interactive prompt with timeout (silent input)
|
||||||
echo -en "${YW}${message}${hint} (timeout ${timeout}s): ${CL}" >&2
|
echo -en "${YW}${message}${hint} (timeout ${timeout}s): ${CL}" >&2
|
||||||
|
|
||||||
if read -t "$timeout" -rs response; then
|
if read -t "$timeout" -rs response </dev/tty; then
|
||||||
echo "" >&2 # Newline after hidden input
|
echo "" >&2 # Newline after hidden input
|
||||||
if [[ -n "$response" ]]; then
|
if [[ -n "$response" ]]; then
|
||||||
# Validate minimum length
|
# Validate minimum length
|
||||||
|
|||||||
@@ -499,7 +499,8 @@ error_handler() {
|
|||||||
|
|
||||||
local response=""
|
local response=""
|
||||||
local read_rc
|
local read_rc
|
||||||
read -t 60 -r response
|
declare -f reclaim_tty >/dev/null 2>&1 && reclaim_tty
|
||||||
|
read -t 60 -r response </dev/tty
|
||||||
read_rc=$?
|
read_rc=$?
|
||||||
if [[ $read_rc -eq 0 ]]; then
|
if [[ $read_rc -eq 0 ]]; then
|
||||||
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
|
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
|
||||||
@@ -543,6 +544,7 @@ error_handler() {
|
|||||||
# read itself failed (e.g. broken/closed stdin, I/O error) rather than
|
# read itself failed (e.g. broken/closed stdin, I/O error) rather than
|
||||||
# timing out - don't guess and destroy the container on a read we
|
# timing out - don't guess and destroy the container on a read we
|
||||||
# couldn't actually capture; keep it since that's the reversible choice.
|
# couldn't actually capture; keep it since that's the reversible choice.
|
||||||
|
while read -r -t 0.1 -n 1 _ </dev/tty 2>/dev/null; do :; done
|
||||||
echo ""
|
echo ""
|
||||||
if declare -f msg_error >/dev/null 2>&1; then
|
if declare -f msg_error >/dev/null 2>&1; then
|
||||||
msg_error "Could not read your response (stdin error) - keeping container ${CTID} for safety."
|
msg_error "Could not read your response (stdin error) - keeping container ${CTID} for safety."
|
||||||
|
|||||||
+1
-1
@@ -201,7 +201,7 @@ network_check() {
|
|||||||
|
|
||||||
# If both IPv4 and IPv6 checks fail, prompt the user
|
# If both IPv4 and IPv6 checks fail, prompt the user
|
||||||
if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then
|
if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then
|
||||||
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt
|
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt </dev/tty
|
||||||
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
|
||||||
else
|
else
|
||||||
|
|||||||
+110
-84
@@ -1292,14 +1292,17 @@ create_temp_dir() {
|
|||||||
# - Copies each given file/directory into a persistent store at
|
# - Copies each given file/directory into a persistent store at
|
||||||
# /opt/<NSAPP>.backup, mirroring its absolute path inside the store, and
|
# /opt/<NSAPP>.backup, mirroring its absolute path inside the store, and
|
||||||
# records it in a manifest so restore_backup needs no arguments.
|
# records it in a manifest so restore_backup needs no arguments.
|
||||||
# - Idempotent: if a store from a previous (failed) run already exists, it is
|
# - Idempotent per path: a path already recorded in the manifest (from this
|
||||||
# left untouched and no new backup is taken. This keeps the last-known-good
|
# run or a previous failed one) is left untouched, keeping the
|
||||||
# data instead of overwriting it with now-partially-updated data on retry.
|
# last-known-good copy instead of overwriting it with now-partially-updated
|
||||||
|
# data on retry. Any requested path NOT yet in the manifest is backed up
|
||||||
|
# now and appended - so a manifest left incomplete by an interrupted prior
|
||||||
|
# run gets completed instead of silently missing paths on restore.
|
||||||
# - Missing source paths are skipped with a warning (not fatal).
|
# - Missing source paths are skipped with a warning (not fatal).
|
||||||
# - Aborts the update on copy failure: if any file/dir cannot be backed up,
|
# - Aborts the update on copy failure: if any file/dir cannot be backed up,
|
||||||
# the half-written store is removed and the script exits, so the update
|
# the script exits before the update runs against unprotected data (the
|
||||||
# never runs against unprotected data (and a retry re-attempts a clean
|
# paths already recorded are left in place, so a retry only redoes the one
|
||||||
# backup rather than skipping it).
|
# that failed).
|
||||||
#
|
#
|
||||||
# restore_backup
|
# restore_backup
|
||||||
# - Copies every path recorded in the manifest back to its origin (replacing
|
# - Copies every path recorded in the manifest back to its origin (replacing
|
||||||
@@ -1318,19 +1321,17 @@ create_backup() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ -f "$manifest" ]]; then
|
if ! mkdir -p "$store" || ! touch "$manifest"; then
|
||||||
msg_ok "Existing backup found at ${store}, skipping backup"
|
msg_error "Backup failed: could not create store at ${store} - aborting update"
|
||||||
return 0
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Backing up data"
|
msg_info "Backing up data"
|
||||||
if ! mkdir -p "$store" || ! : >"$manifest"; then
|
|
||||||
msg_error "Backup failed: could not create store at ${store} - aborting update"
|
|
||||||
rm -rf "$store"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
for path in "$@"; do
|
for path in "$@"; do
|
||||||
path="${path%/}"
|
path="${path%/}"
|
||||||
|
if grep -qxF "$path" "$manifest" 2>/dev/null; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
if [[ ! -e "$path" ]]; then
|
if [[ ! -e "$path" ]]; then
|
||||||
msg_warn "Skipping backup of '${path}' (not found)"
|
msg_warn "Skipping backup of '${path}' (not found)"
|
||||||
continue
|
continue
|
||||||
@@ -1338,7 +1339,6 @@ create_backup() {
|
|||||||
dest="${store}/files${path}"
|
dest="${store}/files${path}"
|
||||||
if ! mkdir -p "$(dirname "$dest")" || ! cp -a "$path" "$dest"; then
|
if ! mkdir -p "$(dirname "$dest")" || ! cp -a "$path" "$dest"; then
|
||||||
msg_error "Backup of '${path}' failed - aborting update"
|
msg_error "Backup of '${path}' failed - aborting update"
|
||||||
rm -rf "$store"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
echo "$path" >>"$manifest"
|
echo "$path" >>"$manifest"
|
||||||
@@ -1466,7 +1466,7 @@ prompt_for_github_token() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
local reply
|
local reply
|
||||||
read -rp "${TAB}Would you like to enter a GitHub Personal Access Token (PAT)? [y/N]: " reply
|
read -rp "${TAB}Would you like to enter a GitHub Personal Access Token (PAT)? [y/N]: " reply </dev/tty
|
||||||
reply="${reply:-n}"
|
reply="${reply:-n}"
|
||||||
|
|
||||||
if [[ ! "${reply,,}" =~ ^(y|yes)$ ]]; then
|
if [[ ! "${reply,,}" =~ ^(y|yes)$ ]]; then
|
||||||
@@ -1475,7 +1475,7 @@ prompt_for_github_token() {
|
|||||||
|
|
||||||
local token
|
local token
|
||||||
while true; do
|
while true; do
|
||||||
read -rp "${TAB}Enter your GitHub PAT: " token
|
read -rp "${TAB}Enter your GitHub PAT: " token </dev/tty
|
||||||
# Trim leading/trailing whitespace
|
# Trim leading/trailing whitespace
|
||||||
token="$(echo "$token" | xargs)"
|
token="$(echo "$token" | xargs)"
|
||||||
if [[ -z "$token" ]]; then
|
if [[ -z "$token" ]]; then
|
||||||
@@ -2040,8 +2040,9 @@ cleanup_orphaned_sources() {
|
|||||||
local basename_file
|
local basename_file
|
||||||
basename_file=$(basename "$sources_file")
|
basename_file=$(basename "$sources_file")
|
||||||
|
|
||||||
# NEVER remove debian.sources - this is the standard Debian repository
|
# NEVER remove the distro's own base sources file (debian.sources,
|
||||||
if [[ "$basename_file" == "debian.sources" ]]; then
|
# ubuntu.sources, ...)
|
||||||
|
if [[ "$basename_file" == "$(get_os_info id).sources" ]]; then
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -2113,7 +2114,7 @@ ensure_apt_working() {
|
|||||||
# Step 4: More aggressive - remove all third-party sources
|
# Step 4: More aggressive - remove all third-party sources
|
||||||
msg_warn "APT update still failing, removing third-party sources"
|
msg_warn "APT update still failing, removing third-party sources"
|
||||||
find /etc/apt/sources.list.d/ -type f \( -name "*.sources" -o -name "*.list" \) \
|
find /etc/apt/sources.list.d/ -type f \( -name "*.sources" -o -name "*.list" \) \
|
||||||
! -name "debian.sources" -delete 2>/dev/null || true
|
! -name "$(get_os_info id).sources" -delete 2>/dev/null || true
|
||||||
|
|
||||||
# Final attempt
|
# Final attempt
|
||||||
if ! $STD apt update; then
|
if ! $STD apt update; then
|
||||||
@@ -2575,11 +2576,6 @@ _deploy_unpacked_archive() {
|
|||||||
local archive="$1" target="$2" workdir="$3"
|
local archive="$1" target="$2" workdir="$3"
|
||||||
local filename="${archive##*/}"
|
local filename="${archive##*/}"
|
||||||
|
|
||||||
mkdir -p "$target"
|
|
||||||
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
|
|
||||||
find "${target:?}" -mindepth 1 -delete
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$filename" == *.zip ]]; then
|
if [[ "$filename" == *.zip ]]; then
|
||||||
ensure_dependencies unzip
|
ensure_dependencies unzip
|
||||||
unzip -q "$archive" -d "$workdir" || {
|
unzip -q "$archive" -d "$workdir" || {
|
||||||
@@ -2606,38 +2602,44 @@ _deploy_unpacked_archive() {
|
|||||||
return 65
|
return 65
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local top_entries inner_dir
|
local top_entries inner_dir source_dir
|
||||||
top_entries=$(find "$workdir" -mindepth 1 -maxdepth 1)
|
top_entries=$(find "$workdir" -mindepth 1 -maxdepth 1)
|
||||||
if [[ "$(echo "$top_entries" | wc -l)" -eq 1 && -d "$top_entries" ]]; then
|
if [[ "$(echo "$top_entries" | wc -l)" -eq 1 && -d "$top_entries" ]]; then
|
||||||
inner_dir="$top_entries"
|
inner_dir="$top_entries"
|
||||||
shopt -s dotglob nullglob
|
source_dir="$inner_dir"
|
||||||
if compgen -G "$inner_dir/*" >/dev/null; then
|
|
||||||
cp -r "$inner_dir"/* "$target/" || {
|
|
||||||
msg_error "Failed to copy contents from $inner_dir to $target"
|
|
||||||
shopt -u dotglob nullglob
|
|
||||||
return 252
|
|
||||||
}
|
|
||||||
else
|
|
||||||
msg_error "Inner directory is empty: $inner_dir"
|
|
||||||
shopt -u dotglob nullglob
|
|
||||||
return 252
|
|
||||||
fi
|
|
||||||
shopt -u dotglob nullglob
|
|
||||||
else
|
else
|
||||||
shopt -s dotglob nullglob
|
source_dir="$workdir"
|
||||||
if compgen -G "$workdir/*" >/dev/null; then
|
fi
|
||||||
cp -r "$workdir"/* "$target/" || {
|
|
||||||
msg_error "Failed to copy contents to $target"
|
shopt -s dotglob nullglob
|
||||||
shopt -u dotglob nullglob
|
if ! compgen -G "$source_dir/*" >/dev/null; then
|
||||||
return 252
|
if [[ -n "$inner_dir" ]]; then
|
||||||
}
|
msg_error "Inner directory is empty: $inner_dir"
|
||||||
else
|
else
|
||||||
msg_error "Unpacked archive is empty"
|
msg_error "Unpacked archive is empty"
|
||||||
shopt -u dotglob nullglob
|
|
||||||
return 252
|
|
||||||
fi
|
fi
|
||||||
shopt -u dotglob nullglob
|
shopt -u dotglob nullglob
|
||||||
|
return 252
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# <target> is only touched once the payload is known good. Wiping earlier left
|
||||||
|
# CLEAN_INSTALL callers with an empty target directory whenever the download
|
||||||
|
# was truncated, the archive was unreadable, or it unpacked to nothing.
|
||||||
|
mkdir -p "$target"
|
||||||
|
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
|
||||||
|
find "${target:?}" -mindepth 1 -delete
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! cp -r "$source_dir"/* "$target/"; then
|
||||||
|
if [[ -n "$inner_dir" ]]; then
|
||||||
|
msg_error "Failed to copy contents from $inner_dir to $target"
|
||||||
|
else
|
||||||
|
msg_error "Failed to copy contents to $target"
|
||||||
|
fi
|
||||||
|
shopt -u dotglob nullglob
|
||||||
|
return 252
|
||||||
|
fi
|
||||||
|
shopt -u dotglob nullglob
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3973,7 +3975,7 @@ _gh_scan_older_releases() {
|
|||||||
local use_fallback="y"
|
local use_fallback="y"
|
||||||
if [[ -t 0 ]]; then
|
if [[ -t 0 ]]; then
|
||||||
msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset."
|
msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset."
|
||||||
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback || use_fallback="y"
|
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback </dev/tty || use_fallback="y"
|
||||||
use_fallback="${use_fallback:-y}"
|
use_fallback="${use_fallback:-y}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -4627,6 +4629,53 @@ _docker_is_noninteractive() {
|
|||||||
[[ "${DOCKER_NONINTERACTIVE:-}" == "1" || "${DOCKER_NONINTERACTIVE:-}" == "true" || "${DOCKER_NONINTERACTIVE:-}" == "TRUE" ]] || [[ ! -t 0 ]]
|
[[ "${DOCKER_NONINTERACTIVE:-}" == "1" || "${DOCKER_NONINTERACTIVE:-}" == "true" || "${DOCKER_NONINTERACTIVE:-}" == "TRUE" ]] || [[ ! -t 0 ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# ensure_docker()
|
||||||
|
#
|
||||||
|
# - Docker precondition for addon scripts that ship a compose stack
|
||||||
|
# - Reuses an existing installation, otherwise offers to install Docker
|
||||||
|
# (Debian/Ubuntu via setup_docker, Alpine via apk)
|
||||||
|
# - Aborts when the user declines or Compose is unavailable afterwards
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
ensure_docker() {
|
||||||
|
if command -v docker &>/dev/null; then
|
||||||
|
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
|
||||||
|
if docker compose version &>/dev/null; then
|
||||||
|
msg_ok "Docker Compose is available"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
msg_error "Docker Compose plugin is not available. Please install it."
|
||||||
|
exit 237
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_warn "Docker is not installed."
|
||||||
|
echo -n "${TAB:- }Install Docker now? (y/N): "
|
||||||
|
local install_docker_prompt
|
||||||
|
read -r install_docker_prompt
|
||||||
|
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
|
msg_error "Docker is required for ${APP:-this script}. Exiting."
|
||||||
|
exit 254
|
||||||
|
fi
|
||||||
|
|
||||||
|
if is_alpine; then
|
||||||
|
msg_info "Installing Docker"
|
||||||
|
$STD apk add --no-cache docker docker-cli-compose
|
||||||
|
$STD rc-update add docker default
|
||||||
|
$STD rc-service docker start
|
||||||
|
msg_ok "Installed Docker"
|
||||||
|
else
|
||||||
|
setup_docker || {
|
||||||
|
msg_error "Docker installation failed."
|
||||||
|
exit 237
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v docker &>/dev/null || ! docker compose version &>/dev/null; then
|
||||||
|
msg_error "Docker or the Compose plugin is still unavailable after installation."
|
||||||
|
exit 237
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
setup_docker() {
|
setup_docker() {
|
||||||
local docker_installed=false
|
local docker_installed=false
|
||||||
local USE_DOCKER_REPO="${USE_DOCKER_REPO:-true}"
|
local USE_DOCKER_REPO="${USE_DOCKER_REPO:-true}"
|
||||||
@@ -4753,8 +4802,8 @@ EOF
|
|||||||
|
|
||||||
# Container Update Check
|
# Container Update Check
|
||||||
# - Skipped entirely when running unattended / non-interactive
|
# - Skipped entirely when running unattended / non-interactive
|
||||||
# - Compose-managed containers: offered via Y/N → docker compose pull + up -d
|
# - Lists containers with a newer image available and the command to update
|
||||||
# - Standalone containers: offered via Y/N → image pull only (no stop/rm)
|
# them; does not pull/recreate anything itself
|
||||||
if [ "$docker_installed" = true ] && ! _docker_is_noninteractive; then
|
if [ "$docker_installed" = true ] && ! _docker_is_noninteractive; then
|
||||||
msg_info "Checking for container updates"
|
msg_info "Checking for container updates"
|
||||||
|
|
||||||
@@ -4792,41 +4841,14 @@ EOF
|
|||||||
if [[ ${#compose_updates[@]} -eq 0 && ${#standalone_updates[@]} -eq 0 ]]; then
|
if [[ ${#compose_updates[@]} -eq 0 && ${#standalone_updates[@]} -eq 0 ]]; then
|
||||||
msg_ok "All containers are up-to-date"
|
msg_ok "All containers are up-to-date"
|
||||||
else
|
else
|
||||||
local reply
|
msg_warn "Updates available (not applied automatically):"
|
||||||
for entry in "${compose_updates[@]}"; do
|
for entry in "${compose_updates[@]}"; do
|
||||||
IFS='|' read -r name image compose_workdir compose_service <<<"$entry"
|
IFS='|' read -r name image compose_workdir compose_service <<<"$entry"
|
||||||
reply=""
|
echo -e "${TAB3}${name} (${image}) — update via: cd ${compose_workdir} && docker compose pull ${compose_service} && docker compose up -d ${compose_service}"
|
||||||
if read -r -t 60 -p "${TAB3}Update ${name} (${image}) via Compose? <y/N> (auto-no in 60s): " reply; then
|
|
||||||
echo ""
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
if [[ "${reply,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_info "Updating $name"
|
|
||||||
if (cd "$compose_workdir" && $STD docker compose pull "$compose_service" && $STD docker compose up -d "$compose_service"); then
|
|
||||||
msg_ok "Updated $name"
|
|
||||||
else
|
|
||||||
msg_warn "Could not update $name — try manually in $compose_workdir"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
for entry in "${standalone_updates[@]}"; do
|
for entry in "${standalone_updates[@]}"; do
|
||||||
IFS='|' read -r name image <<<"$entry"
|
IFS='|' read -r name image <<<"$entry"
|
||||||
reply=""
|
echo -e "${TAB3}${name} (${image}) — update via: docker pull ${image} && docker restart ${name}"
|
||||||
if read -r -t 60 -p "${TAB3}Pull new image for ${name} (${image})? <y/N> (auto-no in 60s): " reply; then
|
|
||||||
echo ""
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
if [[ "${reply,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_info "Pulling new image for $name"
|
|
||||||
if $STD docker pull "$image"; then
|
|
||||||
msg_ok "New image available for $name — recreate the container to apply the update"
|
|
||||||
else
|
|
||||||
msg_warn "Failed to pull image for $name"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -5409,7 +5431,7 @@ setup_hwaccel() {
|
|||||||
# Read with 60 second timeout
|
# Read with 60 second timeout
|
||||||
local selection=""
|
local selection=""
|
||||||
echo -n "Select GPU(s) to configure (1-${gpu_count}, A=all) [timeout 60s, default=all]: "
|
echo -n "Select GPU(s) to configure (1-${gpu_count}, A=all) [timeout 60s, default=all]: "
|
||||||
if read -r -t 60 selection; then
|
if read -r -t 60 selection </dev/tty; then
|
||||||
selection="${selection^^}" # uppercase
|
selection="${selection^^}" # uppercase
|
||||||
else
|
else
|
||||||
echo ""
|
echo ""
|
||||||
@@ -5457,7 +5479,7 @@ setup_hwaccel() {
|
|||||||
echo ""
|
echo ""
|
||||||
msg_custom "🎮" "${GN}" "NVIDIA GPU passthrough detected"
|
msg_custom "🎮" "${GN}" "NVIDIA GPU passthrough detected"
|
||||||
local nvidia_reply=""
|
local nvidia_reply=""
|
||||||
read -r -t 60 -p "${TAB3}⚙️ Install NVIDIA driver libraries in the container? [Y/n] (auto-yes in 60s): " nvidia_reply || nvidia_reply=""
|
read -r -t 60 -p "${TAB3}⚙️ Install NVIDIA driver libraries in the container? [Y/n] (auto-yes in 60s): " nvidia_reply </dev/tty || nvidia_reply=""
|
||||||
case "${nvidia_reply,,}" in
|
case "${nvidia_reply,,}" in
|
||||||
n | no) install_nvidia_drivers="no" ;;
|
n | no) install_nvidia_drivers="no" ;;
|
||||||
*) install_nvidia_drivers="yes" ;;
|
*) install_nvidia_drivers="yes" ;;
|
||||||
@@ -7684,6 +7706,10 @@ setup_nodejs() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$(npm -v 2>/dev/null | cut -d. -f1)" -ge 11 ]]; then
|
||||||
|
$STD npm config set dangerously-allow-all-scripts true --location=global 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
# Set a safe default heap limit for Node.js builds if not explicitly provided.
|
# Set a safe default heap limit for Node.js builds if not explicitly provided.
|
||||||
# Priority:
|
# Priority:
|
||||||
# 1) NODE_OPTIONS (caller/user override)
|
# 1) NODE_OPTIONS (caller/user override)
|
||||||
@@ -9755,7 +9781,7 @@ _gl_scan_older_releases() {
|
|||||||
local use_fallback="y"
|
local use_fallback="y"
|
||||||
if [[ -t 0 ]]; then
|
if [[ -t 0 ]]; then
|
||||||
msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset."
|
msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset."
|
||||||
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback || use_fallback="y"
|
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback </dev/tty || use_fallback="y"
|
||||||
use_fallback="${use_fallback:-y}"
|
use_fallback="${use_fallback:-y}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,13 @@
|
|||||||
|
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
apt-get update >/dev/null 2>&1
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
apt-get install -y curl >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
fi
|
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)
|
||||||
@@ -20,6 +25,7 @@ declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "actual-budget
|
|||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
|
require_debian_like
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
@@ -31,14 +37,6 @@ INSTALL_PATH="/opt/actual-budget-prometheus-exporter"
|
|||||||
CONFIG_PATH="/opt/actual-budget-prometheus-exporter.env"
|
CONFIG_PATH="/opt/actual-budget-prometheus-exporter.env"
|
||||||
SERVICE_PATH="/etc/systemd/system/actual-budget-prometheus-exporter.service"
|
SERVICE_PATH="/etc/systemd/system/actual-budget-prometheus-exporter.service"
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# OS DETECTION
|
|
||||||
# ==============================================================================
|
|
||||||
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
|
|
||||||
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
|
|
||||||
exit 238
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# UNINSTALL
|
# UNINSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|||||||
@@ -6,39 +6,45 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://netbird.io/ | Github: https://github.com/netbirdio/netbird
|
# Source: https://netbird.io/ | Github: https://github.com/netbirdio/netbird
|
||||||
|
|
||||||
function header_info {
|
APP="add-netbird-lxc"
|
||||||
clear
|
APP_TYPE="addon"
|
||||||
cat <<"EOF"
|
|
||||||
_ __ __ ____ _ __
|
|
||||||
/ | / /__ / /_/ __ )(_)________/ /
|
|
||||||
/ |/ / _ \/ __/ __ / / ___/ __ /
|
|
||||||
/ /| / __/ /_/ /_/ / / / / /_/ /
|
|
||||||
/_/ |_/\___/\__/_____/_/_/ \__,_/
|
|
||||||
|
|
||||||
EOF
|
if ! command -v curl &>/dev/null; then
|
||||||
}
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
header_info
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
set -e
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
# Telemetry
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
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/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/api.func) 2>/dev/null || true
|
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" "addon"
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-netbird-lxc" "addon"
|
||||||
|
|
||||||
|
# Enable error handling
|
||||||
|
set -Eeuo pipefail
|
||||||
|
trap 'error_handler' ERR
|
||||||
|
|
||||||
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
|
load_functions
|
||||||
|
|
||||||
|
header_info
|
||||||
|
require_pve_host
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)?" yn
|
read -r -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)? " yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*) break ;;
|
[Yy]*) break ;;
|
||||||
[Nn]*) exit ;;
|
[Nn]*) exit 0 ;;
|
||||||
*) echo "Please answer yes or no." ;;
|
*) echo "Please answer yes or no." ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
header_info
|
|
||||||
echo "Loading..."
|
|
||||||
|
|
||||||
function msg() {
|
echo -e "Loading container list..."
|
||||||
local TEXT="$1"
|
|
||||||
echo -e "$TEXT"
|
|
||||||
}
|
|
||||||
|
|
||||||
NODE=$(hostname)
|
NODE=$(hostname)
|
||||||
MSG_MAX_LENGTH=0
|
MSG_MAX_LENGTH=0
|
||||||
@@ -61,37 +67,51 @@ done
|
|||||||
|
|
||||||
LXC_STATUS=$(pct status "$CTID" | awk '{print $2}')
|
LXC_STATUS=$(pct status "$CTID" | awk '{print $2}')
|
||||||
if [[ "$LXC_STATUS" != "running" ]]; then
|
if [[ "$LXC_STATUS" != "running" ]]; then
|
||||||
msg "\e[1;33m The container $CTID is not running. Starting it now...\e[0m"
|
msg_info "Container $CTID is not running. Starting it now..."
|
||||||
pct start "$CTID"
|
pct start "$CTID"
|
||||||
while [[ "$(pct status "$CTID" | awk '{print $2}')" != "running" ]]; do
|
while [[ "$(pct status "$CTID" | awk '{print $2}')" != "running" ]]; do
|
||||||
msg "\e[1;33m Waiting for the container to start...\e[0m"
|
msg_info "Waiting for the container to start..."
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
msg "\e[1;32m Container $CTID is now running.\e[0m"
|
msg_ok "Container $CTID is now running."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DISTRO=$(pct exec "$CTID" -- cat /etc/os-release | grep -w "ID" | cut -d'=' -f2 | tr -d '"')
|
DISTRO=$(pct exec "$CTID" -- cat /etc/os-release | grep -w "ID" | cut -d'=' -f2 | tr -d '"')
|
||||||
if [[ "$DISTRO" != "debian" && "$DISTRO" != "ubuntu" ]]; then
|
if [[ "$DISTRO" != "debian" && "$DISTRO" != "ubuntu" ]]; then
|
||||||
msg "\e[1;31m Error: This script only supports Debian or Ubuntu LXC containers. Detected: $DISTRO. Aborting...\e[0m"
|
msg_error "This script only supports Debian or Ubuntu LXC containers. Detected: $DISTRO. Aborting..."
|
||||||
exit 238
|
exit 238
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf
|
CTID_CONFIG_PATH="/etc/pve/lxc/${CTID}.conf"
|
||||||
cat <<EOF >>$CTID_CONFIG_PATH
|
cat <<EOF >>"$CTID_CONFIG_PATH"
|
||||||
lxc.cgroup2.devices.allow: c 10:200 rwm
|
lxc.cgroup2.devices.allow: c 10:200 rwm
|
||||||
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
|
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
|
||||||
EOF
|
EOF
|
||||||
header_info
|
|
||||||
msg "Installing NetBird..."
|
msg_info "Installing NetBird"
|
||||||
pct exec "$CTID" -- bash -c '
|
pct exec "$CTID" -- bash -c '
|
||||||
|
set -e
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
apt-get update -qq
|
apt-get update -qq
|
||||||
apt-get install -y curl >/dev/null
|
apt-get install -y curl >/dev/null
|
||||||
fi
|
fi
|
||||||
apt install -y ca-certificates gpg &>/dev/null
|
apt-get install -y ca-certificates gpg &>/dev/null
|
||||||
curl -fsSL "https://pkgs.netbird.io/debian/public.key" | gpg --dearmor >/usr/share/keyrings/netbird-archive-keyring.gpg
|
|
||||||
echo "deb [signed-by=/usr/share/keyrings/netbird-archive-keyring.gpg] https://pkgs.netbird.io/debian stable main" >/etc/apt/sources.list.d/netbird.list
|
# Reuse the shared repository helper instead of hand-rolling the sources entry
|
||||||
apt-get update &>/dev/null
|
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)
|
||||||
|
load_functions
|
||||||
|
|
||||||
|
# Drop the legacy keyring from the pre-deb822 layout
|
||||||
|
rm -f /usr/share/keyrings/netbird-archive-keyring.gpg
|
||||||
|
|
||||||
|
setup_deb822_repo \
|
||||||
|
"netbird" \
|
||||||
|
"https://pkgs.netbird.io/debian/public.key" \
|
||||||
|
"https://pkgs.netbird.io/debian" \
|
||||||
|
"stable" \
|
||||||
|
"main"
|
||||||
|
|
||||||
apt-get install -y netbird-ui &>/dev/null
|
apt-get install -y netbird-ui &>/dev/null
|
||||||
if systemctl list-unit-files docker.service &>/dev/null; then
|
if systemctl list-unit-files docker.service &>/dev/null; then
|
||||||
mkdir -p /etc/systemd/system/netbird.service.d
|
mkdir -p /etc/systemd/system/netbird.service.d
|
||||||
@@ -103,6 +123,5 @@ OVERRIDE
|
|||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
fi
|
fi
|
||||||
'
|
'
|
||||||
msg "\e[1;32m ✔ Installed NetBird.\e[0m"
|
msg_ok "Installed NetBird."
|
||||||
sleep 2
|
echo -e "${YW}Reboot ${CTID} LXC${CL} to apply the changes, then run 'netbird up' in the LXC console"
|
||||||
msg "\e[1;31m Reboot ${CTID} LXC to apply the changes, then run netbird up in the LXC console\e[0m"
|
|
||||||
|
|||||||
@@ -5,35 +5,34 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://tailscale.com/ | Github: https://github.com/tailscale/tailscale
|
# Source: https://tailscale.com/ | Github: https://github.com/tailscale/tailscale
|
||||||
|
|
||||||
set -Eeuo pipefail
|
APP="add-tailscale-lxc"
|
||||||
trap 'echo -e "\n[ERROR] in line $LINENO: exit code $?"' ERR
|
APP_TYPE="addon"
|
||||||
|
|
||||||
function header_info() {
|
if ! command -v curl &>/dev/null; then
|
||||||
clear
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
cat <<"EOF"
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
______ _ __ __
|
apk update >/dev/null 2>&1
|
||||||
/_ __/___ _(_) /_____________ _/ /__
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
/ / / __ `/ / / ___/ ___/ __ `/ / _ \
|
else
|
||||||
/ / / /_/ / / (__ ) /__/ /_/ / / __/
|
apt-get update >/dev/null 2>&1
|
||||||
/_/ \__,_/_/_/____/\___/\__,_/_/\___/
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
EOF
|
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/tools.func)
|
||||||
function msg_info() { echo -e " \e[1;36m➤\e[0m $1"; }
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
function msg_ok() { echo -e " \e[1;32m✔\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
|
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" "addon"
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-tailscale-lxc" "addon"
|
||||||
|
|
||||||
header_info
|
# Enable error handling
|
||||||
|
set -Eeuo pipefail
|
||||||
|
trap 'error_handler' ERR
|
||||||
|
|
||||||
if ! command -v pveversion &>/dev/null; then
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
msg_error "This script must be run on the Proxmox VE host (not inside an LXC container)"
|
load_functions
|
||||||
exit 232
|
|
||||||
fi
|
header_info
|
||||||
|
require_pve_host
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
read -rp "This will add Tailscale to an existing LXC Container ONLY. Proceed (y/n)? " yn
|
read -rp "This will add Tailscale to an existing LXC Container ONLY. Proceed (y/n)? " yn
|
||||||
@@ -44,7 +43,6 @@ while true; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
header_info
|
|
||||||
msg_info "Loading container list..."
|
msg_info "Loading container list..."
|
||||||
|
|
||||||
NODE=$(hostname)
|
NODE=$(hostname)
|
||||||
@@ -73,10 +71,9 @@ CTID_CONFIG_PATH="/etc/pve/lxc/${CTID}.conf"
|
|||||||
grep -q "lxc.cgroup2.devices.allow: c 10:200 rwm" "$CTID_CONFIG_PATH" || echo "lxc.cgroup2.devices.allow: c 10:200 rwm" >>"$CTID_CONFIG_PATH"
|
grep -q "lxc.cgroup2.devices.allow: c 10:200 rwm" "$CTID_CONFIG_PATH" || echo "lxc.cgroup2.devices.allow: c 10:200 rwm" >>"$CTID_CONFIG_PATH"
|
||||||
grep -q "lxc.mount.entry: /dev/net/tun" "$CTID_CONFIG_PATH" || echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file" >>"$CTID_CONFIG_PATH"
|
grep -q "lxc.mount.entry: /dev/net/tun" "$CTID_CONFIG_PATH" || echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file" >>"$CTID_CONFIG_PATH"
|
||||||
|
|
||||||
header_info
|
|
||||||
msg_info "Installing Tailscale in CT $CTID"
|
msg_info "Installing Tailscale in CT $CTID"
|
||||||
|
|
||||||
pct exec "$CTID" -- sh -c '
|
pct exec "$CTID" -- bash -c '
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Detect OS inside container
|
# Detect OS inside container
|
||||||
@@ -144,16 +141,21 @@ else
|
|||||||
apt-get install -y curl >/dev/null
|
apt-get install -y curl >/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Ensure keyrings directory exists
|
# Reuse the shared repository helper instead of hand-rolling the sources entry
|
||||||
mkdir -p /usr/share/keyrings
|
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)
|
||||||
|
load_functions
|
||||||
|
|
||||||
curl -fsSL "https://pkgs.tailscale.com/stable/${ID}/${VERSION_CODENAME}.noarmor.gpg" \
|
# Drop the legacy keyring from the pre-deb822 layout
|
||||||
| tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
|
rm -f /usr/share/keyrings/tailscale-archive-keyring.gpg
|
||||||
|
|
||||||
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${ID} ${VERSION_CODENAME} main" \
|
setup_deb822_repo \
|
||||||
>/etc/apt/sources.list.d/tailscale.list
|
"tailscale" \
|
||||||
|
"https://pkgs.tailscale.com/stable/${ID}/${VERSION_CODENAME}.noarmor.gpg" \
|
||||||
|
"https://pkgs.tailscale.com/stable/${ID}" \
|
||||||
|
"${VERSION_CODENAME}" \
|
||||||
|
"main"
|
||||||
|
|
||||||
apt-get update -qq
|
|
||||||
apt-get install -y tailscale >/dev/null
|
apt-get install -y tailscale >/dev/null
|
||||||
|
|
||||||
if [ -f /tmp/resolv.conf.backup ]; then
|
if [ -f /tmp/resolv.conf.backup ]; then
|
||||||
@@ -168,4 +170,4 @@ TAGS="${TAGS:+$TAGS; }tailscale"
|
|||||||
pct set "$CTID" -tags "$TAGS"
|
pct set "$CTID" -tags "$TAGS"
|
||||||
|
|
||||||
msg_ok "Tailscale installed on CT $CTID"
|
msg_ok "Tailscale installed on CT $CTID"
|
||||||
msg_info "Reboot the container, then run 'tailscale up' inside the container to activate."
|
echo -e "${YW}Reboot the container${CL}, then run 'tailscale up' inside the container to activate."
|
||||||
|
|||||||
@@ -7,8 +7,9 @@
|
|||||||
|
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
if [[ -f "/etc/alpine-release" ]]; then
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
apk -U add curl >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
else
|
else
|
||||||
apt-get update >/dev/null 2>&1
|
apt-get update >/dev/null 2>&1
|
||||||
apt-get install -y curl >/dev/null 2>&1
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
@@ -36,28 +37,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
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# HEADER
|
|
||||||
# ==============================================================================
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
___ __ ____ __ _____
|
|
||||||
/ | ____/ /___ ___ ______ __________/ / / / /___ ____ ___ ___ / ___/__ ______ _____
|
|
||||||
/ /| |/ __ / __ `/ / / / __ `/ ___/ __ / /_/ / __ \/ __ `__ \/ _ \ \__ \/ / / / __ \/ ___/
|
|
||||||
/ ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / __ / /_/ / / / / / / __/ ___/ / /_/ / / / / /__
|
|
||||||
/_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/_/ /_/\____/_/ /_/ /_/\___/ /____/\__, /_/ /_/\___/
|
|
||||||
/____/ /____/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# HELPER FUNCTIONS
|
|
||||||
# ==============================================================================
|
|
||||||
get_ip() {
|
|
||||||
hostname -I 2>/dev/null | awk '{print $1}' || ip -4 addr show scope global 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1 || echo "127.0.0.1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# OS DETECTION
|
# OS DETECTION
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -114,16 +93,12 @@ function update() {
|
|||||||
fi
|
fi
|
||||||
msg_ok "Stopped service"
|
msg_ok "Stopped service"
|
||||||
|
|
||||||
msg_info "Backing up configuration"
|
BACKUP_DIR="/opt/adguardhome-sync_backup"
|
||||||
cp "$CONFIG_PATH" /tmp/adguardhome-sync.yaml.bak 2>/dev/null || true
|
create_backup "$CONFIG_PATH"
|
||||||
msg_ok "Backed up configuration"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_amd64.tar.gz"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_$(arch_resolve).tar.gz"
|
||||||
|
|
||||||
msg_info "Restoring configuration"
|
restore_backup
|
||||||
cp /tmp/adguardhome-sync.yaml.bak "$CONFIG_PATH" 2>/dev/null || true
|
|
||||||
rm -f /tmp/adguardhome-sync.yaml.bak
|
|
||||||
msg_ok "Restored configuration"
|
|
||||||
|
|
||||||
msg_info "Starting service"
|
msg_info "Starting service"
|
||||||
if [[ "$OS" == "Alpine" ]]; then
|
if [[ "$OS" == "Alpine" ]]; then
|
||||||
@@ -141,10 +116,7 @@ function update() {
|
|||||||
# INSTALL
|
# INSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
function install() {
|
function install() {
|
||||||
local ip
|
fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_$(arch_resolve).tar.gz"
|
||||||
ip=$(get_ip)
|
|
||||||
|
|
||||||
fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_amd64.tar.gz"
|
|
||||||
|
|
||||||
# Gather configuration from user
|
# Gather configuration from user
|
||||||
echo ""
|
echo ""
|
||||||
@@ -153,7 +125,7 @@ function install() {
|
|||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Origin instance
|
# Origin instance
|
||||||
echo -e "${YW}── Origin (Primary) Instance ──${CL}"
|
echo -e "${YW}── Origin (Primary) Instance ──${CL}"
|
||||||
local origin_url origin_user origin_pass
|
local origin_url origin_user origin_pass
|
||||||
read -rp " Origin URL (e.g., http://192.168.1.1): " origin_url
|
read -rp " Origin URL (e.g., http://192.168.1.1): " origin_url
|
||||||
origin_url="${origin_url:-http://192.168.1.1}"
|
origin_url="${origin_url:-http://192.168.1.1}"
|
||||||
@@ -167,7 +139,7 @@ function install() {
|
|||||||
|
|
||||||
# Replica instance
|
# Replica instance
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${YW}── Replica Instance ──${CL}"
|
echo -e "${YW}── Replica Instance ──${CL}"
|
||||||
local replica_url replica_user replica_pass
|
local replica_url replica_user replica_pass
|
||||||
read -rp " Replica URL (e.g., http://192.168.1.2): " replica_url
|
read -rp " Replica URL (e.g., http://192.168.1.2): " replica_url
|
||||||
replica_url="${replica_url:-http://192.168.1.2}"
|
replica_url="${replica_url:-http://192.168.1.2}"
|
||||||
@@ -293,7 +265,7 @@ UPDATEEOF
|
|||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
msg_ok "${APP} installed successfully"
|
msg_ok "${APP} installed successfully"
|
||||||
msg_ok "Web UI: ${BL}http://${ip}:${DEFAULT_PORT}${CL}"
|
msg_ok "Web UI: ${BL}http://${IP}:${DEFAULT_PORT}${CL}"
|
||||||
msg_ok "Config: ${BL}${CONFIG_PATH}${CL}"
|
msg_ok "Config: ${BL}${CONFIG_PATH}${CL}"
|
||||||
echo ""
|
echo ""
|
||||||
msg_warn "Edit the config file to add your AdGuardHome instances!"
|
msg_warn "Edit the config file to add your AdGuardHome instances!"
|
||||||
@@ -319,7 +291,8 @@ fi
|
|||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
|
||||||
IP=$(get_ip)
|
get_lxc_ip
|
||||||
|
IP="$LOCAL_IP"
|
||||||
|
|
||||||
# Check if already installed
|
# Check if already installed
|
||||||
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/adguardhome-sync" ]]; then
|
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/adguardhome-sync" ]]; then
|
||||||
|
|||||||
@@ -1,52 +1,40 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Copyright (c) 2021-2026 tteck
|
# Copyright (c) 2021-2026 tteck
|
||||||
# Author: tteck (tteckster)
|
# Author: tteck (tteckster)
|
||||||
# License: MIT
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
|
||||||
|
|
||||||
function header_info {
|
APP="all-templates"
|
||||||
clear
|
APP_TYPE="addon"
|
||||||
cat <<"EOF"
|
|
||||||
___ ____ ______ __ __
|
|
||||||
/ _ | / / / /_ __/__ __ _ ___ / /__ _/ /____ ___
|
|
||||||
/ __ |/ / / / / / -_) ' \/ _ \/ / _ `/ __/ -_|_-<
|
|
||||||
/_/ |_/_/_/ /_/ \__/_/_/_/ .__/_/\_,_/\__/\__/___/
|
|
||||||
/_/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
set -eEuo pipefail
|
if ! command -v curl &>/dev/null; then
|
||||||
shopt -s expand_aliases
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
alias die='EXIT=$? LINE=$LINENO error_exit'
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
trap die ERR
|
apk update >/dev/null 2>&1
|
||||||
function error_exit() {
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
trap - ERR
|
else
|
||||||
local DEFAULT='Unknown failure occured.'
|
apt-get update >/dev/null 2>&1
|
||||||
local REASON="\e[97m${1:-$DEFAULT}\e[39m"
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE"
|
fi
|
||||||
msg "$FLAG $REASON" 1>&2
|
fi
|
||||||
[ ! -z ${CTID-} ] && cleanup_ctid
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
exit $EXIT
|
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)
|
||||||
function warn() {
|
|
||||||
local REASON="\e[97m$1\e[39m"
|
|
||||||
local FLAG="\e[93m[WARNING]\e[39m"
|
|
||||||
msg "$FLAG $REASON"
|
|
||||||
}
|
|
||||||
function info() {
|
|
||||||
local REASON="$1"
|
|
||||||
local FLAG="\e[36m[INFO]\e[39m"
|
|
||||||
msg "$FLAG $REASON"
|
|
||||||
}
|
|
||||||
function msg() {
|
|
||||||
local TEXT="$1"
|
|
||||||
echo -e "$TEXT"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
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" "addon"
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "all-templates" "addon"
|
||||||
|
|
||||||
|
# Enable error handling; destroy any partially-created container before reporting the error
|
||||||
|
set -Eeuo pipefail
|
||||||
|
function _cleanup_on_error() {
|
||||||
|
local ec=$? cmd="$BASH_COMMAND"
|
||||||
|
[[ -n "${CTID:-}" ]] && cleanup_ctid
|
||||||
|
error_handler "$ec" "$cmd"
|
||||||
|
}
|
||||||
|
trap '_cleanup_on_error' ERR
|
||||||
|
|
||||||
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
|
load_functions
|
||||||
|
|
||||||
function validate_container_id() {
|
function validate_container_id() {
|
||||||
local ctid="$1"
|
local ctid="$1"
|
||||||
# Check if ID is numeric
|
# Check if ID is numeric
|
||||||
@@ -79,12 +67,14 @@ function cleanup_ctid() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header_info
|
||||||
|
require_pve_host
|
||||||
|
|
||||||
# Stop Proxmox VE Monitor-All if running
|
# Stop Proxmox VE Monitor-All if running
|
||||||
if systemctl is-active -q ping-instances.service; then
|
if systemctl is-active -q ping-instances.service; then
|
||||||
systemctl stop ping-instances.service
|
systemctl stop ping-instances.service
|
||||||
fi
|
fi
|
||||||
header_info
|
msg_info "Loading"
|
||||||
echo "Loading..."
|
|
||||||
pveam update >/dev/null 2>&1
|
pveam update >/dev/null 2>&1
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Templates" --yesno "This will allow for the creation of one of the many Template LXC Containers. Proceed?" 10 68
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Templates" --yesno "This will allow for the creation of one of the many Template LXC Containers. Proceed?" 10 68
|
||||||
TEMPLATE_MENU=()
|
TEMPLATE_MENU=()
|
||||||
@@ -97,8 +87,8 @@ done < <(pveam available)
|
|||||||
TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Template LXCs" --radiolist "\nSelect a Template LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 10 "${TEMPLATE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"')
|
TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Template LXCs" --radiolist "\nSelect a Template LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 10 "${TEMPLATE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"')
|
||||||
[ -z "$TEMPLATE" ] && {
|
[ -z "$TEMPLATE" ] && {
|
||||||
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Template LXC Selected" --msgbox "It appears that no Template LXC container was selected" 10 68
|
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Template LXC Selected" --msgbox "It appears that no Template LXC container was selected" 10 68
|
||||||
msg "Done"
|
echo "Done"
|
||||||
exit
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# Setup script environment
|
# Setup script environment
|
||||||
@@ -108,9 +98,9 @@ PASS="$(openssl rand -base64 8)"
|
|||||||
# Get valid Container ID
|
# Get valid Container ID
|
||||||
CTID=$(pvesh get /cluster/nextid)
|
CTID=$(pvesh get /cluster/nextid)
|
||||||
if ! validate_container_id "$CTID"; then
|
if ! validate_container_id "$CTID"; then
|
||||||
warn "Container ID $CTID is already in use."
|
msg_warn "Container ID $CTID is already in use."
|
||||||
CTID=$(get_valid_container_id "$CTID")
|
CTID=$(get_valid_container_id "$CTID")
|
||||||
info "Using next available ID: $CTID"
|
msg_info "Using next available ID: $CTID"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PCT_OPTIONS="
|
PCT_OPTIONS="
|
||||||
@@ -142,7 +132,10 @@ function select_storage() {
|
|||||||
CONTENT='vztmpl'
|
CONTENT='vztmpl'
|
||||||
CONTENT_LABEL='Container template'
|
CONTENT_LABEL='Container template'
|
||||||
;;
|
;;
|
||||||
*) false || die "Invalid storage class." ;;
|
*)
|
||||||
|
msg_error "Invalid storage class."
|
||||||
|
exit 112
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# Query all storage locations
|
# Query all storage locations
|
||||||
@@ -161,8 +154,9 @@ function select_storage() {
|
|||||||
|
|
||||||
# Select storage location
|
# Select storage location
|
||||||
if [ $((${#MENU[@]} / 3)) -eq 0 ]; then
|
if [ $((${#MENU[@]} / 3)) -eq 0 ]; then
|
||||||
warn "'$CONTENT_LABEL' needs to be selected for at least one storage location."
|
msg_warn "'$CONTENT_LABEL' needs to be selected for at least one storage location."
|
||||||
die "Unable to detect valid storage location."
|
msg_error "Unable to detect valid storage location."
|
||||||
|
if [[ "$CONTENT" == "rootdir" ]]; then exit 119; else exit 120; fi
|
||||||
elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then
|
elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then
|
||||||
printf ${MENU[0]}
|
printf ${MENU[0]}
|
||||||
else
|
else
|
||||||
@@ -171,43 +165,54 @@ function select_storage() {
|
|||||||
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
|
||||||
"Which storage pool would you like to use for the ${CONTENT_LABEL,,}?\n\n" \
|
"Which storage pool would you like to use for the ${CONTENT_LABEL,,}?\n\n" \
|
||||||
16 $(($MSG_MAX_LENGTH + 23)) 6 \
|
16 $(($MSG_MAX_LENGTH + 23)) 6 \
|
||||||
"${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted."
|
"${MENU[@]}" 3>&1 1>&2 2>&3) || {
|
||||||
|
msg_error "Menu aborted."
|
||||||
|
exit 254
|
||||||
|
}
|
||||||
done
|
done
|
||||||
printf $STORAGE
|
printf $STORAGE
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
header_info
|
|
||||||
# Get template storage
|
# Get template storage
|
||||||
TEMPLATE_STORAGE=$(select_storage template)
|
TEMPLATE_STORAGE=$(select_storage template)
|
||||||
info "Using '$TEMPLATE_STORAGE' for template storage."
|
msg_info "Using '$TEMPLATE_STORAGE' for template storage."
|
||||||
|
|
||||||
# Get container storage
|
# Get container storage
|
||||||
CONTAINER_STORAGE=$(select_storage container)
|
CONTAINER_STORAGE=$(select_storage container)
|
||||||
info "Using '$CONTAINER_STORAGE' for container storage."
|
msg_info "Using '$CONTAINER_STORAGE' for container storage."
|
||||||
|
|
||||||
# Download template
|
# Download template
|
||||||
msg "Downloading LXC template (Patience)..."
|
msg_info "Downloading LXC template (Patience)"
|
||||||
pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template."
|
pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || {
|
||||||
|
msg_error "A problem occured while downloading the LXC template."
|
||||||
|
exit 222
|
||||||
|
}
|
||||||
|
msg_ok "Downloaded LXC template"
|
||||||
|
|
||||||
# Create variable for 'pct' options
|
# Create variable for 'pct' options
|
||||||
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
|
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
|
||||||
[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8})
|
[[ " ${PCT_OPTIONS[*]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8})
|
||||||
|
|
||||||
# Create LXC
|
# Create LXC
|
||||||
msg "Creating LXC container..."
|
msg_info "Creating LXC container"
|
||||||
pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null ||
|
pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} "${PCT_OPTIONS[@]}" >/dev/null || {
|
||||||
die "A problem occured while trying to create container."
|
msg_error "A problem occured while trying to create container."
|
||||||
|
exit 209
|
||||||
|
}
|
||||||
|
msg_ok "Created LXC container"
|
||||||
|
|
||||||
# Save password
|
# Save password
|
||||||
echo "$NAME password: ${PASS}" >>~/$NAME.creds # file is located in the Proxmox root directory
|
echo "$NAME password: ${PASS}" >>~/$NAME.creds # file is located in the Proxmox root directory
|
||||||
|
|
||||||
# Start container
|
# Start container
|
||||||
msg "Starting LXC Container..."
|
msg_info "Starting LXC Container"
|
||||||
pct start "$CTID"
|
pct start "$CTID"
|
||||||
sleep 5
|
sleep 5
|
||||||
|
msg_ok "Started LXC Container"
|
||||||
|
|
||||||
# Get container IP
|
# Get container IP
|
||||||
set +eEuo pipefail
|
set +Eeuo pipefail
|
||||||
max_attempts=5
|
max_attempts=5
|
||||||
attempt=1
|
attempt=1
|
||||||
IP=""
|
IP=""
|
||||||
@@ -216,30 +221,29 @@ while [[ $attempt -le $max_attempts ]]; do
|
|||||||
if [[ -n $IP ]]; then
|
if [[ -n $IP ]]; then
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..."
|
msg_warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..."
|
||||||
sleep 5
|
sleep 5
|
||||||
((attempt++))
|
((attempt++))
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ -z $IP ]]; then
|
if [[ -z $IP ]]; then
|
||||||
warn "Maximum number of attempts reached. IP address not found."
|
msg_warn "Maximum number of attempts reached. IP address not found."
|
||||||
IP="NOT FOUND"
|
IP="NOT FOUND"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set -eEuo pipefail
|
set -Eeuo pipefail
|
||||||
# Start Proxmox VE Monitor-All if available
|
# Start Proxmox VE Monitor-All if available
|
||||||
if [[ -f /etc/systemd/system/ping-instances.service ]]; then
|
if [[ -f /etc/systemd/system/ping-instances.service ]]; then
|
||||||
systemctl start ping-instances.service
|
systemctl start ping-instances.service
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Success message
|
# Success message
|
||||||
header_info
|
|
||||||
echo
|
echo
|
||||||
info "LXC container '$CTID' was successfully created, and its IP address is ${IP}."
|
msg_ok "LXC container '$CTID' was successfully created, and its IP address is ${IP}."
|
||||||
echo
|
echo
|
||||||
info "Proceed to the LXC console to complete the setup."
|
echo -e "${YW}Proceed to the LXC console to complete the setup.${CL}"
|
||||||
echo
|
echo
|
||||||
info "login: root"
|
echo -e "${YW}login: root${CL}"
|
||||||
info "password: $PASS"
|
echo -e "${YW}password: $PASS${CL}"
|
||||||
echo
|
echo
|
||||||
|
|||||||
+9
-33
@@ -6,8 +6,13 @@
|
|||||||
# Source: https://github.com/getarcaneapp/arcane
|
# Source: https://github.com/getarcaneapp/arcane
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
apt-get update >/dev/null 2>&1
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
apt-get install -y curl >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
fi
|
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)
|
||||||
@@ -32,21 +37,6 @@ DEFAULT_PORT=3552
|
|||||||
# Initialize all core functions (colors, formatting, icons, STD mode)
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
load_functions
|
load_functions
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# HEADER
|
|
||||||
# ==============================================================================
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
___ ____ _________ _ ________
|
|
||||||
/ | / __ \/ ____/ | / | / / ____/
|
|
||||||
/ /| | / /_/ / / / /| | / |/ / __/
|
|
||||||
/ ___ |/ _, _/ /___/ ___ |/ /| / /___
|
|
||||||
/_/ |_/_/ |_|\____/_/ |_/_/ |_/_____/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# UNINSTALL
|
# UNINSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -82,26 +72,11 @@ function update() {
|
|||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# CHECK DOCKER
|
|
||||||
# ==============================================================================
|
|
||||||
function check_docker() {
|
|
||||||
if ! command -v docker &>/dev/null; then
|
|
||||||
msg_error "Docker is not installed. This script requires an existing Docker LXC. Exiting."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
if ! docker compose version &>/dev/null; then
|
|
||||||
msg_error "Docker Compose plugin is not available. Please install it before running this script. Exiting."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') and Docker Compose are available"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# INSTALL
|
# INSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
function install() {
|
function install() {
|
||||||
check_docker
|
ensure_docker
|
||||||
|
|
||||||
msg_info "Creating install directory"
|
msg_info "Creating install directory"
|
||||||
mkdir -p "$INSTALL_PATH"
|
mkdir -p "$INSTALL_PATH"
|
||||||
@@ -178,6 +153,7 @@ if [[ "${type:-}" == "update" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
|
confirm_not_pve_host
|
||||||
get_lxc_ip
|
get_lxc_ip
|
||||||
|
|
||||||
# Check if already installed
|
# Check if already installed
|
||||||
|
|||||||
@@ -5,62 +5,153 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://coder.com/ | Github: https://github.com/coder/code-server
|
# Source: https://coder.com/ | Github: https://github.com/coder/code-server
|
||||||
|
|
||||||
function header_info {
|
if ! command -v curl &>/dev/null; then
|
||||||
cat <<"EOF"
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
______ __ _____
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
/ ____/___ ____/ /__ / ___/___ ______ _____ _____
|
apk update >/dev/null 2>&1
|
||||||
/ / / __ \/ __ / _ \ \__ \/ _ \/ ___/ | / / _ \/ ___/
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
/ /___/ /_/ / /_/ / __/ ___/ / __/ / | |/ / __/ /
|
else
|
||||||
\____/\____/\__,_/\___/ /____/\___/_/ |___/\___/_/
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
EOF
|
fi
|
||||||
}
|
fi
|
||||||
IP=$(hostname -I | awk '{print $1}')
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
YW=$(echo "\033[33m")
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
||||||
BL=$(echo "\033[36m")
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
|
||||||
RD=$(echo "\033[01;31m")
|
|
||||||
BGN=$(echo "\033[4;92m")
|
|
||||||
GN=$(echo "\033[1;92m")
|
|
||||||
DGN=$(echo "\033[32m")
|
|
||||||
CL=$(echo "\033[m")
|
|
||||||
BFR="\\r\\033[K"
|
|
||||||
HOLD="-"
|
|
||||||
CM="${GN}✓${CL}"
|
|
||||||
APP="Coder Code Server"
|
|
||||||
hostname="$(hostname)"
|
|
||||||
|
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
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"
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "coder-code-server" "addon"
|
||||||
|
|
||||||
set -o errexit
|
# Enable error handling
|
||||||
set -o errtrace
|
set -Eeuo pipefail
|
||||||
set -o nounset
|
trap 'error_handler' ERR
|
||||||
set -o pipefail
|
|
||||||
shopt -s expand_aliases
|
APP="Coder Code Server"
|
||||||
alias die='EXIT=$? LINE=$LINENO error_exit'
|
APP_TYPE="addon"
|
||||||
trap die ERR
|
|
||||||
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
|
load_functions
|
||||||
|
|
||||||
function error_exit() {
|
|
||||||
trap - ERR
|
|
||||||
local reason="Unknown failure occured."
|
|
||||||
local msg="${1:-$reason}"
|
|
||||||
local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE"
|
|
||||||
echo -e "$flag $msg" 1>&2
|
|
||||||
exit "$EXIT"
|
|
||||||
}
|
|
||||||
clear
|
|
||||||
header_info
|
header_info
|
||||||
if command -v pveversion >/dev/null 2>&1; then
|
ensure_usr_local_bin_persist
|
||||||
echo -e "⚠️ Can't Install on Proxmox "
|
get_lxc_ip
|
||||||
exit
|
IP="$LOCAL_IP"
|
||||||
|
|
||||||
|
confirm_not_pve_host
|
||||||
|
require_debian_like
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# UNINSTALL
|
||||||
|
# ==============================================================================
|
||||||
|
function uninstall() {
|
||||||
|
msg_info "Uninstalling ${APP}"
|
||||||
|
systemctl disable --now code-server@"$USER" &>/dev/null || true
|
||||||
|
$STD apt remove -y code-server
|
||||||
|
rm -f "$HOME/.coder-code-server"
|
||||||
|
msg_ok "${APP} has been uninstalled"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# UPDATE
|
||||||
|
# ==============================================================================
|
||||||
|
function update() {
|
||||||
|
if check_for_gh_release "coder-code-server" "coder/code-server"; then
|
||||||
|
msg_info "Updating ${APP}"
|
||||||
|
fetch_and_deploy_gh_release "coder-code-server" "coder/code-server" "binary" "latest" "/opt/coder-code-server" "code-server_*_$(arch_resolve).deb"
|
||||||
|
systemctl restart code-server@"$USER"
|
||||||
|
msg_ok "Updated successfully!"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# INSTALL
|
||||||
|
# ==============================================================================
|
||||||
|
function install() {
|
||||||
|
msg_info "Installing Dependencies"
|
||||||
|
$STD apt update
|
||||||
|
$STD apt install -y \
|
||||||
|
curl \
|
||||||
|
git
|
||||||
|
msg_ok "Installed Dependencies"
|
||||||
|
|
||||||
|
msg_info "Installing ${APP}"
|
||||||
|
config_path="${HOME}/.config/code-server/config.yaml"
|
||||||
|
preexisting_config=false
|
||||||
|
if [ -f "$config_path" ]; then
|
||||||
|
preexisting_config=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
fetch_and_deploy_gh_release "coder-code-server" "coder/code-server" "binary" "latest" "/opt/coder-code-server" "code-server_*_$(arch_resolve).deb"
|
||||||
|
mkdir -p "${HOME}/.config/code-server/"
|
||||||
|
|
||||||
|
if [ "$preexisting_config" = false ]; then
|
||||||
|
cat <<EOF >"$config_path"
|
||||||
|
bind-addr: 0.0.0.0:8680
|
||||||
|
auth: none
|
||||||
|
password:
|
||||||
|
cert: false
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
systemctl enable -q --now code-server@"$USER"
|
||||||
|
systemctl restart code-server@"$USER"
|
||||||
|
if ! systemctl is-active --quiet code-server@"$USER"; then
|
||||||
|
msg_error "code-server service failed to start."
|
||||||
|
exit 150
|
||||||
|
fi
|
||||||
|
msg_ok "Installed ${APP}"
|
||||||
|
|
||||||
|
msg_info "Creating update script"
|
||||||
|
ensure_usr_local_bin_persist
|
||||||
|
cat <<'EOF' >/usr/local/bin/update_coder-code-server
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Coder Code Server Update Script
|
||||||
|
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/coder-code-server.sh)"
|
||||||
|
EOF
|
||||||
|
chmod +x /usr/local/bin/update_coder-code-server
|
||||||
|
msg_ok "Created update script (/usr/local/bin/update_coder-code-server)"
|
||||||
|
|
||||||
|
echo -e "${APP} should be reachable by going to the following URL.
|
||||||
|
${BL}http://${IP}:8680${CL} \n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==============================================================================
|
||||||
|
# MAIN
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
# Handle type=update (called from update script)
|
||||||
|
if [[ "${type:-}" == "update" ]]; then
|
||||||
|
if command -v code-server &>/dev/null; then
|
||||||
|
update
|
||||||
|
else
|
||||||
|
msg_error "${APP} is not installed. Nothing to update."
|
||||||
|
exit 233
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
if [ -e /etc/alpine-release ]; then
|
|
||||||
echo -e "⚠️ Can't Install on Alpine"
|
if [[ -d "$HOME" && -f "$HOME/.coder-code-server" ]] || command -v code-server &>/dev/null; then
|
||||||
exit
|
msg_warn "${APP} is already installed."
|
||||||
|
echo -n "${TAB}Uninstall ${APP}? (y/N): "
|
||||||
|
read -r uninstall_prompt
|
||||||
|
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
|
uninstall
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "${TAB}Update ${APP}? (y/N): "
|
||||||
|
read -r update_prompt
|
||||||
|
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
|
update
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
msg_warn "No action selected. Exiting."
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn
|
echo -n "${TAB}This will Install ${APP}. Proceed (y/n)? "
|
||||||
|
read -r yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*) break ;;
|
[Yy]*) break ;;
|
||||||
[Nn]*) exit ;;
|
[Nn]*) exit ;;
|
||||||
@@ -68,53 +159,4 @@ while true; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
function msg_info() {
|
install
|
||||||
local msg="$1"
|
|
||||||
echo -ne " ${HOLD} ${YW}${msg}..."
|
|
||||||
}
|
|
||||||
|
|
||||||
function msg_ok() {
|
|
||||||
local msg="$1"
|
|
||||||
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_info "Installing Dependencies"
|
|
||||||
apt-get update &>/dev/null
|
|
||||||
apt-get install -y curl &>/dev/null
|
|
||||||
apt-get install -y git &>/dev/null
|
|
||||||
msg_ok "Installed Dependencies"
|
|
||||||
|
|
||||||
VERSION=$(curl -fsSL https://api.github.com/repos/coder/code-server/releases/latest |
|
|
||||||
grep "tag_name" |
|
|
||||||
awk '{print substr($2, 3, length($2)-4) }')
|
|
||||||
|
|
||||||
msg_info "Installing Code-Server v${VERSION}"
|
|
||||||
config_path="${HOME}/.config/code-server/config.yaml"
|
|
||||||
preexisting_config=false
|
|
||||||
|
|
||||||
if [ -f "$config_path" ]; then
|
|
||||||
preexisting_config=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
curl -fOL https://github.com/coder/code-server/releases/download/v"$VERSION"/code-server_"${VERSION}"_amd64.deb &>/dev/null
|
|
||||||
dpkg -i code-server_"${VERSION}"_amd64.deb &>/dev/null
|
|
||||||
rm -rf code-server_"${VERSION}"_amd64.deb
|
|
||||||
mkdir -p "${HOME}/.config/code-server/"
|
|
||||||
|
|
||||||
if [ "$preexisting_config" = false ]; then
|
|
||||||
cat <<EOF >"$config_path"
|
|
||||||
bind-addr: 0.0.0.0:8680
|
|
||||||
auth: none
|
|
||||||
password:
|
|
||||||
cert: false
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
systemctl enable -q --now code-server@"$USER"
|
|
||||||
systemctl restart code-server@"$USER"
|
|
||||||
if ! systemctl is-active --quiet code-server@"$USER"; then
|
|
||||||
error_exit "code-server service failed to start."
|
|
||||||
fi
|
|
||||||
msg_ok "Installed Code-Server v${VERSION} on $hostname"
|
|
||||||
|
|
||||||
echo -e "${APP} should be reachable by going to the following URL.
|
|
||||||
${BL}http://$IP:8680${CL} \n"
|
|
||||||
|
|||||||
+2
-57
@@ -66,66 +66,11 @@ function update() {
|
|||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# PROXMOX HOST CHECK
|
|
||||||
# ==============================================================================
|
|
||||||
function check_proxmox_host() {
|
|
||||||
if command -v pveversion &>/dev/null; then
|
|
||||||
msg_error "Running on the Proxmox host is NOT recommended!"
|
|
||||||
msg_error "This should be executed inside an LXC container."
|
|
||||||
echo ""
|
|
||||||
echo -n "${TAB}Continue anyway? (y/N): "
|
|
||||||
read -r confirm
|
|
||||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_warn "Aborted. Please run this inside an LXC container."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
msg_warn "Proceeding on Proxmox host at your own risk!"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# CHECK / INSTALL DOCKER
|
|
||||||
# ==============================================================================
|
|
||||||
function check_or_install_docker() {
|
|
||||||
if command -v docker &>/dev/null; then
|
|
||||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
|
|
||||||
if docker compose version &>/dev/null; then
|
|
||||||
msg_ok "Docker Compose is available"
|
|
||||||
else
|
|
||||||
msg_error "Docker Compose plugin is not available. Please install it."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_warn "Docker is not installed."
|
|
||||||
echo -n "${TAB}Install Docker now? (y/N): "
|
|
||||||
read -r install_docker_prompt
|
|
||||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_error "Docker is required for ${APP}. Exiting."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Installing Docker"
|
|
||||||
if [[ -f /etc/alpine-release ]]; then
|
|
||||||
$STD apk add docker docker-cli-compose
|
|
||||||
$STD rc-service docker start
|
|
||||||
$STD rc-update add docker default
|
|
||||||
else
|
|
||||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
|
||||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
|
||||||
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
|
||||||
$STD sh <(curl -fsSL https://get.docker.com)
|
|
||||||
fi
|
|
||||||
msg_ok "Installed Docker"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# INSTALL
|
# INSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
function install() {
|
function install() {
|
||||||
check_or_install_docker
|
ensure_docker
|
||||||
|
|
||||||
msg_info "Installing dependencies"
|
msg_info "Installing dependencies"
|
||||||
if [[ -f /etc/alpine-release ]]; then
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
@@ -172,7 +117,7 @@ if [[ "${type:-}" == "update" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
check_proxmox_host
|
confirm_not_pve_host
|
||||||
get_lxc_ip
|
get_lxc_ip
|
||||||
|
|
||||||
# Check if already installed
|
# Check if already installed
|
||||||
|
|||||||
+18
-20
@@ -7,8 +7,13 @@
|
|||||||
|
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
apt-get update >/dev/null 2>&1
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
apt-get install -y curl >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
fi
|
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)
|
||||||
@@ -45,28 +50,13 @@ if [[ -f "/etc/alpine-release" ]]; then
|
|||||||
SERVICE_PATH="/etc/init.d/copyparty"
|
SERVICE_PATH="/etc/init.d/copyparty"
|
||||||
elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
|
elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
|
||||||
OS="Debian"
|
OS="Debian"
|
||||||
PKG_MANAGER="apt-get install -y"
|
PKG_MANAGER="apt install -y"
|
||||||
SERVICE_PATH="/etc/systemd/system/copyparty.service"
|
SERVICE_PATH="/etc/systemd/system/copyparty.service"
|
||||||
else
|
else
|
||||||
msg_error "Unsupported OS detected. Exiting."
|
msg_error "Unsupported OS detected. Exiting."
|
||||||
exit 238
|
exit 238
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# HEADER
|
|
||||||
# ==============================================================================
|
|
||||||
function header_info() {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
______ ____ __
|
|
||||||
/ ____/___ ____ __ __/ __ \____ ______/ /___ __
|
|
||||||
/ / / __ \/ __ \/ / / / /_/ / __ `/ ___/ __/ / / /
|
|
||||||
/ /___/ /_/ / /_/ / /_/ / ____/ /_/ / / / /_/ /_/ /
|
|
||||||
\____/\____/ .___/\__, /_/ \__,_/_/ \__/\__, /
|
|
||||||
/_/ /____/ /____/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# HELPER FUNCTIONS
|
# HELPER FUNCTIONS
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -173,9 +163,17 @@ function install() {
|
|||||||
|
|
||||||
msg_info "Installing dependencies"
|
msg_info "Installing dependencies"
|
||||||
if [[ "$OS" == "Debian" ]]; then
|
if [[ "$OS" == "Debian" ]]; then
|
||||||
$STD $PKG_MANAGER python3 python3-pil ffmpeg curl
|
$STD $PKG_MANAGER \
|
||||||
|
python3 \
|
||||||
|
python3-pil \
|
||||||
|
ffmpeg \
|
||||||
|
curl
|
||||||
else
|
else
|
||||||
$STD $PKG_MANAGER python3 py3-pillow ffmpeg curl
|
$STD $PKG_MANAGER \
|
||||||
|
python3 \
|
||||||
|
py3-pillow \
|
||||||
|
ffmpeg \
|
||||||
|
curl
|
||||||
fi
|
fi
|
||||||
msg_ok "Dependencies installed (with thumbnail support)"
|
msg_ok "Dependencies installed (with thumbnail support)"
|
||||||
|
|
||||||
|
|||||||
+11
-32
@@ -7,8 +7,13 @@
|
|||||||
|
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
apt-get update >/dev/null 2>&1
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
apt-get install -y curl >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
fi
|
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)
|
||||||
@@ -20,6 +25,7 @@ declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "cronmaster" "
|
|||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
|
require_debian_like
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
@@ -31,29 +37,6 @@ CONFIG_PATH="/opt/cronmaster/.env"
|
|||||||
SERVICE_PATH="/etc/systemd/system/cronmaster.service"
|
SERVICE_PATH="/etc/systemd/system/cronmaster.service"
|
||||||
DEFAULT_PORT=3000
|
DEFAULT_PORT=3000
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# HEADER
|
|
||||||
# ==============================================================================
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
______ __ ___ __
|
|
||||||
/ ____/________ ____ / |/ /___ ______/ /____ _____
|
|
||||||
/ / / ___/ __ \/ __ \/ /|_/ / __ `/ ___/ __/ _ \/ ___/
|
|
||||||
/ /___/ / / /_/ / / / / / / / /_/ (__ ) /_/ __/ /
|
|
||||||
\____/_/ \____/_/ /_/_/ /_/\__,_/____/\__/\___/_/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# OS DETECTION
|
|
||||||
# ==============================================================================
|
|
||||||
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
|
|
||||||
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
|
|
||||||
exit 238
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# UNINSTALL
|
# UNINSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -77,16 +60,12 @@ function update() {
|
|||||||
systemctl stop cronmaster.service &>/dev/null || true
|
systemctl stop cronmaster.service &>/dev/null || true
|
||||||
msg_ok "Stopped service"
|
msg_ok "Stopped service"
|
||||||
|
|
||||||
msg_info "Backing up configuration"
|
BACKUP_DIR="/opt/cronmaster_backup"
|
||||||
cp "$CONFIG_PATH" /tmp/cronmaster.env.bak 2>/dev/null || true
|
create_backup "$CONFIG_PATH"
|
||||||
msg_ok "Backed up configuration"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cronmaster" "fccview/cronmaster" "prebuild" "latest" "$INSTALL_PATH" "cronmaster_*_prebuild.tar.gz"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cronmaster" "fccview/cronmaster" "prebuild" "latest" "$INSTALL_PATH" "cronmaster_*_prebuild.tar.gz"
|
||||||
|
|
||||||
msg_info "Restoring configuration"
|
restore_backup
|
||||||
cp /tmp/cronmaster.env.bak "$CONFIG_PATH" 2>/dev/null || true
|
|
||||||
rm -f /tmp/cronmaster.env.bak
|
|
||||||
msg_ok "Restored configuration"
|
|
||||||
|
|
||||||
msg_info "Starting service"
|
msg_info "Starting service"
|
||||||
systemctl start cronmaster
|
systemctl start cronmaster
|
||||||
|
|||||||
+35
-63
@@ -5,89 +5,61 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://www.crowdsec.net/ | Github: https://github.com/crowdsecurity/crowdsec
|
# Source: https://www.crowdsec.net/ | Github: https://github.com/crowdsecurity/crowdsec
|
||||||
|
|
||||||
YW=$(echo "\033[33m")
|
|
||||||
BL=$(echo "\033[36m")
|
|
||||||
RD=$(echo "\033[01;31m")
|
|
||||||
BGN=$(echo "\033[4;92m")
|
|
||||||
GN=$(echo "\033[1;92m")
|
|
||||||
DGN=$(echo "\033[32m")
|
|
||||||
CL=$(echo "\033[m")
|
|
||||||
BFR="\\r\\033[K"
|
|
||||||
HOLD="-"
|
|
||||||
CM="${GN}✓${CL}"
|
|
||||||
APP="CrowdSec"
|
APP="CrowdSec"
|
||||||
hostname="$(hostname)"
|
APP_TYPE="addon"
|
||||||
|
|
||||||
# Telemetry
|
if ! command -v curl &>/dev/null; then
|
||||||
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
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/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/api.func) 2>/dev/null || true
|
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"
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "crowdsec" "addon"
|
||||||
|
|
||||||
set -o errexit
|
# Enable error handling
|
||||||
set -o errtrace
|
set -Eeuo pipefail
|
||||||
set -o nounset
|
trap 'error_handler' ERR
|
||||||
set -o pipefail
|
|
||||||
shopt -s expand_aliases
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
alias die='EXIT=$? LINE=$LINENO error_exit'
|
load_functions
|
||||||
trap die ERR
|
require_debian_like
|
||||||
|
|
||||||
|
header_info
|
||||||
|
confirm_not_pve_host
|
||||||
|
|
||||||
function error_exit() {
|
|
||||||
trap - ERR
|
|
||||||
local reason="Unknown failure occured."
|
|
||||||
local msg="${1:-$reason}"
|
|
||||||
local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE"
|
|
||||||
echo -e "$flag $msg" 1>&2
|
|
||||||
exit "$EXIT"
|
|
||||||
}
|
|
||||||
if command -v pveversion >/dev/null 2>&1; then
|
|
||||||
echo -e "⚠️ Can't Install on Proxmox "
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn
|
echo -n "${TAB}This will Install ${APP}. Proceed (y/n)? "
|
||||||
|
read -r yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*) break ;;
|
[Yy]*) break ;;
|
||||||
[Nn]*) exit ;;
|
[Nn]*) exit ;;
|
||||||
*) echo "Please answer yes or no." ;;
|
*) echo "Please answer yes or no." ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
clear
|
|
||||||
function header_info() {
|
|
||||||
echo -e "${BL}
|
|
||||||
_____ _ _____
|
|
||||||
/ ____| | |/ ____|
|
|
||||||
| | _ __ _____ ____| | (___ ___ ___
|
|
||||||
| | | __/ _ \ \ /\ / / _ |\___ \ / _ \/ __|
|
|
||||||
| |____| | | (_) \ V V / (_| |____) | __/ (__
|
|
||||||
\_____|_| \___/ \_/\_/ \__ _|_____/ \___|\___|
|
|
||||||
${CL}"
|
|
||||||
}
|
|
||||||
|
|
||||||
header_info
|
|
||||||
|
|
||||||
function msg_info() {
|
|
||||||
local msg="$1"
|
|
||||||
echo -ne " ${HOLD} ${YW}${msg}..."
|
|
||||||
}
|
|
||||||
|
|
||||||
function msg_ok() {
|
|
||||||
local msg="$1"
|
|
||||||
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
|
|
||||||
}
|
|
||||||
|
|
||||||
msg_info "Setting up ${APP} Repository"
|
msg_info "Setting up ${APP} Repository"
|
||||||
apt-get update &>/dev/null
|
$STD apt update
|
||||||
apt-get install -y curl &>/dev/null
|
$STD apt install -y \
|
||||||
apt-get install -y gnupg &>/dev/null
|
curl \
|
||||||
curl -fsSL "https://install.crowdsec.net" | bash &>/dev/null
|
gnupg
|
||||||
|
$STD bash -c "curl -fsSL https://install.crowdsec.net | bash"
|
||||||
msg_ok "Setup ${APP} Repository"
|
msg_ok "Setup ${APP} Repository"
|
||||||
|
|
||||||
msg_info "Installing ${APP}"
|
msg_info "Installing ${APP}"
|
||||||
apt-get update &>/dev/null
|
$STD apt update
|
||||||
apt-get install -y crowdsec &>/dev/null
|
$STD apt install -y crowdsec
|
||||||
msg_ok "Installed ${APP} on $hostname"
|
msg_ok "Installed ${APP}"
|
||||||
|
|
||||||
msg_info "Installing ${APP} Common Bouncer"
|
msg_info "Installing ${APP} Common Bouncer"
|
||||||
apt-get install -y crowdsec-firewall-bouncer-iptables &>/dev/null
|
$STD apt install -y crowdsec-firewall-bouncer-iptables
|
||||||
msg_ok "Installed ${APP} Common Bouncer"
|
msg_ok "Installed ${APP} Common Bouncer"
|
||||||
|
|
||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
|
|||||||
+2
-57
@@ -72,66 +72,11 @@ function update() {
|
|||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# PROXMOX HOST CHECK
|
|
||||||
# ==============================================================================
|
|
||||||
function check_proxmox_host() {
|
|
||||||
if command -v pveversion &>/dev/null; then
|
|
||||||
msg_error "Running on the Proxmox host is NOT recommended!"
|
|
||||||
msg_error "This should be executed inside an LXC container."
|
|
||||||
echo ""
|
|
||||||
echo -n "${TAB}Continue anyway? (y/N): "
|
|
||||||
read -r confirm
|
|
||||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_warn "Aborted. Please run this inside an LXC container."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
msg_warn "Proceeding on Proxmox host at your own risk!"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# CHECK / INSTALL DOCKER
|
|
||||||
# ==============================================================================
|
|
||||||
function check_or_install_docker() {
|
|
||||||
if command -v docker &>/dev/null; then
|
|
||||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
|
|
||||||
if docker compose version &>/dev/null; then
|
|
||||||
msg_ok "Docker Compose is available"
|
|
||||||
else
|
|
||||||
msg_error "Docker Compose plugin is not available. Please install it."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_warn "Docker is not installed."
|
|
||||||
echo -n "${TAB}Install Docker now? (y/N): "
|
|
||||||
read -r install_docker_prompt
|
|
||||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_error "Docker is required for ${APP}. Exiting."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Installing Docker"
|
|
||||||
if [[ -f /etc/alpine-release ]]; then
|
|
||||||
$STD apk add docker docker-cli-compose
|
|
||||||
$STD rc-service docker start
|
|
||||||
$STD rc-update add docker default
|
|
||||||
else
|
|
||||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
|
||||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
|
||||||
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
|
||||||
$STD sh <(curl -fsSL https://get.docker.com)
|
|
||||||
fi
|
|
||||||
msg_ok "Installed Docker"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# INSTALL
|
# INSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
function install() {
|
function install() {
|
||||||
check_or_install_docker
|
ensure_docker
|
||||||
|
|
||||||
msg_info "Creating install directories"
|
msg_info "Creating install directories"
|
||||||
mkdir -p "$INSTALL_PATH" "$STACKS_PATH"
|
mkdir -p "$INSTALL_PATH" "$STACKS_PATH"
|
||||||
@@ -167,7 +112,7 @@ if [[ "${type:-}" == "update" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
check_proxmox_host
|
confirm_not_pve_host
|
||||||
get_lxc_ip
|
get_lxc_ip
|
||||||
|
|
||||||
# Check if already installed
|
# Check if already installed
|
||||||
|
|||||||
+2
-57
@@ -65,66 +65,11 @@ function update() {
|
|||||||
exit
|
exit
|
||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# PROXMOX HOST CHECK
|
|
||||||
# ==============================================================================
|
|
||||||
function check_proxmox_host() {
|
|
||||||
if command -v pveversion &>/dev/null; then
|
|
||||||
msg_error "Running on the Proxmox host is NOT recommended!"
|
|
||||||
msg_error "This should be executed inside an LXC container."
|
|
||||||
echo ""
|
|
||||||
echo -n "${TAB}Continue anyway? (y/N): "
|
|
||||||
read -r confirm
|
|
||||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_warn "Aborted. Please run this inside an LXC container."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
msg_warn "Proceeding on Proxmox host at your own risk!"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# CHECK / INSTALL DOCKER
|
|
||||||
# ==============================================================================
|
|
||||||
function check_or_install_docker() {
|
|
||||||
if command -v docker &>/dev/null; then
|
|
||||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
|
|
||||||
if docker compose version &>/dev/null; then
|
|
||||||
msg_ok "Docker Compose is available"
|
|
||||||
else
|
|
||||||
msg_error "Docker Compose plugin is not available. Please install it."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_warn "Docker is not installed."
|
|
||||||
echo -n "${TAB}Install Docker now? (y/N): "
|
|
||||||
read -r install_docker_prompt
|
|
||||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_error "Docker is required for ${APP}. Exiting."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Installing Docker"
|
|
||||||
if [[ -f /etc/alpine-release ]]; then
|
|
||||||
$STD apk add docker docker-cli-compose
|
|
||||||
$STD rc-service docker start
|
|
||||||
$STD rc-update add docker default
|
|
||||||
else
|
|
||||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
|
||||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
|
||||||
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
|
||||||
$STD sh <(curl -fsSL https://get.docker.com)
|
|
||||||
fi
|
|
||||||
msg_ok "Installed Docker"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# INSTALL
|
# INSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
function install() {
|
function install() {
|
||||||
check_or_install_docker
|
ensure_docker
|
||||||
|
|
||||||
msg_info "Installing dependencies"
|
msg_info "Installing dependencies"
|
||||||
if [[ -f /etc/alpine-release ]]; then
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
@@ -170,7 +115,7 @@ if [[ "${type:-}" == "update" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
check_proxmox_host
|
confirm_not_pve_host
|
||||||
get_lxc_ip
|
get_lxc_ip
|
||||||
|
|
||||||
# Check if already installed
|
# Check if already installed
|
||||||
|
|||||||
@@ -5,55 +5,51 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://github.com/filebrowserspace/quantum
|
# Source: https://github.com/filebrowserspace/quantum
|
||||||
|
|
||||||
function header_info() {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
_______ __ ____ ____ __
|
|
||||||
/ ____(_) /__ / __ )_________ _ __________ _____ / __ \__ ______ _____ / /___ ______ ___
|
|
||||||
/ /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/ / / / / / / / __ `/ __ \/ __/ / / / __ `__ \
|
|
||||||
/ __/ / / / __/ /_/ / / / /_/ / |/ |/ (__ ) __/ / / /_/ / /_/ / /_/ / / / / /_/ /_/ / / / / / /
|
|
||||||
/_/ /_/_/\___/_____/_/ \____/|__/|__/____/\___/_/ \___\_\__,_/\__,_/_/ /_/\__/\__,_/_/ /_/ /_/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
YW=$(echo "\033[33m")
|
|
||||||
GN=$(echo "\033[1;92m")
|
|
||||||
RD=$(echo "\033[01;31m")
|
|
||||||
BL=$(echo "\033[36m")
|
|
||||||
CL=$(echo "\033[m")
|
|
||||||
CM="${GN}✔️${CL}"
|
|
||||||
CROSS="${RD}✖️${CL}"
|
|
||||||
INFO="${BL}ℹ️${CL}"
|
|
||||||
|
|
||||||
APP="FileBrowser Quantum"
|
APP="FileBrowser Quantum"
|
||||||
|
APP_TYPE="addon"
|
||||||
INSTALL_PATH="/usr/local/bin/filebrowser"
|
INSTALL_PATH="/usr/local/bin/filebrowser"
|
||||||
CONFIG_PATH="/usr/local/community-scripts/fq-config.yaml"
|
CONFIG_PATH="/usr/local/community-scripts/fq-config.yaml"
|
||||||
DEFAULT_PORT=8080
|
DEFAULT_PORT=8080
|
||||||
SRC_DIR="/"
|
SRC_DIR="/"
|
||||||
TMP_BIN="/tmp/filebrowser.$$"
|
|
||||||
|
|
||||||
# Telemetry
|
if ! command -v curl &>/dev/null; then
|
||||||
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
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/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/api.func) 2>/dev/null || true
|
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"
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "filebrowser-quantum" "addon"
|
||||||
|
|
||||||
# Get primary IP
|
# Enable error handling
|
||||||
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
set -Eeuo pipefail
|
||||||
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
trap 'error_handler' ERR
|
||||||
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
|
|
||||||
[[ -z "$IP" ]] && IP="127.0.0.1"
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
|
load_functions
|
||||||
|
|
||||||
|
header_info
|
||||||
|
get_lxc_ip
|
||||||
|
IP="$LOCAL_IP"
|
||||||
|
|
||||||
# Proxmox Host Warning
|
# Proxmox Host Warning
|
||||||
if [[ -d "/etc/pve" ]]; then
|
if [[ -d "/etc/pve" ]]; then
|
||||||
echo -e "${RD}⚠️ Warning: Running this addon directly on the Proxmox host is not recommended!${CL}"
|
msg_warn "Running this addon directly on the Proxmox host is not recommended!"
|
||||||
echo -e "${YW} Only the boot disk will be visible — passthrough drives will not be indexed.${CL}"
|
msg_warn "Only the boot disk will be visible — passthrough drives will not be indexed."
|
||||||
echo -e "${YW} This causes incorrect disk usage stats and incomplete file browsing.${CL}"
|
msg_warn "This causes incorrect disk usage stats and incomplete file browsing."
|
||||||
echo -e "${YW} Run this addon inside an LXC or VM instead and mount your drives there.${CL}"
|
msg_warn "Run this addon inside an LXC or VM instead and mount your drives there."
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Continue anyway on the Proxmox host? (y/N): "
|
echo -n "${TAB}Continue anyway on the Proxmox host? (y/N): "
|
||||||
read -r host_confirm
|
read -r host_confirm
|
||||||
if [[ ! "${host_confirm,,}" =~ ^(y|yes)$ ]]; then
|
if [[ ! "${host_confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||||
echo -e "${YW}Aborted.${CL}"
|
msg_error "Aborted."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -66,18 +62,12 @@ if [[ -f "/etc/alpine-release" ]]; then
|
|||||||
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 install -y"
|
||||||
else
|
else
|
||||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
msg_error "Unsupported OS detected. Exiting."
|
||||||
exit 238
|
exit 238
|
||||||
fi
|
fi
|
||||||
|
|
||||||
header_info
|
|
||||||
|
|
||||||
function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
|
|
||||||
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
|
|
||||||
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
|
|
||||||
|
|
||||||
# Detect legacy FileBrowser installation
|
# Detect legacy FileBrowser installation
|
||||||
LEGACY_DB="/usr/local/community-scripts/filebrowser.db"
|
LEGACY_DB="/usr/local/community-scripts/filebrowser.db"
|
||||||
LEGACY_BIN="/usr/local/bin/filebrowser"
|
LEGACY_BIN="/usr/local/bin/filebrowser"
|
||||||
@@ -85,80 +75,82 @@ LEGACY_SERVICE_DEB="/etc/systemd/system/filebrowser.service"
|
|||||||
LEGACY_SERVICE_ALP="/etc/init.d/filebrowser"
|
LEGACY_SERVICE_ALP="/etc/init.d/filebrowser"
|
||||||
|
|
||||||
if [[ -f "$LEGACY_DB" || -f "$LEGACY_BIN" && ! -f "$CONFIG_PATH" ]]; then
|
if [[ -f "$LEGACY_DB" || -f "$LEGACY_BIN" && ! -f "$CONFIG_PATH" ]]; then
|
||||||
echo -e "${YW}⚠️ Detected legacy FileBrowser installation.${CL}"
|
msg_warn "Detected legacy FileBrowser installation."
|
||||||
echo -n "Uninstall legacy FileBrowser and continue with Quantum install? (y/n): "
|
echo -n "${TAB}Uninstall legacy FileBrowser and continue with Quantum install? (y/n): "
|
||||||
read -r remove_legacy
|
read -r remove_legacy
|
||||||
if [[ "${remove_legacy,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${remove_legacy,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Uninstalling legacy FileBrowser"
|
msg_info "Uninstalling legacy FileBrowser"
|
||||||
if [[ -f "$LEGACY_SERVICE_DEB" ]]; then
|
if [[ -f "$LEGACY_SERVICE_DEB" ]]; then
|
||||||
systemctl disable --now filebrowser.service &>/dev/null
|
systemctl disable --now filebrowser.service &>/dev/null || true
|
||||||
rm -f "$LEGACY_SERVICE_DEB"
|
rm -f "$LEGACY_SERVICE_DEB"
|
||||||
elif [[ -f "$LEGACY_SERVICE_ALP" ]]; then
|
elif [[ -f "$LEGACY_SERVICE_ALP" ]]; then
|
||||||
rc-service filebrowser stop &>/dev/null
|
rc-service filebrowser stop &>/dev/null || true
|
||||||
rc-update del filebrowser &>/dev/null
|
rc-update del filebrowser &>/dev/null || true
|
||||||
rm -f "$LEGACY_SERVICE_ALP"
|
rm -f "$LEGACY_SERVICE_ALP"
|
||||||
fi
|
fi
|
||||||
rm -f "$LEGACY_BIN" "$LEGACY_DB"
|
rm -f "$LEGACY_BIN" "$LEGACY_DB"
|
||||||
msg_ok "Legacy FileBrowser removed"
|
msg_ok "Legacy FileBrowser removed"
|
||||||
else
|
else
|
||||||
echo -e "${YW}❌ Installation aborted by user.${CL}"
|
msg_error "Installation aborted by user."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Existing installation
|
# Existing installation
|
||||||
if [[ -f "$INSTALL_PATH" ]]; then
|
if [[ -f "$INSTALL_PATH" ]]; then
|
||||||
echo -e "${YW}⚠️ ${APP} is already installed.${CL}"
|
msg_warn "${APP} is already installed."
|
||||||
echo -n "Uninstall ${APP}? (y/N): "
|
echo -n "${TAB}Uninstall ${APP}? (y/N): "
|
||||||
read -r uninstall_prompt
|
read -r 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 || true
|
||||||
rm -f "$SERVICE_PATH"
|
rm -f "$SERVICE_PATH"
|
||||||
else
|
else
|
||||||
rc-service filebrowser stop &>/dev/null
|
rc-service filebrowser stop &>/dev/null || true
|
||||||
rc-update del filebrowser &>/dev/null
|
rc-update del filebrowser &>/dev/null || true
|
||||||
rm -f "$SERVICE_PATH"
|
rm -f "$SERVICE_PATH"
|
||||||
fi
|
fi
|
||||||
rm -f "$INSTALL_PATH" "$CONFIG_PATH"
|
rm -f "$INSTALL_PATH" "$CONFIG_PATH" "$HOME/.filebrowser-quantum"
|
||||||
msg_ok "${APP} has been uninstalled."
|
msg_ok "${APP} has been uninstalled."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -n "Update ${APP}? (y/N): "
|
echo -n "${TAB}Update ${APP}? (y/N): "
|
||||||
read -r update_prompt
|
read -r update_prompt
|
||||||
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
msg_info "Updating ${APP}"
|
if check_for_gh_release "filebrowser-quantum" "gtsteffaniak/filebrowser"; then
|
||||||
if ! command -v curl &>/dev/null; then $PKG_MANAGER curl &>/dev/null; fi
|
msg_info "Updating ${APP}"
|
||||||
curl -fsSL https://github.com/gtsteffaniak/filebrowser/releases/latest/download/linux-amd64-filebrowser -o "$TMP_BIN"
|
if ! command -v curl &>/dev/null; then $STD $PKG_MANAGER curl; fi
|
||||||
chmod +x "$TMP_BIN"
|
fetch_and_deploy_gh_release "filebrowser-quantum" "gtsteffaniak/filebrowser" "singlefile" "latest" "/usr/local/bin" "linux-$(arch_resolve)-filebrowser"
|
||||||
mv -f "$TMP_BIN" /usr/local/bin/filebrowser
|
mv -f /usr/local/bin/filebrowser-quantum "$INSTALL_PATH"
|
||||||
msg_ok "Updated ${APP}"
|
msg_ok "Updated ${APP}"
|
||||||
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}"
|
msg_warn "Update skipped. Exiting."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${YW}⚠️ ${APP} is not installed.${CL}"
|
msg_warn "${APP} is not installed."
|
||||||
echo -n "Enter port number (Default: ${DEFAULT_PORT}): "
|
echo -n "${TAB}Enter port number (Default: ${DEFAULT_PORT}): "
|
||||||
read -r PORT
|
read -r PORT
|
||||||
PORT=${PORT:-$DEFAULT_PORT}
|
PORT=${PORT:-$DEFAULT_PORT}
|
||||||
|
|
||||||
echo -n "Install ${APP}? (y/n): "
|
echo -n "${TAB}Install ${APP}? (y/n): "
|
||||||
read -r install_prompt
|
read -r install_prompt
|
||||||
if ! [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
if ! [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
||||||
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
|
msg_warn "Installation skipped. Exiting."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
msg_info "Installing ${APP} on ${OS}"
|
msg_info "Installing ${APP} on ${OS}"
|
||||||
$PKG_MANAGER curl ffmpeg &>/dev/null
|
$STD $PKG_MANAGER \
|
||||||
curl -fsSL https://github.com/gtsteffaniak/filebrowser/releases/latest/download/linux-amd64-filebrowser -o "$TMP_BIN"
|
curl \
|
||||||
chmod +x "$TMP_BIN"
|
ffmpeg
|
||||||
mv -f "$TMP_BIN" /usr/local/bin/filebrowser
|
fetch_and_deploy_gh_release "filebrowser-quantum" "gtsteffaniak/filebrowser" "singlefile" "latest" "/usr/local/bin" "linux-$(arch_resolve)-filebrowser"
|
||||||
|
mv -f /usr/local/bin/filebrowser-quantum "$INSTALL_PATH"
|
||||||
msg_ok "Installed ${APP}"
|
msg_ok "Installed ${APP}"
|
||||||
|
|
||||||
msg_info "Preparing configuration directory"
|
msg_info "Preparing configuration directory"
|
||||||
@@ -167,7 +159,7 @@ chown root:root /usr/local/community-scripts
|
|||||||
chmod 755 /usr/local/community-scripts
|
chmod 755 /usr/local/community-scripts
|
||||||
msg_ok "Directory prepared"
|
msg_ok "Directory prepared"
|
||||||
|
|
||||||
echo -n "Use No Authentication? (y/N): "
|
echo -n "${TAB}Use No Authentication? (y/N): "
|
||||||
read -r noauth_prompt
|
read -r noauth_prompt
|
||||||
|
|
||||||
# === YAML CONFIG GENERATION ===
|
# === YAML CONFIG GENERATION ===
|
||||||
@@ -251,9 +243,9 @@ depend() {
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
chmod +x "$SERVICE_PATH"
|
chmod +x "$SERVICE_PATH"
|
||||||
rc-update add filebrowser default &>/dev/null
|
$STD rc-update add filebrowser default
|
||||||
rc-service filebrowser start &>/dev/null
|
$STD rc-service filebrowser start
|
||||||
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}"
|
msg_ok "${APP} is reachable at: ${BL}http://${IP}:${PORT}${CL}"
|
||||||
|
|||||||
+62
-77
@@ -5,53 +5,50 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://filebrowser.org/ | Github: https://github.com/filebrowser/filebrowser
|
# Source: https://filebrowser.org/ | Github: https://github.com/filebrowser/filebrowser
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
_______ __ ____
|
|
||||||
/ ____(_) /__ / __ )_________ _ __________ _____
|
|
||||||
/ /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/
|
|
||||||
/ __/ / / / __/ /_/ / / / /_/ / |/ |/ (__ ) __/ /
|
|
||||||
/_/ /_/_/\___/_____/_/ \____/|__/|__/____/\___/_/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
YW=$(echo "\033[33m")
|
|
||||||
GN=$(echo "\033[1;92m")
|
|
||||||
RD=$(echo "\033[01;31m")
|
|
||||||
BL=$(echo "\033[36m")
|
|
||||||
CL=$(echo "\033[m")
|
|
||||||
CM="${GN}✔️${CL}"
|
|
||||||
CROSS="${RD}✖️${CL}"
|
|
||||||
INFO="${BL}ℹ️${CL}"
|
|
||||||
|
|
||||||
APP="FileBrowser"
|
APP="FileBrowser"
|
||||||
|
APP_TYPE="addon"
|
||||||
INSTALL_PATH="/usr/local/bin/filebrowser"
|
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
|
if ! command -v curl &>/dev/null; then
|
||||||
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
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/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/api.func) 2>/dev/null || true
|
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"
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "filebrowser" "addon"
|
||||||
|
|
||||||
# Get first non-loopback IP & Detect primary network interface dynamically
|
# Enable error handling
|
||||||
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}')
|
set -Eeuo pipefail
|
||||||
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1)
|
trap 'error_handler' ERR
|
||||||
|
|
||||||
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
[[ -z "$IP" ]] && IP="127.0.0.1"
|
load_functions
|
||||||
|
|
||||||
|
header_info
|
||||||
|
get_lxc_ip
|
||||||
|
IP="$LOCAL_IP"
|
||||||
|
|
||||||
# Proxmox Host Warning
|
# Proxmox Host Warning
|
||||||
if [[ -d "/etc/pve" ]]; then
|
if [[ -d "/etc/pve" ]]; then
|
||||||
echo -e "${RD}⚠️ Warning: Running this addon directly on the Proxmox host is not recommended!${CL}"
|
msg_warn "Running this addon directly on the Proxmox host is not recommended!"
|
||||||
echo -e "${YW} Only the boot disk will be visible — passthrough drives will not be indexed.${CL}"
|
msg_warn "Only the boot disk will be visible — passthrough drives will not be indexed."
|
||||||
echo -e "${YW} This causes incorrect disk usage stats and incomplete file browsing.${CL}"
|
msg_warn "This causes incorrect disk usage stats and incomplete file browsing."
|
||||||
echo -e "${YW} Run this addon inside an LXC or VM instead and mount your drives there.${CL}"
|
msg_warn "Run this addon inside an LXC or VM instead and mount your drives there."
|
||||||
echo ""
|
echo ""
|
||||||
echo -n "Continue anyway on the Proxmox host? (y/N): "
|
echo -n "${TAB}Continue anyway on the Proxmox host? (y/N): "
|
||||||
read -r host_confirm
|
read -r host_confirm
|
||||||
if [[ ! "${host_confirm,,}" =~ ^(y|yes)$ ]]; then
|
if [[ ! "${host_confirm,,}" =~ ^(y|yes)$ ]]; then
|
||||||
echo -e "${YW}Aborted.${CL}"
|
msg_error "Aborted."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@@ -64,71 +61,59 @@ if [[ -f "/etc/alpine-release" ]]; then
|
|||||||
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 install -y"
|
||||||
else
|
else
|
||||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
msg_error "Unsupported OS detected. Exiting."
|
||||||
exit 238
|
exit 238
|
||||||
fi
|
fi
|
||||||
|
|
||||||
header_info
|
|
||||||
|
|
||||||
function msg_info() {
|
|
||||||
local msg="$1"
|
|
||||||
echo -e "${INFO} ${YW}${msg}...${CL}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function msg_ok() {
|
|
||||||
local msg="$1"
|
|
||||||
echo -e "${CM} ${GN}${msg}${CL}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function msg_error() {
|
|
||||||
local msg="$1"
|
|
||||||
echo -e "${CROSS} ${RD}${msg}${CL}"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -f "$INSTALL_PATH" ]; then
|
if [ -f "$INSTALL_PATH" ]; then
|
||||||
echo -e "${YW}⚠️ ${APP} is already installed.${CL}"
|
msg_warn "${APP} is already installed."
|
||||||
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 || true
|
||||||
rm -f "$SERVICE_PATH"
|
rm -f "$SERVICE_PATH"
|
||||||
else
|
else
|
||||||
rc-service filebrowser stop &>/dev/null
|
rc-service filebrowser stop &>/dev/null || true
|
||||||
rc-update del filebrowser &>/dev/null
|
rc-update del filebrowser &>/dev/null || true
|
||||||
rm -f "$SERVICE_PATH"
|
rm -f "$SERVICE_PATH"
|
||||||
fi
|
fi
|
||||||
rm -f "$INSTALL_PATH" "$DB_PATH"
|
rm -f "$INSTALL_PATH" "$DB_PATH" "$HOME/.filebrowser"
|
||||||
msg_ok "${APP} has been uninstalled."
|
msg_ok "${APP} has been uninstalled."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
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}"
|
if check_for_gh_release "filebrowser" "filebrowser/filebrowser"; then
|
||||||
if ! command -v curl &>/dev/null; then $PKG_MANAGER curl &>/dev/null; fi
|
msg_info "Updating ${APP}"
|
||||||
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
|
fetch_and_deploy_gh_release "filebrowser" "filebrowser/filebrowser" "prebuild" "latest" "/opt/filebrowser-dist" "linux-$(arch_resolve)-filebrowser.tar.gz"
|
||||||
chmod +x "$INSTALL_PATH"
|
install -m 755 /opt/filebrowser-dist/filebrowser "$INSTALL_PATH"
|
||||||
msg_ok "Updated ${APP}"
|
rm -rf /opt/filebrowser-dist
|
||||||
|
msg_ok "Updated ${APP}"
|
||||||
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}"
|
msg_warn "Update skipped. Exiting."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${YW}⚠️ ${APP} is not installed.${CL}"
|
msg_warn "${APP} is not installed."
|
||||||
read -r -p "Enter port number (Default: ${DEFAULT_PORT}): " PORT
|
read -r -p "Enter port number (Default: ${DEFAULT_PORT}): " PORT
|
||||||
PORT=${PORT:-$DEFAULT_PORT}
|
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
|
$STD $PKG_MANAGER \
|
||||||
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null
|
tar \
|
||||||
chmod +x "$INSTALL_PATH"
|
curl
|
||||||
|
fetch_and_deploy_gh_release "filebrowser" "filebrowser/filebrowser" "prebuild" "latest" "/opt/filebrowser-dist" "linux-$(arch_resolve)-filebrowser.tar.gz"
|
||||||
|
install -m 755 /opt/filebrowser-dist/filebrowser "$INSTALL_PATH"
|
||||||
|
rm -rf /opt/filebrowser-dist
|
||||||
msg_ok "Installed ${APP}"
|
msg_ok "Installed ${APP}"
|
||||||
|
|
||||||
msg_info "Creating FileBrowser directory"
|
msg_info "Creating FileBrowser directory"
|
||||||
@@ -144,19 +129,19 @@ if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
|
|||||||
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
|
$STD filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
|
||||||
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
$STD filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
|
||||||
filebrowser config set --auth.method=noauth --database "$DB_PATH" &>/dev/null
|
$STD filebrowser config set --auth.method=noauth --database "$DB_PATH"
|
||||||
if ! filebrowser users update 1 --perm.admin --database "$DB_PATH" &>/dev/null; then
|
if ! filebrowser users update 1 --perm.admin --database "$DB_PATH" &>/dev/null; then
|
||||||
filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH" &>/dev/null
|
$STD filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH"
|
||||||
fi
|
fi
|
||||||
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
|
$STD filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
|
||||||
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null
|
$STD filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
|
||||||
filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH" &>/dev/null
|
$STD filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH"
|
||||||
msg_ok "Default authentication configured (admin:community-scripts.org)"
|
msg_ok "Default authentication configured (admin:community-scripts.org)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -194,13 +179,13 @@ depend() {
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
chmod +x "$SERVICE_PATH"
|
chmod +x "$SERVICE_PATH"
|
||||||
rc-update add filebrowser default &>/dev/null
|
$STD rc-update add filebrowser default
|
||||||
rc-service filebrowser start &>/dev/null
|
$STD rc-service filebrowser start
|
||||||
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}"
|
msg_ok "${APP} is reachable at: ${BL}http://${IP}:${PORT}${CL}"
|
||||||
else
|
else
|
||||||
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}"
|
msg_warn "Installation skipped. Exiting."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|||||||
+41
-50
@@ -5,55 +5,47 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://nicolargo.github.io/glances/ | Github: https://github.com/nicolargo/glances
|
# Source: https://nicolargo.github.io/glances/ | Github: https://github.com/nicolargo/glances
|
||||||
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
________
|
|
||||||
/ ____/ /___ _____ ________ _____
|
|
||||||
/ / __/ / __ `/ __ \/ ___/ _ \/ ___/
|
|
||||||
/ /_/ / / /_/ / / / / /__/ __(__ )
|
|
||||||
\____/_/\__,_/_/ /_/\___/\___/____/
|
|
||||||
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
APP="Glances"
|
APP="Glances"
|
||||||
YW=$(echo "\033[33m")
|
APP_TYPE="addon"
|
||||||
GN=$(echo "\033[1;92m")
|
|
||||||
RD=$(echo "\033[01;31m")
|
|
||||||
BL=$(echo "\033[36m")
|
|
||||||
CL=$(echo "\033[m")
|
|
||||||
CM="${GN}✔️${CL}"
|
|
||||||
CROSS="${RD}✖️${CL}"
|
|
||||||
INFO="${BL}ℹ️${CL}"
|
|
||||||
|
|
||||||
function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
|
if ! command -v curl &>/dev/null; then
|
||||||
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
|
apk update >/dev/null 2>&1
|
||||||
# Telemetry
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
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/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/api.func) 2>/dev/null || true
|
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"
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "glances" "addon"
|
||||||
|
|
||||||
get_lxc_ip() {
|
# Enable error handling
|
||||||
if command -v hostname >/dev/null 2>&1 && hostname -I 2>/dev/null; then
|
set -Eeuo pipefail
|
||||||
hostname -I | awk '{print $1}'
|
trap 'error_handler' ERR
|
||||||
elif command -v ip >/dev/null 2>&1; then
|
|
||||||
ip -4 addr show scope global | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
else
|
load_functions
|
||||||
echo "127.0.0.1"
|
|
||||||
fi
|
header_info
|
||||||
}
|
get_lxc_ip
|
||||||
IP=$(get_lxc_ip)
|
IP="$LOCAL_IP"
|
||||||
|
|
||||||
install_glances_debian() {
|
install_glances_debian() {
|
||||||
msg_info "Installing dependencies"
|
msg_info "Installing dependencies"
|
||||||
apt-get update >/dev/null 2>&1
|
$STD apt update
|
||||||
apt-get install -y gcc lm-sensors wireless-tools curl >/dev/null 2>&1
|
$STD apt install -y \
|
||||||
|
gcc \
|
||||||
|
lm-sensors \
|
||||||
|
wireless-tools \
|
||||||
|
curl
|
||||||
msg_ok "Installed dependencies"
|
msg_ok "Installed dependencies"
|
||||||
|
|
||||||
msg_info "Setting up Python + uv"
|
msg_info "Setting up Python + uv"
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
|
||||||
setup_uv PYTHON_VERSION="3.12"
|
setup_uv PYTHON_VERSION="3.12"
|
||||||
msg_ok "Setup Python + uv"
|
msg_ok "Setup Python + uv"
|
||||||
|
|
||||||
@@ -61,10 +53,10 @@ install_glances_debian() {
|
|||||||
cd /opt
|
cd /opt
|
||||||
mkdir -p glances
|
mkdir -p glances
|
||||||
cd glances
|
cd glances
|
||||||
uv venv --clear
|
$STD uv venv --clear
|
||||||
source .venv/bin/activate >/dev/null 2>&1
|
source .venv/bin/activate >/dev/null 2>&1
|
||||||
uv pip install --upgrade pip wheel setuptools >/dev/null 2>&1
|
$STD uv pip install --upgrade pip wheel setuptools
|
||||||
uv pip install "glances[web]" >/dev/null 2>&1
|
$STD uv pip install "glances[web]"
|
||||||
deactivate
|
deactivate
|
||||||
msg_ok "Installed $APP"
|
msg_ok "Installed $APP"
|
||||||
|
|
||||||
@@ -86,7 +78,7 @@ EOF
|
|||||||
systemctl enable -q --now glances
|
systemctl enable -q --now glances
|
||||||
msg_ok "Created systemd service"
|
msg_ok "Created systemd service"
|
||||||
|
|
||||||
echo -e "\n$APP is now running at: http://$IP:61208\n"
|
msg_ok "$APP is now running at: http://${IP}:61208"
|
||||||
}
|
}
|
||||||
|
|
||||||
# update on Debian/Ubuntu
|
# update on Debian/Ubuntu
|
||||||
@@ -98,7 +90,7 @@ update_glances_debian() {
|
|||||||
msg_info "Updating $APP"
|
msg_info "Updating $APP"
|
||||||
cd /opt/glances
|
cd /opt/glances
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
uv pip install --upgrade "glances[web]" >/dev/null 2>&1
|
$STD uv pip install --upgrade "glances[web]"
|
||||||
deactivate
|
deactivate
|
||||||
systemctl restart glances
|
systemctl restart glances
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
@@ -116,14 +108,13 @@ uninstall_glances_debian() {
|
|||||||
# install on Alpine
|
# install on Alpine
|
||||||
install_glances_alpine() {
|
install_glances_alpine() {
|
||||||
msg_info "Installing dependencies"
|
msg_info "Installing dependencies"
|
||||||
apk update >/dev/null 2>&1
|
$STD apk update
|
||||||
$STD apk add --no-cache \
|
$STD apk add --no-cache \
|
||||||
gcc musl-dev linux-headers python3-dev \
|
gcc musl-dev linux-headers python3-dev \
|
||||||
python3 py3-pip py3-virtualenv lm-sensors wireless-tools curl >/dev/null 2>&1
|
python3 py3-pip py3-virtualenv lm-sensors wireless-tools curl
|
||||||
msg_ok "Installed dependencies"
|
msg_ok "Installed dependencies"
|
||||||
|
|
||||||
msg_info "Setting up Python + uv"
|
msg_info "Setting up Python + uv"
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
|
|
||||||
setup_uv PYTHON_VERSION="3.12"
|
setup_uv PYTHON_VERSION="3.12"
|
||||||
msg_ok "Setup Python + uv"
|
msg_ok "Setup Python + uv"
|
||||||
|
|
||||||
@@ -131,10 +122,10 @@ install_glances_alpine() {
|
|||||||
cd /opt
|
cd /opt
|
||||||
mkdir -p glances
|
mkdir -p glances
|
||||||
cd glances
|
cd glances
|
||||||
uv venv --clear
|
$STD uv venv --clear
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
uv pip install --upgrade pip wheel setuptools >/dev/null 2>&1
|
$STD uv pip install --upgrade pip wheel setuptools
|
||||||
uv pip install "glances[web]" >/dev/null 2>&1
|
$STD uv pip install "glances[web]"
|
||||||
deactivate
|
deactivate
|
||||||
msg_ok "Installed $APP"
|
msg_ok "Installed $APP"
|
||||||
|
|
||||||
@@ -165,7 +156,7 @@ update_glances_alpine() {
|
|||||||
msg_info "Updating $APP"
|
msg_info "Updating $APP"
|
||||||
cd /opt/glances
|
cd /opt/glances
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
uv pip install --upgrade "glances[web]" >/dev/null 2>&1
|
$STD uv pip install --upgrade "glances[web]"
|
||||||
deactivate
|
deactivate
|
||||||
rc-service glances restart
|
rc-service glances restart
|
||||||
msg_ok "Updated successfully!"
|
msg_ok "Updated successfully!"
|
||||||
|
|||||||
+10
-16
@@ -7,8 +7,13 @@
|
|||||||
|
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
apt-get update >/dev/null 2>&1
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
apt-get install -y curl >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
fi
|
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)
|
||||||
@@ -19,7 +24,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
|
|||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
init_tool_telemetry "" "addon"
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "homebrew" "addon"
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
@@ -29,18 +34,7 @@ APP="homebrew"
|
|||||||
APP_TYPE="tools"
|
APP_TYPE="tools"
|
||||||
INSTALL_PATH="/home/linuxbrew/.linuxbrew"
|
INSTALL_PATH="/home/linuxbrew/.linuxbrew"
|
||||||
|
|
||||||
# ==============================================================================
|
require_debian_like
|
||||||
# OS DETECTION
|
|
||||||
# ==============================================================================
|
|
||||||
if [[ -f "/etc/alpine-release" ]]; then
|
|
||||||
echo -e "${CROSS} Alpine is not supported by Homebrew. Exiting."
|
|
||||||
exit 1
|
|
||||||
elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
|
|
||||||
OS="Debian"
|
|
||||||
else
|
|
||||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# UNINSTALL
|
# UNINSTALL
|
||||||
@@ -81,7 +75,7 @@ function install() {
|
|||||||
msg_ok "Created user 'brew'"
|
msg_ok "Created user 'brew'"
|
||||||
else
|
else
|
||||||
msg_error "Cannot install Homebrew without a non-root user. Exiting."
|
msg_error "Cannot install Homebrew without a non-root user. Exiting."
|
||||||
exit 1
|
exit 254
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
msg_ok "Detected User: $BREW_USER"
|
msg_ok "Detected User: $BREW_USER"
|
||||||
|
|||||||
@@ -7,8 +7,13 @@
|
|||||||
|
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
apt-get update >/dev/null 2>&1
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
apt-get install -y curl >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
fi
|
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)
|
||||||
@@ -27,39 +32,12 @@ APP="Immich Public Proxy"
|
|||||||
APP_TYPE="addon"
|
APP_TYPE="addon"
|
||||||
INSTALL_PATH="/opt/immich-proxy"
|
INSTALL_PATH="/opt/immich-proxy"
|
||||||
CONFIG_PATH="/opt/immich-proxy/app"
|
CONFIG_PATH="/opt/immich-proxy/app"
|
||||||
|
SERVICE_PATH="/etc/systemd/system/immich-proxy.service"
|
||||||
DEFAULT_PORT=3000
|
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
|
||||||
|
require_debian_like
|
||||||
# ==============================================================================
|
|
||||||
# HEADER
|
|
||||||
# ==============================================================================
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
____ _ __ ____
|
|
||||||
/ _/___ ___ ____ ___ (_)____/ /_ / __ \_________ _ ____ __
|
|
||||||
/ // __ `__ \/ __ `__ \/ / ___/ __ \______/ /_/ / ___/ __ \| |/_/ / / /
|
|
||||||
_/ // / / / / / / / / / / / /__/ / / /_____/ ____/ / / /_/ /> </ /_/ /
|
|
||||||
/___/_/ /_/ /_/_/ /_/ /_/_/\___/_/ /_/ /_/ /_/ \____/_/|_|\__, /
|
|
||||||
/____/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# OS DETECTION
|
|
||||||
# ==============================================================================
|
|
||||||
if [[ -f "/etc/alpine-release" ]]; then
|
|
||||||
msg_error "Alpine is not supported for ${APP}. Use Debian."
|
|
||||||
exit 238
|
|
||||||
elif [[ -f "/etc/debian_version" ]]; then
|
|
||||||
OS="Debian"
|
|
||||||
SERVICE_PATH="/etc/systemd/system/immich-proxy.service"
|
|
||||||
else
|
|
||||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
|
||||||
exit 238
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# UNINSTALL
|
# UNINSTALL
|
||||||
@@ -83,19 +61,13 @@ function update() {
|
|||||||
systemctl stop immich-proxy.service &>/dev/null || true
|
systemctl stop immich-proxy.service &>/dev/null || true
|
||||||
msg_ok "Stopped service"
|
msg_ok "Stopped service"
|
||||||
|
|
||||||
msg_info "Backing up configuration"
|
BACKUP_DIR="/opt/immich-public-proxy_backup"
|
||||||
cp "$CONFIG_PATH"/.env /tmp/ipp.env.bak 2>/dev/null || true
|
create_backup "$CONFIG_PATH"/.env "$CONFIG_PATH"/config.json
|
||||||
cp "$CONFIG_PATH"/config.json /tmp/ipp.config.json.bak 2>/dev/null || true
|
|
||||||
msg_ok "Backed up configuration"
|
|
||||||
|
|
||||||
NODE_VERSION="24" setup_nodejs
|
NODE_VERSION="24" setup_nodejs
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH"
|
||||||
|
|
||||||
msg_info "Restoring configuration"
|
restore_backup
|
||||||
cp /tmp/ipp.env.bak "$CONFIG_PATH"/.env 2>/dev/null || true
|
|
||||||
cp /tmp/ipp.config.json.bak "$CONFIG_PATH"/config.json 2>/dev/null || true
|
|
||||||
rm -f /tmp/ipp.*.bak
|
|
||||||
msg_ok "Restored configuration"
|
|
||||||
|
|
||||||
msg_info "Installing dependencies"
|
msg_info "Installing dependencies"
|
||||||
cd "$CONFIG_PATH"
|
cd "$CONFIG_PATH"
|
||||||
|
|||||||
+12
-38
@@ -7,8 +7,13 @@
|
|||||||
|
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
apt-get update >/dev/null 2>&1
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
apt-get install -y curl >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
fi
|
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)
|
||||||
@@ -27,39 +32,12 @@ APP="Jellystat"
|
|||||||
APP_TYPE="addon"
|
APP_TYPE="addon"
|
||||||
INSTALL_PATH="/opt/jellystat"
|
INSTALL_PATH="/opt/jellystat"
|
||||||
CONFIG_PATH="/opt/jellystat/.env"
|
CONFIG_PATH="/opt/jellystat/.env"
|
||||||
|
SERVICE_PATH="/etc/systemd/system/jellystat.service"
|
||||||
DEFAULT_PORT=3000
|
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
|
||||||
|
require_debian_like
|
||||||
# ==============================================================================
|
|
||||||
# HEADER
|
|
||||||
# ==============================================================================
|
|
||||||
function header_info {
|
|
||||||
clear
|
|
||||||
cat <<"EOF"
|
|
||||||
__ ____ __ __
|
|
||||||
/ /__ / / /_ _______/ /_____ _/ /_
|
|
||||||
__ / / _ \/ / / / / / ___/ __/ __ `/ __/
|
|
||||||
/ /_/ / __/ / / /_/ (__ ) /_/ /_/ / /_
|
|
||||||
\____/\___/_/_/\__, /____/\__/\__,_/\__/
|
|
||||||
/____/
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# OS DETECTION
|
|
||||||
# ==============================================================================
|
|
||||||
if [[ -f "/etc/alpine-release" ]]; then
|
|
||||||
msg_error "Alpine is not supported for ${APP}. Use Debian/Ubuntu."
|
|
||||||
exit 238
|
|
||||||
elif [[ -f "/etc/debian_version" ]]; then
|
|
||||||
OS="Debian"
|
|
||||||
SERVICE_PATH="/etc/systemd/system/jellystat.service"
|
|
||||||
else
|
|
||||||
echo -e "${CROSS} Unsupported OS detected. Exiting."
|
|
||||||
exit 238
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# UNINSTALL
|
# UNINSTALL
|
||||||
@@ -102,16 +80,12 @@ function update() {
|
|||||||
systemctl stop jellystat.service &>/dev/null || true
|
systemctl stop jellystat.service &>/dev/null || true
|
||||||
msg_ok "Stopped service"
|
msg_ok "Stopped service"
|
||||||
|
|
||||||
msg_info "Backing up configuration"
|
BACKUP_DIR="/opt/jellystat_backup"
|
||||||
cp "$CONFIG_PATH" /tmp/jellystat.env.bak 2>/dev/null || true
|
create_backup "$CONFIG_PATH"
|
||||||
msg_ok "Backed up configuration"
|
|
||||||
|
|
||||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "jellystat" "CyferShepard/Jellystat" "tarball" "latest" "$INSTALL_PATH"
|
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "jellystat" "CyferShepard/Jellystat" "tarball" "latest" "$INSTALL_PATH"
|
||||||
|
|
||||||
msg_info "Restoring configuration"
|
restore_backup
|
||||||
cp /tmp/jellystat.env.bak "$CONFIG_PATH" 2>/dev/null || true
|
|
||||||
rm -f /tmp/jellystat.env.bak
|
|
||||||
msg_ok "Restored configuration"
|
|
||||||
|
|
||||||
msg_info "Installing dependencies"
|
msg_info "Installing dependencies"
|
||||||
cd "$INSTALL_PATH"
|
cd "$INSTALL_PATH"
|
||||||
|
|||||||
+12
-61
@@ -6,8 +6,13 @@
|
|||||||
# Source: https://komo.do/ | Github: https://github.com/moghtech/komodo
|
# Source: https://komo.do/ | Github: https://github.com/moghtech/komodo
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
apt-get update >/dev/null 2>&1 || apk update >/dev/null 2>&1
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
apt-get install -y curl >/dev/null 2>&1 || apk add --no-cache curl >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
fi
|
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)
|
||||||
@@ -131,25 +136,7 @@ function update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# PROXMOX HOST CHECK
|
# DEPENDENCIES
|
||||||
# ==============================================================================
|
|
||||||
function check_proxmox_host() {
|
|
||||||
if command -v pveversion &>/dev/null; then
|
|
||||||
msg_error "Running on the Proxmox host is NOT recommended!"
|
|
||||||
msg_error "This should be executed inside an LXC container."
|
|
||||||
echo ""
|
|
||||||
echo -n "${TAB}Continue anyway? (y/N): "
|
|
||||||
read -r confirm
|
|
||||||
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_warn "Aborted. Please run this inside an LXC container."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
msg_warn "Proceeding on Proxmox host at your own risk!"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# CHECK / INSTALL DOCKER
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
function ensure_openssl() {
|
function ensure_openssl() {
|
||||||
if command -v openssl &>/dev/null; then
|
if command -v openssl &>/dev/null; then
|
||||||
@@ -163,53 +150,17 @@ function ensure_openssl() {
|
|||||||
$STD apt-get install -y openssl
|
$STD apt-get install -y openssl
|
||||||
else
|
else
|
||||||
msg_error "openssl is required but could not be installed automatically."
|
msg_error "openssl is required but could not be installed automatically."
|
||||||
exit 10
|
exit 237
|
||||||
fi
|
fi
|
||||||
msg_ok "Installed openssl"
|
msg_ok "Installed openssl"
|
||||||
}
|
}
|
||||||
|
|
||||||
function check_or_install_docker() {
|
|
||||||
if command -v docker &>/dev/null; then
|
|
||||||
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
|
|
||||||
if docker compose version &>/dev/null; then
|
|
||||||
msg_ok "Docker Compose is available"
|
|
||||||
else
|
|
||||||
msg_error "Docker Compose plugin is not available. Please install it."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
ensure_openssl
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_warn "Docker is not installed."
|
|
||||||
echo -n "${TAB}Install Docker now? (y/N): "
|
|
||||||
read -r install_docker_prompt
|
|
||||||
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
|
|
||||||
msg_error "Docker is required for ${APP}. Exiting."
|
|
||||||
exit 10
|
|
||||||
fi
|
|
||||||
|
|
||||||
msg_info "Installing Docker"
|
|
||||||
if [[ -f /etc/alpine-release ]]; then
|
|
||||||
$STD apk add docker docker-cli-compose
|
|
||||||
$STD rc-service docker start
|
|
||||||
$STD rc-update add docker default
|
|
||||||
else
|
|
||||||
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
|
|
||||||
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
|
|
||||||
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
|
|
||||||
$STD sh <(curl -fsSL https://get.docker.com)
|
|
||||||
fi
|
|
||||||
msg_ok "Installed Docker"
|
|
||||||
|
|
||||||
ensure_openssl
|
|
||||||
}
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# INSTALL
|
# INSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
function install() {
|
function install() {
|
||||||
check_or_install_docker
|
ensure_docker
|
||||||
|
ensure_openssl
|
||||||
|
|
||||||
echo -e "${TAB}Choose the database for Komodo:"
|
echo -e "${TAB}Choose the database for Komodo:"
|
||||||
echo -e "${TAB} 1) MongoDB (recommended)"
|
echo -e "${TAB} 1) MongoDB (recommended)"
|
||||||
@@ -292,7 +243,7 @@ if [[ "${type:-}" == "update" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
check_proxmox_host
|
confirm_not_pve_host
|
||||||
get_lxc_ip
|
get_lxc_ip
|
||||||
|
|
||||||
# Declare variables used by find_compose_file
|
# Declare variables used by find_compose_file
|
||||||
|
|||||||
+40
-89
@@ -5,74 +5,31 @@
|
|||||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||||
# Source: https://www.netdata.cloud/ | Github: https://github.com/netdata/netdata
|
# Source: https://www.netdata.cloud/ | Github: https://github.com/netdata/netdata
|
||||||
|
|
||||||
function header_info {
|
APP="Netdata"
|
||||||
clear
|
APP_TYPE="addon"
|
||||||
cat <<"EOF"
|
|
||||||
_ __ __ ____ __
|
|
||||||
/ | / /__ / /_/ __ \____ _/ /_____ _
|
|
||||||
/ |/ / _ \/ __/ / / / __ `/ __/ __ `/
|
|
||||||
/ /| / __/ /_/ /_/ / /_/ / /_/ /_/ /
|
|
||||||
/_/ |_/\___/\__/_____/\__,_/\__/\__,_/
|
|
||||||
|
|
||||||
EOF
|
if ! command -v curl &>/dev/null; then
|
||||||
}
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
YW=$(echo "\033[33m")
|
apk update >/dev/null 2>&1
|
||||||
BL=$(echo "\033[36m")
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
RD=$(echo "\033[01;31m")
|
else
|
||||||
GN=$(echo "\033[1;92m")
|
apt-get update >/dev/null 2>&1
|
||||||
CL=$(echo "\033[m")
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
BFR="\\r\\033[K"
|
fi
|
||||||
HOLD="-"
|
fi
|
||||||
CM="${GN}✓${CL}"
|
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
|
||||||
silent() { "$@" >/dev/null 2>&1; }
|
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)
|
||||||
# Telemetry
|
|
||||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
|
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" "addon"
|
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "netdata" "addon"
|
||||||
|
|
||||||
set -e
|
# Enable error handling
|
||||||
header_info
|
set -Eeuo pipefail
|
||||||
echo "Loading..."
|
trap 'error_handler' ERR
|
||||||
function msg_info() {
|
|
||||||
local msg="$1"
|
|
||||||
echo -ne " ${HOLD} ${YW}${msg}..."
|
|
||||||
}
|
|
||||||
|
|
||||||
function msg_ok() {
|
# Initialize all core functions (colors, formatting, icons, STD mode)
|
||||||
local msg="$1"
|
load_functions
|
||||||
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function msg_error() { echo -e "${RD}✗ $1${CL}"; }
|
|
||||||
|
|
||||||
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
|
|
||||||
# Supported: Proxmox VE 8.0.x – 8.9.x and 9.0–9.x
|
|
||||||
pve_check() {
|
|
||||||
local PVE_VER
|
|
||||||
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
|
|
||||||
|
|
||||||
# Check for Proxmox VE 8.x: allow 8.0–8.9
|
|
||||||
if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then
|
|
||||||
local MINOR="${BASH_REMATCH[1]}"
|
|
||||||
if ((MINOR < 0 || MINOR > 9)); then
|
|
||||||
msg_error "This version of Proxmox VE is not supported."
|
|
||||||
msg_error "Supported: Proxmox VE version 8.0 – 8.9"
|
|
||||||
exit 105
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for Proxmox VE 9.x: allow 9.0–9.x
|
|
||||||
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# All other unsupported versions
|
|
||||||
msg_error "This version of Proxmox VE is not supported."
|
|
||||||
msg_error "Supported versions: Proxmox VE 8.0 – 8.9 or 9.0–9.x"
|
|
||||||
exit 105
|
|
||||||
}
|
|
||||||
|
|
||||||
detect_codename() {
|
detect_codename() {
|
||||||
source /etc/os-release
|
source /etc/os-release
|
||||||
@@ -83,7 +40,7 @@ detect_codename() {
|
|||||||
CODENAME="${VERSION_CODENAME:-}"
|
CODENAME="${VERSION_CODENAME:-}"
|
||||||
if [[ -z "$CODENAME" ]]; then
|
if [[ -z "$CODENAME" ]]; then
|
||||||
msg_error "Could not detect Debian codename."
|
msg_error "Could not detect Debian codename."
|
||||||
exit 71
|
exit 238
|
||||||
fi
|
fi
|
||||||
echo "$CODENAME"
|
echo "$CODENAME"
|
||||||
}
|
}
|
||||||
@@ -97,9 +54,8 @@ get_latest_repo_pkg() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install() {
|
install() {
|
||||||
header_info
|
|
||||||
while true; do
|
while true; do
|
||||||
read -p "Are you sure you want to install NetData on Proxmox VE host. Proceed(y/n)? " yn
|
read -r -p "Are you sure you want to install ${APP} on Proxmox VE host. Proceed(y/n)? " yn
|
||||||
case $yn in
|
case $yn in
|
||||||
[Yy]*) break ;;
|
[Yy]*) break ;;
|
||||||
[Nn]*) exit ;;
|
[Nn]*) exit ;;
|
||||||
@@ -107,56 +63,51 @@ install() {
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
read -r -p "Verbose mode? <y/N> " prompt
|
|
||||||
[[ ${prompt,,} =~ ^(y|yes)$ ]] && STD="" || STD="silent"
|
|
||||||
|
|
||||||
CODENAME=$(detect_codename)
|
CODENAME=$(detect_codename)
|
||||||
REPO_URL="https://repo.netdata.cloud/repos/repoconfig/debian/${CODENAME}/"
|
REPO_URL="https://repo.netdata.cloud/repos/repoconfig/debian/${CODENAME}/"
|
||||||
|
|
||||||
msg_info "Setting up repository"
|
msg_info "Setting up repository"
|
||||||
$STD apt-get install -y debian-keyring
|
$STD apt install -y debian-keyring
|
||||||
PKG=$(get_latest_repo_pkg "$REPO_URL")
|
PKG=$(get_latest_repo_pkg "$REPO_URL")
|
||||||
if [[ -z "$PKG" ]]; then
|
if [[ -z "$PKG" ]]; then
|
||||||
msg_error "Could not find netdata-repo package for Debian $CODENAME"
|
msg_error "Could not find netdata-repo package for Debian $CODENAME"
|
||||||
exit 237
|
exit 237
|
||||||
fi
|
fi
|
||||||
curl -fsSL "${REPO_URL}${PKG}" -o "$PKG"
|
TMP_DEB=$(mktemp --suffix=.deb)
|
||||||
$STD dpkg -i "$PKG"
|
curl -fsSL "${REPO_URL}${PKG}" -o "$TMP_DEB"
|
||||||
rm -f "$PKG"
|
$STD dpkg -i "$TMP_DEB"
|
||||||
|
rm -f "$TMP_DEB"
|
||||||
msg_ok "Set up repository"
|
msg_ok "Set up repository"
|
||||||
|
|
||||||
msg_info "Installing Netdata"
|
msg_info "Installing ${APP}"
|
||||||
$STD apt-get update
|
$STD apt update
|
||||||
$STD apt-get install -y netdata
|
$STD apt install -y netdata
|
||||||
msg_ok "Installed Netdata"
|
msg_ok "Installed ${APP}"
|
||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
echo -e "\n Netdata should be reachable at${BL} http://$(hostname -I | awk '{print $1}'):19999 ${CL}\n"
|
get_lxc_ip
|
||||||
|
echo -e "\n${APP} should be reachable at${BL} http://${LOCAL_IP}:19999 ${CL}\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
uninstall() {
|
uninstall() {
|
||||||
header_info
|
msg_info "Uninstalling ${APP}"
|
||||||
read -r -p "Verbose mode? <y/N> " prompt
|
|
||||||
[[ ${prompt,,} =~ ^(y|yes)$ ]] && STD="" || STD="silent"
|
|
||||||
|
|
||||||
msg_info "Uninstalling Netdata"
|
|
||||||
systemctl stop netdata || true
|
systemctl stop netdata || true
|
||||||
rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d
|
rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d
|
||||||
rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list
|
rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list
|
||||||
$STD apt-get remove --purge -y netdata netdata-repo
|
$STD apt remove --purge -y netdata netdata-repo
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
$STD apt autoremove -y
|
$STD apt autoremove -y
|
||||||
$STD userdel netdata || true
|
$STD userdel netdata || true
|
||||||
msg_ok "Uninstalled Netdata"
|
msg_ok "Uninstalled ${APP}"
|
||||||
msg_ok "Completed successfully!\n"
|
msg_ok "Completed successfully!\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
header_info
|
header_info
|
||||||
pve_check
|
require_pve_host
|
||||||
|
|
||||||
OPTIONS=(Install "Install NetData on Proxmox VE"
|
OPTIONS=(Install "Install ${APP} on Proxmox VE"
|
||||||
Uninstall "Uninstall NetData from Proxmox VE")
|
Uninstall "Uninstall ${APP} from Proxmox VE")
|
||||||
|
|
||||||
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" \
|
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP}" \
|
||||||
--menu "Select an option:" 10 58 2 "${OPTIONS[@]}" 3>&1 1>&2 2>&3)
|
--menu "Select an option:" 10 58 2 "${OPTIONS[@]}" 3>&1 1>&2 2>&3)
|
||||||
|
|
||||||
case $CHOICE in
|
case $CHOICE in
|
||||||
|
|||||||
@@ -7,8 +7,13 @@
|
|||||||
|
|
||||||
if ! command -v curl &>/dev/null; then
|
if ! command -v curl &>/dev/null; then
|
||||||
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
|
||||||
apt-get update >/dev/null 2>&1
|
if [[ -f /etc/alpine-release ]]; then
|
||||||
apt-get install -y curl >/dev/null 2>&1
|
apk update >/dev/null 2>&1
|
||||||
|
apk add --no-cache curl >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
apt-get update >/dev/null 2>&1
|
||||||
|
apt-get install -y curl >/dev/null 2>&1
|
||||||
|
fi
|
||||||
fi
|
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)
|
||||||
@@ -20,6 +25,7 @@ declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "nextcloud-exp
|
|||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
trap 'error_handler' ERR
|
trap 'error_handler' ERR
|
||||||
load_functions
|
load_functions
|
||||||
|
require_debian_like
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
@@ -31,14 +37,6 @@ BINARY_PATH="/usr/bin/nextcloud-exporter"
|
|||||||
CONFIG_PATH="/etc/nextcloud-exporter.env"
|
CONFIG_PATH="/etc/nextcloud-exporter.env"
|
||||||
SERVICE_PATH="/etc/systemd/system/nextcloud-exporter.service"
|
SERVICE_PATH="/etc/systemd/system/nextcloud-exporter.service"
|
||||||
|
|
||||||
# ==============================================================================
|
|
||||||
# OS DETECTION
|
|
||||||
# ==============================================================================
|
|
||||||
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
|
|
||||||
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
|
|
||||||
exit 238
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# UNINSTALL
|
# UNINSTALL
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user