mirror of
https://github.com/community-scripts/ProxmoxVE.git
synced 2026-04-15 23:12:16 +00:00
Compare commits
121 Commits
fix/homarr
...
cleanup_do
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d108daea0f | ||
|
|
487403be61 | ||
|
|
555338a188 | ||
|
|
8839d72200 | ||
|
|
44745c7e28 | ||
|
|
e2e30d65c0 | ||
|
|
d88036e58b | ||
|
|
7f9b0abf04 | ||
|
|
11072c854a | ||
|
|
b4a21b6f88 | ||
|
|
750d54f0e5 | ||
|
|
8cccdf9fa5 | ||
|
|
a7f815ef06 | ||
|
|
7790d73c53 | ||
|
|
8a243d2a2f | ||
|
|
04eb2ba9d1 | ||
|
|
4500d413a2 | ||
|
|
da1fe82c71 | ||
|
|
7fa11aa6b5 | ||
|
|
f06dedd872 | ||
|
|
18e09c26d9 | ||
|
|
209f92bf0f | ||
|
|
a17ba89e7b | ||
|
|
08ee4699df | ||
|
|
a49d9c5713 | ||
|
|
18fd0f2393 | ||
|
|
9b35339cbe | ||
|
|
a9c2307b0e | ||
|
|
0e809c6ee9 | ||
|
|
64d000b73a | ||
|
|
65353d01e1 | ||
|
|
683be87e9e | ||
|
|
5894734857 | ||
|
|
c881811499 | ||
|
|
33716c92e5 | ||
|
|
dda2ea811f | ||
|
|
392ff1f575 | ||
|
|
af9bf93707 | ||
|
|
cfe5e7baa7 | ||
|
|
1d609976d3 | ||
|
|
041de06a4d | ||
|
|
f0bfec1b59 | ||
|
|
83ef4a5857 | ||
|
|
0baafa3993 | ||
|
|
e55fe43e2d | ||
|
|
482f579dc0 | ||
|
|
2652ae6c95 | ||
|
|
e9f802dd29 | ||
|
|
60957a8eee | ||
|
|
0bf87f6fcc | ||
|
|
3dd3040010 | ||
|
|
6a86f52c0e | ||
|
|
346dfd8bf7 | ||
|
|
2331f92c32 | ||
|
|
66ec27a1fb | ||
|
|
9e1c4a39a1 | ||
|
|
7c6460f903 | ||
|
|
c3f7cc4d32 | ||
|
|
41fc57072a | ||
|
|
d8b0ea0490 | ||
|
|
86a40ebfbe | ||
|
|
bea342ba04 | ||
|
|
dd86af007e | ||
|
|
146cd312d5 | ||
|
|
8b0156ede8 | ||
|
|
f8668c74fc | ||
|
|
ecb4d36d6a | ||
|
|
daaa137cec | ||
|
|
e820d58f2e | ||
|
|
90bc07f65b | ||
|
|
b40bc46b4b | ||
|
|
cacc04b26d | ||
|
|
e9e65854cc | ||
|
|
017e709ac7 | ||
|
|
ba876c7495 | ||
|
|
0d2d1f46f5 | ||
|
|
5e865278e9 | ||
|
|
a18642a8f8 | ||
|
|
9a82ec48b2 | ||
|
|
f2d46dd8c8 | ||
|
|
2707295eba | ||
|
|
82cc074b05 | ||
|
|
6b224ac649 | ||
|
|
a69f9955f4 | ||
|
|
7d19269122 | ||
|
|
498d37ae3a | ||
|
|
703ad0ecb7 | ||
|
|
ae6cf7666e | ||
|
|
2c2beab3ce | ||
|
|
a10100d66a | ||
|
|
41848653d6 | ||
|
|
1eb246ee41 | ||
|
|
68b486be92 | ||
|
|
9dd4bff9c5 | ||
|
|
ae3e1deece | ||
|
|
c11b2e9db2 | ||
|
|
f7c2477e09 | ||
|
|
8b7c620f92 | ||
|
|
d3a935e347 | ||
|
|
74c430ddf2 | ||
|
|
be0d0a6a7a | ||
|
|
507ad186dd | ||
|
|
927e7181c2 | ||
|
|
c5083471d9 | ||
|
|
fb6c428a0f | ||
|
|
ac3cf75b11 | ||
|
|
8e010cacfe | ||
|
|
a7a6d5dd17 | ||
|
|
046e8c749a | ||
|
|
daffd75719 | ||
|
|
c999a61c60 | ||
|
|
e8201ef3e5 | ||
|
|
10af5efd6b | ||
|
|
00fdd3a3c5 | ||
|
|
0c5bcb8122 | ||
|
|
42c02d1326 | ||
|
|
5d84c935e5 | ||
|
|
f489db21cd | ||
|
|
a674e84eef | ||
|
|
ec8b73c148 | ||
|
|
e5fd7e4436 |
18
.gitattributes
vendored
18
.gitattributes
vendored
@@ -4,35 +4,29 @@
|
||||
*.sh linguist-detectable=true
|
||||
*.bash linguist-language=Shell
|
||||
*.func linguist-language=Shell
|
||||
*.func linguist-detectable=true
|
||||
*.install linguist-language=Shell
|
||||
|
||||
# ---------------------------------------
|
||||
# Treat Golang files as Go (for /api/)
|
||||
api/**/*.go linguist-language=Go
|
||||
|
||||
# Exclude header art from stats
|
||||
# ---------------------------------------
|
||||
# Treat frontend as JavaScript/TypeScript (optional)
|
||||
frontend/**/*.ts linguist-language=TypeScript
|
||||
frontend/**/*.js linguist-language=JavaScript
|
||||
ct/headers/* linguist-documentation
|
||||
|
||||
# ---------------------------------------
|
||||
# Exclude documentation from stats
|
||||
# ---------------------------------------
|
||||
*.md linguist-documentation
|
||||
docs/** linguist-documentation
|
||||
README.md linguist-documentation
|
||||
CONTRIBUTING.md linguist-documentation
|
||||
SECURITY.md linguist-documentation
|
||||
|
||||
# ---------------------------------------
|
||||
# Exclude generated/config files
|
||||
*.json linguist-generated
|
||||
frontend/public/json/*.json linguist-generated=false
|
||||
*.lock linguist-generated
|
||||
*.yml linguist-generated
|
||||
*.yaml linguist-generated
|
||||
# ---------------------------------------
|
||||
.github/** linguist-generated
|
||||
.vscode/** linguist-generated
|
||||
|
||||
# ---------------------------------------
|
||||
# Standard text handling
|
||||
# ---------------------------------------
|
||||
* text=auto eol=lf
|
||||
|
||||
3
.github/CODEOWNERS
generated
vendored
3
.github/CODEOWNERS
generated
vendored
@@ -12,6 +12,3 @@
|
||||
|
||||
# Set default reviewers
|
||||
* @community-scripts/Contributor
|
||||
|
||||
# All changes in frontend
|
||||
/frontend/ @community-scripts/Frontend-Dev
|
||||
|
||||
129
.github/changelogs/2026/04.md
generated
vendored
129
.github/changelogs/2026/04.md
generated
vendored
@@ -1,3 +1,132 @@
|
||||
## 2026-04-11
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Immich: Ensure newline before appending IMMICH_HELMET_FILE to .env [@MickLesk](https://github.com/MickLesk) ([#13667](https://github.com/community-scripts/ProxmoxVE/pull/13667))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- BentoPDF: replace http-server with nginx to fix WASM initialization timeout [@MickLesk](https://github.com/MickLesk) ([#13625](https://github.com/community-scripts/ProxmoxVE/pull/13625))
|
||||
- Element Synapse: Add MatrixRTC configuration for Element Call support [@MickLesk](https://github.com/MickLesk) ([#13665](https://github.com/community-scripts/ProxmoxVE/pull/13665))
|
||||
- RomM: Use ROMM_BASE_PATH from .env for symlinks and nginx config [@MickLesk](https://github.com/MickLesk) ([#13666](https://github.com/community-scripts/ProxmoxVE/pull/13666))
|
||||
- Immich: Pin version to 2.7.4 [@vhsdream](https://github.com/vhsdream) ([#13661](https://github.com/community-scripts/ProxmoxVE/pull/13661))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Crafty Controller: Wait for credentials file instead of fixed sleep [@MickLesk](https://github.com/MickLesk) ([#13670](https://github.com/community-scripts/ProxmoxVE/pull/13670))
|
||||
- Refactor: Alpine-Wakapi [@tremor021](https://github.com/tremor021) ([#13656](https://github.com/community-scripts/ProxmoxVE/pull/13656))
|
||||
|
||||
## 2026-04-10
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix: ensure trailing newline in redis.conf before appending bind directive [@Copilot](https://github.com/Copilot) ([#13647](https://github.com/community-scripts/ProxmoxVE/pull/13647))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Immich: Pin version to 2.7.3 [@vhsdream](https://github.com/vhsdream) ([#13631](https://github.com/community-scripts/ProxmoxVE/pull/13631))
|
||||
- Homarr: bind Redis to localhost only [@MickLesk](https://github.com/MickLesk) ([#13552](https://github.com/community-scripts/ProxmoxVE/pull/13552))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- tools.func: prevent script crash when entering GitHub token after rate limit [@MickLesk](https://github.com/MickLesk) ([#13638](https://github.com/community-scripts/ProxmoxVE/pull/13638))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- addons: Filebrowser & Filebrowser-Quantum get warning if host install [@MickLesk](https://github.com/MickLesk) ([#13639](https://github.com/community-scripts/ProxmoxVE/pull/13639))
|
||||
|
||||
## 2026-04-09
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- boostack: add: git [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13620](https://github.com/community-scripts/ProxmoxVE/pull/13620))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Update OPNsense version from 25.7 to 26.1 [@tdn131](https://github.com/tdn131) ([#13626](https://github.com/community-scripts/ProxmoxVE/pull/13626))
|
||||
- CheckMK: Bump Default OS to 13 (trixie) + dynamic codename + fix RELEASE-Tag Fetching [@MickLesk](https://github.com/MickLesk) ([#13610](https://github.com/community-scripts/ProxmoxVE/pull/13610))
|
||||
|
||||
## 2026-04-08
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- IronClaw | Alpine-IronClaw ([#13591](https://github.com/community-scripts/ProxmoxVE/pull/13591))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- immich: disable upgrade-insecure-requests CSP directive [@MickLesk](https://github.com/MickLesk) ([#13600](https://github.com/community-scripts/ProxmoxVE/pull/13600))
|
||||
- Immich: v2.7.2 [@vhsdream](https://github.com/vhsdream) ([#13579](https://github.com/community-scripts/ProxmoxVE/pull/13579))
|
||||
- Update flaresolverr-install.sh [@maztheman](https://github.com/maztheman) ([#13584](https://github.com/community-scripts/ProxmoxVE/pull/13584))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- bambuddy: add mkdir before data restore & add ffmpeg dependency [@MickLesk](https://github.com/MickLesk) ([#13601](https://github.com/community-scripts/ProxmoxVE/pull/13601))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- feat: update UHF Server script to use setup_ffmpeg [@zackwithak13](https://github.com/zackwithak13) ([#13564](https://github.com/community-scripts/ProxmoxVE/pull/13564))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- core: add script page badges to descriptions | change donate URL [@MickLesk](https://github.com/MickLesk) ([#13596](https://github.com/community-scripts/ProxmoxVE/pull/13596))
|
||||
|
||||
## 2026-04-07
|
||||
|
||||
### 🗑️ Deleted Scripts
|
||||
|
||||
- Remove low-install-count CT scripts and installers [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#13570](https://github.com/community-scripts/ProxmoxVE/pull/13570))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- core: improve resilience for top Proxmox error codes (209, 215, 118, 206) [@MickLesk](https://github.com/MickLesk) ([#13575](https://github.com/community-scripts/ProxmoxVE/pull/13575))
|
||||
|
||||
## 2026-04-06
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- OpenThread Border Router ([#13536](https://github.com/community-scripts/ProxmoxVE/pull/13536))
|
||||
- Homelable ([#13539](https://github.com/community-scripts/ProxmoxVE/pull/13539))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Papra: check env before copy [@MickLesk](https://github.com/MickLesk) ([#13553](https://github.com/community-scripts/ProxmoxVE/pull/13553))
|
||||
- changedetection: fix: typing_extensions error [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13548](https://github.com/community-scripts/ProxmoxVE/pull/13548))
|
||||
- kasm: fix: fetch latest version [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13547](https://github.com/community-scripts/ProxmoxVE/pull/13547))
|
||||
|
||||
## 2026-04-05
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Grist: remove install:ee step (private repo, not needed for grist-core) [@MickLesk](https://github.com/MickLesk) ([#13526](https://github.com/community-scripts/ProxmoxVE/pull/13526))
|
||||
- Nginx Proxy Manager: ensure /tmp/nginx/body exists via openresty service [@MickLesk](https://github.com/MickLesk) ([#13528](https://github.com/community-scripts/ProxmoxVE/pull/13528))
|
||||
- MotionEye: run as root to enable SMB share support [@MickLesk](https://github.com/MickLesk) ([#13527](https://github.com/community-scripts/ProxmoxVE/pull/13527))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- core: silent() function - use return instead of exit to allow || true error handling [@MickLesk](https://github.com/MickLesk) ([#13529](https://github.com/community-scripts/ProxmoxVE/pull/13529))
|
||||
|
||||
## 2026-04-04
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
2
.github/pull_request_template.md
generated
vendored
2
.github/pull_request_template.md
generated
vendored
@@ -22,6 +22,6 @@ Fixes #
|
||||
- [ ] ✨ **New feature** – Adds new, non-breaking functionality.
|
||||
- [ ] 💥 **Breaking change** – Alters existing functionality in a way that may require updates.
|
||||
- [ ] 🆕 **New script** – A fully functional and tested script or script set.
|
||||
- [ ] 🌍 **Website update** – Changes to website-related JSON files or metadata.
|
||||
- [ ] 🌍 **Website update** – Changes to script metadata (PocketBase/website data).
|
||||
- [ ] 🔧 **Refactoring / Code Cleanup** – Improves readability or maintainability without changing functionality.
|
||||
- [ ] 📝 **Documentation update** – Changes to `README`, `AppName.md`, `CONTRIBUTING.md`, or other docs.
|
||||
|
||||
474
.github/workflows/pocketbase-bot.yml
generated
vendored
474
.github/workflows/pocketbase-bot.yml
generated
vendored
@@ -31,6 +31,8 @@ jobs:
|
||||
ACTOR: ${{ github.event.comment.user.login }}
|
||||
ACTOR_ASSOCIATION: ${{ github.event.comment.author_association }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
FRONTEND_URL: ${{ secrets.FRONTEND_URL }}
|
||||
REVALIDATE_SECRET: ${{ secrets.REVALIDATE_SECRET }}
|
||||
run: |
|
||||
node << 'ENDSCRIPT'
|
||||
(async function () {
|
||||
@@ -113,7 +115,6 @@ jobs:
|
||||
}
|
||||
|
||||
// ── Permission check ───────────────────────────────────────────────
|
||||
// author_association: OWNER = repo/org owner, MEMBER = org member (includes Contributors team)
|
||||
const association = process.env.ACTOR_ASSOCIATION;
|
||||
if (association !== 'OWNER' && association !== 'MEMBER') {
|
||||
await addReaction('-1');
|
||||
@@ -128,18 +129,11 @@ jobs:
|
||||
await addReaction('eyes');
|
||||
|
||||
// ── Parse command ──────────────────────────────────────────────────
|
||||
// Formats (first line of comment):
|
||||
// /pocketbase <slug> field=value [field=value ...] ← field updates (simple values)
|
||||
// /pocketbase <slug> set <field> ← value from code block below
|
||||
// /pocketbase <slug> note list|add|edit|remove ... ← note management
|
||||
// /pocketbase <slug> method list ← list install methods
|
||||
// /pocketbase <slug> method <type> cpu=N ram=N hdd=N ← edit install method resources
|
||||
const commentBody = process.env.COMMENT_BODY || '';
|
||||
const lines = commentBody.trim().split('\n');
|
||||
const firstLine = lines[0].trim();
|
||||
const withoutCmd = firstLine.replace(/^\/pocketbase\s+/, '').trim();
|
||||
|
||||
// Extract code block content from comment body (```...``` or ```lang\n...```)
|
||||
function extractCodeBlock(body) {
|
||||
const m = body.match(/```[^\n]*\n([\s\S]*?)```/);
|
||||
return m ? m[1].trim() : null;
|
||||
@@ -147,6 +141,8 @@ jobs:
|
||||
const codeBlockValue = extractCodeBlock(commentBody);
|
||||
|
||||
const HELP_TEXT =
|
||||
'**Show current state:**\n' +
|
||||
'```\n/pocketbase <slug> info\n```\n\n' +
|
||||
'**Field update (simple):** `/pocketbase <slug> field=value [field=value ...]`\n\n' +
|
||||
'**Field update (HTML/multiline) — value from code block:**\n' +
|
||||
'````\n' +
|
||||
@@ -162,12 +158,16 @@ jobs:
|
||||
'/pocketbase <slug> note edit <type> "<old text>" "<new text>"\n' +
|
||||
'/pocketbase <slug> note remove <type> "<text>"\n' +
|
||||
'```\n\n' +
|
||||
'**Install method resources:**\n' +
|
||||
'**Install method management:**\n' +
|
||||
'```\n' +
|
||||
'/pocketbase <slug> method list\n' +
|
||||
'/pocketbase <slug> method <type> hdd=10\n' +
|
||||
'/pocketbase <slug> method <type> cpu=4 ram=2048 hdd=20\n' +
|
||||
'```\n\n' +
|
||||
'/pocketbase <slug> method <type> config_path="/opt/app/.env"\n' +
|
||||
'/pocketbase <slug> method <type> os=debian version=13\n' +
|
||||
'/pocketbase <slug> method add <type> cpu=2 ram=2048 hdd=8 os=debian version=13\n' +
|
||||
'/pocketbase <slug> method remove <type>\n' +
|
||||
'```\n' +
|
||||
'Method fields: `cpu` `ram` `hdd` `os` `version` `config_path` `script`\n\n' +
|
||||
'**Editable fields:** `name` `description` `logo` `documentation` `website` `project_url` `github` ' +
|
||||
'`config_path` `port` `default_user` `default_passwd` ' +
|
||||
'`updateable` `privileged` `has_arm` `is_dev` ' +
|
||||
@@ -189,8 +189,7 @@ jobs:
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// ── Allowed fields and their types ─────────────────────────────────
|
||||
// ── PocketBase: authenticate (shared by all paths) ─────────────────
|
||||
// ── PocketBase: authenticate ───────────────────────────────────────
|
||||
const raw = process.env.POCKETBASE_URL.replace(/\/$/, '');
|
||||
const apiBase = /\/api$/i.test(raw) ? raw : raw + '/api';
|
||||
const coll = process.env.POCKETBASE_COLLECTION;
|
||||
@@ -210,7 +209,7 @@ jobs:
|
||||
}
|
||||
const token = JSON.parse(authRes.body).token;
|
||||
|
||||
// ── PocketBase: find record by slug (shared by all paths) ──────────
|
||||
// ── PocketBase: find record by slug ────────────────────────────────
|
||||
const recordsUrl = apiBase + '/collections/' + encodeURIComponent(coll) + '/records';
|
||||
const filter = "(slug='" + slug.replace(/'/g, "''") + "')";
|
||||
const listRes = await request(recordsUrl + '?filter=' + encodeURIComponent(filter) + '&perPage=1', {
|
||||
@@ -228,57 +227,164 @@ jobs:
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// ── Shared helpers ─────────────────────────────────────────────────
|
||||
|
||||
// Key=value parser: handles unquoted and "quoted" values
|
||||
function parseKVPairs(str) {
|
||||
const fields = {};
|
||||
let pos = 0;
|
||||
while (pos < str.length) {
|
||||
while (pos < str.length && /\s/.test(str[pos])) pos++;
|
||||
if (pos >= str.length) break;
|
||||
let keyStart = pos;
|
||||
while (pos < str.length && str[pos] !== '=' && !/\s/.test(str[pos])) pos++;
|
||||
const key = str.substring(keyStart, pos).trim();
|
||||
if (!key || pos >= str.length || str[pos] !== '=') { pos++; continue; }
|
||||
pos++;
|
||||
let value;
|
||||
if (pos < str.length && str[pos] === '"') {
|
||||
pos++;
|
||||
let valStart = pos;
|
||||
while (pos < str.length && str[pos] !== '"') {
|
||||
if (str[pos] === '\\') pos++;
|
||||
pos++;
|
||||
}
|
||||
value = str.substring(valStart, pos).replace(/\\"/g, '"');
|
||||
if (pos < str.length) pos++;
|
||||
} else {
|
||||
let valStart = pos;
|
||||
while (pos < str.length && !/\s/.test(str[pos])) pos++;
|
||||
value = str.substring(valStart, pos);
|
||||
}
|
||||
fields[key] = value;
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
// Token parser for note commands: unquoted-word OR "quoted string"
|
||||
function parseTokens(str) {
|
||||
const tokens = [];
|
||||
let pos = 0;
|
||||
while (pos < str.length) {
|
||||
while (pos < str.length && /\s/.test(str[pos])) pos++;
|
||||
if (pos >= str.length) break;
|
||||
if (str[pos] === '"') {
|
||||
pos++;
|
||||
let start = pos;
|
||||
while (pos < str.length && str[pos] !== '"') {
|
||||
if (str[pos] === '\\') pos++;
|
||||
pos++;
|
||||
}
|
||||
tokens.push(str.substring(start, pos).replace(/\\"/g, '"'));
|
||||
if (pos < str.length) pos++;
|
||||
} else {
|
||||
let start = pos;
|
||||
while (pos < str.length && !/\s/.test(str[pos])) pos++;
|
||||
tokens.push(str.substring(start, pos));
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
// Read JSON blob from record (handles parsed objects and strings)
|
||||
function readJsonBlob(val) {
|
||||
if (Array.isArray(val)) return val;
|
||||
try { return JSON.parse(val || '[]'); } catch (e) { return []; }
|
||||
}
|
||||
|
||||
// Frontend cache revalidation (silent, best-effort)
|
||||
async function revalidate(s) {
|
||||
const frontendUrl = process.env.FRONTEND_URL;
|
||||
const secret = process.env.REVALIDATE_SECRET;
|
||||
if (!frontendUrl || !secret) return;
|
||||
try {
|
||||
await request(frontendUrl.replace(/\/$/, '') + '/api/revalidate', {
|
||||
method: 'POST',
|
||||
headers: { 'Authorization': 'Bearer ' + secret, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ tags: ['scripts', 'script-' + s] })
|
||||
});
|
||||
} catch (e) { console.warn('Revalidation skipped:', e.message); }
|
||||
}
|
||||
|
||||
// Format notes list for display
|
||||
function formatNotesList(arr) {
|
||||
if (arr.length === 0) return '*None*';
|
||||
return arr.map(function (n, i) {
|
||||
return (i + 1) + '. **`' + (n.type || '?') + '`**: ' + (n.text || '');
|
||||
}).join('\n');
|
||||
}
|
||||
|
||||
// Format install methods list for display
|
||||
function formatMethodsList(arr) {
|
||||
if (arr.length === 0) return '*None*';
|
||||
return arr.map(function (im, i) {
|
||||
const r = im.resources || {};
|
||||
const parts = [
|
||||
(r.os || '?') + ' ' + (r.version || '?'),
|
||||
(r.cpu != null ? r.cpu : '?') + 'C / ' + (r.ram != null ? r.ram : '?') + ' MB / ' + (r.hdd != null ? r.hdd : '?') + ' GB'
|
||||
];
|
||||
if (im.config_path) parts.push('config: `' + im.config_path + '`');
|
||||
if (im.script) parts.push('script: `' + im.script + '`');
|
||||
return (i + 1) + '. **`' + (im.type || '?') + '`** — ' + parts.join(', ');
|
||||
}).join('\n');
|
||||
}
|
||||
|
||||
// ── Route: dispatch to subcommand handler ──────────────────────────
|
||||
const infoMatch = rest.match(/^info$/i);
|
||||
const noteMatch = rest.match(/^note\s+(list|add|edit|remove)\b/i);
|
||||
const methodMatch = rest.match(/^method\b/i);
|
||||
const setMatch = rest.match(/^set\s+(\S+)/i);
|
||||
|
||||
if (noteMatch) {
|
||||
// ── NOTE SUBCOMMAND (reads/writes notes_json on script record) ────
|
||||
if (infoMatch) {
|
||||
// ── INFO SUBCOMMAND ──────────────────────────────────────────────
|
||||
const notesArr = readJsonBlob(record.notes_json);
|
||||
const methodsArr = readJsonBlob(record.install_methods_json);
|
||||
|
||||
const out = [];
|
||||
out.push('ℹ️ **PocketBase Bot**: Info for **`' + slug + '`**\n');
|
||||
|
||||
out.push('**Basic info:**');
|
||||
out.push('- **Name:** ' + (record.name || '—'));
|
||||
out.push('- **Slug:** `' + slug + '`');
|
||||
out.push('- **Port:** ' + (record.port != null ? '`' + record.port + '`' : '—'));
|
||||
out.push('- **Updateable:** ' + (record.updateable ? 'Yes' : 'No'));
|
||||
out.push('- **Privileged:** ' + (record.privileged ? 'Yes' : 'No'));
|
||||
out.push('- **ARM:** ' + (record.has_arm ? 'Yes' : 'No'));
|
||||
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_deleted) out.push('- **Deleted:** Yes' + (record.deleted_message ? ' — ' + record.deleted_message : ''));
|
||||
out.push('');
|
||||
|
||||
out.push('**Links:**');
|
||||
out.push('- **Website:** ' + (record.website || '—'));
|
||||
out.push('- **Docs:** ' + (record.documentation || '—'));
|
||||
out.push('- **Logo:** ' + (record.logo ? '[link](' + record.logo + ')' : '—'));
|
||||
out.push('- **GitHub:** ' + (record.github || '—'));
|
||||
if (record.config_path) out.push('- **Config:** `' + record.config_path + '`');
|
||||
out.push('');
|
||||
|
||||
out.push('**Credentials:**');
|
||||
out.push('- **User:** ' + (record.default_user || '—'));
|
||||
out.push('- **Password:** ' + (record.default_passwd ? '*(set)*' : '—'));
|
||||
out.push('');
|
||||
|
||||
out.push('**Install methods** (' + methodsArr.length + '):');
|
||||
out.push(formatMethodsList(methodsArr));
|
||||
out.push('');
|
||||
|
||||
out.push('**Notes** (' + notesArr.length + '):');
|
||||
out.push(formatNotesList(notesArr));
|
||||
|
||||
await addReaction('+1');
|
||||
await postComment(out.join('\n'));
|
||||
|
||||
} else if (noteMatch) {
|
||||
// ── NOTE SUBCOMMAND ──────────────────────────────────────────────
|
||||
const noteAction = noteMatch[1].toLowerCase();
|
||||
const noteArgsStr = rest.substring(noteMatch[0].length).trim();
|
||||
let notesArr = readJsonBlob(record.notes_json);
|
||||
|
||||
// Parse notes_json from the already-fetched script record
|
||||
// PocketBase may return JSON fields as already-parsed objects
|
||||
let notesArr = [];
|
||||
try {
|
||||
const rawNotes = record.notes_json;
|
||||
notesArr = Array.isArray(rawNotes) ? rawNotes : JSON.parse(rawNotes || '[]');
|
||||
} catch (e) { notesArr = []; }
|
||||
|
||||
// Token parser: unquoted-word OR "quoted string" (supports \" escapes)
|
||||
function parseNoteTokens(str) {
|
||||
const tokens = [];
|
||||
let pos = 0;
|
||||
while (pos < str.length) {
|
||||
while (pos < str.length && /\s/.test(str[pos])) pos++;
|
||||
if (pos >= str.length) break;
|
||||
if (str[pos] === '"') {
|
||||
pos++;
|
||||
let start = pos;
|
||||
while (pos < str.length && str[pos] !== '"') {
|
||||
if (str[pos] === '\\') pos++;
|
||||
pos++;
|
||||
}
|
||||
tokens.push(str.substring(start, pos).replace(/\\"/g, '"'));
|
||||
if (pos < str.length) pos++;
|
||||
} else {
|
||||
let start = pos;
|
||||
while (pos < str.length && !/\s/.test(str[pos])) pos++;
|
||||
tokens.push(str.substring(start, pos));
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
function formatNotesList(arr) {
|
||||
if (arr.length === 0) return '*None*';
|
||||
return arr.map(function (n, i) {
|
||||
return (i + 1) + '. **`' + (n.type || '?') + '`**: ' + (n.text || '');
|
||||
}).join('\n');
|
||||
}
|
||||
|
||||
async function patchNotesJson(arr) {
|
||||
async function patchNotes(arr) {
|
||||
const res = await request(recordsUrl + '/' + record.id, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||
@@ -286,7 +392,7 @@ jobs:
|
||||
});
|
||||
if (!res.ok) {
|
||||
await addReaction('-1');
|
||||
await postComment('❌ **PocketBase Bot**: Failed to update `notes_json`:\n```\n' + res.body + '\n```');
|
||||
await postComment('❌ **PocketBase Bot**: Failed to update notes:\n```\n' + res.body + '\n```');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -299,7 +405,7 @@ jobs:
|
||||
);
|
||||
|
||||
} else if (noteAction === 'add') {
|
||||
const tokens = parseNoteTokens(noteArgsStr);
|
||||
const tokens = parseTokens(noteArgsStr);
|
||||
if (tokens.length < 2) {
|
||||
await addReaction('-1');
|
||||
await postComment(
|
||||
@@ -311,7 +417,8 @@ jobs:
|
||||
const noteType = tokens[0].toLowerCase();
|
||||
const noteText = tokens.slice(1).join(' ');
|
||||
notesArr.push({ type: noteType, text: noteText });
|
||||
await patchNotesJson(notesArr);
|
||||
await patchNotes(notesArr);
|
||||
await revalidate(slug);
|
||||
await addReaction('+1');
|
||||
await postComment(
|
||||
'✅ **PocketBase Bot**: Added note to **`' + slug + '`**\n\n' +
|
||||
@@ -321,7 +428,7 @@ jobs:
|
||||
);
|
||||
|
||||
} else if (noteAction === 'edit') {
|
||||
const tokens = parseNoteTokens(noteArgsStr);
|
||||
const tokens = parseTokens(noteArgsStr);
|
||||
if (tokens.length < 3) {
|
||||
await addReaction('-1');
|
||||
await postComment(
|
||||
@@ -346,7 +453,8 @@ jobs:
|
||||
process.exit(0);
|
||||
}
|
||||
notesArr[idx].text = newText;
|
||||
await patchNotesJson(notesArr);
|
||||
await patchNotes(notesArr);
|
||||
await revalidate(slug);
|
||||
await addReaction('+1');
|
||||
await postComment(
|
||||
'✅ **PocketBase Bot**: Edited note in **`' + slug + '`**\n\n' +
|
||||
@@ -357,7 +465,7 @@ jobs:
|
||||
);
|
||||
|
||||
} else if (noteAction === 'remove') {
|
||||
const tokens = parseNoteTokens(noteArgsStr);
|
||||
const tokens = parseTokens(noteArgsStr);
|
||||
if (tokens.length < 2) {
|
||||
await addReaction('-1');
|
||||
await postComment(
|
||||
@@ -381,7 +489,8 @@ jobs:
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
await patchNotesJson(notesArr);
|
||||
await patchNotes(notesArr);
|
||||
await revalidate(slug);
|
||||
await addReaction('+1');
|
||||
await postComment(
|
||||
'✅ **PocketBase Bot**: Removed note from **`' + slug + '`**\n\n' +
|
||||
@@ -392,36 +501,36 @@ jobs:
|
||||
}
|
||||
|
||||
} else if (methodMatch) {
|
||||
// ── METHOD SUBCOMMAND (reads/writes install_methods_json on script record) ──
|
||||
// ── METHOD SUBCOMMAND ────────────────────────────────────────────
|
||||
const methodArgs = rest.replace(/^method\s*/i, '').trim();
|
||||
const methodListMode = !methodArgs || methodArgs.toLowerCase() === 'list';
|
||||
let methodsArr = readJsonBlob(record.install_methods_json);
|
||||
|
||||
// Parse install_methods_json from the already-fetched script record
|
||||
// PocketBase may return JSON fields as already-parsed objects
|
||||
let methodsArr = [];
|
||||
try {
|
||||
const rawMethods = record.install_methods_json;
|
||||
methodsArr = Array.isArray(rawMethods) ? rawMethods : JSON.parse(rawMethods || '[]');
|
||||
} catch (e) { methodsArr = []; }
|
||||
// Method field classification
|
||||
const RESOURCE_KEYS = { cpu: 'number', ram: 'number', hdd: 'number', os: 'string', version: 'string' };
|
||||
const METHOD_KEYS = { config_path: 'string', script: 'string' };
|
||||
const ALL_METHOD_KEYS = Object.assign({}, RESOURCE_KEYS, METHOD_KEYS);
|
||||
|
||||
function formatMethodsList(arr) {
|
||||
if (arr.length === 0) return '*None*';
|
||||
return arr.map(function (im, i) {
|
||||
const r = im.resources || {};
|
||||
return (i + 1) + '. **`' + (im.type || '?') + '`** — CPU: `' + (r.cpu != null ? r.cpu : '?') +
|
||||
'` · RAM: `' + (r.ram != null ? r.ram : '?') + ' MB` · HDD: `' + (r.hdd != null ? r.hdd : '?') + ' GB`';
|
||||
}).join('\n');
|
||||
function applyMethodChanges(method, parsed) {
|
||||
if (!method.resources) method.resources = {};
|
||||
for (const [k, v] of Object.entries(parsed)) {
|
||||
if (RESOURCE_KEYS[k]) {
|
||||
method.resources[k] = RESOURCE_KEYS[k] === 'number' ? parseInt(v, 10) : v;
|
||||
} else if (METHOD_KEYS[k]) {
|
||||
method[k] = v === '' ? null : v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function patchInstallMethodsJson(arr) {
|
||||
async function patchMethods(arr) {
|
||||
const res = await request(recordsUrl + '/' + record.id, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Authorization': token, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ install_methods_json: JSON.stringify(arr) })
|
||||
body: JSON.stringify({ install_methods_json: arr })
|
||||
});
|
||||
if (!res.ok) {
|
||||
await addReaction('-1');
|
||||
await postComment('❌ **PocketBase Bot**: Failed to update `install_methods_json`:\n```\n' + res.body + '\n```');
|
||||
await postComment('❌ **PocketBase Bot**: Failed to update install methods:\n```\n' + res.body + '\n```');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -432,70 +541,122 @@ jobs:
|
||||
'ℹ️ **PocketBase Bot**: Install methods for **`' + slug + '`** (' + methodsArr.length + ' total)\n\n' +
|
||||
formatMethodsList(methodsArr)
|
||||
);
|
||||
|
||||
} else {
|
||||
// Parse: <type> cpu=N ram=N hdd=N
|
||||
const methodParts = methodArgs.match(/^(\S+)\s+(.+)$/);
|
||||
if (!methodParts) {
|
||||
await addReaction('-1');
|
||||
// Check for add / remove sub-actions
|
||||
const addMatch = methodArgs.match(/^add\s+(\S+)(?:\s+(.+))?$/i);
|
||||
const removeMatch = methodArgs.match(/^remove\s+(\S+)$/i);
|
||||
|
||||
if (addMatch) {
|
||||
// ── METHOD ADD ───────────────────────────────────────────────
|
||||
const newType = addMatch[1];
|
||||
if (methodsArr.some(function (im) { return (im.type || '').toLowerCase() === newType.toLowerCase(); })) {
|
||||
await addReaction('-1');
|
||||
await postComment('❌ **PocketBase Bot**: Install method `' + newType + '` already exists for `' + slug + '`.\n\nUse `/pocketbase ' + slug + ' method list` to see all methods.');
|
||||
process.exit(0);
|
||||
}
|
||||
const newMethod = { type: newType, resources: { cpu: 1, ram: 512, hdd: 4, os: 'debian', version: '13' } };
|
||||
if (addMatch[2]) {
|
||||
const parsed = parseKVPairs(addMatch[2]);
|
||||
const unknown = Object.keys(parsed).filter(function (k) { return !ALL_METHOD_KEYS[k]; });
|
||||
if (unknown.length > 0) {
|
||||
await addReaction('-1');
|
||||
await postComment('❌ **PocketBase Bot**: Unknown method field(s): `' + unknown.join('`, `') + '`\n\n**Allowed:** `' + Object.keys(ALL_METHOD_KEYS).join('`, `') + '`');
|
||||
process.exit(0);
|
||||
}
|
||||
applyMethodChanges(newMethod, parsed);
|
||||
}
|
||||
methodsArr.push(newMethod);
|
||||
await patchMethods(methodsArr);
|
||||
await revalidate(slug);
|
||||
await addReaction('+1');
|
||||
await postComment(
|
||||
'❌ **PocketBase Bot**: Invalid `method` syntax.\n\n' +
|
||||
'**Usage:**\n```\n/pocketbase ' + slug + ' method list\n/pocketbase ' + slug + ' method <type> hdd=10\n/pocketbase ' + slug + ' method <type> cpu=4 ram=2048 hdd=20\n```'
|
||||
'✅ **PocketBase Bot**: Added install method **`' + newType + '`** to **`' + slug + '`**\n\n' +
|
||||
formatMethodsList([newMethod]) + '\n\n' +
|
||||
'*Executed by @' + actor + '*'
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
const targetType = methodParts[1].toLowerCase();
|
||||
const resourcesStr = methodParts[2];
|
||||
|
||||
// Parse resource fields (only cpu/ram/hdd allowed)
|
||||
const RESOURCE_FIELDS = { cpu: true, ram: true, hdd: true };
|
||||
const resourceChanges = {};
|
||||
const rePairs = /([a-z]+)=(\d+)/gi;
|
||||
let m;
|
||||
while ((m = rePairs.exec(resourcesStr)) !== null) {
|
||||
const key = m[1].toLowerCase();
|
||||
if (RESOURCE_FIELDS[key]) resourceChanges[key] = parseInt(m[2], 10);
|
||||
}
|
||||
if (Object.keys(resourceChanges).length === 0) {
|
||||
await addReaction('-1');
|
||||
await postComment('❌ **PocketBase Bot**: No valid resource fields found. Use `cpu=N`, `ram=N`, `hdd=N`.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Find matching method by type name (case-insensitive)
|
||||
const idx = methodsArr.findIndex(function (im) {
|
||||
return (im.type || '').toLowerCase() === targetType;
|
||||
});
|
||||
if (idx === -1) {
|
||||
await addReaction('-1');
|
||||
const availableTypes = methodsArr.map(function (im) { return im.type || '?'; });
|
||||
} else if (removeMatch) {
|
||||
// ── METHOD REMOVE ────────────────────────────────────────────
|
||||
const removeType = removeMatch[1].toLowerCase();
|
||||
const removed = methodsArr.filter(function (im) { return (im.type || '').toLowerCase() === removeType; });
|
||||
if (removed.length === 0) {
|
||||
await addReaction('-1');
|
||||
const available = methodsArr.map(function (im) { return im.type || '?'; });
|
||||
await postComment('❌ **PocketBase Bot**: No install method `' + removeType + '` found.\n\n**Available:** `' + (available.length ? available.join('`, `') : '(none)') + '`');
|
||||
process.exit(0);
|
||||
}
|
||||
methodsArr = methodsArr.filter(function (im) { return (im.type || '').toLowerCase() !== removeType; });
|
||||
await patchMethods(methodsArr);
|
||||
await revalidate(slug);
|
||||
await addReaction('+1');
|
||||
await postComment(
|
||||
'❌ **PocketBase Bot**: No install method with type `' + targetType + '` found for `' + slug + '`.\n\n' +
|
||||
'**Available types:** `' + (availableTypes.length ? availableTypes.join('`, `') : '(none)') + '`\n\n' +
|
||||
'Use `/pocketbase ' + slug + ' method list` to see all methods.'
|
||||
'✅ **PocketBase Bot**: Removed install method **`' + removed[0].type + '`** from **`' + slug + '`**\n\n' +
|
||||
'*Executed by @' + actor + '*'
|
||||
);
|
||||
|
||||
} else {
|
||||
// ── METHOD EDIT ──────────────────────────────────────────────
|
||||
const editParts = methodArgs.match(/^(\S+)\s+(.+)$/);
|
||||
if (!editParts) {
|
||||
await addReaction('-1');
|
||||
await postComment(
|
||||
'❌ **PocketBase Bot**: Invalid `method` syntax.\n\n' +
|
||||
'**Usage:**\n```\n/pocketbase ' + slug + ' method list\n' +
|
||||
'/pocketbase ' + slug + ' method <type> cpu=4 ram=2048 hdd=20\n' +
|
||||
'/pocketbase ' + slug + ' method <type> config_path="/opt/app/.env"\n' +
|
||||
'/pocketbase ' + slug + ' method add <type> cpu=2 ram=2048 hdd=8\n' +
|
||||
'/pocketbase ' + slug + ' method remove <type>\n```'
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
const targetType = editParts[1].toLowerCase();
|
||||
const parsed = parseKVPairs(editParts[2]);
|
||||
|
||||
const unknown = Object.keys(parsed).filter(function (k) { return !ALL_METHOD_KEYS[k]; });
|
||||
if (unknown.length > 0) {
|
||||
await addReaction('-1');
|
||||
await postComment('❌ **PocketBase Bot**: Unknown method field(s): `' + unknown.join('`, `') + '`\n\n**Allowed:** `' + Object.keys(ALL_METHOD_KEYS).join('`, `') + '`');
|
||||
process.exit(0);
|
||||
}
|
||||
if (Object.keys(parsed).length === 0) {
|
||||
await addReaction('-1');
|
||||
await postComment('❌ **PocketBase Bot**: No valid `key=value` pairs found.\n\n**Allowed:** `' + Object.keys(ALL_METHOD_KEYS).join('`, `') + '`');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const idx = methodsArr.findIndex(function (im) { return (im.type || '').toLowerCase() === targetType; });
|
||||
if (idx === -1) {
|
||||
await addReaction('-1');
|
||||
const available = methodsArr.map(function (im) { return im.type || '?'; });
|
||||
await postComment(
|
||||
'❌ **PocketBase Bot**: No install method `' + targetType + '` found for `' + slug + '`.\n\n' +
|
||||
'**Available:** `' + (available.length ? available.join('`, `') : '(none)') + '`\n\n' +
|
||||
'Use `/pocketbase ' + slug + ' method list` to see all methods.'
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
applyMethodChanges(methodsArr[idx], parsed);
|
||||
await patchMethods(methodsArr);
|
||||
await revalidate(slug);
|
||||
|
||||
const changesLines = Object.entries(parsed)
|
||||
.map(function ([k, v]) {
|
||||
const unit = k === 'ram' ? ' MB' : k === 'hdd' ? ' GB' : '';
|
||||
return '- `' + k + '` → `' + v + unit + '`';
|
||||
}).join('\n');
|
||||
await addReaction('+1');
|
||||
await postComment(
|
||||
'✅ **PocketBase Bot**: Updated install method **`' + methodsArr[idx].type + '`** for **`' + slug + '`**\n\n' +
|
||||
'**Changes applied:**\n' + changesLines + '\n\n' +
|
||||
'*Executed by @' + actor + '*'
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
if (!methodsArr[idx].resources) methodsArr[idx].resources = {};
|
||||
if (resourceChanges.cpu != null) methodsArr[idx].resources.cpu = resourceChanges.cpu;
|
||||
if (resourceChanges.ram != null) methodsArr[idx].resources.ram = resourceChanges.ram;
|
||||
if (resourceChanges.hdd != null) methodsArr[idx].resources.hdd = resourceChanges.hdd;
|
||||
|
||||
await patchInstallMethodsJson(methodsArr);
|
||||
|
||||
const changesLines = Object.entries(resourceChanges)
|
||||
.map(function ([k, v]) { return '- `' + k + '` → `' + v + (k === 'ram' ? ' MB' : k === 'hdd' ? ' GB' : '') + '`'; })
|
||||
.join('\n');
|
||||
await addReaction('+1');
|
||||
await postComment(
|
||||
'✅ **PocketBase Bot**: Updated install method **`' + methodsArr[idx].type + '`** for **`' + slug + '`**\n\n' +
|
||||
'**Changes applied:**\n' + changesLines + '\n\n' +
|
||||
'*Executed by @' + actor + '*'
|
||||
);
|
||||
}
|
||||
|
||||
} else if (setMatch) {
|
||||
// ── SET SUBCOMMAND (multi-line / HTML / special chars via code block) ──
|
||||
// ── SET SUBCOMMAND (value from code block) ───────────────────────
|
||||
const fieldName = setMatch[1].toLowerCase();
|
||||
const SET_ALLOWED = {
|
||||
name: 'string', description: 'string', logo: 'string',
|
||||
@@ -531,6 +692,7 @@ jobs:
|
||||
await postComment('❌ **PocketBase Bot**: PATCH failed for `' + slug + '`:\n```\n' + setPatchRes.body + '\n```');
|
||||
process.exit(1);
|
||||
}
|
||||
await revalidate(slug);
|
||||
const preview = codeBlockValue.length > 300 ? codeBlockValue.substring(0, 300) + '…' : codeBlockValue;
|
||||
await addReaction('+1');
|
||||
await postComment(
|
||||
@@ -541,11 +703,6 @@ jobs:
|
||||
|
||||
} else {
|
||||
// ── FIELD=VALUE PATH ─────────────────────────────────────────────
|
||||
const fieldsStr = rest;
|
||||
|
||||
// Skipped: slug, script_created/updated, created (auto), categories/
|
||||
// install_methods/notes/type (relations), github_data/install_methods_json/
|
||||
// notes_json (auto-generated), execute_in (select relation), last_update_commit (auto)
|
||||
const ALLOWED_FIELDS = {
|
||||
name: 'string',
|
||||
description: 'string',
|
||||
@@ -568,39 +725,7 @@ jobs:
|
||||
deleted_message: 'string',
|
||||
};
|
||||
|
||||
// Field=value parser (handles quoted values and empty=null)
|
||||
function parseFields(str) {
|
||||
const fields = {};
|
||||
let pos = 0;
|
||||
while (pos < str.length) {
|
||||
while (pos < str.length && /\s/.test(str[pos])) pos++;
|
||||
if (pos >= str.length) break;
|
||||
let keyStart = pos;
|
||||
while (pos < str.length && str[pos] !== '=' && !/\s/.test(str[pos])) pos++;
|
||||
const key = str.substring(keyStart, pos).trim();
|
||||
if (!key || pos >= str.length || str[pos] !== '=') { pos++; continue; }
|
||||
pos++;
|
||||
let value;
|
||||
if (str[pos] === '"') {
|
||||
pos++;
|
||||
let valStart = pos;
|
||||
while (pos < str.length && str[pos] !== '"') {
|
||||
if (str[pos] === '\\') pos++;
|
||||
pos++;
|
||||
}
|
||||
value = str.substring(valStart, pos).replace(/\\"/g, '"');
|
||||
if (pos < str.length) pos++;
|
||||
} else {
|
||||
let valStart = pos;
|
||||
while (pos < str.length && !/\s/.test(str[pos])) pos++;
|
||||
value = str.substring(valStart, pos);
|
||||
}
|
||||
fields[key] = value;
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
const parsedFields = parseFields(fieldsStr);
|
||||
const parsedFields = parseKVPairs(rest);
|
||||
|
||||
const unknownFields = Object.keys(parsedFields).filter(function (f) { return !ALLOWED_FIELDS[f]; });
|
||||
if (unknownFields.length > 0) {
|
||||
@@ -655,6 +780,7 @@ jobs:
|
||||
await postComment('❌ **PocketBase Bot**: PATCH failed for `' + slug + '`:\n```\n' + patchRes.body + '\n```');
|
||||
process.exit(1);
|
||||
}
|
||||
await revalidate(slug);
|
||||
await addReaction('+1');
|
||||
const changesLines = Object.entries(payload)
|
||||
.map(function ([k, v]) { return '- `' + k + '` → `' + JSON.stringify(v) + '`'; })
|
||||
|
||||
1
.github/workflows/push-json-to-pocketbase.yml
generated
vendored
1
.github/workflows/push-json-to-pocketbase.yml
generated
vendored
@@ -170,7 +170,6 @@ jobs:
|
||||
website: data.website,
|
||||
logo: data.logo,
|
||||
description: data.description,
|
||||
config_path: data.config_path,
|
||||
default_user: (data.default_credentials && data.default_credentials.username) || data.default_user || null,
|
||||
default_passwd: (data.default_credentials && data.default_credentials.password) || data.default_passwd || null,
|
||||
is_dev: false
|
||||
|
||||
43
.gitignore
vendored
43
.gitignore
vendored
@@ -2,32 +2,14 @@
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Editor & IDE files (keeping .vscode settings but ignoring unnecessary metadata)
|
||||
# Editor & IDE files
|
||||
!.vscode/
|
||||
.vscode/*.workspace
|
||||
.vscode/*.tmp
|
||||
|
||||
# Log and Cache files
|
||||
# Log files
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Python-specific exclusions
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
*.venv/
|
||||
venv/
|
||||
env/
|
||||
*.env
|
||||
|
||||
# API and Backend specific exclusions
|
||||
api/.env
|
||||
api/__pycache__/
|
||||
api/*.sqlite3
|
||||
|
||||
# Install scripts and temporary files
|
||||
install/tmp/
|
||||
@@ -41,7 +23,7 @@ vm/*.vmdk
|
||||
vm/*.iso
|
||||
vm/*.bak
|
||||
|
||||
# Miscellaneous temporary or unnecessary files
|
||||
# Miscellaneous temporary files
|
||||
*.bak
|
||||
*.swp
|
||||
*.swo
|
||||
@@ -49,22 +31,7 @@ vm/*.bak
|
||||
*.tmp
|
||||
*.backup
|
||||
|
||||
# JSON configuration backups
|
||||
# JSON temporary files
|
||||
json/
|
||||
json/*.bak
|
||||
json/*.tmp
|
||||
json/.vscode/
|
||||
|
||||
# Ignore compiled binaries or packaged artifacts
|
||||
*.exe
|
||||
*.dll
|
||||
*.bin
|
||||
*.deb
|
||||
*.rpm
|
||||
*.tar.gz
|
||||
*.zip
|
||||
*.tgz
|
||||
|
||||
# Ignore repository metadata or Git itself
|
||||
.git/
|
||||
.gitignore
|
||||
.vscode/settings.json
|
||||
|
||||
16
.vscode/.editorconfig
generated
vendored
16
.vscode/.editorconfig
generated
vendored
@@ -1,16 +0,0 @@
|
||||
; editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
continuation_indent_size = 2
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = 120
|
||||
tab_width = 2
|
||||
; trim_trailing_whitespace = true ; disabled until files are cleaned up
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
362
CHANGELOG.md
362
CHANGELOG.md
@@ -35,6 +35,9 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +51,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
|
||||
<details>
|
||||
<summary><h4>April (4 entries)</h4></summary>
|
||||
<summary><h4>April (11 entries)</h4></summary>
|
||||
|
||||
[View April 2026 Changelog](.github/changelogs/2026/04.md)
|
||||
|
||||
@@ -439,6 +442,192 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
</details>
|
||||
|
||||
## 2026-04-15
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- Revert "Remove low-install-count CT scripts and installers (#13570)" [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13752](https://github.com/community-scripts/ProxmoxVE/pull/13752))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Domain Monitor: Fix file ownership after update [@tremor021](https://github.com/tremor021) ([#13759](https://github.com/community-scripts/ProxmoxVE/pull/13759))
|
||||
|
||||
- #### 💥 Breaking Changes
|
||||
|
||||
- Reitti: refactor scripts for v4 - remove RabbitMQ and Photon [@MickLesk](https://github.com/MickLesk) ([#13728](https://github.com/community-scripts/ProxmoxVE/pull/13728))
|
||||
|
||||
## 2026-04-14
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- Immich: Pin photo-processing library revisions [@vhsdream](https://github.com/vhsdream) ([#13748](https://github.com/community-scripts/ProxmoxVE/pull/13748))
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- BentoPDF: Nginx fixes [@tremor021](https://github.com/tremor021) ([#13741](https://github.com/community-scripts/ProxmoxVE/pull/13741))
|
||||
- Zerobyte: add git to dependencies to fix bun install failure [@Copilot](https://github.com/Copilot) ([#13721](https://github.com/community-scripts/ProxmoxVE/pull/13721))
|
||||
- alpine-nextcloud-install: do not use deprecated nginx config [@AlexanderStein](https://github.com/AlexanderStein) ([#13726](https://github.com/community-scripts/ProxmoxVE/pull/13726))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Mealie: support v3.15+ Nuxt 4 migration [@MickLesk](https://github.com/MickLesk) ([#13731](https://github.com/community-scripts/ProxmoxVE/pull/13731))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Lyrion: correct service name and version file in update script [@MickLesk](https://github.com/MickLesk) ([#13734](https://github.com/community-scripts/ProxmoxVE/pull/13734))
|
||||
- Changedetection: move env vars from service file to .env [@tremor021](https://github.com/tremor021) ([#13732](https://github.com/community-scripts/ProxmoxVE/pull/13732))
|
||||
|
||||
## 2026-04-13
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Slskd: Remove stale Soularr lock file on startup and redirect logs to stderr [@MickLesk](https://github.com/MickLesk) ([#13669](https://github.com/community-scripts/ProxmoxVE/pull/13669))
|
||||
- Bambuddy: preserve database and archive on update [@Copilot](https://github.com/Copilot) ([#13706](https://github.com/community-scripts/ProxmoxVE/pull/13706))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Immich: Pin version to 2.7.5 [@vhsdream](https://github.com/vhsdream) ([#13715](https://github.com/community-scripts/ProxmoxVE/pull/13715))
|
||||
- Bytestash: auto backup/restore data on update [@MickLesk](https://github.com/MickLesk) ([#13707](https://github.com/community-scripts/ProxmoxVE/pull/13707))
|
||||
- OpenCloud: pin version to 6.0.0 [@vhsdream](https://github.com/vhsdream) ([#13691](https://github.com/community-scripts/ProxmoxVE/pull/13691))
|
||||
|
||||
- #### 💥 Breaking Changes
|
||||
|
||||
- Mealie: pin version to v3.14.0 in install and update scripts [@Copilot](https://github.com/Copilot) ([#13724](https://github.com/community-scripts/ProxmoxVE/pull/13724))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- core: remove unused TEMP_DIR mktemp leak in build_container / clean sonarqube [@MickLesk](https://github.com/MickLesk) ([#13708](https://github.com/community-scripts/ProxmoxVE/pull/13708))
|
||||
|
||||
## 2026-04-12
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Alpine-Wakapi: Remove container checks in update_script function [@MickLesk](https://github.com/MickLesk) ([#13694](https://github.com/community-scripts/ProxmoxVE/pull/13694))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- IronClaw: Install keychain dependencies and launch in a DBus session [@MickLesk](https://github.com/MickLesk) ([#13692](https://github.com/community-scripts/ProxmoxVE/pull/13692))
|
||||
- MeTube: Allow pnpm build scripts to fix ERR_PNPM_IGNORED_BUILDS [@MickLesk](https://github.com/MickLesk) ([#13668](https://github.com/community-scripts/ProxmoxVE/pull/13668))
|
||||
|
||||
## 2026-04-11
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Immich: Ensure newline before appending IMMICH_HELMET_FILE to .env [@MickLesk](https://github.com/MickLesk) ([#13667](https://github.com/community-scripts/ProxmoxVE/pull/13667))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- BentoPDF: replace http-server with nginx to fix WASM initialization timeout [@MickLesk](https://github.com/MickLesk) ([#13625](https://github.com/community-scripts/ProxmoxVE/pull/13625))
|
||||
- Element Synapse: Add MatrixRTC configuration for Element Call support [@MickLesk](https://github.com/MickLesk) ([#13665](https://github.com/community-scripts/ProxmoxVE/pull/13665))
|
||||
- RomM: Use ROMM_BASE_PATH from .env for symlinks and nginx config [@MickLesk](https://github.com/MickLesk) ([#13666](https://github.com/community-scripts/ProxmoxVE/pull/13666))
|
||||
- Immich: Pin version to 2.7.4 [@vhsdream](https://github.com/vhsdream) ([#13661](https://github.com/community-scripts/ProxmoxVE/pull/13661))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Crafty Controller: Wait for credentials file instead of fixed sleep [@MickLesk](https://github.com/MickLesk) ([#13670](https://github.com/community-scripts/ProxmoxVE/pull/13670))
|
||||
- Refactor: Alpine-Wakapi [@tremor021](https://github.com/tremor021) ([#13656](https://github.com/community-scripts/ProxmoxVE/pull/13656))
|
||||
|
||||
## 2026-04-10
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix: ensure trailing newline in redis.conf before appending bind directive [@Copilot](https://github.com/Copilot) ([#13647](https://github.com/community-scripts/ProxmoxVE/pull/13647))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Immich: Pin version to 2.7.3 [@vhsdream](https://github.com/vhsdream) ([#13631](https://github.com/community-scripts/ProxmoxVE/pull/13631))
|
||||
- Homarr: bind Redis to localhost only [@MickLesk](https://github.com/MickLesk) ([#13552](https://github.com/community-scripts/ProxmoxVE/pull/13552))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- tools.func: prevent script crash when entering GitHub token after rate limit [@MickLesk](https://github.com/MickLesk) ([#13638](https://github.com/community-scripts/ProxmoxVE/pull/13638))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- addons: Filebrowser & Filebrowser-Quantum get warning if host install [@MickLesk](https://github.com/MickLesk) ([#13639](https://github.com/community-scripts/ProxmoxVE/pull/13639))
|
||||
|
||||
## 2026-04-09
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- boostack: add: git [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13620](https://github.com/community-scripts/ProxmoxVE/pull/13620))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Update OPNsense version from 25.7 to 26.1 [@tdn131](https://github.com/tdn131) ([#13626](https://github.com/community-scripts/ProxmoxVE/pull/13626))
|
||||
- CheckMK: Bump Default OS to 13 (trixie) + dynamic codename + fix RELEASE-Tag Fetching [@MickLesk](https://github.com/MickLesk) ([#13610](https://github.com/community-scripts/ProxmoxVE/pull/13610))
|
||||
|
||||
## 2026-04-08
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- IronClaw | Alpine-IronClaw ([#13591](https://github.com/community-scripts/ProxmoxVE/pull/13591))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- immich: disable upgrade-insecure-requests CSP directive [@MickLesk](https://github.com/MickLesk) ([#13600](https://github.com/community-scripts/ProxmoxVE/pull/13600))
|
||||
- Immich: v2.7.2 [@vhsdream](https://github.com/vhsdream) ([#13579](https://github.com/community-scripts/ProxmoxVE/pull/13579))
|
||||
- Update flaresolverr-install.sh [@maztheman](https://github.com/maztheman) ([#13584](https://github.com/community-scripts/ProxmoxVE/pull/13584))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- bambuddy: add mkdir before data restore & add ffmpeg dependency [@MickLesk](https://github.com/MickLesk) ([#13601](https://github.com/community-scripts/ProxmoxVE/pull/13601))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- feat: update UHF Server script to use setup_ffmpeg [@zackwithak13](https://github.com/zackwithak13) ([#13564](https://github.com/community-scripts/ProxmoxVE/pull/13564))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- core: add script page badges to descriptions | change donate URL [@MickLesk](https://github.com/MickLesk) ([#13596](https://github.com/community-scripts/ProxmoxVE/pull/13596))
|
||||
|
||||
## 2026-04-07
|
||||
|
||||
### 🗑️ Deleted Scripts
|
||||
|
||||
- Remove low-install-count CT scripts and installers [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#13570](https://github.com/community-scripts/ProxmoxVE/pull/13570))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- core: improve resilience for top Proxmox error codes (209, 215, 118, 206) [@MickLesk](https://github.com/MickLesk) ([#13575](https://github.com/community-scripts/ProxmoxVE/pull/13575))
|
||||
|
||||
## 2026-04-06
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- OpenThread Border Router ([#13536](https://github.com/community-scripts/ProxmoxVE/pull/13536))
|
||||
- Homelable ([#13539](https://github.com/community-scripts/ProxmoxVE/pull/13539))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Papra: check env before copy [@MickLesk](https://github.com/MickLesk) ([#13553](https://github.com/community-scripts/ProxmoxVE/pull/13553))
|
||||
- changedetection: fix: typing_extensions error [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13548](https://github.com/community-scripts/ProxmoxVE/pull/13548))
|
||||
- kasm: fix: fetch latest version [@CrazyWolf13](https://github.com/CrazyWolf13) ([#13547](https://github.com/community-scripts/ProxmoxVE/pull/13547))
|
||||
|
||||
## 2026-04-05
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
@@ -927,173 +1116,4 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
|
||||
|
||||
### 📚 Documentation
|
||||
|
||||
- Update: Docs/website metadata workflow [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12858](https://github.com/community-scripts/ProxmoxVE/pull/12858))
|
||||
|
||||
## 2026-03-12
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- manyfold: fix incorrect port in upstream requests by forwarding original host [@anlopo](https://github.com/anlopo) ([#12812](https://github.com/community-scripts/ProxmoxVE/pull/12812))
|
||||
- SparkyFitness: install pnpm dependencies from workspace root [@MickLesk](https://github.com/MickLesk) ([#12792](https://github.com/community-scripts/ProxmoxVE/pull/12792))
|
||||
- n8n: add build-essential to update dependencies [@MickLesk](https://github.com/MickLesk) ([#12795](https://github.com/community-scripts/ProxmoxVE/pull/12795))
|
||||
- Frigate openvino labelmap patch [@semtex1987](https://github.com/semtex1987) ([#12751](https://github.com/community-scripts/ProxmoxVE/pull/12751))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- Pin Patchmon to 1.4.2 [@vhsdream](https://github.com/vhsdream) ([#12789](https://github.com/community-scripts/ProxmoxVE/pull/12789))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- tools.func: correct PATH escaping in ROCm profile script [@MickLesk](https://github.com/MickLesk) ([#12793](https://github.com/community-scripts/ProxmoxVE/pull/12793))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- core: add mode=generated for unattended frontend installs [@MickLesk](https://github.com/MickLesk) ([#12807](https://github.com/community-scripts/ProxmoxVE/pull/12807))
|
||||
- core: validate storage availability when loading defaults [@MickLesk](https://github.com/MickLesk) ([#12794](https://github.com/community-scripts/ProxmoxVE/pull/12794))
|
||||
|
||||
- #### 🔧 Refactor
|
||||
|
||||
- tools.func: support older NVIDIA driver versions with 2 segments (xxx.xxx) [@MickLesk](https://github.com/MickLesk) ([#12796](https://github.com/community-scripts/ProxmoxVE/pull/12796))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Fix PBS microcode naming [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12834](https://github.com/community-scripts/ProxmoxVE/pull/12834))
|
||||
|
||||
### 📂 Github
|
||||
|
||||
- Cleanup: remove old workflow files [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12818](https://github.com/community-scripts/ProxmoxVE/pull/12818))
|
||||
- Cleanup: remove frontend, move JSONs to json/ top-level [@MickLesk](https://github.com/MickLesk) ([#12813](https://github.com/community-scripts/ProxmoxVE/pull/12813))
|
||||
|
||||
### ❔ Uncategorized
|
||||
|
||||
- Remove json files [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12830](https://github.com/community-scripts/ProxmoxVE/pull/12830))
|
||||
|
||||
## 2026-03-11
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- fix: Init telemetry in addon scripts [@MickLesk](https://github.com/MickLesk) ([#12777](https://github.com/community-scripts/ProxmoxVE/pull/12777))
|
||||
- Tracearr: Increase default disk variable from 5 to 10 [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12762](https://github.com/community-scripts/ProxmoxVE/pull/12762))
|
||||
- Fix Wireguard Dashboard update [@odin568](https://github.com/odin568) ([#12767](https://github.com/community-scripts/ProxmoxVE/pull/12767))
|
||||
|
||||
### 🧰 Tools
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- Coder-Code-Server: Check if config file exists [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12758](https://github.com/community-scripts/ProxmoxVE/pull/12758))
|
||||
|
||||
## 2026-03-10
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- [Fix] Immich: Pin libvips to 8.17.3 [@vhsdream](https://github.com/vhsdream) ([#12744](https://github.com/community-scripts/ProxmoxVE/pull/12744))
|
||||
|
||||
## 2026-03-09
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- Pin Opencloud to 5.2.0 [@vhsdream](https://github.com/vhsdream) ([#12721](https://github.com/community-scripts/ProxmoxVE/pull/12721))
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- [Hotfix] qBittorrent: Disable UPnP port forwarding by default [@vhsdream](https://github.com/vhsdream) ([#12728](https://github.com/community-scripts/ProxmoxVE/pull/12728))
|
||||
- [Quickfix] Opencloud: ensure correct case for binary [@vhsdream](https://github.com/vhsdream) ([#12729](https://github.com/community-scripts/ProxmoxVE/pull/12729))
|
||||
- Omada: Bump libssl [@MickLesk](https://github.com/MickLesk) ([#12724](https://github.com/community-scripts/ProxmoxVE/pull/12724))
|
||||
- openwebui: Ensure required dependencies [@MickLesk](https://github.com/MickLesk) ([#12717](https://github.com/community-scripts/ProxmoxVE/pull/12717))
|
||||
- Frigate: try an OpenVino model build fallback [@MickLesk](https://github.com/MickLesk) ([#12704](https://github.com/community-scripts/ProxmoxVE/pull/12704))
|
||||
- Change cronjob setup to use www-data user [@opastorello](https://github.com/opastorello) ([#12695](https://github.com/community-scripts/ProxmoxVE/pull/12695))
|
||||
- RustDesk Server: Fix check_for_gh_release function call [@tremor021](https://github.com/tremor021) ([#12694](https://github.com/community-scripts/ProxmoxVE/pull/12694))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- feat: improve zigbee2mqtt backup handler [@MickLesk](https://github.com/MickLesk) ([#12714](https://github.com/community-scripts/ProxmoxVE/pull/12714))
|
||||
|
||||
- #### 💥 Breaking Changes
|
||||
|
||||
- Reactive Resume: rewrite for v5 using original repo amruthpilla/reactive-resume [@MickLesk](https://github.com/MickLesk) ([#12705](https://github.com/community-scripts/ProxmoxVE/pull/12705))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- tools: add Alpine (apk) support to ensure_dependencies and is_package_installed [@MickLesk](https://github.com/MickLesk) ([#12703](https://github.com/community-scripts/ProxmoxVE/pull/12703))
|
||||
- tools.func: extend hwaccel with ROCm [@MickLesk](https://github.com/MickLesk) ([#12707](https://github.com/community-scripts/ProxmoxVE/pull/12707))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- feat: add CopycatWarningToast component for user warnings [@BramSuurdje](https://github.com/BramSuurdje) ([#12733](https://github.com/community-scripts/ProxmoxVE/pull/12733))
|
||||
|
||||
## 2026-03-08
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- [Fix] Immich: chown install dir before machine-learning update [@vhsdream](https://github.com/vhsdream) ([#12684](https://github.com/community-scripts/ProxmoxVE/pull/12684))
|
||||
- [Fix] Scanopy: Build generate-fixtures [@vhsdream](https://github.com/vhsdream) ([#12686](https://github.com/community-scripts/ProxmoxVE/pull/12686))
|
||||
- fix: rustdeskserver: use correct repo string [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12682](https://github.com/community-scripts/ProxmoxVE/pull/12682))
|
||||
- NZBGet: Fixes for RAR5 handling [@tremor021](https://github.com/tremor021) ([#12675](https://github.com/community-scripts/ProxmoxVE/pull/12675))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- LXC-Execute: Fix slug [@tremor021](https://github.com/tremor021) ([#12681](https://github.com/community-scripts/ProxmoxVE/pull/12681))
|
||||
|
||||
## 2026-03-07
|
||||
|
||||
### 🆕 New Scripts
|
||||
|
||||
- ImmichFrame ([#12653](https://github.com/community-scripts/ProxmoxVE/pull/12653))
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- Grocy: bump PHP version from 8.3 to 8.5 [@MickLesk](https://github.com/MickLesk) ([#12651](https://github.com/community-scripts/ProxmoxVE/pull/12651))
|
||||
- Check for influxdb3 installation in update_script [@odin568](https://github.com/odin568) ([#12648](https://github.com/community-scripts/ProxmoxVE/pull/12648))
|
||||
- Update Rdtclient to dotnet 10.0 [@asylumexp](https://github.com/asylumexp) ([#12638](https://github.com/community-scripts/ProxmoxVE/pull/12638))
|
||||
- fix(immich): fix update script failing to add Debian testing repo when preferences file already exists [@Copilot](https://github.com/Copilot) ([#12631](https://github.com/community-scripts/ProxmoxVE/pull/12631))
|
||||
|
||||
### 💾 Core
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- tools: add interactive GitHub PAT prompt on rate limit / auth failure [@MickLesk](https://github.com/MickLesk) ([#12652](https://github.com/community-scripts/ProxmoxVE/pull/12652))
|
||||
|
||||
### 🌐 Website
|
||||
|
||||
- #### 📝 Script Information
|
||||
|
||||
- Papra: update repository URL to papra-hq/papra [@MickLesk](https://github.com/MickLesk) ([#12650](https://github.com/community-scripts/ProxmoxVE/pull/12650))
|
||||
|
||||
## 2026-03-06
|
||||
|
||||
### 🚀 Updated Scripts
|
||||
|
||||
- #### 🐞 Bug Fixes
|
||||
|
||||
- RustDesk Server: Fix update script [@tremor021](https://github.com/tremor021) ([#12625](https://github.com/community-scripts/ProxmoxVE/pull/12625))
|
||||
- [Node-RED] Restart service after update [@Aurelien30000](https://github.com/Aurelien30000) ([#12621](https://github.com/community-scripts/ProxmoxVE/pull/12621))
|
||||
- wealthfolio: update cors [@CrazyWolf13](https://github.com/CrazyWolf13) ([#12617](https://github.com/community-scripts/ProxmoxVE/pull/12617))
|
||||
- CryptPad: Better update handling [@tremor021](https://github.com/tremor021) ([#12611](https://github.com/community-scripts/ProxmoxVE/pull/12611))
|
||||
|
||||
- #### ✨ New Features
|
||||
|
||||
- RustDesk Server: Switch to updated repository [@tremor021](https://github.com/tremor021) ([#12083](https://github.com/community-scripts/ProxmoxVE/pull/12083))
|
||||
|
||||
- #### 💥 Breaking Changes
|
||||
|
||||
- Semaphore: Move from BoltDB to SQLite [@tremor021](https://github.com/tremor021) ([#12624](https://github.com/community-scripts/ProxmoxVE/pull/12624))
|
||||
- Update: Docs/website metadata workflow [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#12858](https://github.com/community-scripts/ProxmoxVE/pull/12858))
|
||||
137
CONTRIBUTING.md
Normal file
137
CONTRIBUTING.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Contributing to Proxmox VE Helper-Scripts
|
||||
|
||||
Welcome! We're glad you want to contribute. This guide covers everything you need to add new scripts, improve existing ones, or help in other ways.
|
||||
|
||||
For detailed coding standards and full documentation, visit **[community-scripts.org/docs](https://community-scripts.org/docs)**.
|
||||
|
||||
---
|
||||
|
||||
## How Can I Help?
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **New scripts** must always be submitted to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) first — not to this repository.
|
||||
> PRs with new scripts opened directly against ProxmoxVE **will be closed without review**.
|
||||
> **Bug fixes, improvements, and features for existing scripts** go here (ProxmoxVE).
|
||||
|
||||
| I want to… | Where to go |
|
||||
| :------------------------------------------ | :------------------------------------------------------------------------------------------- |
|
||||
| **Add a brand-new script** | [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) — testing repo for new scripts |
|
||||
| **Fix a bug or improve an existing script** | This repo (ProxmoxVE) — open a PR here |
|
||||
| **Add a feature to an existing script** | This repo (ProxmoxVE) — open a PR here |
|
||||
| Report a bug or broken script | [Open an Issue](https://github.com/community-scripts/ProxmoxVE/issues) |
|
||||
| Request a new script or feature | [Start a Discussion](https://github.com/community-scripts/ProxmoxVE/discussions) |
|
||||
| Report a security vulnerability | [Security Policy](SECURITY.md) |
|
||||
| Chat with contributors | [Discord](https://discord.gg/3AnUqsXnmK) |
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before writing scripts, we recommend setting up:
|
||||
|
||||
- **Visual Studio Code** with these extensions:
|
||||
- [Shell Syntax](https://marketplace.visualstudio.com/items?itemName=bmalehorn.shell-syntax)
|
||||
- [ShellCheck](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck)
|
||||
- [Shell Format](https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format)
|
||||
|
||||
---
|
||||
|
||||
## Script Structure
|
||||
|
||||
Every script consists of two files:
|
||||
|
||||
| File | Purpose |
|
||||
| :--------------------------- | :------------------------------------------------------ |
|
||||
| `ct/AppName.sh` | Container creation, variable setup, and update handling |
|
||||
| `install/AppName-install.sh` | Application installation logic |
|
||||
|
||||
Use existing scripts in [`ct/`](ct/) and [`install/`](install/) as reference. Full coding standards and annotated templates are at **[community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution)**.
|
||||
|
||||
---
|
||||
|
||||
## Contribution Process
|
||||
|
||||
### Adding a new script
|
||||
|
||||
New scripts are **not accepted directly in this repository**. The workflow is:
|
||||
|
||||
1. Fork [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) and clone it
|
||||
2. Create a branch: `git switch -c feat/myapp`
|
||||
3. Write your two script files:
|
||||
- `ct/myapp.sh`
|
||||
- `install/myapp-install.sh`
|
||||
4. Test thoroughly in ProxmoxVED — run the script against a real Proxmox instance
|
||||
5. Open a PR in **ProxmoxVED** for review and testing
|
||||
6. Once accepted and verified there, the script will be promoted to ProxmoxVE by maintainers
|
||||
|
||||
Follow the coding standards at [community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution).
|
||||
|
||||
---
|
||||
|
||||
### Fixing a bug or improving an existing script
|
||||
|
||||
Changes to scripts that already exist in ProxmoxVE go directly here:
|
||||
|
||||
1. Fork **this repository** (ProxmoxVE) and clone it:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/YOUR_USERNAME/ProxmoxVE
|
||||
cd ProxmoxVE
|
||||
```
|
||||
|
||||
2. Create a branch:
|
||||
|
||||
```bash
|
||||
git switch -c fix/myapp-description
|
||||
```
|
||||
|
||||
3. Make your changes to the relevant files in `ct/` and/or `install/`
|
||||
|
||||
4. Open a PR from your fork to `community-scripts/ProxmoxVE/main`
|
||||
|
||||
Your PR should only contain the files you changed. Do not include unrelated modifications.
|
||||
|
||||
---
|
||||
|
||||
## Code Standards
|
||||
|
||||
Key rules at a glance:
|
||||
|
||||
- One script per service — keep them focused
|
||||
- Naming convention: lowercase, hyphen-separated (`my-app.sh`)
|
||||
- Shebang: `#!/usr/bin/env bash`
|
||||
- Quote all variables: `"$VAR"` not `$VAR`
|
||||
- Use lowercase variable names
|
||||
- Do not hardcode credentials or sensitive values
|
||||
|
||||
Full standards and examples: **[community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution)**
|
||||
|
||||
---
|
||||
|
||||
## Developer Mode & Debugging
|
||||
|
||||
Set the `dev_mode` variable to enable debugging features when testing. Flags can be combined (comma-separated):
|
||||
|
||||
```bash
|
||||
dev_mode="trace,keep" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/myapp.sh)"
|
||||
```
|
||||
|
||||
| Flag | Description |
|
||||
| :----------- | :----------------------------------------------------------- |
|
||||
| `trace` | Enables `set -x` for maximum verbosity during execution |
|
||||
| `keep` | Prevents the container from being deleted if the build fails |
|
||||
| `pause` | Pauses execution at key points before customization |
|
||||
| `breakpoint` | Drops to a shell at hardcoded `breakpoint` calls in scripts |
|
||||
| `logs` | Saves detailed build logs to `/var/log/community-scripts/` |
|
||||
| `dryrun` | Bypasses actual container creation (limited support) |
|
||||
| `motd` | Forces an update of the Message of the Day |
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- **Website metadata** (name, description, logo, tags) is managed via the website — use the "Report Issue" link on any script page to request changes. Do not submit metadata changes via repo files.
|
||||
- **JSON files** in `json/` define script properties used by the website. See existing files for structure reference.
|
||||
- Keep PRs small and focused. One fix or feature per PR is ideal.
|
||||
- PRs with **new scripts** opened against ProxmoxVE will be closed — submit them to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) instead.
|
||||
- PRs that fail CI checks will not be merged.
|
||||
368
README.md
368
README.md
@@ -1,283 +1,209 @@
|
||||
<div align="center">
|
||||
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png" height="120px" alt="Proxmox VE Helper-Scripts Logo" />
|
||||
|
||||
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo-81x112.png" height="112px" alt="Proxmox VE Helper-Scripts Logo" />
|
||||
|
||||
<h1>Proxmox VE Helper-Scripts</h1>
|
||||
<p><em>A Community Legacy in Memory of @tteck</em></p>
|
||||
<p><strong>One-command installations for services, containers, and VMs on Proxmox VE</strong><br/>
|
||||
A community project — built on the foundation of <a href="https://github.com/tteck">@tteck</a>'s original work</p>
|
||||
|
||||
<p>
|
||||
<a href="https://community-scripts.org">
|
||||
<img src="https://img.shields.io/badge/🌐_Website-Visit-4c9b3f?style=for-the-badge&labelColor=2d3748" alt="Website" />
|
||||
</a>
|
||||
<a href="https://discord.gg/3AnUqsXnmK">
|
||||
<img src="https://img.shields.io/badge/💬_Discord-Join-7289da?style=for-the-badge&labelColor=2d3748" alt="Discord" />
|
||||
</a>
|
||||
<a href="https://ko-fi.com/community_scripts">
|
||||
<img src="https://img.shields.io/badge/❤️_Support-Donate-FF5F5F?style=for-the-badge&labelColor=2d3748" alt="Donate" />
|
||||
</a>
|
||||
<a href="https://community-scripts.org"><img src="https://img.shields.io/badge/Website-community--scripts.org-4c9b3f?style=flat-square" /></a>
|
||||
<a href="https://discord.gg/3AnUqsXnmK"><img src="https://img.shields.io/badge/Discord-Join_us-7289da?style=flat-square&logo=discord&logoColor=white" /></a>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/stargazers"><img src="https://img.shields.io/github/stars/community-scripts/ProxmoxVE?style=flat-square&label=Stars&color=f5a623" /></a>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/CHANGELOG.md"><img src="https://img.shields.io/badge/Changelog-view-6c5ce7?style=flat-square" /></a>
|
||||
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue?style=flat-square" /></a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/README.md">
|
||||
<img src="https://img.shields.io/badge/🤝_Contribute-Guidelines-ff4785?style=for-the-badge&labelColor=2d3748" alt="Contribute" />
|
||||
</a>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/USER_SUBMITTED_GUIDES.md">
|
||||
<img src="https://img.shields.io/badge/📚_Guides-Read-0077b5?style=for-the-badge&labelColor=2d3748" alt="Guides" />
|
||||
</a>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/blob/main/CHANGELOG.md">
|
||||
<img src="https://img.shields.io/badge/📋_Changelog-View-6c5ce7?style=for-the-badge&labelColor=2d3748" alt="Changelog" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
**Simplify your Proxmox VE setup with community-driven automation scripts**
|
||||
Originally created by tteck, now maintained and expanded by the community
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div align="center">
|
||||
<sub>🙌 <strong>Shoutout to</strong></sub>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://selfh.st/">
|
||||
<img src="https://img.shields.io/badge/selfh.st-Icons_for_Self--Hosted-2563eb?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTIgMkM2LjQ4IDIgMiA2LjQ4IDIgMTJzNC40OCAxMCAxMCAxMCAxMC00LjQ4IDEwLTEwUzE3LjUyIDIgMTIgMnptMCAxOGMtNC40MSAwLTgtMy41OS04LThzMy41OS04IDgtOCA4IDMuNTkgOCA4LTMuNTkgOC04IDh6IiBmaWxsPSJ3aGl0ZSIvPjwvc3ZnPg==&labelColor=1e3a8a" alt="selfh.st Icons" />
|
||||
</a>
|
||||
<br />
|
||||
<sub><a href="https://github.com/selfhst/icons">View on GitHub</a> • Consistent, beautiful icons for 5000+ self-hosted apps</sub>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Key Features
|
||||
## What is this?
|
||||
|
||||
<div align="center">
|
||||
**Simplify your Proxmox VE setup with community-driven automation scripts.**
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" width="25%">
|
||||
<h3>⚡ Quick Setup</h3>
|
||||
<p>One-command installations for popular services and containers</p>
|
||||
</td>
|
||||
<td align="center" width="25%">
|
||||
<h3>⚙️ Flexible Config</h3>
|
||||
<p>Simple mode for beginners, advanced options for power users</p>
|
||||
</td>
|
||||
<td align="center" width="25%">
|
||||
<h3>🔄 Auto Updates</h3>
|
||||
<p>Keep your installations current with built-in update mechanisms</p>
|
||||
</td>
|
||||
<td align="center" width="25%">
|
||||
<h3>🛠️ Easy Management</h3>
|
||||
<p>Post-install scripts for configuration and troubleshooting</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" width="25%">
|
||||
<h3>👥 Community Driven</h3>
|
||||
<p>Actively maintained with contributions from users worldwide</p>
|
||||
</td>
|
||||
<td align="center" width="25%">
|
||||
<h3>📖 Well Documented</h3>
|
||||
<p>Comprehensive guides and community support</p>
|
||||
</td>
|
||||
<td align="center" width="25%">
|
||||
<h3>🔒 Secure</h3>
|
||||
<p>Regular security updates and best practices</p>
|
||||
</td>
|
||||
<td align="center" width="25%">
|
||||
<h3>⚡ Performance</h3>
|
||||
<p>Optimized configurations for best performance</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
Install and configure popular self-hosted services with a single command — no manual package hunting, no config file archaeology. Paste a command into your Proxmox shell, answer a few prompts, and your container or VM is up and running.
|
||||
|
||||
</div>
|
||||
The collection covers hundreds of services across categories like home automation, media servers, networking tools, databases, monitoring stacks, and more.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Requirements
|
||||
## Requirements
|
||||
|
||||
<div align="center">
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" width="33%">
|
||||
<h3>🖥️ Proxmox VE</h3>
|
||||
<p>Version: 8.4.x | 9.0.x | 9.1.x</p>
|
||||
</td>
|
||||
<td align="center" width="33%">
|
||||
<h3>🐧 Operating System</h3>
|
||||
<p>Debian-based with Proxmox Tools</p>
|
||||
</td>
|
||||
<td align="center" width="33%">
|
||||
<h3>🌐 Network</h3>
|
||||
<p>Internet connection required</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
| Component | Details |
|
||||
| -------------- | ------------------------------------------------ |
|
||||
| **Proxmox VE** | Version 8.4, 9.0, or 9.1 |
|
||||
| **Host OS** | Proxmox VE (Debian-based) |
|
||||
| **Access** | Root shell access on the Proxmox host |
|
||||
| **Network** | Internet connection required during installation |
|
||||
|
||||
---
|
||||
|
||||
## 📥 Getting Started
|
||||
## Getting Started
|
||||
|
||||
Choose your preferred installation method:
|
||||
The fastest way to find and run scripts:
|
||||
|
||||
### Method 1: One-Click Web Installer
|
||||
1. Go to **[community-scripts.org](https://community-scripts.org)**
|
||||
2. Search for the service you want (e.g. "Home Assistant", "Nginx Proxy Manager", "Jellyfin")
|
||||
3. Copy the one-line install command from the script page
|
||||
4. Open your **Proxmox Shell** and paste it
|
||||
5. Choose between **Default** or **Advanced** setup and follow the prompts
|
||||
|
||||
The fastest way to get started:
|
||||
|
||||
1. Visit **[community-scripts.org](https://community-scripts.org/)** 🌐
|
||||
2. Search for your desired script (e.g., "Home Assistant", "Docker")
|
||||
3. Copy the bash command displayed on the script page
|
||||
4. Open your **Proxmox Shell** and paste the command
|
||||
5. Press Enter and follow the interactive prompts
|
||||
|
||||
### Method 2: PVEScripts-Local
|
||||
|
||||
Install a convenient script manager directly in your Proxmox UI:
|
||||
|
||||
```bash
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/pve-scripts-local.sh)"
|
||||
```
|
||||
|
||||
This adds a menu to your Proxmox interface for easy script access without visiting the website.
|
||||
|
||||
📖 **Learn more:** [ProxmoxVE-Local Repository](https://github.com/community-scripts/ProxmoxVE-Local)
|
||||
Each script page documents what the container includes, default resource allocation, and post-install notes.
|
||||
|
||||
---
|
||||
|
||||
## 💬 Join the Community
|
||||
## How Scripts Work
|
||||
|
||||
<div align="center">
|
||||
Every script follows the same pattern:
|
||||
|
||||
<table>
|
||||
**Default mode** — Picks sensible resource defaults (CPU, RAM, storage) and asks only the minimum required questions. Most installs finish in under five minutes.
|
||||
|
||||
**Advanced mode** — Gives you full control over container settings, networking, storage backends, and application-level configuration before anything is installed.
|
||||
|
||||
After installation, each container ships with a **post-install helper** accessible from the Proxmox shell. It handles common tasks like:
|
||||
|
||||
- Applying updates to the installed service
|
||||
- Changing application settings without manually editing config files
|
||||
- Basic troubleshooting and log access
|
||||
|
||||
---
|
||||
|
||||
## What's Included
|
||||
|
||||
The repository covers a wide range of categories. A few examples:
|
||||
|
||||
| Category | Examples |
|
||||
| --------------- | --------------------------------------------------- |
|
||||
| Home Automation | Home Assistant, Zigbee2MQTT, ESPHome, Node-RED |
|
||||
| Media | Jellyfin, Plex, Radarr, Sonarr, Immich |
|
||||
| Networking | AdGuard Home, Nginx Proxy Manager, Pi-hole, Traefik |
|
||||
| Monitoring | Grafana, Prometheus, Uptime Kuma, Netdata |
|
||||
| Databases | PostgreSQL, MariaDB, Redis, InfluxDB |
|
||||
| Security | Vaultwarden, CrowdSec, Authentik |
|
||||
| Dev & Tools | Gitea, Portainer, VS Code Server, n8n |
|
||||
|
||||
> Browse the full list at **[community-scripts.org/categories](https://community-scripts.org/categories)** — new scripts are added regularly.
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
This project runs on community contributions. Whether you want to write new scripts, improve existing ones, or just report a bug — every bit helps.
|
||||
|
||||
### Where to start
|
||||
|
||||
| I want to… | Go here |
|
||||
| ------------------------------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| Add a **new** script | [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED) — new scripts are tested here first |
|
||||
| Fix or improve an **existing** script | [Contributing Guidelines](CONTRIBUTING.md) — open a PR in this repo |
|
||||
| Report a bug or broken script | [Issues](https://github.com/community-scripts/ProxmoxVE/issues) |
|
||||
| Request a new script or feature | [Discussions](https://github.com/community-scripts/ProxmoxVE/discussions) |
|
||||
| Report a security vulnerability | [Security Policy](SECURITY.md) |
|
||||
| Get help or chat with other users | [Discord](https://discord.gg/3AnUqsXnmK) |
|
||||
|
||||
### Before you open a PR
|
||||
|
||||
- **New scripts go to [ProxmoxVED](https://github.com/community-scripts/ProxmoxVED), not here.** PRs with new scripts opened directly against this repo will be closed.
|
||||
- Bug fixes and improvements to existing scripts belong in this repo — read the [Contributing Guidelines](CONTRIBUTING.md) first.
|
||||
- Keep PRs focused. One fix or feature per PR.
|
||||
- Document what your script installs and any non-obvious decisions in the corresponding JSON metadata file.
|
||||
|
||||
---
|
||||
|
||||
## Core Team
|
||||
|
||||
<table align="center">
|
||||
<tr>
|
||||
<td align="center" width="33%">
|
||||
<h3>💬 Discord</h3>
|
||||
<p>Real-time chat, support, and discussions</p>
|
||||
<a href="https://discord.gg/3AnUqsXnmK">
|
||||
<img src="https://img.shields.io/badge/Join-7289da?style=for-the-badge&logo=discord&logoColor=white" alt="Discord" />
|
||||
<td align="center">
|
||||
<a href="https://github.com/MickLesk">
|
||||
<img src="https://github.com/MickLesk.png" width="80" height="80" style="border-radius:50%" alt="MickLesk" /><br/>
|
||||
<sub><b>MickLesk</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" width="33%">
|
||||
<h3>💭 Discussions</h3>
|
||||
<p>Feature requests, Q&A, and ideas</p>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/discussions">
|
||||
<img src="https://img.shields.io/badge/Discuss-238636?style=for-the-badge&logo=github&logoColor=white" alt="Discussions" />
|
||||
<td align="center">
|
||||
<a href="https://github.com/michelroegl-brunner">
|
||||
<img src="https://github.com/michelroegl-brunner.png" width="80" height="80" style="border-radius:50%" alt="michelroegl-brunner" /><br/>
|
||||
<sub><b>michelroegl-brunner</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center" width="33%">
|
||||
<h3>🐛 Issues</h3>
|
||||
<p>Bug reports and issue tracking</p>
|
||||
<a href="https://github.com/community-scripts/ProxmoxVE/issues">
|
||||
<img src="https://img.shields.io/badge/Report-d73a4a?style=for-the-badge&logo=github&logoColor=white" alt="Issues" />
|
||||
<td align="center">
|
||||
<a href="https://github.com/BramSuurdje">
|
||||
<img src="https://github.com/BramSuurdje.png" width="80" height="80" style="border-radius:50%" alt="BramSuurdje" /><br/>
|
||||
<sub><b>BramSuurdje</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/CrazyWolf13">
|
||||
<img src="https://github.com/CrazyWolf13.png" width="80" height="80" style="border-radius:50%" alt="CrazyWolf13" /><br/>
|
||||
<sub><b>CrazyWolf13</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/tremor021">
|
||||
<img src="https://github.com/tremor021.png" width="80" height="80" style="border-radius:50%" alt="tremor021" /><br/>
|
||||
<sub><b>tremor021</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/vhsdream">
|
||||
<img src="https://github.com/vhsdream.png" width="80" height="80" style="border-radius:50%" alt="vhsdream" /><br/>
|
||||
<sub><b>vhsdream</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Contribute
|
||||
## Project Activity
|
||||
|
||||
<div align="center">
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center" width="25%">
|
||||
<h3>💻 Code</h3>
|
||||
<p>Add new scripts or improve existing ones</p>
|
||||
</td>
|
||||
<td align="center" width="25%">
|
||||
<h3>📝 Documentation</h3>
|
||||
<p>Write guides, improve READMEs, translate content</p>
|
||||
</td>
|
||||
<td align="center" width="25%">
|
||||
<h3>🧪 Testing</h3>
|
||||
<p>Test scripts and report compatibility issues</p>
|
||||
</td>
|
||||
<td align="center" width="25%">
|
||||
<h3>💡 Ideas</h3>
|
||||
<p>Suggest features or workflow improvements</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
<br />
|
||||
|
||||
👉 Check our **[Contributing Guidelines](https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/README.md)** to get started
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## ❤️ Support the Project
|
||||
|
||||
This project is maintained by volunteers in memory of tteck. Your support helps us maintain infrastructure, improve documentation, and give back to important causes.
|
||||
|
||||
**🎗️ 30% of all donations go directly to cancer research and hospice care**
|
||||
|
||||
<div align="center">
|
||||
|
||||
<a href="https://ko-fi.com/community_scripts">
|
||||
<img src="https://img.shields.io/badge/☕_Buy_us_a_coffee-Support_on_Ko--fi-FF5F5F?style=for-the-badge&labelColor=2d3748" alt="Support on Ko-fi" />
|
||||
</a>
|
||||
|
||||
<br />
|
||||
<sub>Every contribution helps keep this project alive and supports meaningful causes</sub>
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## 📈 Project Statistics
|
||||
<p align="center">
|
||||
<img
|
||||
src="https://repobeats.axiom.co/api/embed/57edde03e00f88d739bdb5b844ff7d07dd079375.svg"
|
||||
alt="Repobeats analytics"
|
||||
width="650"
|
||||
alt="Repository activity"
|
||||
width="700"
|
||||
/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://star-history.com/#community-scripts/ProxmoxVE&Date">
|
||||
<picture>
|
||||
<source
|
||||
media="(prefers-color-scheme: dark)"
|
||||
srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date&theme=dark"
|
||||
/>
|
||||
<source
|
||||
media="(prefers-color-scheme: light)"
|
||||
srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date"
|
||||
/>
|
||||
<img
|
||||
alt="Star History Chart"
|
||||
src="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date"
|
||||
width="650"
|
||||
/>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date&theme=dark" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" />
|
||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" width="700" />
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 📜 License
|
||||
## Support the Project
|
||||
|
||||
This project is licensed under the **[MIT License](LICENSE)** - feel free to use, modify, and distribute.
|
||||
This project is maintained by volunteers. All infrastructure costs come out of pocket, and the work is done in people's spare time.
|
||||
|
||||
**30% of all donations are forwarded directly to cancer research and hospice care** — a cause that was important to tteck.
|
||||
|
||||
<div align="center">
|
||||
<a href="https://ko-fi.com/community_scripts">
|
||||
<img src="https://img.shields.io/badge/Support_on_Ko--fi-FF5F5F?style=for-the-badge&logo=ko-fi&logoColor=white" alt="Support on Ko-fi" />
|
||||
</a>
|
||||
|
||||
<a href="https://community-scripts.org/donate">
|
||||
<img src="https://img.shields.io/badge/Donate-community--scripts.org%2Fdonate-4c9b3f?style=for-the-badge" alt="Donate via community-scripts.org" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the [MIT License](LICENSE) — free to use, modify, and redistribute for personal and commercial purposes.
|
||||
|
||||
See the full license text in [LICENSE](LICENSE).
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
<sub>Made with ❤️ by the Proxmox community in memory of tteck</sub>
|
||||
<br />
|
||||
<sub>Built on the foundation of <a href="https://github.com/tteck">tteck</a>'s original work · <a href="https://github.com/tteck/Proxmox">Original Repository</a></sub><br/>
|
||||
<sub>Maintained and expanded by the community · In memory of tteck</sub><br/>
|
||||
<sub><i>Proxmox® is a registered trademark of <a href="https://www.proxmox.com/en/about/company">Proxmox Server Solutions GmbH</a></i></sub>
|
||||
</div>
|
||||
|
||||
71
ct/alpine-ironclaw.sh
Normal file
71
ct/alpine-ironclaw.sh
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/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/nearai/ironclaw
|
||||
|
||||
APP="Alpine-IronClaw"
|
||||
var_tags="${var_tags:-ai;agent;alpine}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-1024}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-alpine}"
|
||||
var_version="${var_version:-3.23}"
|
||||
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/ironclaw ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "ironclaw-bin" "nearai/ironclaw"; then
|
||||
msg_info "Stopping Service"
|
||||
rc-service ironclaw stop 2>/dev/null || true
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
msg_info "Backing up Configuration"
|
||||
cp /root/.ironclaw/.env /root/ironclaw.env.bak
|
||||
msg_ok "Backed up Configuration"
|
||||
|
||||
fetch_and_deploy_gh_release "ironclaw-bin" "nearai/ironclaw" "prebuild" "latest" "/usr/local/bin" \
|
||||
"ironclaw-$(uname -m)-unknown-linux-musl.tar.gz"
|
||||
chmod +x /usr/local/bin/ironclaw
|
||||
|
||||
msg_info "Restoring Configuration"
|
||||
cp /root/ironclaw.env.bak /root/.ironclaw/.env
|
||||
rm -f /root/ironclaw.env.bak
|
||||
msg_ok "Restored Configuration"
|
||||
|
||||
msg_info "Starting Service"
|
||||
rc-service ironclaw start
|
||||
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} Complete setup by running:${CL}"
|
||||
echo -e "${TAB}${BGN}ironclaw onboard${CL}"
|
||||
echo -e "${INFO}${YW} Then start the service:${CL}"
|
||||
echo -e "${TAB}${BGN}rc-service ironclaw start${CL}"
|
||||
echo -e "${INFO}${YW} Access the Web UI at:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||
echo -e "${INFO}${YW} Auth token and database credentials:${CL}"
|
||||
echo -e "${TAB}${BGN}cat /root/.ironclaw/.env${CL}"
|
||||
@@ -22,8 +22,6 @@ catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -d /opt/wakapi ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
@@ -44,12 +42,10 @@ function update_script() {
|
||||
cp /opt/wakapi/config.yml /opt/wakapi/wakapi_db.db /opt/wakapi-backup/
|
||||
msg_ok "Created backup"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "wakapi" "muety/wakapi" "tarball"
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "wakapi" "muety/wakapi" "prebuild" "latest" "/opt/wakapi" "wakapi_linux_amd64.zip"
|
||||
|
||||
msg_info "Configuring Wakapi"
|
||||
cd /opt/wakapi
|
||||
$STD go mod download
|
||||
$STD go build -o wakapi
|
||||
cp /opt/wakapi-backup/config.yml /opt/wakapi/
|
||||
cp /opt/wakapi-backup/wakapi_db.db /opt/wakapi/
|
||||
rm -rf /opt/wakapi-backup
|
||||
|
||||
@@ -29,6 +29,8 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
ensure_dependencies ffmpeg
|
||||
|
||||
if check_for_gh_release "bambuddy" "maziggy/bambuddy"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop bambuddy
|
||||
@@ -37,6 +39,9 @@ function update_script() {
|
||||
msg_info "Backing up Configuration and Data"
|
||||
cp /opt/bambuddy/.env /opt/bambuddy.env.bak
|
||||
cp -r /opt/bambuddy/data /opt/bambuddy_data_bak
|
||||
[[ -f /opt/bambuddy/bambuddy.db ]] && cp /opt/bambuddy/bambuddy.db /opt/bambuddy.db.bak
|
||||
[[ -f /opt/bambuddy/bambutrack.db ]] && cp /opt/bambuddy/bambutrack.db /opt/bambutrack.db.bak
|
||||
[[ -d /opt/bambuddy/archive ]] && cp -r /opt/bambuddy/archive /opt/bambuddy_archive_bak
|
||||
msg_ok "Backed up Configuration and Data"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bambuddy" "maziggy/bambuddy" "tarball" "latest" "/opt/bambuddy"
|
||||
@@ -54,10 +59,17 @@ function update_script() {
|
||||
msg_ok "Rebuilt Frontend"
|
||||
|
||||
msg_info "Restoring Configuration and Data"
|
||||
mkdir -p /opt/bambuddy/data
|
||||
cp /opt/bambuddy.env.bak /opt/bambuddy/.env
|
||||
cp -r /opt/bambuddy_data_bak/. /opt/bambuddy/data/
|
||||
rm -f /opt/bambuddy.env.bak
|
||||
rm -rf /opt/bambuddy_data_bak
|
||||
[[ -f /opt/bambuddy.db.bak ]] && cp /opt/bambuddy.db.bak /opt/bambuddy/bambuddy.db
|
||||
[[ -f /opt/bambutrack.db.bak ]] && cp /opt/bambutrack.db.bak /opt/bambuddy/bambutrack.db
|
||||
if [[ -d /opt/bambuddy_archive_bak ]]; then
|
||||
mkdir -p /opt/bambuddy/archive
|
||||
cp -r /opt/bambuddy_archive_bak/. /opt/bambuddy/archive/
|
||||
fi
|
||||
rm -f /opt/bambuddy.env.bak /opt/bambuddy.db.bak /opt/bambutrack.db.bak
|
||||
rm -rf /opt/bambuddy_data_bak /opt/bambuddy_archive_bak
|
||||
msg_ok "Restored Configuration and Data"
|
||||
|
||||
msg_info "Starting Service"
|
||||
|
||||
@@ -42,7 +42,6 @@ function update_script() {
|
||||
msg_info "Updating BentoPDF"
|
||||
cd /opt/bentopdf
|
||||
$STD npm ci --no-audit --no-fund
|
||||
$STD npm install http-server -g
|
||||
if [[ -f /opt/production.env ]]; then
|
||||
mv /opt/production.env ./.env.production
|
||||
else
|
||||
@@ -52,15 +51,97 @@ function update_script() {
|
||||
export SIMPLE_MODE=true
|
||||
export VITE_USE_CDN=true
|
||||
$STD npm run build:all
|
||||
if [[ ! -f /opt/bentopdf/dist/config.json ]]; then
|
||||
cat <<'EOF' >/opt/bentopdf/dist/config.json
|
||||
{}
|
||||
EOF
|
||||
fi
|
||||
msg_ok "Updated BentoPDF"
|
||||
|
||||
msg_info "Starting Service"
|
||||
if grep -q '8080' /etc/systemd/system/bentopdf.service; then
|
||||
sed -i -e 's|/bentopdf|/bentopdf/dist|' \
|
||||
-e 's|npx.*|npx http-server -g -b -d false -r --no-dotfiles|' \
|
||||
/etc/systemd/system/bentopdf.service
|
||||
systemctl daemon-reload
|
||||
ensure_dependencies nginx openssl
|
||||
if [[ ! -f /etc/ssl/private/bentopdf-selfsigned.key || ! -f /etc/ssl/certs/bentopdf-selfsigned.crt ]]; then
|
||||
CERT_CN="$(hostname -I | awk '{print $1}')"
|
||||
$STD openssl req -x509 -nodes -newkey rsa:2048 -days 3650 \
|
||||
-keyout /etc/ssl/private/bentopdf-selfsigned.key \
|
||||
-out /etc/ssl/certs/bentopdf-selfsigned.crt \
|
||||
-subj "/CN=${CERT_CN}"
|
||||
fi
|
||||
cat <<'EOF' >/etc/nginx/sites-available/bentopdf
|
||||
server {
|
||||
listen 8080;
|
||||
server_name _;
|
||||
return 301 https://$host:8443$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 8443 ssl;
|
||||
server_name _;
|
||||
ssl_certificate /etc/ssl/certs/bentopdf-selfsigned.crt;
|
||||
ssl_certificate_key /etc/ssl/private/bentopdf-selfsigned.key;
|
||||
root /opt/bentopdf/dist;
|
||||
index index.html;
|
||||
|
||||
# Required for LibreOffice WASM (Word/Excel/PowerPoint to PDF via SharedArrayBuffer)
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
add_header Cross-Origin-Embedder-Policy "require-corp" always;
|
||||
add_header Cross-Origin-Resource-Policy "cross-origin" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
|
||||
gzip_static on;
|
||||
|
||||
location ~* /libreoffice-wasm/soffice\.wasm\.gz$ {
|
||||
gzip off;
|
||||
types {} default_type application/wasm;
|
||||
add_header Content-Encoding gzip;
|
||||
add_header Vary "Accept-Encoding";
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
location ~* /libreoffice-wasm/soffice\.data\.gz$ {
|
||||
gzip off;
|
||||
types {} default_type application/octet-stream;
|
||||
add_header Content-Encoding gzip;
|
||||
add_header Vary "Accept-Encoding";
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
location ~* \.wasm$ {
|
||||
types {} default_type application/wasm;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
location ~* \.(wasm\.gz|data\.gz|data)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ $uri.html =404;
|
||||
}
|
||||
|
||||
error_page 404 /404.html;
|
||||
}
|
||||
EOF
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
ln -sf /etc/nginx/sites-available/bentopdf /etc/nginx/sites-enabled/bentopdf
|
||||
cat <<'EOF' >/etc/systemd/system/bentopdf.service
|
||||
[Unit]
|
||||
Description=BentoPDF Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/sbin/nginx -g "daemon off;"
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl start bentopdf
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
@@ -75,4 +156,4 @@ description
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:8443${CL}"
|
||||
|
||||
@@ -29,6 +29,7 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
setup_mariadb
|
||||
ensure_dependencies git
|
||||
if check_for_gh_release "bookstack" "BookStackApp/BookStack"; then
|
||||
msg_info "Stopping Apache2"
|
||||
systemctl stop apache2
|
||||
|
||||
@@ -29,28 +29,41 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
if check_for_gh_release "bytestash" "jordan-dalby/ByteStash"; then
|
||||
read -rp "${TAB3}Did you make a backup via application WebUI? (y/n): " backuped
|
||||
if [[ "$backuped" =~ ^[Yy]$ ]]; then
|
||||
msg_info "Stopping Services"
|
||||
systemctl stop bytestash-backend bytestash-frontend
|
||||
msg_ok "Services Stopped"
|
||||
msg_info "Stopping Services"
|
||||
systemctl stop bytestash-backend bytestash-frontend
|
||||
msg_ok "Services Stopped"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bytestash" "jordan-dalby/ByteStash" "tarball"
|
||||
|
||||
msg_info "Configuring ByteStash"
|
||||
cd /opt/bytestash/server
|
||||
$STD npm install
|
||||
cd /opt/bytestash/client
|
||||
$STD npm install
|
||||
msg_ok "Updated ByteStash"
|
||||
|
||||
msg_info "Starting Services"
|
||||
systemctl start bytestash-backend bytestash-frontend
|
||||
msg_ok "Started Services"
|
||||
else
|
||||
msg_error "PLEASE MAKE A BACKUP FIRST!"
|
||||
exit
|
||||
msg_info "Backing up data"
|
||||
tmp_dir="/opt/bytestash-data-backup"
|
||||
mkdir -p "$tmp_dir"
|
||||
if [[ -d /opt/bytestash/data ]]; then
|
||||
cp -r /opt/bytestash/data "$tmp_dir"/data
|
||||
elif [[ -d /opt/data ]]; then
|
||||
cp -r /opt/data "$tmp_dir"/data
|
||||
fi
|
||||
msg_ok "Data backed up"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "bytestash" "jordan-dalby/ByteStash" "tarball"
|
||||
|
||||
msg_info "Restoring data"
|
||||
if [[ -d "$tmp_dir"/data ]]; then
|
||||
mkdir -p /opt/bytestash/data
|
||||
cp -r "$tmp_dir"/data/* /opt/bytestash/data/
|
||||
rm -rf "$tmp_dir"
|
||||
fi
|
||||
msg_ok "Data restored"
|
||||
|
||||
msg_info "Configuring ByteStash"
|
||||
cd /opt/bytestash/server
|
||||
$STD npm install
|
||||
cd /opt/bytestash/client
|
||||
$STD npm install
|
||||
msg_ok "Updated ByteStash"
|
||||
|
||||
msg_info "Starting Services"
|
||||
systemctl start bytestash-backend bytestash-frontend
|
||||
msg_ok "Started Services"
|
||||
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
|
||||
@@ -34,11 +34,11 @@ function update_script() {
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
|
||||
msg_info "Updating ${APP}"
|
||||
$STD pip3 install changedetection.io --upgrade
|
||||
$STD pip3 install changedetection.io --upgrade --break-system-packages --ignore-installed typing_extensions
|
||||
msg_ok "Updated ${APP}"
|
||||
|
||||
msg_info "Updating Playwright"
|
||||
$STD pip3 install playwright --upgrade
|
||||
$STD pip3 install playwright --upgrade --break-system-packages
|
||||
msg_ok "Updated Playwright"
|
||||
|
||||
if [[ -f /etc/systemd/system/browserless.service ]]; then
|
||||
|
||||
@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-6}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-12}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
@@ -29,10 +29,11 @@ function update_script() {
|
||||
fi
|
||||
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/checkmk/checkmk/tags | grep "name" | awk '{print substr($2, 3, length($2)-4) }' | tr ' ' '\n' | grep -Ev 'rc|b' | sort -V | tail -n 1)
|
||||
RELEASE="${RELEASE%%+*}"
|
||||
msg_info "Updating ${APP} to v${RELEASE}"
|
||||
$STD omd stop monitoring
|
||||
$STD omd cp monitoring monitoringbackup
|
||||
curl -fsSL "https://download.checkmk.com/checkmk/${RELEASE}/check-mk-raw-${RELEASE}_0.bookworm_amd64.deb" -o "/opt/checkmk.deb"
|
||||
curl -fsSL "https://download.checkmk.com/checkmk/${RELEASE}/check-mk-raw-${RELEASE}_0.$(get_os_info codename)_amd64.deb" -o "/opt/checkmk.deb"
|
||||
$STD apt-get install -y /opt/checkmk.deb
|
||||
$STD omd --force -V ${RELEASE}.cre update --conflict=install monitoring
|
||||
$STD omd start monitoring
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 tteck
|
||||
# Author: tteck (tteckster)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://daemonsync.me/
|
||||
|
||||
APP="Daemon Sync"
|
||||
var_tags="${var_tags:-sync}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-512}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -d /var ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
msg_info "Updating LXC"
|
||||
$STD apt update
|
||||
$STD apt -y upgrade
|
||||
msg_ok "Updated LXC"
|
||||
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 "${TAB}${GATEWAY}${BGN}http://${IP}:8084${CL}"
|
||||
@@ -34,7 +34,7 @@ function update_script() {
|
||||
fi
|
||||
|
||||
if ! grep -Fq "www-data /usr/bin/php /opt/domain-monitor/cron/check_domains.php" /etc/crontab; then
|
||||
echo "0 0 * * * www-data /usr/bin/php /opt/domain-monitor/cron/check_domains.php" >> /etc/crontab
|
||||
echo "0 0 * * * www-data /usr/bin/php /opt/domain-monitor/cron/check_domains.php" >>/etc/crontab
|
||||
fi
|
||||
|
||||
if check_for_gh_release "domain-monitor" "Hosteroid/domain-monitor"; then
|
||||
@@ -52,6 +52,7 @@ function update_script() {
|
||||
msg_info "Updating Domain Monitor"
|
||||
cd /opt/domain-monitor
|
||||
$STD composer install
|
||||
chown -R www-data:www-data /opt/domain-monitor
|
||||
msg_ok "Updated Domain Monitor"
|
||||
|
||||
msg_info "Restoring backup"
|
||||
|
||||
6
ct/headers/alpine-ironclaw
Normal file
6
ct/headers/alpine-ironclaw
Normal file
@@ -0,0 +1,6 @@
|
||||
___ __ _ ____ ________
|
||||
/ | / /___ (_)___ ___ / _/________ ____ / ____/ /___ __ __
|
||||
/ /| | / / __ \/ / __ \/ _ \______ / // ___/ __ \/ __ \/ / / / __ `/ | /| / /
|
||||
/ ___ |/ / /_/ / / / / / __/_____// // / / /_/ / / / / /___/ / /_/ /| |/ |/ /
|
||||
/_/ |_/_/ .___/_/_/ /_/\___/ /___/_/ \____/_/ /_/\____/_/\__,_/ |__/|__/
|
||||
/_/
|
||||
@@ -1,6 +0,0 @@
|
||||
____ _____
|
||||
/ __ \____ ____ ____ ___ ____ ____ / ___/__ ______ _____
|
||||
/ / / / __ `/ _ \/ __ `__ \/ __ \/ __ \ \__ \/ / / / __ \/ ___/
|
||||
/ /_/ / /_/ / __/ / / / / / /_/ / / / / ___/ / /_/ / / / / /__
|
||||
/_____/\__,_/\___/_/ /_/ /_/\____/_/ /_/ /____/\__, /_/ /_/\___/
|
||||
/____/
|
||||
6
ct/headers/homelable
Normal file
6
ct/headers/homelable
Normal file
@@ -0,0 +1,6 @@
|
||||
__ __ __ __ __
|
||||
/ / / /___ ____ ___ ___ / /___ _/ /_ / /__
|
||||
/ /_/ / __ \/ __ `__ \/ _ \/ / __ `/ __ \/ / _ \
|
||||
/ __ / /_/ / / / / / / __/ / /_/ / /_/ / / __/
|
||||
/_/ /_/\____/_/ /_/ /_/\___/_/\__,_/_.___/_/\___/
|
||||
|
||||
6
ct/headers/ironclaw
Normal file
6
ct/headers/ironclaw
Normal file
@@ -0,0 +1,6 @@
|
||||
____ ________
|
||||
/ _/________ ____ / ____/ /___ __ __
|
||||
/ // ___/ __ \/ __ \/ / / / __ `/ | /| / /
|
||||
_/ // / / /_/ / / / / /___/ / /_/ /| |/ |/ /
|
||||
/___/_/ \____/_/ /_/\____/_/\__,_/ |__/|__/
|
||||
|
||||
6
ct/headers/openthread-br
Normal file
6
ct/headers/openthread-br
Normal file
@@ -0,0 +1,6 @@
|
||||
____ ________ __ ____ ____
|
||||
/ __ \____ ___ ____/_ __/ /_ ________ ____ _____/ / / __ )/ __ \
|
||||
/ / / / __ \/ _ \/ __ \/ / / __ \/ ___/ _ \/ __ `/ __ /_____/ __ / /_/ /
|
||||
/ /_/ / /_/ / __/ / / / / / / / / / / __/ /_/ / /_/ /_____/ /_/ / _, _/
|
||||
\____/ .___/\___/_/ /_/_/ /_/ /_/_/ \___/\__,_/\__,_/ /_____/_/ |_|
|
||||
/_/
|
||||
@@ -1,6 +0,0 @@
|
||||
____ _______ ______ __
|
||||
/ __ \/ __/__ \ ___/_ __/___ ____ / /____
|
||||
/ /_/ / /_ __/ // _ \/ / / __ \/ __ \/ / ___/
|
||||
/ ____/ __// __// __/ / / /_/ / /_/ / (__ )
|
||||
/_/ /_/ /____/\___/_/ \____/\____/_/____/
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
______ _____
|
||||
/_ __/_ ______ ___ / ___/___ ____ ________
|
||||
/ / / / / / __ \/ _ \\__ \/ _ \/ __ \/ ___/ _ \
|
||||
/ / / /_/ / /_/ / __/__/ / __/ / / (__ ) __/
|
||||
/_/ \__, / .___/\___/____/\___/_/ /_/____/\___/
|
||||
/____/_/
|
||||
@@ -1,6 +0,0 @@
|
||||
_ __ __ _
|
||||
| | / /__ _________/ /___ ___________(_)___
|
||||
| | / / _ \/ ___/ __ / __ `/ ___/ ___/ / __ \
|
||||
| |/ / __/ / / /_/ / /_/ / /__/ /__/ / /_/ /
|
||||
|___/\___/_/ \__,_/\__,_/\___/\___/_/\____/
|
||||
|
||||
@@ -65,6 +65,8 @@ EOF
|
||||
|
||||
msg_info "Updating Homarr"
|
||||
cp /opt/homarr/redis.conf /etc/redis/redis.conf
|
||||
sed -i -e '$a\' /etc/redis/redis.conf
|
||||
grep -q '^bind 127.0.0.1 -::1$' /etc/redis/redis.conf || echo "bind 127.0.0.1 -::1" >> /etc/redis/redis.conf
|
||||
rm /etc/nginx/nginx.conf
|
||||
cp /opt/homarr/nginx.conf /etc/nginx/templates/nginx.conf
|
||||
msg_ok "Updated Homarr"
|
||||
|
||||
78
ct/homelable.sh
Normal file
78
ct/homelable.sh
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/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
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/Pouzor/homelable
|
||||
|
||||
APP="Homelable"
|
||||
var_tags="${var_tags:-monitoring;network;visualization}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /opt/homelable ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "homelable" "Pouzor/homelable"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop homelable
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
msg_info "Backing up Configuration and Data"
|
||||
cp /opt/homelable/backend/.env /opt/homelable.env.bak
|
||||
cp -r /opt/homelable/data /opt/homelable_data_bak
|
||||
msg_ok "Backed up Configuration and Data"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "homelable" "Pouzor/homelable" "tarball" "latest" "/opt/homelable"
|
||||
|
||||
msg_info "Updating Python Dependencies"
|
||||
cd /opt/homelable/backend
|
||||
$STD uv venv /opt/homelable/backend/.venv
|
||||
$STD uv pip install --python /opt/homelable/backend/.venv/bin/python -r requirements.txt
|
||||
msg_ok "Updated Python Dependencies"
|
||||
|
||||
msg_info "Rebuilding Frontend"
|
||||
cd /opt/homelable/frontend
|
||||
$STD npm ci
|
||||
$STD npm run build
|
||||
msg_ok "Rebuilt Frontend"
|
||||
|
||||
msg_info "Restoring Configuration and Data"
|
||||
cp /opt/homelable.env.bak /opt/homelable/backend/.env
|
||||
cp -r /opt/homelable_data_bak/. /opt/homelable/data/
|
||||
rm -f /opt/homelable.env.bak
|
||||
rm -rf /opt/homelable_data_bak
|
||||
msg_ok "Restored Configuration and Data"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start homelable
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed Successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||
21
ct/immich.sh
21
ct/immich.sh
@@ -109,7 +109,7 @@ EOF
|
||||
msg_ok "Image-processing libraries up to date"
|
||||
fi
|
||||
|
||||
RELEASE="v2.6.3"
|
||||
RELEASE="v2.7.5"
|
||||
if check_for_gh_release "Immich" "immich-app/immich" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
|
||||
if [[ $(cat ~/.immich) > "2.5.1" ]]; then
|
||||
msg_info "Enabling Maintenance Mode"
|
||||
@@ -181,6 +181,12 @@ EOF
|
||||
unset SHARP_IGNORE_GLOBAL_LIBVIPS
|
||||
export SHARP_FORCE_GLOBAL_LIBVIPS=true
|
||||
$STD pnpm --filter immich --frozen-lockfile --prod --no-optional deploy "$APP_DIR"
|
||||
|
||||
# Patch helmet.json: disable upgrade-insecure-requests for HTTP access
|
||||
if [[ -f "$APP_DIR/helmet.json" ]]; then
|
||||
jq '.contentSecurityPolicy.directives["upgrade-insecure-requests"] = null' "$APP_DIR/helmet.json" >"$APP_DIR/helmet.json.tmp" && mv "$APP_DIR/helmet.json.tmp" "$APP_DIR/helmet.json"
|
||||
fi
|
||||
|
||||
cp "$APP_DIR"/package.json "$APP_DIR"/bin
|
||||
sed -i "s|^start|${APP_DIR}/bin/start|" "$APP_DIR"/bin/immich-admin
|
||||
|
||||
@@ -269,6 +275,10 @@ EOF
|
||||
if ! grep -q '^DB_HOSTNAME=' "$INSTALL_DIR"/.env; then
|
||||
sed -i '/^DB_DATABASE_NAME/a DB_HOSTNAME=127.0.0.1' "$INSTALL_DIR"/.env
|
||||
fi
|
||||
if ! grep -q 'HELMET_FILE' "$INSTALL_DIR"/.env; then
|
||||
sed -i -e '$a\' "$INSTALL_DIR"/.env
|
||||
echo "IMMICH_HELMET_FILE=true" >>"$INSTALL_DIR"/.env
|
||||
fi
|
||||
|
||||
if grep -q 'ExecStart=/usr/bin/node' /etc/systemd/system/immich-web.service; then
|
||||
sed -i '/^EnvironmentFile=/d' /etc/systemd/system/immich-web.service
|
||||
@@ -299,7 +309,8 @@ function compile_libjxl() {
|
||||
SOURCE=${SOURCE_DIR}/libjxl
|
||||
JPEGLI_LIBJPEG_LIBRARY_SOVERSION="62"
|
||||
JPEGLI_LIBJPEG_LIBRARY_VERSION="62.3.0"
|
||||
: "${LIBJXL_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libjxl.json)}"
|
||||
LIBJXL_REVISION="794a5dcf0d54f9f0b20d288a12e87afb91d20dfc"
|
||||
# : "${LIBJXL_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libjxl.json)}"
|
||||
if [[ "$LIBJXL_REVISION" != "$(grep 'libjxl' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
|
||||
msg_info "Recompiling libjxl"
|
||||
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
|
||||
@@ -343,7 +354,8 @@ function compile_libjxl() {
|
||||
function compile_libheif() {
|
||||
SOURCE=${SOURCE_DIR}/libheif
|
||||
ensure_dependencies libaom-dev
|
||||
: "${LIBHEIF_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libheif.json)}"
|
||||
LIBHEIF_REVISION="35dad50a9145332a7bfdf1ff6aef6801fb613d68"
|
||||
# : "${LIBHEIF_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libheif.json)}"
|
||||
if [[ "${update:-}" ]] || [[ "$LIBHEIF_REVISION" != "$(grep 'libheif' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
|
||||
msg_info "Recompiling libheif"
|
||||
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
|
||||
@@ -374,7 +386,8 @@ function compile_libheif() {
|
||||
|
||||
function compile_libraw() {
|
||||
SOURCE=${SOURCE_DIR}/libraw
|
||||
: "${LIBRAW_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libraw.json)}"
|
||||
LIBRAW_REVISION="0b56545a4f828743f28a4345cdfdd4c49f9f9a2a"
|
||||
# : "${LIBRAW_REVISION:=$(jq -cr '.revision' "$BASE_DIR"/server/sources/libraw.json)}"
|
||||
if [[ "$LIBRAW_REVISION" != "$(grep 'libraw' ~/.immich_library_revisions | awk '{print $2}')" ]]; then
|
||||
msg_info "Recompiling libraw"
|
||||
[[ -d "$SOURCE" ]] && rm -rf "$SOURCE"
|
||||
|
||||
71
ct/ironclaw.sh
Normal file
71
ct/ironclaw.sh
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/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/nearai/ironclaw
|
||||
|
||||
APP="IronClaw"
|
||||
var_tags="${var_tags:-ai;agent;security}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -f /usr/local/bin/ironclaw ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "ironclaw-bin" "nearai/ironclaw"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop ironclaw
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
msg_info "Backing up Configuration"
|
||||
cp /root/.ironclaw/.env /root/ironclaw.env.bak
|
||||
msg_ok "Backed up Configuration"
|
||||
|
||||
fetch_and_deploy_gh_release "ironclaw-bin" "nearai/ironclaw" "prebuild" "latest" "/usr/local/bin" \
|
||||
"ironclaw-$(uname -m)-unknown-linux-$([[ -f /etc/alpine-release ]] && echo "musl" || echo "gnu").tar.gz"
|
||||
chmod +x /usr/local/bin/ironclaw
|
||||
|
||||
msg_info "Restoring Configuration"
|
||||
cp /root/ironclaw.env.bak /root/.ironclaw/.env
|
||||
rm -f /root/ironclaw.env.bak
|
||||
msg_ok "Restored Configuration"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start ironclaw
|
||||
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} Complete setup by running:${CL}"
|
||||
echo -e "${TAB}${BGN}ironclaw onboard${CL}"
|
||||
echo -e "${INFO}${YW} Then start the service:${CL}"
|
||||
echo -e "${TAB}${BGN}systemctl start ironclaw${CL}"
|
||||
echo -e "${INFO}${YW} Access the Web UI at:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||
echo -e "${INFO}${YW} Auth token and database credentials:${CL}"
|
||||
echo -e "${TAB}${BGN}cat /root/.ironclaw/.env${CL}"
|
||||
26
ct/kasm.sh
26
ct/kasm.sh
@@ -15,6 +15,7 @@ var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-0}"
|
||||
var_fuse="${var_fuse:-yes}"
|
||||
var_tun="${var_tun:-yes}"
|
||||
var_kasm_version="${var_kasm_version:-}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
@@ -32,18 +33,21 @@ function update_script() {
|
||||
|
||||
msg_info "Checking for new version"
|
||||
CURRENT_VERSION=$(readlink -f /opt/kasm/current | awk -F'/' '{print $4}')
|
||||
KASM_URL=$(curl -fsSL "https://www.kasm.com/downloads" | tr '\n' ' ' | grep -oE 'https://kasm-static-content[^"]*kasm_release_[0-9]+\.[0-9]+\.[0-9]+\.[a-z0-9]+\.tar\.gz' | head -n 1)
|
||||
if [[ -z "$KASM_URL" ]]; then
|
||||
SERVICE_IMAGE_URL=$(curl -fsSL "https://www.kasm.com/downloads" | tr '\n' ' ' | grep -oE 'https://kasm-static-content[^"]*kasm_release_service_images_amd64_[0-9]+\.[0-9]+\.[0-9]+\.tar\.gz' | head -n 1)
|
||||
if [[ -n "$SERVICE_IMAGE_URL" ]]; then
|
||||
KASM_VERSION=$(echo "$SERVICE_IMAGE_URL" | sed -E 's/.*kasm_release_service_images_amd64_([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
|
||||
KASM_URL="https://kasm-static-content.s3.amazonaws.com/kasm_release_${KASM_VERSION}.tar.gz"
|
||||
fi
|
||||
else
|
||||
KASM_VERSION=$(echo "$KASM_URL" | sed -E 's/.*kasm_release_([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
|
||||
fi
|
||||
KASM_VERSION=$(curl -s https://kasm.com/downloads | grep -oP '<h1[^>]*>.*?</h1>' | sed -E 's/<\/?h1[^>]*>//g' | grep -oP '\d+\.\d+\.\d+')
|
||||
KASM_URL="https://kasm-static-content.s3.amazonaws.com/kasm_release_${KASM_VERSION:-var_kasm_version}.tar.gz"
|
||||
|
||||
if [[ -z "$KASM_URL" ]] || [[ -z "$KASM_VERSION" ]]; then
|
||||
# KASM_URL=$(curl -fsSL "https://www.kasm.com/downloads" | tr '\n' ' ' | grep -oE 'https://kasm-static-content[^"]*kasm_release_[0-9]+\.[0-9]+\.[0-9]+\.[a-z0-9]+\.tar\.gz' | head -n 1)
|
||||
# if [[ -z "$KASM_URL" ]]; then
|
||||
# SERVICE_IMAGE_URL=$(curl -fsSL "https://www.kasm.com/downloads" | tr '\n' ' ' | grep -oE 'https://kasm-static-content[^"]*kasm_release_service_images_amd64_[0-9]+\.[0-9]+\.[0-9]+\.tar\.gz' | head -n 1)
|
||||
# if [[ -n "$SERVICE_IMAGE_URL" ]]; then
|
||||
# KASM_VERSION=$(echo "$SERVICE_IMAGE_URL" | sed -E 's/.*kasm_release_service_images_amd64_([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
|
||||
# KASM_URL="https://kasm-static-content.s3.amazonaws.com/kasm_release_${KASM_VERSION}.tar.gz"
|
||||
# fi
|
||||
# else
|
||||
# KASM_VERSION=$(echo "$KASM_URL" | sed -E 's/.*kasm_release_([0-9]+\.[0-9]+\.[0-9]+).*/\1/')
|
||||
# fi
|
||||
|
||||
if [[ -z "$KASM_VERSION" ]] || [[ -z "$KASM_URL" ]]; then
|
||||
msg_error "Unable to detect latest Kasm release URL."
|
||||
exit 250
|
||||
fi
|
||||
|
||||
@@ -30,16 +30,16 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
DEB_URL=$(curl -s 'https://lyrion.org/getting-started/' | grep -oP '<a\s[^>]*href="\K[^"]*amd64\.deb(?="[^>]*>)' | head -n 1)
|
||||
DEB_URL=$(curl_with_retry 'https://lyrion.org/getting-started/' | grep -oP '<a\s[^>]*href="\K[^"]*amd64\.deb(?="[^>]*>)' | head -n 1)
|
||||
RELEASE=$(echo "$DEB_URL" | grep -oP 'lyrionmusicserver_\K[0-9.]+(?=_amd64\.deb)')
|
||||
DEB_FILE="/tmp/lyrionmusicserver_${RELEASE}_amd64.deb"
|
||||
if [[ ! -f /opt/lyrion_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/lyrion_version.txt)" ]]; then
|
||||
msg_info "Updating $APP to ${RELEASE}"
|
||||
curl -fsSL -o "$DEB_FILE" "$DEB_URL"
|
||||
curl_with_retry "$DEB_URL" "$DEB_FILE"
|
||||
$STD apt install "$DEB_FILE" -y
|
||||
systemctl restart lyrion
|
||||
$STD rm -f "$DEB_FILE"
|
||||
echo "${RELEASE}" >/opt/${APP}_version.txt
|
||||
systemctl restart lyrionmusicserver
|
||||
rm -f "$DEB_FILE"
|
||||
echo "${RELEASE}" >/opt/lyrion_version.txt
|
||||
msg_ok "Updated $APP to ${RELEASE}"
|
||||
msg_ok "Updated successfully!"
|
||||
else
|
||||
|
||||
10
ct/mealie.sh
10
ct/mealie.sh
@@ -40,7 +40,7 @@ function update_script() {
|
||||
cp -f /opt/mealie/mealie.env /opt/mealie.env
|
||||
msg_ok "Backup completed"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball" "latest" "/opt/mealie"
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "mealie" "mealie-recipes/mealie" "tarball"
|
||||
|
||||
msg_info "Installing Python Dependencies with uv"
|
||||
cd /opt/mealie
|
||||
@@ -49,9 +49,10 @@ function update_script() {
|
||||
|
||||
msg_info "Building Frontend"
|
||||
MEALIE_VERSION=$(<$HOME/.mealie)
|
||||
$STD sed -i "s|https://github.com/mealie-recipes/mealie/commit/|https://github.com/mealie-recipes/mealie/releases/tag/|g" /opt/mealie/frontend/pages/admin/site-settings.vue
|
||||
$STD sed -i "s|value: data.buildId,|value: \"v${MEALIE_VERSION}\",|g" /opt/mealie/frontend/pages/admin/site-settings.vue
|
||||
$STD sed -i "s|value: data.production ? i18n.t(\"about.production\") : i18n.t(\"about.development\"),|value: \"bare-metal\",|g" /opt/mealie/frontend/pages/admin/site-settings.vue
|
||||
SITE_SETTINGS=$(find /opt/mealie/frontend -name "site-settings.vue" -path "*/admin/*" | head -1)
|
||||
$STD sed -i "s|https://github.com/mealie-recipes/mealie/commit/|https://github.com/mealie-recipes/mealie/releases/tag/|g" "$SITE_SETTINGS"
|
||||
$STD sed -i "s|value: data.buildId,|value: \"v${MEALIE_VERSION}\",|g" "$SITE_SETTINGS"
|
||||
$STD sed -i "s|value: data.production ? i18n.t(\"about.production\") : i18n.t(\"about.development\"),|value: \"bare-metal\",|g" "$SITE_SETTINGS"
|
||||
export NUXT_TELEMETRY_DISABLED=1
|
||||
cd /opt/mealie/frontend
|
||||
$STD yarn install --prefer-offline --frozen-lockfile --non-interactive --production=false --network-timeout 1000000
|
||||
@@ -97,4 +98,3 @@ msg_ok "Completed successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:9000${CL}"
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ function update_script() {
|
||||
$STD corepack enable
|
||||
$STD corepack prepare pnpm --activate || true
|
||||
fi
|
||||
echo 'onlyBuiltDependencies=*' >> .npmrc
|
||||
$STD pnpm install --frozen-lockfile
|
||||
$STD pnpm run build
|
||||
msg_ok "Built Frontend"
|
||||
|
||||
@@ -29,7 +29,7 @@ function update_script() {
|
||||
exit
|
||||
fi
|
||||
|
||||
RELEASE="v5.2.0"
|
||||
RELEASE="v6.0.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
|
||||
msg_info "Stopping services"
|
||||
systemctl stop opencloud opencloud-wopi
|
||||
|
||||
87
ct/openthread-br.sh
Normal file
87
ct/openthread-br.sh
Normal file
@@ -0,0 +1,87 @@
|
||||
#!/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://openthread.io/guides/border-router
|
||||
|
||||
APP="OpenThread-BR"
|
||||
var_tags="${var_tags:-thread;iot;border-router;matter}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-4}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-0}"
|
||||
var_tun="${var_tun:-yes}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /opt/ot-br-posix ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
cd /opt/ot-br-posix
|
||||
LOCAL_COMMIT=$(git rev-parse HEAD)
|
||||
$STD git fetch --depth 1 origin main
|
||||
REMOTE_COMMIT=$(git rev-parse origin/main)
|
||||
|
||||
if [[ "${LOCAL_COMMIT}" == "${REMOTE_COMMIT}" ]]; then
|
||||
msg_ok "Already up to date (${LOCAL_COMMIT:0:7})"
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Stopping Services"
|
||||
systemctl stop otbr-web
|
||||
systemctl stop otbr-agent
|
||||
msg_ok "Stopped Services"
|
||||
|
||||
msg_info "Updating Source"
|
||||
$STD git reset --hard origin/main
|
||||
$STD git submodule update --depth 1 --init --recursive
|
||||
msg_ok "Updated Source"
|
||||
|
||||
msg_info "Rebuilding OpenThread Border Router (Patience)"
|
||||
cd /opt/ot-br-posix/build
|
||||
$STD cmake -GNinja \
|
||||
-DBUILD_TESTING=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DOTBR_DBUS=ON \
|
||||
-DOTBR_MDNS=openthread \
|
||||
-DOTBR_REST=ON \
|
||||
-DOTBR_WEB=ON \
|
||||
-DOTBR_BORDER_ROUTING=ON \
|
||||
-DOTBR_BACKBONE_ROUTER=ON \
|
||||
-DOT_FIREWALL=ON \
|
||||
-DOT_POSIX_NAT64_CIDR="192.168.255.0/24" \
|
||||
..
|
||||
$STD ninja
|
||||
$STD ninja install
|
||||
msg_ok "Rebuilt OpenThread Border Router"
|
||||
|
||||
msg_info "Starting Services"
|
||||
systemctl start otbr-agent
|
||||
systemctl start otbr-web
|
||||
msg_ok "Started Services"
|
||||
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 "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
||||
27
ct/papra.sh
27
ct/papra.sh
@@ -35,14 +35,37 @@ function update_script() {
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
msg_info "Backing up Configuration"
|
||||
cp /opt/papra/apps/papra-server/.env /opt/papra_env.bak
|
||||
if [[ -f /opt/papra/apps/papra-server/.env ]]; then
|
||||
cp /opt/papra/apps/papra-server/.env /opt/papra_env.bak
|
||||
fi
|
||||
msg_ok "Backed up Configuration"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "papra" "papra-hq/papra" "tarball"
|
||||
|
||||
msg_info "Building Application"
|
||||
cd /opt/papra
|
||||
cp /opt/papra_env.bak /opt/papra/apps/papra-server/.env
|
||||
if [[ -f /opt/papra_env.bak ]]; then
|
||||
cp /opt/papra_env.bak /opt/papra/apps/papra-server/.env
|
||||
else
|
||||
msg_warn ".env missing, regenerating from defaults"
|
||||
LOCAL_IP=$(hostname -I | awk '{print $1}')
|
||||
cat <<EOF >/opt/papra/apps/papra-server/.env
|
||||
NODE_ENV=production
|
||||
SERVER_SERVE_PUBLIC_DIR=true
|
||||
PORT=1221
|
||||
DATABASE_URL=file:/opt/papra_data/db/db.sqlite
|
||||
DOCUMENT_STORAGE_FILESYSTEM_ROOT=/opt/papra_data/documents
|
||||
PAPRA_CONFIG_DIR=/opt/papra_data
|
||||
AUTH_SECRET=$(cat /opt/papra_data/.secret)
|
||||
BETTER_AUTH_SECRET=$(cat /opt/papra_data/.secret)
|
||||
BETTER_AUTH_TELEMETRY=0
|
||||
CLIENT_BASE_URL=http://${LOCAL_IP}:1221
|
||||
SERVER_BASE_URL=http://${LOCAL_IP}:1221
|
||||
EMAILS_DRY_RUN=true
|
||||
INGESTION_FOLDER_IS_ENABLED=true
|
||||
INGESTION_FOLDER_ROOT_PATH=/opt/papra_data/ingestion
|
||||
EOF
|
||||
fi
|
||||
$STD pnpm install --frozen-lockfile
|
||||
$STD pnpm --filter "@papra/app-client..." run build
|
||||
$STD pnpm --filter "@papra/app-server..." run build
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: TheRealVira
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://pf2etools.com/ | Github: https://github.com/Pf2eToolsOrg/Pf2eTools
|
||||
|
||||
APP="Pf2eTools"
|
||||
var_tags="${var_tags:-wiki}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-512}"
|
||||
var_disk="${var_disk:-6}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d "/opt/${APP}" ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
if check_for_gh_release "pf2etools" "Pf2eToolsOrg/Pf2eTools"; then
|
||||
msg_info "Updating System"
|
||||
$STD apt update
|
||||
$STD apt -y upgrade
|
||||
msg_ok "Updated System"
|
||||
|
||||
rm -rf /opt/Pf2eTools
|
||||
fetch_and_deploy_gh_release "pf2etools" "Pf2eToolsOrg/Pf2eTools" "tarball" "latest" "/opt/Pf2eTools"
|
||||
|
||||
msg_info "Updating ${APP}"
|
||||
cd /opt/Pf2eTools
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
chown -R www-data: "/opt/${APP}"
|
||||
chmod -R 755 "/opt/${APP}"
|
||||
msg_ok "Updated ${APP}"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
||||
210
ct/reitti.sh
210
ct/reitti.sh
@@ -37,39 +37,136 @@ function update_script() {
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d /var/cache/nginx/tiles ]; then
|
||||
msg_info "Installing Nginx Tile Cache"
|
||||
mkdir -p /var/cache/nginx/tiles
|
||||
$STD apt install -y nginx
|
||||
cat <<EOF >/etc/nginx/nginx.conf
|
||||
user www-data;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
http {
|
||||
proxy_cache_path /var/cache/nginx/tiles levels=1:2 keys_zone=tiles:10m max_size=1g inactive=30d use_temp_path=off;
|
||||
server {
|
||||
listen 80;
|
||||
location / {
|
||||
proxy_pass https://tile.openstreetmap.org/;
|
||||
proxy_set_header Host tile.openstreetmap.org;
|
||||
proxy_set_header User-Agent "Reitti/1.0";
|
||||
proxy_cache tiles;
|
||||
proxy_cache_valid 200 30d;
|
||||
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
chown -R www-data:www-data /var/cache/nginx
|
||||
chmod -R 750 /var/cache/nginx
|
||||
systemctl restart nginx
|
||||
echo "reitti.ui.tiles.cache.url=http://127.0.0.1" >> /opt/reitti/application.properties
|
||||
systemctl restart reitti
|
||||
msg_info "Installed Nginx Tile Cache"
|
||||
# Migrate v3 -> v4: Remove RabbitMQ (no longer required) / Photon / Spring Settings
|
||||
if systemctl is-enabled --quiet rabbitmq-server 2>/dev/null; then
|
||||
msg_info "Migrating to v4: Removing RabbitMQ"
|
||||
systemctl stop rabbitmq-server
|
||||
systemctl disable rabbitmq-server
|
||||
$STD apt-get purge -y rabbitmq-server erlang-base
|
||||
$STD apt-get autoremove -y
|
||||
msg_ok "Removed RabbitMQ"
|
||||
fi
|
||||
|
||||
|
||||
if systemctl is-enabled --quiet photon 2>/dev/null; then
|
||||
msg_info "Migrating to v4: Removing Photon service"
|
||||
systemctl stop photon
|
||||
systemctl disable photon
|
||||
rm -f /etc/systemd/system/photon.service
|
||||
systemctl daemon-reload
|
||||
msg_ok "Removed Photon service"
|
||||
fi
|
||||
|
||||
if grep -q "spring.rabbitmq\|PHOTON_BASE_URL\|PROCESSING_WAIT_TIME\|DANGEROUS_LIFE" /opt/reitti/application.properties 2>/dev/null; then
|
||||
msg_info "Migrating to v4: Rewriting application.properties"
|
||||
local DB_URL DB_USER DB_PASS
|
||||
DB_URL=$(grep '^spring.datasource.url=' /opt/reitti/application.properties | cut -d'=' -f2-)
|
||||
DB_USER=$(grep '^spring.datasource.username=' /opt/reitti/application.properties | cut -d'=' -f2-)
|
||||
DB_PASS=$(grep '^spring.datasource.password=' /opt/reitti/application.properties | cut -d'=' -f2-)
|
||||
cp /opt/reitti/application.properties /opt/reitti/application.properties.bak
|
||||
cat <<PROPEOF >/opt/reitti/application.properties
|
||||
# Server configuration
|
||||
server.port=8080
|
||||
server.servlet.context-path=/
|
||||
server.forward-headers-strategy=framework
|
||||
server.compression.enabled=true
|
||||
server.compression.min-response-size=1024
|
||||
server.compression.mime-types=text/plain,application/json
|
||||
|
||||
# Logging configuration
|
||||
logging.level.root=INFO
|
||||
logging.level.org.hibernate.engine.jdbc.spi.SqlExceptionHelper=FATAL
|
||||
logging.level.com.dedicatedcode.reitti=INFO
|
||||
|
||||
# Internationalization
|
||||
spring.messages.basename=messages
|
||||
spring.messages.encoding=UTF-8
|
||||
spring.messages.cache-duration=3600
|
||||
spring.messages.fallback-to-system-locale=false
|
||||
|
||||
# PostgreSQL configuration
|
||||
spring.datasource.url=${DB_URL}
|
||||
spring.datasource.username=${DB_USER}
|
||||
spring.datasource.password=${DB_PASS}
|
||||
spring.datasource.hikari.maximum-pool-size=20
|
||||
|
||||
# Redis configuration
|
||||
spring.data.redis.host=127.0.0.1
|
||||
spring.data.redis.port=6379
|
||||
spring.data.redis.username=
|
||||
spring.data.redis.password=
|
||||
spring.data.redis.database=0
|
||||
spring.cache.redis.key-prefix=
|
||||
|
||||
spring.cache.cache-names=processed-visits,significant-places,users,magic-links,configurations,transport-mode-configs,avatarThumbnails,avatarData,user-settings
|
||||
spring.cache.redis.time-to-live=1d
|
||||
|
||||
# Upload configuration
|
||||
spring.servlet.multipart.max-file-size=5GB
|
||||
spring.servlet.multipart.max-request-size=5GB
|
||||
server.tomcat.max-part-count=100
|
||||
|
||||
# Rqueue configuration
|
||||
rqueue.web.enable=false
|
||||
rqueue.job.enabled=false
|
||||
rqueue.message.durability.in-terminal-state=0
|
||||
rqueue.key.prefix=\${spring.cache.redis.key-prefix}
|
||||
rqueue.message.converter.provider.class=com.dedicatedcode.reitti.config.RQueueCustomMessageConverter
|
||||
|
||||
# Application-specific settings
|
||||
reitti.server.advertise-uri=
|
||||
|
||||
reitti.security.local-login.disable=false
|
||||
|
||||
# OIDC / Security Settings
|
||||
reitti.security.oidc.enabled=false
|
||||
reitti.security.oidc.registration.enabled=false
|
||||
|
||||
reitti.import.batch-size=10000
|
||||
reitti.import.processing-idle-start-time=10
|
||||
|
||||
reitti.geo-point-filter.max-speed-kmh=1000
|
||||
reitti.geo-point-filter.max-accuracy-meters=100
|
||||
reitti.geo-point-filter.history-lookback-hours=24
|
||||
reitti.geo-point-filter.window-size=50
|
||||
|
||||
reitti.process-data.schedule=0 */10 * * * *
|
||||
reitti.process-data.refresh-views.schedule=0 0 4 * * *
|
||||
reitti.imports.schedule=0 5/10 * * * *
|
||||
reitti.imports.owntracks-recorder.schedule=\${reitti.imports.schedule}
|
||||
|
||||
# Geocoding service configuration
|
||||
reitti.geocoding.max-errors=10
|
||||
reitti.geocoding.photon.base-url=
|
||||
|
||||
# Tiles Configuration
|
||||
reitti.ui.tiles.cache.url=http://127.0.0.1
|
||||
reitti.ui.tiles.default.service=https://tile.openstreetmap.org/{z}/{x}/{y}.png
|
||||
reitti.ui.tiles.default.attribution=© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors
|
||||
|
||||
# Data management configuration
|
||||
reitti.data-management.enabled=false
|
||||
reitti.data-management.preview-cleanup.cron=0 0 4 * * *
|
||||
|
||||
reitti.storage.path=data/
|
||||
reitti.storage.cleanup.cron=0 0 4 * * *
|
||||
|
||||
# Location data density normalization
|
||||
reitti.location.density.target-points-per-minute=4
|
||||
|
||||
# Logging buffer
|
||||
reitti.logging.buffer-size=1000
|
||||
reitti.logging.max-buffer-size=10000
|
||||
|
||||
spring.config.import=optional:oidc.properties
|
||||
PROPEOF
|
||||
# Update reitti.service dependencies
|
||||
if [[ -f /etc/systemd/system/reitti.service ]]; then
|
||||
sed -i 's/ rabbitmq-server\.service//g; s/ photon\.service//g' /etc/systemd/system/reitti.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
msg_ok "Rewrote application.properties (backup: application.properties.bak)"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "reitti" "dedicatedcode/reitti"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop reitti
|
||||
@@ -83,55 +180,6 @@ EOF
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start reitti
|
||||
chown -R www-data:www-data /var/cache/nginx
|
||||
chmod -R 750 /var/cache/nginx
|
||||
systemctl restart nginx
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
|
||||
if check_for_gh_release "photon" "komoot/photon"; then
|
||||
if [[ -f "$HOME/.photon" ]] && [[ "$(cat "$HOME/.photon")" == 0.7 ]]; then
|
||||
CURRENT_VERSION="$(<"$HOME/.photon")"
|
||||
echo
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "Photon v1 upgrade detected (breaking change)"
|
||||
echo
|
||||
echo "Your current version: $CURRENT_VERSION"
|
||||
echo
|
||||
echo "Photon v1 requires a manual migration before updating."
|
||||
echo
|
||||
echo "You need to:"
|
||||
echo " 1. Remove existing geocoding data (not actual reitti data):"
|
||||
echo " rm -rf /opt/photon_data"
|
||||
echo
|
||||
echo " 2. Follow the inial setup guide again:"
|
||||
echo " https://github.com/community-scripts/ProxmoxVE/discussions/8737"
|
||||
echo
|
||||
echo " 3. Re-download and import Photon data for v1"
|
||||
echo
|
||||
read -rp "Do you want to continue anyway? (y/N): " CONTINUE
|
||||
echo
|
||||
|
||||
if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then
|
||||
msg_info "Migration required. Update cancelled."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
msg_warn "Continuing without migration may break Photon in the future!"
|
||||
fi
|
||||
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop photon
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
rm -f /opt/photon/photon.jar
|
||||
USE_ORIGINAL_FILENAME="true" fetch_and_deploy_gh_release "photon" "komoot/photon" "singlefile" "latest" "/opt/photon" "photon-*.jar"
|
||||
mv /opt/photon/photon-*.jar /opt/photon/photon.jar
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start photon
|
||||
systemctl restart nginx
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
|
||||
@@ -54,8 +54,12 @@ function update_script() {
|
||||
# Merge static assets into dist folder
|
||||
cp -rf /opt/romm/frontend/assets/* /opt/romm/frontend/dist/assets/
|
||||
mkdir -p /opt/romm/frontend/dist/assets/romm
|
||||
ln -sfn /var/lib/romm/resources /opt/romm/frontend/dist/assets/romm/resources
|
||||
ln -sfn /var/lib/romm/assets /opt/romm/frontend/dist/assets/romm/assets
|
||||
ROMM_BASE=$(grep '^ROMM_BASE_PATH=' /opt/romm/.env | cut -d'=' -f2)
|
||||
ROMM_BASE=${ROMM_BASE:-/var/lib/romm}
|
||||
ln -sfn "$ROMM_BASE"/resources /opt/romm/frontend/dist/assets/romm/resources
|
||||
ln -sfn "$ROMM_BASE"/assets /opt/romm/frontend/dist/assets/romm/assets
|
||||
sed -i "s|alias .*/library/;|alias ${ROMM_BASE}/library/;|" /etc/nginx/sites-available/romm
|
||||
systemctl reload nginx
|
||||
msg_ok "Updated ROMM"
|
||||
|
||||
msg_info "Starting Services"
|
||||
|
||||
@@ -43,6 +43,7 @@ function update_script() {
|
||||
RELEASE=$(get_latest_github_release "SonarSource/sonarqube")
|
||||
curl -fsSL "https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-${RELEASE}.zip" -o $temp_file
|
||||
unzip -q "$temp_file" -d /opt
|
||||
rm -f "$temp_file"
|
||||
mv /opt/sonarqube-${RELEASE} /opt/sonarqube
|
||||
echo "${RELEASE}" > ~/.sonarqube
|
||||
msg_ok "Updated SonarQube"
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: tlissak | Co-Author MickLesk
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://typesense.org/
|
||||
|
||||
APP="TypeSense"
|
||||
var_tags="${var_tags:-database}"
|
||||
var_cpu="${var_cpu:-1}"
|
||||
var_ram="${var_ram:-1024}"
|
||||
var_disk="${var_disk:-4}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -f /etc/typesense/typesense-server.ini ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
if check_for_gh_release "typesense" "typesense/typesense"; then
|
||||
msg_info "Updating Typesense"
|
||||
$STD apt update
|
||||
$STD apt -y upgrade
|
||||
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 IP:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}${IP}:8108${CL}"
|
||||
@@ -38,8 +38,14 @@ function update_script() {
|
||||
$STD apt -y upgrade
|
||||
msg_ok "Updated LXC"
|
||||
|
||||
msg_info "Updating UHF Server"
|
||||
if dpkg -l ffmpeg 2>&1 | grep -q "ii"; then
|
||||
apt remove ffmpeg -y && apt autoremove -y
|
||||
fi
|
||||
setup_ffmpeg
|
||||
fetch_and_deploy_gh_release "comskip" "swapplications/comskip" "prebuild" "latest" "/opt/comskip" "comskip-x64-*.zip"
|
||||
fetch_and_deploy_gh_release "uhf-server" "swapplications/uhf-server-dist" "prebuild" "latest" "/opt/uhf-server" "UHF.Server-linux-x64-*.zip"
|
||||
msg_ok "Updated UHF Server"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start uhf-server
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: BrynnJKnight
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://verdaccio.org/ | Github: https://github.com/verdaccio/verdaccio
|
||||
|
||||
APP="Verdaccio"
|
||||
var_tags="${var_tags:-dev-tools;npm;registry}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -f /etc/systemd/system/verdaccio.service ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
msg_info "Updating LXC Container"
|
||||
$STD apt update
|
||||
$STD apt upgrade -y
|
||||
msg_ok "Updated LXC Container"
|
||||
|
||||
NODE_VERSION="24" NODE_MODULE="verdaccio" setup_nodejs
|
||||
systemctl restart verdaccio
|
||||
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 "${TAB}${GATEWAY}${BGN}http://${IP}:4873${CL}"
|
||||
@@ -38,6 +38,7 @@ function update_script() {
|
||||
cp /opt/zerobyte/.env /opt/zerobyte.env.bak
|
||||
msg_ok "Backed up Configuration"
|
||||
|
||||
ensure_dependencies git
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "zerobyte" "nicotsx/zerobyte" "tarball"
|
||||
|
||||
|
||||
532
docs/DEV_MODE.md
532
docs/DEV_MODE.md
@@ -1,532 +0,0 @@
|
||||
# Dev Mode - Debugging & Development Guide
|
||||
|
||||
Development modes provide powerful debugging and testing capabilities for container creation and installation processes.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Single mode
|
||||
export dev_mode="motd"
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/wallabag.sh)"
|
||||
|
||||
# Multiple modes (comma-separated)
|
||||
export dev_mode="motd,keep,trace"
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/wallabag.sh)"
|
||||
|
||||
# Combine with verbose output
|
||||
export var_verbose="yes"
|
||||
export dev_mode="pause,logs"
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/wallabag.sh)"
|
||||
```
|
||||
|
||||
## Available Modes
|
||||
|
||||
### 1. **motd** - Early SSH/MOTD Setup
|
||||
|
||||
Sets up SSH access and MOTD **before** the main application installation.
|
||||
|
||||
**Use Case**:
|
||||
|
||||
- Quick access to container for manual debugging
|
||||
- Continue installation manually if something goes wrong
|
||||
- Verify container networking before main install
|
||||
|
||||
**Behavior**:
|
||||
|
||||
```
|
||||
✔ Container created
|
||||
✔ Network configured
|
||||
[DEV] Setting up MOTD and SSH before installation
|
||||
✔ [DEV] MOTD/SSH ready - container accessible
|
||||
# Container is now accessible via SSH while installation proceeds
|
||||
```
|
||||
|
||||
**Combined with**: `keep`, `breakpoint`, `logs`
|
||||
|
||||
---
|
||||
|
||||
### 2. **keep** - Preserve Container on Failure
|
||||
|
||||
Never delete the container when installation fails. Skips cleanup prompt.
|
||||
|
||||
**Use Case**:
|
||||
|
||||
- Repeated tests of the same installation
|
||||
- Debugging failed installations
|
||||
- Manual fix attempts
|
||||
|
||||
**Behavior**:
|
||||
|
||||
```
|
||||
✖ Installation failed in container 107 (exit code: 1)
|
||||
✔ Container creation log: /tmp/create-lxc-107-abc12345.log
|
||||
✔ Installation log: /tmp/install-lxc-107-abc12345.log
|
||||
|
||||
🔧 [DEV] Keep mode active - container 107 preserved
|
||||
root@proxmox:~#
|
||||
```
|
||||
|
||||
**Container remains**: `pct enter 107` to access and debug
|
||||
|
||||
**Combined with**: `motd`, `trace`, `logs`
|
||||
|
||||
---
|
||||
|
||||
### 3. **trace** - Bash Command Tracing
|
||||
|
||||
Enables `set -x` for complete command-line tracing. Shows every command before execution.
|
||||
|
||||
**Use Case**:
|
||||
|
||||
- Deep debugging of installation logic
|
||||
- Understanding script flow
|
||||
- Identifying where errors occur exactly
|
||||
|
||||
**Behavior**:
|
||||
|
||||
```
|
||||
+(/opt/wallabag/bin/console): /opt/wallabag/bin/console cache:warmup
|
||||
+(/opt/wallabag/bin/console): env APP_ENV=prod /opt/wallabag/bin/console cache:warmup
|
||||
+(/opt/wallabag/bin/console): [[ -d /opt/wallabag/app/cache ]]
|
||||
+(/opt/wallabag/bin/console): rm -rf /opt/wallabag/app/cache/*
|
||||
```
|
||||
|
||||
**⚠️ Warning**: Exposes passwords and secrets in log output! Only use in isolated environments.
|
||||
|
||||
**Log Output**: All trace output saved to logs (see `logs` mode)
|
||||
|
||||
**Combined with**: `keep`, `pause`, `logs`
|
||||
|
||||
---
|
||||
|
||||
### 4. **pause** - Step-by-Step Execution
|
||||
|
||||
Pauses after each major step (`msg_info`). Requires manual Enter press to continue.
|
||||
|
||||
**Use Case**:
|
||||
|
||||
- Inspect container state between steps
|
||||
- Understand what each step does
|
||||
- Identify which step causes problems
|
||||
|
||||
**Behavior**:
|
||||
|
||||
```
|
||||
⏳ Setting up Container OS
|
||||
[PAUSE] Press Enter to continue...
|
||||
⏳ Updating Container OS
|
||||
[PAUSE] Press Enter to continue...
|
||||
⏳ Installing Dependencies
|
||||
[PAUSE] Press Enter to continue...
|
||||
```
|
||||
|
||||
**Between pauses**: You can open another terminal and inspect the container
|
||||
|
||||
```bash
|
||||
# In another terminal while paused
|
||||
pct enter 107
|
||||
root@container:~# df -h # Check disk usage
|
||||
root@container:~# ps aux # Check running processes
|
||||
```
|
||||
|
||||
**Combined with**: `motd`, `keep`, `logs`
|
||||
|
||||
---
|
||||
|
||||
### 5. **breakpoint** - Interactive Shell on Error
|
||||
|
||||
Opens interactive shell inside the container when an error occurs instead of cleanup prompt.
|
||||
|
||||
**Use Case**:
|
||||
|
||||
- Live debugging in the actual container
|
||||
- Manual command testing
|
||||
- Inspect container state at point of failure
|
||||
|
||||
**Behavior**:
|
||||
|
||||
```
|
||||
✖ Installation failed in container 107 (exit code: 1)
|
||||
✔ Container creation log: /tmp/create-lxc-107-abc12345.log
|
||||
✔ Installation log: /tmp/install-lxc-107-abc12345.log
|
||||
|
||||
🐛 [DEV] Breakpoint mode - opening shell in container 107
|
||||
Type 'exit' to return to host
|
||||
root@wallabag:~#
|
||||
|
||||
# Now you can debug:
|
||||
root@wallabag:~# tail -f /root/.install-abc12345.log
|
||||
root@wallabag:~# mysql -u root -p$PASSWORD wallabag
|
||||
root@wallabag:~# apt-get install -y strace
|
||||
root@wallabag:~# exit
|
||||
|
||||
Container 107 still running. Remove now? (y/N): n
|
||||
🔧 Container 107 kept for debugging
|
||||
```
|
||||
|
||||
**Combined with**: `keep`, `logs`, `trace`
|
||||
|
||||
---
|
||||
|
||||
### 6. **logs** - Persistent Logging
|
||||
|
||||
Saves all logs to `/var/log/community-scripts/` with timestamps. Logs persist even on successful installation.
|
||||
|
||||
**Use Case**:
|
||||
|
||||
- Post-mortem analysis
|
||||
- Performance analysis
|
||||
- Automated testing with log collection
|
||||
- CI/CD integration
|
||||
|
||||
**Behavior**:
|
||||
|
||||
```
|
||||
Logs location: /var/log/community-scripts/
|
||||
|
||||
create-lxc-abc12345-20251117_143022.log (host-side creation)
|
||||
install-abc12345-20251117_143022.log (container-side installation)
|
||||
```
|
||||
|
||||
**Access logs**:
|
||||
|
||||
```bash
|
||||
# View creation log
|
||||
tail -f /var/log/community-scripts/create-lxc-*.log
|
||||
|
||||
# Search for errors
|
||||
grep ERROR /var/log/community-scripts/*.log
|
||||
|
||||
# Analyze performance
|
||||
grep "msg_info\|msg_ok" /var/log/community-scripts/create-*.log
|
||||
```
|
||||
|
||||
**With trace mode**: Creates detailed trace of all commands
|
||||
|
||||
```bash
|
||||
grep "^+" /var/log/community-scripts/install-*.log
|
||||
```
|
||||
|
||||
**Combined with**: All other modes (recommended for CI/CD)
|
||||
|
||||
---
|
||||
|
||||
### 7. **dryrun** - Simulation Mode
|
||||
|
||||
Shows all commands that would be executed without actually running them.
|
||||
|
||||
**Use Case**:
|
||||
|
||||
- Test script logic without making changes
|
||||
- Verify command syntax
|
||||
- Understand what will happen
|
||||
- Pre-flight checks
|
||||
|
||||
**Behavior**:
|
||||
|
||||
```
|
||||
[DRYRUN] apt-get update
|
||||
[DRYRUN] apt-get install -y curl
|
||||
[DRYRUN] mkdir -p /opt/wallabag
|
||||
[DRYRUN] cd /opt/wallabag
|
||||
[DRYRUN] git clone https://github.com/wallabag/wallabag.git .
|
||||
```
|
||||
|
||||
**No actual changes made**: Container/system remains unchanged
|
||||
|
||||
**Combined with**: `trace` (shows dryrun trace), `logs` (shows what would run)
|
||||
|
||||
---
|
||||
|
||||
## Mode Combinations
|
||||
|
||||
### Development Workflow
|
||||
|
||||
```bash
|
||||
# First test: See what would happen
|
||||
export dev_mode="dryrun,logs"
|
||||
bash -c "$(curl ...)"
|
||||
|
||||
# Then test with tracing and pauses
|
||||
export dev_mode="pause,trace,logs"
|
||||
bash -c "$(curl ...)"
|
||||
|
||||
# Finally full debug with early SSH access
|
||||
export dev_mode="motd,keep,breakpoint,logs"
|
||||
bash -c "$(curl ...)"
|
||||
```
|
||||
|
||||
### CI/CD Integration
|
||||
|
||||
```bash
|
||||
# Automated testing with full logging
|
||||
export dev_mode="logs"
|
||||
export var_verbose="yes"
|
||||
bash -c "$(curl ...)"
|
||||
|
||||
# Capture logs for analysis
|
||||
tar czf installation-logs-$(date +%s).tar.gz /var/log/community-scripts/
|
||||
```
|
||||
|
||||
### Production-like Testing
|
||||
|
||||
```bash
|
||||
# Keep containers for manual verification
|
||||
export dev_mode="keep,logs"
|
||||
for i in {1..5}; do
|
||||
bash -c "$(curl ...)"
|
||||
done
|
||||
|
||||
# Inspect all created containers
|
||||
pct list
|
||||
pct enter 100
|
||||
```
|
||||
|
||||
### Live Debugging
|
||||
|
||||
```bash
|
||||
# SSH in early, step through installation, debug on error
|
||||
export dev_mode="motd,pause,breakpoint,keep"
|
||||
bash -c "$(curl ...)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables Reference
|
||||
|
||||
### Dev Mode Variables
|
||||
|
||||
- `dev_mode` (string): Comma-separated list of modes
|
||||
- Format: `"motd,keep,trace"`
|
||||
- Default: Empty (no dev modes)
|
||||
|
||||
### Output Control
|
||||
|
||||
- `var_verbose="yes"`: Show all command output (disables silent mode)
|
||||
- Pairs well with: `trace`, `pause`, `logs`
|
||||
|
||||
### Examples with vars
|
||||
|
||||
```bash
|
||||
# Maximum verbosity and debugging
|
||||
export var_verbose="yes"
|
||||
export dev_mode="motd,trace,pause,logs"
|
||||
bash -c "$(curl ...)"
|
||||
|
||||
# Silent debug (logs only)
|
||||
export dev_mode="keep,logs"
|
||||
bash -c "$(curl ...)"
|
||||
|
||||
# Interactive debugging
|
||||
export var_verbose="yes"
|
||||
export dev_mode="motd,breakpoint"
|
||||
bash -c "$(curl ...)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting with Dev Mode
|
||||
|
||||
### "Installation failed at step X"
|
||||
|
||||
```bash
|
||||
export dev_mode="pause,logs"
|
||||
# Step through until the failure point
|
||||
# Check container state between pauses
|
||||
pct enter 107
|
||||
```
|
||||
|
||||
### "Password/credentials not working"
|
||||
|
||||
```bash
|
||||
export dev_mode="motd,keep,trace"
|
||||
# With trace mode, see exact password handling (be careful with logs!)
|
||||
# Use motd to SSH in and test manually
|
||||
ssh root@container-ip
|
||||
```
|
||||
|
||||
### "Permission denied errors"
|
||||
|
||||
```bash
|
||||
export dev_mode="breakpoint,keep"
|
||||
# Get shell at failure point
|
||||
# Check file permissions, user context, SELinux status
|
||||
ls -la /path/to/file
|
||||
whoami
|
||||
```
|
||||
|
||||
### "Networking issues"
|
||||
|
||||
```bash
|
||||
export dev_mode="motd"
|
||||
# SSH in with motd mode before main install
|
||||
ssh root@container-ip
|
||||
ping 8.8.8.8
|
||||
nslookup example.com
|
||||
```
|
||||
|
||||
### "Need to manually complete installation"
|
||||
|
||||
```bash
|
||||
export dev_mode="motd,keep"
|
||||
# Container accessible via SSH while installation runs
|
||||
# After failure, SSH in and manually continue
|
||||
ssh root@container-ip
|
||||
# ... manual commands ...
|
||||
exit
|
||||
# Then use 'keep' mode to preserve container for inspection
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Log Files Locations
|
||||
|
||||
### Default (without `logs` mode)
|
||||
|
||||
- Host creation: `/tmp/create-lxc-<SESSION_ID>.log`
|
||||
- Container install: Copied to `/tmp/install-lxc-<CTID>-<SESSION_ID>.log` on failure
|
||||
|
||||
### With `logs` mode
|
||||
|
||||
- Host creation: `/var/log/community-scripts/create-lxc-<SESSION_ID>-<TIMESTAMP>.log`
|
||||
- Container install: `/var/log/community-scripts/install-<SESSION_ID>-<TIMESTAMP>.log`
|
||||
|
||||
### View logs
|
||||
|
||||
```bash
|
||||
# Tail in real-time
|
||||
tail -f /var/log/community-scripts/*.log
|
||||
|
||||
# Search for errors
|
||||
grep -r "exit code [1-9]" /var/log/community-scripts/
|
||||
|
||||
# Filter by session
|
||||
grep "ed563b19" /var/log/community-scripts/*.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO
|
||||
|
||||
- Use `logs` mode for CI/CD and automated testing
|
||||
- Use `motd` for early SSH access during long installations
|
||||
- Use `pause` when learning the installation flow
|
||||
- Use `trace` when debugging logic issues (watch for secrets!)
|
||||
- Combine modes for comprehensive debugging
|
||||
- Archive logs after successful tests
|
||||
|
||||
### ❌ DON'T
|
||||
|
||||
- Use `trace` in production or with untrusted networks (exposes secrets)
|
||||
- Leave `keep` mode enabled for unattended scripts (containers accumulate)
|
||||
- Use `dryrun` and expect actual changes
|
||||
- Commit `dev_mode` exports to production deployment scripts
|
||||
- Use `breakpoint` in non-interactive environments (will hang)
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Debug a Failed Installation
|
||||
|
||||
```bash
|
||||
# Initial test to see the failure
|
||||
export dev_mode="keep,logs"
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/wallabag.sh)"
|
||||
|
||||
# Container 107 kept, check logs
|
||||
tail /var/log/community-scripts/install-*.log
|
||||
|
||||
# SSH in to debug
|
||||
pct enter 107
|
||||
root@wallabag:~# cat /root/.install-*.log | tail -100
|
||||
root@wallabag:~# apt-get update # Retry the failing command
|
||||
root@wallabag:~# exit
|
||||
|
||||
# Re-run with manual step-through
|
||||
export dev_mode="motd,pause,keep"
|
||||
bash -c "$(curl ...)"
|
||||
```
|
||||
|
||||
### Example 2: Verify Installation Steps
|
||||
|
||||
```bash
|
||||
export dev_mode="pause,logs"
|
||||
export var_verbose="yes"
|
||||
bash -c "$(curl ...)"
|
||||
|
||||
# Press Enter through each step
|
||||
# Monitor container in another terminal
|
||||
# pct enter 107
|
||||
# Review logs in real-time
|
||||
```
|
||||
|
||||
### Example 3: CI/CD Pipeline Integration
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
export dev_mode="logs"
|
||||
export var_verbose="no"
|
||||
|
||||
for app in wallabag nextcloud wordpress; do
|
||||
echo "Testing $app installation..."
|
||||
APP="$app" bash -c "$(curl ...)" || {
|
||||
echo "FAILED: $app"
|
||||
tar czf logs-$app.tar.gz /var/log/community-scripts/
|
||||
exit 1
|
||||
}
|
||||
echo "SUCCESS: $app"
|
||||
done
|
||||
|
||||
echo "All installations successful"
|
||||
tar czf all-logs.tar.gz /var/log/community-scripts/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Custom Log Analysis
|
||||
|
||||
```bash
|
||||
# Extract all errors
|
||||
grep "ERROR\|exit code [1-9]" /var/log/community-scripts/*.log
|
||||
|
||||
# Performance timeline
|
||||
grep "^$(date +%Y-%m-%d)" /var/log/community-scripts/*.log | grep "msg_"
|
||||
|
||||
# Memory usage during install
|
||||
grep "free\|available" /var/log/community-scripts/*.log
|
||||
```
|
||||
|
||||
### Integration with External Tools
|
||||
|
||||
```bash
|
||||
# Send logs to Elasticsearch
|
||||
curl -X POST "localhost:9200/installation-logs/_doc" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d @/var/log/community-scripts/install-*.log
|
||||
|
||||
# Archive for compliance
|
||||
tar czf installation-records-$(date +%Y%m).tar.gz \
|
||||
/var/log/community-scripts/
|
||||
gpg --encrypt installation-records-*.tar.gz
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Support & Issues
|
||||
|
||||
When reporting installation issues, always include:
|
||||
|
||||
```bash
|
||||
# Collect all relevant information
|
||||
export dev_mode="logs"
|
||||
# Run the failing installation
|
||||
# Then provide:
|
||||
tar czf debug-logs.tar.gz /var/log/community-scripts/
|
||||
```
|
||||
|
||||
Include the `debug-logs.tar.gz` when reporting issues for better diagnostics.
|
||||
@@ -1,298 +0,0 @@
|
||||
# Exit Code Reference
|
||||
|
||||
Comprehensive documentation of all exit codes used in ProxmoxVE scripts.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Generic/Shell Errors (1-255)](#genericshell-errors)
|
||||
- [Package Manager Errors (100-101, 255)](#package-manager-errors)
|
||||
- [Node.js/npm Errors (243-254)](#nodejsnpm-errors)
|
||||
- [Python/pip Errors (210-212)](#pythonpip-errors)
|
||||
- [Database Errors (231-254)](#database-errors)
|
||||
- [Proxmox Custom Codes (200-231)](#proxmox-custom-codes)
|
||||
|
||||
---
|
||||
|
||||
## Generic/Shell Errors
|
||||
|
||||
Standard Unix/Linux exit codes used across all scripts.
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | --------------------------------------- | ----------------------------------------- | ---------------------------------------------- |
|
||||
| **1** | General error / Operation not permitted | Permission denied, general failure | Check user permissions, run as root if needed |
|
||||
| **2** | Misuse of shell builtins | Syntax error in script | Review script syntax, check bash version |
|
||||
| **126** | Command cannot execute | Permission problem, not executable | `chmod +x script.sh` or check file permissions |
|
||||
| **127** | Command not found | Missing binary, wrong PATH | Install required package, check PATH variable |
|
||||
| **128** | Invalid argument to exit | Invalid exit code passed | Use exit codes 0-255 only |
|
||||
| **130** | Terminated by Ctrl+C (SIGINT) | User interrupted script | Expected behavior, no action needed |
|
||||
| **137** | Killed (SIGKILL) | Out of memory, forced termination | Check memory usage, increase RAM allocation |
|
||||
| **139** | Segmentation fault | Memory access violation, corrupted binary | Reinstall package, check system stability |
|
||||
| **143** | Terminated (SIGTERM) | Graceful shutdown signal | Expected during container stops |
|
||||
|
||||
---
|
||||
|
||||
## Package Manager Errors
|
||||
|
||||
APT, DPKG, and package installation errors.
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | -------------------------- | --------------------------------------- | ------------------------------------------------- |
|
||||
| **100** | APT: Package manager error | Broken packages, dependency conflicts | `apt --fix-broken install`, `dpkg --configure -a` |
|
||||
| **101** | APT: Configuration error | Malformed sources.list, bad repo config | Check `/etc/apt/sources.list`, run `apt update` |
|
||||
| **255** | DPKG: Fatal internal error | Corrupted package database | `dpkg --configure -a`, restore from backup |
|
||||
|
||||
---
|
||||
|
||||
## Node.js/npm Errors
|
||||
|
||||
Node.js runtime and package manager errors.
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | ------------------------------------------ | ------------------------------ | ---------------------------------------------- |
|
||||
| **243** | Node.js: Out of memory | JavaScript heap exhausted | Increase `--max-old-space-size`, optimize code |
|
||||
| **245** | Node.js: Invalid command-line option | Wrong Node.js flags | Check Node.js version, verify CLI options |
|
||||
| **246** | Node.js: Internal JavaScript Parse Error | Syntax error in JS code | Review JavaScript syntax, check dependencies |
|
||||
| **247** | Node.js: Fatal internal error | Node.js runtime crash | Update Node.js, check for known bugs |
|
||||
| **248** | Node.js: Invalid C++ addon / N-API failure | Native module incompatibility | Rebuild native modules, update packages |
|
||||
| **249** | Node.js: Inspector error | Debug/inspect protocol failure | Disable inspector, check port conflicts |
|
||||
| **254** | npm/pnpm/yarn: Unknown fatal error | Package manager crash | Clear cache, reinstall package manager |
|
||||
|
||||
---
|
||||
|
||||
## Python/pip Errors
|
||||
|
||||
Python runtime and package installation errors.
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | ------------------------------------ | --------------------------------------- | -------------------------------------------------------- |
|
||||
| **210** | Python: Virtualenv missing or broken | venv not created, corrupted environment | `python3 -m venv venv`, recreate virtualenv |
|
||||
| **211** | Python: Dependency resolution failed | Conflicting package versions | Use `pip install --upgrade`, check requirements.txt |
|
||||
| **212** | Python: Installation aborted | EXTERNALLY-MANAGED, permission denied | Use `--break-system-packages` or venv, check permissions |
|
||||
|
||||
---
|
||||
|
||||
## Database Errors
|
||||
|
||||
### PostgreSQL (231-234)
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | ----------------------- | ---------------------------------- | ----------------------------------------------------- |
|
||||
| **231** | Connection failed | Server not running, wrong socket | `systemctl start postgresql`, check connection string |
|
||||
| **232** | Authentication failed | Wrong credentials | Verify username/password, check `pg_hba.conf` |
|
||||
| **233** | Database does not exist | Database not created | `CREATE DATABASE`, restore from backup |
|
||||
| **234** | Fatal error in query | Syntax error, constraint violation | Review SQL syntax, check constraints |
|
||||
|
||||
### MySQL/MariaDB (241-244)
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | ----------------------- | ---------------------------------- | ---------------------------------------------------- |
|
||||
| **241** | Connection failed | Server not running, wrong socket | `systemctl start mysql`, check connection parameters |
|
||||
| **242** | Authentication failed | Wrong credentials | Verify username/password, grant privileges |
|
||||
| **243** | Database does not exist | Database not created | `CREATE DATABASE`, restore from backup |
|
||||
| **244** | Fatal error in query | Syntax error, constraint violation | Review SQL syntax, check constraints |
|
||||
|
||||
### MongoDB (251-254)
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | --------------------- | -------------------- | ------------------------------------------ |
|
||||
| **251** | Connection failed | Server not running | `systemctl start mongod`, check port 27017 |
|
||||
| **252** | Authentication failed | Wrong credentials | Verify username/password, create user |
|
||||
| **253** | Database not found | Database not created | Database auto-created on first write |
|
||||
| **254** | Fatal query error | Invalid query syntax | Review MongoDB query syntax |
|
||||
|
||||
---
|
||||
|
||||
## Proxmox Custom Codes
|
||||
|
||||
Custom exit codes specific to ProxmoxVE scripts.
|
||||
|
||||
### Container Creation Errors (200-209)
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | ---------------------------------------------- | ------------------------------------------------------- | ------------------------------------------------------- |
|
||||
| **200** | Failed to create lock file | Permission denied, disk full | Check `/tmp` permissions, free disk space |
|
||||
| **203** | Missing CTID variable | Script configuration error | Set CTID in script or via prompt |
|
||||
| **204** | Missing PCT_OSTYPE variable | Template selection failed | Verify template availability |
|
||||
| **205** | Invalid CTID (<100) | CTID below minimum value | Use CTID ≥ 100 (1-99 reserved for Proxmox) |
|
||||
| **206** | CTID already in use | Container/VM with same ID exists | Check `pct list` and `/etc/pve/lxc/`, use different ID |
|
||||
| **207** | Password contains unescaped special characters | Special chars like `-`, `/`, `\`, `*` at start/end | Avoid leading special chars, use alphanumeric passwords |
|
||||
| **208** | Invalid configuration | DNS format (`.home` vs `home`), MAC format (`-` vs `:`) | Remove leading dots from DNS, use `:` in MAC addresses |
|
||||
| **209** | Container creation failed | Multiple possible causes | Check logs in `/tmp/pct_create_*.log`, verify template |
|
||||
|
||||
### Cluster & Storage Errors (210, 214, 217)
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | --------------------------------- | ---------------------------------- | ----------------------------------------------------------- |
|
||||
| **210** | Cluster not quorate | Cluster nodes down, network issues | Check cluster status: `pvecm status`, fix node connectivity |
|
||||
| **211** | Timeout waiting for template lock | Concurrent download in progress | Wait for other download to complete (60s timeout) |
|
||||
| **214** | Not enough storage space | Disk full, quota exceeded | Free disk space, increase storage allocation |
|
||||
| **217** | Storage does not support rootdir | Wrong storage type selected | Use storage supporting containers (dir, zfspool, lvm-thin) |
|
||||
|
||||
### Container Verification Errors (215-216)
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | -------------------------------- | -------------------------------- | --------------------------------------------------------- |
|
||||
| **215** | Container created but not listed | Ghost state, incomplete creation | Check `/etc/pve/lxc/CTID.conf`, remove manually if needed |
|
||||
| **216** | RootFS entry missing in config | Incomplete container creation | Delete container, retry creation |
|
||||
|
||||
### Template Errors (218, 220-223, 225)
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | ----------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------- |
|
||||
| **218** | Template file corrupted or incomplete | Download interrupted, file <1MB, invalid archive | Delete template, run `pveam update && pveam download` |
|
||||
| **220** | Unable to resolve template path | Template storage not accessible | Check storage availability, verify permissions |
|
||||
| **221** | Template file exists but not readable | Permission denied | `chmod 644 template.tar.zst`, check storage permissions |
|
||||
| **222** | Template download failed after 3 attempts | Network issues, storage problems | Check internet connectivity, verify storage space |
|
||||
| **223** | Template not available after download | Storage sync issue, I/O delay | Wait a few seconds, verify storage is mounted |
|
||||
| **225** | No template available for OS/Version | Unsupported OS version, catalog outdated | Run `pveam update`, check `pveam available -section system` |
|
||||
|
||||
### LXC Stack Errors (231)
|
||||
|
||||
| Code | Description | Common Causes | Solutions |
|
||||
| ------- | ------------------------------ | ------------------------------------------- | -------------------------------------------- |
|
||||
| **231** | LXC stack upgrade/retry failed | Outdated `pve-container`, Debian 13.1 issue | See [Debian 13.1 Fix Guide](#debian-131-fix) |
|
||||
|
||||
---
|
||||
|
||||
## Special Case: Debian 13.1 "unsupported version" Error
|
||||
|
||||
### Problem
|
||||
|
||||
```
|
||||
TASK ERROR: unable to create CT 129 - unsupported debian version '13.1'
|
||||
```
|
||||
|
||||
### Root Cause
|
||||
|
||||
Outdated `pve-container` package doesn't recognize Debian 13 (Trixie).
|
||||
|
||||
### Solutions
|
||||
|
||||
#### Option 1: Full System Upgrade (Recommended)
|
||||
|
||||
```bash
|
||||
apt update
|
||||
apt full-upgrade -y
|
||||
reboot
|
||||
```
|
||||
|
||||
Verify fix:
|
||||
|
||||
```bash
|
||||
dpkg -l pve-container
|
||||
# PVE 8: Should show 5.3.3+
|
||||
# PVE 9: Should show 6.0.13+
|
||||
```
|
||||
|
||||
#### Option 2: Update Only pve-container
|
||||
|
||||
```bash
|
||||
apt update
|
||||
apt install --only-upgrade pve-container -y
|
||||
```
|
||||
|
||||
**Warning:** If Proxmox fails to boot after this, your system was inconsistent. Perform Option 1 instead.
|
||||
|
||||
#### Option 3: Verify Repository Configuration
|
||||
|
||||
Many users disable Enterprise repos but forget to add no-subscription repos.
|
||||
|
||||
**For PVE 9 (Trixie):**
|
||||
|
||||
```bash
|
||||
cat /etc/apt/sources.list.d/pve-no-subscription.list
|
||||
```
|
||||
|
||||
Should contain:
|
||||
|
||||
```
|
||||
deb http://download.proxmox.com/debian/pve trixie pve-no-subscription
|
||||
deb http://download.proxmox.com/debian/ceph-squid trixie no-subscription
|
||||
```
|
||||
|
||||
**For PVE 8 (Bookworm):**
|
||||
|
||||
```
|
||||
deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription
|
||||
deb http://download.proxmox.com/debian/ceph-quincy bookworm no-subscription
|
||||
```
|
||||
|
||||
Then:
|
||||
|
||||
```bash
|
||||
apt update
|
||||
apt full-upgrade -y
|
||||
```
|
||||
|
||||
### Reference
|
||||
|
||||
Official discussion: [GitHub #8126](https://github.com/community-scripts/ProxmoxVE/discussions/8126)
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting Tips
|
||||
|
||||
### Finding Error Details
|
||||
|
||||
1. **Check logs:**
|
||||
|
||||
```bash
|
||||
tail -n 50 /tmp/pct_create_*.log
|
||||
```
|
||||
|
||||
2. **Enable verbose mode:**
|
||||
|
||||
```bash
|
||||
bash -x script.sh # Shows every command executed
|
||||
```
|
||||
|
||||
3. **Check container status:**
|
||||
|
||||
```bash
|
||||
pct list
|
||||
pct status CTID
|
||||
```
|
||||
|
||||
4. **Verify storage:**
|
||||
```bash
|
||||
pvesm status
|
||||
df -h
|
||||
```
|
||||
|
||||
### Common Patterns
|
||||
|
||||
- **Exit 0 with error message:** Configuration validation failed (check DNS, MAC, password format)
|
||||
- **Exit 206 but container not visible:** Ghost container state - check `/etc/pve/lxc/` manually
|
||||
- **Exit 209 generic error:** Check `/tmp/pct_create_*.log` for specific `pct create` failure reason
|
||||
- **Exit 218 or 222:** Template issues - delete and re-download template
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Chart
|
||||
|
||||
| Exit Code Range | Category | Typical Issue |
|
||||
| --------------- | ------------------ | ------------------------------------------- |
|
||||
| 1-2, 126-143 | Shell/System | Permissions, signals, missing commands |
|
||||
| 100-101, 255 | Package Manager | APT/DPKG errors, broken packages |
|
||||
| 200-209 | Container Creation | CTID, password, configuration |
|
||||
| 210-217 | Storage/Cluster | Disk space, quorum, storage type |
|
||||
| 218-225 | Templates | Download, corruption, availability |
|
||||
| 231-254 | Databases/Runtime | PostgreSQL, MySQL, MongoDB, Node.js, Python |
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Found an undocumented exit code or have a solution to share? Please:
|
||||
|
||||
1. Open an issue on [GitHub](https://github.com/community-scripts/ProxmoxVE/issues)
|
||||
2. Include:
|
||||
- Exit code number
|
||||
- Error message
|
||||
- Steps to reproduce
|
||||
- Solution that worked for you
|
||||
|
||||
---
|
||||
|
||||
_Last updated: November 2025_
|
||||
_ProxmoxVE Version: 2.x_
|
||||
298
docs/README.md
298
docs/README.md
@@ -1,298 +0,0 @@
|
||||
# 📚 ProxmoxVE Documentation
|
||||
|
||||
Complete guide to all ProxmoxVE documentation - quickly find what you need.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 **Quick Navigation by Goal**
|
||||
|
||||
### 👤 **I want to...**
|
||||
|
||||
**Contribute a new application**
|
||||
→ Start with: [contribution/README.md](contribution/README.md)
|
||||
→ Then: [ct/DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md) + [install/DETAILED_GUIDE.md](install/DETAILED_GUIDE.md)
|
||||
|
||||
**Understand the architecture**
|
||||
→ Read: [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md)
|
||||
→ Then: [misc/README.md](misc/README.md)
|
||||
|
||||
**Debug a failed installation**
|
||||
→ Check: [EXIT_CODES.md](EXIT_CODES.md)
|
||||
→ Then: [DEV_MODE.md](DEV_MODE.md)
|
||||
→ See also: [misc/error_handler.func/](misc/error_handler.func/)
|
||||
|
||||
**Configure system defaults**
|
||||
→ Read: [guides/DEFAULTS_SYSTEM_GUIDE.md](guides/DEFAULTS_SYSTEM_GUIDE.md)
|
||||
|
||||
**Deploy containers automatically**
|
||||
→ Read: [guides/UNATTENDED_DEPLOYMENTS.md](guides/UNATTENDED_DEPLOYMENTS.md)
|
||||
|
||||
**Develop a function library**
|
||||
→ Study: [misc/](misc/) documentation
|
||||
|
||||
---
|
||||
|
||||
## 👤 **Quick Start by Role**
|
||||
|
||||
### **I'm a...**
|
||||
|
||||
**New Contributor**
|
||||
→ Start: [contribution/README.md](contribution/README.md)
|
||||
→ Then: Choose your path below
|
||||
|
||||
**Container Creator**
|
||||
→ Read: [ct/README.md](ct/README.md)
|
||||
→ Deep Dive: [ct/DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md)
|
||||
→ Reference: [misc/build.func/](misc/build.func/)
|
||||
|
||||
**Installation Script Developer**
|
||||
→ Read: [install/README.md](install/README.md)
|
||||
→ Deep Dive: [install/DETAILED_GUIDE.md](install/DETAILED_GUIDE.md)
|
||||
→ Reference: [misc/tools.func/](misc/tools.func/)
|
||||
|
||||
**VM Provisioner**
|
||||
→ Read: [vm/README.md](vm/README.md)
|
||||
→ Reference: [misc/cloud-init.func/](misc/cloud-init.func/)
|
||||
|
||||
**Tools Developer**
|
||||
→ Read: [tools/README.md](tools/README.md)
|
||||
→ Reference: [misc/build.func/](misc/build.func/)
|
||||
|
||||
**API Integrator**
|
||||
→ Read: [api/README.md](api/README.md)
|
||||
→ Reference: [misc/api.func/](misc/api.func/)
|
||||
|
||||
**System Operator**
|
||||
→ Start: [EXIT_CODES.md](EXIT_CODES.md)
|
||||
→ Then: [guides/DEFAULTS_SYSTEM_GUIDE.md](guides/DEFAULTS_SYSTEM_GUIDE.md)
|
||||
→ Automate: [guides/UNATTENDED_DEPLOYMENTS.md](guides/UNATTENDED_DEPLOYMENTS.md)
|
||||
→ Debug: [DEV_MODE.md](DEV_MODE.md)
|
||||
|
||||
**Architect**
|
||||
→ Read: [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md)
|
||||
→ Deep Dive: [misc/README.md](misc/README.md)
|
||||
|
||||
---
|
||||
|
||||
## 📂 **Documentation Structure**
|
||||
|
||||
### Project-Mirrored Directories
|
||||
|
||||
Each major project directory has documentation:
|
||||
|
||||
```
|
||||
ProxmoxVE/
|
||||
├─ ct/ ↔ docs/ct/ (README.md + DETAILED_GUIDE.md)
|
||||
├─ install/ ↔ docs/install/ (README.md + DETAILED_GUIDE.md)
|
||||
├─ vm/ ↔ docs/vm/ (README.md)
|
||||
├─ tools/ ↔ docs/tools/ (README.md)
|
||||
├─ api/ ↔ docs/api/ (README.md)
|
||||
├─ misc/ ↔ docs/misc/ (9 function libraries)
|
||||
└─ [system-wide] ↔ docs/guides/ (configuration & deployment guides)
|
||||
```
|
||||
|
||||
### Core Documentation
|
||||
|
||||
| Document | Purpose | Audience |
|
||||
|----------|---------|----------|
|
||||
| [contribution/README.md](contribution/README.md) | How to contribute | Contributors |
|
||||
| [ct/DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md) | Create ct scripts | Container developers |
|
||||
| [install/DETAILED_GUIDE.md](install/DETAILED_GUIDE.md) | Create install scripts | Installation developers |
|
||||
| [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md) | Architecture deep-dive | Architects, advanced users |
|
||||
| [guides/DEFAULTS_SYSTEM_GUIDE.md](guides/DEFAULTS_SYSTEM_GUIDE.md) | Configuration system | Operators, power users |
|
||||
| [guides/CONFIGURATION_REFERENCE.md](guides/CONFIGURATION_REFERENCE.md) | Configuration options reference | Advanced users |
|
||||
| [guides/UNATTENDED_DEPLOYMENTS.md](guides/UNATTENDED_DEPLOYMENTS.md) | Automated deployments | DevOps, automation |
|
||||
| [EXIT_CODES.md](EXIT_CODES.md) | Exit code reference | Troubleshooters |
|
||||
| [DEV_MODE.md](DEV_MODE.md) | Debugging tools | Developers |
|
||||
|
||||
---
|
||||
|
||||
## 📂 **Directory Guide**
|
||||
|
||||
### [ct/](ct/) - Container Scripts
|
||||
Documentation for `/ct` - Container creation scripts that run on the Proxmox host.
|
||||
|
||||
**Includes**:
|
||||
- Overview of container creation process
|
||||
- Deep dive: [DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md) - Complete reference with examples
|
||||
- Reference to [misc/build.func/](misc/build.func/)
|
||||
- Quick start for creating new containers
|
||||
|
||||
### [install/](install/) - Installation Scripts
|
||||
Documentation for `/install` - Scripts that run inside containers to install applications.
|
||||
|
||||
**Includes**:
|
||||
- Overview of 10-phase installation pattern
|
||||
- Deep dive: [DETAILED_GUIDE.md](install/DETAILED_GUIDE.md) - Complete reference with examples
|
||||
- Reference to [misc/tools.func/](misc/tools.func/)
|
||||
- Alpine vs Debian differences
|
||||
|
||||
### [vm/](vm/) - Virtual Machine Scripts
|
||||
Documentation for `/vm` - VM creation scripts using cloud-init provisioning.
|
||||
|
||||
**Includes**:
|
||||
- Overview of VM provisioning
|
||||
- Link to [misc/cloud-init.func/](misc/cloud-init.func/)
|
||||
- VM vs Container comparison
|
||||
- Cloud-init examples
|
||||
|
||||
### [tools/](tools/) - Tools & Utilities
|
||||
Documentation for `/tools` - Management tools and add-ons.
|
||||
|
||||
**Includes**:
|
||||
- Overview of tools structure
|
||||
- Integration points
|
||||
- Contributing new tools
|
||||
- Common operations
|
||||
|
||||
### [api/](api/) - API Integration
|
||||
Documentation for `/api` - Telemetry and API backend.
|
||||
|
||||
**Includes**:
|
||||
- API overview
|
||||
- Integration methods
|
||||
- API endpoints
|
||||
- Privacy information
|
||||
|
||||
### [misc/](misc/) - Function Libraries
|
||||
Documentation for `/misc` - 9 core function libraries with complete references.
|
||||
|
||||
**Contains**:
|
||||
- **build.func/** - Container orchestration (7 files)
|
||||
- **core.func/** - Utilities and messaging (5 files)
|
||||
- **error_handler.func/** - Error handling (5 files)
|
||||
- **api.func/** - API integration (5 files)
|
||||
- **install.func/** - Container setup (5 files)
|
||||
- **tools.func/** - Package installation (6 files)
|
||||
- **alpine-install.func/** - Alpine setup (5 files)
|
||||
- **alpine-tools.func/** - Alpine tools (5 files)
|
||||
- **cloud-init.func/** - VM provisioning (5 files)
|
||||
|
||||
---
|
||||
|
||||
## 🎓 **Learning Paths**
|
||||
|
||||
### Path 1: First-Time Contributor (2-3 hours)
|
||||
|
||||
1. [contribution/README.md](contribution/README.md) - Quick Start
|
||||
2. Pick your area:
|
||||
- Containers → [ct/README.md](ct/README.md) + [ct/DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md)
|
||||
- Installation → [install/README.md](install/README.md) + [install/DETAILED_GUIDE.md](install/DETAILED_GUIDE.md)
|
||||
- VMs → [vm/README.md](vm/README.md)
|
||||
3. Study existing similar script
|
||||
4. Create your contribution
|
||||
5. Submit PR
|
||||
|
||||
### Path 2: Intermediate Developer (4-6 hours)
|
||||
|
||||
1. [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md)
|
||||
2. Dive into function libraries:
|
||||
- [misc/build.func/README.md](misc/build.func/README.md)
|
||||
- [misc/tools.func/README.md](misc/tools.func/README.md)
|
||||
- [misc/install.func/README.md](misc/install.func/README.md)
|
||||
3. Study advanced examples
|
||||
4. Create complex applications
|
||||
|
||||
### Path 3: Advanced Architect (8+ hours)
|
||||
|
||||
1. All of Intermediate Path
|
||||
2. Study all 9 function libraries in depth
|
||||
3. [guides/DEFAULTS_SYSTEM_GUIDE.md](guides/DEFAULTS_SYSTEM_GUIDE.md) - Configuration system
|
||||
4. [DEV_MODE.md](DEV_MODE.md) - Debugging and development
|
||||
5. Design new features or function libraries
|
||||
|
||||
### Path 4: Troubleshooter (30 minutes - 1 hour)
|
||||
|
||||
1. [EXIT_CODES.md](EXIT_CODES.md) - Find error code
|
||||
2. [DEV_MODE.md](DEV_MODE.md) - Run with debugging
|
||||
3. Check relevant function library docs
|
||||
4. Review logs and fix
|
||||
|
||||
---
|
||||
|
||||
## 📊 **By the Numbers**
|
||||
|
||||
| Metric | Count |
|
||||
|--------|:---:|
|
||||
| **Documentation Files** | 63 |
|
||||
| **Total Lines** | 15,000+ |
|
||||
| **Function Libraries** | 9 |
|
||||
| **Functions Documented** | 150+ |
|
||||
| **Code Examples** | 50+ |
|
||||
| **Flowcharts** | 15+ |
|
||||
| **Do/Don't Sections** | 20+ |
|
||||
| **Real-World Examples** | 30+ |
|
||||
|
||||
---
|
||||
|
||||
## 🔍 **Find It Fast**
|
||||
|
||||
### By Feature
|
||||
- **How do I create a container?** → [ct/DETAILED_GUIDE.md](ct/DETAILED_GUIDE.md)
|
||||
- **How do I create an install script?** → [install/DETAILED_GUIDE.md](install/DETAILED_GUIDE.md)
|
||||
- **How do I create a VM?** → [vm/README.md](vm/README.md)
|
||||
- **How do I install Node.js?** → [misc/tools.func/](misc/tools.func/)
|
||||
- **How do I debug?** → [DEV_MODE.md](DEV_MODE.md)
|
||||
|
||||
### By Error
|
||||
- **Exit code 206?** → [EXIT_CODES.md](EXIT_CODES.md)
|
||||
- **Network failed?** → [misc/install.func/](misc/install.func/)
|
||||
- **Package error?** → [misc/tools.func/](misc/tools.func/)
|
||||
|
||||
### By Role
|
||||
- **Contributor** → [contribution/README.md](contribution/README.md)
|
||||
- **Operator** → [guides/DEFAULTS_SYSTEM_GUIDE.md](guides/DEFAULTS_SYSTEM_GUIDE.md)
|
||||
- **Automation** → [guides/UNATTENDED_DEPLOYMENTS.md](guides/UNATTENDED_DEPLOYMENTS.md)
|
||||
- **Developer** → [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md)
|
||||
- **Architect** → [misc/README.md](misc/README.md)
|
||||
|
||||
---
|
||||
|
||||
## ✅ **Documentation Features**
|
||||
|
||||
- ✅ **Project-mirrored structure** - Organized like the actual project
|
||||
- ✅ **Complete function references** - Every function documented
|
||||
- ✅ **Real-world examples** - Copy-paste ready code
|
||||
- ✅ **Visual flowcharts** - ASCII diagrams of workflows
|
||||
- ✅ **Integration guides** - How components connect
|
||||
- ✅ **Troubleshooting** - Common issues and solutions
|
||||
- ✅ **Best practices** - DO/DON'T sections throughout
|
||||
- ✅ **Learning paths** - Structured curriculum by role
|
||||
- ✅ **Quick references** - Fast lookup by error code
|
||||
- ✅ **Comprehensive navigation** - This page
|
||||
|
||||
---
|
||||
|
||||
## 🚀 **Start Here**
|
||||
|
||||
**New to ProxmoxVE?** → [contribution/README.md](contribution/README.md)
|
||||
|
||||
**Looking for something specific?** → Choose your role above or browse by directory
|
||||
|
||||
**Need to debug?** → [EXIT_CODES.md](EXIT_CODES.md)
|
||||
|
||||
**Want to understand architecture?** → [TECHNICAL_REFERENCE.md](TECHNICAL_REFERENCE.md)
|
||||
|
||||
---
|
||||
|
||||
## 🤝 **Contributing Documentation**
|
||||
|
||||
Found an error? Want to improve docs?
|
||||
|
||||
1. See: [contribution/README.md](contribution/README.md) for full contribution guide
|
||||
2. Open issue: [GitHub Issues](https://github.com/community-scripts/ProxmoxVE/issues)
|
||||
3. Or submit PR with improvements
|
||||
|
||||
---
|
||||
|
||||
## 📝 **Status**
|
||||
|
||||
- **Last Updated**: December 2025
|
||||
- **Version**: 2.3 (Consolidated & Reorganized)
|
||||
- **Completeness**: ✅ 100% - All components documented
|
||||
- **Quality**: ✅ Production-ready
|
||||
- **Structure**: ✅ Clean and organized
|
||||
|
||||
---
|
||||
|
||||
**Welcome to ProxmoxVE! Start with [CONTRIBUTION_GUIDE.md](CONTRIBUTION_GUIDE.md) or choose your role above.** 🚀
|
||||
@@ -1,897 +0,0 @@
|
||||
# Technical Reference: Configuration System Architecture
|
||||
|
||||
> **For Developers and Advanced Users**
|
||||
>
|
||||
> _Deep dive into how the defaults and configuration system works_
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [System Architecture](#system-architecture)
|
||||
2. [File Format Specifications](#file-format-specifications)
|
||||
3. [Function Reference](#function-reference)
|
||||
4. [Variable Precedence](#variable-precedence)
|
||||
5. [Data Flow Diagrams](#data-flow-diagrams)
|
||||
6. [Security Model](#security-model)
|
||||
7. [Implementation Details](#implementation-details)
|
||||
|
||||
---
|
||||
|
||||
## System Architecture
|
||||
|
||||
### Component Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Installation Script │
|
||||
│ (pihole-install.sh, docker-install.sh, etc.) │
|
||||
└────────────────────┬────────────────────────────────────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ build.func Library │
|
||||
│ ┌──────────────────────────────────────────────────────┐ │
|
||||
│ │ variables() │ │
|
||||
│ │ - Initialize NSAPP, var_install, etc. │ │
|
||||
│ └──────────────────────────────────────────────────────┘ │
|
||||
│ ┌──────────────────────────────────────────────────────┐ │
|
||||
│ │ install_script() │ │
|
||||
│ │ - Display mode menu │ │
|
||||
│ │ - Route to appropriate workflow │ │
|
||||
│ └──────────────────────────────────────────────────────┘ │
|
||||
│ ┌──────────────────────────────────────────────────────┐ │
|
||||
│ │ base_settings() │ │
|
||||
│ │ - Apply built-in defaults │ │
|
||||
│ │ - Read environment variables (var_*) │ │
|
||||
│ └──────────────────────────────────────────────────────┘ │
|
||||
│ ┌──────────────────────────────────────────────────────┐ │
|
||||
│ │ load_vars_file() │ │
|
||||
│ │ - Safe file parsing (NO source/eval) │ │
|
||||
│ │ - Whitelist validation │ │
|
||||
│ │ - Value sanitization │ │
|
||||
│ └──────────────────────────────────────────────────────┘ │
|
||||
│ ┌──────────────────────────────────────────────────────┐ │
|
||||
│ │ default_var_settings() │ │
|
||||
│ │ - Load user defaults │ │
|
||||
│ │ - Display summary │ │
|
||||
│ └──────────────────────────────────────────────────────┘ │
|
||||
│ ┌──────────────────────────────────────────────────────┐ │
|
||||
│ │ maybe_offer_save_app_defaults() │ │
|
||||
│ │ - Offer to save current settings │ │
|
||||
│ │ - Handle updates vs. new saves │ │
|
||||
│ └──────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Configuration Files (on Disk) │
|
||||
│ ┌──────────────────────────────────────────────────────┐ │
|
||||
│ │ /usr/local/community-scripts/default.vars │ │
|
||||
│ │ (User global defaults) │ │
|
||||
│ └──────────────────────────────────────────────────────┘ │
|
||||
│ ┌──────────────────────────────────────────────────────┐ │
|
||||
│ │ /usr/local/community-scripts/defaults/*.vars │ │
|
||||
│ │ (App-specific defaults) │ │
|
||||
│ └──────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Format Specifications
|
||||
|
||||
### User Defaults: `default.vars`
|
||||
|
||||
**Location**: `/usr/local/community-scripts/default.vars`
|
||||
|
||||
**MIME Type**: `text/plain`
|
||||
|
||||
**Encoding**: UTF-8 (no BOM)
|
||||
|
||||
**Format Specification**:
|
||||
|
||||
```
|
||||
# File Format: Simple key=value pairs
|
||||
# Purpose: Store global user defaults
|
||||
# Security: Sanitized values, whitelist validation
|
||||
|
||||
# Comments and blank lines are ignored
|
||||
# Line format: var_name=value
|
||||
# No spaces around the equals sign
|
||||
# String values do not need quoting (but may be quoted)
|
||||
|
||||
[CONTENT]
|
||||
var_cpu=4
|
||||
var_ram=2048
|
||||
var_disk=20
|
||||
var_hostname=mydefault
|
||||
var_brg=vmbr0
|
||||
var_gateway=192.168.1.1
|
||||
```
|
||||
|
||||
**Formal Grammar**:
|
||||
|
||||
```
|
||||
FILE := (BLANK_LINE | COMMENT_LINE | VAR_LINE)*
|
||||
BLANK_LINE := \n
|
||||
COMMENT_LINE := '#' [^\n]* \n
|
||||
VAR_LINE := VAR_NAME '=' VAR_VALUE \n
|
||||
VAR_NAME := 'var_' [a-z_]+
|
||||
VAR_VALUE := [^\n]* # Any printable characters except newline
|
||||
```
|
||||
|
||||
**Constraints**:
|
||||
|
||||
| Constraint | Value |
|
||||
| ----------------- | ------------------------ |
|
||||
| Max file size | 64 KB |
|
||||
| Max line length | 1024 bytes |
|
||||
| Max variables | 100 |
|
||||
| Allowed var names | `var_[a-z_]+` |
|
||||
| Value validation | Whitelist + Sanitization |
|
||||
|
||||
**Example Valid File**:
|
||||
|
||||
```bash
|
||||
# Global User Defaults
|
||||
# Created: 2024-11-28
|
||||
|
||||
# Resource defaults
|
||||
var_cpu=4
|
||||
var_ram=2048
|
||||
var_disk=20
|
||||
|
||||
# Network defaults
|
||||
var_brg=vmbr0
|
||||
var_gateway=192.168.1.1
|
||||
var_mtu=1500
|
||||
var_vlan=100
|
||||
|
||||
# System defaults
|
||||
var_timezone=Europe/Berlin
|
||||
var_hostname=default-container
|
||||
|
||||
# Storage
|
||||
var_container_storage=local
|
||||
var_template_storage=local
|
||||
|
||||
# Security
|
||||
var_ssh=yes
|
||||
var_protection=0
|
||||
var_unprivileged=1
|
||||
```
|
||||
|
||||
### App Defaults: `<app>.vars`
|
||||
|
||||
**Location**: `/usr/local/community-scripts/defaults/<appname>.vars`
|
||||
|
||||
**Format**: Identical to `default.vars`
|
||||
|
||||
**Naming Convention**: `<nsapp>.vars`
|
||||
|
||||
- `nsapp` = lowercase app name with spaces removed
|
||||
- Examples:
|
||||
- `pihole` → `pihole.vars`
|
||||
- `opnsense` → `opnsense.vars`
|
||||
- `docker compose` → `dockercompose.vars`
|
||||
|
||||
**Example App Defaults**:
|
||||
|
||||
```bash
|
||||
# App-specific defaults for PiHole (pihole)
|
||||
# Generated on 2024-11-28T15:32:00Z
|
||||
# These override user defaults when installing pihole
|
||||
|
||||
var_unprivileged=1
|
||||
var_cpu=2
|
||||
var_ram=1024
|
||||
var_disk=10
|
||||
var_brg=vmbr0
|
||||
var_net=veth
|
||||
var_gateway=192.168.1.1
|
||||
var_hostname=pihole
|
||||
var_timezone=Europe/Berlin
|
||||
var_container_storage=local
|
||||
var_template_storage=local
|
||||
var_tags=dns,pihole
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Function Reference
|
||||
|
||||
### `load_vars_file()`
|
||||
|
||||
**Purpose**: Safely load variables from .vars files without using `source` or `eval`
|
||||
|
||||
**Signature**:
|
||||
|
||||
```bash
|
||||
load_vars_file(filepath)
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
|
||||
| Param | Type | Required | Example |
|
||||
| -------- | ------ | -------- | ------------------------------------------- |
|
||||
| filepath | String | Yes | `/usr/local/community-scripts/default.vars` |
|
||||
|
||||
**Returns**:
|
||||
|
||||
- `0` on success
|
||||
- `1` on error (file missing, parse error, etc.)
|
||||
|
||||
**Environment Side Effects**:
|
||||
|
||||
- Sets all parsed `var_*` variables as shell variables
|
||||
- Does NOT unset variables if file missing (safe)
|
||||
- Does NOT affect other variables
|
||||
|
||||
**Implementation Pattern**:
|
||||
|
||||
```bash
|
||||
load_vars_file() {
|
||||
local file="$1"
|
||||
|
||||
# File must exist
|
||||
[ -f "$file" ] || return 0
|
||||
|
||||
# Parse line by line (not with source/eval)
|
||||
local line key val
|
||||
while IFS='=' read -r key val || [ -n "$key" ]; do
|
||||
# Skip comments and empty lines
|
||||
[[ "$key" =~ ^[[:space:]]*# ]] && continue
|
||||
[[ -z "$key" ]] && continue
|
||||
|
||||
# Validate key is in whitelist
|
||||
_is_whitelisted_key "$key" || continue
|
||||
|
||||
# Sanitize and export value
|
||||
val="$(_sanitize_value "$val")"
|
||||
[ $? -eq 0 ] && export "$key=$val"
|
||||
done < "$file"
|
||||
|
||||
return 0
|
||||
}
|
||||
```
|
||||
|
||||
**Usage Examples**:
|
||||
|
||||
```bash
|
||||
# Load user defaults
|
||||
load_vars_file "/usr/local/community-scripts/default.vars"
|
||||
|
||||
# Load app-specific defaults
|
||||
load_vars_file "$(get_app_defaults_path)"
|
||||
|
||||
# Check if successful
|
||||
if load_vars_file "$vars_path"; then
|
||||
echo "Settings loaded successfully"
|
||||
else
|
||||
echo "Failed to load settings"
|
||||
fi
|
||||
|
||||
# Values are now available as variables
|
||||
echo "Using $var_cpu cores"
|
||||
echo "Allocating ${var_ram} MB RAM"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `get_app_defaults_path()`
|
||||
|
||||
**Purpose**: Get the full path for app-specific defaults file
|
||||
|
||||
**Signature**:
|
||||
|
||||
```bash
|
||||
get_app_defaults_path()
|
||||
```
|
||||
|
||||
**Parameters**: None
|
||||
|
||||
**Returns**:
|
||||
|
||||
- String: Full path to app defaults file
|
||||
|
||||
**Implementation**:
|
||||
|
||||
```bash
|
||||
get_app_defaults_path() {
|
||||
local n="${NSAPP:-${APP,,}}"
|
||||
echo "/usr/local/community-scripts/defaults/${n}.vars"
|
||||
}
|
||||
```
|
||||
|
||||
**Usage Examples**:
|
||||
|
||||
```bash
|
||||
# Get app defaults path
|
||||
app_defaults="$(get_app_defaults_path)"
|
||||
echo "App defaults at: $app_defaults"
|
||||
|
||||
# Check if app defaults exist
|
||||
if [ -f "$(get_app_defaults_path)" ]; then
|
||||
echo "App defaults available"
|
||||
fi
|
||||
|
||||
# Load app defaults
|
||||
load_vars_file "$(get_app_defaults_path)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `default_var_settings()`
|
||||
|
||||
**Purpose**: Load and display user global defaults
|
||||
|
||||
**Signature**:
|
||||
|
||||
```bash
|
||||
default_var_settings()
|
||||
```
|
||||
|
||||
**Parameters**: None
|
||||
|
||||
**Returns**:
|
||||
|
||||
- `0` on success
|
||||
- `1` on error
|
||||
|
||||
**Workflow**:
|
||||
|
||||
```
|
||||
1. Find default.vars location
|
||||
(usually /usr/local/community-scripts/default.vars)
|
||||
|
||||
2. Create if missing
|
||||
|
||||
3. Load variables from file
|
||||
|
||||
4. Map var_verbose → VERBOSE variable
|
||||
|
||||
5. Call base_settings (apply to container config)
|
||||
|
||||
6. Call echo_default (display summary)
|
||||
```
|
||||
|
||||
**Implementation Pattern**:
|
||||
|
||||
```bash
|
||||
default_var_settings() {
|
||||
local VAR_WHITELIST=(
|
||||
var_apt_cacher var_apt_cacher_ip var_brg var_cpu var_disk var_fuse var_gpu
|
||||
var_gateway var_hostname var_ipv6_method var_mac var_mtu
|
||||
var_net var_ns var_pw var_ram var_tags var_tun var_unprivileged
|
||||
var_verbose var_vlan var_ssh var_ssh_authorized_key
|
||||
var_container_storage var_template_storage
|
||||
)
|
||||
|
||||
# Ensure file exists
|
||||
_ensure_default_vars
|
||||
|
||||
# Find and load
|
||||
local dv="$(_find_default_vars)"
|
||||
load_vars_file "$dv"
|
||||
|
||||
# Map verbose flag
|
||||
if [[ -n "${var_verbose:-}" ]]; then
|
||||
case "${var_verbose,,}" in
|
||||
1 | yes | true | on) VERBOSE="yes" ;;
|
||||
*) VERBOSE="${var_verbose}" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Apply and display
|
||||
base_settings "$VERBOSE"
|
||||
echo_default
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `maybe_offer_save_app_defaults()`
|
||||
|
||||
**Purpose**: Offer to save current settings as app-specific defaults
|
||||
|
||||
**Signature**:
|
||||
|
||||
```bash
|
||||
maybe_offer_save_app_defaults()
|
||||
```
|
||||
|
||||
**Parameters**: None
|
||||
|
||||
**Returns**: None (side effects only)
|
||||
|
||||
**Behavior**:
|
||||
|
||||
1. After advanced installation completes
|
||||
2. Offers user: "Save as App Defaults for <APP>?"
|
||||
3. If yes:
|
||||
- Saves to `/usr/local/community-scripts/defaults/<app>.vars`
|
||||
- Only whitelisted variables included
|
||||
- Previous defaults backed up (if exists)
|
||||
4. If no:
|
||||
- No action taken
|
||||
|
||||
**Flow**:
|
||||
|
||||
```bash
|
||||
maybe_offer_save_app_defaults() {
|
||||
local app_vars_path="$(get_app_defaults_path)"
|
||||
|
||||
# Build current settings from memory
|
||||
local new_tmp="$(_build_current_app_vars_tmp)"
|
||||
|
||||
# Check if already exists
|
||||
if [ -f "$app_vars_path" ]; then
|
||||
# Show diff and ask: Update? Keep? View Diff?
|
||||
_show_app_defaults_diff_menu "$new_tmp" "$app_vars_path"
|
||||
else
|
||||
# New defaults - just save
|
||||
if whiptail --yesno "Save as App Defaults for $APP?" 10 60; then
|
||||
mv "$new_tmp" "$app_vars_path"
|
||||
chmod 644 "$app_vars_path"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `_sanitize_value()`
|
||||
|
||||
**Purpose**: Remove dangerous characters/patterns from configuration values
|
||||
|
||||
**Signature**:
|
||||
|
||||
```bash
|
||||
_sanitize_value(value)
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
|
||||
| Param | Type | Required |
|
||||
| ----- | ------ | -------- |
|
||||
| value | String | Yes |
|
||||
|
||||
**Returns**:
|
||||
|
||||
- `0` (success) + sanitized value on stdout
|
||||
- `1` (failure) + nothing if dangerous
|
||||
|
||||
**Dangerous Patterns**:
|
||||
|
||||
| Pattern | Threat | Example |
|
||||
| --------- | -------------------- | -------------------- |
|
||||
| `$(...)` | Command substitution | `$(rm -rf /)` |
|
||||
| `` ` ` `` | Command substitution | `` `whoami` `` |
|
||||
| `;` | Command separator | `value; rm -rf /` |
|
||||
| `&` | Background execution | `value & malicious` |
|
||||
| `<(` | Process substitution | `<(cat /etc/passwd)` |
|
||||
|
||||
**Implementation**:
|
||||
|
||||
```bash
|
||||
_sanitize_value() {
|
||||
case "$1" in
|
||||
*'$('* | *'`'* | *';'* | *'&'* | *'<('*)
|
||||
echo ""
|
||||
return 1 # Reject dangerous value
|
||||
;;
|
||||
esac
|
||||
echo "$1"
|
||||
return 0
|
||||
}
|
||||
```
|
||||
|
||||
**Usage Examples**:
|
||||
|
||||
```bash
|
||||
# Safe value
|
||||
_sanitize_value "192.168.1.1" # Returns: 192.168.1.1 (status: 0)
|
||||
|
||||
# Dangerous value
|
||||
_sanitize_value "$(whoami)" # Returns: (empty) (status: 1)
|
||||
|
||||
# Usage in code
|
||||
if val="$(_sanitize_value "$user_input")"; then
|
||||
export var_hostname="$val"
|
||||
else
|
||||
msg_error "Invalid value: contains dangerous characters"
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `_is_whitelisted_key()`
|
||||
|
||||
**Purpose**: Check if variable name is in allowed whitelist
|
||||
|
||||
**Signature**:
|
||||
|
||||
```bash
|
||||
_is_whitelisted_key(key)
|
||||
```
|
||||
|
||||
**Parameters**:
|
||||
|
||||
| Param | Type | Required | Example |
|
||||
| ----- | ------ | -------- | --------- |
|
||||
| key | String | Yes | `var_cpu` |
|
||||
|
||||
**Returns**:
|
||||
|
||||
- `0` if key is whitelisted
|
||||
- `1` if key is NOT whitelisted
|
||||
|
||||
**Implementation**:
|
||||
|
||||
```bash
|
||||
_is_whitelisted_key() {
|
||||
local k="$1"
|
||||
local w
|
||||
for w in "${VAR_WHITELIST[@]}"; do
|
||||
[ "$k" = "$w" ] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
```
|
||||
|
||||
**Usage Examples**:
|
||||
|
||||
```bash
|
||||
# Check if variable can be saved
|
||||
if _is_whitelisted_key "var_cpu"; then
|
||||
echo "var_cpu can be saved"
|
||||
fi
|
||||
|
||||
# Reject unknown variables
|
||||
if ! _is_whitelisted_key "var_custom"; then
|
||||
msg_error "var_custom is not supported"
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Variable Precedence
|
||||
|
||||
### Loading Order
|
||||
|
||||
When a container is being created, variables are resolved in this order:
|
||||
|
||||
```
|
||||
Step 1: Read ENVIRONMENT VARIABLES
|
||||
├─ Check if var_cpu is already set in shell environment
|
||||
├─ Check if var_ram is already set
|
||||
└─ ...all var_* variables
|
||||
|
||||
Step 2: Load APP-SPECIFIC DEFAULTS
|
||||
├─ Check if /usr/local/community-scripts/defaults/pihole.vars exists
|
||||
├─ Load all var_* from that file
|
||||
└─ These override built-ins but NOT environment variables
|
||||
|
||||
Step 3: Load USER GLOBAL DEFAULTS
|
||||
├─ Check if /usr/local/community-scripts/default.vars exists
|
||||
├─ Load all var_* from that file
|
||||
└─ These override built-ins but NOT app-specific
|
||||
|
||||
Step 4: Use BUILT-IN DEFAULTS
|
||||
└─ Hardcoded in script (lowest priority)
|
||||
```
|
||||
|
||||
### Precedence Examples
|
||||
|
||||
**Example 1: Environment Variable Wins**
|
||||
|
||||
```bash
|
||||
# Shell environment has highest priority
|
||||
$ export var_cpu=16
|
||||
$ bash pihole-install.sh
|
||||
|
||||
# Result: Container gets 16 cores
|
||||
# (ignores app defaults, user defaults, built-ins)
|
||||
```
|
||||
|
||||
**Example 2: App Defaults Override User Defaults**
|
||||
|
||||
```bash
|
||||
# User Defaults: var_cpu=4
|
||||
# App Defaults: var_cpu=2
|
||||
$ bash pihole-install.sh
|
||||
|
||||
# Result: Container gets 2 cores
|
||||
# (app-specific setting takes precedence)
|
||||
```
|
||||
|
||||
**Example 3: All Defaults Missing (Built-ins Used)**
|
||||
|
||||
```bash
|
||||
# No environment variables set
|
||||
# No app defaults file
|
||||
# No user defaults file
|
||||
$ bash pihole-install.sh
|
||||
|
||||
# Result: Uses built-in defaults
|
||||
# (var_cpu might be 2 by default)
|
||||
```
|
||||
|
||||
### Implementation in Code
|
||||
|
||||
```bash
|
||||
# Typical pattern in build.func
|
||||
|
||||
base_settings() {
|
||||
# Priority 1: Environment variables (already set if export used)
|
||||
CT_TYPE=${var_unprivileged:-"1"} # Use existing or default
|
||||
|
||||
# Priority 2: Load app defaults (may override above)
|
||||
if [ -f "$(get_app_defaults_path)" ]; then
|
||||
load_vars_file "$(get_app_defaults_path)"
|
||||
fi
|
||||
|
||||
# Priority 3: Load user defaults
|
||||
if [ -f "/usr/local/community-scripts/default.vars" ]; then
|
||||
load_vars_file "/usr/local/community-scripts/default.vars"
|
||||
fi
|
||||
|
||||
# Priority 4: Apply built-in defaults (lowest)
|
||||
CORE_COUNT=${var_cpu:-"${APP_CPU_DEFAULT:-2}"}
|
||||
RAM_SIZE=${var_ram:-"${APP_RAM_DEFAULT:-1024}"}
|
||||
|
||||
# Result: var_cpu has been set through precedence chain
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Flow Diagrams
|
||||
|
||||
### Installation Flow: Advanced Settings
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ Start Script│
|
||||
└──────┬───────┘
|
||||
│
|
||||
v
|
||||
┌──────────────────────────────┐
|
||||
│ Display Installation Mode │
|
||||
│ Menu (5 options) │
|
||||
└──────┬───────────────────────┘
|
||||
│ User selects "Advanced Settings"
|
||||
v
|
||||
┌──────────────────────────────────┐
|
||||
│ Call: base_settings() │
|
||||
│ (Apply built-in defaults) │
|
||||
└──────┬───────────────────────────┘
|
||||
│
|
||||
v
|
||||
┌──────────────────────────────────┐
|
||||
│ Call: advanced_settings() │
|
||||
│ (Show 19-step wizard) │
|
||||
│ - Ask CPU, RAM, Disk, Network... │
|
||||
└──────┬───────────────────────────┘
|
||||
│
|
||||
v
|
||||
┌──────────────────────────────────┐
|
||||
│ Show Summary │
|
||||
│ Review all chosen values │
|
||||
└──────┬───────────────────────────┘
|
||||
│ User confirms
|
||||
v
|
||||
┌──────────────────────────────────┐
|
||||
│ Create Container │
|
||||
│ Using current variable values │
|
||||
└──────┬───────────────────────────┘
|
||||
│
|
||||
v
|
||||
┌──────────────────────────────────┐
|
||||
│ Installation Complete │
|
||||
└──────┬───────────────────────────┘
|
||||
│
|
||||
v
|
||||
┌──────────────────────────────────────┐
|
||||
│ Offer: Save as App Defaults? │
|
||||
│ (Save current settings) │
|
||||
└──────┬───────────────────────────────┘
|
||||
│
|
||||
├─ YES → Save to defaults/<app>.vars
|
||||
│
|
||||
└─ NO → Exit
|
||||
```
|
||||
|
||||
### Variable Resolution Flow
|
||||
|
||||
```
|
||||
CONTAINER CREATION STARTED
|
||||
│
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ Check ENVIRONMENT │
|
||||
│ for var_cpu, var_..│
|
||||
└──────┬──────────────┘
|
||||
│ Found? Use them (Priority 1)
|
||||
│ Not found? Continue...
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ Load App Defaults │
|
||||
│ /defaults/<app>.vars │
|
||||
└──────┬───────────────────┘
|
||||
│ File exists? Parse & load (Priority 2)
|
||||
│ Not found? Continue...
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ Load User Defaults │
|
||||
│ /default.vars │
|
||||
└──────┬───────────────────┘
|
||||
│ File exists? Parse & load (Priority 3)
|
||||
│ Not found? Continue...
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ Use Built-in Defaults │
|
||||
│ (Hardcoded values) │
|
||||
└──────┬───────────────────┘
|
||||
│
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ All Variables Resolved │
|
||||
│ Ready for container │
|
||||
│ creation │
|
||||
└──────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security Model
|
||||
|
||||
### Threat Model
|
||||
|
||||
| Threat | Mitigation |
|
||||
| ---------------------------- | ------------------------------------------------- |
|
||||
| **Arbitrary Code Execution** | No `source` or `eval`; manual parsing only |
|
||||
| **Variable Injection** | Whitelist of allowed variable names |
|
||||
| **Command Substitution** | `_sanitize_value()` blocks `$()`, backticks, etc. |
|
||||
| **Path Traversal** | Files locked to `/usr/local/community-scripts/` |
|
||||
| **Permission Escalation** | Files created with restricted permissions |
|
||||
| **Information Disclosure** | Sensitive variables not logged |
|
||||
|
||||
### Security Controls
|
||||
|
||||
#### 1. Input Validation
|
||||
|
||||
```bash
|
||||
# Only specific variables allowed
|
||||
if ! _is_whitelisted_key "$key"; then
|
||||
skip_this_variable
|
||||
fi
|
||||
|
||||
# Values sanitized
|
||||
if ! val="$(_sanitize_value "$value")"; then
|
||||
reject_entire_line
|
||||
fi
|
||||
```
|
||||
|
||||
#### 2. Safe File Parsing
|
||||
|
||||
```bash
|
||||
# ❌ DANGEROUS (OLD)
|
||||
source /path/to/config.conf
|
||||
# Could execute: rm -rf / or any code
|
||||
|
||||
# ✅ SAFE (NEW)
|
||||
load_vars_file "/path/to/config.conf"
|
||||
# Only reads var_name=value pairs, no execution
|
||||
```
|
||||
|
||||
#### 3. Whitelisting
|
||||
|
||||
```bash
|
||||
# Only these variables can be configured
|
||||
var_cpu, var_ram, var_disk, var_brg, ...
|
||||
var_hostname, var_pw, var_ssh, ...
|
||||
|
||||
# NOT allowed:
|
||||
var_malicious, var_hack, custom_var, ...
|
||||
```
|
||||
|
||||
#### 4. Value Constraints
|
||||
|
||||
```bash
|
||||
# No command injection patterns
|
||||
if [[ "$value" =~ ($|`|;|&|<\() ]]; then
|
||||
reject_value
|
||||
fi
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Module: `build.func`
|
||||
|
||||
**Load Order** (in actual scripts):
|
||||
|
||||
1. `#!/usr/bin/env bash` - Shebang
|
||||
2. `source /dev/stdin <<<$(curl ... api.func)` - API functions
|
||||
3. `source /dev/stdin <<<$(curl ... build.func)` - Build functions
|
||||
4. `variables()` - Initialize variables
|
||||
5. `check_root()` - Security check
|
||||
6. `install_script()` - Main flow
|
||||
|
||||
**Key Sections**:
|
||||
|
||||
```bash
|
||||
# Section 1: Initialization & Variables
|
||||
- variables()
|
||||
- NSAPP, var_install, INTEGER pattern, etc.
|
||||
|
||||
# Section 2: Storage Management
|
||||
- storage_selector()
|
||||
- ensure_storage_selection_for_vars_file()
|
||||
|
||||
# Section 3: Base Settings
|
||||
- base_settings() # Apply defaults to all var_*
|
||||
- echo_default() # Display current settings
|
||||
|
||||
# Section 4: Variable Loading
|
||||
- load_vars_file() # Safe parsing
|
||||
- _is_whitelisted_key() # Validation
|
||||
- _sanitize_value() # Threat mitigation
|
||||
|
||||
# Section 5: Defaults Management
|
||||
- default_var_settings() # Load user defaults
|
||||
- get_app_defaults_path() # Get app defaults path
|
||||
- maybe_offer_save_app_defaults() # Save option
|
||||
|
||||
# Section 6: Installation Flow
|
||||
- install_script() # Main entry point
|
||||
- advanced_settings() # 20-step wizard
|
||||
```
|
||||
|
||||
### Regex Patterns Used
|
||||
|
||||
| Pattern | Purpose | Example Match |
|
||||
| ---------------------- | --------------------- | ----------------------- |
|
||||
| `^[0-9]+([.][0-9]+)?$` | Integer validation | `4`, `192.168` |
|
||||
| `^var_[a-z_]+$` | Variable name | `var_cpu`, `var_ssh` |
|
||||
| `*'$('*` | Command substitution | `$(whoami)` |
|
||||
| `*\`\*` | Backtick substitution | `` `cat /etc/passwd` `` |
|
||||
|
||||
---
|
||||
|
||||
## Appendix: Migration Reference
|
||||
|
||||
### Old Pattern (Deprecated)
|
||||
|
||||
```bash
|
||||
# ❌ OLD: config-file.func
|
||||
source config-file.conf # Executes arbitrary code
|
||||
if [ "$USE_DEFAULTS" = "yes" ]; then
|
||||
apply_settings_directly
|
||||
fi
|
||||
```
|
||||
|
||||
### New Pattern (Current)
|
||||
|
||||
```bash
|
||||
# ✅ NEW: load_vars_file()
|
||||
if load_vars_file "$(get_app_defaults_path)"; then
|
||||
echo "Settings loaded securely"
|
||||
fi
|
||||
```
|
||||
|
||||
### Function Mapping
|
||||
|
||||
| Old | New | Location |
|
||||
| ---------------- | --------------------------------- | ---------- |
|
||||
| `read_config()` | `load_vars_file()` | build.func |
|
||||
| `write_config()` | `_build_current_app_vars_tmp()` | build.func |
|
||||
| None | `maybe_offer_save_app_defaults()` | build.func |
|
||||
| None | `get_app_defaults_path()` | build.func |
|
||||
|
||||
---
|
||||
|
||||
**End of Technical Reference**
|
||||
@@ -1,146 +0,0 @@
|
||||
# API Integration Documentation (/api)
|
||||
|
||||
This directory contains comprehensive documentation for API integration and the `/api` directory.
|
||||
|
||||
## Overview
|
||||
|
||||
The `/api` directory contains the Proxmox Community Scripts API backend for diagnostic reporting, telemetry, and analytics integration.
|
||||
|
||||
## Key Components
|
||||
|
||||
### Main API Service
|
||||
Located in `/api/main.go`:
|
||||
- RESTful API for receiving telemetry data
|
||||
- Installation statistics tracking
|
||||
- Error reporting and analytics
|
||||
- Performance monitoring
|
||||
|
||||
### Integration with Scripts
|
||||
The API is integrated into all installation scripts via `api.func`:
|
||||
- Sends installation start/completion events
|
||||
- Reports errors and exit codes
|
||||
- Collects anonymous usage statistics
|
||||
- Enables project analytics
|
||||
|
||||
## Documentation Structure
|
||||
|
||||
API documentation covers:
|
||||
- API endpoint specifications
|
||||
- Integration methods
|
||||
- Data formats and schemas
|
||||
- Error handling
|
||||
- Privacy and data handling
|
||||
|
||||
## Key Resources
|
||||
|
||||
- **[misc/api.func/](../misc/api.func/)** - API function library documentation
|
||||
- **[misc/api.func/README.md](../misc/api.func/README.md)** - Quick reference
|
||||
- **[misc/api.func/API_FUNCTIONS_REFERENCE.md](../misc/api.func/API_FUNCTIONS_REFERENCE.md)** - Complete function reference
|
||||
|
||||
## API Functions
|
||||
|
||||
The `api.func` library provides:
|
||||
|
||||
### `post_to_api()`
|
||||
Send container installation data to API.
|
||||
|
||||
**Usage**:
|
||||
```bash
|
||||
post_to_api CTID STATUS APP_NAME
|
||||
```
|
||||
|
||||
### `post_update_to_api()`
|
||||
Report application update status.
|
||||
|
||||
**Usage**:
|
||||
```bash
|
||||
post_update_to_api CTID APP_NAME VERSION
|
||||
```
|
||||
|
||||
### `get_error_description()`
|
||||
Get human-readable error description from exit code.
|
||||
|
||||
**Usage**:
|
||||
```bash
|
||||
ERROR_DESC=$(get_error_description EXIT_CODE)
|
||||
```
|
||||
|
||||
## API Integration Points
|
||||
|
||||
### In Container Creation (`ct/AppName.sh`)
|
||||
- Called by build.func to report container creation
|
||||
- Sends initial container setup data
|
||||
- Reports success or failure
|
||||
|
||||
### In Installation Scripts (`install/appname-install.sh`)
|
||||
- Called at start of installation
|
||||
- Called on installation completion
|
||||
- Called on error conditions
|
||||
|
||||
### Data Collected
|
||||
- Container/VM ID
|
||||
- Application name and version
|
||||
- Installation duration
|
||||
- Success/failure status
|
||||
- Error codes (if failure)
|
||||
- Anonymous usage metrics
|
||||
|
||||
## Privacy
|
||||
|
||||
All API data:
|
||||
- ✅ Anonymous (no personal data)
|
||||
- ✅ Aggregated for statistics
|
||||
- ✅ Used only for project improvement
|
||||
- ✅ No tracking of user identities
|
||||
- ✅ Can be disabled if desired
|
||||
|
||||
## API Architecture
|
||||
|
||||
```
|
||||
Installation Scripts
|
||||
│
|
||||
├─ Call: api.func functions
|
||||
│
|
||||
└─ POST to: https://api.community-scripts.org
|
||||
│
|
||||
├─ Receives data
|
||||
├─ Validates format
|
||||
├─ Stores metrics
|
||||
└─ Aggregates statistics
|
||||
│
|
||||
└─ Used for:
|
||||
├─ Download tracking
|
||||
├─ Error trending
|
||||
├─ Feature usage stats
|
||||
└─ Project health monitoring
|
||||
```
|
||||
|
||||
## Common API Tasks
|
||||
|
||||
- **Enable API reporting** → Built-in by default, no configuration needed
|
||||
- **Disable API** → Set `api_disable="yes"` before running
|
||||
- **View API data** → Visit https://community-scripts.org/stats
|
||||
- **Report API errors** → [GitHub Issues](https://github.com/community-scripts/ProxmoxVE/issues)
|
||||
|
||||
## Debugging API Issues
|
||||
|
||||
If API calls fail:
|
||||
1. Check internet connectivity
|
||||
2. Verify API endpoint availability
|
||||
3. Review error codes in [EXIT_CODES.md](../EXIT_CODES.md)
|
||||
4. Check API function logs
|
||||
5. Report issues on GitHub
|
||||
|
||||
## API Endpoint
|
||||
|
||||
**Base URL**: `https://api.community-scripts.org`
|
||||
|
||||
**Endpoints**:
|
||||
- `POST /install` - Report container installation
|
||||
- `POST /update` - Report application update
|
||||
- `GET /stats` - Public statistics
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
**Maintainers**: community-scripts team
|
||||
@@ -1,868 +0,0 @@
|
||||
# 🤖 AI Contribution Guidelines for ProxmoxVE
|
||||
|
||||
> **This documentation is intended for all AI assistants (GitHub Copilot, Claude, ChatGPT, etc.) contributing to this project.**
|
||||
|
||||
## 🎯 Core Principles
|
||||
|
||||
### 1. **Maximum Use of `tools.func` Functions**
|
||||
|
||||
We have an extensive library of helper functions. **NEVER** implement your own solutions when a function already exists!
|
||||
|
||||
### 2. **No Pointless Variables**
|
||||
|
||||
Only create variables when they:
|
||||
|
||||
- Are used multiple times
|
||||
- Improve readability
|
||||
- Are intended for configuration
|
||||
|
||||
### 3. **Consistent Script Structure**
|
||||
|
||||
All scripts follow an identical structure. Deviations are not acceptable.
|
||||
|
||||
### 4. **Bare-Metal Installation**
|
||||
|
||||
We do **NOT use Docker** for our installation scripts. All applications are installed directly on the system.
|
||||
|
||||
---
|
||||
|
||||
## 📁 Script Types and Their Structure
|
||||
|
||||
### CT Script (`ct/AppName.sh`)
|
||||
|
||||
```bash
|
||||
#!/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: AuthorName (GitHubUsername)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://application-url.com
|
||||
|
||||
APP="AppName"
|
||||
var_tags="${var_tags:-tag1;tag2;tag3}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
if [[ ! -d /opt/appname ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
if check_for_gh_release "appname" "YourUsername/YourRepo"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop appname
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
msg_info "Backing up Data"
|
||||
cp -r /opt/appname/data /opt/appname_data_backup
|
||||
msg_ok "Backed up Data"
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
|
||||
|
||||
# Build steps...
|
||||
|
||||
msg_info "Restoring Data"
|
||||
cp -r /opt/appname_data_backup/. /opt/appname/data
|
||||
rm -rf /opt/appname_data_backup
|
||||
msg_ok "Restored Data"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start appname
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed Successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:PORT${CL}"
|
||||
```
|
||||
|
||||
### Install Script (`install/AppName-install.sh`)
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: AuthorName (GitHubUsername)
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://application-url.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-get install -y \
|
||||
dependency1 \
|
||||
dependency2
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
# Runtime Setup (ALWAYS use our functions!)
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
# or
|
||||
PG_VERSION="16" setup_postgresql
|
||||
# or
|
||||
setup_uv
|
||||
# etc.
|
||||
|
||||
fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
|
||||
|
||||
msg_info "Setting up Application"
|
||||
cd /opt/appname
|
||||
# Build/Setup Schritte...
|
||||
msg_ok "Set up Application"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/appname.service
|
||||
[Unit]
|
||||
Description=AppName Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/appname
|
||||
ExecStart=/path/to/executable
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now appname
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Available Helper Functions
|
||||
|
||||
### Release Management
|
||||
|
||||
| Function | Description | Example |
|
||||
| ----------------------------- | ----------------------------------- | ------------------------------------------------------------- |
|
||||
| `fetch_and_deploy_gh_release` | Fetches and installs GitHub Release | `fetch_and_deploy_gh_release "app" "owner/repo"` |
|
||||
| `check_for_gh_release` | Checks for new version | `if check_for_gh_release "app" "YourUsername/YourRepo"; then` |
|
||||
|
||||
**Modes for `fetch_and_deploy_gh_release`:**
|
||||
|
||||
```bash
|
||||
# Tarball/Source (Standard)
|
||||
fetch_and_deploy_gh_release "appname" "owner/repo"
|
||||
|
||||
# Binary (.deb)
|
||||
fetch_and_deploy_gh_release "appname" "owner/repo" "binary"
|
||||
|
||||
# Prebuilt Archive
|
||||
fetch_and_deploy_gh_release "appname" "owner/repo" "prebuild" "latest" "/opt/appname" "filename.tar.gz"
|
||||
|
||||
# Single Binary
|
||||
fetch_and_deploy_gh_release "appname" "owner/repo" "singlefile" "latest" "/opt/appname" "binary-linux-amd64"
|
||||
```
|
||||
|
||||
**Clean Install Flag:**
|
||||
|
||||
```bash
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo"
|
||||
```
|
||||
|
||||
### Runtime/Language Setup
|
||||
|
||||
| Function | Variable(s) | Example |
|
||||
| -------------- | ----------------------------- | ---------------------------------------------------- |
|
||||
| `setup_nodejs` | `NODE_VERSION`, `NODE_MODULE` | `NODE_VERSION="22" setup_nodejs` |
|
||||
| `setup_uv` | `PYTHON_VERSION` | `PYTHON_VERSION="3.12" setup_uv` |
|
||||
| `setup_go` | `GO_VERSION` | `GO_VERSION="1.22" setup_go` |
|
||||
| `setup_rust` | `RUST_VERSION`, `RUST_CRATES` | `RUST_CRATES="monolith" setup_rust` |
|
||||
| `setup_ruby` | `RUBY_VERSION` | `RUBY_VERSION="3.3" setup_ruby` |
|
||||
| `setup_java` | `JAVA_VERSION` | `JAVA_VERSION="21" setup_java` |
|
||||
| `setup_php` | `PHP_VERSION`, `PHP_MODULES` | `PHP_VERSION="8.3" PHP_MODULES="redis,gd" setup_php` |
|
||||
|
||||
### Database Setup
|
||||
|
||||
| Function | Variable(s) | Example |
|
||||
| --------------------- | ------------------------------------ | ----------------------------------------------------------- |
|
||||
| `setup_postgresql` | `PG_VERSION`, `PG_MODULES` | `PG_VERSION="16" setup_postgresql` |
|
||||
| `setup_postgresql_db` | `PG_DB_NAME`, `PG_DB_USER` | `PG_DB_NAME="mydb" PG_DB_USER="myuser" setup_postgresql_db` |
|
||||
| `setup_mariadb_db` | `MARIADB_DB_NAME`, `MARIADB_DB_USER` | `MARIADB_DB_NAME="mydb" setup_mariadb_db` |
|
||||
| `setup_mysql` | `MYSQL_VERSION` | `setup_mysql` |
|
||||
| `setup_mongodb` | `MONGO_VERSION` | `setup_mongodb` |
|
||||
| `setup_clickhouse` | - | `setup_clickhouse` |
|
||||
|
||||
### Tools & Utilities
|
||||
|
||||
| Function | Description |
|
||||
| ------------------- | ---------------------------------- |
|
||||
| `setup_adminer` | Installs Adminer for DB management |
|
||||
| `setup_composer` | Install PHP Composer |
|
||||
| `setup_ffmpeg` | Install FFmpeg |
|
||||
| `setup_imagemagick` | Install ImageMagick |
|
||||
| `setup_gs` | Install Ghostscript |
|
||||
| `setup_hwaccel` | Configure hardware acceleration |
|
||||
|
||||
### Helper Utilities
|
||||
|
||||
| Function | Description | Example |
|
||||
| ----------------------------- | ---------------------------- | ----------------------------------------- |
|
||||
| `import_local_ip` | Sets `$LOCAL_IP` variable | `import_local_ip` |
|
||||
| `ensure_dependencies` | Checks/installs dependencies | `ensure_dependencies curl jq` |
|
||||
| `install_packages_with_retry` | APT install with retry | `install_packages_with_retry nginx redis` |
|
||||
|
||||
---
|
||||
|
||||
## ❌ Anti-Patterns (NEVER use!)
|
||||
|
||||
### 1. Pointless Variables
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - unnecessary variables
|
||||
APP_NAME="myapp"
|
||||
APP_DIR="/opt/${APP_NAME}"
|
||||
APP_USER="root"
|
||||
APP_PORT="3000"
|
||||
cd $APP_DIR
|
||||
|
||||
# ✅ CORRECT - use directly
|
||||
cd /opt/myapp
|
||||
```
|
||||
|
||||
### 2. Custom Download Logic
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - custom wget/curl logic
|
||||
RELEASE=$(curl -s https://api.github.com/repos/YourUsername/YourRepo/releases/latest | jq -r '.tag_name')
|
||||
wget https://github.com/YourUsername/YourRepo/archive/${RELEASE}.tar.gz
|
||||
tar -xzf ${RELEASE}.tar.gz
|
||||
mv repo-${RELEASE} /opt/myapp
|
||||
|
||||
# ✅ CORRECT - use our function
|
||||
fetch_and_deploy_gh_release "myapp" "YourUsername/YourRepo" "tarball" "latest" "/opt/myapp"
|
||||
```
|
||||
|
||||
### 3. Custom Version-Check Logic
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - custom version check
|
||||
CURRENT=$(cat /opt/myapp/version.txt)
|
||||
LATEST=$(curl -s https://api.github.com/repos/YourUsername/YourRepo/releases/latest | jq -r '.tag_name')
|
||||
if [[ "$CURRENT" != "$LATEST" ]]; then
|
||||
# update...
|
||||
fi
|
||||
|
||||
# ✅ CORRECT - use our function
|
||||
if check_for_gh_release "myapp" "YourUsername/YourRepo"; then
|
||||
# update...
|
||||
fi
|
||||
```
|
||||
|
||||
### 4. Docker-based Installation
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - using Docker
|
||||
docker pull myapp/myapp:latest
|
||||
docker run -d --name myapp myapp/myapp:latest
|
||||
|
||||
# ✅ CORRECT - Bare-Metal Installation
|
||||
fetch_and_deploy_gh_release "myapp" "YourUsername/YourRepo"
|
||||
npm install && npm run build
|
||||
```
|
||||
|
||||
### 5. Custom Runtime Installation
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - custom Node.js installation
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
|
||||
apt install -y nodejs
|
||||
|
||||
# ✅ CORRECT - use our function
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
```
|
||||
|
||||
### 6. Redundant echo Statements
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - custom logging messages
|
||||
echo "Installing dependencies..."
|
||||
apt install -y curl
|
||||
echo "Done!"
|
||||
|
||||
# ✅ CORRECT - use msg_info/msg_ok
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y curl
|
||||
msg_ok "Installed Dependencies"
|
||||
```
|
||||
|
||||
### 7. Missing $STD Usage
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - apt without $STD
|
||||
apt install -y nginx
|
||||
|
||||
# ✅ CORRECT - with $STD for silent output
|
||||
$STD apt install -y nginx
|
||||
```
|
||||
|
||||
### 8. Wrapping `tools.func` Functions in msg Blocks
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - tools.func functions have their own msg_info/msg_ok!
|
||||
msg_info "Installing Node.js"
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
msg_ok "Installed Node.js"
|
||||
|
||||
msg_info "Updating Application"
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
|
||||
msg_ok "Updated Application"
|
||||
|
||||
# ✅ CORRECT - call directly without msg wrapper
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
|
||||
```
|
||||
|
||||
**Functions with built-in messages (NEVER wrap in msg blocks):**
|
||||
|
||||
- `fetch_and_deploy_gh_release`
|
||||
- `check_for_gh_release`
|
||||
- `setup_nodejs`
|
||||
- `setup_postgresql` / `setup_postgresql_db`
|
||||
- `setup_mariadb` / `setup_mariadb_db`
|
||||
- `setup_mongodb`
|
||||
- `setup_mysql`
|
||||
- `setup_ruby`
|
||||
- `setup_go`
|
||||
- `setup_java`
|
||||
- `setup_php`
|
||||
- `setup_uv`
|
||||
- `setup_rust`
|
||||
- `setup_composer`
|
||||
- `setup_ffmpeg`
|
||||
- `setup_imagemagick`
|
||||
- `setup_gs`
|
||||
- `setup_adminer`
|
||||
- `setup_hwaccel`
|
||||
|
||||
### 9. Creating Unnecessary System Users
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - LXC containers run as root, no separate user needed
|
||||
useradd -m -s /usr/bin/bash appuser
|
||||
chown -R appuser:appuser /opt/appname
|
||||
sudo -u appuser npm install
|
||||
|
||||
# ✅ CORRECT - run directly as root
|
||||
cd /opt/appname
|
||||
$STD npm install
|
||||
```
|
||||
|
||||
### 10. Using `export` in .env Files
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - export is unnecessary in .env files
|
||||
cat <<EOF >/opt/appname/.env
|
||||
export DATABASE_URL=postgres://...
|
||||
export SECRET_KEY=abc123
|
||||
export NODE_ENV=production
|
||||
EOF
|
||||
|
||||
# ✅ CORRECT - simple KEY=VALUE format (files are sourced with set -a)
|
||||
cat <<EOF >/opt/appname/.env
|
||||
DATABASE_URL=postgres://...
|
||||
SECRET_KEY=abc123
|
||||
NODE_ENV=production
|
||||
EOF
|
||||
```
|
||||
|
||||
### 11. Using External Shell Scripts
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - external script that gets executed
|
||||
cat <<'EOF' >/opt/appname/install_script.sh
|
||||
#!/bin/bash
|
||||
cd /opt/appname
|
||||
npm install
|
||||
npm run build
|
||||
EOF
|
||||
chmod +x /opt/appname/install_script.sh
|
||||
$STD bash /opt/appname/install_script.sh
|
||||
rm -f /opt/appname/install_script.sh
|
||||
|
||||
# ✅ CORRECT - run commands directly
|
||||
cd /opt/appname
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
```
|
||||
|
||||
### 12. Using `sudo` in LXC Containers
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - sudo is unnecessary in LXC (already root)
|
||||
sudo -u postgres psql -c "CREATE DATABASE mydb;"
|
||||
sudo -u appuser npm install
|
||||
|
||||
# ✅ CORRECT - use functions or run directly as root
|
||||
PG_DB_NAME="mydb" PG_DB_USER="myuser" setup_postgresql_db
|
||||
|
||||
cd /opt/appname
|
||||
$STD npm install
|
||||
```
|
||||
|
||||
### 13. Unnecessary `systemctl daemon-reload`
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - daemon-reload is only needed when MODIFYING existing services
|
||||
cat <<EOF >/etc/systemd/system/appname.service
|
||||
# ... service config ...
|
||||
EOF
|
||||
systemctl daemon-reload # Unnecessary for new services!
|
||||
systemctl enable -q --now appname
|
||||
|
||||
# ✅ CORRECT - new services don't need daemon-reload
|
||||
cat <<EOF >/etc/systemd/system/appname.service
|
||||
# ... service config ...
|
||||
EOF
|
||||
systemctl enable -q --now appname
|
||||
```
|
||||
|
||||
### 14. Creating Custom Credentials Files
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - custom credentials file is not part of the standard template
|
||||
msg_info "Saving Credentials"
|
||||
cat <<EOF >~/appname.creds
|
||||
Database User: ${DB_USER}
|
||||
Database Pass: ${DB_PASS}
|
||||
EOF
|
||||
msg_ok "Saved Credentials"
|
||||
|
||||
# ✅ CORRECT - credentials are stored in .env or shown in final message only
|
||||
# If you use setup_postgresql_db / setup_mariadb_db, a standard ~/[appname].creds is created automatically
|
||||
```
|
||||
|
||||
### 15. Wrong Footer Pattern
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - old cleanup pattern with msg blocks
|
||||
motd_ssh
|
||||
customize
|
||||
|
||||
msg_info "Cleaning up"
|
||||
$STD apt-get -y autoremove
|
||||
$STD apt-get -y autoclean
|
||||
msg_ok "Cleaned"
|
||||
|
||||
# ✅ CORRECT - use cleanup_lxc function
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
### 16. Manual Database Creation Instead of Functions
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - manual database creation
|
||||
DB_USER="myuser"
|
||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | cut -c1-13)
|
||||
$STD sudo -u postgres psql -c "CREATE ROLE $DB_USER WITH LOGIN PASSWORD '$DB_PASS';"
|
||||
$STD sudo -u postgres psql -c "CREATE DATABASE mydb WITH OWNER $DB_USER;"
|
||||
$STD sudo -u postgres psql -d mydb -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
||||
|
||||
# ✅ CORRECT - use setup_postgresql_db function
|
||||
# This sets PG_DB_USER, PG_DB_PASS, PG_DB_NAME automatically
|
||||
PG_DB_NAME="mydb" PG_DB_USER="myuser" PG_DB_EXTENSIONS="postgis" setup_postgresql_db
|
||||
```
|
||||
|
||||
### 17. Writing Files Without Heredocs
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - echo / printf / tee
|
||||
echo "# Config" > /opt/app/config.yml
|
||||
echo "port: 3000" >> /opt/app/config.yml
|
||||
|
||||
printf "# Config\nport: 3000\n" > /opt/app/config.yml
|
||||
cat config.yml | tee /opt/app/config.yml
|
||||
```
|
||||
|
||||
```bash
|
||||
# ✅ CORRECT - always use a single heredoc
|
||||
cat <<EOF >/opt/app/config.yml
|
||||
# Config
|
||||
port: 3000
|
||||
EOF
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Important Rules
|
||||
|
||||
### Variable Declarations (CT Script)
|
||||
|
||||
```bash
|
||||
# Standard declarations (ALWAYS present)
|
||||
APP="AppName"
|
||||
var_tags="${var_tags:-tag1;tag2}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-8}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-13}"
|
||||
var_unprivileged="${var_unprivileged:-1}"
|
||||
```
|
||||
|
||||
### Update-Script Pattern
|
||||
|
||||
```bash
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
# 1. Check if installation exists
|
||||
if [[ ! -d /opt/appname ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
# 2. Check for update
|
||||
if check_for_gh_release "appname" "YourUsername/YourRepo"; then
|
||||
# 3. Stop service
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop appname
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
# 4. Backup data (if present)
|
||||
msg_info "Backing up Data"
|
||||
cp -r /opt/appname/data /opt/appname_data_backup
|
||||
msg_ok "Backed up Data"
|
||||
|
||||
# 5. Perform clean install
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
|
||||
|
||||
# 6. Rebuild (if needed)
|
||||
cd /opt/appname
|
||||
$STD npm install
|
||||
$STD npm run build
|
||||
|
||||
# 7. Restore data
|
||||
msg_info "Restoring Data"
|
||||
cp -r /opt/appname_data_backup/. /opt/appname/data
|
||||
rm -rf /opt/appname_data_backup
|
||||
msg_ok "Restored Data"
|
||||
|
||||
# 8. Start service
|
||||
msg_info "Starting Service"
|
||||
systemctl start appname
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit # IMPORTANT: Always end with exit!
|
||||
}
|
||||
```
|
||||
|
||||
### Systemd Service Pattern
|
||||
|
||||
```bash
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/appname.service
|
||||
[Unit]
|
||||
Description=AppName Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/appname
|
||||
Environment=NODE_ENV=production
|
||||
ExecStart=/usr/bin/node /opt/appname/server.js
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now appname
|
||||
msg_ok "Created Service"
|
||||
```
|
||||
|
||||
### Installation Script Footer
|
||||
|
||||
```bash
|
||||
# ALWAYS at the end of the install script:
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Reference: Good Example Scripts
|
||||
|
||||
Look at these recent well-implemented applications as reference:
|
||||
|
||||
### Container Scripts (Latest 10)
|
||||
|
||||
- [ct/thingsboard.sh](../ct/thingsboard.sh) - IoT platform with proper update_script
|
||||
- [ct/unifi-os-server.sh](../ct/unifi-os-server.sh) - Complex setup with podman
|
||||
- [ct/trip.sh](../ct/trip.sh) - Simple Ruby app
|
||||
- [ct/fladder.sh](../ct/fladder.sh) - Media app with database
|
||||
- [ct/qui.sh](../ct/qui.sh) - Lightweight utility
|
||||
- [ct/kutt.sh](../ct/kutt.sh) - Node.js with PostgreSQL
|
||||
- [ct/flatnotes.sh](../ct/flatnotes.sh) - Python notes app
|
||||
- [ct/investbrain.sh](../ct/investbrain.sh) - Finance app
|
||||
- [ct/gwn-manager.sh](../ct/gwn-manager.sh) - Network management
|
||||
- [ct/sportarr.sh](../ct/sportarr.sh) - Specialized \*Arr variant
|
||||
|
||||
### Install Scripts (Latest)
|
||||
|
||||
- [install/unifi-os-server-install.sh](../install/unifi-os-server-install.sh) - Complex setup with API integration
|
||||
- [install/trip-install.sh](../install/trip-install.sh) - Rails application setup
|
||||
- [install/mail-archiver-install.sh](../install/mail-archiver-install.sh) - Email-related service
|
||||
|
||||
**Key things to notice:**
|
||||
|
||||
- Proper error handling with `catch_errors`
|
||||
- Use of `check_for_gh_release` and `fetch_and_deploy_gh_release`
|
||||
- Correct backup/restore patterns in `update_script`
|
||||
- Footer always ends with `motd_ssh`, `customize`, `cleanup_lxc`
|
||||
- Website metadata requested via the website (Report issue on script page) if needed
|
||||
|
||||
---
|
||||
|
||||
## Website Metadata (Reference)
|
||||
|
||||
Website metadata (name, slug, description, logo, categories, etc.) is **not** added as files in the repo. Contributors request or update it via the **website**: go to the script's page and use the **Report issue** button; the flow will guide you. The structure below is a **reference** for what metadata exists (e.g. for the form or when describing what you need).
|
||||
|
||||
### JSON Structure (Reference)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "AppName",
|
||||
"slug": "appname",
|
||||
"categories": [1],
|
||||
"date_created": "2026-01-16",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 3000,
|
||||
"documentation": "https://docs.appname.com/",
|
||||
"website": "https://appname.com/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/appname.webp",
|
||||
"config_path": "/opt/appname/.env",
|
||||
"description": "Short description of the application and its purpose.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/appname.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 8,
|
||||
"os": "Debian",
|
||||
"version": "13"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": []
|
||||
}
|
||||
```
|
||||
|
||||
### Required Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
| --------------------- | ------- | -------------------------------------------------- |
|
||||
| `name` | string | Display name of the application |
|
||||
| `slug` | string | Lowercase, no spaces, used for filenames |
|
||||
| `categories` | array | Category ID(s) - see category list below |
|
||||
| `date_created` | string | Creation date (YYYY-MM-DD) |
|
||||
| `type` | string | `ct` for container, `vm` for virtual machine |
|
||||
| `updateable` | boolean | Whether update_script is implemented |
|
||||
| `privileged` | boolean | Whether container needs privileged mode |
|
||||
| `interface_port` | number | Primary web interface port (or `null`) |
|
||||
| `documentation` | string | Link to official docs |
|
||||
| `website` | string | Link to official website |
|
||||
| `logo` | string | URL to application logo (preferably selfhst icons) |
|
||||
| `config_path` | string | Path to main config file (or empty string) |
|
||||
| `description` | string | Brief description of the application |
|
||||
| `install_methods` | array | Installation configurations |
|
||||
| `default_credentials` | object | Default username/password (or null) |
|
||||
| `notes` | array | Additional notes/warnings |
|
||||
|
||||
### Categories
|
||||
|
||||
| ID | Category |
|
||||
| --- | ------------------------- |
|
||||
| 0 | Miscellaneous |
|
||||
| 1 | Proxmox & Virtualization |
|
||||
| 2 | Operating Systems |
|
||||
| 3 | Containers & Docker |
|
||||
| 4 | Network & Firewall |
|
||||
| 5 | Adblock & DNS |
|
||||
| 6 | Authentication & Security |
|
||||
| 7 | Backup & Recovery |
|
||||
| 8 | Databases |
|
||||
| 9 | Monitoring & Analytics |
|
||||
| 10 | Dashboards & Frontends |
|
||||
| 11 | Files & Downloads |
|
||||
| 12 | Documents & Notes |
|
||||
| 13 | Media & Streaming |
|
||||
| 14 | \*Arr Suite |
|
||||
| 15 | NVR & Cameras |
|
||||
| 16 | IoT & Smart Home |
|
||||
| 17 | ZigBee, Z-Wave & Matter |
|
||||
| 18 | MQTT & Messaging |
|
||||
| 19 | Automation & Scheduling |
|
||||
| 20 | AI / Coding & Dev-Tools |
|
||||
| 21 | Webservers & Proxies |
|
||||
| 22 | Bots & ChatOps |
|
||||
| 23 | Finance & Budgeting |
|
||||
| 24 | Gaming & Leisure |
|
||||
| 25 | Business & ERP |
|
||||
|
||||
### Notes Format
|
||||
|
||||
```json
|
||||
"notes": [
|
||||
{
|
||||
"text": "Change the default password after first login!",
|
||||
"type": "warning"
|
||||
},
|
||||
{
|
||||
"text": "Requires at least 4GB RAM for optimal performance.",
|
||||
"type": "info"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**Note types:** `info`, `warning`, `error`
|
||||
|
||||
### Examples with Credentials
|
||||
|
||||
```json
|
||||
"default_credentials": {
|
||||
"username": "admin",
|
||||
"password": "admin"
|
||||
}
|
||||
```
|
||||
|
||||
Or no credentials:
|
||||
|
||||
```json
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Checklist Before PR Creation
|
||||
|
||||
- [ ] No Docker installation used
|
||||
- [ ] `fetch_and_deploy_gh_release` used for GitHub releases
|
||||
- [ ] `check_for_gh_release` used for update checks
|
||||
- [ ] `setup_*` functions used for runtimes (nodejs, postgresql, etc.)
|
||||
- [ ] **`tools.func` functions NOT wrapped in msg_info/msg_ok blocks**
|
||||
- [ ] No redundant variables (only when used multiple times)
|
||||
- [ ] `$STD` before all apt/npm/build commands
|
||||
- [ ] `msg_info`/`msg_ok`/`msg_error` for logging (only for custom code)
|
||||
- [ ] Correct script structure followed (see templates)
|
||||
- [ ] Update function present and functional (CT scripts)
|
||||
- [ ] Data backup implemented in update function (if applicable)
|
||||
- [ ] `motd_ssh`, `customize`, `cleanup_lxc` at the end of install scripts
|
||||
- [ ] No custom download/version-check logic
|
||||
- [ ] All links point to `community-scripts/ProxmoxVE` (not `ProxmoxVED`!)
|
||||
- [ ] Website metadata requested via the website (Report issue) if needed
|
||||
- [ ] Category IDs are valid (0-25)
|
||||
- [ ] Default OS version is Debian 13 or newer (unless special requirement)
|
||||
- [ ] Default resources are reasonable for the application
|
||||
|
||||
---
|
||||
|
||||
## 💡 Tips for AI Assistants
|
||||
|
||||
1. **ALWAYS search `tools.func` first** before implementing custom solutions
|
||||
2. **Use recent scripts as reference** (Thingsboard, UniFi OS, Trip, Flatnotes, etc.)
|
||||
3. **Ask when uncertain** instead of introducing wrong patterns
|
||||
4. **Test via GitHub** - push to your fork and test with curl (not local bash)
|
||||
```bash
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"
|
||||
# Wait 10-30 seconds after pushing - GitHub takes time to update files
|
||||
```
|
||||
5. **Consistency > Creativity** - follow established patterns strictly
|
||||
6. **Check the templates** - they show the correct structure
|
||||
7. **Don't wrap tools.func functions** - they handle their own msg_info/msg_ok output
|
||||
8. **Minimal variables** - only create variables that are truly reused multiple times
|
||||
9. **Always use $STD** - ensures silent/non-interactive execution
|
||||
10. **Reference good examples** - look at recent additions in each category
|
||||
|
||||
---
|
||||
|
||||
## 🍒 Important: Cherry-Picking Your Files for PR Submission
|
||||
|
||||
⚠️ **CRITICAL**: When you submit your PR, you must use git cherry-pick to send ONLY your 2 files!
|
||||
|
||||
Why? Because `setup-fork.sh` modifies 600+ files to update links. If you commit all changes, your PR will be impossible to merge.
|
||||
|
||||
**See**: [README.md - Cherry-Pick Section](README.md#-cherry-pick-submitting-only-your-changes) for complete instructions on:
|
||||
|
||||
- Creating a clean submission branch
|
||||
- Cherry-picking only your files (ct/myapp.sh, install/myapp-install.sh)
|
||||
- Verifying your PR has only 2 file changes (not 600+)
|
||||
|
||||
**Quick reference**:
|
||||
|
||||
```bash
|
||||
# Create clean branch from upstream
|
||||
git fetch upstream
|
||||
git checkout -b submit/myapp upstream/main
|
||||
|
||||
# Cherry-pick your commit(s) or manually add your 2 files
|
||||
# Then push to your fork and create PR
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Further Documentation
|
||||
|
||||
- [CONTRIBUTING.md](CONTRIBUTING.md) - General contribution guidelines
|
||||
- [GUIDE.md](GUIDE.md) - Detailed developer documentation
|
||||
- [HELPER_FUNCTIONS.md](HELPER_FUNCTIONS.md) - Complete tools.func reference
|
||||
- [README.md](README.md) - Cherry-pick guide and workflow instructions
|
||||
- [../TECHNICAL_REFERENCE.md](../TECHNICAL_REFERENCE.md) - Technical deep dive
|
||||
- [../EXIT_CODES.md](../EXIT_CODES.md) - Exit code reference
|
||||
- [templates_ct/](templates_ct/) - CT script templates
|
||||
- [templates_install/](templates_install/) - Install script templates
|
||||
- [templates_json/](templates_json/) - Metadata structure reference; submit via website
|
||||
@@ -1,41 +0,0 @@
|
||||
# 🧪 Code Audit: LXC Script Flow
|
||||
|
||||
This guide explains the current execution flow and what to verify during reviews.
|
||||
|
||||
## Execution Flow (CT + Install)
|
||||
|
||||
1. `ct/appname.sh` runs on the Proxmox host and sources `misc/build.func`.
|
||||
2. `build.func` orchestrates prompts, container creation, and invokes the install script.
|
||||
3. Inside the container, `misc/install.func` exposes helper functions via `$FUNCTIONS_FILE_PATH`.
|
||||
4. `install/appname-install.sh` performs the application install.
|
||||
5. The CT script prints the completion message.
|
||||
|
||||
## Audit Checklist
|
||||
|
||||
### CT Script (ct/)
|
||||
|
||||
- Sources `misc/build.func` from `community-scripts/ProxmoxVE/main` (setup-fork.sh updates for forks).
|
||||
- Uses `check_for_gh_release` + `fetch_and_deploy_gh_release` for updates.
|
||||
- No Docker-based installs.
|
||||
|
||||
### Install Script (install/)
|
||||
|
||||
- Sources `$FUNCTIONS_FILE_PATH`.
|
||||
- Uses `tools.func` helpers (setup\_\*).
|
||||
- Ends with `motd_ssh`, `customize`, `cleanup_lxc`.
|
||||
|
||||
### Website Metadata
|
||||
|
||||
- Website metadata for new/updated scripts is requested via the website (Report issue on script page) where applicable.
|
||||
|
||||
### Testing
|
||||
|
||||
- Test via curl from your fork (CT script only).
|
||||
- Wait 10-30 seconds after push.
|
||||
|
||||
## References
|
||||
|
||||
- `docs/contribution/templates_ct/AppName.sh`
|
||||
- `docs/contribution/templates_install/AppName-install.sh`
|
||||
- `docs/contribution/templates_json/AppName.json`
|
||||
- `docs/contribution/GUIDE.md`
|
||||
@@ -1,176 +0,0 @@
|
||||
# Community Scripts Contribution Guide
|
||||
|
||||
## **Welcome to the communty-scripts Repository!**
|
||||
|
||||
📜 These documents outline the essential coding standards for all our scripts and JSON files. Adhering to these standards ensures that our codebase remains consistent, readable, and maintainable. By following these guidelines, we can improve collaboration, reduce errors, and enhance the overall quality of our project.
|
||||
|
||||
### Why Coding Standards Matter
|
||||
|
||||
Coding standards are crucial for several reasons:
|
||||
|
||||
1. **Consistency**: Consistent code is easier to read, understand, and maintain. It helps new team members quickly get up to speed and reduces the learning curve.
|
||||
2. **Readability**: Clear and well-structured code is easier to debug and extend. It allows developers to quickly identify and fix issues.
|
||||
3. **Maintainability**: Code that follows a standard structure is easier to refactor and update. It ensures that changes can be made with minimal risk of introducing new bugs.
|
||||
4. **Collaboration**: When everyone follows the same standards, it becomes easier to collaborate on code. It reduces friction and misunderstandings during code reviews and merges.
|
||||
|
||||
### Scope of These Documents
|
||||
|
||||
These documents cover the coding standards for the following types of files in our project:
|
||||
|
||||
- **`install/$AppName-install.sh` Scripts**: These scripts are responsible for the installation of applications.
|
||||
- **`ct/$AppName.sh` Scripts**: These scripts handle the creation and updating of containers.
|
||||
- **Website metadata**: Display data (name, description, logo, etc.) is requested via the website (Report issue on the script page), not via files in the repo.
|
||||
|
||||
Each section provides detailed guidelines on various aspects of coding, including shebang usage, comments, variable naming, function naming, indentation, error handling, command substitution, quoting, script structure, and logging. Additionally, examples are provided to illustrate the application of these standards.
|
||||
|
||||
By following the coding standards outlined in this document, we ensure that our scripts and JSON files are of high quality, making our project more robust and easier to manage. Please refer to this guide whenever you create or update scripts and JSON files to maintain a high standard of code quality across the project. 📚🔍
|
||||
|
||||
Let's work together to keep our codebase clean, efficient, and maintainable! 💪🚀
|
||||
|
||||
## Getting Started
|
||||
|
||||
Before contributing, please ensure that you have the following setup:
|
||||
|
||||
1. **Visual Studio Code** (recommended for script development)
|
||||
2. **Recommended VS Code Extensions:**
|
||||
- [Shell Syntax](https://marketplace.visualstudio.com/items?itemName=bmalehorn.shell-syntax)
|
||||
- [ShellCheck](https://marketplace.visualstudio.com/items?itemName=timonwong.shellcheck)
|
||||
- [Shell Format](https://marketplace.visualstudio.com/items?itemName=foxundermoon.shell-format)
|
||||
|
||||
### Important Notes
|
||||
|
||||
- Use [AppName.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/templates_ct/AppName.sh) and [AppName-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/templates_install/AppName-install.sh) as templates when creating new scripts.
|
||||
|
||||
---
|
||||
|
||||
# 🚀 The Application Script (ct/AppName.sh)
|
||||
|
||||
- You can find all coding standards, as well as the structure for this file [here](https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/templates_ct/AppName.md).
|
||||
- These scripts are responsible for container creation, setting the necessary variables and handling the update of the application once installed.
|
||||
|
||||
---
|
||||
|
||||
# 🛠 The Installation Script (install/AppName-install.sh)
|
||||
|
||||
- You can find all coding standards, as well as the structure for this file [here](https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/templates_install/AppName-install.md).
|
||||
- These scripts are responsible for the installation of the application.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Building Your Own Scripts
|
||||
|
||||
Start with the [template script](https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/templates_install/AppName-install.sh)
|
||||
|
||||
---
|
||||
|
||||
## 🤝 Contribution Process
|
||||
|
||||
### 1. Fork the repository
|
||||
|
||||
Fork to your GitHub account
|
||||
|
||||
### 2. Clone your fork on your local environment
|
||||
|
||||
```bash
|
||||
git clone https://github.com/yourUserName/ForkName
|
||||
```
|
||||
|
||||
### 3. Create a new branch
|
||||
|
||||
```bash
|
||||
git switch -c your-feature-branch
|
||||
```
|
||||
|
||||
### 4. Run setup-fork.sh to auto-configure your fork
|
||||
|
||||
```bash
|
||||
bash docs/contribution/setup-fork.sh --full
|
||||
```
|
||||
|
||||
This script automatically:
|
||||
|
||||
- Detects your GitHub username
|
||||
- Updates ALL curl URLs to point to your fork (for testing)
|
||||
- Creates `.git-setup-info` with your config
|
||||
- Backs up all modified files (\*.backup)
|
||||
|
||||
**IMPORTANT**: This modifies 600+ files! Use cherry-pick when submitting your PR (see below).
|
||||
|
||||
### 5. Commit ONLY your new application files
|
||||
|
||||
```bash
|
||||
git commit -m "Your commit message"
|
||||
```
|
||||
|
||||
### 5. Push to your fork
|
||||
|
||||
```bash
|
||||
git push origin your-feature-branch
|
||||
```
|
||||
|
||||
### 6. Cherry-Pick: Submit Only Your Files for PR
|
||||
|
||||
⚠️ **IMPORTANT**: setup-fork.sh modified 600+ files. You MUST only submit your 2 new files!
|
||||
|
||||
See [README.md - Cherry-Pick Guide](README.md#-cherry-pick-submitting-only-your-changes) for step-by-step instructions.
|
||||
|
||||
Quick version:
|
||||
|
||||
```bash
|
||||
# Create clean branch from upstream
|
||||
git fetch upstream
|
||||
git checkout -b submit/myapp upstream/main
|
||||
|
||||
# Copy only your files
|
||||
cp ../your-work-branch/ct/myapp.sh ct/myapp.sh
|
||||
cp ../your-work-branch/install/myapp-install.sh install/myapp-install.sh
|
||||
|
||||
# Commit and verify
|
||||
git add ct/myapp.sh install/myapp-install.sh
|
||||
git commit -m "feat: add MyApp"
|
||||
git diff upstream/main --name-only # Should show ONLY your 2 files
|
||||
|
||||
# Push and create PR
|
||||
git push origin submit/myapp
|
||||
```
|
||||
|
||||
### 7. Create a Pull Request
|
||||
|
||||
Open a Pull Request from `submit/myapp` → `community-scripts/ProxmoxVE/main`.
|
||||
|
||||
Verify the PR shows ONLY these 2 files:
|
||||
|
||||
- `ct/myapp.sh`
|
||||
- `install/myapp-install.sh`
|
||||
|
||||
---
|
||||
|
||||
# 🛠️ Developer Mode & Debugging
|
||||
|
||||
When building or testing scripts, you can use the `dev_mode` variable to enable powerful debugging features. These flags can be combined (comma-separated).
|
||||
|
||||
**Usage**:
|
||||
```bash
|
||||
# Example: Run with trace and keep the container even if it fails
|
||||
dev_mode="trace,keep" bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/myapp.sh)"
|
||||
```
|
||||
|
||||
### Available Flags:
|
||||
|
||||
| Flag | Description |
|
||||
| :--- | :--- |
|
||||
| `trace` | Enables `set -x` for maximum verbosity during execution. |
|
||||
| `keep` | Prevents the container from being deleted if the build fails. |
|
||||
| `pause` | Pauses execution at key points (e.g., before customization). |
|
||||
| `breakpoint` | Allows hardcoded `breakpoint` calls in scripts to drop to a shell. |
|
||||
| `logs` | Saves detailed build logs to `/var/log/community-scripts/`. |
|
||||
| `dryrun` | Bypasses actual container creation (limited support). |
|
||||
| `motd` | Forces an update of the Message of the Day (MOTD). |
|
||||
|
||||
---
|
||||
|
||||
## 📚 Pages
|
||||
|
||||
- [CT Template: AppName.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/templates_ct/AppName.sh)
|
||||
- [Install Template: AppName-install.sh](https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/templates_install/AppName-install.sh)
|
||||
- [JSON Template: AppName.json](https://github.com/community-scripts/ProxmoxVE/blob/main/docs/contribution/templates_json/AppName.json) — metadata structure reference; submit via the website (Report issue on script page)
|
||||
@@ -1,231 +0,0 @@
|
||||
# 🍴 Fork Setup Guide
|
||||
|
||||
**Just forked ProxmoxVE? Run this first!**
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Clone your fork
|
||||
git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git
|
||||
cd ProxmoxVE
|
||||
|
||||
# Run setup script (auto-detects your username from git)
|
||||
bash docs/contribution/setup-fork.sh --full
|
||||
```
|
||||
|
||||
That's it! ✅
|
||||
|
||||
---
|
||||
|
||||
## What Does It Do?
|
||||
|
||||
The `setup-fork.sh` script automatically:
|
||||
|
||||
1. **Detects** your GitHub username from git config
|
||||
2. **Updates ALL hardcoded links** to point to your fork:
|
||||
- Documentation links pointing to `community-scripts/ProxmoxVE`
|
||||
- **Curl download URLs** in scripts (e.g., `curl ... github.com/community-scripts/ProxmoxVE/main/...`)
|
||||
3. **Creates** `.git-setup-info` with your configuration details
|
||||
4. **Backs up** all modified files (\*.backup for safety)
|
||||
|
||||
### Why Updating Curl Links Matters
|
||||
|
||||
Your scripts contain `curl` commands that download dependencies from GitHub (build.func, tools.func, etc.):
|
||||
|
||||
```bash
|
||||
# First line of ct/myapp.sh
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
```
|
||||
|
||||
**WITHOUT setup-fork.sh:**
|
||||
|
||||
- Script URLs still point to `community-scripts/ProxmoxVE/main`
|
||||
- If you test locally with `bash ct/myapp.sh`, you're testing local files, but the script's curl commands would download from **upstream** repo
|
||||
- Your modifications aren't actually being tested via the curl commands! ❌
|
||||
|
||||
**AFTER setup-fork.sh:**
|
||||
|
||||
- Script URLs are updated to `YourUsername/ProxmoxVE/main`
|
||||
- When you test via curl from GitHub: `bash -c "$(curl ... YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"`, it downloads from **your fork**
|
||||
- The script's curl commands also point to your fork, so you're actually testing your changes! ✅
|
||||
- ⏱️ **Important:** GitHub takes 10-30 seconds to recognize pushed files - wait before testing!
|
||||
|
||||
```bash
|
||||
# Example: What setup-fork.sh changes
|
||||
|
||||
# BEFORE (points to upstream):
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
|
||||
# AFTER (points to your fork):
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/john/ProxmoxVE/main/misc/build.func)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
### Auto-Detect (Recommended)
|
||||
|
||||
```bash
|
||||
bash docs/contribution/setup-fork.sh --full
|
||||
```
|
||||
|
||||
Automatically reads your GitHub username from `git remote origin url`
|
||||
|
||||
### Specify Username
|
||||
|
||||
```bash
|
||||
bash docs/contribution/setup-fork.sh --full john
|
||||
```
|
||||
|
||||
Updates links to `github.com/john/ProxmoxVE`
|
||||
|
||||
### Custom Repository Name
|
||||
|
||||
```bash
|
||||
bash docs/contribution/setup-fork.sh --full john my-fork
|
||||
```
|
||||
|
||||
Updates links to `github.com/john/my-fork`
|
||||
|
||||
---
|
||||
|
||||
## What Gets Updated?
|
||||
|
||||
The script updates hardcoded links in these areas when using `--full`:
|
||||
|
||||
- `ct/`, `install/`, `vm/` scripts
|
||||
- `misc/` function libraries
|
||||
- `docs/` (including `docs/contribution/`)
|
||||
- Code examples in documentation
|
||||
|
||||
---
|
||||
|
||||
## After Setup
|
||||
|
||||
1. **Review changes**
|
||||
|
||||
```bash
|
||||
git diff docs/
|
||||
```
|
||||
|
||||
2. **Read git workflow tips**
|
||||
|
||||
```bash
|
||||
cat .git-setup-info
|
||||
```
|
||||
|
||||
3. **Start contributing**
|
||||
|
||||
```bash
|
||||
git checkout -b feature/my-app
|
||||
# Make your changes...
|
||||
git commit -m "feat: add my awesome app"
|
||||
```
|
||||
|
||||
4. **Follow the guide**
|
||||
```bash
|
||||
cat docs/contribution/GUIDE.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Keep Your Fork Updated
|
||||
|
||||
```bash
|
||||
# Add upstream if you haven't already
|
||||
git remote add upstream https://github.com/community-scripts/ProxmoxVE.git
|
||||
|
||||
# Get latest from upstream
|
||||
git fetch upstream
|
||||
git rebase upstream/main
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### Create a Feature Branch
|
||||
|
||||
```bash
|
||||
git checkout -b feature/docker-improvements
|
||||
# Make changes...
|
||||
git push origin feature/docker-improvements
|
||||
# Then create PR on GitHub
|
||||
```
|
||||
|
||||
### Sync Before Contributing
|
||||
|
||||
```bash
|
||||
git fetch upstream
|
||||
git rebase upstream/main
|
||||
git push -f origin main # Update your fork's main
|
||||
git checkout -b feature/my-feature
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Git is not installed" or "not a git repository"
|
||||
|
||||
```bash
|
||||
# Make sure you cloned the repo first
|
||||
git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git
|
||||
cd ProxmoxVE
|
||||
bash docs/contribution/setup-fork.sh --full
|
||||
```
|
||||
|
||||
### "Could not auto-detect GitHub username"
|
||||
|
||||
```bash
|
||||
# Your git origin URL isn't set up correctly
|
||||
git remote -v
|
||||
# Should show your fork URL, not community-scripts
|
||||
|
||||
# Fix it:
|
||||
git remote set-url origin https://github.com/YOUR_USERNAME/ProxmoxVE.git
|
||||
bash docs/contribution/setup-fork.sh --full
|
||||
```
|
||||
|
||||
### "Permission denied"
|
||||
|
||||
```bash
|
||||
# Make script executable
|
||||
chmod +x docs/contribution/setup-fork.sh
|
||||
bash docs/contribution/setup-fork.sh --full
|
||||
```
|
||||
|
||||
### Reverted Changes by Accident?
|
||||
|
||||
```bash
|
||||
# Backups are created automatically
|
||||
git checkout docs/*.backup
|
||||
# Or just re-run setup-fork.sh
|
||||
bash docs/contribution/setup-fork.sh --full
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. ✅ Run `bash docs/contribution/setup-fork.sh --full`
|
||||
2. 📖 Read [docs/contribution/GUIDE.md](GUIDE.md)
|
||||
3. 🍴 Choose your contribution path:
|
||||
- **Containers** → [docs/ct/README.md](docs/ct/README.md)
|
||||
- **Installation** → [docs/install/README.md](docs/install/README.md)
|
||||
- **VMs** → [docs/vm/README.md](docs/vm/README.md)
|
||||
- **Tools** → [docs/tools/README.md](docs/tools/README.md)
|
||||
4. 💻 Create your feature branch and contribute!
|
||||
|
||||
---
|
||||
|
||||
## Questions?
|
||||
|
||||
- **Fork Setup Issues?** → See [Troubleshooting](#troubleshooting) above
|
||||
- **How to Contribute?** → [docs/contribution/GUIDE.md](GUIDE.md)
|
||||
- **Git Workflows?** → `cat .git-setup-info`
|
||||
- **Project Structure?** → [docs/README.md](docs/README.md)
|
||||
|
||||
---
|
||||
|
||||
## Happy Contributing! 🚀
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,753 +0,0 @@
|
||||
# 🛠️ Helper Functions Reference
|
||||
|
||||
**Quick reference for all helper functions available in `tools.func`**
|
||||
|
||||
> These functions are automatically available in install scripts via `$FUNCTIONS_FILE_PATH`
|
||||
|
||||
---
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Scripts to Watch](#scripts-to-watch)
|
||||
- [Runtime & Language Setup](#runtime--language-setup)
|
||||
- [Database Setup](#database-setup)
|
||||
- [GitHub Release Helpers](#github-release-helpers)
|
||||
- [Tools & Utilities](#tools--utilities)
|
||||
- [SSL/TLS](#ssltls)
|
||||
- [Utility Functions](#utility-functions)
|
||||
- [Package Management](#package-management)
|
||||
|
||||
---
|
||||
|
||||
## 📚 Scripts to Watch
|
||||
|
||||
**Learn from real, well-implemented scripts. Each app requires TWO files that work together:**
|
||||
|
||||
| File | Location | Purpose |
|
||||
| ------------------ | ---------------------------- | ------------------------------------------------------------------------ |
|
||||
| **CT Script** | `ct/appname.sh` | Runs on **Proxmox host** - creates container, contains `update_script()` |
|
||||
| **Install Script** | `install/appname-install.sh` | Runs **inside container** - installs and configures the app |
|
||||
|
||||
> ⚠️ **Both files are ALWAYS required!** The CT script calls the install script automatically during container creation.
|
||||
|
||||
Install scripts are **not** run directly by users; they are invoked by the CT script inside the container.
|
||||
|
||||
### Node.js + PostgreSQL
|
||||
|
||||
**Koel** - Music streaming with PHP + Node.js + PostgreSQL
|
||||
| File | Link |
|
||||
| ----------------- | -------------------------------------------------------- |
|
||||
| CT (update logic) | [ct/koel.sh](../../ct/koel.sh) |
|
||||
| Install | [install/koel-install.sh](../../install/koel-install.sh) |
|
||||
|
||||
**Actual Budget** - Finance app with npm global install
|
||||
| File | Link |
|
||||
| ----------------- | ------------------------------------------------------------------------ |
|
||||
| CT (update logic) | [ct/actualbudget.sh](../../ct/actualbudget.sh) |
|
||||
| Install | [install/actualbudget-install.sh](../../install/actualbudget-install.sh) |
|
||||
|
||||
### Python + uv
|
||||
|
||||
**MeTube** - YouTube downloader with Python uv + Node.js + Deno
|
||||
| File | Link |
|
||||
| ----------------- | ------------------------------------------------------------ |
|
||||
| CT (update logic) | [ct/metube.sh](../../ct/metube.sh) |
|
||||
| Install | [install/metube-install.sh](../../install/metube-install.sh) |
|
||||
|
||||
**Endurain** - Fitness tracker with Python uv + PostgreSQL/PostGIS
|
||||
| File | Link |
|
||||
| ----------------- | ---------------------------------------------------------------- |
|
||||
| CT (update logic) | [ct/endurain.sh](../../ct/endurain.sh) |
|
||||
| Install | [install/endurain-install.sh](../../install/endurain-install.sh) |
|
||||
|
||||
### Java + Gradle
|
||||
|
||||
**BookLore** - Book management with Java 21 + Gradle + MariaDB + Nginx
|
||||
| File | Link |
|
||||
| ----------------- | -------------------------------------------------------------- |
|
||||
| CT (update logic) | [ct/booklore.sh](../../ct/booklore.sh) |
|
||||
| Install | [install/booklore-install.sh](../../install/booklore-install.sh) |
|
||||
|
||||
### Pnpm + Meilisearch
|
||||
|
||||
**KaraKeep** - Bookmark manager with Pnpm + Meilisearch + Puppeteer
|
||||
| File | Link |
|
||||
| ----------------- | -------------------------------------------------------------- |
|
||||
| CT (update logic) | [ct/karakeep.sh](../../ct/karakeep.sh) |
|
||||
| Install | [install/karakeep-install.sh](../../install/karakeep-install.sh) |
|
||||
|
||||
### PHP + MariaDB/MySQL
|
||||
|
||||
**Wallabag** - Read-it-later with PHP + MariaDB + Redis + Nginx
|
||||
| File | Link |
|
||||
| ----------------- | ---------------------------------------------------------------- |
|
||||
| CT (update logic) | [ct/wallabag.sh](../../ct/wallabag.sh) |
|
||||
| Install | [install/wallabag-install.sh](../../install/wallabag-install.sh) |
|
||||
|
||||
**InvoiceNinja** - Invoicing with PHP + MariaDB + Supervisor
|
||||
| File | Link |
|
||||
| ----------------- | ------------------------------------------------------------------------ |
|
||||
| CT (update logic) | [ct/invoiceninja.sh](../../ct/invoiceninja.sh) |
|
||||
| Install | [install/invoiceninja-install.sh](../../install/invoiceninja-install.sh) |
|
||||
|
||||
**BookStack** - Wiki/Docs with PHP + MariaDB + Apache
|
||||
| File | Link |
|
||||
| ----------------- | ------------------------------------------------------------------ |
|
||||
| CT (update logic) | [ct/bookstack.sh](../../ct/bookstack.sh) |
|
||||
| Install | [install/bookstack-install.sh](../../install/bookstack-install.sh) |
|
||||
|
||||
### PHP + SQLite (Simple)
|
||||
|
||||
**Speedtest Tracker** - Speedtest with PHP + SQLite + Nginx
|
||||
| File | Link |
|
||||
| ----------------- | ---------------------------------------------------------------------------------- |
|
||||
| CT (update logic) | [ct/speedtest-tracker.sh](../../ct/speedtest-tracker.sh) |
|
||||
| Install | [install/speedtest-tracker-install.sh](../../install/speedtest-tracker-install.sh) |
|
||||
|
||||
---
|
||||
|
||||
## Runtime & Language Setup
|
||||
|
||||
### `setup_nodejs`
|
||||
|
||||
Install Node.js from NodeSource repository.
|
||||
|
||||
```bash
|
||||
# Default (Node.js 24)
|
||||
setup_nodejs
|
||||
|
||||
# Specific version
|
||||
NODE_VERSION="20" setup_nodejs
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
NODE_VERSION="24" setup_nodejs
|
||||
```
|
||||
|
||||
### `setup_go`
|
||||
|
||||
Install Go programming language (latest stable).
|
||||
|
||||
```bash
|
||||
setup_go
|
||||
|
||||
# Use in script
|
||||
setup_go
|
||||
cd /opt/myapp
|
||||
$STD go build -o myapp .
|
||||
```
|
||||
|
||||
### `setup_rust`
|
||||
|
||||
Install Rust via rustup.
|
||||
|
||||
```bash
|
||||
setup_rust
|
||||
|
||||
# Use in script
|
||||
setup_rust
|
||||
source "$HOME/.cargo/env"
|
||||
$STD cargo build --release
|
||||
```
|
||||
|
||||
### `setup_uv`
|
||||
|
||||
Install Python uv package manager (fast pip/venv replacement).
|
||||
|
||||
```bash
|
||||
# Default
|
||||
setup_uv
|
||||
|
||||
# Install a specific Python version
|
||||
PYTHON_VERSION="3.12" setup_uv
|
||||
|
||||
# Use in script
|
||||
setup_uv
|
||||
cd /opt/myapp
|
||||
$STD uv sync --locked
|
||||
```
|
||||
|
||||
### `setup_ruby`
|
||||
|
||||
Install Ruby from official repositories.
|
||||
|
||||
```bash
|
||||
setup_ruby
|
||||
```
|
||||
|
||||
### `setup_php`
|
||||
|
||||
Install PHP with configurable modules and FPM/Apache support.
|
||||
|
||||
```bash
|
||||
# Basic PHP
|
||||
setup_php
|
||||
|
||||
# Full configuration
|
||||
PHP_VERSION="8.4" \
|
||||
PHP_MODULE="mysqli,gd,curl,mbstring,xml,zip,ldap" \
|
||||
PHP_FPM="YES" \
|
||||
PHP_APACHE="YES" \
|
||||
setup_php
|
||||
```
|
||||
|
||||
**Environment Variables:**
|
||||
| Variable | Default | Description |
|
||||
| ------------- | ------- | ------------------------------- |
|
||||
| `PHP_VERSION` | `8.4` | PHP version to install |
|
||||
| `PHP_MODULE` | `""` | Comma-separated list of modules |
|
||||
| `PHP_FPM` | `NO` | Install PHP-FPM |
|
||||
| `PHP_APACHE` | `NO` | Install Apache module |
|
||||
|
||||
### `setup_composer`
|
||||
|
||||
Install PHP Composer package manager.
|
||||
|
||||
```bash
|
||||
setup_php
|
||||
setup_composer
|
||||
|
||||
# Use in script
|
||||
$STD composer install --no-dev
|
||||
```
|
||||
|
||||
### `setup_java`
|
||||
|
||||
Install Java (OpenJDK).
|
||||
|
||||
```bash
|
||||
# Default (Java 21)
|
||||
setup_java
|
||||
|
||||
# Specific version
|
||||
JAVA_VERSION="17" setup_java
|
||||
JAVA_VERSION="21" setup_java
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Database Setup
|
||||
|
||||
### `setup_mariadb`
|
||||
|
||||
Install MariaDB server.
|
||||
|
||||
```bash
|
||||
setup_mariadb
|
||||
```
|
||||
|
||||
### `setup_mariadb_db`
|
||||
|
||||
Create a MariaDB database and user. Sets `$MARIADB_DB_PASS` with the generated password.
|
||||
|
||||
```bash
|
||||
setup_mariadb
|
||||
MARIADB_DB_NAME="myapp_db" MARIADB_DB_USER="myapp_user" setup_mariadb_db
|
||||
|
||||
# After calling, these variables are available:
|
||||
# $MARIADB_DB_NAME - Database name
|
||||
# $MARIADB_DB_USER - Database user
|
||||
# $MARIADB_DB_PASS - Generated password (saved to ~/[appname].creds)
|
||||
```
|
||||
|
||||
### `setup_mysql`
|
||||
|
||||
Install MySQL server.
|
||||
|
||||
```bash
|
||||
setup_mysql
|
||||
```
|
||||
|
||||
### `setup_postgresql`
|
||||
|
||||
Install PostgreSQL server.
|
||||
|
||||
```bash
|
||||
# Default (PostgreSQL 16)
|
||||
setup_postgresql
|
||||
|
||||
# Specific version
|
||||
PG_VERSION="16" setup_postgresql
|
||||
PG_VERSION="16" setup_postgresql
|
||||
```
|
||||
|
||||
### `setup_postgresql_db`
|
||||
|
||||
Create a PostgreSQL database and user. Sets `$PG_DB_PASS` with the generated password.
|
||||
|
||||
```bash
|
||||
PG_VERSION="17" setup_postgresql
|
||||
PG_DB_NAME="myapp_db" PG_DB_USER="myapp_user" setup_postgresql_db
|
||||
|
||||
# After calling, these variables are available:
|
||||
# $PG_DB_NAME - Database name
|
||||
# $PG_DB_USER - Database user
|
||||
# $PG_DB_PASS - Generated password (saved to ~/[appname].creds)
|
||||
```
|
||||
|
||||
### `setup_mongodb`
|
||||
|
||||
Install MongoDB server.
|
||||
|
||||
```bash
|
||||
setup_mongodb
|
||||
```
|
||||
|
||||
### `setup_clickhouse`
|
||||
|
||||
Install ClickHouse analytics database.
|
||||
|
||||
```bash
|
||||
setup_clickhouse
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Repository Management
|
||||
|
||||
### `setup_deb822_repo`
|
||||
|
||||
The modern standard (Debian 12+) for adding external repositories. Automatically handles GPG keys and sources.
|
||||
|
||||
```bash
|
||||
setup_deb822_repo \
|
||||
"nodejs" \
|
||||
"https://deb.nodesource.com/gpgkey/nodesource.gpg.key" \
|
||||
"https://deb.nodesource.com/node_22.x" \
|
||||
"bookworm" \
|
||||
"main"
|
||||
```
|
||||
|
||||
### `prepare_repository_setup`
|
||||
|
||||
A high-level helper that performs three critical tasks before adding a new repo:
|
||||
1. Cleans up old repo files matching the names provided.
|
||||
2. Removes old GPG keyrings from all standard locations.
|
||||
3. Ensures APT is in a working state (fixes locks, runs update).
|
||||
|
||||
```bash
|
||||
# Clean up old mysql/mariadb artifacts before setup
|
||||
prepare_repository_setup "mariadb" "mysql"
|
||||
```
|
||||
|
||||
### `cleanup_tool_keyrings`
|
||||
|
||||
Force-removes GPG keys for specific tools from `/usr/share/keyrings/`, `/etc/apt/keyrings/`, and `/etc/apt/trusted.gpg.d/`.
|
||||
|
||||
```bash
|
||||
cleanup_tool_keyrings "docker" "kubernetes"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## GitHub Release Helpers
|
||||
|
||||
> **Note**: `fetch_and_deploy_gh_release` is the **preferred method** for downloading GitHub releases. It handles version tracking automatically. Only use `get_latest_github_release` if you need the version number separately.
|
||||
|
||||
### `fetch_and_deploy_gh_release`
|
||||
|
||||
**Primary method** for downloading and extracting GitHub releases. Handles version tracking automatically.
|
||||
|
||||
```bash
|
||||
# Basic usage - downloads tarball to /opt/appname
|
||||
fetch_and_deploy_gh_release "appname" "owner/repo"
|
||||
|
||||
# With explicit parameters
|
||||
fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
|
||||
|
||||
# Pre-built release with specific asset pattern
|
||||
fetch_and_deploy_gh_release "koel" "koel/koel" "prebuild" "latest" "/opt/koel" "koel-*.tar.gz"
|
||||
|
||||
# Clean install (removes old directory first) - used in update_script
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo" "tarball" "latest" "/opt/appname"
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
| Parameter | Default | Description |
|
||||
| --------------- | ------------- | ----------------------------------------------------------------- |
|
||||
| `name` | required | App name (for version tracking) |
|
||||
| `repo` | required | GitHub repo (`owner/repo`) |
|
||||
| `type` | `tarball` | Release type: `tarball`, `zipball`, `prebuild`, `binary` |
|
||||
| `version` | `latest` | Version tag or `latest` |
|
||||
| `dest` | `/opt/[name]` | Destination directory |
|
||||
| `asset_pattern` | `""` | For `prebuild`: glob pattern to match asset (e.g. `app-*.tar.gz`) |
|
||||
|
||||
**Environment Variables:**
|
||||
| Variable | Description |
|
||||
| ----------------- | ------------------------------------------------------------ |
|
||||
| `CLEAN_INSTALL=1` | Remove destination directory before extracting (for updates) |
|
||||
|
||||
### `check_for_gh_release`
|
||||
|
||||
Check if a newer version is available. Returns 0 if update needed, 1 if already at latest. **Use in `update_script()` function.**
|
||||
|
||||
```bash
|
||||
# In update_script() function in ct/appname.sh
|
||||
if check_for_gh_release "appname" "owner/repo"; then
|
||||
msg_info "Updating..."
|
||||
# Stop services, backup, update, restore, start
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "appname" "owner/repo"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
```
|
||||
|
||||
### `get_latest_github_release`
|
||||
|
||||
Get the latest release version from a GitHub repository. **Only use if you need the version number separately** (e.g., for manual download or display).
|
||||
|
||||
```bash
|
||||
RELEASE=$(get_latest_github_release "owner/repo")
|
||||
echo "Latest version: $RELEASE"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tools & Utilities
|
||||
|
||||
### `setup_meilisearch`
|
||||
|
||||
Install Meilisearch, a lightning-fast search engine.
|
||||
|
||||
```bash
|
||||
setup_meilisearch
|
||||
|
||||
# Use in script
|
||||
$STD php artisan scout:sync-index-settings
|
||||
```
|
||||
|
||||
### `setup_yq`
|
||||
|
||||
Install yq YAML processor.
|
||||
|
||||
```bash
|
||||
setup_yq
|
||||
|
||||
# Use in script
|
||||
yq '.server.port = 8080' -i config.yaml
|
||||
````
|
||||
|
||||
### `setup_ffmpeg`
|
||||
|
||||
Install FFmpeg with common codecs.
|
||||
|
||||
```bash
|
||||
setup_ffmpeg
|
||||
```
|
||||
|
||||
### `setup_hwaccel`
|
||||
|
||||
Setup GPU hardware acceleration (Intel/AMD/NVIDIA).
|
||||
|
||||
```bash
|
||||
# Only runs if GPU passthrough is detected (/dev/dri, /dev/nvidia0, /dev/kfd)
|
||||
setup_hwaccel
|
||||
```
|
||||
|
||||
### `setup_imagemagick`
|
||||
|
||||
Install ImageMagick 7 from source.
|
||||
|
||||
```bash
|
||||
setup_imagemagick
|
||||
```
|
||||
|
||||
### `setup_docker`
|
||||
|
||||
Install Docker Engine.
|
||||
|
||||
```bash
|
||||
setup_docker
|
||||
```
|
||||
|
||||
### `setup_adminer`
|
||||
|
||||
Install Adminer for database management.
|
||||
|
||||
```bash
|
||||
setup_mariadb
|
||||
setup_adminer
|
||||
|
||||
# Access at http://IP/adminer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## SSL/TLS
|
||||
|
||||
### `create_self_signed_cert`
|
||||
|
||||
Create a self-signed SSL certificate.
|
||||
|
||||
```bash
|
||||
create_self_signed_cert
|
||||
|
||||
# Creates files at:
|
||||
# /etc/ssl/[appname]/[appname].key
|
||||
# /etc/ssl/[appname]/[appname].crt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Utility Functions
|
||||
|
||||
### `verify_tool_version`
|
||||
|
||||
Validate that the installed major version matches the expected version. Useful during upgrades or troubleshooting.
|
||||
|
||||
```bash
|
||||
# Verify Node.js is version 22
|
||||
verify_tool_version "nodejs" "22" "$(node -v | grep -oP '^v\K[0-9]+')"
|
||||
```
|
||||
|
||||
### `get_lxc_ip`
|
||||
|
||||
Set the `$LOCAL_IP` variable with the container's IP address.
|
||||
|
||||
```bash
|
||||
get_lxc_ip
|
||||
echo "Container IP: $LOCAL_IP"
|
||||
|
||||
# Use in config files
|
||||
sed -i "s/localhost/$LOCAL_IP/g" /opt/myapp/config.yaml
|
||||
```
|
||||
|
||||
### `ensure_dependencies`
|
||||
|
||||
Ensure packages are installed (installs if missing).
|
||||
|
||||
```bash
|
||||
ensure_dependencies "jq" "unzip" "curl"
|
||||
```
|
||||
|
||||
### `msg_info` / `msg_ok` / `msg_error` / `msg_warn`
|
||||
|
||||
Display formatted messages.
|
||||
|
||||
```bash
|
||||
msg_info "Installing application..."
|
||||
# ... do work ...
|
||||
msg_ok "Installation complete"
|
||||
|
||||
msg_warn "Optional feature not available"
|
||||
msg_error "Installation failed"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Package Management
|
||||
|
||||
### `cleanup_lxc`
|
||||
|
||||
Final cleanup function - call at end of install script.
|
||||
|
||||
```bash
|
||||
# At the end of your install script
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc # Handles autoremove, autoclean, cache cleanup
|
||||
```
|
||||
|
||||
### `install_packages_with_retry`
|
||||
|
||||
Install packages with automatic retry on failure.
|
||||
|
||||
```bash
|
||||
install_packages_with_retry "package1" "package2" "package3"
|
||||
```
|
||||
|
||||
### `prepare_repository_setup`
|
||||
|
||||
Prepare system for adding new repositories (cleanup old repos, keyrings).
|
||||
|
||||
```bash
|
||||
prepare_repository_setup "mariadb" "mysql"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Examples
|
||||
|
||||
### Example 1: Node.js App with PostgreSQL (install script)
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: YourUsername
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/example/myapp
|
||||
|
||||
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"
|
||||
|
||||
# Setup runtimes and databases FIRST
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
PG_VERSION="16" setup_postgresql
|
||||
PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db
|
||||
get_lxc_ip
|
||||
|
||||
# Download app using fetch_and_deploy (handles version tracking)
|
||||
fetch_and_deploy_gh_release "myapp" "example/myapp" "tarball" "latest" "/opt/myapp"
|
||||
|
||||
msg_info "Setting up MyApp"
|
||||
cd /opt/myapp
|
||||
$STD npm ci --production
|
||||
msg_ok "Setup MyApp"
|
||||
|
||||
msg_info "Configuring MyApp"
|
||||
cat <<EOF >/opt/myapp/.env
|
||||
DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost/${PG_DB_NAME}
|
||||
HOST=${LOCAL_IP}
|
||||
PORT=3000
|
||||
EOF
|
||||
msg_ok "Configured MyApp"
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/myapp.service
|
||||
[Unit]
|
||||
Description=MyApp
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/opt/myapp
|
||||
ExecStart=/usr/bin/node /opt/myapp/server.js
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now myapp
|
||||
msg_ok "Created Service"
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
### Example 2: Matching Container Script (ct script)
|
||||
|
||||
```bash
|
||||
#!/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: YourUsername
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/example/myapp
|
||||
|
||||
APP="MyApp"
|
||||
var_tags="${var_tags:-webapp}"
|
||||
var_cpu="${var_cpu:-2}"
|
||||
var_ram="${var_ram:-2048}"
|
||||
var_disk="${var_disk:-6}"
|
||||
var_os="${var_os:-debian}"
|
||||
var_version="${var_version:-12}"
|
||||
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/myapp ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
# check_for_gh_release returns true if update available
|
||||
if check_for_gh_release "myapp" "example/myapp"; then
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop myapp
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
msg_info "Creating Backup"
|
||||
cp /opt/myapp/.env /tmp/myapp_env.bak
|
||||
msg_ok "Created Backup"
|
||||
|
||||
# CLEAN_INSTALL=1 removes old dir before extracting
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "myapp" "example/myapp" "tarball" "latest" "/opt/myapp"
|
||||
|
||||
msg_info "Restoring Config & Rebuilding"
|
||||
cp /tmp/myapp_env.bak /opt/myapp/.env
|
||||
rm /tmp/myapp_env.bak
|
||||
cd /opt/myapp
|
||||
$STD npm ci --production
|
||||
msg_ok "Restored Config & Rebuilt"
|
||||
|
||||
msg_info "Starting Service"
|
||||
systemctl start myapp
|
||||
msg_ok "Started Service"
|
||||
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"
|
||||
```
|
||||
|
||||
### Example 3: PHP App with MariaDB (install script)
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
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"
|
||||
|
||||
# PHP with FPM and common modules
|
||||
PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bcmath,curl,gd,intl,mbstring,mysql,xml,zip" setup_php
|
||||
setup_composer
|
||||
setup_mariadb
|
||||
MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" setup_mariadb_db
|
||||
get_lxc_ip
|
||||
|
||||
# Download pre-built release (with asset pattern)
|
||||
fetch_and_deploy_gh_release "myapp" "example/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz"
|
||||
|
||||
msg_info "Configuring MyApp"
|
||||
cd /opt/myapp
|
||||
cp .env.example .env
|
||||
sed -i "s|APP_URL=.*|APP_URL=http://${LOCAL_IP}|" .env
|
||||
sed -i "s|DB_DATABASE=.*|DB_DATABASE=${MARIADB_DB_NAME}|" .env
|
||||
sed -i "s|DB_USERNAME=.*|DB_USERNAME=${MARIADB_DB_USER}|" .env
|
||||
sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=${MARIADB_DB_PASS}|" .env
|
||||
$STD composer install --no-dev --no-interaction
|
||||
$STD php artisan key:generate --force
|
||||
$STD php artisan migrate --force
|
||||
chown -R www-data:www-data /opt/myapp
|
||||
msg_ok "Configured MyApp"
|
||||
|
||||
# ... nginx config, service creation ...
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
@@ -1,654 +0,0 @@
|
||||
# 🤝 Contributing to ProxmoxVE
|
||||
|
||||
Complete guide to contributing to the ProxmoxVE project - from your first fork to submitting your pull request.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Quick Start](#quick-start)
|
||||
- [Setting Up Your Fork](#setting-up-your-fork)
|
||||
- [Coding Standards](#coding-standards)
|
||||
- [Code Audit](#code-audit)
|
||||
- [Guides & Resources](#guides--resources)
|
||||
- [FAQ](#faq)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### 60 Seconds to Contributing (Development)
|
||||
|
||||
When developing and testing **in your fork**:
|
||||
|
||||
```bash
|
||||
# 1. Fork on GitHub
|
||||
# Visit: https://github.com/community-scripts/ProxmoxVE → Fork (top right)
|
||||
|
||||
# 2. Clone your fork
|
||||
git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git
|
||||
cd ProxmoxVE
|
||||
|
||||
# 3. Auto-configure your fork (IMPORTANT - updates all links!)
|
||||
bash docs/contribution/setup-fork.sh --full
|
||||
|
||||
# 4. Create a feature branch
|
||||
git checkout -b feature/my-awesome-app
|
||||
|
||||
# 5. Read the guides
|
||||
cat docs/README.md # Documentation overview
|
||||
cat docs/ct/DETAILED_GUIDE.md # For container scripts
|
||||
cat docs/install/DETAILED_GUIDE.md # For install scripts
|
||||
|
||||
# 6. Create your contribution
|
||||
cp docs/contribution/templates_ct/AppName.sh ct/myapp.sh
|
||||
cp docs/contribution/templates_install/AppName-install.sh install/myapp-install.sh
|
||||
# ... edit files ...
|
||||
|
||||
# 7. Push to your fork and test via GitHub
|
||||
git push origin feature/my-awesome-app
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"
|
||||
# ⏱️ GitHub may take 10-30 seconds to update files - be patient!
|
||||
|
||||
# 8. Request website metadata via the website
|
||||
# Go to the script's page on the website, use the "Report issue" button — it will guide you.
|
||||
|
||||
# 9. No direct install-script test
|
||||
# Install scripts are executed by the CT script inside the container
|
||||
|
||||
# 10. Commit ONLY your new files (see Cherry-Pick section below!)
|
||||
git add ct/myapp.sh install/myapp-install.sh
|
||||
git commit -m "feat: add MyApp container and install scripts"
|
||||
git push origin feature/my-awesome-app
|
||||
|
||||
# 11. Create Pull Request on GitHub
|
||||
```
|
||||
|
||||
⚠️ **IMPORTANT: After setup-fork.sh, many files are modified!**
|
||||
|
||||
See the **Cherry-Pick: Submitting Only Your Changes** section below to learn how to push ONLY your 2 files instead of 600+ modified files!
|
||||
|
||||
### How Users Run Scripts (After Merged)
|
||||
|
||||
Once your script is merged to the main repository, users download and run it from GitHub like this:
|
||||
|
||||
```bash
|
||||
# ✅ Users run from GitHub (normal usage after PR merged)
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/myapp.sh)"
|
||||
|
||||
# Install scripts are called by the CT script and are not run directly by users
|
||||
```
|
||||
|
||||
### Development vs. Production Execution
|
||||
|
||||
**During Development (you, in your fork):**
|
||||
|
||||
```bash
|
||||
# You MUST test via curl from your GitHub fork (not local files!)
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"
|
||||
|
||||
# The script's curl commands are updated by setup-fork.sh to point to YOUR fork
|
||||
# This ensures you're testing your actual changes
|
||||
# ⏱️ Wait 10-30 seconds after pushing - GitHub updates slowly
|
||||
```
|
||||
|
||||
**After Merge (users, from GitHub):**
|
||||
|
||||
```bash
|
||||
# Users download the script from upstream via curl
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/myapp.sh)"
|
||||
|
||||
# The script's curl commands now point back to upstream (community-scripts)
|
||||
# This is the stable, tested version
|
||||
```
|
||||
|
||||
**Summary:**
|
||||
|
||||
- **Development**: Push to fork, test via curl → setup-fork.sh changes curl URLs to your fork
|
||||
- **Production**: curl | bash from upstream → curl URLs point to community-scripts repo
|
||||
|
||||
---
|
||||
|
||||
## 🍴 Setting Up Your Fork
|
||||
|
||||
### Automatic Setup (Recommended)
|
||||
|
||||
When you clone your fork, run the setup script to automatically configure everything:
|
||||
|
||||
```bash
|
||||
bash docs/contribution/setup-fork.sh --full
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
|
||||
- Auto-detects your GitHub username from git config
|
||||
- Auto-detects your fork repository name
|
||||
- Updates **ALL** hardcoded links to point to your fork instead of the main repo (`--full`)
|
||||
- Creates `.git-setup-info` with your configuration
|
||||
- Allows you to develop and test independently in your fork
|
||||
|
||||
**Why this matters:**
|
||||
|
||||
Without running this script, all links in your fork will still point to the upstream repository (community-scripts). This is a problem when testing because:
|
||||
|
||||
- Installation links will pull from upstream, not your fork
|
||||
- Updates will target the wrong repository
|
||||
- Your contributions won't be properly tested
|
||||
|
||||
**After running setup-fork.sh:**
|
||||
|
||||
Your fork is fully configured and ready to develop. You can:
|
||||
|
||||
- Push changes to your fork
|
||||
- Test via curl: `bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"`
|
||||
- All links will reference your fork for development
|
||||
- ⏱️ Wait 10-30 seconds after pushing - GitHub takes time to update
|
||||
- Commit and push with confidence
|
||||
- Create a PR to merge into upstream
|
||||
|
||||
**See**: [FORK_SETUP.md](FORK_SETUP.md) for detailed instructions
|
||||
|
||||
### Manual Setup
|
||||
|
||||
If the script doesn't work, manually configure:
|
||||
|
||||
```bash
|
||||
# Set git user
|
||||
git config user.name "Your Name"
|
||||
git config user.email "your.email@example.com"
|
||||
|
||||
# Add upstream remote for syncing with main repo
|
||||
git remote add upstream https://github.com/community-scripts/ProxmoxVE.git
|
||||
|
||||
# Verify remotes
|
||||
git remote -v
|
||||
# Should show: origin (your fork) and upstream (main repo)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 Coding Standards
|
||||
|
||||
All scripts and configurations must follow our coding standards to ensure consistency and quality.
|
||||
|
||||
### Available Guides
|
||||
|
||||
- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Essential coding standards and best practices
|
||||
- **[CODE-AUDIT.md](CODE-AUDIT.md)** - Code review checklist and audit procedures
|
||||
- **[GUIDE.md](GUIDE.md)** - Comprehensive contribution guide
|
||||
- **[HELPER_FUNCTIONS.md](HELPER_FUNCTIONS.md)** - Reference for all tools.func helper functions
|
||||
- **Container Scripts** - `/ct/` templates and guidelines
|
||||
- **Install Scripts** - `/install/` templates and guidelines
|
||||
- **Website metadata** – Request via the website (Report issue on the script page); see [templates_json/AppName.md](templates_json/AppName.md)
|
||||
|
||||
### Quick Checklist
|
||||
|
||||
- ✅ Use `/ct/example.sh` as template for container scripts
|
||||
- ✅ Use `/install/example-install.sh` as template for install scripts
|
||||
- ✅ Follow naming conventions: `appname.sh` and `appname-install.sh`
|
||||
- ✅ Include proper shebang: `#!/usr/bin/env bash`
|
||||
- ✅ Add copyright header with author
|
||||
- ✅ Handle errors properly with `msg_error`, `msg_ok`, etc.
|
||||
- ✅ Test before submitting PR (via curl from your fork, not local bash)
|
||||
- ✅ Update documentation if needed
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Code Audit
|
||||
|
||||
Before submitting a pull request, ensure your code passes our audit:
|
||||
|
||||
**See**: [CODE_AUDIT.md](CODE_AUDIT.md) for complete audit checklist
|
||||
|
||||
Key points:
|
||||
|
||||
- Code consistency with existing scripts
|
||||
- Proper error handling
|
||||
- Correct variable naming
|
||||
- Adequate comments and documentation
|
||||
- Security best practices
|
||||
|
||||
---
|
||||
|
||||
## 🍒 Cherry-Pick: Submitting Only Your Changes
|
||||
|
||||
**Problem**: `setup-fork.sh` modifies 600+ files to update links. You don't want to submit all of those changes - only your new 2 files!
|
||||
|
||||
**Solution**: Use git cherry-pick to select only YOUR files.
|
||||
|
||||
### Step-by-Step Cherry-Pick Guide
|
||||
|
||||
#### 1. Check what changed
|
||||
|
||||
```bash
|
||||
# See all modified files
|
||||
git status
|
||||
|
||||
# Verify your files are there
|
||||
git status | grep -E "ct/myapp|install/myapp"
|
||||
```
|
||||
|
||||
#### 2. Create a clean feature branch for submission
|
||||
|
||||
```bash
|
||||
# Go back to upstream main (clean slate)
|
||||
git fetch upstream
|
||||
git checkout -b submit/myapp upstream/main
|
||||
|
||||
# Don't use your modified main branch!
|
||||
```
|
||||
|
||||
#### 3. Cherry-pick ONLY your files
|
||||
|
||||
Cherry-picking extracts specific changes from commits:
|
||||
|
||||
```bash
|
||||
# Option A: Cherry-pick commits that added your files
|
||||
# (if you committed your files separately)
|
||||
git cherry-pick <commit-hash-of-your-files>
|
||||
|
||||
# Option B: Manually copy and commit only your files
|
||||
# From your work branch, get the file contents
|
||||
git show feature/my-awesome-app:ct/myapp.sh > /tmp/myapp.sh
|
||||
git show feature/my-awesome-app:install/myapp-install.sh > /tmp/myapp-install.sh
|
||||
|
||||
# Add them to the clean branch
|
||||
cp /tmp/myapp.sh ct/myapp.sh
|
||||
cp /tmp/myapp-install.sh install/myapp-install.sh
|
||||
|
||||
# Commit
|
||||
git add ct/myapp.sh install/myapp-install.sh
|
||||
git commit -m "feat: add MyApp"
|
||||
```
|
||||
|
||||
#### 4. Verify only your files are in the PR
|
||||
|
||||
```bash
|
||||
# Check git diff against upstream
|
||||
git diff upstream/main --name-only
|
||||
# Should show ONLY:
|
||||
# ct/myapp.sh
|
||||
# install/myapp-install.sh
|
||||
```
|
||||
|
||||
#### 5. Push and create PR
|
||||
|
||||
```bash
|
||||
# Push your clean submission branch
|
||||
git push origin submit/myapp
|
||||
|
||||
# Create PR on GitHub from: submit/myapp → main
|
||||
```
|
||||
|
||||
### Why This Matters
|
||||
|
||||
- ✅ Clean PR with only your changes
|
||||
- ✅ Easier for maintainers to review
|
||||
- ✅ Faster merge without conflicts
|
||||
- ❌ Without cherry-pick: PR has 600+ file changes (won't merge!)
|
||||
|
||||
### If You Made a Mistake
|
||||
|
||||
```bash
|
||||
# Delete the messy branch
|
||||
git branch -D submit/myapp
|
||||
|
||||
# Go back to clean branch
|
||||
git checkout -b submit/myapp upstream/main
|
||||
|
||||
# Try cherry-picking again
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
If you're using **Visual Studio Code** with an AI assistant, you can leverage our detailed guidelines to generate high-quality contributions automatically.
|
||||
|
||||
### How to Use AI Assistance
|
||||
|
||||
1. **Open the AI Guidelines**
|
||||
|
||||
```
|
||||
docs/contribution/AI.md
|
||||
```
|
||||
|
||||
This file contains all requirements, patterns, and examples for writing proper scripts.
|
||||
|
||||
2. **Prepare Your Information**
|
||||
|
||||
Before asking the AI to generate code, gather:
|
||||
- **Repository URL**: e.g., `https://github.com/owner/myapp`
|
||||
- **Dockerfile/Script**: Paste the app's installation instructions (if available)
|
||||
- **Dependencies**: What packages does it need? (Node, Python, Java, PostgreSQL, etc.)
|
||||
- **Ports**: What port does it listen on? (e.g., 3000, 8080, 5000)
|
||||
- **Configuration**: Any environment variables or config files?
|
||||
|
||||
3. **Tell the AI Assistant**
|
||||
|
||||
Share with the AI:
|
||||
- The repository URL
|
||||
- The Dockerfile or install instructions
|
||||
- Link to [docs/contribution/AI.md](AI.md) with instructions to follow
|
||||
|
||||
**Example prompt:**
|
||||
|
||||
```
|
||||
I want to contribute a container script for MyApp to ProxmoxVE.
|
||||
Repository: https://github.com/owner/myapp
|
||||
|
||||
Here's the Dockerfile:
|
||||
[paste Dockerfile content]
|
||||
|
||||
Please follow the guidelines in docs/contribution/AI.md to create:
|
||||
1. ct/myapp.sh (container script)
|
||||
2. install/myapp-install.sh (installation script)
|
||||
|
||||
Website listing/metadata is requested separately via the website (Report issue on the script page).
|
||||
```
|
||||
|
||||
4. **AI Will Generate**
|
||||
|
||||
The AI will produce scripts that:
|
||||
- Follow all ProxmoxVE patterns and conventions
|
||||
- Use helper functions from `tools.func` correctly
|
||||
- Include proper error handling and messages
|
||||
- Have correct update mechanisms
|
||||
- Are ready to submit as a PR
|
||||
|
||||
Website listing/metadata is requested separately via the website (Report issue on the script page).
|
||||
|
||||
### Key Points for AI Assistants
|
||||
|
||||
- **Templates Location**: `docs/contribution/templates_ct/AppName.sh`, `templates_install/`, `templates_json/`
|
||||
- **Guidelines**: Must follow `docs/contribution/AI.md` exactly
|
||||
- **Helper Functions**: Use only functions from `misc/tools.func` - never write custom ones
|
||||
- **Testing**: Always test before submission via curl from your fork
|
||||
```bash
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"
|
||||
# Wait 10-30 seconds after pushing changes
|
||||
```
|
||||
- **No Docker**: Container scripts must be bare-metal, not Docker-based
|
||||
|
||||
### Benefits
|
||||
|
||||
- **Speed**: AI generates boilerplate in seconds
|
||||
- **Consistency**: Follows same patterns as 200+ existing scripts
|
||||
- **Quality**: Less bugs and more maintainable code
|
||||
- **Learning**: See how your app should be structured
|
||||
|
||||
---
|
||||
|
||||
### Documentation
|
||||
|
||||
- **[docs/README.md](../README.md)** - Main documentation hub
|
||||
- **[docs/ct/README.md](../ct/README.md)** - Container scripts overview
|
||||
- **[docs/install/README.md](../install/README.md)** - Installation scripts overview
|
||||
- **[docs/ct/DETAILED_GUIDE.md](../ct/DETAILED_GUIDE.md)** - Complete ct/ script reference
|
||||
- **[docs/install/DETAILED_GUIDE.md](../install/DETAILED_GUIDE.md)** - Complete install/ script reference
|
||||
- **[docs/TECHNICAL_REFERENCE.md](../TECHNICAL_REFERENCE.md)** - Architecture deep-dive
|
||||
- **[docs/EXIT_CODES.md](../EXIT_CODES.md)** - Exit codes reference
|
||||
- **[docs/DEV_MODE.md](../DEV_MODE.md)** - Debugging guide
|
||||
|
||||
### Community Guides
|
||||
|
||||
See [USER_SUBMITTED_GUIDES.md](USER_SUBMITTED_GUIDES.md) for excellent community-written guides:
|
||||
|
||||
- Home Assistant installation and configuration
|
||||
- Frigate setup on Proxmox
|
||||
- Docker and Portainer installation
|
||||
- Database setup and optimization
|
||||
- And many more!
|
||||
|
||||
### Templates
|
||||
|
||||
Use these templates when creating new scripts:
|
||||
|
||||
```bash
|
||||
# Container script template
|
||||
cp docs/contribution/templates_ct/AppName.sh ct/my-app.sh
|
||||
|
||||
# Installation script template
|
||||
cp docs/contribution/templates_install/AppName-install.sh install/my-app-install.sh
|
||||
```
|
||||
|
||||
For website metadata (description, logo, etc.), use the Report issue button on the script's page on the website.
|
||||
|
||||
**Template Features:**
|
||||
|
||||
- Updated to match current codebase patterns
|
||||
- Includes all available helper functions from `tools.func`
|
||||
- Examples for Node.js, Python, PHP, Go applications
|
||||
- Database setup examples (MariaDB, PostgreSQL)
|
||||
- Proper service creation and cleanup
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Git Workflow
|
||||
|
||||
### Keep Your Fork Updated
|
||||
|
||||
```bash
|
||||
# Fetch latest from upstream
|
||||
git fetch upstream
|
||||
|
||||
# Rebase your work on latest main
|
||||
git rebase upstream/main
|
||||
|
||||
# Push to your fork
|
||||
git push -f origin main
|
||||
```
|
||||
|
||||
### Create Feature Branch
|
||||
|
||||
```bash
|
||||
# Create and switch to new branch
|
||||
git checkout -b feature/my-feature
|
||||
|
||||
# Make changes...
|
||||
git add .
|
||||
git commit -m "feat: description of changes"
|
||||
|
||||
# Push to your fork
|
||||
git push origin feature/my-feature
|
||||
|
||||
# Create Pull Request on GitHub
|
||||
```
|
||||
|
||||
### Before Submitting PR
|
||||
|
||||
1. **Sync with upstream**
|
||||
|
||||
```bash
|
||||
git fetch upstream
|
||||
git rebase upstream/main
|
||||
```
|
||||
|
||||
2. **Test your changes** (via curl from your fork)
|
||||
|
||||
```bash
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)"
|
||||
# Follow prompts and test the container
|
||||
# ⏱️ Wait 10-30 seconds after pushing - GitHub takes time to update
|
||||
```
|
||||
|
||||
3. **Check code standards**
|
||||
- [ ] Follows template structure
|
||||
- [ ] Proper error handling
|
||||
- [ ] Documentation updated (if needed)
|
||||
- [ ] No hardcoded values
|
||||
- [ ] Version tracking implemented
|
||||
|
||||
4. **Push final changes**
|
||||
```bash
|
||||
git push origin feature/my-feature
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Pull Request Checklist
|
||||
|
||||
Before opening a PR:
|
||||
|
||||
- [ ] Code follows coding standards (see CONTRIBUTING.md)
|
||||
- [ ] All templates used correctly
|
||||
- [ ] Tested on Proxmox VE
|
||||
- [ ] Error handling implemented
|
||||
- [ ] Documentation updated (if applicable)
|
||||
- [ ] No merge conflicts
|
||||
- [ ] Synced with upstream/main
|
||||
- [ ] Clear PR title and description
|
||||
|
||||
---
|
||||
|
||||
## ❓ FAQ
|
||||
|
||||
### ❌ Why can't I test with `bash ct/myapp.sh` locally?
|
||||
|
||||
You might try:
|
||||
|
||||
```bash
|
||||
# ❌ WRONG - This won't test your actual changes!
|
||||
bash ct/myapp.sh
|
||||
./ct/myapp.sh
|
||||
sh ct/myapp.sh
|
||||
```
|
||||
|
||||
**Why this fails:**
|
||||
|
||||
- `bash ct/myapp.sh` uses the LOCAL clone file
|
||||
- The LOCAL file doesn't execute the curl commands - it's already on disk
|
||||
- The curl URLs INSIDE the script are modified by setup-fork.sh, but they're not executed
|
||||
- So you can't verify if your curl URLs actually work
|
||||
- Users will get the curl URL version (which may be broken)
|
||||
|
||||
**Solution:** Always test via curl from GitHub:
|
||||
|
||||
```bash
|
||||
# ✅ CORRECT - Tests the actual GitHub URLs
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/myapp.sh)"
|
||||
```
|
||||
|
||||
### ❓ How do I test my changes?
|
||||
|
||||
You **cannot** test locally with `bash ct/myapp.sh` from your cloned directory!
|
||||
|
||||
You **must** push to GitHub and test via curl from your fork:
|
||||
|
||||
```bash
|
||||
# 1. Push your changes to your fork
|
||||
git push origin feature/my-awesome-app
|
||||
|
||||
# 2. Test via curl (this loads the script from GitHub, not local files)
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)"
|
||||
|
||||
# 3. For verbose/debug output, pass environment variables
|
||||
VERBOSE=yes bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)"
|
||||
DEV_MODE_LOGS=true bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/my-app.sh)"
|
||||
```
|
||||
|
||||
**Why?**
|
||||
|
||||
- Local `bash ct/myapp.sh` uses local files from your clone
|
||||
- But the script's INTERNAL curl commands have been modified by setup-fork.sh to point to your fork
|
||||
- This discrepancy means you're not actually testing the curl URLs
|
||||
- Testing via curl ensures the script downloads from YOUR fork GitHub URLs
|
||||
- ⏱️ **Important:** GitHub takes 10-30 seconds to recognize newly pushed files. Wait before testing!
|
||||
|
||||
**What if local bash worked?**
|
||||
|
||||
You'd be testing local files only, not the actual GitHub URLs that users will download. This means broken curl links wouldn't be caught during testing.
|
||||
|
||||
### What if my PR has conflicts?
|
||||
|
||||
```bash
|
||||
# Sync with upstream main repository
|
||||
git fetch upstream
|
||||
git rebase upstream/main
|
||||
|
||||
# Resolve conflicts in your editor
|
||||
git add .
|
||||
git rebase --continue
|
||||
git push -f origin your-branch
|
||||
```
|
||||
|
||||
### How do I keep my fork updated?
|
||||
|
||||
Two ways:
|
||||
|
||||
**Option 1: Run setup script again**
|
||||
|
||||
```bash
|
||||
bash docs/contribution/setup-fork.sh --full
|
||||
```
|
||||
|
||||
**Option 2: Manual sync**
|
||||
|
||||
```bash
|
||||
git fetch upstream
|
||||
git rebase upstream/main
|
||||
git push -f origin main
|
||||
```
|
||||
|
||||
### Where do I ask questions?
|
||||
|
||||
- **GitHub Issues**: For bugs and feature requests
|
||||
- **GitHub Discussions**: For general questions and ideas
|
||||
- **Discord**: Community-scripts server for real-time chat
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Learning Resources
|
||||
|
||||
### For First-Time Contributors
|
||||
|
||||
1. Read: [docs/README.md](../README.md) - Documentation overview
|
||||
2. Read: [CONTRIBUTING.md](CONTRIBUTING.md) - Essential coding standards
|
||||
3. Choose your path:
|
||||
- Containers → [docs/ct/DETAILED_GUIDE.md](../ct/DETAILED_GUIDE.md)
|
||||
- Installation → [docs/install/DETAILED_GUIDE.md](../install/DETAILED_GUIDE.md)
|
||||
4. Study existing scripts in same category
|
||||
5. Create your contribution
|
||||
|
||||
### For Experienced Developers
|
||||
|
||||
1. Review [CONTRIBUTING.md](CONTRIBUTING.md) - Coding standards
|
||||
2. Review [CODE_AUDIT.md](CODE_AUDIT.md) - Audit checklist
|
||||
3. Check templates in `/docs/contribution/templates_*/`
|
||||
4. Use AI assistants with [AI.md](AI.md) for code generation
|
||||
5. Submit PR with confidence
|
||||
|
||||
### For Using AI Assistants
|
||||
|
||||
See "Using AI Assistants" section above for:
|
||||
|
||||
- How to structure prompts
|
||||
- What information to provide
|
||||
- How to validate AI output
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Ready to Contribute?
|
||||
|
||||
1. **Fork** the repository
|
||||
2. **Clone** your fork and **setup** with `bash docs/contribution/setup-fork.sh --full`
|
||||
3. **Choose** your contribution type (container, installation, tools, etc.)
|
||||
4. **Read** the appropriate detailed guide
|
||||
5. **Create** your feature branch
|
||||
6. **Develop** and **test** your changes
|
||||
7. **Commit** with clear messages
|
||||
8. **Push** to your fork
|
||||
9. **Create** Pull Request
|
||||
|
||||
---
|
||||
|
||||
## 📞 Contact & Support
|
||||
|
||||
- **GitHub**: [community-scripts/ProxmoxVE](https://github.com/community-scripts/ProxmoxVE)
|
||||
- **Issues**: [GitHub Issues](https://github.com/community-scripts/ProxmoxVE/issues)
|
||||
- **Discussions**: [GitHub Discussions](https://github.com/community-scripts/ProxmoxVE/discussions)
|
||||
- **Discord**: [Join Server](https://discord.gg/UHrpNWGwkH)
|
||||
|
||||
---
|
||||
|
||||
**Thank you for contributing to ProxmoxVE!** 🙏
|
||||
|
||||
Your efforts help make Proxmox VE automation accessible to everyone. Happy coding! 🚀
|
||||
@@ -1,336 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
################################################################################
|
||||
# ProxmoxVE Fork Setup Script
|
||||
#
|
||||
# Automatically configures documentation and scripts for your fork
|
||||
# Detects your GitHub username and repository from git config
|
||||
# Updates all hardcoded links to point to your fork
|
||||
#
|
||||
# Usage:
|
||||
# ./setup-fork.sh # Auto-detect from git config (updates misc/ only)
|
||||
# ./setup-fork.sh YOUR_USERNAME # Specify username (updates misc/ only)
|
||||
# ./setup-fork.sh YOUR_USERNAME REPO_NAME # Specify both (updates misc/ only)
|
||||
# ./setup-fork.sh --full # Update all files including ct/, install/, vm/, etc.
|
||||
#
|
||||
# Examples:
|
||||
# ./setup-fork.sh john # Uses john/ProxmoxVE, updates misc/ only
|
||||
# ./setup-fork.sh john my-fork # Uses john/my-fork, updates misc/ only
|
||||
# ./setup-fork.sh --full # Auto-detect + update all files
|
||||
################################################################################
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Default values
|
||||
REPO_NAME="ProxmoxVE"
|
||||
USERNAME=""
|
||||
AUTO_DETECT=true
|
||||
UPDATE_ALL=false
|
||||
|
||||
################################################################################
|
||||
# FUNCTIONS
|
||||
################################################################################
|
||||
|
||||
print_header() {
|
||||
echo -e "\n${BLUE}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${BLUE}║${NC} ProxmoxVE Fork Setup Script"
|
||||
echo -e "${BLUE}║${NC} Configuring for your fork..."
|
||||
echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}\n"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✓${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}✗${NC} $1"
|
||||
}
|
||||
|
||||
# Detect username from git remote
|
||||
detect_username() {
|
||||
local remote_url
|
||||
|
||||
# Try to get from origin
|
||||
if ! remote_url=$(git config --get remote.origin.url 2>/dev/null); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract username from SSH or HTTPS URL
|
||||
if [[ $remote_url =~ git@github.com:([^/]+) ]]; then
|
||||
echo "${BASH_REMATCH[1]}"
|
||||
elif [[ $remote_url =~ github.com/([^/]+) ]]; then
|
||||
echo "${BASH_REMATCH[1]}"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Detect repo name from git remote
|
||||
detect_repo_name() {
|
||||
local remote_url
|
||||
|
||||
if ! remote_url=$(git config --get remote.origin.url 2>/dev/null); then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract repo name (remove .git if present)
|
||||
if [[ $remote_url =~ /([^/]+?)(.git)?$ ]]; then
|
||||
local repo="${BASH_REMATCH[1]}"
|
||||
echo "${repo%.git}"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Ask user for confirmation
|
||||
confirm() {
|
||||
local prompt="$1"
|
||||
local response
|
||||
|
||||
echo -ne "${YELLOW}${prompt} (y/n)${NC} "
|
||||
read -r response
|
||||
[[ $response =~ ^[Yy]$ ]]
|
||||
}
|
||||
|
||||
# Update links in files
|
||||
update_links() {
|
||||
local old_repo="community-scripts"
|
||||
local old_name="ProxmoxVE"
|
||||
local new_owner="$1"
|
||||
local new_repo="$2"
|
||||
local files_updated=0
|
||||
|
||||
print_info "Scanning for hardcoded links..."
|
||||
|
||||
# Change to repo root
|
||||
local repo_root=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
||||
|
||||
# Determine search path
|
||||
local search_path="$repo_root/misc"
|
||||
if [[ "$UPDATE_ALL" == "true" ]]; then
|
||||
search_path="$repo_root"
|
||||
print_info "Searching all files (--full mode)"
|
||||
else
|
||||
print_info "Searching misc/ directory only (core functions)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Find all files containing the old repo reference
|
||||
while IFS= read -r file; do
|
||||
# Count occurrences
|
||||
local count=$(grep -E -c "(github.com|githubusercontent.com)/$old_repo/$old_name" "$file" 2>/dev/null || echo 0)
|
||||
|
||||
if [[ $count -gt 0 ]]; then
|
||||
# Backup original
|
||||
cp "$file" "$file.backup"
|
||||
|
||||
# Replace links - use different sed syntax for BSD/macOS vs GNU sed
|
||||
if sed --version &>/dev/null 2>&1; then
|
||||
# GNU sed
|
||||
sed -E -i "s@(github.com|githubusercontent.com)/$old_repo/$old_name@\\1/$new_owner/$new_repo@g" "$file"
|
||||
else
|
||||
# BSD sed (macOS)
|
||||
sed -E -i '' "s@(github.com|githubusercontent.com)/$old_repo/$old_name@\\1/$new_owner/$new_repo@g" "$file"
|
||||
fi
|
||||
|
||||
((files_updated++))
|
||||
print_success "Updated $file ($count links)"
|
||||
fi
|
||||
done < <(find "$search_path" -type f \( -name "*.md" -o -name "*.sh" -o -name "*.func" -o -name "*.json" \) -not -path "*/.git/*" 2>/dev/null | xargs grep -E -l "(github.com|githubusercontent.com)/$old_repo/$old_name" 2>/dev/null)
|
||||
|
||||
return $files_updated
|
||||
}
|
||||
|
||||
# Create user git config setup info
|
||||
create_git_setup_info() {
|
||||
local username="$1"
|
||||
|
||||
cat >.git-setup-info <<'EOF'
|
||||
# Git Configuration for ProxmoxVE Development
|
||||
|
||||
## Recommended Git Configuration
|
||||
|
||||
### Set up remotes for easy syncing with upstream:
|
||||
|
||||
```bash
|
||||
# View your current remotes
|
||||
git remote -v
|
||||
|
||||
# If you don't have 'upstream' configured, add it:
|
||||
git remote add upstream https://github.com/community-scripts/ProxmoxVE.git
|
||||
|
||||
# Verify both remotes exist:
|
||||
git remote -v
|
||||
# Should show:
|
||||
# origin https://github.com/YOUR_USERNAME/ProxmoxVE.git (fetch)
|
||||
# origin https://github.com/YOUR_USERNAME/ProxmoxVE.git (push)
|
||||
# upstream https://github.com/community-scripts/ProxmoxVE.git (fetch)
|
||||
# upstream https://github.com/community-scripts/ProxmoxVE.git (push)
|
||||
```
|
||||
|
||||
### Configure Git User (if not done globally)
|
||||
|
||||
```bash
|
||||
git config user.name "Your Name"
|
||||
git config user.email "your.email@example.com"
|
||||
|
||||
# Or configure globally:
|
||||
git config --global user.name "Your Name"
|
||||
git config --global user.email "your.email@example.com"
|
||||
```
|
||||
|
||||
### Useful Git Workflows
|
||||
|
||||
**Keep your fork up-to-date:**
|
||||
```bash
|
||||
git fetch upstream
|
||||
git rebase upstream/main
|
||||
git push origin main
|
||||
```
|
||||
|
||||
**Create feature branch:**
|
||||
```bash
|
||||
git checkout -b feature/my-awesome-app
|
||||
# Make changes...
|
||||
git commit -m "feat: add my awesome app"
|
||||
git push origin feature/my-awesome-app
|
||||
```
|
||||
|
||||
**Pull latest from upstream:**
|
||||
```bash
|
||||
git fetch upstream
|
||||
git merge upstream/main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
For more help, see: docs/contribution/README.md
|
||||
EOF
|
||||
|
||||
print_success "Created .git-setup-info file"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# MAIN LOGIC
|
||||
################################################################################
|
||||
|
||||
print_header
|
||||
|
||||
# Parse command line arguments
|
||||
if [[ $# -gt 0 ]]; then
|
||||
# Check for --full flag
|
||||
if [[ "$1" == "--full" ]]; then
|
||||
UPDATE_ALL=true
|
||||
shift # Remove --full from arguments
|
||||
fi
|
||||
|
||||
# Process remaining arguments
|
||||
if [[ $# -gt 0 ]]; then
|
||||
USERNAME="$1"
|
||||
AUTO_DETECT=false
|
||||
|
||||
if [[ $# -gt 1 ]]; then
|
||||
REPO_NAME="$2"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Try auto-detection
|
||||
if [[ -z "$USERNAME" ]]; then
|
||||
if username=$(detect_username); then
|
||||
USERNAME="$username"
|
||||
print_success "Detected GitHub username: $USERNAME"
|
||||
else
|
||||
print_error "Could not auto-detect GitHub username from git config"
|
||||
echo -e "${YELLOW}Please run:${NC}"
|
||||
echo " ./setup-fork.sh YOUR_USERNAME"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Auto-detect repo name if needed
|
||||
if repo_name=$(detect_repo_name); then
|
||||
REPO_NAME="$repo_name"
|
||||
if [[ "$REPO_NAME" != "ProxmoxVE" ]]; then
|
||||
print_info "Detected custom repo name: $REPO_NAME"
|
||||
else
|
||||
print_success "Using default repo name: ProxmoxVE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Validate inputs
|
||||
if [[ -z "$USERNAME" ]]; then
|
||||
print_error "Username cannot be empty"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$REPO_NAME" ]]; then
|
||||
print_error "Repository name cannot be empty"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Show what we'll do
|
||||
echo -e "${BLUE}Configuration Summary:${NC}"
|
||||
echo " Repository URL: https://github.com/$USERNAME/$REPO_NAME"
|
||||
if [[ "$UPDATE_ALL" == "true" ]]; then
|
||||
echo " Files to update: ALL files (ct/, install/, vm/, misc/, docs/, etc.)"
|
||||
else
|
||||
echo " Files to update: misc/ directory only (core functions)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Ask for confirmation
|
||||
if ! confirm "Apply these changes?"; then
|
||||
print_warning "Setup cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Update all links
|
||||
if update_links "$USERNAME" "$REPO_NAME"; then
|
||||
links_changed=$?
|
||||
print_success "Updated $links_changed files"
|
||||
else
|
||||
print_warning "No links needed updating or some files not found"
|
||||
fi
|
||||
|
||||
# Create git setup info file
|
||||
create_git_setup_info "$USERNAME"
|
||||
|
||||
# Final summary
|
||||
echo ""
|
||||
echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}"
|
||||
echo -e "${GREEN}║${NC} Fork Setup Complete! ${GREEN}║${NC}"
|
||||
echo -e "${GREEN}╚════════════════════════════════════════════════════════════╝${NC}"
|
||||
echo ""
|
||||
|
||||
print_success "All documentation links updated to point to your fork"
|
||||
print_info "Your fork: https://github.com/$USERNAME/$REPO_NAME"
|
||||
print_info "Upstream: https://github.com/community-scripts/ProxmoxVE"
|
||||
echo ""
|
||||
|
||||
echo -e "${BLUE}Next Steps:${NC}"
|
||||
echo " 1. Review the changes: git diff"
|
||||
echo " 2. Check .git-setup-info for recommended git workflow"
|
||||
echo " 3. Start developing: git checkout -b feature/my-app"
|
||||
echo " 4. Read: docs/contribution/README.md"
|
||||
echo ""
|
||||
|
||||
print_success "Happy contributing! 🚀"
|
||||
@@ -1,278 +0,0 @@
|
||||
# CT Container Scripts - Quick Reference
|
||||
|
||||
> [!WARNING]
|
||||
> **This is legacy documentation.** Refer to the **modern template** at [templates_ct/AppName.sh](AppName.sh) for best practices.
|
||||
>
|
||||
> Current templates use:
|
||||
>
|
||||
> - `tools.func` helpers instead of manual patterns
|
||||
> - `check_for_gh_release` and `fetch_and_deploy_gh_release` from build.func
|
||||
> - Automatic setup-fork.sh configuration
|
||||
|
||||
---
|
||||
|
||||
## Before Creating a Script
|
||||
|
||||
1. **Fork & Clone:**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/YOUR_USERNAME/ProxmoxVE.git
|
||||
cd ProxmoxVE
|
||||
```
|
||||
|
||||
2. **Run setup-fork.sh** (updates all curl URLs to your fork):
|
||||
|
||||
```bash
|
||||
bash docs/contribution/setup-fork.sh
|
||||
```
|
||||
|
||||
3. **Copy the Modern Template:**
|
||||
|
||||
```bash
|
||||
cp templates_ct/AppName.sh ct/MyApp.sh
|
||||
# Edit ct/MyApp.sh with your app details
|
||||
```
|
||||
|
||||
4. **Test Your Script (via GitHub):**
|
||||
|
||||
⚠️ **Important:** You must push to GitHub and test via curl, not `bash ct/MyApp.sh`!
|
||||
|
||||
```bash
|
||||
# Push your changes to your fork first
|
||||
git push origin feature/my-awesome-app
|
||||
|
||||
# Then test via curl (this loads from YOUR fork, not local files)
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/MyApp.sh)"
|
||||
```
|
||||
|
||||
> 💡 **Why?** The script's curl commands are modified by setup-fork.sh, but local execution uses local files, not the updated GitHub URLs. Testing via curl ensures your script actually works.
|
||||
>
|
||||
> ⏱️ **Note:** GitHub sometimes takes 10-30 seconds to update files. If you don't see your changes, wait and try again.
|
||||
|
||||
5. **Cherry-Pick for PR** (submit ONLY your 3-4 files):
|
||||
- See [Cherry-Pick Guide](../README.md) for step-by-step git commands
|
||||
|
||||
---
|
||||
|
||||
## Template Structure
|
||||
|
||||
The modern template includes:
|
||||
|
||||
### Header
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# (Note: setup-fork.sh changes this URL to point to YOUR fork during development)
|
||||
```
|
||||
|
||||
### Metadata
|
||||
|
||||
```bash
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: YourUsername
|
||||
# License: MIT
|
||||
APP="MyApp"
|
||||
var_tags="app-category;foss"
|
||||
var_cpu="2"
|
||||
var_ram="2048"
|
||||
var_disk="4"
|
||||
var_os="alpine"
|
||||
var_version="3.20"
|
||||
var_unprivileged="1"
|
||||
```
|
||||
|
||||
### Core Setup
|
||||
|
||||
```bash
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
```
|
||||
|
||||
### Update Function
|
||||
|
||||
The modern template provides a standard update pattern:
|
||||
|
||||
```bash
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
# Use tools.func helpers:
|
||||
check_for_gh_release "myapp" "owner/repo"
|
||||
fetch_and_deploy_gh_release "myapp" "owner/repo" "tarball" "latest" "/opt/myapp"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Check for Updates (App Repository)
|
||||
|
||||
Use `check_for_gh_release` with the **app repo**:
|
||||
|
||||
```bash
|
||||
check_for_gh_release "myapp" "owner/repo"
|
||||
```
|
||||
|
||||
### Deploy External App
|
||||
|
||||
Use `fetch_and_deploy_gh_release` with the **app repo**:
|
||||
|
||||
```bash
|
||||
fetch_and_deploy_gh_release "myapp" "owner/repo"
|
||||
```
|
||||
|
||||
### Avoid Manual Version Checking
|
||||
|
||||
❌ OLD (manual):
|
||||
|
||||
```bash
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/myapp/myapp/releases/latest | grep tag_name)
|
||||
```
|
||||
|
||||
✅ NEW (use tools.func):
|
||||
|
||||
```bash
|
||||
fetch_and_deploy_gh_release "myapp" "owner/repo"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use tools.func helpers** - Don't manually curl for versions
|
||||
2. **Only add app-specific dependencies** - Don't add ca-certificates, curl, gnupg (handled by build.func)
|
||||
3. **Test via curl from your fork** - Push first, then: `bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/MyApp.sh)"`
|
||||
4. **Wait for GitHub to update** - Takes 10-30 seconds after git push
|
||||
5. **Cherry-pick only YOUR files** - Submit only ct/MyApp.sh, install/MyApp-install.sh (2 files). Website metadata: use Report issue on the script's page on the website.
|
||||
6. **Verify before PR** - Run `git diff upstream/main --name-only` to confirm only your files changed
|
||||
|
||||
---
|
||||
|
||||
## Common Update Patterns
|
||||
|
||||
See the [modern template](AppName.sh) and [AI.md](../AI.md) for complete working examples.
|
||||
|
||||
Recent reference scripts with good update functions:
|
||||
|
||||
- [Trip](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/trip.sh)
|
||||
- [Thingsboard](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/thingsboard.sh)
|
||||
- [UniFi](https://github.com/community-scripts/ProxmoxVE/blob/main/ct/unifi.sh)
|
||||
|
||||
---
|
||||
|
||||
## Need Help?
|
||||
|
||||
- **[README.md](../README.md)** - Full contribution workflow
|
||||
- **[AI.md](../AI.md)** - AI-generated script guidelines
|
||||
- **[FORK_SETUP.md](../FORK_SETUP.md)** - Why setup-fork.sh is important
|
||||
- **[Slack Community](https://discord.gg/your-link)** - Ask questions
|
||||
|
||||
````
|
||||
|
||||
### 3.4 **Verbosity**
|
||||
|
||||
- Use the appropriate flag (**-q** in the examples) for a command to suppress its output.
|
||||
Example:
|
||||
|
||||
```bash
|
||||
curl -fsSL
|
||||
unzip -q
|
||||
````
|
||||
|
||||
- If a command does not come with this functionality use `$STD` to suppress it's output.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
$STD php artisan migrate --force
|
||||
$STD php artisan config:clear
|
||||
```
|
||||
|
||||
### 3.5 **Backups**
|
||||
|
||||
- Backup user data if necessary.
|
||||
- Move all user data back in the directory when the update is finished.
|
||||
|
||||
> [!NOTE]
|
||||
> This is not meant to be a permanent backup
|
||||
|
||||
Example backup:
|
||||
|
||||
```bash
|
||||
mv /opt/snipe-it /opt/snipe-it-backup
|
||||
```
|
||||
|
||||
Example config restore:
|
||||
|
||||
```bash
|
||||
cp /opt/snipe-it-backup/.env /opt/snipe-it/.env
|
||||
cp -r /opt/snipe-it-backup/public/uploads/ /opt/snipe-it/public/uploads/
|
||||
cp -r /opt/snipe-it-backup/storage/private_uploads /opt/snipe-it/storage/private_uploads
|
||||
```
|
||||
|
||||
### 3.6 **Cleanup**
|
||||
|
||||
- Do not forget to remove any temporary files/folders such as zip-files or temporary backups.
|
||||
Example:
|
||||
|
||||
```bash
|
||||
rm -rf /opt/v${RELEASE}.zip
|
||||
rm -rf /opt/snipe-it-backup
|
||||
```
|
||||
|
||||
### 3.7 **No update function**
|
||||
|
||||
- In case you can not provide an update function use the following code to provide user feedback.
|
||||
|
||||
```bash
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
if [[ ! -d /opt/snipeit ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
msg_error "Currently we don't provide an update function for this ${APP}."
|
||||
exit
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4 **End of the script**
|
||||
|
||||
- `start`: Launches Whiptail dialogue
|
||||
- `build_container`: Collects and integrates user settings
|
||||
- `description`: Sets LXC container description
|
||||
- With `echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"` you can point the user to the IP:PORT/folder needed to access the app.
|
||||
|
||||
```bash
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}${CL}"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. **Contribution checklist**
|
||||
|
||||
- [ ] Shebang is correctly set (`#!/usr/bin/env bash`).
|
||||
- [ ] Correct link to _build.func_
|
||||
- [ ] Metadata (author, license) is included at the top.
|
||||
- [ ] Variables follow naming conventions.
|
||||
- [ ] Update function exists.
|
||||
- [ ] Update functions checks if app is installed and for new version.
|
||||
- [ ] Update function cleans up temporary files.
|
||||
- [ ] Script ends with a helpful message for the user to reach the application.
|
||||
@@ -1,138 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: [YourGitHubUsername]
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: [SOURCE_URL e.g. https://github.com/example/app]
|
||||
|
||||
# ============================================================================
|
||||
# APP CONFIGURATION
|
||||
# ============================================================================
|
||||
# These values are sent to build.func and define default container resources.
|
||||
# Users can customize these during installation via the interactive prompts.
|
||||
# ============================================================================
|
||||
|
||||
APP="[AppName]"
|
||||
var_tags="${var_tags:-[category1];[category2]}" # Max 2 tags, semicolon-separated
|
||||
var_cpu="${var_cpu:-2}" # CPU cores: 1-4 typical
|
||||
var_ram="${var_ram:-2048}" # RAM in MB: 512, 1024, 2048, etc.
|
||||
var_disk="${var_disk:-8}" # Disk in GB: 6, 8, 10, 20 typical
|
||||
var_os="${var_os:-debian}" # OS: debian, ubuntu, alpine
|
||||
var_version="${var_version:-13}" # OS Version: 13 (Debian), 24.04 (Ubuntu), 3.21 (Alpine)
|
||||
var_unprivileged="${var_unprivileged:-1}" # 1=unprivileged (secure), 0=privileged (for Docker/Podman)
|
||||
|
||||
# ============================================================================
|
||||
# INITIALIZATION - These are required in all CT scripts
|
||||
# ============================================================================
|
||||
header_info "$APP" # Display app name and setup header
|
||||
variables # Initialize build.func variables
|
||||
color # Load color variables for output
|
||||
catch_errors # Enable error handling with automatic exit on failure
|
||||
|
||||
# ============================================================================
|
||||
# UPDATE SCRIPT - Called when user selects "Update" from web interface
|
||||
# ============================================================================
|
||||
# This function is triggered by the web interface to update the application.
|
||||
# It should:
|
||||
# 1. Check if installation exists
|
||||
# 2. Check for new GitHub releases
|
||||
# 3. Stop running services
|
||||
# 4. Backup critical data
|
||||
# 5. Deploy new version
|
||||
# 6. Run post-update commands (migrations, config updates, etc.)
|
||||
# 7. Restore data if needed
|
||||
# 8. Start services
|
||||
#
|
||||
# Exit with `exit` at the end to prevent container restart.
|
||||
# ============================================================================
|
||||
|
||||
function update_script() {
|
||||
header_info
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
# Step 1: Verify installation exists
|
||||
if [[ ! -d /opt/[appname] ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
# Step 2: Check if update is available
|
||||
if check_for_gh_release "[appname]" "YourUsername/YourRepo"; then
|
||||
|
||||
# Step 3: Stop services before update
|
||||
msg_info "Stopping Service"
|
||||
systemctl stop [appname]
|
||||
msg_ok "Stopped Service"
|
||||
|
||||
# Step 4: Backup critical data before overwriting
|
||||
msg_info "Backing up Data"
|
||||
cp -r /opt/[appname]/data /opt/[appname]_data_backup 2>/dev/null || true
|
||||
msg_ok "Backed up Data"
|
||||
|
||||
# Step 5: Download and deploy new version
|
||||
# CLEAN_INSTALL=1 removes old directory before extracting
|
||||
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "[appname]" "owner/repo" "tarball" "latest" "/opt/[appname]"
|
||||
|
||||
# Step 6: Run post-update commands (uncomment as needed)
|
||||
# These examples show common patterns - use what applies to your app:
|
||||
#
|
||||
# For Node.js apps:
|
||||
# msg_info "Installing Dependencies"
|
||||
# cd /opt/[appname]
|
||||
# $STD npm ci --production
|
||||
# msg_ok "Installed Dependencies"
|
||||
#
|
||||
# For Python apps:
|
||||
# msg_info "Installing Dependencies"
|
||||
# cd /opt/[appname]
|
||||
# $STD uv sync --frozen
|
||||
# msg_ok "Installed Dependencies"
|
||||
#
|
||||
# For database migrations:
|
||||
# msg_info "Running Database Migrations"
|
||||
# cd /opt/[appname]
|
||||
# $STD npm run migrate
|
||||
# msg_ok "Ran Database Migrations"
|
||||
#
|
||||
# For PHP apps:
|
||||
# msg_info "Installing Dependencies"
|
||||
# cd /opt/[appname]
|
||||
# $STD composer install --no-dev
|
||||
# msg_ok "Installed Dependencies"
|
||||
|
||||
# Step 7: Restore data from backup
|
||||
msg_info "Restoring Data"
|
||||
cp -r /opt/[appname]_data_backup/. /opt/[appname]/data/ 2>/dev/null || true
|
||||
rm -rf /opt/[appname]_data_backup
|
||||
msg_ok "Restored Data"
|
||||
|
||||
# Step 8: Restart service with new version
|
||||
msg_info "Starting Service"
|
||||
systemctl start [appname]
|
||||
msg_ok "Started Service"
|
||||
msg_ok "Updated successfully!"
|
||||
fi
|
||||
exit
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# MAIN EXECUTION - Container creation flow
|
||||
# ============================================================================
|
||||
# These are called by build.func and handle the full installation process:
|
||||
# 1. start - Initialize container creation
|
||||
# 2. build_container - Execute the install script inside container
|
||||
# 3. description - Display completion info and access details
|
||||
# ============================================================================
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
|
||||
# ============================================================================
|
||||
# COMPLETION MESSAGE
|
||||
# ============================================================================
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:[PORT]${CL}"
|
||||
@@ -1,494 +0,0 @@
|
||||
# Install Scripts - Quick Reference
|
||||
|
||||
> [!WARNING]
|
||||
> **This is legacy documentation.** Refer to the **modern template** at [templates_install/AppName-install.sh](AppName-install.sh) for best practices.
|
||||
>
|
||||
> Current templates use:
|
||||
>
|
||||
> - `tools.func` helpers (setup_nodejs, setup_uv, setup_postgresql_db, etc.)
|
||||
> - Automatic dependency installation via build.func
|
||||
> - Standardized environment variable patterns
|
||||
|
||||
---
|
||||
|
||||
## Before Creating a Script
|
||||
|
||||
1. **Copy the Modern Template:**
|
||||
|
||||
```bash
|
||||
cp templates_install/AppName-install.sh install/MyApp-install.sh
|
||||
# Edit install/MyApp-install.sh
|
||||
```
|
||||
|
||||
2. **Key Pattern:**
|
||||
- CT scripts source build.func and call the install script
|
||||
- Install scripts use sourced FUNCTIONS_FILE_PATH (via build.func)
|
||||
- Both scripts work together in the container
|
||||
|
||||
3. **Test via GitHub:**
|
||||
|
||||
```bash
|
||||
# Push your changes to your fork first
|
||||
git push origin feature/my-awesome-app
|
||||
|
||||
# Test the CT script via curl (it will call the install script)
|
||||
bash -c "$(curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/ProxmoxVE/main/ct/MyApp.sh)"
|
||||
# ⏱️ Wait 10-30 seconds after pushing - GitHub takes time to update
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Template Structure
|
||||
|
||||
### Header
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/install.func)
|
||||
# (setup-fork.sh modifies this URL to point to YOUR fork during development)
|
||||
```
|
||||
|
||||
### Dependencies (App-Specific Only)
|
||||
|
||||
```bash
|
||||
# Don't add: ca-certificates, curl, gnupg, wget, git, jq
|
||||
# These are handled by build.func
|
||||
msg_info "Installing dependencies"
|
||||
$STD apt-get install -y app-specific-deps
|
||||
msg_ok "Installed dependencies"
|
||||
```
|
||||
|
||||
### Runtime Setup
|
||||
|
||||
Use tools.func helpers instead of manual installation:
|
||||
|
||||
```bash
|
||||
# ✅ NEW (use tools.func):
|
||||
NODE_VERSION="20"
|
||||
setup_nodejs
|
||||
# OR
|
||||
PYTHON_VERSION="3.12"
|
||||
setup_uv
|
||||
# OR
|
||||
PG_DB_NAME="myapp_db"
|
||||
PG_DB_USER="myapp"
|
||||
setup_postgresql_db
|
||||
```
|
||||
|
||||
### Service Configuration
|
||||
|
||||
```bash
|
||||
# Create .env file
|
||||
msg_info "Configuring MyApp"
|
||||
cat << EOF > /opt/myapp/.env
|
||||
DEBUG=false
|
||||
PORT=8080
|
||||
DATABASE_URL=postgresql://...
|
||||
EOF
|
||||
msg_ok "Configuration complete"
|
||||
|
||||
# Create systemd service
|
||||
msg_info "Creating systemd service"
|
||||
cat << EOF > /etc/systemd/system/myapp.service
|
||||
[Unit]
|
||||
Description=MyApp
|
||||
[Service]
|
||||
ExecStart=/usr/bin/node /opt/myapp/app.js
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
msg_ok "Service created"
|
||||
```
|
||||
|
||||
### Finalization
|
||||
|
||||
```bash
|
||||
msg_info "Finalizing MyApp installation"
|
||||
systemctl enable --now myapp
|
||||
motd_ssh
|
||||
customize
|
||||
msg_ok "MyApp installation complete"
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### Avoid Manual Version Checking
|
||||
|
||||
❌ OLD (manual):
|
||||
|
||||
```bash
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/app/repo/releases/latest | grep tag_name)
|
||||
wget https://github.com/app/repo/releases/download/$RELEASE/app.tar.gz
|
||||
```
|
||||
|
||||
✅ NEW (use tools.func via CT script's fetch_and_deploy_gh_release):
|
||||
|
||||
```bash
|
||||
# In CT script, not install script:
|
||||
fetch_and_deploy_gh_release "myapp" "app/repo" "app.tar.gz" "latest" "/opt/myapp"
|
||||
```
|
||||
|
||||
### Database Setup
|
||||
|
||||
```bash
|
||||
# Use setup_postgresql_db, setup_mysql_db, etc.
|
||||
PG_DB_NAME="myapp"
|
||||
PG_DB_USER="myapp"
|
||||
setup_postgresql_db
|
||||
```
|
||||
|
||||
### Node.js Setup
|
||||
|
||||
```bash
|
||||
NODE_VERSION="20"
|
||||
setup_nodejs
|
||||
npm install --no-save
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Only add app-specific dependencies**
|
||||
- Don't add: ca-certificates, curl, gnupg, wget, git, jq
|
||||
- These are handled by build.func
|
||||
|
||||
2. **Use tools.func helpers**
|
||||
- setup_nodejs, setup_python, setup_uv, setup_postgresql_db, setup_mysql_db, etc.
|
||||
|
||||
3. **Don't do version checks in install script**
|
||||
- Version checking happens in CT script's update_script()
|
||||
- Install script just installs the latest
|
||||
|
||||
4. **Structure:**
|
||||
- Dependencies
|
||||
- Runtime setup (tools.func)
|
||||
- Deployment (fetch from CT script)
|
||||
- Configuration files
|
||||
- Systemd service
|
||||
- Finalization
|
||||
|
||||
---
|
||||
|
||||
## Reference Scripts
|
||||
|
||||
See working examples:
|
||||
|
||||
- [Trip](https://github.com/community-scripts/ProxmoxVE/blob/main/install/trip-install.sh)
|
||||
- [Thingsboard](https://github.com/community-scripts/ProxmoxVE/blob/main/install/thingsboard-install.sh)
|
||||
- [UniFi](https://github.com/community-scripts/ProxmoxVE/blob/main/install/unifi-install.sh)
|
||||
|
||||
---
|
||||
|
||||
## Need Help?
|
||||
|
||||
- **[Modern Template](AppName-install.sh)** - Start here
|
||||
- **[CT Template](../templates_ct/AppName.sh)** - How CT scripts work
|
||||
- **[README.md](../README.md)** - Full contribution workflow
|
||||
- **[AI.md](../AI.md)** - AI-generated script guidelines
|
||||
|
||||
### 1.2 **Comments**
|
||||
|
||||
- Add clear comments for script metadata, including author, copyright, and license information.
|
||||
- Use meaningful inline comments to explain complex commands or logic.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: [YourUserName]
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: [SOURCE_URL]
|
||||
```
|
||||
|
||||
> [!NOTE]:
|
||||
>
|
||||
> - Add your username
|
||||
> - When updating/reworking scripts, add "| Co-Author [YourUserName]"
|
||||
|
||||
### 1.3 **Variables and function import**
|
||||
|
||||
- This sections adds the support for all needed functions and variables.
|
||||
|
||||
```bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. **Variable naming and management**
|
||||
|
||||
### 2.1 **Naming conventions**
|
||||
|
||||
- Use uppercase names for constants and environment variables.
|
||||
- Use lowercase names for local script variables.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
DB_NAME=snipeit_db # Environment-like variable (constant)
|
||||
db_user="snipeit" # Local variable
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. **Dependencies**
|
||||
|
||||
### 3.1 **Install all at once**
|
||||
|
||||
- Install all dependencies with a single command if possible
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
$STD apt-get install -y \
|
||||
curl \
|
||||
composer \
|
||||
git \
|
||||
sudo \
|
||||
mc \
|
||||
nginx
|
||||
```
|
||||
|
||||
### 3.2 **Collapse dependencies**
|
||||
|
||||
Collapse dependencies to keep the code readable.
|
||||
|
||||
Example:
|
||||
Use
|
||||
|
||||
```bash
|
||||
php8.2-{bcmath,common,ctype}
|
||||
```
|
||||
|
||||
instead of
|
||||
|
||||
```bash
|
||||
php8.2-bcmath php8.2-common php8.2-ctype
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. **Paths to application files**
|
||||
|
||||
If possible install the app and all necessary files in `/opt/`
|
||||
|
||||
---
|
||||
|
||||
## 5. **Version management**
|
||||
|
||||
### 5.1 **Install the latest release**
|
||||
|
||||
- Always try and install the latest release
|
||||
- Do not hardcode any version if not absolutely necessary
|
||||
|
||||
Example for a git release:
|
||||
|
||||
```bash
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/snipe/snipe-it/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
|
||||
curl -fsSL "https://github.com/snipe/snipe-it/archive/refs/tags/v${RELEASE}.zip"
|
||||
```
|
||||
|
||||
### 5.2 **Save the version for update checks**
|
||||
|
||||
- Write the installed version into a file.
|
||||
- This is used for the update function in **AppName.sh** to check for if a Update is needed.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
echo "${RELEASE}" >"/opt/AppName_version.txt"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. **Input and output management**
|
||||
|
||||
### 6.1 **User feedback**
|
||||
|
||||
- Use standard functions like `msg_info`, `msg_ok` or `msg_error` to print status messages.
|
||||
- Each `msg_info` must be followed with a `msg_ok` before any other output is made.
|
||||
- Display meaningful progress messages at key stages.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt-get install -y ...
|
||||
msg_ok "Installed Dependencies"
|
||||
```
|
||||
|
||||
### 6.2 **Verbosity**
|
||||
|
||||
- Use the appropiate flag (**-q** in the examples) for a command to suppres its output
|
||||
Example:
|
||||
|
||||
```bash
|
||||
curl -fsSL
|
||||
unzip -q
|
||||
```
|
||||
|
||||
- If a command dose not come with such a functionality use `$STD` (a custom standard redirection variable) for managing output verbosity.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
$STD apt-get install -y nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. **String/File Manipulation**
|
||||
|
||||
### 7.1 **File Manipulation**
|
||||
|
||||
- Use `sed` to replace placeholder values in configuration files.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
sed -i -e "s|^DB_DATABASE=.*|DB_DATABASE=$DB_NAME|" \
|
||||
-e "s|^DB_USERNAME=.*|DB_USERNAME=$DB_USER|" \
|
||||
-e "s|^DB_PASSWORD=.*|DB_PASSWORD=$DB_PASS|" .env
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. **Security practices**
|
||||
|
||||
### 8.1 **Password generation**
|
||||
|
||||
- Use `openssl` to generate random passwords.
|
||||
- Use only alphanumeric values to not introduce unknown behaviour.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
```
|
||||
|
||||
### 8.2 **File permissions**
|
||||
|
||||
Explicitly set secure ownership and permissions for sensitive files.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
chown -R www-data: /opt/snipe-it
|
||||
chmod -R 755 /opt/snipe-it
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. **Service Configuration**
|
||||
|
||||
### 9.1 **Configuration files**
|
||||
|
||||
Use `cat <<EOF` to write configuration files in a clean and readable way.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
cat <<EOF >/etc/nginx/conf.d/snipeit.conf
|
||||
server {
|
||||
listen 80;
|
||||
root /opt/snipe-it/public;
|
||||
index index.php;
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
### 9.2 **Credential management**
|
||||
|
||||
Store the generated credentials in a file.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
USERNAME=username
|
||||
PASSWORD=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
{
|
||||
echo "Application-Credentials"
|
||||
echo "Username: $USERNAME"
|
||||
echo "Password: $PASSWORD"
|
||||
} >> ~/application.creds
|
||||
```
|
||||
|
||||
### 9.3 **Enviroment files**
|
||||
|
||||
Use `cat <<EOF` to write enviromental files in a clean and readable way.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
cat <<EOF >/path/to/.env
|
||||
VARIABLE="value"
|
||||
PORT=3000
|
||||
DB_NAME="${DB_NAME}"
|
||||
EOF
|
||||
```
|
||||
|
||||
### 9.4 **Services**
|
||||
|
||||
Enable affected services after configuration changes and start them right away.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
systemctl enable -q --now nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. **Cleanup**
|
||||
|
||||
### 10.1 **Remove temporary files**
|
||||
|
||||
Remove temporary files and downloads after use.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
rm -rf /opt/v${RELEASE}.zip
|
||||
```
|
||||
|
||||
### 10.2 **Autoremove and autoclean**
|
||||
|
||||
Remove unused dependencies to reduce disk space usage.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
apt-get -y autoremove
|
||||
apt-get -y autoclean
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. **Best Practices Checklist**
|
||||
|
||||
- [ ] Shebang is correctly set (`#!/usr/bin/env bash`).
|
||||
- [ ] Metadata (author, license) is included at the top.
|
||||
- [ ] Variables follow naming conventions.
|
||||
- [ ] Sensitive values are dynamically generated.
|
||||
- [ ] Files and services have proper permissions.
|
||||
- [ ] Script cleans up temporary files.
|
||||
|
||||
---
|
||||
|
||||
### Example: High-Level Script Flow
|
||||
|
||||
1. Dependencies installation
|
||||
2. Database setup
|
||||
3. Download and configure application
|
||||
4. Service configuration
|
||||
5. Final cleanup
|
||||
@@ -1,207 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: [YourGitHubUsername]
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: [SOURCE_URL e.g. https://github.com/example/app]
|
||||
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
# =============================================================================
|
||||
# DEPENDENCIES - Only add app-specific dependencies here!
|
||||
# Don't add: ca-certificates, curl, gnupg, git, build-essential (handled by build.func)
|
||||
# =============================================================================
|
||||
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt install -y \
|
||||
libharfbuzz0b \
|
||||
fontconfig
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
# =============================================================================
|
||||
# SETUP RUNTIMES & DATABASES (if needed)
|
||||
# =============================================================================
|
||||
# Examples (uncomment as needed):
|
||||
#
|
||||
# NODE_VERSION="22" setup_nodejs
|
||||
# NODE_VERSION="22" NODE_MODULE="pnpm" setup_nodejs # Installs pnpm
|
||||
# PYTHON_VERSION="3.13" setup_uv
|
||||
# JAVA_VERSION="21" setup_java
|
||||
# GO_VERSION="1.22" setup_go
|
||||
# PHP_VERSION="8.4" PHP_FPM="YES" setup_php
|
||||
# setup_postgresql # Server only
|
||||
# setup_mariadb # Server only
|
||||
# setup_meilisearch # Search engine
|
||||
#
|
||||
# Then set up DB and user (sets $[DB]_DB_PASS):
|
||||
# PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db
|
||||
# MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" setup_mariadb_db
|
||||
|
||||
# =============================================================================
|
||||
# DOWNLOAD & DEPLOY APPLICATION
|
||||
# =============================================================================
|
||||
# fetch_and_deploy_gh_release modes:
|
||||
# "tarball" - Source tarball (default if omitted)
|
||||
# "binary" - .deb package (auto-detects amd64/arm64)
|
||||
# "prebuild" - Pre-built archive (.tar.gz)
|
||||
# "singlefile" - Single binary file
|
||||
#
|
||||
# Examples:
|
||||
# fetch_and_deploy_gh_release "myapp" "YourUsername/myapp" "tarball" "latest" "/opt/myapp"
|
||||
# fetch_and_deploy_gh_release "myapp" "YourUsername/myapp" "binary" "latest" "/tmp"
|
||||
# fetch_and_deploy_gh_release "myapp" "YourUsername/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz"
|
||||
|
||||
fetch_and_deploy_gh_release "[appname]" "owner/repo" "tarball" "latest" "/opt/[appname]"
|
||||
|
||||
# --- Tools & Utilities ---
|
||||
# get_lxc_ip # Sets $LOCAL_IP variable (call early!)
|
||||
# setup_ffmpeg # Install FFmpeg with codecs
|
||||
# setup_hwaccel # Setup GPU hardware acceleration
|
||||
# setup_imagemagick # Install ImageMagick 7
|
||||
# setup_docker # Install Docker Engine
|
||||
# setup_adminer # Install Adminer for DB management
|
||||
# create_self_signed_cert # Creates cert in /etc/ssl/[appname]/
|
||||
|
||||
# =============================================================================
|
||||
# EXAMPLES
|
||||
# =============================================================================
|
||||
#
|
||||
# EXAMPLE 1: Node.js Application with PostgreSQL
|
||||
# ---------------------------------------------
|
||||
# NODE_VERSION="22" setup_nodejs
|
||||
# PG_VERSION="17" setup_postgresql
|
||||
# PG_DB_NAME="myapp" PG_DB_USER="myapp" setup_postgresql_db
|
||||
# get_lxc_ip
|
||||
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp"
|
||||
#
|
||||
# msg_info "Configuring MyApp"
|
||||
# cd /opt/myapp
|
||||
# $STD npm ci
|
||||
# cat <<EOF >/opt/myapp/.env
|
||||
# DATABASE_URL=postgresql://${PG_DB_USER}:${PG_DB_PASS}@localhost/${PG_DB_NAME}
|
||||
# HOST=${LOCAL_IP}
|
||||
# PORT=3000
|
||||
# EOF
|
||||
# msg_ok "Configured MyApp"
|
||||
#
|
||||
# EXAMPLE 2: Python Application with uv
|
||||
# ------------------------------------
|
||||
# PYTHON_VERSION="3.13" setup_uv
|
||||
# get_lxc_ip
|
||||
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "tarball" "latest" "/opt/myapp"
|
||||
#
|
||||
# msg_info "Setting up MyApp"
|
||||
# cd /opt/myapp
|
||||
# $STD uv sync
|
||||
# cat <<EOF >/opt/myapp/.env
|
||||
# HOST=${LOCAL_IP}
|
||||
# PORT=8000
|
||||
# EOF
|
||||
# msg_ok "Setup MyApp"
|
||||
|
||||
# =============================================================================
|
||||
# EXAMPLE 3: PHP Application with MariaDB + Nginx
|
||||
# =============================================================================
|
||||
# PHP_VERSION="8.4" PHP_FPM="YES" PHP_MODULE="bcmath,curl,gd,intl,mbstring,mysql,xml,zip" setup_php
|
||||
# setup_composer
|
||||
# setup_mariadb
|
||||
# MARIADB_DB_NAME="myapp" MARIADB_DB_USER="myapp" setup_mariadb_db
|
||||
# get_lxc_ip
|
||||
# fetch_and_deploy_gh_release "myapp" "owner/myapp" "prebuild" "latest" "/opt/myapp" "myapp-*.tar.gz"
|
||||
#
|
||||
# msg_info "Configuring MyApp"
|
||||
# cd /opt/myapp
|
||||
# cp .env.example .env
|
||||
# sed -i "s|APP_URL=.*|APP_URL=http://${LOCAL_IP}|" .env
|
||||
# sed -i "s|DB_DATABASE=.*|DB_DATABASE=${MARIADB_DB_NAME}|" .env
|
||||
# sed -i "s|DB_USERNAME=.*|DB_USERNAME=${MARIADB_DB_USER}|" .env
|
||||
# sed -i "s|DB_PASSWORD=.*|DB_PASSWORD=${MARIADB_DB_PASS}|" .env
|
||||
# $STD composer install --no-dev --no-interaction
|
||||
# chown -R www-data:www-data /opt/myapp
|
||||
# msg_ok "Configured MyApp"
|
||||
|
||||
# =============================================================================
|
||||
# YOUR APPLICATION INSTALLATION
|
||||
# =============================================================================
|
||||
# 1. Setup runtimes and databases FIRST
|
||||
# 2. Call get_lxc_ip if you need the container IP
|
||||
# 3. Use fetch_and_deploy_gh_release to download the app (handles version tracking)
|
||||
# 4. Configure the application
|
||||
# 5. Create systemd service
|
||||
# 6. Finalize with motd_ssh, customize, cleanup_lxc
|
||||
|
||||
# --- Setup runtimes/databases ---
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
get_lxc_ip
|
||||
|
||||
# --- Download and install app ---
|
||||
fetch_and_deploy_gh_release "[appname]" "[owner/repo]" "tarball" "latest" "/opt/[appname]"
|
||||
|
||||
msg_info "Setting up [AppName]"
|
||||
cd /opt/[appname]
|
||||
# $STD npm ci
|
||||
msg_ok "Setup [AppName]"
|
||||
|
||||
# =============================================================================
|
||||
# CONFIGURATION
|
||||
# =============================================================================
|
||||
|
||||
msg_info "Configuring [AppName]"
|
||||
cd /opt/[appname]
|
||||
|
||||
# Install application dependencies (uncomment as needed):
|
||||
# $STD npm ci --production # Node.js apps
|
||||
# $STD uv sync --frozen # Python apps
|
||||
# $STD composer install --no-dev # PHP apps
|
||||
# $STD cargo build --release # Rust apps
|
||||
|
||||
# Create .env file if needed:
|
||||
cat <<EOF >/opt/[appname]/.env
|
||||
# Use import_local_ip to get container IP, or hardcode if building on Proxmox
|
||||
APP_URL=http://localhost
|
||||
PORT=8080
|
||||
EOF
|
||||
|
||||
msg_ok "Configured [AppName]"
|
||||
|
||||
# =============================================================================
|
||||
# CREATE SYSTEMD SERVICE
|
||||
# =============================================================================
|
||||
|
||||
msg_info "Creating Service"
|
||||
cat <<EOF >/etc/systemd/system/[appname].service
|
||||
[Unit]
|
||||
Description=[AppName] Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/[appname]
|
||||
ExecStart=/usr/bin/node /opt/[appname]/server.js
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
systemctl enable -q --now [appname]
|
||||
msg_ok "Created Service"
|
||||
|
||||
# =============================================================================
|
||||
# CLEANUP & FINALIZATION
|
||||
# =============================================================================
|
||||
# These are called automatically, but shown here for clarity:
|
||||
# motd_ssh - Displays service info on SSH login
|
||||
# customize - Enables optional customizations
|
||||
# cleanup_lxc - Removes temp files, bash history, logs
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"name": "AppName",
|
||||
"slug": "appname",
|
||||
"categories": [
|
||||
0
|
||||
],
|
||||
"date_created": "2026-01-18",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 3000,
|
||||
"documentation": "https://docs.example.com/",
|
||||
"website": "https://example.com/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/appname.webp",
|
||||
"config_path": "/opt/appname/.env",
|
||||
"description": "Short description of what AppName does and its main features.",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/appname.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 8,
|
||||
"os": "Debian",
|
||||
"version": "13"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "Change the default password after first login!",
|
||||
"type": "warning"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
# Website Metadata - Quick Reference
|
||||
|
||||
Metadata (name, slug, description, logo, categories, etc.) controls how your application appears on the website. You do **not** add JSON files to the repo — you request changes via the website.
|
||||
|
||||
---
|
||||
|
||||
## How to Request or Update Metadata
|
||||
|
||||
1. **Go to the script on the website** — Open the [ProxmoxVE website](https://community-scripts.github.io/ProxmoxVE/), find your script (or the script you want to update).
|
||||
2. **Press the "Report issue" button** on that script’s page.
|
||||
3. **Follow the guide** — The flow will walk you through submitting or updating metadata.
|
||||
|
||||
---
|
||||
|
||||
## Metadata Structure (Reference)
|
||||
|
||||
The following describes the structure of script metadata used by the website. Use it as reference when filling out the form or describing what you need.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "MyApp",
|
||||
"slug": "myapp",
|
||||
"categories": [1],
|
||||
"date_created": "2026-01-18",
|
||||
"type": "ct",
|
||||
"updateable": true,
|
||||
"privileged": false,
|
||||
"interface_port": 3000,
|
||||
"documentation": "https://docs.example.com/",
|
||||
"website": "https://example.com/",
|
||||
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp/myapp.webp",
|
||||
"config_path": "/opt/myapp/.env",
|
||||
"description": "Brief description of what MyApp does",
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/myapp.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 8,
|
||||
"os": "Debian",
|
||||
"version": "13"
|
||||
}
|
||||
}
|
||||
],
|
||||
"default_credentials": {
|
||||
"username": null,
|
||||
"password": null
|
||||
},
|
||||
"notes": [
|
||||
{
|
||||
"text": "Change the default password after first login!",
|
||||
"type": "warning"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Field Reference
|
||||
|
||||
| Field | Required | Example | Notes |
|
||||
| --------------------- | -------- | ----------------- | ---------------------------------------------- |
|
||||
| `name` | Yes | "MyApp" | Display name |
|
||||
| `slug` | Yes | "myapp" | URL-friendly identifier (lowercase, no spaces) |
|
||||
| `categories` | Yes | [1] | One or more category IDs |
|
||||
| `date_created` | Yes | "2026-01-18" | Format: YYYY-MM-DD |
|
||||
| `type` | Yes | "ct" | Container type: "ct" or "vm" |
|
||||
| `interface_port` | Yes | 3000 | Default web interface port |
|
||||
| `logo` | No | "https://..." | Logo URL (64px x 64px PNG) |
|
||||
| `config_path` | Yes | "/opt/myapp/.env" | Main config file location |
|
||||
| `description` | Yes | "App description" | Brief description (100 chars) |
|
||||
| `install_methods` | Yes | See below | Installation resources (array) |
|
||||
| `default_credentials` | No | See below | Optional default login |
|
||||
| `notes` | No | See below | Additional notes (array) |
|
||||
|
||||
---
|
||||
|
||||
## Install Methods
|
||||
|
||||
Each installation method specifies resource requirements:
|
||||
|
||||
```json
|
||||
"install_methods": [
|
||||
{
|
||||
"type": "default",
|
||||
"script": "ct/myapp.sh",
|
||||
"resources": {
|
||||
"cpu": 2,
|
||||
"ram": 2048,
|
||||
"hdd": 8,
|
||||
"os": "Debian",
|
||||
"version": "13"
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
**Resource Defaults:**
|
||||
|
||||
- CPU: Cores (1-8)
|
||||
- RAM: Megabytes (256-4096)
|
||||
- Disk: Gigabytes (4-50)
|
||||
|
||||
---
|
||||
|
||||
## Common Categories
|
||||
|
||||
- `0` Miscellaneous
|
||||
- `1` Proxmox & Virtualization
|
||||
- `2` Operating Systems
|
||||
- `3` Containers & Docker
|
||||
- `4` Network & Firewall
|
||||
- `5` Adblock & DNS
|
||||
- `6` Authentication & Security
|
||||
- `7` Backup & Recovery
|
||||
- `8` Databases
|
||||
- `9` Monitoring & Analytics
|
||||
- `10` Dashboards & Frontends
|
||||
- `11` Files & Downloads
|
||||
- `12` Documents & Notes
|
||||
- `13` Media & Streaming
|
||||
- `14` \*Arr Suite
|
||||
- `15` NVR & Cameras
|
||||
- `16` IoT & Smart Home
|
||||
- `17` ZigBee, Z-Wave & Matter
|
||||
- `18` MQTT & Messaging
|
||||
- `19` Automation & Scheduling
|
||||
- `20` AI / Coding & Dev-Tools
|
||||
- `21` Webservers & Proxies
|
||||
- `22` Bots & ChatOps
|
||||
- `23` Finance & Budgeting
|
||||
- `24` Gaming & Leisure
|
||||
- `25` Business & ERP
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use the JSON Generator** - It validates structure
|
||||
2. **Keep descriptions short** - 100 characters max
|
||||
3. **Use real resource requirements** - Based on your testing
|
||||
4. **Include sensible defaults** - Pre-filled in install_methods
|
||||
5. **Slug must be lowercase** - No spaces, use hyphens
|
||||
|
||||
---
|
||||
|
||||
## See Examples on the Website
|
||||
|
||||
View script pages on the [ProxmoxVE website](https://community-scripts.github.io/ProxmoxVE/) to see how metadata is displayed for existing scripts.
|
||||
|
||||
---
|
||||
|
||||
## Need Help?
|
||||
|
||||
- **Request metadata** — Use the Report issue button on the script’s page on the website (see [How to Request or Update Metadata](#how-to-request-or-update-metadata) above).
|
||||
- **[JSON Generator](https://community-scripts.github.io/ProxmoxVE/json-editor)** - Reference only; structure validation
|
||||
- **[README.md](../README.md)** - Full contribution workflow
|
||||
@@ -1,472 +0,0 @@
|
||||
# 🚀 **Application Container Scripts (ct/AppName.sh)**
|
||||
|
||||
**Modern Guide to Creating LXC Container Installation Scripts**
|
||||
|
||||
> **Updated**: December 2025
|
||||
> **Context**: Fully integrated with build.func, advanced_settings wizard, and defaults system
|
||||
> **Example Used**: `/ct/pihole.sh`, `/ct/docker.sh`
|
||||
|
||||
---
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Architecture & Flow](#architecture--flow)
|
||||
- [File Structure](#file-structure)
|
||||
- [Complete Script Template](#complete-script-template)
|
||||
- [Function Reference](#function-reference)
|
||||
- [Advanced Features](#advanced-features)
|
||||
- [Real Examples](#real-examples)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Contribution Checklist](#contribution-checklist)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
### Purpose
|
||||
|
||||
Container scripts (`ct/AppName.sh`) are **entry points for creating LXC containers** with specific applications pre-installed. They:
|
||||
|
||||
1. Define container defaults (CPU, RAM, disk, OS)
|
||||
2. Call the main build orchestrator (`build.func`)
|
||||
3. Implement application-specific update mechanisms
|
||||
4. Provide user-facing success messages
|
||||
|
||||
### Execution Context
|
||||
|
||||
```
|
||||
Proxmox Host
|
||||
↓
|
||||
ct/AppName.sh sourced (runs as root on host)
|
||||
↓
|
||||
build.func: Creates LXC container + runs install script inside
|
||||
↓
|
||||
install/AppName-install.sh (runs inside container)
|
||||
↓
|
||||
Container ready with app installed
|
||||
```
|
||||
|
||||
### Key Integration Points
|
||||
|
||||
- **build.func** - Main orchestrator (container creation, storage, variable management)
|
||||
- **install.func** - Container-specific setup (OS update, package management)
|
||||
- **tools.func** - Tool installation helpers (repositories, GitHub releases)
|
||||
- **core.func** - UI/messaging functions (colors, spinners, validation)
|
||||
- **error_handler.func** - Error handling and signal management
|
||||
|
||||
---
|
||||
|
||||
## Architecture & Flow
|
||||
|
||||
### Container Creation Flow
|
||||
|
||||
```
|
||||
START: bash ct/pihole.sh
|
||||
↓
|
||||
[1] Set APP, var_*, defaults
|
||||
↓
|
||||
[2] header_info() → Display ASCII art
|
||||
↓
|
||||
[3] variables() → Parse arguments & load build.func
|
||||
↓
|
||||
[4] color() → Setup ANSI codes
|
||||
↓
|
||||
[5] catch_errors() → Setup trap handlers
|
||||
↓
|
||||
[6] install_script() → Show mode menu (5 options)
|
||||
↓
|
||||
├─ INSTALL_MODE="0" (Default)
|
||||
├─ INSTALL_MODE="1" (Advanced - 19-step wizard)
|
||||
├─ INSTALL_MODE="2" (User Defaults)
|
||||
├─ INSTALL_MODE="3" (App Defaults)
|
||||
└─ INSTALL_MODE="4" (Settings Menu)
|
||||
↓
|
||||
[7] advanced_settings() → Collect user configuration (if mode=1)
|
||||
↓
|
||||
[8] start() → Confirm or re-edit settings
|
||||
↓
|
||||
[9] build_container() → Create LXC + execute install script
|
||||
↓
|
||||
[10] description() → Set container description
|
||||
↓
|
||||
[11] SUCCESS → Display access URL
|
||||
↓
|
||||
END
|
||||
```
|
||||
|
||||
### Default Values Precedence
|
||||
|
||||
```
|
||||
Priority 1 (Highest): Environment Variables (var_cpu, var_ram, etc.)
|
||||
Priority 2: App-Specific Defaults (/defaults/AppName.vars)
|
||||
Priority 3: User Global Defaults (/default.vars)
|
||||
Priority 4 (Lowest): Built-in Defaults (in build.func)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
### Minimal ct/AppName.sh Template
|
||||
|
||||
```
|
||||
#!/usr/bin/env bash # [1] Shebang
|
||||
# [2] Copyright/License
|
||||
source <(curl -s .../misc/build.func) # [3] Import functions
|
||||
# [4] APP metadata
|
||||
APP="AppName" # [5] Default values
|
||||
var_tags="tag1;tag2"
|
||||
var_cpu="2"
|
||||
var_ram="2048"
|
||||
...
|
||||
|
||||
header_info "$APP" # [6] Display header
|
||||
variables # [7] Process arguments
|
||||
color # [8] Setup colors
|
||||
catch_errors # [9] Setup error handling
|
||||
|
||||
function update_script() { ... } # [10] Update function (optional)
|
||||
|
||||
start # [11] Launch container creation
|
||||
build_container
|
||||
description
|
||||
msg_ok "Completed successfully!\n"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Script Template
|
||||
|
||||
### 1. File Header & Imports
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: YourUsername
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/example/project
|
||||
|
||||
# Import main orchestrator
|
||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/build.func)
|
||||
```
|
||||
|
||||
> **⚠️ IMPORTANT**: Before opening a PR, change URL to `community-scripts` repo!
|
||||
|
||||
### 2. Application Metadata
|
||||
|
||||
```bash
|
||||
# Application Configuration
|
||||
APP="ApplicationName"
|
||||
var_tags="tag1;tag2;tag3" # Max 3-4 tags, no spaces, semicolon-separated
|
||||
|
||||
# Container Resources
|
||||
var_cpu="2" # CPU cores
|
||||
var_ram="2048" # RAM in MB
|
||||
var_disk="10" # Disk in GB
|
||||
|
||||
# Container Type & OS
|
||||
var_os="debian" # Options: alpine, debian, ubuntu
|
||||
var_version="12" # Alpine: 3.20+, Debian: 11-13, Ubuntu: 20.04+
|
||||
var_unprivileged="1" # 1=unprivileged (secure), 0=privileged (rarely needed)
|
||||
```
|
||||
|
||||
**Variable Naming Convention**:
|
||||
- Variables exposed to user: `var_*` (e.g., `var_cpu`, `var_hostname`, `var_ssh`)
|
||||
- Internal variables: lowercase (e.g., `container_id`, `app_version`)
|
||||
|
||||
### 3. Display & Initialization
|
||||
|
||||
```bash
|
||||
# Display header ASCII art
|
||||
header_info "$APP"
|
||||
|
||||
# Process command-line arguments and load configuration
|
||||
variables
|
||||
|
||||
# Setup ANSI color codes and formatting
|
||||
color
|
||||
|
||||
# Initialize error handling (trap ERR, EXIT, INT, TERM)
|
||||
catch_errors
|
||||
```
|
||||
|
||||
### 4. Update Function (Highly Recommended)
|
||||
|
||||
```bash
|
||||
function update_script() {
|
||||
header_info
|
||||
|
||||
# Always start with these checks
|
||||
check_container_storage
|
||||
check_container_resources
|
||||
|
||||
# Verify app is installed
|
||||
if [[ ! -d /opt/appname ]]; then
|
||||
msg_error "No ${APP} Installation Found!"
|
||||
exit
|
||||
fi
|
||||
|
||||
# Get latest version from GitHub
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \
|
||||
grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
|
||||
|
||||
# Compare with saved version
|
||||
if [[ ! -f /opt/${APP}_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/${APP}_version.txt)" ]]; then
|
||||
msg_info "Updating ${APP} to v${RELEASE}"
|
||||
|
||||
# Backup user data
|
||||
cp -r /opt/appname /opt/appname-backup
|
||||
|
||||
# Perform update
|
||||
cd /opt
|
||||
wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app-${RELEASE}.tar.gz"
|
||||
tar -xzf app-${RELEASE}.tar.gz
|
||||
|
||||
# Restore user data
|
||||
cp /opt/appname-backup/config/* /opt/appname/config/
|
||||
|
||||
# Cleanup
|
||||
rm -rf app-${RELEASE}.tar.gz /opt/appname-backup
|
||||
|
||||
# Save new version
|
||||
echo "${RELEASE}" > /opt/${APP}_version.txt
|
||||
|
||||
msg_ok "Updated ${APP} to v${RELEASE}"
|
||||
else
|
||||
msg_ok "No update required. ${APP} is already at v${RELEASE}."
|
||||
fi
|
||||
|
||||
exit
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Script Launch
|
||||
|
||||
```bash
|
||||
# Start the container creation workflow
|
||||
start
|
||||
|
||||
# Build the container with selected configuration
|
||||
build_container
|
||||
|
||||
# Set container description/notes in Proxmox UI
|
||||
description
|
||||
|
||||
# Display success message
|
||||
msg_ok "Completed successfully!\n"
|
||||
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
|
||||
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
|
||||
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8080${CL}"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Function Reference
|
||||
|
||||
### Core Functions (From build.func)
|
||||
|
||||
#### `variables()`
|
||||
|
||||
**Purpose**: Initialize container variables, load user arguments, setup orchestration
|
||||
|
||||
**Triggered by**: Called automatically at script start
|
||||
|
||||
**Behavior**:
|
||||
1. Parse command-line arguments (if any)
|
||||
2. Generate random UUID for session tracking
|
||||
3. Load container storage from Proxmox
|
||||
4. Initialize application-specific defaults
|
||||
5. Setup SSH/environment configuration
|
||||
|
||||
#### `start()`
|
||||
|
||||
**Purpose**: Launch the container creation menu with 5 installation modes
|
||||
|
||||
**Menu Options**:
|
||||
```
|
||||
1. Default Installation (Quick setup, predefined settings)
|
||||
2. Advanced Installation (19-step wizard with full control)
|
||||
3. User Defaults (Load ~/.community-scripts/default.vars)
|
||||
4. App Defaults (Load /defaults/AppName.vars)
|
||||
5. Settings Menu (Interactive mode selection)
|
||||
```
|
||||
|
||||
#### `build_container()`
|
||||
|
||||
**Purpose**: Main orchestrator for LXC container creation
|
||||
|
||||
**Operations**:
|
||||
1. Validates all variables
|
||||
2. Creates LXC container via `pct create`
|
||||
3. Executes `install/AppName-install.sh` inside container
|
||||
4. Monitors installation progress
|
||||
5. Handles errors and rollback on failure
|
||||
|
||||
#### `description()`
|
||||
|
||||
**Purpose**: Set container description/notes visible in Proxmox UI
|
||||
|
||||
---
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### 1. Custom Configuration Menus
|
||||
|
||||
If your app has additional setup beyond standard vars:
|
||||
|
||||
```bash
|
||||
custom_app_settings() {
|
||||
CONFIGURE_DB=$(whiptail --title "Database Setup" \
|
||||
--yesno "Would you like to configure a custom database?" 8 60)
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
DB_HOST=$(whiptail --inputbox "Database Host:" 8 60 3>&1 1>&2 2>&3)
|
||||
DB_PORT=$(whiptail --inputbox "Database Port:" 8 60 "3306" 3>&1 1>&2 2>&3)
|
||||
fi
|
||||
}
|
||||
|
||||
custom_app_settings
|
||||
```
|
||||
|
||||
### 2. Update Function Patterns
|
||||
|
||||
Save installed version for update checks
|
||||
|
||||
### 3. Health Check Functions
|
||||
|
||||
Add custom validation:
|
||||
|
||||
```bash
|
||||
function health_check() {
|
||||
header_info
|
||||
|
||||
if [[ ! -d /opt/appname ]]; then
|
||||
msg_error "Application not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! systemctl is-active --quiet appname; then
|
||||
msg_error "Application service not running"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
msg_ok "Health check passed"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Real Examples
|
||||
|
||||
### Example 1: Simple Web App (Debian-based)
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source <(curl -fsSL https://git.community-scripts.org/community-scripts/ProxmoxVE/raw/branch/main/misc/build.func)
|
||||
|
||||
APP="Homarr"
|
||||
var_tags="dashboard;homepage"
|
||||
var_cpu="2"
|
||||
var_ram="1024"
|
||||
var_disk="5"
|
||||
var_os="debian"
|
||||
var_version="12"
|
||||
var_unprivileged="1"
|
||||
|
||||
header_info "$APP"
|
||||
variables
|
||||
color
|
||||
catch_errors
|
||||
|
||||
function update_script() {
|
||||
# Update logic here
|
||||
}
|
||||
|
||||
start
|
||||
build_container
|
||||
description
|
||||
msg_ok "Completed successfully!\n"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Container Creation Fails
|
||||
|
||||
**Symptom**: `pct create` exits with error code 209
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Check existing containers
|
||||
pct list | grep CTID
|
||||
|
||||
# Remove conflicting container
|
||||
pct destroy CTID
|
||||
|
||||
# Retry ct/AppName.sh
|
||||
```
|
||||
|
||||
### Update Function Doesn't Detect New Version
|
||||
|
||||
**Debug**:
|
||||
```bash
|
||||
# Check version file
|
||||
cat /opt/AppName_version.txt
|
||||
|
||||
# Test GitHub API
|
||||
curl -fsSL https://api.github.com/repos/user/repo/releases/latest | grep tag_name
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contribution Checklist
|
||||
|
||||
Before submitting a PR:
|
||||
|
||||
### Script Structure
|
||||
- [ ] Shebang is `#!/usr/bin/env bash`
|
||||
- [ ] Imports `build.func` from community-scripts repo
|
||||
- [ ] Copyright header with author and source URL
|
||||
- [ ] APP variable matches filename
|
||||
- [ ] `var_tags` are semicolon-separated (no spaces)
|
||||
|
||||
### Default Values
|
||||
- [ ] `var_cpu` set appropriately (2-4 for most apps)
|
||||
- [ ] `var_ram` set appropriately (1024-4096 MB minimum)
|
||||
- [ ] `var_disk` sufficient for app + data (5-20 GB)
|
||||
- [ ] `var_os` is realistic
|
||||
|
||||
### Functions
|
||||
- [ ] `update_script()` implemented
|
||||
- [ ] Update function checks if app installed
|
||||
- [ ] Proper error handling with `msg_error`
|
||||
|
||||
### Testing
|
||||
- [ ] Script tested with default installation
|
||||
- [ ] Script tested with advanced (19-step) installation
|
||||
- [ ] Update function tested on existing installation
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO:
|
||||
|
||||
1. **Use meaningful defaults**
|
||||
2. **Implement version tracking**
|
||||
3. **Handle edge cases**
|
||||
4. **Use proper messaging with msg_info/msg_ok/msg_error**
|
||||
|
||||
### ❌ DON'T:
|
||||
|
||||
1. **Hardcode versions**
|
||||
2. **Use custom color codes** (use built-in variables)
|
||||
3. **Forget error handling**
|
||||
4. **Leave temporary files**
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
**Compatibility**: ProxmoxVE with build.func v3+
|
||||
@@ -1,72 +0,0 @@
|
||||
# Container Scripts Documentation (/ct)
|
||||
|
||||
This directory contains comprehensive documentation for container creation scripts in the `/ct` directory.
|
||||
|
||||
## Overview
|
||||
|
||||
Container scripts (`ct/*.sh`) are the entry points for creating LXC containers in Proxmox VE. They run on the host and orchestrate the entire container creation process.
|
||||
|
||||
## Documentation Structure
|
||||
|
||||
Each script has standardized documentation following the project pattern.
|
||||
|
||||
## Key Resources
|
||||
|
||||
- **[DETAILED_GUIDE.md](DETAILED_GUIDE.md)** - Complete reference for creating ct scripts
|
||||
- **[../contribution/README.md](../contribution/README.md)** - How to contribute
|
||||
- **[../misc/build.func/](../misc/build.func/)** - Core orchestrator documentation
|
||||
|
||||
## Container Creation Flow
|
||||
|
||||
```
|
||||
ct/AppName.sh (host-side)
|
||||
│
|
||||
├─ Calls: build.func (orchestrator)
|
||||
│
|
||||
├─ Variables: var_cpu, var_ram, var_disk, var_os
|
||||
│
|
||||
└─ Creates: LXC Container
|
||||
│
|
||||
└─ Runs: install/appname-install.sh (inside)
|
||||
```
|
||||
|
||||
## Available Scripts
|
||||
|
||||
See `/ct` directory for all container creation scripts. Common examples:
|
||||
|
||||
- `pihole.sh` - Pi-hole DNS/DHCP server
|
||||
- `docker.sh` - Docker container runtime
|
||||
- `wallabag.sh` - Article reading & archiving
|
||||
- `nextcloud.sh` - Private cloud storage
|
||||
- `debian.sh` - Basic Debian container
|
||||
- And 30+ more...
|
||||
|
||||
## Quick Start
|
||||
|
||||
To understand how to create a container script:
|
||||
|
||||
1. Read: [UPDATED_APP-ct.md](../UPDATED_APP-ct.md)
|
||||
2. Study: A similar existing script in `/ct`
|
||||
3. Copy template and customize
|
||||
4. Test locally
|
||||
5. Submit PR
|
||||
|
||||
## Contributing a New Container
|
||||
|
||||
1. Create `ct/myapp.sh`
|
||||
2. Create `install/myapp-install.sh`
|
||||
3. Follow template in [UPDATED_APP-ct.md](../UPDATED_APP-ct.md)
|
||||
4. Test thoroughly
|
||||
5. Submit PR with both files
|
||||
|
||||
## Common Tasks
|
||||
|
||||
- **Add new container application** → [contribution/README.md](../contribution/README.md)
|
||||
- **Debug container creation** → [EXIT_CODES.md](../EXIT_CODES.md)
|
||||
- **Understand build.func** → [misc/build.func/](../misc/build.func/)
|
||||
- **Development mode debugging** → [DEV_MODE.md](../DEV_MODE.md)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
**Maintainers**: community-scripts team
|
||||
@@ -1,904 +0,0 @@
|
||||
# Configuration Reference
|
||||
|
||||
**Complete reference for all configuration variables and options in community-scripts for Proxmox VE.**
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Variable Naming Convention](#variable-naming-convention)
|
||||
2. [Complete Variable Reference](#complete-variable-reference)
|
||||
3. [Resource Configuration](#resource-configuration)
|
||||
4. [Network Configuration](#network-configuration)
|
||||
5. [IPv6 Configuration](#ipv6-configuration)
|
||||
6. [SSH Configuration](#ssh-configuration)
|
||||
7. [Container Features](#container-features)
|
||||
8. [Storage Configuration](#storage-configuration)
|
||||
9. [Security Settings](#security-settings)
|
||||
10. [Advanced Options](#advanced-options)
|
||||
11. [Quick Reference Table](#quick-reference-table)
|
||||
|
||||
---
|
||||
|
||||
## Variable Naming Convention
|
||||
|
||||
All configuration variables follow a consistent pattern:
|
||||
|
||||
```
|
||||
var_<setting>=<value>
|
||||
```
|
||||
|
||||
**Rules:**
|
||||
- ✅ Always starts with `var_`
|
||||
- ✅ Lowercase letters only
|
||||
- ✅ Underscores for word separation
|
||||
- ✅ No spaces around `=`
|
||||
- ✅ Values can be quoted if needed
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# ✓ Correct
|
||||
var_cpu=4
|
||||
var_hostname=myserver
|
||||
var_ssh_authorized_key=ssh-rsa AAAA...
|
||||
|
||||
# ✗ Wrong
|
||||
CPU=4 # Missing var_ prefix
|
||||
var_CPU=4 # Uppercase not allowed
|
||||
var_cpu = 4 # Spaces around =
|
||||
var-cpu=4 # Hyphens not allowed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Variable Reference
|
||||
|
||||
### var_unprivileged
|
||||
|
||||
**Type:** Boolean (0 or 1)
|
||||
**Default:** `1` (unprivileged)
|
||||
**Description:** Determines if container runs unprivileged (recommended) or privileged.
|
||||
|
||||
```bash
|
||||
var_unprivileged=1 # Unprivileged (safer, recommended)
|
||||
var_unprivileged=0 # Privileged (less secure, more features)
|
||||
```
|
||||
|
||||
**When to use privileged (0):**
|
||||
- Hardware access required
|
||||
- Certain kernel modules needed
|
||||
- Legacy applications
|
||||
- Nested virtualization with full features
|
||||
|
||||
**Security Impact:**
|
||||
- Unprivileged: Container root is mapped to unprivileged user on host
|
||||
- Privileged: Container root = host root (security risk)
|
||||
|
||||
---
|
||||
|
||||
### var_cpu
|
||||
|
||||
**Type:** Integer
|
||||
**Default:** Varies by app (usually 1-4)
|
||||
**Range:** 1 to host CPU count
|
||||
**Description:** Number of CPU cores allocated to container.
|
||||
|
||||
```bash
|
||||
var_cpu=1 # Single core (minimal)
|
||||
var_cpu=2 # Dual core (typical)
|
||||
var_cpu=4 # Quad core (recommended for apps)
|
||||
var_cpu=8 # High performance
|
||||
```
|
||||
|
||||
**Best Practices:**
|
||||
- Start with 2 cores for most applications
|
||||
- Monitor usage with `pct exec <id> -- htop`
|
||||
- Can be changed after creation
|
||||
- Consider host CPU count (don't over-allocate)
|
||||
|
||||
---
|
||||
|
||||
### var_ram
|
||||
|
||||
**Type:** Integer (MB)
|
||||
**Default:** Varies by app (usually 512-2048)
|
||||
**Range:** 512 MB to host RAM
|
||||
**Description:** Amount of RAM in megabytes.
|
||||
|
||||
```bash
|
||||
var_ram=512 # 512 MB (minimal)
|
||||
var_ram=1024 # 1 GB (typical)
|
||||
var_ram=2048 # 2 GB (comfortable)
|
||||
var_ram=4096 # 4 GB (recommended for databases)
|
||||
var_ram=8192 # 8 GB (high memory apps)
|
||||
```
|
||||
|
||||
**Conversion Guide:**
|
||||
```
|
||||
512 MB = 0.5 GB
|
||||
1024 MB = 1 GB
|
||||
2048 MB = 2 GB
|
||||
4096 MB = 4 GB
|
||||
8192 MB = 8 GB
|
||||
16384 MB = 16 GB
|
||||
```
|
||||
|
||||
**Best Practices:**
|
||||
- Minimum 512 MB for basic Linux
|
||||
- 1 GB for typical applications
|
||||
- 2-4 GB for web servers, databases
|
||||
- Monitor with `free -h` inside container
|
||||
|
||||
---
|
||||
|
||||
### var_disk
|
||||
|
||||
**Type:** Integer (GB)
|
||||
**Default:** Varies by app (usually 2-8)
|
||||
**Range:** 0.001 GB to storage capacity
|
||||
**Description:** Root disk size in gigabytes.
|
||||
|
||||
```bash
|
||||
var_disk=2 # 2 GB (minimal OS only)
|
||||
var_disk=4 # 4 GB (typical)
|
||||
var_disk=8 # 8 GB (comfortable)
|
||||
var_disk=20 # 20 GB (recommended for apps)
|
||||
var_disk=50 # 50 GB (large applications)
|
||||
var_disk=100 # 100 GB (databases, media)
|
||||
```
|
||||
|
||||
**Important Notes:**
|
||||
- Can be expanded after creation (not reduced)
|
||||
- Actual space depends on storage type
|
||||
- Thin provisioning supported on most storage
|
||||
- Plan for logs, data, updates
|
||||
|
||||
**Recommended Sizes by Use Case:**
|
||||
```
|
||||
Basic Linux container: 4 GB
|
||||
Web server (Nginx/Apache): 8 GB
|
||||
Application server: 10-20 GB
|
||||
Database server: 20-50 GB
|
||||
Docker host: 30-100 GB
|
||||
Media server: 100+ GB
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### var_hostname
|
||||
|
||||
**Type:** String
|
||||
**Default:** Application name
|
||||
**Max Length:** 63 characters
|
||||
**Description:** Container hostname (FQDN format allowed).
|
||||
|
||||
```bash
|
||||
var_hostname=myserver
|
||||
var_hostname=pihole
|
||||
var_hostname=docker-01
|
||||
var_hostname=web.example.com
|
||||
```
|
||||
|
||||
**Rules:**
|
||||
- Lowercase letters, numbers, hyphens
|
||||
- Cannot start or end with hyphen
|
||||
- No underscores allowed
|
||||
- No spaces
|
||||
|
||||
**Best Practices:**
|
||||
```bash
|
||||
# ✓ Good
|
||||
var_hostname=web-server
|
||||
var_hostname=db-primary
|
||||
var_hostname=app.domain.com
|
||||
|
||||
# ✗ Avoid
|
||||
var_hostname=Web_Server # Uppercase, underscore
|
||||
var_hostname=-server # Starts with hyphen
|
||||
var_hostname=my server # Contains space
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### var_brg
|
||||
|
||||
**Type:** String
|
||||
**Default:** `vmbr0`
|
||||
**Description:** Network bridge interface.
|
||||
|
||||
```bash
|
||||
var_brg=vmbr0 # Default Proxmox bridge
|
||||
var_brg=vmbr1 # Custom bridge
|
||||
var_brg=vmbr2 # Isolated network
|
||||
```
|
||||
|
||||
**Common Setups:**
|
||||
```
|
||||
vmbr0 → Main network (LAN)
|
||||
vmbr1 → Guest network
|
||||
vmbr2 → DMZ
|
||||
vmbr3 → Management
|
||||
vmbr4 → Storage network
|
||||
```
|
||||
|
||||
**Check available bridges:**
|
||||
```bash
|
||||
ip link show | grep vmbr
|
||||
# or
|
||||
brctl show
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### var_net
|
||||
|
||||
**Type:** String
|
||||
**Options:** `dhcp` or `static`
|
||||
**Default:** `dhcp`
|
||||
**Description:** IPv4 network configuration method.
|
||||
|
||||
```bash
|
||||
var_net=dhcp # Automatic IP via DHCP
|
||||
var_net=static # Manual IP configuration
|
||||
```
|
||||
|
||||
**DHCP Mode:**
|
||||
- Automatic IP assignment
|
||||
- Easy setup
|
||||
- Good for development
|
||||
- Requires DHCP server on network
|
||||
|
||||
**Static Mode:**
|
||||
- Fixed IP address
|
||||
- Requires gateway configuration
|
||||
- Better for servers
|
||||
- Configure via advanced settings or after creation
|
||||
|
||||
---
|
||||
|
||||
### var_gateway
|
||||
|
||||
**Type:** IPv4 Address
|
||||
**Default:** Auto-detected from host
|
||||
**Description:** Network gateway IP address.
|
||||
|
||||
```bash
|
||||
var_gateway=192.168.1.1
|
||||
var_gateway=10.0.0.1
|
||||
var_gateway=172.16.0.1
|
||||
```
|
||||
|
||||
**Auto-detection:**
|
||||
If not specified, system detects gateway from host:
|
||||
```bash
|
||||
ip route | grep default
|
||||
```
|
||||
|
||||
**When to specify:**
|
||||
- Multiple gateways available
|
||||
- Custom routing setup
|
||||
- Different network segment
|
||||
|
||||
---
|
||||
|
||||
### var_vlan
|
||||
|
||||
**Type:** Integer
|
||||
**Range:** 1-4094
|
||||
**Default:** None
|
||||
**Description:** VLAN tag for network isolation.
|
||||
|
||||
```bash
|
||||
var_vlan=10 # VLAN 10
|
||||
var_vlan=100 # VLAN 100
|
||||
var_vlan=200 # VLAN 200
|
||||
```
|
||||
|
||||
**Common VLAN Schemes:**
|
||||
```
|
||||
VLAN 10 → Management
|
||||
VLAN 20 → Servers
|
||||
VLAN 30 → Desktops
|
||||
VLAN 40 → Guest WiFi
|
||||
VLAN 50 → IoT devices
|
||||
VLAN 99 → DMZ
|
||||
```
|
||||
|
||||
**Requirements:**
|
||||
- Switch must support VLANs
|
||||
- Proxmox bridge configured for VLAN aware
|
||||
- Gateway on same VLAN
|
||||
|
||||
---
|
||||
|
||||
### var_mtu
|
||||
|
||||
**Type:** Integer
|
||||
**Default:** `1500`
|
||||
**Range:** 68-9000
|
||||
**Description:** Maximum Transmission Unit size.
|
||||
|
||||
```bash
|
||||
var_mtu=1500 # Standard Ethernet
|
||||
var_mtu=1492 # PPPoE
|
||||
var_mtu=9000 # Jumbo frames
|
||||
```
|
||||
|
||||
**Common Values:**
|
||||
```
|
||||
1500 → Standard Ethernet (default)
|
||||
1492 → PPPoE connections
|
||||
1400 → Some VPN setups
|
||||
9000 → Jumbo frames (10GbE networks)
|
||||
```
|
||||
|
||||
**When to change:**
|
||||
- Jumbo frames for performance on 10GbE
|
||||
- PPPoE internet connections
|
||||
- VPN tunnels with overhead
|
||||
- Specific network requirements
|
||||
|
||||
---
|
||||
|
||||
### var_mac
|
||||
|
||||
**Type:** MAC Address
|
||||
**Format:** `XX:XX:XX:XX:XX:XX`
|
||||
**Default:** Auto-generated
|
||||
**Description:** Container MAC address.
|
||||
|
||||
```bash
|
||||
var_mac=02:00:00:00:00:01
|
||||
var_mac=DE:AD:BE:EF:00:01
|
||||
```
|
||||
|
||||
**When to specify:**
|
||||
- MAC-based licensing
|
||||
- Static DHCP reservations
|
||||
- Network access control
|
||||
- Cloning configurations
|
||||
|
||||
**Best Practices:**
|
||||
- Use locally administered addresses (2nd bit set)
|
||||
- Start with `02:`, `06:`, `0A:`, `0E:`
|
||||
- Avoid vendor OUIs
|
||||
- Document custom MACs
|
||||
|
||||
---
|
||||
|
||||
### var_ipv6_method
|
||||
|
||||
**Type:** String
|
||||
**Options:** `auto`, `dhcp`, `static`, `none`, `disable`
|
||||
**Default:** `none`
|
||||
**Description:** IPv6 configuration method.
|
||||
|
||||
```bash
|
||||
var_ipv6_method=auto # SLAAC (auto-configuration)
|
||||
var_ipv6_method=dhcp # DHCPv6
|
||||
var_ipv6_method=static # Manual configuration
|
||||
var_ipv6_method=none # IPv6 enabled but not configured
|
||||
var_ipv6_method=disable # IPv6 completely disabled
|
||||
```
|
||||
|
||||
**Detailed Options:**
|
||||
|
||||
**auto (SLAAC)**
|
||||
- Stateless Address Auto-Configuration
|
||||
- Router advertisements
|
||||
- No DHCPv6 server needed
|
||||
- Recommended for most cases
|
||||
|
||||
**dhcp (DHCPv6)**
|
||||
- Stateful configuration
|
||||
- Requires DHCPv6 server
|
||||
- More control over addressing
|
||||
|
||||
**static**
|
||||
- Manual IPv6 address
|
||||
- Manual gateway
|
||||
- Full control
|
||||
|
||||
**none**
|
||||
- IPv6 stack active
|
||||
- No address configured
|
||||
- Can configure later
|
||||
|
||||
**disable**
|
||||
- IPv6 completely disabled at kernel level
|
||||
- Use when IPv6 causes issues
|
||||
- Sets `net.ipv6.conf.all.disable_ipv6=1`
|
||||
|
||||
---
|
||||
|
||||
### var_ns
|
||||
|
||||
**Type:** IP Address
|
||||
**Default:** Auto (from host)
|
||||
**Description:** DNS nameserver IP.
|
||||
|
||||
```bash
|
||||
var_ns=8.8.8.8 # Google DNS
|
||||
var_ns=1.1.1.1 # Cloudflare DNS
|
||||
var_ns=9.9.9.9 # Quad9 DNS
|
||||
var_ns=192.168.1.1 # Local DNS
|
||||
```
|
||||
|
||||
**Common DNS Servers:**
|
||||
```
|
||||
8.8.8.8, 8.8.4.4 → Google Public DNS
|
||||
1.1.1.1, 1.0.0.1 → Cloudflare DNS
|
||||
9.9.9.9, 149.112.112.112 → Quad9 DNS
|
||||
208.67.222.222 → OpenDNS
|
||||
192.168.1.1 → Local router/Pi-hole
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### var_ssh
|
||||
|
||||
**Type:** Boolean
|
||||
**Options:** `yes` or `no`
|
||||
**Default:** `no`
|
||||
**Description:** Enable SSH server in container.
|
||||
|
||||
```bash
|
||||
var_ssh=yes # SSH server enabled
|
||||
var_ssh=no # SSH server disabled (console only)
|
||||
```
|
||||
|
||||
**When enabled:**
|
||||
- OpenSSH server installed
|
||||
- Started on boot
|
||||
- Port 22 open
|
||||
- Root login allowed
|
||||
|
||||
**Security Considerations:**
|
||||
- Disable if not needed
|
||||
- Use SSH keys instead of passwords
|
||||
- Consider non-standard port
|
||||
- Firewall rules recommended
|
||||
|
||||
---
|
||||
|
||||
### var_ssh_authorized_key
|
||||
|
||||
**Type:** String (SSH public key)
|
||||
**Default:** None
|
||||
**Description:** SSH public key for root user.
|
||||
|
||||
```bash
|
||||
var_ssh_authorized_key=ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC... user@host
|
||||
var_ssh_authorized_key=ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... user@host
|
||||
```
|
||||
|
||||
**Supported Key Types:**
|
||||
- RSA (2048-4096 bits)
|
||||
- Ed25519 (recommended)
|
||||
- ECDSA
|
||||
- DSA (deprecated)
|
||||
|
||||
**How to get your public key:**
|
||||
```bash
|
||||
cat ~/.ssh/id_rsa.pub
|
||||
# or
|
||||
cat ~/.ssh/id_ed25519.pub
|
||||
```
|
||||
|
||||
**Multiple keys:**
|
||||
Separate with newlines (in file) or use multiple deployments.
|
||||
|
||||
---
|
||||
|
||||
### var_pw
|
||||
|
||||
**Type:** String
|
||||
**Default:** Empty (auto-login)
|
||||
**Description:** Root password.
|
||||
|
||||
```bash
|
||||
var_pw=SecurePassword123! # Set password
|
||||
var_pw= # Auto-login (empty)
|
||||
```
|
||||
|
||||
**Auto-login behavior:**
|
||||
- No password required for console
|
||||
- Automatic login on console access
|
||||
- SSH still requires key if enabled
|
||||
- Suitable for development
|
||||
|
||||
**Password best practices:**
|
||||
- Minimum 12 characters
|
||||
- Mix upper/lower/numbers/symbols
|
||||
- Use password manager
|
||||
- Rotate regularly
|
||||
|
||||
---
|
||||
|
||||
### var_nesting
|
||||
|
||||
**Type:** Boolean (0 or 1)
|
||||
**Default:** `1`
|
||||
**Description:** Allow nested containers (required for Docker).
|
||||
|
||||
```bash
|
||||
var_nesting=1 # Nested containers allowed
|
||||
var_nesting=0 # Nested containers disabled
|
||||
```
|
||||
|
||||
**Required for:**
|
||||
- Docker
|
||||
- LXC inside LXC
|
||||
- Systemd features
|
||||
- Container orchestration
|
||||
|
||||
**Security Impact:**
|
||||
- Slightly reduced isolation
|
||||
- Required for container platforms
|
||||
- Generally safe when unprivileged
|
||||
|
||||
---
|
||||
|
||||
### var_diagnostics
|
||||
|
||||
**Type:** Boolean (yes or no)
|
||||
**Default:** `yes`
|
||||
**Description:** Determines if anonymous telemetry and diagnostic data is sent to Community-Scripts API.
|
||||
|
||||
```bash
|
||||
var_diagnostics=yes # Allow telemetry (helps us improve scripts)
|
||||
var_diagnostics=no # Disable all telemetry
|
||||
```
|
||||
|
||||
**Privacy & Usage:**
|
||||
- Data is strictly anonymous (random session ID)
|
||||
- Reports success/failure of installations
|
||||
- Maps error codes (e.g., APT lock, out of RAM)
|
||||
- No user-specific data, hostnames, or secret keys are ever sent
|
||||
|
||||
---
|
||||
|
||||
### var_gpu
|
||||
|
||||
**Type:** Boolean/Toggle
|
||||
**Options:** `yes` or `no`
|
||||
**Default:** `no`
|
||||
**Description:** Enable GPU passthrough for the container.
|
||||
|
||||
```bash
|
||||
var_gpu=yes # Enable GPU passthrough (auto-detect)
|
||||
var_gpu=no # Disable GPU passthrough (default)
|
||||
```
|
||||
|
||||
**Features enabled:**
|
||||
- Auto-detects Intel (QuickSync), NVIDIA, and AMD GPUs
|
||||
- Passes through `/dev/dri` and render nodes
|
||||
- Configures appropriate container permissions
|
||||
- Crucial for media servers (Plex, Jellyfin, Immich)
|
||||
|
||||
**Prerequisites:**
|
||||
- Host drivers installed correctly
|
||||
- Hardware present and visible to Proxmox
|
||||
- IOMMU enabled (for some configurations)
|
||||
|
||||
---
|
||||
|
||||
### var_tun
|
||||
|
||||
**Type:** Boolean/Toggle
|
||||
**Options:** `yes` or `no`
|
||||
**Default:** `no`
|
||||
**Description:** Enable TUN/TAP device support.
|
||||
|
||||
```bash
|
||||
var_tun=yes # Enable TUN/TAP support
|
||||
var_tun=no # Disable TUN/TAP support (default)
|
||||
```
|
||||
|
||||
**Required for:**
|
||||
- VPN software (WireGuard, OpenVPN)
|
||||
- Network tunneling (Tailscale, ZeroTier)
|
||||
- Custom network bridges
|
||||
|
||||
---
|
||||
|
||||
### var_keyctl
|
||||
|
||||
**Type:** Boolean (0 or 1)
|
||||
**Default:** `0`
|
||||
**Description:** Enable keyctl system call.
|
||||
|
||||
```bash
|
||||
var_keyctl=1 # Keyctl enabled
|
||||
var_keyctl=0 # Keyctl disabled
|
||||
```
|
||||
|
||||
**Required for:**
|
||||
- Docker in some configurations
|
||||
- Systemd keyring features
|
||||
- Encryption key management
|
||||
- Some authentication systems
|
||||
|
||||
---
|
||||
|
||||
### var_fuse
|
||||
|
||||
**Type:** Boolean/Toggle
|
||||
**Options:** `yes` or `no`
|
||||
**Default:** `no`
|
||||
**Description:** Enable FUSE filesystem support.
|
||||
|
||||
```bash
|
||||
var_fuse=yes # FUSE enabled
|
||||
var_fuse=no # FUSE disabled
|
||||
```
|
||||
|
||||
**Required for:**
|
||||
- sshfs
|
||||
- AppImage
|
||||
- Some backup tools
|
||||
- User-space filesystems
|
||||
|
||||
---
|
||||
|
||||
### var_mknod
|
||||
|
||||
**Type:** Boolean (0 or 1)
|
||||
**Default:** `0`
|
||||
**Description:** Allow device node creation.
|
||||
|
||||
```bash
|
||||
var_mknod=1 # Device nodes allowed
|
||||
var_mknod=0 # Device nodes disabled
|
||||
```
|
||||
|
||||
**Requires:**
|
||||
- Kernel 5.3+
|
||||
- Experimental feature
|
||||
- Use with caution
|
||||
|
||||
---
|
||||
|
||||
### var_mount_fs
|
||||
|
||||
**Type:** String (comma-separated)
|
||||
**Default:** Empty
|
||||
**Description:** Allowed mountable filesystems.
|
||||
|
||||
```bash
|
||||
var_mount_fs=nfs
|
||||
var_mount_fs=nfs,cifs
|
||||
var_mount_fs=ext4,xfs,nfs
|
||||
```
|
||||
|
||||
**Common Options:**
|
||||
```
|
||||
nfs → NFS network shares
|
||||
cifs → SMB/CIFS shares
|
||||
ext4 → Ext4 filesystems
|
||||
xfs → XFS filesystems
|
||||
btrfs → Btrfs filesystems
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### var_protection
|
||||
|
||||
**Type:** Boolean
|
||||
**Options:** `yes` or `no`
|
||||
**Default:** `no`
|
||||
**Description:** Prevent accidental deletion.
|
||||
|
||||
```bash
|
||||
var_protection=yes # Protected from deletion
|
||||
var_protection=no # Can be deleted normally
|
||||
```
|
||||
|
||||
**When protected:**
|
||||
- Cannot delete via GUI
|
||||
- Cannot delete via `pct destroy`
|
||||
- Must disable protection first
|
||||
- Good for production containers
|
||||
|
||||
---
|
||||
|
||||
### var_tags
|
||||
|
||||
**Type:** String (comma-separated)
|
||||
**Default:** `community-script`
|
||||
**Description:** Container tags for organization.
|
||||
|
||||
```bash
|
||||
var_tags=production
|
||||
var_tags=production,webserver
|
||||
var_tags=dev,testing,temporary
|
||||
```
|
||||
|
||||
**Best Practices:**
|
||||
```bash
|
||||
# Environment tags
|
||||
var_tags=production
|
||||
var_tags=development
|
||||
var_tags=staging
|
||||
|
||||
# Function tags
|
||||
var_tags=webserver,nginx
|
||||
var_tags=database,postgresql
|
||||
var_tags=cache,redis
|
||||
|
||||
# Project tags
|
||||
var_tags=project-alpha,frontend
|
||||
var_tags=customer-xyz,billing
|
||||
|
||||
# Combined
|
||||
var_tags=production,webserver,project-alpha
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### var_timezone
|
||||
|
||||
**Type:** String (TZ database format)
|
||||
**Default:** Host timezone
|
||||
**Description:** Container timezone.
|
||||
|
||||
```bash
|
||||
var_timezone=Europe/Berlin
|
||||
var_timezone=America/New_York
|
||||
var_timezone=Asia/Tokyo
|
||||
```
|
||||
|
||||
**Common Timezones:**
|
||||
```
|
||||
Europe/London
|
||||
Europe/Berlin
|
||||
Europe/Paris
|
||||
America/New_York
|
||||
America/Chicago
|
||||
America/Los_Angeles
|
||||
Asia/Tokyo
|
||||
Asia/Singapore
|
||||
Australia/Sydney
|
||||
UTC
|
||||
```
|
||||
|
||||
**List all timezones:**
|
||||
```bash
|
||||
timedatectl list-timezones
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### var_verbose
|
||||
|
||||
**Type:** Boolean
|
||||
**Options:** `yes` or `no`
|
||||
**Default:** `no`
|
||||
**Description:** Enable verbose output.
|
||||
|
||||
```bash
|
||||
var_verbose=yes # Show all commands
|
||||
var_verbose=no # Silent mode
|
||||
```
|
||||
|
||||
**When enabled:**
|
||||
- Shows all executed commands
|
||||
- Displays detailed progress
|
||||
- Useful for debugging
|
||||
- More log output
|
||||
|
||||
---
|
||||
|
||||
### var_apt_cacher
|
||||
|
||||
**Type:** Boolean
|
||||
**Options:** `yes` or `no`
|
||||
**Default:** `no`
|
||||
**Description:** Use APT caching proxy.
|
||||
|
||||
```bash
|
||||
var_apt_cacher=yes
|
||||
var_apt_cacher=no
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- Faster package installs
|
||||
- Reduced bandwidth
|
||||
- Offline package cache
|
||||
- Speeds up multiple containers
|
||||
|
||||
---
|
||||
|
||||
### var_apt_cacher_ip
|
||||
|
||||
**Type:** IP Address
|
||||
**Default:** None
|
||||
**Description:** APT cacher proxy IP.
|
||||
|
||||
```bash
|
||||
var_apt_cacher=yes
|
||||
var_apt_cacher_ip=192.168.1.100
|
||||
```
|
||||
|
||||
**Setup apt-cacher-ng:**
|
||||
```bash
|
||||
apt install apt-cacher-ng
|
||||
# Runs on port 3142
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### var_container_storage
|
||||
|
||||
**Type:** String
|
||||
**Default:** Auto-detected
|
||||
**Description:** Storage for container.
|
||||
|
||||
```bash
|
||||
var_container_storage=local
|
||||
var_container_storage=local-zfs
|
||||
var_container_storage=pve-storage
|
||||
```
|
||||
|
||||
**List available storage:**
|
||||
```bash
|
||||
pvesm status
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### var_template_storage
|
||||
|
||||
**Type:** String
|
||||
**Default:** Auto-detected
|
||||
**Description:** Storage for templates.
|
||||
|
||||
```bash
|
||||
var_template_storage=local
|
||||
var_template_storage=nfs-templates
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Table
|
||||
|
||||
| Variable | Type | Default | Example |
|
||||
|----------|------|---------|---------|
|
||||
| `var_unprivileged` | 0/1 | 1 | `var_unprivileged=1` |
|
||||
| `var_cpu` | int | varies | `var_cpu=4` |
|
||||
| `var_ram` | int (MB) | varies | `var_ram=4096` |
|
||||
| `var_disk` | int (GB) | varies | `var_disk=20` |
|
||||
| `var_hostname` | string | app name | `var_hostname=server` |
|
||||
| `var_brg` | string | vmbr0 | `var_brg=vmbr1` |
|
||||
| `var_net` | dhcp/static | dhcp | `var_net=dhcp` |
|
||||
| `var_gateway` | IP | auto | `var_gateway=192.168.1.1` |
|
||||
| `var_ipv6_method` | string | none | `var_ipv6_method=disable` |
|
||||
| `var_vlan` | int | - | `var_vlan=100` |
|
||||
| `var_mtu` | int | 1500 | `var_mtu=9000` |
|
||||
| `var_mac` | MAC | auto | `var_mac=02:00:00:00:00:01` |
|
||||
| `var_ns` | IP | auto | `var_ns=8.8.8.8` |
|
||||
| `var_ssh` | yes/no | no | `var_ssh=yes` |
|
||||
| `var_ssh_authorized_key` | string | - | `var_ssh_authorized_key=ssh-rsa...` |
|
||||
| `var_pw` | string | empty | `var_pw=password` |
|
||||
| `var_nesting` | 0/1 | 1 | `var_nesting=1` |
|
||||
| `var_keyctl` | 0/1 | 0 | `var_keyctl=1` |
|
||||
| `var_fuse` | 0/1 | 0 | `var_fuse=1` |
|
||||
| `var_mknod` | 0/1 | 0 | `var_mknod=1` |
|
||||
| `var_mount_fs` | string | - | `var_mount_fs=nfs,cifs` |
|
||||
| `var_protection` | yes/no | no | `var_protection=yes` |
|
||||
| `var_tags` | string | community-script | `var_tags=prod,web` |
|
||||
| `var_timezone` | string | host TZ | `var_timezone=Europe/Berlin` |
|
||||
| `var_verbose` | yes/no | no | `var_verbose=yes` |
|
||||
| `var_apt_cacher` | yes/no | no | `var_apt_cacher=yes` |
|
||||
| `var_apt_cacher_ip` | IP | - | `var_apt_cacher_ip=192.168.1.10` |
|
||||
| `var_container_storage` | string | auto | `var_container_storage=local-zfs` |
|
||||
| `var_template_storage` | string | auto | `var_template_storage=local` |
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Defaults System Guide](DEFAULTS_GUIDE.md)
|
||||
- [Unattended Deployments](UNATTENDED_DEPLOYMENTS.md)
|
||||
- [Security Best Practices](SECURITY_GUIDE.md)
|
||||
- [Network Configuration](NETWORK_GUIDE.md)
|
||||
@@ -1,760 +0,0 @@
|
||||
# Configuration & Defaults System - User Guide
|
||||
|
||||
> **Complete Guide to App Defaults and User Defaults**
|
||||
>
|
||||
> *Learn how to configure, save, and reuse your installation settings*
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Quick Start](#quick-start)
|
||||
2. [Understanding the Defaults System](#understanding-the-defaults-system)
|
||||
3. [Installation Modes](#installation-modes)
|
||||
4. [How to Save Defaults](#how-to-save-defaults)
|
||||
5. [How to Use Saved Defaults](#how-to-use-saved-defaults)
|
||||
6. [Managing Your Defaults](#managing-your-defaults)
|
||||
7. [Advanced Configuration](#advanced-configuration)
|
||||
8. [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 30-Second Setup
|
||||
|
||||
```bash
|
||||
# 1. Run any container installation script
|
||||
bash pihole-install.sh
|
||||
|
||||
# 2. When prompted, select: "Advanced Settings"
|
||||
# (This allows you to customize everything)
|
||||
|
||||
# 3. Answer all configuration questions
|
||||
|
||||
# 4. At the end, when asked "Save as App Defaults?"
|
||||
# Select: YES
|
||||
|
||||
# 5. Done! Your settings are now saved
|
||||
```
|
||||
|
||||
**Next Time**: Run the same script again, select **"App Defaults"** and your settings will be applied automatically!
|
||||
|
||||
---
|
||||
|
||||
## Understanding the Defaults System
|
||||
|
||||
### The Three-Tier System
|
||||
|
||||
Your installation settings are managed through three layers:
|
||||
|
||||
#### 🔷 **Tier 1: Built-in Defaults** (Fallback)
|
||||
```
|
||||
These are hardcoded in the scripts
|
||||
Provide sensible defaults for each application
|
||||
Example: PiHole uses 2 CPU cores by default
|
||||
```
|
||||
|
||||
#### 🔶 **Tier 2: User Defaults** (Global)
|
||||
```
|
||||
Your personal global defaults
|
||||
Applied to ALL container installations
|
||||
Location: /usr/local/community-scripts/default.vars
|
||||
Example: "I always want 4 CPU cores and 2GB RAM"
|
||||
```
|
||||
|
||||
#### 🔴 **Tier 3: App Defaults** (Specific)
|
||||
```
|
||||
Application-specific saved settings
|
||||
Only applied when installing that specific app
|
||||
Location: /usr/local/community-scripts/defaults/<appname>.vars
|
||||
Example: "Whenever I install PiHole, use these exact settings"
|
||||
```
|
||||
|
||||
### Priority System
|
||||
|
||||
When installing a container, settings are applied in this order:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ 1. Environment Variables (HIGHEST) │ Set in shell: export var_cpu=8
|
||||
│ (these override everything) │
|
||||
├─────────────────────────────────────┤
|
||||
│ 2. App Defaults │ From: defaults/pihole.vars
|
||||
│ (app-specific saved settings) │
|
||||
├─────────────────────────────────────┤
|
||||
│ 3. User Defaults │ From: default.vars
|
||||
│ (your global defaults) │
|
||||
├─────────────────────────────────────┤
|
||||
│ 4. Built-in Defaults (LOWEST) │ Hardcoded in script
|
||||
│ (failsafe, always available) │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**In Plain English**:
|
||||
- If you set an environment variable → it wins
|
||||
- Otherwise, if you have app-specific defaults → use those
|
||||
- Otherwise, if you have user defaults → use those
|
||||
- Otherwise, use the hardcoded defaults
|
||||
|
||||
---
|
||||
|
||||
## Installation Modes
|
||||
|
||||
When you run any installation script, you'll be presented with a menu:
|
||||
|
||||
### Option 1️⃣ : **Default Settings**
|
||||
|
||||
```
|
||||
Quick installation with standard settings
|
||||
├─ Best for: First-time users, quick deployments
|
||||
├─ What happens:
|
||||
│ 1. Script uses built-in defaults
|
||||
│ 2. Container created immediately
|
||||
│ 3. No questions asked
|
||||
└─ Time: ~2 minutes
|
||||
```
|
||||
|
||||
**When to use**: You want a standard installation, don't need customization
|
||||
|
||||
---
|
||||
|
||||
### Option 2️⃣ : **Advanced Settings**
|
||||
|
||||
```
|
||||
Full customization with 19 configuration steps
|
||||
├─ Best for: Power users, custom requirements
|
||||
├─ What happens:
|
||||
│ 1. Script asks for EVERY setting
|
||||
│ 2. You control: CPU, RAM, Disk, Network, SSH, etc.
|
||||
│ 3. Shows summary before creating
|
||||
│ 4. Offers to save as App Defaults
|
||||
└─ Time: ~5-10 minutes
|
||||
```
|
||||
|
||||
**When to use**: You want full control over the configuration
|
||||
|
||||
**Available Settings**:
|
||||
- CPU cores, RAM amount, Disk size
|
||||
- Container name, network settings
|
||||
- SSH access, API access, Features
|
||||
- Password, SSH keys, Tags
|
||||
|
||||
---
|
||||
|
||||
### Option 3️⃣ : **User Defaults**
|
||||
|
||||
```
|
||||
Use your saved global defaults
|
||||
├─ Best for: Consistent deployments across many containers
|
||||
├─ Requires: You've previously saved User Defaults
|
||||
├─ What happens:
|
||||
│ 1. Loads settings from: /usr/local/community-scripts/default.vars
|
||||
│ 2. Shows you the loaded settings
|
||||
│ 3. Creates container immediately
|
||||
└─ Time: ~2 minutes
|
||||
```
|
||||
|
||||
**When to use**: You have preferred defaults you want to use for every app
|
||||
|
||||
---
|
||||
|
||||
### Option 4️⃣ : **App Defaults** (if available)
|
||||
|
||||
```
|
||||
Use previously saved app-specific defaults
|
||||
├─ Best for: Repeating the same configuration multiple times
|
||||
├─ Requires: You've previously saved App Defaults for this app
|
||||
├─ What happens:
|
||||
│ 1. Loads settings from: /usr/local/community-scripts/defaults/<app>.vars
|
||||
│ 2. Shows you the loaded settings
|
||||
│ 3. Creates container immediately
|
||||
└─ Time: ~2 minutes
|
||||
```
|
||||
|
||||
**When to use**: You've installed this app before and want identical settings
|
||||
|
||||
---
|
||||
|
||||
### Option 5️⃣ : **Settings Menu**
|
||||
|
||||
```
|
||||
Manage your saved configurations
|
||||
├─ Functions:
|
||||
│ • View current settings
|
||||
│ • Edit storage selections
|
||||
│ • Manage defaults location
|
||||
│ • See what's currently configured
|
||||
└─ Time: ~1 minute
|
||||
```
|
||||
|
||||
**When to use**: You want to review or modify saved settings
|
||||
|
||||
---
|
||||
|
||||
## How to Save Defaults
|
||||
|
||||
### Method 1: Save While Installing
|
||||
|
||||
This is the easiest way:
|
||||
|
||||
#### Step-by-Step: Create App Defaults
|
||||
|
||||
```bash
|
||||
# 1. Run the installation script
|
||||
bash pihole-install.sh
|
||||
|
||||
# 2. Choose installation mode
|
||||
# ┌─────────────────────────┐
|
||||
# │ Select installation mode:│
|
||||
# │ 1) Default Settings │
|
||||
# │ 2) Advanced Settings │
|
||||
# │ 3) User Defaults │
|
||||
# │ 4) App Defaults │
|
||||
# │ 5) Settings Menu │
|
||||
# └─────────────────────────┘
|
||||
#
|
||||
# Enter: 2 (Advanced Settings)
|
||||
|
||||
# 3. Answer all configuration questions
|
||||
# • Container name? → my-pihole
|
||||
# • CPU cores? → 4
|
||||
# • RAM amount? → 2048
|
||||
# • Disk size? → 20
|
||||
# • SSH access? → yes
|
||||
# ... (more options)
|
||||
|
||||
# 4. Review summary (shown before creation)
|
||||
# ✓ Confirm to proceed
|
||||
|
||||
# 5. After creation completes, you'll see:
|
||||
# ┌──────────────────────────────────┐
|
||||
# │ Save as App Defaults for PiHole? │
|
||||
# │ (Yes/No) │
|
||||
# └──────────────────────────────────┘
|
||||
#
|
||||
# Select: Yes
|
||||
|
||||
# 6. Done! Settings saved to:
|
||||
# /usr/local/community-scripts/defaults/pihole.vars
|
||||
```
|
||||
|
||||
#### Step-by-Step: Create User Defaults
|
||||
|
||||
```bash
|
||||
# Same as App Defaults, but:
|
||||
# When you select "Advanced Settings"
|
||||
# FIRST app you run with this selection will offer
|
||||
# to save as "User Defaults" additionally
|
||||
|
||||
# This saves to: /usr/local/community-scripts/default.vars
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Method 2: Manual File Creation
|
||||
|
||||
For advanced users who want to create defaults without running installation:
|
||||
|
||||
```bash
|
||||
# Create User Defaults manually
|
||||
sudo tee /usr/local/community-scripts/default.vars > /dev/null << 'EOF'
|
||||
# Global User Defaults
|
||||
var_cpu=4
|
||||
var_ram=2048
|
||||
var_disk=20
|
||||
var_unprivileged=1
|
||||
var_brg=vmbr0
|
||||
var_gateway=192.168.1.1
|
||||
var_timezone=Europe/Berlin
|
||||
var_ssh=yes
|
||||
var_container_storage=local
|
||||
var_template_storage=local
|
||||
EOF
|
||||
|
||||
# Create App Defaults manually
|
||||
sudo tee /usr/local/community-scripts/defaults/pihole.vars > /dev/null << 'EOF'
|
||||
# App-specific defaults for PiHole
|
||||
var_unprivileged=1
|
||||
var_cpu=2
|
||||
var_ram=1024
|
||||
var_disk=10
|
||||
var_brg=vmbr0
|
||||
var_gateway=192.168.1.1
|
||||
var_hostname=pihole
|
||||
var_container_storage=local
|
||||
var_template_storage=local
|
||||
EOF
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Method 3: Using Environment Variables
|
||||
|
||||
Set defaults via environment before running:
|
||||
|
||||
```bash
|
||||
# Set as environment variables
|
||||
export var_cpu=4
|
||||
export var_ram=2048
|
||||
export var_disk=20
|
||||
export var_hostname=my-container
|
||||
|
||||
# Run installation
|
||||
bash pihole-install.sh
|
||||
|
||||
# These settings will be used
|
||||
# (Can still be overridden by saved defaults)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How to Use Saved Defaults
|
||||
|
||||
### Using User Defaults
|
||||
|
||||
```bash
|
||||
# 1. Run any installation script
|
||||
bash pihole-install.sh
|
||||
|
||||
# 2. When asked for mode, select:
|
||||
# Option: 3 (User Defaults)
|
||||
|
||||
# 3. Your settings from default.vars are applied
|
||||
# 4. Container created with your saved settings
|
||||
```
|
||||
|
||||
### Using App Defaults
|
||||
|
||||
```bash
|
||||
# 1. Run the app you configured before
|
||||
bash pihole-install.sh
|
||||
|
||||
# 2. When asked for mode, select:
|
||||
# Option: 4 (App Defaults)
|
||||
|
||||
# 3. Your settings from defaults/pihole.vars are applied
|
||||
# 4. Container created with exact same settings
|
||||
```
|
||||
|
||||
### Overriding Saved Defaults
|
||||
|
||||
```bash
|
||||
# Even if you have defaults saved,
|
||||
# you can override them with environment variables
|
||||
|
||||
export var_cpu=8 # Override saved defaults
|
||||
export var_hostname=custom-name
|
||||
|
||||
bash pihole-install.sh
|
||||
# Installation will use these values instead of saved defaults
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Managing Your Defaults
|
||||
|
||||
### View Your Settings
|
||||
|
||||
#### View User Defaults
|
||||
```bash
|
||||
cat /usr/local/community-scripts/default.vars
|
||||
```
|
||||
|
||||
#### View App Defaults
|
||||
```bash
|
||||
cat /usr/local/community-scripts/defaults/pihole.vars
|
||||
```
|
||||
|
||||
#### List All Saved App Defaults
|
||||
```bash
|
||||
ls -la /usr/local/community-scripts/defaults/
|
||||
```
|
||||
|
||||
### Edit Your Settings
|
||||
|
||||
#### Edit User Defaults
|
||||
```bash
|
||||
sudo nano /usr/local/community-scripts/default.vars
|
||||
```
|
||||
|
||||
#### Edit App Defaults
|
||||
```bash
|
||||
sudo nano /usr/local/community-scripts/defaults/pihole.vars
|
||||
```
|
||||
|
||||
### Update Existing Defaults
|
||||
|
||||
```bash
|
||||
# Run installation again with your app
|
||||
bash pihole-install.sh
|
||||
|
||||
# Select: Advanced Settings
|
||||
# Make desired changes
|
||||
# At end, when asked to save:
|
||||
# "Defaults already exist, Update?"
|
||||
# Select: Yes
|
||||
|
||||
# Your saved defaults are updated
|
||||
```
|
||||
|
||||
### Delete Defaults
|
||||
|
||||
#### Delete User Defaults
|
||||
```bash
|
||||
sudo rm /usr/local/community-scripts/default.vars
|
||||
```
|
||||
|
||||
#### Delete App Defaults
|
||||
```bash
|
||||
sudo rm /usr/local/community-scripts/defaults/pihole.vars
|
||||
```
|
||||
|
||||
#### Delete All App Defaults
|
||||
```bash
|
||||
sudo rm /usr/local/community-scripts/defaults/*
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Available Variables
|
||||
|
||||
All configurable variables start with `var_`:
|
||||
|
||||
#### Resource Allocation
|
||||
```bash
|
||||
var_cpu=4 # CPU cores
|
||||
var_ram=2048 # RAM in MB
|
||||
var_disk=20 # Disk in GB
|
||||
var_unprivileged=1 # 0=privileged, 1=unprivileged
|
||||
```
|
||||
|
||||
#### Network
|
||||
```bash
|
||||
var_brg=vmbr0 # Bridge interface
|
||||
var_net=dhcp # dhcp, static IP/CIDR, or IP range (see below)
|
||||
var_gateway=192.168.1.1 # Default gateway (required for static IP)
|
||||
var_mtu=1500 # MTU size
|
||||
var_vlan=100 # VLAN ID
|
||||
```
|
||||
|
||||
#### IP Range Scanning
|
||||
|
||||
You can specify an IP range instead of a static IP. The system will ping each IP in the range and automatically assign the first free IP:
|
||||
|
||||
```bash
|
||||
# Format: START_IP/CIDR-END_IP/CIDR
|
||||
var_net=192.168.1.100/24-192.168.1.200/24
|
||||
var_gateway=192.168.1.1
|
||||
```
|
||||
|
||||
This is useful for automated deployments where you want static IPs but don't want to track which IPs are already in use.
|
||||
|
||||
#### System
|
||||
```bash
|
||||
var_hostname=pihole # Container name
|
||||
var_timezone=Europe/Berlin # Timezone
|
||||
var_pw=SecurePass123 # Root password
|
||||
var_tags=dns,pihole # Tags for organization
|
||||
var_verbose=yes # Enable verbose output
|
||||
```
|
||||
|
||||
#### Security & Access
|
||||
```bash
|
||||
var_ssh=yes # Enable SSH
|
||||
var_ssh_authorized_key="ssh-rsa AA..." # SSH public key
|
||||
var_protection=1 # Enable protection flag
|
||||
```
|
||||
|
||||
#### Features
|
||||
```bash
|
||||
var_fuse=1 # FUSE filesystem support
|
||||
var_tun=1 # TUN device support
|
||||
var_nesting=1 # Nesting (Docker in LXC)
|
||||
var_keyctl=1 # Keyctl syscall
|
||||
var_mknod=1 # Device node creation
|
||||
```
|
||||
|
||||
#### Storage
|
||||
```bash
|
||||
var_container_storage=local # Where to store container
|
||||
var_template_storage=local # Where to store templates
|
||||
```
|
||||
|
||||
### Example Configuration Files
|
||||
|
||||
#### Gaming Server Defaults
|
||||
```bash
|
||||
# High performance for gaming containers
|
||||
var_cpu=8
|
||||
var_ram=4096
|
||||
var_disk=50
|
||||
var_unprivileged=0
|
||||
var_fuse=1
|
||||
var_nesting=1
|
||||
var_tags=gaming
|
||||
```
|
||||
|
||||
#### Development Server
|
||||
```bash
|
||||
# Development with Docker support
|
||||
var_cpu=4
|
||||
var_ram=2048
|
||||
var_disk=30
|
||||
var_unprivileged=1
|
||||
var_nesting=1
|
||||
var_ssh=yes
|
||||
var_tags=development
|
||||
```
|
||||
|
||||
#### IoT/Monitoring
|
||||
```bash
|
||||
# Low-resource, always-on containers
|
||||
var_cpu=2
|
||||
var_ram=512
|
||||
var_disk=10
|
||||
var_unprivileged=1
|
||||
var_nesting=0
|
||||
var_fuse=0
|
||||
var_tun=0
|
||||
var_tags=iot,monitoring
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "App Defaults not available" Message
|
||||
|
||||
**Problem**: You want to use App Defaults, but option says they're not available
|
||||
|
||||
**Solution**:
|
||||
1. You haven't created App Defaults yet for this app
|
||||
2. Run the app with "Advanced Settings"
|
||||
3. When finished, save as App Defaults
|
||||
4. Next time, App Defaults will be available
|
||||
|
||||
---
|
||||
|
||||
### "Settings not being applied"
|
||||
|
||||
**Problem**: You saved defaults, but they're not being used
|
||||
|
||||
**Checklist**:
|
||||
```bash
|
||||
# 1. Verify files exist
|
||||
ls -la /usr/local/community-scripts/default.vars
|
||||
ls -la /usr/local/community-scripts/defaults/<app>.vars
|
||||
|
||||
# 2. Check file permissions (should be readable)
|
||||
stat /usr/local/community-scripts/default.vars
|
||||
|
||||
# 3. Verify correct mode selected
|
||||
# (Make sure you selected "User Defaults" or "App Defaults")
|
||||
|
||||
# 4. Check for environment variable override
|
||||
env | grep var_
|
||||
# If you have var_* set in environment,
|
||||
# those override your saved defaults
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### "Cannot write to defaults location"
|
||||
|
||||
**Problem**: Permission denied when saving defaults
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Create the defaults directory if missing
|
||||
sudo mkdir -p /usr/local/community-scripts/defaults
|
||||
|
||||
# Fix permissions
|
||||
sudo chmod 755 /usr/local/community-scripts
|
||||
sudo chmod 755 /usr/local/community-scripts/defaults
|
||||
|
||||
# Make sure you're running as root
|
||||
sudo bash pihole-install.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### "Defaults directory doesn't exist"
|
||||
|
||||
**Problem**: Script can't find where to save defaults
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Create the directory
|
||||
sudo mkdir -p /usr/local/community-scripts/defaults
|
||||
|
||||
# Verify
|
||||
ls -la /usr/local/community-scripts/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Settings seem random or wrong
|
||||
|
||||
**Problem**: Container gets different settings than expected
|
||||
|
||||
**Possible Causes & Solutions**:
|
||||
|
||||
```bash
|
||||
# 1. Check if environment variables are set
|
||||
env | grep var_
|
||||
# If you see var_* entries, those override your defaults
|
||||
# Clear them: unset var_cpu var_ram (etc)
|
||||
|
||||
# 2. Verify correct defaults are in files
|
||||
cat /usr/local/community-scripts/default.vars
|
||||
cat /usr/local/community-scripts/defaults/pihole.vars
|
||||
|
||||
# 3. Check which mode you actually selected
|
||||
# (Script output shows which defaults were applied)
|
||||
|
||||
# 4. Check Proxmox logs for errors
|
||||
sudo journalctl -u pve-daemon -n 50
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### "Variable not recognized"
|
||||
|
||||
**Problem**: You set a variable that doesn't work
|
||||
|
||||
**Solution**:
|
||||
Only certain variables are allowed (security whitelist):
|
||||
|
||||
```
|
||||
Allowed variables (starting with var_):
|
||||
✓ var_cpu, var_ram, var_disk, var_unprivileged
|
||||
✓ var_brg, var_gateway, var_mtu, var_vlan, var_net
|
||||
✓ var_hostname, var_pw, var_timezone
|
||||
✓ var_ssh, var_ssh_authorized_key
|
||||
✓ var_fuse, var_tun, var_nesting, var_keyctl
|
||||
✓ var_container_storage, var_template_storage
|
||||
✓ var_tags, var_verbose
|
||||
✓ var_apt_cacher, var_apt_cacher_ip
|
||||
✓ var_protection, var_mount_fs
|
||||
|
||||
✗ Other variables are NOT supported
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ Do's
|
||||
|
||||
✓ Use **App Defaults** when you want app-specific settings
|
||||
✓ Use **User Defaults** for your global preferences
|
||||
✓ Edit defaults files directly with `nano` (safe)
|
||||
✓ Keep separate App Defaults for each app
|
||||
✓ Back up your defaults regularly
|
||||
✓ Use environment variables for temporary overrides
|
||||
|
||||
### ❌ Don'ts
|
||||
|
||||
✗ Don't use `source` on defaults files (security risk)
|
||||
✗ Don't put sensitive passwords in defaults (use SSH keys)
|
||||
✗ Don't modify defaults while installation is running
|
||||
✗ Don't delete defaults.d while containers are being created
|
||||
✗ Don't use special characters without escaping
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Defaults Locations
|
||||
|
||||
| Type | Location | Example |
|
||||
|------|----------|---------|
|
||||
| User Defaults | `/usr/local/community-scripts/default.vars` | Global settings |
|
||||
| App Defaults | `/usr/local/community-scripts/defaults/<app>.vars` | PiHole-specific |
|
||||
| Backup Dir | `/usr/local/community-scripts/defaults/` | All app defaults |
|
||||
|
||||
### File Format
|
||||
|
||||
```bash
|
||||
# Comments start with #
|
||||
var_name=value
|
||||
|
||||
# No spaces around =
|
||||
✓ var_cpu=4
|
||||
✗ var_cpu = 4
|
||||
|
||||
# String values don't need quotes
|
||||
✓ var_hostname=mycontainer
|
||||
✓ var_hostname='mycontainer'
|
||||
|
||||
# Values with spaces need quotes
|
||||
✓ var_tags="docker,production,testing"
|
||||
✗ var_tags=docker,production,testing
|
||||
```
|
||||
|
||||
### Command Reference
|
||||
|
||||
```bash
|
||||
# View defaults
|
||||
cat /usr/local/community-scripts/default.vars
|
||||
|
||||
# Edit defaults
|
||||
sudo nano /usr/local/community-scripts/default.vars
|
||||
|
||||
# List all app defaults
|
||||
ls /usr/local/community-scripts/defaults/
|
||||
|
||||
# Backup your defaults
|
||||
cp -r /usr/local/community-scripts/defaults/ ~/defaults-backup/
|
||||
|
||||
# Set temporary override
|
||||
export var_cpu=8
|
||||
bash pihole-install.sh
|
||||
|
||||
# Create custom defaults
|
||||
sudo tee /usr/local/community-scripts/defaults/custom.vars << 'EOF'
|
||||
var_cpu=4
|
||||
var_ram=2048
|
||||
EOF
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
### Need More Information?
|
||||
|
||||
- 📖 [Main Documentation](../../docs/)
|
||||
- 🐛 [Report Issues](https://github.com/community-scripts/ProxmoxVE/issues)
|
||||
- 💬 [Discussions](https://github.com/community-scripts/ProxmoxVE/discussions)
|
||||
|
||||
### Useful Commands
|
||||
|
||||
```bash
|
||||
# Check what variables are available
|
||||
grep "var_" /path/to/app-install.sh | head -20
|
||||
|
||||
# Verify defaults syntax
|
||||
cat /usr/local/community-scripts/default.vars
|
||||
|
||||
# Monitor installation with defaults
|
||||
bash pihole-install.sh 2>&1 | tee installation.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Document Information
|
||||
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| Version | 1.0 |
|
||||
| Last Updated | November 28, 2025 |
|
||||
| Status | Current |
|
||||
| License | MIT |
|
||||
|
||||
---
|
||||
|
||||
**Happy configuring! 🚀**
|
||||
@@ -1,58 +0,0 @@
|
||||
# Configuration & Deployment Guides
|
||||
|
||||
This directory contains comprehensive guides for configuring and deploying Proxmox VE containers using community-scripts.
|
||||
|
||||
## 📚 Available Guides
|
||||
|
||||
### [Configuration Reference](CONFIGURATION_REFERENCE.md)
|
||||
|
||||
Complete reference for all configuration options, environment variables, and advanced settings available in the build system.
|
||||
|
||||
**Topics covered:**
|
||||
|
||||
- Container specifications (CPU, RAM, Disk)
|
||||
- Network configuration (IPv4/IPv6, VLAN, MTU)
|
||||
- Storage selection and management
|
||||
- Privilege modes and features
|
||||
- OS selection and versions
|
||||
|
||||
### [Defaults System Guide](DEFAULTS_SYSTEM_GUIDE.md)
|
||||
|
||||
Understanding and customizing default settings for container deployments.
|
||||
|
||||
**Topics covered:**
|
||||
|
||||
- Default system settings
|
||||
- Per-script overrides
|
||||
- Custom defaults configuration
|
||||
- Environment variable precedence
|
||||
|
||||
### [Unattended Deployments](UNATTENDED_DEPLOYMENTS.md)
|
||||
|
||||
Automating container deployments without user interaction.
|
||||
|
||||
**Topics covered:**
|
||||
|
||||
- Environment variable configuration
|
||||
- Batch deployments
|
||||
- CI/CD integration
|
||||
- Scripted installations
|
||||
- Pre-configured templates
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- **[CT Scripts Guide](../ct/)** - Container script structure and usage
|
||||
- **[Install Scripts Guide](../install/)** - Installation script internals
|
||||
- **[API Documentation](../api/)** - API integration and endpoints
|
||||
- **[Build Functions](../misc/build.func/)** - Build system functions reference
|
||||
- **[Tools Functions](../misc/tools.func/)** - Utility functions reference
|
||||
|
||||
## 💡 Quick Start
|
||||
|
||||
For most users, start with the **Unattended Deployments** guide to learn how to automate your container setups.
|
||||
|
||||
For advanced configuration options, refer to the **Configuration Reference**.
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
If you'd like to improve these guides or add new ones, please see our [Contribution Guide](../contribution/).
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,44 +0,0 @@
|
||||
<div align="center">
|
||||
<a href="#">
|
||||
<img src="https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/images/logo.png" height="100px" />
|
||||
</a>
|
||||
</div>
|
||||
<h2 align="center">User Submitted Guides </h2>
|
||||
|
||||
<sub> In order to contribute a guide on installing with Proxmox VE Helper Scripts, you should open a pull request that adds the guide to the `USER_SUBMITTED_GUIDES.md` file. </sub>
|
||||
|
||||
[Proxmox Automation with Proxmox Helper Scripts!](https://www.youtube.com/watch?v=kcpu4z5eSEU)
|
||||
|
||||
[Installing Home Assistant OS using Proxmox 8](https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-8/201835)
|
||||
|
||||
[How To Separate Zigbee2MQTT From Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-separate-zigbee2mqtt-from-home-assistant-in-proxmox/)
|
||||
|
||||
[How To Install Home Assistant On Proxmox: The Easy Way](https://smarthomescene.com/guides/how-to-install-home-assistant-on-proxmox-the-easy-way/)
|
||||
|
||||
[Home Assistant: Installing InfluxDB (LXC)](https://www.derekseaman.com/2023/04/home-assistant-installing-influxdb-lxc.html)
|
||||
|
||||
[Home Assistant: Proxmox Quick Start Guide](https://www.derekseaman.com/2023/10/home-assistant-proxmox-ve-8-0-quick-start-guide-2.html)
|
||||
|
||||
[Home Assistant: Installing Grafana (LXC) with Let’s Encrypt SSL](https://www.derekseaman.com/2023/04/home-assistant-installing-grafana-lxc.html)
|
||||
|
||||
[Proxmox: Plex LXC with Alder Lake Transcoding](https://www.derekseaman.com/2023/04/proxmox-plex-lxc-with-alder-lake-transcoding.html)
|
||||
|
||||
[How To Backup Home Assistant In Proxmox](https://smarthomescene.com/guides/how-to-backup-home-assistant-in-proxmox/)
|
||||
|
||||
[Running Frigate on Proxmox](https://www.homeautomationguy.io/blog/running-frigate-on-proxmox)
|
||||
|
||||
[Frigate VM on Proxmox with PCIe Coral TPU](https://www.derekseaman.com/2023/06/home-assistant-frigate-vm-on-proxmox-with-pcie-coral-tpu.html)
|
||||
|
||||
[Moving Home Assistant’s Database To MariaDB On Proxmox](https://smarthomescene.com/guides/moving-home-assistants-database-to-mariadb-on-proxmox/)
|
||||
|
||||
[How-to: Proxmox VE 7.4 to 8.0 Upgrade](https://www.derekseaman.com/2023/06/how-to-proxmox-7-4-to-8-0-upgrade.html)
|
||||
|
||||
[iGPU Transcoding In Proxmox with Jellyfin](https://www.youtube.com/watch?v=XAa_qpNmzZs)
|
||||
|
||||
[Proxmox + NetData](<https://dbt3ch.com/books/proxmox-netdata-for-better-insights-and-notifications/page/proxmox-netdata-for-better-insights-and-notifications>)
|
||||
|
||||
[Proxmox Homelab Series](<https://blog.kye.dev/proxmox-series>)
|
||||
|
||||
[The fastest installation of Docker and Portainer on Proxmox VE](https://lavr.site/en-fastest-install-docker-portainer-proxmox/)
|
||||
|
||||
[How To Setup Proxmox Backuper Server Using Helper Scripts](<https://youtu.be/6C2JOsrZZZw?si=kkrrcL_nLCDBJkOB>)
|
||||
@@ -1,647 +0,0 @@
|
||||
# 🛠️ **Application Installation Scripts (install/AppName-install.sh)**
|
||||
|
||||
**Modern Guide to Writing In-Container Installation Scripts**
|
||||
|
||||
> **Updated**: December 2025
|
||||
> **Context**: Integrated with tools.func, error_handler.func, and install.func
|
||||
> **Examples Used**: `/install/pihole-install.sh`, `/install/mealie-install.sh`
|
||||
|
||||
---
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Execution Context](#execution-context)
|
||||
- [File Structure](#file-structure)
|
||||
- [Complete Script Template](#complete-script-template)
|
||||
- [Installation Phases](#installation-phases)
|
||||
- [Function Reference](#function-reference)
|
||||
- [Best Practices](#best-practices)
|
||||
- [Real Examples](#real-examples)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Contribution Checklist](#contribution-checklist)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
### Purpose
|
||||
|
||||
Installation scripts (`install/AppName-install.sh`) **run inside the LXC container** and are responsible for:
|
||||
|
||||
1. Setting up the container OS (updates, packages)
|
||||
2. Installing application dependencies
|
||||
3. Downloading and configuring the application
|
||||
4. Setting up services and systemd units
|
||||
5. Creating version tracking files for updates
|
||||
6. Generating credentials/configurations
|
||||
7. Final cleanup and validation
|
||||
|
||||
### Execution Flow
|
||||
|
||||
```
|
||||
ct/AppName.sh (Proxmox Host)
|
||||
↓
|
||||
build_container()
|
||||
↓
|
||||
pct exec CTID bash -c "$(cat install/AppName-install.sh)"
|
||||
↓
|
||||
install/AppName-install.sh (Inside Container)
|
||||
↓
|
||||
Container Ready with App Installed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Execution Context
|
||||
|
||||
### Environment Variables Available
|
||||
|
||||
```bash
|
||||
# From Proxmox/Container
|
||||
CTID # Container ID (100, 101, etc.)
|
||||
PCT_OSTYPE # OS type (alpine, debian, ubuntu)
|
||||
HOSTNAME # Container hostname
|
||||
|
||||
# From build.func
|
||||
FUNCTIONS_FILE_PATH # Bash functions library (core.func + tools.func)
|
||||
VERBOSE # Verbose mode (yes/no)
|
||||
STD # Standard redirection variable (silent/empty)
|
||||
|
||||
# From install.func
|
||||
APP # Application name
|
||||
NSAPP # Normalized app name (lowercase, no spaces)
|
||||
METHOD # Installation method (ct/install)
|
||||
RANDOM_UUID # Session UUID for telemetry
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
### Minimal install/AppName-install.sh Template
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash # [1] Shebang
|
||||
|
||||
# [2] Copyright/Metadata
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: YourUsername
|
||||
# License: MIT
|
||||
# Source: https://example.com
|
||||
|
||||
# [3] Load functions
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
color
|
||||
verb_ip6
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
# [4] Installation steps
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt-get install -y package1 package2
|
||||
msg_ok "Installed Dependencies"
|
||||
|
||||
# [5] Final setup
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Script Template
|
||||
|
||||
### Phase 1: Header & Initialization
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) 2021-2026 community-scripts ORG
|
||||
# Author: YourUsername
|
||||
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
|
||||
# Source: https://github.com/application/repo
|
||||
|
||||
# Load all available functions (from core.func + tools.func)
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
# Initialize environment
|
||||
color # Setup ANSI colors and icons
|
||||
verb_ip6 # Configure IPv6 (if needed)
|
||||
catch_errors # Setup error traps
|
||||
setting_up_container # Verify OS is ready
|
||||
network_check # Verify internet connectivity
|
||||
update_os # Update packages (apk/apt)
|
||||
```
|
||||
|
||||
### Phase 2: Dependency Installation
|
||||
|
||||
```bash
|
||||
msg_info "Installing Dependencies"
|
||||
$STD apt-get install -y \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
nano \
|
||||
build-essential \
|
||||
libssl-dev \
|
||||
python3-dev
|
||||
msg_ok "Installed Dependencies"
|
||||
```
|
||||
|
||||
### Phase 3: Tool Setup (Using tools.func)
|
||||
|
||||
```bash
|
||||
# Setup specific tool versions
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
PHP_VERSION="8.4" setup_php
|
||||
PYTHON_VERSION="3.12" setup_uv
|
||||
```
|
||||
|
||||
### Phase 4: Application Download & Setup
|
||||
|
||||
```bash
|
||||
# Download from GitHub
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \
|
||||
grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
|
||||
|
||||
wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app-${RELEASE}.tar.gz"
|
||||
cd /opt
|
||||
tar -xzf app-${RELEASE}.tar.gz
|
||||
rm -f app-${RELEASE}.tar.gz
|
||||
```
|
||||
|
||||
### Phase 5: Configuration Files
|
||||
|
||||
```bash
|
||||
# Using cat << EOF (multiline)
|
||||
cat <<'EOF' >/etc/nginx/sites-available/appname
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /opt/appname/public;
|
||||
index index.php index.html;
|
||||
}
|
||||
EOF
|
||||
|
||||
# Using sed for replacements
|
||||
sed -i -e "s|^DB_HOST=.*|DB_HOST=localhost|" \
|
||||
-e "s|^DB_USER=.*|DB_USER=appuser|" \
|
||||
/opt/appname/.env
|
||||
```
|
||||
|
||||
### Phase 6: Database Setup (If Needed)
|
||||
|
||||
```bash
|
||||
msg_info "Setting up Database"
|
||||
|
||||
DB_NAME="appname_db"
|
||||
DB_USER="appuser"
|
||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
|
||||
# For MySQL/MariaDB
|
||||
mysql -u root <<EOF
|
||||
CREATE DATABASE ${DB_NAME};
|
||||
CREATE USER '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
|
||||
GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
msg_ok "Database setup complete"
|
||||
```
|
||||
|
||||
### Phase 7: Permission & Ownership
|
||||
|
||||
```bash
|
||||
msg_info "Setting permissions"
|
||||
|
||||
# Web applications typically run as www-data
|
||||
chown -R www-data:www-data /opt/appname
|
||||
chmod -R 755 /opt/appname
|
||||
chmod -R 644 /opt/appname/*
|
||||
chmod 755 /opt/appname/*/.*
|
||||
|
||||
msg_ok "Permissions set"
|
||||
```
|
||||
|
||||
### Phase 8: Service Configuration
|
||||
|
||||
```bash
|
||||
# Enable systemd service
|
||||
systemctl enable -q --now appname
|
||||
|
||||
# Or for OpenRC (Alpine)
|
||||
rc-service appname start
|
||||
rc-update add appname default
|
||||
|
||||
# Verify service is running
|
||||
if systemctl is-active --quiet appname; then
|
||||
msg_ok "Service running successfully"
|
||||
else
|
||||
msg_error "Service failed to start"
|
||||
journalctl -u appname -n 20
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
### Phase 9: Version Tracking
|
||||
|
||||
```bash
|
||||
# Essential for update detection
|
||||
echo "${RELEASE}" > /opt/${APP}_version.txt
|
||||
|
||||
# Or with additional metadata
|
||||
cat > /opt/${APP}_version.txt <<EOF
|
||||
Version: ${RELEASE}
|
||||
InstallDate: $(date)
|
||||
InstallMethod: ${METHOD}
|
||||
EOF
|
||||
```
|
||||
|
||||
### Phase 10: Final Setup & Cleanup
|
||||
|
||||
```bash
|
||||
# Display MOTD and enable autologin
|
||||
motd_ssh
|
||||
|
||||
# Final customization
|
||||
customize
|
||||
|
||||
# Clean up package manager cache
|
||||
msg_info "Cleaning up"
|
||||
apt-get -y autoremove
|
||||
apt-get -y autoclean
|
||||
msg_ok "Cleaned"
|
||||
|
||||
# Or for Alpine
|
||||
apk cache clean
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
# System cleanup
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Installation Phases
|
||||
|
||||
### Phase 1: Container OS Setup
|
||||
- Network interface brought up and configured
|
||||
- Internet connectivity verified
|
||||
- Package lists updated
|
||||
- All OS packages upgraded to latest versions
|
||||
|
||||
### Phase 2: Base Dependencies
|
||||
```bash
|
||||
msg_info "Installing Base Dependencies"
|
||||
$STD apt-get install -y \
|
||||
curl wget git nano build-essential
|
||||
msg_ok "Installed Base Dependencies"
|
||||
```
|
||||
|
||||
### Phase 3: Tool Installation
|
||||
```bash
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
PHP_VERSION="8.4" setup_php
|
||||
```
|
||||
|
||||
### Phase 4: Application Setup
|
||||
```bash
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \
|
||||
grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
|
||||
wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app.tar.gz"
|
||||
```
|
||||
|
||||
### Phase 5: Configuration
|
||||
Application-specific configuration files and environment setup
|
||||
|
||||
### Phase 6: Service Registration
|
||||
Enable and verify systemd services are running
|
||||
|
||||
---
|
||||
|
||||
## Function Reference
|
||||
|
||||
### Core Messaging Functions
|
||||
|
||||
#### `msg_info(message)`
|
||||
|
||||
Displays an info message with spinner animation
|
||||
|
||||
```bash
|
||||
msg_info "Installing application"
|
||||
# Output: ⏳ Installing application (with spinning animation)
|
||||
```
|
||||
|
||||
#### `msg_ok(message)`
|
||||
|
||||
Displays success message with checkmark
|
||||
|
||||
```bash
|
||||
msg_ok "Installation completed"
|
||||
# Output: ✔️ Installation completed
|
||||
```
|
||||
|
||||
#### `msg_error(message)`
|
||||
|
||||
Displays error message and exits
|
||||
|
||||
```bash
|
||||
msg_error "Installation failed"
|
||||
# Output: ✖️ Installation failed
|
||||
```
|
||||
|
||||
### Package Management
|
||||
|
||||
#### `$STD` Variable
|
||||
|
||||
Controls output verbosity
|
||||
|
||||
```bash
|
||||
# Silent mode (respects VERBOSE setting)
|
||||
$STD apt-get install -y nginx
|
||||
```
|
||||
|
||||
#### `update_os()`
|
||||
|
||||
Updates OS packages
|
||||
|
||||
```bash
|
||||
update_os
|
||||
# Runs: apt update && apt upgrade
|
||||
```
|
||||
|
||||
### Tool Installation Functions
|
||||
|
||||
#### `setup_nodejs()`
|
||||
|
||||
Installs Node.js with optional global modules
|
||||
|
||||
```bash
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
NODE_VERSION="22" NODE_MODULE="yarn,@vue/cli" setup_nodejs
|
||||
```
|
||||
|
||||
#### `setup_php()`
|
||||
|
||||
Installs PHP with optional extensions
|
||||
|
||||
```bash
|
||||
PHP_VERSION="8.4" PHP_MODULE="bcmath,curl,gd,intl,redis" setup_php
|
||||
```
|
||||
|
||||
#### Other Tools
|
||||
|
||||
```bash
|
||||
setup_mariadb # MariaDB database
|
||||
setup_mysql # MySQL database
|
||||
setup_postgresql # PostgreSQL
|
||||
setup_docker # Docker Engine
|
||||
setup_composer # PHP Composer
|
||||
setup_python # Python 3
|
||||
setup_ruby # Ruby
|
||||
setup_rust # Rust
|
||||
```
|
||||
|
||||
### Cleanup Functions
|
||||
|
||||
#### `cleanup_lxc()`
|
||||
|
||||
Comprehensive container cleanup
|
||||
|
||||
- Removes package manager caches
|
||||
- Cleans temporary files
|
||||
- Clears language package caches
|
||||
- Removes systemd journal logs
|
||||
|
||||
```bash
|
||||
cleanup_lxc
|
||||
# Output: ⏳ Cleaning up
|
||||
# ✔️ Cleaned
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO:
|
||||
|
||||
1. **Always Use $STD for Commands**
|
||||
```bash
|
||||
# ✅ Good: Respects VERBOSE setting
|
||||
$STD apt-get install -y nginx
|
||||
```
|
||||
|
||||
2. **Generate Random Passwords Safely**
|
||||
```bash
|
||||
# ✅ Good: Alphanumeric only
|
||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
```
|
||||
|
||||
3. **Check Command Success**
|
||||
```bash
|
||||
# ✅ Good: Verify success
|
||||
if ! wget -q "https://example.com/file.tar.gz"; then
|
||||
msg_error "Download failed"
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
|
||||
4. **Set Proper Permissions**
|
||||
```bash
|
||||
# ✅ Good: Explicit permissions
|
||||
chown -R www-data:www-data /opt/appname
|
||||
chmod -R 755 /opt/appname
|
||||
```
|
||||
|
||||
5. **Save Version for Update Checks**
|
||||
```bash
|
||||
# ✅ Good: Version tracked
|
||||
echo "${RELEASE}" > /opt/${APP}_version.txt
|
||||
```
|
||||
|
||||
6. **Handle Alpine vs Debian Differences**
|
||||
```bash
|
||||
# ✅ Good: Detect OS
|
||||
if grep -qi 'alpine' /etc/os-release; then
|
||||
apk add package
|
||||
else
|
||||
apt-get install -y package
|
||||
fi
|
||||
```
|
||||
|
||||
### ❌ DON'T:
|
||||
|
||||
1. **Hardcode Versions**
|
||||
```bash
|
||||
# ❌ Bad: Won't auto-update
|
||||
wget https://example.com/app-1.2.3.tar.gz
|
||||
```
|
||||
|
||||
2. **Use Root Without Password**
|
||||
```bash
|
||||
# ❌ Bad: Security risk
|
||||
mysql -u root
|
||||
```
|
||||
|
||||
3. **Forget Error Handling**
|
||||
```bash
|
||||
# ❌ Bad: Silent failures
|
||||
wget https://example.com/file
|
||||
tar -xzf file
|
||||
```
|
||||
|
||||
4. **Leave Temporary Files**
|
||||
```bash
|
||||
# ✅ Always cleanup
|
||||
rm -rf /opt/app-${RELEASE}.tar.gz
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Real Examples
|
||||
|
||||
### Example 1: Node.js Application
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
color
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
msg_info "Installing Node.js"
|
||||
NODE_VERSION="22" setup_nodejs
|
||||
msg_ok "Node.js installed"
|
||||
|
||||
msg_info "Installing Application"
|
||||
cd /opt
|
||||
RELEASE=$(curl -fsSL https://api.github.com/repos/user/repo/releases/latest | \
|
||||
grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')
|
||||
wget -q "https://github.com/user/repo/releases/download/v${RELEASE}/app.tar.gz"
|
||||
tar -xzf app.tar.gz
|
||||
echo "${RELEASE}" > /opt/app_version.txt
|
||||
msg_ok "Application installed"
|
||||
|
||||
systemctl enable --now app
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
### Example 2: PHP Application with Database
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
color
|
||||
catch_errors
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
|
||||
PHP_VERSION="8.4" PHP_MODULE="bcmath,curl,pdo_mysql" setup_php
|
||||
setup_mariadb # Uses distribution packages (recommended)
|
||||
# Or for specific version: MARIADB_VERSION="11.4" setup_mariadb
|
||||
|
||||
# Database setup
|
||||
DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)
|
||||
mysql -u root <<EOF
|
||||
CREATE DATABASE appdb;
|
||||
CREATE USER 'appuser'@'localhost' IDENTIFIED BY '${DB_PASS}';
|
||||
GRANT ALL ON appdb.* TO 'appuser'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
EOF
|
||||
|
||||
# App installation
|
||||
cd /opt
|
||||
wget -q https://github.com/user/repo/releases/latest/download/app.tar.gz
|
||||
tar -xzf app.tar.gz
|
||||
|
||||
# Configuration
|
||||
cat > /opt/app/.env <<EOF
|
||||
DB_HOST=localhost
|
||||
DB_NAME=appdb
|
||||
DB_USER=appuser
|
||||
DB_PASS=${DB_PASS}
|
||||
EOF
|
||||
|
||||
chown -R www-data:www-data /opt/app
|
||||
systemctl enable --now php-fpm
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Installation Hangs
|
||||
|
||||
**Check internet connectivity**:
|
||||
```bash
|
||||
ping -c 1 8.8.8.8
|
||||
```
|
||||
|
||||
**Enable verbose mode**:
|
||||
```bash
|
||||
# In ct/AppName.sh, before running
|
||||
VERBOSE="yes" bash install/AppName-install.sh
|
||||
```
|
||||
|
||||
### Package Not Found
|
||||
|
||||
**Update package lists**:
|
||||
```bash
|
||||
apt update
|
||||
apt-cache search package_name
|
||||
```
|
||||
|
||||
### Service Won't Start
|
||||
|
||||
**Check logs**:
|
||||
```bash
|
||||
journalctl -u appname -n 50
|
||||
systemctl status appname
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contribution Checklist
|
||||
|
||||
Before submitting a PR:
|
||||
|
||||
### Structure
|
||||
- [ ] Shebang is `#!/usr/bin/env bash`
|
||||
- [ ] Loads functions from `$FUNCTIONS_FILE_PATH`
|
||||
- [ ] Copyright header with author
|
||||
- [ ] Clear phase comments
|
||||
|
||||
### Installation
|
||||
- [ ] `setting_up_container` called early
|
||||
- [ ] `network_check` before downloads
|
||||
- [ ] `update_os` before package installation
|
||||
- [ ] All errors checked properly
|
||||
|
||||
### Functions
|
||||
- [ ] Uses `msg_info/msg_ok/msg_error` for status
|
||||
- [ ] Uses `$STD` for command output silencing
|
||||
- [ ] Version saved to `/opt/${APP}_version.txt`
|
||||
- [ ] Proper permissions set
|
||||
|
||||
### Cleanup
|
||||
- [ ] `motd_ssh` called for final setup
|
||||
- [ ] `customize` called for options
|
||||
- [ ] `cleanup_lxc` called at end
|
||||
|
||||
### Testing
|
||||
- [ ] Tested with default settings
|
||||
- [ ] Tested with advanced (19-step) mode
|
||||
- [ ] Service starts and runs correctly
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
**Compatibility**: ProxmoxVE with install.func v3+
|
||||
@@ -1,160 +0,0 @@
|
||||
# Installation Scripts Documentation (/install)
|
||||
|
||||
This directory contains comprehensive documentation for installation scripts in the `/install` directory.
|
||||
|
||||
## Overview
|
||||
|
||||
Installation scripts (`install/*.sh`) run inside LXC containers and handle application-specific setup, configuration, and deployment.
|
||||
|
||||
## Documentation Structure
|
||||
|
||||
Each installation script category has documentation following the project pattern.
|
||||
|
||||
## Key Resources
|
||||
|
||||
- **[DETAILED_GUIDE.md](DETAILED_GUIDE.md)** - Complete reference for creating install scripts
|
||||
- **[../contribution/README.md](../contribution/README.md)** - How to contribute
|
||||
- **[../misc/install.func/](../misc/install.func/)** - Installation workflow documentation
|
||||
- **[../misc/tools.func/](../misc/tools.func/)** - Package installation documentation
|
||||
|
||||
## Installation Script Flow
|
||||
|
||||
```
|
||||
install/appname-install.sh (container-side)
|
||||
│
|
||||
├─ Sources: $FUNCTIONS_FILE_PATH
|
||||
│ ├─ core.func (messaging)
|
||||
│ ├─ error_handler.func (error handling)
|
||||
│ ├─ install.func (setup)
|
||||
│ └─ tools.func (packages & tools)
|
||||
│
|
||||
├─ 10-Phase Installation:
|
||||
│ 1. OS Setup
|
||||
│ 2. Base Dependencies
|
||||
│ 3. Tool Setup
|
||||
│ 4. Application Download
|
||||
│ 5. Configuration
|
||||
│ 6. Database Setup
|
||||
│ 7. Permissions
|
||||
│ 8. Services
|
||||
│ 9. Version Tracking
|
||||
│ 10. Final Cleanup
|
||||
│
|
||||
└─ Result: Application ready
|
||||
```
|
||||
|
||||
## Available Installation Scripts
|
||||
|
||||
See `/install` directory for all installation scripts. Examples:
|
||||
|
||||
- `pihole-install.sh` - Pi-hole installation
|
||||
- `docker-install.sh` - Docker installation
|
||||
- `wallabag-install.sh` - Wallabag setup
|
||||
- `nextcloud-install.sh` - Nextcloud deployment
|
||||
- `debian-install.sh` - Base Debian setup
|
||||
- And 30+ more...
|
||||
|
||||
## Quick Start
|
||||
|
||||
To understand how to create an installation script:
|
||||
|
||||
1. Read: [UPDATED_APP-install.md](../UPDATED_APP-install.md)
|
||||
2. Study: A similar existing script in `/install`
|
||||
3. Copy template and customize
|
||||
4. Test in container
|
||||
5. Submit PR
|
||||
|
||||
## 10-Phase Installation Pattern
|
||||
|
||||
Every installation script follows this structure:
|
||||
|
||||
### Phase 1: OS Setup
|
||||
```bash
|
||||
setting_up_container
|
||||
network_check
|
||||
update_os
|
||||
```
|
||||
|
||||
### Phase 2: Base Dependencies
|
||||
```bash
|
||||
pkg_update
|
||||
pkg_install curl wget git
|
||||
```
|
||||
|
||||
### Phase 3: Tool Setup
|
||||
```bash
|
||||
setup_nodejs "20"
|
||||
setup_php "8.3"
|
||||
setup_mariadb # Uses distribution packages (recommended)
|
||||
# MARIADB_VERSION="11.4" setup_mariadb # For specific version
|
||||
```
|
||||
|
||||
### Phase 4: Application Download
|
||||
```bash
|
||||
git clone https://github.com/user/app /opt/app
|
||||
cd /opt/app
|
||||
```
|
||||
|
||||
### Phase 5: Configuration
|
||||
```bash
|
||||
# Create .env files, config files, etc.
|
||||
cat > .env <<EOF
|
||||
SETTING=value
|
||||
EOF
|
||||
```
|
||||
|
||||
### Phase 6: Database Setup
|
||||
```bash
|
||||
# Create databases, users, etc.
|
||||
mysql -e "CREATE DATABASE appdb"
|
||||
```
|
||||
|
||||
### Phase 7: Permissions
|
||||
```bash
|
||||
chown -R appuser:appgroup /opt/app
|
||||
chmod -R 755 /opt/app
|
||||
```
|
||||
|
||||
### Phase 8: Services
|
||||
```bash
|
||||
systemctl enable app
|
||||
systemctl start app
|
||||
```
|
||||
|
||||
### Phase 9: Version Tracking
|
||||
```bash
|
||||
echo "1.0.0" > /opt/app_version.txt
|
||||
```
|
||||
|
||||
### Phase 10: Final Cleanup
|
||||
```bash
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
## Contributing an Installation Script
|
||||
|
||||
1. Create `ct/myapp.sh` (host script)
|
||||
2. Create `install/myapp-install.sh` (container script)
|
||||
3. Follow 10-phase pattern in [UPDATED_APP-install.md](../UPDATED_APP-install.md)
|
||||
4. Test in actual container
|
||||
5. Submit PR with both files
|
||||
|
||||
## Common Tasks
|
||||
|
||||
- **Create new installation script** → [UPDATED_APP-install.md](../UPDATED_APP-install.md)
|
||||
- **Install Node.js/PHP/Database** → [misc/tools.func/](../misc/tools.func/)
|
||||
- **Setup Alpine container** → [misc/alpine-install.func/](../misc/alpine-install.func/)
|
||||
- **Debug installation errors** → [EXIT_CODES.md](../EXIT_CODES.md)
|
||||
- **Use dev mode** → [DEV_MODE.md](../DEV_MODE.md)
|
||||
|
||||
## Alpine vs Debian
|
||||
|
||||
- **Debian-based** → Use `tools.func`, `install.func`, `systemctl`
|
||||
- **Alpine-based** → Use `alpine-tools.func`, `alpine-install.func`, `rc-service`
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
**Maintainers**: community-scripts team
|
||||
@@ -1,283 +0,0 @@
|
||||
# Misc Documentation
|
||||
|
||||
This directory contains comprehensive documentation for all function libraries and components of the Proxmox Community Scripts project. Each section is organized as a dedicated subdirectory with detailed references, examples, and integration guides.
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ **Core Function Libraries**
|
||||
|
||||
### 📁 [build.func/](./build.func/)
|
||||
**Core LXC Container Orchestration** - Main orchestrator for Proxmox LXC container creation
|
||||
|
||||
**Contents:**
|
||||
- BUILD_FUNC_FLOWCHART.md - Visual execution flows and decision trees
|
||||
- BUILD_FUNC_ARCHITECTURE.md - System architecture and design
|
||||
- BUILD_FUNC_ENVIRONMENT_VARIABLES.md - Complete environment variable reference
|
||||
- BUILD_FUNC_FUNCTIONS_REFERENCE.md - Alphabetical function reference
|
||||
- BUILD_FUNC_EXECUTION_FLOWS.md - Detailed execution flows
|
||||
- BUILD_FUNC_USAGE_EXAMPLES.md - Practical usage examples
|
||||
- README.md - Overview and quick reference
|
||||
|
||||
**Key Functions**: `variables()`, `start()`, `build_container()`, `build_defaults()`, `advanced_settings()`
|
||||
|
||||
---
|
||||
|
||||
### 📁 [core.func/](./core.func/)
|
||||
**System Utilities & Foundation** - Essential utility functions and system checks
|
||||
|
||||
**Contents:**
|
||||
- CORE_FLOWCHART.md - Visual execution flows
|
||||
- CORE_FUNCTIONS_REFERENCE.md - Complete function reference
|
||||
- CORE_INTEGRATION.md - Integration points
|
||||
- CORE_USAGE_EXAMPLES.md - Practical examples
|
||||
- README.md - Overview and quick reference
|
||||
|
||||
**Key Functions**: `color()`, `msg_info()`, `msg_ok()`, `msg_error()`, `root_check()`, `pve_check()`, `parse_dev_mode()`
|
||||
|
||||
---
|
||||
|
||||
### 📁 [error_handler.func/](./error_handler.func/)
|
||||
**Error Handling & Signal Management** - Comprehensive error handling and signal trapping
|
||||
|
||||
**Contents:**
|
||||
- ERROR_HANDLER_FLOWCHART.md - Visual error handling flows
|
||||
- ERROR_HANDLER_FUNCTIONS_REFERENCE.md - Function reference
|
||||
- ERROR_HANDLER_INTEGRATION.md - Integration with other components
|
||||
- ERROR_HANDLER_USAGE_EXAMPLES.md - Practical examples
|
||||
- README.md - Overview and quick reference
|
||||
|
||||
**Key Functions**: `catch_errors()`, `error_handler()`, `explain_exit_code()`, `signal_handler()`
|
||||
|
||||
---
|
||||
|
||||
### 📁 [api.func/](./api.func/)
|
||||
**Proxmox API Integration** - API communication and diagnostic reporting
|
||||
|
||||
**Contents:**
|
||||
- API_FLOWCHART.md - API communication flows
|
||||
- API_FUNCTIONS_REFERENCE.md - Function reference
|
||||
- API_INTEGRATION.md - Integration points
|
||||
- API_USAGE_EXAMPLES.md - Practical examples
|
||||
- README.md - Overview and quick reference
|
||||
|
||||
**Key Functions**: `post_to_api()`, `post_update_to_api()`, `get_error_description()`
|
||||
|
||||
---
|
||||
|
||||
## 📦 **Installation & Setup Function Libraries**
|
||||
|
||||
### 📁 [install.func/](./install.func/)
|
||||
**Container Installation Workflow** - Installation orchestration for container-internal setup
|
||||
|
||||
**Contents:**
|
||||
- INSTALL_FUNC_FLOWCHART.md - Installation workflow diagrams
|
||||
- INSTALL_FUNC_FUNCTIONS_REFERENCE.md - Complete function reference
|
||||
- INSTALL_FUNC_INTEGRATION.md - Integration with build and tools
|
||||
- INSTALL_FUNC_USAGE_EXAMPLES.md - Practical examples
|
||||
- README.md - Overview and quick reference
|
||||
|
||||
**Key Functions**: `setting_up_container()`, `network_check()`, `update_os()`, `motd_ssh()`, `cleanup_lxc()`
|
||||
|
||||
---
|
||||
|
||||
### 📁 [tools.func/](./tools.func/)
|
||||
**Package & Tool Installation** - Robust package management and 30+ tool installation functions
|
||||
|
||||
**Contents:**
|
||||
- TOOLS_FUNC_FLOWCHART.md - Package management flows
|
||||
- TOOLS_FUNC_FUNCTIONS_REFERENCE.md - 30+ function reference
|
||||
- TOOLS_FUNC_INTEGRATION.md - Integration with install workflows
|
||||
- TOOLS_FUNC_USAGE_EXAMPLES.md - Practical examples
|
||||
- TOOLS_FUNC_ENVIRONMENT_VARIABLES.md - Configuration reference
|
||||
- README.md - Overview and quick reference
|
||||
|
||||
**Key Functions**: `setup_nodejs()`, `setup_php()`, `setup_mariadb()`, `setup_docker()`, `setup_deb822_repo()`, `pkg_install()`, `pkg_update()`
|
||||
|
||||
---
|
||||
|
||||
### 📁 [alpine-install.func/](./alpine-install.func/)
|
||||
**Alpine Container Setup** - Alpine Linux-specific installation functions
|
||||
|
||||
**Contents:**
|
||||
- ALPINE_INSTALL_FUNC_FLOWCHART.md - Alpine setup flows
|
||||
- ALPINE_INSTALL_FUNC_FUNCTIONS_REFERENCE.md - Function reference
|
||||
- ALPINE_INSTALL_FUNC_INTEGRATION.md - Integration points
|
||||
- ALPINE_INSTALL_FUNC_USAGE_EXAMPLES.md - Practical examples
|
||||
- README.md - Overview and quick reference
|
||||
|
||||
**Key Functions**: `update_os()` (apk version), `verb_ip6()`, `motd_ssh()` (Alpine), `customize()`
|
||||
|
||||
---
|
||||
|
||||
### 📁 [alpine-tools.func/](./alpine-tools.func/)
|
||||
**Alpine Tool Installation** - Alpine-specific package and tool installation
|
||||
|
||||
**Contents:**
|
||||
- ALPINE_TOOLS_FUNC_FLOWCHART.md - Alpine package flows
|
||||
- ALPINE_TOOLS_FUNC_FUNCTIONS_REFERENCE.md - Function reference
|
||||
- ALPINE_TOOLS_FUNC_INTEGRATION.md - Integration with Alpine workflows
|
||||
- ALPINE_TOOLS_FUNC_USAGE_EXAMPLES.md - Practical examples
|
||||
- README.md - Overview and quick reference
|
||||
|
||||
**Key Functions**: `apk_add()`, `apk_update()`, `apk_del()`, `add_community_repo()`, Alpine tool setup functions
|
||||
|
||||
---
|
||||
|
||||
### 📁 [cloud-init.func/](./cloud-init.func/)
|
||||
**VM Cloud-Init Configuration** - Cloud-init and VM provisioning functions
|
||||
|
||||
**Contents:**
|
||||
- CLOUD_INIT_FUNC_FLOWCHART.md - Cloud-init flows
|
||||
- CLOUD_INIT_FUNC_FUNCTIONS_REFERENCE.md - Function reference
|
||||
- CLOUD_INIT_FUNC_INTEGRATION.md - Integration points
|
||||
- CLOUD_INIT_FUNC_USAGE_EXAMPLES.md - Practical examples
|
||||
- README.md - Overview and quick reference
|
||||
|
||||
**Key Functions**: `generate_cloud_init()`, `generate_user_data()`, `setup_ssh_keys()`, `setup_static_ip()`
|
||||
|
||||
---
|
||||
|
||||
## 🔗 **Function Library Relationships**
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Container Creation Flow │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ct/AppName.sh │
|
||||
│ ↓ (sources) │
|
||||
│ build.func │
|
||||
│ ├─ variables() │
|
||||
│ ├─ build_container() │
|
||||
│ └─ advanced_settings() │
|
||||
│ ↓ (calls pct create with) │
|
||||
│ install/appname-install.sh │
|
||||
│ ↓ (sources) │
|
||||
│ ├─ core.func (colors, messaging) │
|
||||
│ ├─ error_handler.func (error trapping) │
|
||||
│ ├─ install.func (setup/network) │
|
||||
│ └─ tools.func (packages/tools) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Alpine Container Flow │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ install/appname-install.sh (Alpine) │
|
||||
│ ↓ (sources) │
|
||||
│ ├─ core.func (colors) │
|
||||
│ ├─ error_handler.func (errors) │
|
||||
│ ├─ alpine-install.func (apk setup) │
|
||||
│ └─ alpine-tools.func (apk tools) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ VM Provisioning Flow │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ vm/OsName-vm.sh │
|
||||
│ ↓ (uses) │
|
||||
│ cloud-init.func │
|
||||
│ ├─ generate_cloud_init() │
|
||||
│ ├─ setup_ssh_keys() │
|
||||
│ └─ configure_network() │
|
||||
│ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 **Documentation Quick Stats**
|
||||
|
||||
| Library | Files | Functions | Status |
|
||||
|---------|:---:|:---:|:---:|
|
||||
| build.func | 7 | 50+ | ✅ Complete |
|
||||
| core.func | 5 | 20+ | ✅ Complete |
|
||||
| error_handler.func | 5 | 10+ | ✅ Complete |
|
||||
| api.func | 5 | 5+ | ✅ Complete |
|
||||
| install.func | 5 | 8+ | ✅ Complete |
|
||||
| tools.func | 6 | 30+ | ✅ Complete |
|
||||
| alpine-install.func | 5 | 6+ | ✅ Complete |
|
||||
| alpine-tools.func | 5 | 15+ | ✅ Complete |
|
||||
| cloud-init.func | 5 | 12+ | ✅ Complete |
|
||||
|
||||
**Total**: 9 function libraries, 48 documentation files, 150+ functions
|
||||
|
||||
---
|
||||
|
||||
## 🚀 **Getting Started**
|
||||
|
||||
### For Container Creation Scripts
|
||||
Start with: **[build.func/](./build.func/)** → **[tools.func/](./tools.func/)** → **[install.func/](./install.func/)**
|
||||
|
||||
### For Alpine Containers
|
||||
Start with: **[alpine-install.func/](./alpine-install.func/)** → **[alpine-tools.func/](./alpine-tools.func/)**
|
||||
|
||||
### For VM Provisioning
|
||||
Start with: **[cloud-init.func/](./cloud-init.func/)**
|
||||
|
||||
### For Troubleshooting
|
||||
Start with: **[error_handler.func/](./error_handler.func/)** → **[EXIT_CODES.md](../EXIT_CODES.md)**
|
||||
|
||||
---
|
||||
|
||||
## 📚 **Related Top-Level Documentation**
|
||||
|
||||
- **[CONTRIBUTION_GUIDE.md](../CONTRIBUTION_GUIDE.md)** - How to contribute to ProxmoxVE
|
||||
- **[UPDATED_APP-ct.md](../UPDATED_APP-ct.md)** - Container script guide
|
||||
- **[UPDATED_APP-install.md](../UPDATED_APP-install.md)** - Installation script guide
|
||||
- **[DEFAULTS_SYSTEM_GUIDE.md](../DEFAULTS_SYSTEM_GUIDE.md)** - Configuration system
|
||||
- **[TECHNICAL_REFERENCE.md](../TECHNICAL_REFERENCE.md)** - Architecture reference
|
||||
- **[EXIT_CODES.md](../EXIT_CODES.md)** - Complete exit code reference
|
||||
- **[DEV_MODE.md](../DEV_MODE.md)** - Development debugging modes
|
||||
- **[CHANGELOG_MISC.md](../CHANGELOG_MISC.md)** - Change history
|
||||
|
||||
---
|
||||
|
||||
## 🔄 **Standardized Documentation Structure**
|
||||
|
||||
Each function library follows the same documentation pattern:
|
||||
|
||||
```
|
||||
function-library/
|
||||
├── README.md # Quick reference & overview
|
||||
├── FUNCTION_LIBRARY_FLOWCHART.md # Visual execution flows
|
||||
├── FUNCTION_LIBRARY_FUNCTIONS_REFERENCE.md # Alphabetical reference
|
||||
├── FUNCTION_LIBRARY_INTEGRATION.md # Integration points
|
||||
├── FUNCTION_LIBRARY_USAGE_EXAMPLES.md # Practical examples
|
||||
└── [FUNCTION_LIBRARY_ENVIRONMENT_VARIABLES.md] # (if applicable)
|
||||
```
|
||||
|
||||
**Advantages**:
|
||||
- ✅ Consistent navigation across all libraries
|
||||
- ✅ Quick reference sections in each README
|
||||
- ✅ Visual flowcharts for understanding
|
||||
- ✅ Complete function references
|
||||
- ✅ Real-world usage examples
|
||||
- ✅ Integration guides for connecting libraries
|
||||
|
||||
---
|
||||
|
||||
## 📝 **Documentation Standards**
|
||||
|
||||
All documentation follows these standards:
|
||||
|
||||
1. **README.md** - Quick overview, key features, quick reference
|
||||
2. **FLOWCHART.md** - ASCII flowcharts and visual diagrams
|
||||
3. **FUNCTIONS_REFERENCE.md** - Every function with full details
|
||||
4. **INTEGRATION.md** - How this library connects to others
|
||||
5. **USAGE_EXAMPLES.md** - Copy-paste ready examples
|
||||
6. **ENVIRONMENT_VARIABLES.md** - (if applicable) Configuration reference
|
||||
|
||||
---
|
||||
|
||||
## ✅ **Last Updated**: December 2025
|
||||
**Maintainers**: community-scripts team
|
||||
**License**: MIT
|
||||
**Status**: All 9 libraries fully documented and standardized
|
||||
|
||||
---
|
||||
|
||||
*This directory contains specialized documentation for specific components of the Proxmox Community Scripts project.*
|
||||
@@ -1,29 +0,0 @@
|
||||
# alpine-install.func Flowchart
|
||||
|
||||
Alpine container initialization flow (apk-based, OpenRC init system).
|
||||
|
||||
## Alpine Container Setup Flow
|
||||
|
||||
```
|
||||
Alpine Container Started
|
||||
↓
|
||||
setting_up_container()
|
||||
↓
|
||||
verb_ip6() [optional - IPv6]
|
||||
↓
|
||||
update_os() [apk update/upgrade]
|
||||
↓
|
||||
network_check()
|
||||
↓
|
||||
Application Installation
|
||||
↓
|
||||
motd_ssh()
|
||||
↓
|
||||
customize()
|
||||
↓
|
||||
cleanup_lxc()
|
||||
↓
|
||||
Complete ✓
|
||||
```
|
||||
|
||||
**Last Updated**: December 2025
|
||||
@@ -1,30 +0,0 @@
|
||||
# alpine-install.func Functions Reference
|
||||
|
||||
Alpine Linux-specific installation functions (apk-based, OpenRC).
|
||||
|
||||
## Core Functions
|
||||
|
||||
### setting_up_container()
|
||||
Initialize Alpine container setup.
|
||||
|
||||
### update_os()
|
||||
Update Alpine packages via `apk update && apk upgrade`.
|
||||
|
||||
### verb_ip6()
|
||||
Enable IPv6 on Alpine with persistent configuration.
|
||||
|
||||
### network_check()
|
||||
Verify network connectivity in Alpine.
|
||||
|
||||
### motd_ssh()
|
||||
Configure SSH daemon and MOTD on Alpine.
|
||||
|
||||
### customize()
|
||||
Apply Alpine-specific customizations.
|
||||
|
||||
### cleanup_lxc()
|
||||
Final cleanup (Alpine-specific).
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
@@ -1,14 +0,0 @@
|
||||
# alpine-install.func Integration Guide
|
||||
|
||||
Integration of alpine-install.func with Alpine container workflows.
|
||||
|
||||
## Alpine-Specific Integration
|
||||
|
||||
Alpine containers use:
|
||||
- `apk` instead of `apt-get`
|
||||
- `OpenRC` instead of `systemd`
|
||||
- Alpine-specific package names
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
@@ -1,24 +0,0 @@
|
||||
# alpine-install.func Usage Examples
|
||||
|
||||
Basic examples for Alpine container installation.
|
||||
|
||||
### Example: Basic Alpine Setup
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
setting_up_container
|
||||
update_os
|
||||
|
||||
# Install Alpine packages
|
||||
apk add --no-cache curl wget git
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
@@ -1,273 +0,0 @@
|
||||
# alpine-install.func Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The `alpine-install.func` file provides Alpine Linux-specific installation and configuration functions for LXC containers. It complements the standard `install.func` with Alpine-specific operations using the apk package manager instead of apt.
|
||||
|
||||
## Purpose and Use Cases
|
||||
|
||||
- **Alpine Container Setup**: Initialize Alpine Linux containers with proper configuration
|
||||
- **IPv6 Management**: Enable or disable IPv6 in Alpine with persistent configuration
|
||||
- **Network Verification**: Verify connectivity in Alpine environments
|
||||
- **SSH Configuration**: Setup SSH daemon on Alpine
|
||||
- **Auto-Login Setup**: Configure passwordless root login for Alpine containers
|
||||
- **Package Management**: Safe apk operations with error handling
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Key Function Groups
|
||||
- **Initialization**: `setting_up_container()` - Alpine setup message
|
||||
- **Network**: `verb_ip6()`, `network_check()` - IPv6 and connectivity
|
||||
- **OS Configuration**: `update_os()` - Alpine package updates
|
||||
- **SSH/MOTD**: `motd_ssh()` - SSH and login message setup
|
||||
- **Container Customization**: `customize()`, `cleanup_lxc()` - Final setup
|
||||
|
||||
### Dependencies
|
||||
- **External**: `apk`, `curl`, `wget`, `ping`
|
||||
- **Internal**: Uses functions from `core.func`, `error_handler.func`
|
||||
|
||||
### Integration Points
|
||||
- Used by: Alpine-based install scripts (alpine.sh, alpine-ntfy.sh, etc.)
|
||||
- Uses: Environment variables from build.func
|
||||
- Provides: Alpine-specific installation and management services
|
||||
|
||||
## Documentation Files
|
||||
|
||||
### 📊 [ALPINE_INSTALL_FUNC_FLOWCHART.md](./ALPINE_INSTALL_FUNC_FLOWCHART.md)
|
||||
Visual execution flows showing Alpine container initialization and setup workflows.
|
||||
|
||||
### 📚 [ALPINE_INSTALL_FUNC_FUNCTIONS_REFERENCE.md](./ALPINE_INSTALL_FUNC_FUNCTIONS_REFERENCE.md)
|
||||
Complete alphabetical reference of all functions with parameters and usage details.
|
||||
|
||||
### 💡 [ALPINE_INSTALL_FUNC_USAGE_EXAMPLES.md](./ALPINE_INSTALL_FUNC_USAGE_EXAMPLES.md)
|
||||
Practical examples showing how to use Alpine installation functions.
|
||||
|
||||
### 🔗 [ALPINE_INSTALL_FUNC_INTEGRATION.md](./ALPINE_INSTALL_FUNC_INTEGRATION.md)
|
||||
How alpine-install.func integrates with standard install workflows.
|
||||
|
||||
## Key Features
|
||||
|
||||
### Alpine-Specific Functions
|
||||
- **apk Package Manager**: Alpine package operations (instead of apt-get)
|
||||
- **OpenRC Support**: Alpine uses OpenRC init instead of systemd
|
||||
- **Lightweight Setup**: Minimal dependencies appropriate for Alpine
|
||||
- **IPv6 Configuration**: Persistent IPv6 settings via `/etc/network/interfaces`
|
||||
|
||||
### Network & Connectivity
|
||||
- **IPv6 Toggle**: Enable/disable with persistent configuration
|
||||
- **Connectivity Check**: Verify internet access in Alpine
|
||||
- **DNS Verification**: Resolve domain names correctly
|
||||
- **Retry Logic**: Automatic recovery from transient failures
|
||||
|
||||
### SSH & Auto-Login
|
||||
- **SSH Daemon**: Setup and start sshd on Alpine
|
||||
- **Root Keys**: Configure root SSH access
|
||||
- **Auto-Login**: Optional automatic login without password
|
||||
- **MOTD**: Custom login message on Alpine
|
||||
|
||||
## Function Categories
|
||||
|
||||
### 🔹 Core Functions
|
||||
- `setting_up_container()` - Alpine container setup message
|
||||
- `update_os()` - Update Alpine packages via apk
|
||||
- `verb_ip6()` - Enable/disable IPv6 persistently
|
||||
- `network_check()` - Verify network connectivity
|
||||
|
||||
### 🔹 SSH & Configuration Functions
|
||||
- `motd_ssh()` - Configure SSH daemon on Alpine
|
||||
- `customize()` - Apply Alpine-specific customizations
|
||||
- `cleanup_lxc()` - Final cleanup
|
||||
|
||||
### 🔹 Service Management (OpenRC)
|
||||
- `rc-update` - Enable/disable services for Alpine
|
||||
- `rc-service` - Start/stop services on Alpine
|
||||
- Service configuration files in `/etc/init.d/`
|
||||
|
||||
## Differences from Debian Install
|
||||
|
||||
| Feature | Debian (install.func) | Alpine (alpine-install.func) |
|
||||
|---------|:---:|:---:|
|
||||
| Package Manager | apt-get | apk |
|
||||
| Init System | systemd | OpenRC |
|
||||
| SSH Service | systemctl | rc-service |
|
||||
| Config Files | /etc/systemd/ | /etc/init.d/ |
|
||||
| Network Config | /etc/network/ or Netplan | /etc/network/interfaces |
|
||||
| IPv6 Setup | netplan files | /etc/network/interfaces |
|
||||
| Auto-Login | getty override | `/etc/inittab` or shell config |
|
||||
| Size | ~200MB | ~100MB |
|
||||
|
||||
## Execution Flow for Alpine
|
||||
|
||||
```
|
||||
Alpine Container Started
|
||||
↓
|
||||
source $FUNCTIONS_FILE_PATH
|
||||
↓
|
||||
setting_up_container() ← Alpine setup message
|
||||
↓
|
||||
update_os() ← apk update
|
||||
↓
|
||||
verb_ip6() ← IPv6 configuration (optional)
|
||||
↓
|
||||
network_check() ← Verify connectivity
|
||||
↓
|
||||
[Application-Specific Installation]
|
||||
↓
|
||||
motd_ssh() ← Configure SSH/MOTD
|
||||
customize() ← Apply customizations
|
||||
↓
|
||||
cleanup_lxc() ← Final cleanup
|
||||
↓
|
||||
Alpine Installation Complete
|
||||
```
|
||||
|
||||
## Common Usage Patterns
|
||||
|
||||
### Basic Alpine Setup
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
setting_up_container
|
||||
update_os
|
||||
|
||||
# Install Alpine-specific packages
|
||||
apk add --no-cache curl wget git
|
||||
|
||||
# ... application installation ...
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
### With IPv6 Enabled
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
setting_up_container
|
||||
verb_ip6
|
||||
update_os
|
||||
network_check
|
||||
|
||||
# ... application installation ...
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
### Installing Services
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
setting_up_container
|
||||
update_os
|
||||
|
||||
# Install via apk
|
||||
apk add --no-cache nginx
|
||||
|
||||
# Enable and start service on Alpine
|
||||
rc-update add nginx
|
||||
rc-service nginx start
|
||||
|
||||
motd_ssh
|
||||
customize
|
||||
cleanup_lxc
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO
|
||||
- Use `apk add --no-cache` to reduce image size
|
||||
- Enable IPv6 if application needs it (`verb_ip6`)
|
||||
- Use `rc-service` for service management on Alpine
|
||||
- Check `/etc/network/interfaces` for IPv6 persistence
|
||||
- Test network connectivity before critical operations
|
||||
- Use `$STD` for output suppression in production
|
||||
|
||||
### ❌ DON'T
|
||||
- Use `apt-get` commands (Alpine doesn't have apt)
|
||||
- Use `systemctl` (Alpine uses OpenRC, not systemd)
|
||||
- Use `service` command (it may not exist on Alpine)
|
||||
- Assume systemd exists on Alpine
|
||||
- Forget to add `--no-cache` flag to `apk add`
|
||||
- Hardcode paths from Debian (different on Alpine)
|
||||
|
||||
## Alpine-Specific Considerations
|
||||
|
||||
### Package Names
|
||||
Some packages have different names on Alpine:
|
||||
```bash
|
||||
# Debian → Alpine
|
||||
# curl → curl (same)
|
||||
# wget → wget (same)
|
||||
# python3 → python3 (same)
|
||||
# libpq5 → postgresql-client
|
||||
# libmariadb3 → mariadb-client
|
||||
```
|
||||
|
||||
### Service Management
|
||||
```bash
|
||||
# Debian (systemd) → Alpine (OpenRC)
|
||||
systemctl start nginx → rc-service nginx start
|
||||
systemctl enable nginx → rc-update add nginx
|
||||
systemctl status nginx → rc-service nginx status
|
||||
```
|
||||
|
||||
### Network Configuration
|
||||
```bash
|
||||
# Debian (Netplan) → Alpine (/etc/network/interfaces)
|
||||
/etc/netplan/01-*.yaml → /etc/network/interfaces
|
||||
netplan apply → Configure directly in interfaces
|
||||
|
||||
# Enable IPv6 persistently on Alpine:
|
||||
# Add to /etc/network/interfaces:
|
||||
# iface eth0 inet6 static
|
||||
# address <IPv6_ADDRESS>
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "apk command not found"
|
||||
- This is Alpine Linux, not Debian
|
||||
- Install packages with `apk add` instead of `apt-get install`
|
||||
- Example: `apk add --no-cache curl wget`
|
||||
|
||||
### "IPv6 not persisting after reboot"
|
||||
- IPv6 must be configured in `/etc/network/interfaces`
|
||||
- The `verb_ip6()` function handles this automatically
|
||||
- Verify: `cat /etc/network/interfaces`
|
||||
|
||||
### "Service won't start on Alpine"
|
||||
- Alpine uses OpenRC, not systemd
|
||||
- Use `rc-service nginx start` instead of `systemctl start nginx`
|
||||
- Enable service: `rc-update add nginx`
|
||||
- Check logs: `/var/log/` or `rc-service nginx status`
|
||||
|
||||
### "Container too large"
|
||||
- Alpine should be much smaller than Debian
|
||||
- Verify using `apk add --no-cache` (removes package cache)
|
||||
- Example: `apk add --no-cache nginx` (not `apk add nginx`)
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- **[alpine-tools.func/](../alpine-tools.func/)** - Alpine tool installation
|
||||
- **[install.func/](../install.func/)** - Standard installation functions
|
||||
- **[core.func/](../core.func/)** - Utility functions
|
||||
- **[error_handler.func/](../error_handler.func/)** - Error handling
|
||||
- **[UPDATED_APP-install.md](../../UPDATED_APP-install.md)** - Application script guide
|
||||
|
||||
## Recent Updates
|
||||
|
||||
### Version 2.0 (Dec 2025)
|
||||
- ✅ Enhanced IPv6 persistence configuration
|
||||
- ✅ Improved OpenRC service management
|
||||
- ✅ Better apk error handling
|
||||
- ✅ Added Alpine-specific best practices documentation
|
||||
- ✅ Streamlined SSH setup for Alpine
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
**Maintainers**: community-scripts team
|
||||
**License**: MIT
|
||||
@@ -1,25 +0,0 @@
|
||||
# alpine-tools.func Flowchart
|
||||
|
||||
Alpine tool installation and package management flow.
|
||||
|
||||
## Tool Installation on Alpine
|
||||
|
||||
```
|
||||
apk_update()
|
||||
↓
|
||||
add_community_repo() [optional]
|
||||
↓
|
||||
apk_add PACKAGES
|
||||
↓
|
||||
Tool Installation
|
||||
↓
|
||||
rc-service start
|
||||
↓
|
||||
rc-update add [enable at boot]
|
||||
↓
|
||||
Complete ✓
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
@@ -1,31 +0,0 @@
|
||||
# alpine-tools.func Functions Reference
|
||||
|
||||
Alpine-specific tool installation functions.
|
||||
|
||||
## Core Functions
|
||||
|
||||
### apk_update()
|
||||
Update Alpine package lists.
|
||||
|
||||
### apk_add(PACKAGES)
|
||||
Install Alpine packages.
|
||||
|
||||
### apk_del(PACKAGES)
|
||||
Remove Alpine packages.
|
||||
|
||||
### add_community_repo()
|
||||
Enable Alpine community repository.
|
||||
|
||||
### add_testing_repo()
|
||||
Enable Alpine testing repository.
|
||||
|
||||
### Alpine Tool Functions
|
||||
- `setup_nodejs()` - Alpine Node.js
|
||||
- `setup_php()` - Alpine PHP
|
||||
- `setup_mariadb()` - Alpine MariaDB
|
||||
- `setup_postgresql()` - Alpine PostgreSQL
|
||||
- (+ more Alpine-specific setups)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
@@ -1,7 +0,0 @@
|
||||
# alpine-tools.func Integration Guide
|
||||
|
||||
Alpine tool installation integration with container workflows.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
@@ -1,19 +0,0 @@
|
||||
# alpine-tools.func Usage Examples
|
||||
|
||||
Examples for Alpine tool installation.
|
||||
|
||||
### Example: Alpine Setup with Tools
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
apk_update
|
||||
setup_nodejs "20"
|
||||
setup_php "8.3"
|
||||
setup_mariadb "11"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
@@ -1,297 +0,0 @@
|
||||
# alpine-tools.func Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The `alpine-tools.func` file provides Alpine Linux-specific tool installation functions for package and service management within Alpine LXC containers. It complements `tools.func` with Alpine-specific implementations using the apk package manager.
|
||||
|
||||
## Purpose and Use Cases
|
||||
|
||||
- **Alpine Tool Installation**: Install services and tools using apk on Alpine
|
||||
- **Package Management**: Safe apk operations with error handling
|
||||
- **Service Setup**: Install and configure common services on Alpine
|
||||
- **Dependency Management**: Handle Alpine-specific package dependencies
|
||||
- **Repository Management**: Setup and manage Alpine package repositories
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Key Function Groups
|
||||
- **Package Operations**: Alpine-specific apk commands with error handling
|
||||
- **Service Installation**: Install databases, web servers, tools on Alpine
|
||||
- **Repository Setup**: Configure Alpine community and testing repositories
|
||||
- **Tool Setup**: Install development tools and utilities
|
||||
|
||||
### Dependencies
|
||||
- **External**: `apk`, `curl`, `wget`
|
||||
- **Internal**: Uses functions from `core.func`, `error_handler.func`
|
||||
|
||||
### Integration Points
|
||||
- Used by: Alpine-based application install scripts
|
||||
- Uses: Environment variables from build.func
|
||||
- Provides: Alpine package and tool installation services
|
||||
|
||||
## Documentation Files
|
||||
|
||||
### 📊 [ALPINE_TOOLS_FUNC_FLOWCHART.md](./ALPINE_TOOLS_FUNC_FLOWCHART.md)
|
||||
Visual execution flows for package operations and tool installation on Alpine.
|
||||
|
||||
### 📚 [ALPINE_TOOLS_FUNC_FUNCTIONS_REFERENCE.md](./ALPINE_TOOLS_FUNC_FUNCTIONS_REFERENCE.md)
|
||||
Complete alphabetical reference of all Alpine tool functions.
|
||||
|
||||
### 💡 [ALPINE_TOOLS_FUNC_USAGE_EXAMPLES.md](./ALPINE_TOOLS_FUNC_USAGE_EXAMPLES.md)
|
||||
Practical examples for common Alpine installation patterns.
|
||||
|
||||
### 🔗 [ALPINE_TOOLS_FUNC_INTEGRATION.md](./ALPINE_TOOLS_FUNC_INTEGRATION.md)
|
||||
How alpine-tools.func integrates with Alpine installation workflows.
|
||||
|
||||
## Key Features
|
||||
|
||||
### Alpine Package Management
|
||||
- **apk Add**: Safe package installation with error handling
|
||||
- **apk Update**: Update package lists with retry logic
|
||||
- **apk Del**: Remove packages and dependencies
|
||||
- **Repository Configuration**: Add community and testing repos
|
||||
|
||||
### Alpine Tool Coverage
|
||||
- **Web Servers**: nginx, lighttpd
|
||||
- **Databases**: mariadb, postgresql, sqlite
|
||||
- **Development**: gcc, make, git, node.js (via apk)
|
||||
- **Services**: sshd, docker, podman
|
||||
- **Utilities**: curl, wget, htop, vim
|
||||
|
||||
### Error Handling
|
||||
- **Retry Logic**: Automatic recovery from transient failures
|
||||
- **Dependency Resolution**: Handle missing dependencies
|
||||
- **Lock Management**: Wait for apk locks to release
|
||||
- **Error Reporting**: Clear error messages
|
||||
|
||||
## Function Categories
|
||||
|
||||
### 🔹 Package Management
|
||||
- `apk_update()` - Update Alpine packages with retry
|
||||
- `apk_add()` - Install packages safely
|
||||
- `apk_del()` - Remove packages completely
|
||||
|
||||
### 🔹 Repository Functions
|
||||
- `add_community_repo()` - Enable community repositories
|
||||
- `add_testing_repo()` - Enable testing repositories
|
||||
- `setup_apk_repo()` - Configure custom apk repositories
|
||||
|
||||
### 🔹 Service Installation Functions
|
||||
- `setup_nginx()` - Install and configure nginx
|
||||
- `setup_mariadb()` - Install MariaDB on Alpine
|
||||
- `setup_postgresql()` - Install PostgreSQL
|
||||
- `setup_docker()` - Install Docker on Alpine
|
||||
- `setup_nodejs()` - Install Node.js from Alpine repos
|
||||
|
||||
### 🔹 Development Tools
|
||||
- `setup_build_tools()` - Install gcc, make, build-essential
|
||||
- `setup_git()` - Install git version control
|
||||
- `setup_python()` - Install Python 3 and pip
|
||||
|
||||
## Alpine vs Debian Package Differences
|
||||
|
||||
| Package | Debian | Alpine |
|
||||
|---------|:---:|:---:|
|
||||
| nginx | `apt-get install nginx` | `apk add nginx` |
|
||||
| mariadb | `apt-get install mariadb-server` | `apk add mariadb` |
|
||||
| PostgreSQL | `apt-get install postgresql` | `apk add postgresql` |
|
||||
| Node.js | `apt-get install nodejs npm` | `apk add nodejs npm` |
|
||||
| Docker | Special setup | `apk add docker` |
|
||||
| Python | `apt-get install python3 python3-pip` | `apk add python3 py3-pip` |
|
||||
|
||||
## Common Usage Patterns
|
||||
|
||||
### Basic Alpine Tool Installation
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
# Update package lists
|
||||
apk_update
|
||||
|
||||
# Install nginx
|
||||
apk_add nginx
|
||||
|
||||
# Start service
|
||||
rc-service nginx start
|
||||
rc-update add nginx
|
||||
```
|
||||
|
||||
### With Community Repository
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
# Enable community repo for more packages
|
||||
add_community_repo
|
||||
|
||||
# Update and install
|
||||
apk_update
|
||||
apk_add postgresql postgresql-client
|
||||
|
||||
# Start service
|
||||
rc-service postgresql start
|
||||
```
|
||||
|
||||
### Development Environment
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
|
||||
|
||||
# Install build tools
|
||||
setup_build_tools
|
||||
setup_git
|
||||
setup_nodejs "20"
|
||||
|
||||
# Install application
|
||||
git clone https://example.com/app
|
||||
cd app
|
||||
npm install
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO
|
||||
- Always use `apk add --no-cache` to keep images small
|
||||
- Call `apk_update()` before installing packages
|
||||
- Use community repository for more packages (`add_community_repo`)
|
||||
- Handle apk locks gracefully with retry logic
|
||||
- Use `$STD` variable for output control
|
||||
- Check if tool already installed before reinstalling
|
||||
|
||||
### ❌ DON'T
|
||||
- Use `apt-get` commands (Alpine doesn't have apt)
|
||||
- Install packages without `--no-cache` flag
|
||||
- Hardcode Alpine-specific paths
|
||||
- Mix Alpine and Debian commands
|
||||
- Forget to enable services with `rc-update`
|
||||
- Use `systemctl` (Alpine has OpenRC, not systemd)
|
||||
|
||||
## Alpine Repository Configuration
|
||||
|
||||
### Default Repositories
|
||||
Alpine comes with main repository enabled by default. Additional repos:
|
||||
|
||||
```bash
|
||||
# Community repository (apk add php, go, rust, etc.)
|
||||
add_community_repo
|
||||
|
||||
# Testing repository (bleeding edge packages)
|
||||
add_testing_repo
|
||||
```
|
||||
|
||||
### Repository Locations
|
||||
```bash
|
||||
/etc/apk/repositories # Main repo list
|
||||
/etc/apk/keys/ # GPG keys for repos
|
||||
/var/cache/apk/ # Package cache
|
||||
```
|
||||
|
||||
## Package Size Optimization
|
||||
|
||||
Alpine is designed for small container images:
|
||||
|
||||
```bash
|
||||
# DON'T: Leaves package cache (increases image size)
|
||||
apk add nginx
|
||||
|
||||
# DO: Remove cache to reduce size
|
||||
apk add --no-cache nginx
|
||||
|
||||
# Expected sizes:
|
||||
# Alpine base: ~5MB
|
||||
# Alpine + nginx: ~10-15MB
|
||||
# Debian base: ~75MB
|
||||
# Debian + nginx: ~90-95MB
|
||||
```
|
||||
|
||||
## Service Management on Alpine
|
||||
|
||||
### Using OpenRC
|
||||
```bash
|
||||
# Start service immediately
|
||||
rc-service nginx start
|
||||
|
||||
# Stop service
|
||||
rc-service nginx stop
|
||||
|
||||
# Restart service
|
||||
rc-service nginx restart
|
||||
|
||||
# Enable at boot
|
||||
rc-update add nginx
|
||||
|
||||
# Disable at boot
|
||||
rc-update del nginx
|
||||
|
||||
# List enabled services
|
||||
rc-update show
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "apk: lock is held by PID"
|
||||
```bash
|
||||
# Alpine apk database is locked (another process using apk)
|
||||
# Wait a moment
|
||||
sleep 5
|
||||
apk_update
|
||||
|
||||
# Or manually:
|
||||
rm /var/lib/apk/lock 2>/dev/null || true
|
||||
apk update
|
||||
```
|
||||
|
||||
### "Package not found"
|
||||
```bash
|
||||
# May be in community or testing repository
|
||||
add_community_repo
|
||||
apk_update
|
||||
apk_add package-name
|
||||
```
|
||||
|
||||
### "Repository not responding"
|
||||
```bash
|
||||
# Alpine repo may be slow or unreachable
|
||||
# Try updating again with retry logic
|
||||
apk_update # Built-in retry logic
|
||||
|
||||
# Or manually retry
|
||||
sleep 10
|
||||
apk update
|
||||
```
|
||||
|
||||
### "Service fails to start"
|
||||
```bash
|
||||
# Check service status on Alpine
|
||||
rc-service nginx status
|
||||
|
||||
# View logs
|
||||
tail /var/log/nginx/error.log
|
||||
|
||||
# Verify configuration
|
||||
nginx -t
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- **[alpine-install.func/](../alpine-install.func/)** - Alpine installation functions
|
||||
- **[tools.func/](../tools.func/)** - Debian/standard tool installation
|
||||
- **[core.func/](../core.func/)** - Utility functions
|
||||
- **[error_handler.func/](../error_handler.func/)** - Error handling
|
||||
- **[UPDATED_APP-install.md](../../UPDATED_APP-install.md)** - Application script guide
|
||||
|
||||
## Recent Updates
|
||||
|
||||
### Version 2.0 (Dec 2025)
|
||||
- ✅ Enhanced apk error handling and retry logic
|
||||
- ✅ Improved repository management
|
||||
- ✅ Better service management with OpenRC
|
||||
- ✅ Added Alpine-specific optimization guidance
|
||||
- ✅ Enhanced package cache management
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: December 2025
|
||||
**Maintainers**: community-scripts team
|
||||
**License**: MIT
|
||||
@@ -1,342 +0,0 @@
|
||||
# api.func Execution Flowchart
|
||||
|
||||
## Main API Communication Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ API Communication Initialization │
|
||||
│ Entry point when api.func functions are called by installation scripts │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Prerequisites Check │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Prerequisites Validation │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Check curl │ │ Check │ │ Check │ │ │
|
||||
│ │ │ Availability │ │ Diagnostics │ │ Random UUID │ │ │
|
||||
│ │ │ │ │ Setting │ │ │ │
|
||||
│ │ │ • command -v │ │ • DIAGNOSTICS │ │ • RANDOM_UUID │ │
|
||||
│ │ │ curl │ │ = "yes" │ │ not empty │ │
|
||||
│ │ │ • Return if │ │ • Return if │ │ • Return if │ │
|
||||
│ │ │ not found │ │ disabled │ │ not set │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Data Collection │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ System Information Gathering │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Get PVE │ │ Collect │ │ Prepare JSON │ │ │
|
||||
│ │ │ Version │ │ Environment │ │ Payload │ │
|
||||
│ │ │ │ │ Variables │ │ │ │
|
||||
│ │ │ • pveversion │ │ • CT_TYPE │ │ • Create JSON │ │
|
||||
│ │ │ command │ │ • DISK_SIZE │ │ structure │ │
|
||||
│ │ │ • Parse version │ │ • CORE_COUNT │ │ • Include all │ │
|
||||
│ │ │ • Extract │ │ • RAM_SIZE │ │ variables │ │
|
||||
│ │ │ major.minor │ │ • var_os │ │ • Format for API │ │
|
||||
│ │ │ │ │ • var_version │ │ │ │
|
||||
│ │ │ │ │ • NSAPP │ │ │ │
|
||||
│ │ │ │ │ • METHOD │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ API Request Execution │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ HTTP Request Processing │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Prepare │ │ Execute │ │ Handle │ │ │
|
||||
│ │ │ Request │ │ HTTP Request │ │ Response │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Set API URL │ │ • curl -s -w │ │ • Capture HTTP │ │
|
||||
│ │ │ • Set headers │ │ "%{http_code}" │ │ status code │ │
|
||||
│ │ │ • Set payload │ │ • POST request │ │ • Store response │ │
|
||||
│ │ │ • Content-Type │ │ • JSON data │ │ • Handle errors │ │
|
||||
│ │ │ application/ │ │ • Follow │ │ gracefully │ │
|
||||
│ │ │ json │ │ redirects │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## LXC API Reporting Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ POST_TO_API() Flow │
|
||||
│ Send LXC container installation data to API │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ LXC Data Preparation │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ LXC-Specific Data Collection │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Set LXC │ │ Include LXC │ │ Set Status │ │ │
|
||||
│ │ │ Type │ │ Variables │ │ Information │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • ct_type: 1 │ │ • DISK_SIZE │ │ • status: │ │
|
||||
│ │ │ • type: "lxc" │ │ • CORE_COUNT │ │ "installing" │ │
|
||||
│ │ │ • Include all │ │ • RAM_SIZE │ │ • Include all │ │
|
||||
│ │ │ LXC data │ │ • var_os │ │ tracking data │ │
|
||||
│ │ │ │ │ • var_version │ │ │ │
|
||||
│ │ │ │ │ • DISABLEIP6 │ │ │ │
|
||||
│ │ │ │ │ • NSAPP │ │ │ │
|
||||
│ │ │ │ │ • METHOD │ │ │ │
|
||||
│ │ │ │ │ • pve_version │ │ │ │
|
||||
│ │ │ │ │ • random_id │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ JSON Payload Creation │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ JSON Structure Generation │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Create JSON │ │ Validate │ │ Format for │ │ │
|
||||
│ │ │ Structure │ │ Data │ │ API Request │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Use heredoc │ │ • Check all │ │ • Ensure proper │ │
|
||||
│ │ │ syntax │ │ variables │ │ JSON format │ │
|
||||
│ │ │ • Include all │ │ are set │ │ • Escape special │ │
|
||||
│ │ │ required │ │ • Validate │ │ characters │ │
|
||||
│ │ │ fields │ │ data types │ │ • Set content │ │
|
||||
│ │ │ • Format │ │ • Handle │ │ type │ │
|
||||
│ │ │ properly │ │ missing │ │ │ │
|
||||
│ │ │ │ │ values │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## VM API Reporting Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ POST_TO_API_VM() Flow │
|
||||
│ Send VM installation data to API │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ VM Data Preparation │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ VM-Specific Data Collection │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Check │ │ Set VM │ │ Process Disk │ │ │
|
||||
│ │ │ Diagnostics │ │ Type │ │ Size │ │
|
||||
│ │ │ File │ │ │ │ │ │
|
||||
│ │ │ │ │ • ct_type: 2 │ │ • Remove 'G' │ │
|
||||
│ │ │ • Check file │ │ • type: "vm" │ │ suffix │ │
|
||||
│ │ │ existence │ │ • Include all │ │ • Convert to │ │
|
||||
│ │ │ • Read │ │ VM data │ │ numeric value │ │
|
||||
│ │ │ DIAGNOSTICS │ │ │ │ • Store in │ │
|
||||
│ │ │ setting │ │ │ │ DISK_SIZE_API │ │
|
||||
│ │ │ • Parse value │ │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ VM JSON Payload Creation │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ VM-Specific JSON Structure │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Include VM │ │ Set VM │ │ Format VM │ │ │
|
||||
│ │ │ Variables │ │ Status │ │ Data for API │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • DISK_SIZE_API │ │ • status: │ │ • Ensure proper │ │
|
||||
│ │ │ • CORE_COUNT │ │ "installing" │ │ JSON format │ │
|
||||
│ │ │ • RAM_SIZE │ │ • Include all │ │ • Handle VM- │ │
|
||||
│ │ │ • var_os │ │ tracking │ │ specific data │ │
|
||||
│ │ │ • var_version │ │ information │ │ • Set appropriate │ │
|
||||
│ │ │ • NSAPP │ │ │ │ content type │ │
|
||||
│ │ │ • METHOD │ │ │ │ │ │
|
||||
│ │ │ • pve_version │ │ │ │ │ │
|
||||
│ │ │ • random_id │ │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Status Update Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ POST_UPDATE_TO_API() Flow │
|
||||
│ Send installation completion status to API │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Update Prevention Check │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Duplicate Update Prevention │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Check │ │ Set Flag │ │ Return Early │ │ │
|
||||
│ │ │ POST_UPDATE_ │ │ if First │ │ if Already │ │
|
||||
│ │ │ DONE │ │ Update │ │ Updated │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Check if │ │ • Set │ │ • Return 0 │ │
|
||||
│ │ │ already │ │ POST_UPDATE_ │ │ • Skip API call │ │
|
||||
│ │ │ updated │ │ DONE=true │ │ • Prevent │ │
|
||||
│ │ │ • Prevent │ │ • Continue │ │ duplicate │ │
|
||||
│ │ │ duplicate │ │ with update │ │ requests │ │
|
||||
│ │ │ requests │ │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Status and Error Processing │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Status Determination │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Determine │ │ Get Error │ │ Prepare Status │ │ │
|
||||
│ │ │ Status │ │ Description │ │ Data │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • status: │ │ • Call │ │ • Include status │ │
|
||||
│ │ │ "success" or │ │ get_error_ │ │ • Include error │ │
|
||||
│ │ │ "failed" │ │ description() │ │ description │ │
|
||||
│ │ │ • Set exit │ │ • Get human- │ │ • Include random │ │
|
||||
│ │ │ code based │ │ readable │ │ ID for tracking │ │
|
||||
│ │ │ on status │ │ error message │ │ │ │
|
||||
│ │ │ • Default to │ │ • Handle │ │ │ │
|
||||
│ │ │ error if │ │ unknown │ │ │ │
|
||||
│ │ │ not set │ │ errors │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Status Update API Request │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Status Update Payload Creation │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Create │ │ Send Status │ │ Mark Update │ │ │
|
||||
│ │ │ Status JSON │ │ Update │ │ Complete │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Include │ │ • POST to │ │ • Set │ │
|
||||
│ │ │ status │ │ updatestatus │ │ POST_UPDATE_ │ │
|
||||
│ │ │ • Include │ │ endpoint │ │ DONE=true │ │
|
||||
│ │ │ error │ │ • Include JSON │ │ • Prevent further │ │
|
||||
│ │ │ description │ │ payload │ │ updates │ │
|
||||
│ │ │ • Include │ │ • Handle │ │ • Complete │ │
|
||||
│ │ │ random_id │ │ response │ │ process │ │
|
||||
│ │ │ │ │ gracefully │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Error Description Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ GET_ERROR_DESCRIPTION() Flow │
|
||||
│ Convert numeric exit codes to human-readable explanations │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Error Code Classification │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Error Code Categories │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ General │ │ Network │ │ LXC-Specific │ │ │
|
||||
│ │ │ System │ │ Errors │ │ Errors │ │
|
||||
│ │ │ Errors │ │ │ │ │ │
|
||||
│ │ │ │ │ • 18: Connection│ │ • 100-101: LXC │ │
|
||||
│ │ │ • 0-9: Basic │ │ failed │ │ install errors │ │
|
||||
│ │ │ errors │ │ • 22: Invalid │ │ • 200-209: LXC │ │
|
||||
│ │ │ • 126-128: │ │ argument │ │ creation errors │ │
|
||||
│ │ │ Command │ │ • 28: No space │ │ │ │
|
||||
│ │ │ errors │ │ • 35: Timeout │ │ │ │
|
||||
│ │ │ • 129-143: │ │ • 56: TLS error │ │ │ │
|
||||
│ │ │ Signal │ │ • 60: SSL cert │ │ │ │
|
||||
│ │ │ errors │ │ error │ │ │ │
|
||||
│ │ │ • 152: Resource │ │ │ │ │ │
|
||||
│ │ │ limit │ │ │ │ │ │
|
||||
│ │ │ • 255: Unknown │ │ │ │ │ │
|
||||
│ │ │ critical │ │ │ │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Error Message Return │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Error Message Formatting │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ │
|
||||
│ │ │ Match Error │ │ Return │ │ Default Case │ │ │
|
||||
│ │ │ Code │ │ Description │ │ │ │
|
||||
│ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Use case │ │ • Return │ │ • Return "Unknown │ │
|
||||
│ │ │ statement │ │ human- │ │ error code │ │
|
||||
│ │ │ • Match │ │ readable │ │ (exit_code)" │ │
|
||||
│ │ │ specific │ │ message │ │ • Handle │ │
|
||||
│ │ │ codes │ │ • Include │ │ unrecognized │ │
|
||||
│ │ │ • Handle │ │ context │ │ codes │ │
|
||||
│ │ │ ranges │ │ information │ │ • Provide fallback │ │
|
||||
│ │ │ │ │ │ │ message │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Integration Points
|
||||
|
||||
### With Installation Scripts
|
||||
- **build.func**: Sends LXC installation data
|
||||
- **vm-core.func**: Sends VM installation data
|
||||
- **install.func**: Reports installation status
|
||||
- **alpine-install.func**: Reports Alpine installation data
|
||||
|
||||
### With Error Handling
|
||||
- **error_handler.func**: Provides error explanations
|
||||
- **core.func**: Uses error descriptions in silent execution
|
||||
- **Diagnostic reporting**: Tracks error patterns
|
||||
|
||||
### External Dependencies
|
||||
- **curl**: HTTP client for API communication
|
||||
- **Community Scripts API**: External API endpoint
|
||||
- **Network connectivity**: Required for API communication
|
||||
@@ -1,433 +0,0 @@
|
||||
# api.func Functions Reference
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a comprehensive alphabetical reference of all functions in `api.func`, including parameters, dependencies, usage examples, and error handling.
|
||||
|
||||
## Function Categories
|
||||
|
||||
### Error Description Functions
|
||||
|
||||
#### `get_error_description()`
|
||||
**Purpose**: Convert numeric exit codes to human-readable explanations
|
||||
**Parameters**:
|
||||
- `$1` - Exit code to explain
|
||||
**Returns**: Human-readable error explanation string
|
||||
**Side Effects**: None
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: None
|
||||
|
||||
**Supported Exit Codes**:
|
||||
- **General System**: 0-9, 18, 22, 28, 35, 56, 60, 125-128, 129-143, 152, 255
|
||||
- **LXC-Specific**: 100-101, 200-209
|
||||
- **Docker**: 125
|
||||
|
||||
**Usage Example**:
|
||||
```bash
|
||||
error_msg=$(get_error_description 127)
|
||||
echo "Error 127: $error_msg"
|
||||
# Output: Error 127: Command not found: Incorrect path or missing dependency.
|
||||
```
|
||||
|
||||
**Error Code Examples**:
|
||||
```bash
|
||||
get_error_description 0 # " " (space)
|
||||
get_error_description 1 # "General error: An unspecified error occurred."
|
||||
get_error_description 127 # "Command not found: Incorrect path or missing dependency."
|
||||
get_error_description 200 # "LXC creation failed."
|
||||
get_error_description 255 # "Unknown critical error, often due to missing permissions or broken scripts."
|
||||
```
|
||||
|
||||
### API Communication Functions
|
||||
|
||||
#### `post_to_api()`
|
||||
**Purpose**: Send LXC container installation data to community-scripts.org API
|
||||
**Parameters**: None (uses environment variables)
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
- Sends HTTP POST request to API
|
||||
- Stores response in RESPONSE variable
|
||||
- Requires curl command and network connectivity
|
||||
**Dependencies**: `curl` command
|
||||
**Environment Variables Used**: `DIAGNOSTICS`, `RANDOM_UUID`, `CT_TYPE`, `DISK_SIZE`, `CORE_COUNT`, `RAM_SIZE`, `var_os`, `var_version`, `DISABLEIP6`, `NSAPP`, `METHOD`
|
||||
|
||||
**Prerequisites**:
|
||||
- `curl` command must be available
|
||||
- `DIAGNOSTICS` must be set to "yes"
|
||||
- `RANDOM_UUID` must be set and not empty
|
||||
|
||||
**API Endpoint**: `https://api.community-scripts.org/dev/upload`
|
||||
|
||||
**JSON Payload Structure**:
|
||||
```json
|
||||
{
|
||||
"ct_type": 1,
|
||||
"type": "lxc",
|
||||
"disk_size": 8,
|
||||
"core_count": 2,
|
||||
"ram_size": 2048,
|
||||
"os_type": "debian",
|
||||
"os_version": "12",
|
||||
"disableip6": "true",
|
||||
"nsapp": "plex",
|
||||
"method": "install",
|
||||
"pve_version": "8.0",
|
||||
"status": "installing",
|
||||
"random_id": "uuid-string"
|
||||
}
|
||||
```
|
||||
|
||||
**Usage Example**:
|
||||
```bash
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE=8
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export NSAPP="plex"
|
||||
export METHOD="install"
|
||||
|
||||
post_to_api
|
||||
```
|
||||
|
||||
#### `post_to_api_vm()`
|
||||
**Purpose**: Send VM installation data to community-scripts.org API
|
||||
**Parameters**: None (uses environment variables)
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
- Sends HTTP POST request to API
|
||||
- Stores response in RESPONSE variable
|
||||
- Requires curl command and network connectivity
|
||||
**Dependencies**: `curl` command, diagnostics file
|
||||
**Environment Variables Used**: `DIAGNOSTICS`, `RANDOM_UUID`, `DISK_SIZE`, `CORE_COUNT`, `RAM_SIZE`, `var_os`, `var_version`, `NSAPP`, `METHOD`
|
||||
|
||||
**Prerequisites**:
|
||||
- `/usr/local/community-scripts/diagnostics` file must exist
|
||||
- `DIAGNOSTICS` must be set to "yes" in diagnostics file
|
||||
- `curl` command must be available
|
||||
- `RANDOM_UUID` must be set and not empty
|
||||
|
||||
**API Endpoint**: `https://api.community-scripts.org/dev/upload`
|
||||
|
||||
**JSON Payload Structure**:
|
||||
```json
|
||||
{
|
||||
"ct_type": 2,
|
||||
"type": "vm",
|
||||
"disk_size": 8,
|
||||
"core_count": 2,
|
||||
"ram_size": 2048,
|
||||
"os_type": "debian",
|
||||
"os_version": "12",
|
||||
"disableip6": "",
|
||||
"nsapp": "plex",
|
||||
"method": "install",
|
||||
"pve_version": "8.0",
|
||||
"status": "installing",
|
||||
"random_id": "uuid-string"
|
||||
}
|
||||
```
|
||||
|
||||
**Usage Example**:
|
||||
```bash
|
||||
# Create diagnostics file
|
||||
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics
|
||||
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export DISK_SIZE="8G"
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export NSAPP="plex"
|
||||
export METHOD="install"
|
||||
|
||||
post_to_api_vm
|
||||
```
|
||||
|
||||
#### `post_update_to_api()`
|
||||
**Purpose**: Send installation completion status to community-scripts.org API
|
||||
**Parameters**:
|
||||
- `$1` - Status ("success" or "failed", default: "failed")
|
||||
- `$2` - Exit code (default: 1)
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
- Sends HTTP POST request to API
|
||||
- Sets POST_UPDATE_DONE=true to prevent duplicates
|
||||
- Stores response in RESPONSE variable
|
||||
**Dependencies**: `curl` command, `get_error_description()`
|
||||
**Environment Variables Used**: `DIAGNOSTICS`, `RANDOM_UUID`
|
||||
|
||||
**Prerequisites**:
|
||||
- `curl` command must be available
|
||||
- `DIAGNOSTICS` must be set to "yes"
|
||||
- `RANDOM_UUID` must be set and not empty
|
||||
- POST_UPDATE_DONE must be false (prevents duplicates)
|
||||
|
||||
**API Endpoint**: `https://api.community-scripts.org/dev/upload/updatestatus`
|
||||
|
||||
**JSON Payload Structure**:
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"error": "Error description from get_error_description()",
|
||||
"random_id": "uuid-string"
|
||||
}
|
||||
```
|
||||
|
||||
**Usage Example**:
|
||||
```bash
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Report successful installation
|
||||
post_update_to_api "success" 0
|
||||
|
||||
# Report failed installation
|
||||
post_update_to_api "failed" 127
|
||||
```
|
||||
|
||||
## Function Call Hierarchy
|
||||
|
||||
### API Communication Flow
|
||||
```
|
||||
post_to_api()
|
||||
├── Check curl availability
|
||||
├── Check DIAGNOSTICS setting
|
||||
├── Check RANDOM_UUID
|
||||
├── Get PVE version
|
||||
├── Create JSON payload
|
||||
└── Send HTTP POST request
|
||||
|
||||
post_to_api_vm()
|
||||
├── Check diagnostics file
|
||||
├── Check curl availability
|
||||
├── Check DIAGNOSTICS setting
|
||||
├── Check RANDOM_UUID
|
||||
├── Process disk size
|
||||
├── Get PVE version
|
||||
├── Create JSON payload
|
||||
└── Send HTTP POST request
|
||||
|
||||
post_update_to_api()
|
||||
├── Check POST_UPDATE_DONE flag
|
||||
├── Check curl availability
|
||||
├── Check DIAGNOSTICS setting
|
||||
├── Check RANDOM_UUID
|
||||
├── Determine status and exit code
|
||||
├── Get error description
|
||||
├── Create JSON payload
|
||||
├── Send HTTP POST request
|
||||
└── Set POST_UPDATE_DONE=true
|
||||
```
|
||||
|
||||
### Error Description Flow
|
||||
```
|
||||
get_error_description()
|
||||
├── Match exit code
|
||||
├── Return appropriate description
|
||||
└── Handle unknown codes
|
||||
```
|
||||
|
||||
## Error Code Reference
|
||||
|
||||
### General System Errors
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 0 | (space) |
|
||||
| 1 | General error: An unspecified error occurred. |
|
||||
| 2 | Incorrect shell usage or invalid command arguments. |
|
||||
| 3 | Unexecuted function or invalid shell condition. |
|
||||
| 4 | Error opening a file or invalid path. |
|
||||
| 5 | I/O error: An input/output failure occurred. |
|
||||
| 6 | No such device or address. |
|
||||
| 7 | Insufficient memory or resource exhaustion. |
|
||||
| 8 | Non-executable file or invalid file format. |
|
||||
| 9 | Failed child process execution. |
|
||||
| 18 | Connection to a remote server failed. |
|
||||
| 22 | Invalid argument or faulty network connection. |
|
||||
| 28 | No space left on device. |
|
||||
| 35 | Timeout while establishing a connection. |
|
||||
| 56 | Faulty TLS connection. |
|
||||
| 60 | SSL certificate error. |
|
||||
|
||||
### Command Execution Errors
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 125 | Docker error: Container could not start. |
|
||||
| 126 | Command not executable: Incorrect permissions or missing dependencies. |
|
||||
| 127 | Command not found: Incorrect path or missing dependency. |
|
||||
| 128 | Invalid exit signal, e.g., incorrect Git command. |
|
||||
|
||||
### Signal Errors
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 129 | Signal 1 (SIGHUP): Process terminated due to hangup. |
|
||||
| 130 | Signal 2 (SIGINT): Manual termination via Ctrl+C. |
|
||||
| 132 | Signal 4 (SIGILL): Illegal machine instruction. |
|
||||
| 133 | Signal 5 (SIGTRAP): Debugging error or invalid breakpoint signal. |
|
||||
| 134 | Signal 6 (SIGABRT): Program aborted itself. |
|
||||
| 135 | Signal 7 (SIGBUS): Memory error, invalid memory address. |
|
||||
| 137 | Signal 9 (SIGKILL): Process forcibly terminated (OOM-killer or 'kill -9'). |
|
||||
| 139 | Signal 11 (SIGSEGV): Segmentation fault, possibly due to invalid pointer access. |
|
||||
| 141 | Signal 13 (SIGPIPE): Pipe closed unexpectedly. |
|
||||
| 143 | Signal 15 (SIGTERM): Process terminated normally. |
|
||||
| 152 | Signal 24 (SIGXCPU): CPU time limit exceeded. |
|
||||
|
||||
### LXC-Specific Errors
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 100 | LXC install error: Unexpected error in create_lxc.sh. |
|
||||
| 101 | LXC install error: No network connection detected. |
|
||||
| 200 | LXC creation failed. |
|
||||
| 201 | LXC error: Invalid Storage class. |
|
||||
| 202 | User aborted menu in create_lxc.sh. |
|
||||
| 203 | CTID not set in create_lxc.sh. |
|
||||
| 204 | PCT_OSTYPE not set in create_lxc.sh. |
|
||||
| 205 | CTID cannot be less than 100 in create_lxc.sh. |
|
||||
| 206 | CTID already in use in create_lxc.sh. |
|
||||
| 207 | Template not found in create_lxc.sh. |
|
||||
| 208 | Error downloading template in create_lxc.sh. |
|
||||
| 209 | Container creation failed, but template is intact in create_lxc.sh. |
|
||||
|
||||
### Other Errors
|
||||
| Code | Description |
|
||||
|------|-------------|
|
||||
| 255 | Unknown critical error, often due to missing permissions or broken scripts. |
|
||||
| * | Unknown error code (exit_code). |
|
||||
|
||||
## Environment Variable Dependencies
|
||||
|
||||
### Required Variables
|
||||
- **`DIAGNOSTICS`**: Enable/disable diagnostic reporting ("yes"/"no")
|
||||
- **`RANDOM_UUID`**: Unique identifier for tracking
|
||||
|
||||
### Optional Variables
|
||||
- **`CT_TYPE`**: Container type (1 for LXC, 2 for VM)
|
||||
- **`DISK_SIZE`**: Disk size in GB (or GB with 'G' suffix for VM)
|
||||
- **`CORE_COUNT`**: Number of CPU cores
|
||||
- **`RAM_SIZE`**: RAM size in MB
|
||||
- **`var_os`**: Operating system type
|
||||
- **`var_version`**: OS version
|
||||
- **`DISABLEIP6`**: IPv6 disable setting
|
||||
- **`NSAPP`**: Namespace application name
|
||||
- **`METHOD`**: Installation method
|
||||
|
||||
### Internal Variables
|
||||
- **`POST_UPDATE_DONE`**: Prevents duplicate status updates
|
||||
- **`API_URL`**: Community scripts API endpoint
|
||||
- **`JSON_PAYLOAD`**: API request payload
|
||||
- **`RESPONSE`**: API response
|
||||
- **`DISK_SIZE_API`**: Processed disk size for VM API
|
||||
|
||||
## Error Handling Patterns
|
||||
|
||||
### API Communication Errors
|
||||
- All API functions handle curl failures gracefully
|
||||
- Network errors don't block installation process
|
||||
- Missing prerequisites cause early return
|
||||
- Duplicate updates are prevented
|
||||
|
||||
### Error Description Errors
|
||||
- Unknown error codes return generic message
|
||||
- All error codes are handled with case statement
|
||||
- Fallback message includes the actual error code
|
||||
|
||||
### Prerequisites Validation
|
||||
- Check curl availability before API calls
|
||||
- Validate DIAGNOSTICS setting
|
||||
- Ensure RANDOM_UUID is set
|
||||
- Check for duplicate updates
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### With build.func
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source core.func
|
||||
source api.func
|
||||
source build.func
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Container creation...
|
||||
# ... build.func code ...
|
||||
|
||||
# Report completion
|
||||
if [[ $? -eq 0 ]]; then
|
||||
post_update_to_api "success" 0
|
||||
else
|
||||
post_update_to_api "failed" $?
|
||||
fi
|
||||
```
|
||||
|
||||
### With vm-core.func
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source core.func
|
||||
source api.func
|
||||
source vm-core.func
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Report VM installation start
|
||||
post_to_api_vm
|
||||
|
||||
# VM creation...
|
||||
# ... vm-core.func code ...
|
||||
|
||||
# Report completion
|
||||
post_update_to_api "success" 0
|
||||
```
|
||||
|
||||
### With error_handler.func
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source core.func
|
||||
source error_handler.func
|
||||
source api.func
|
||||
|
||||
# Use error descriptions
|
||||
error_code=127
|
||||
error_msg=$(get_error_description $error_code)
|
||||
echo "Error $error_code: $error_msg"
|
||||
|
||||
# Report error to API
|
||||
post_update_to_api "failed" $error_code
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### API Usage
|
||||
1. Always check prerequisites before API calls
|
||||
2. Use unique identifiers for tracking
|
||||
3. Handle API failures gracefully
|
||||
4. Don't block installation on API failures
|
||||
|
||||
### Error Reporting
|
||||
1. Use appropriate error codes
|
||||
2. Provide meaningful error descriptions
|
||||
3. Report both success and failure cases
|
||||
4. Prevent duplicate status updates
|
||||
|
||||
### Diagnostic Reporting
|
||||
1. Respect user privacy settings
|
||||
2. Only send data when diagnostics enabled
|
||||
3. Use anonymous tracking identifiers
|
||||
4. Include relevant system information
|
||||
|
||||
### Error Handling
|
||||
1. Handle unknown error codes gracefully
|
||||
2. Provide fallback error messages
|
||||
3. Include error code in unknown error messages
|
||||
4. Use consistent error message format
|
||||
@@ -1,643 +0,0 @@
|
||||
# api.func Integration Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes how `api.func` integrates with other components in the Proxmox Community Scripts project, including dependencies, data flow, and API surface.
|
||||
|
||||
## Dependencies
|
||||
|
||||
### External Dependencies
|
||||
|
||||
#### Required Commands
|
||||
- **`curl`**: HTTP client for API communication
|
||||
- **`uuidgen`**: Generate unique identifiers (optional, can use other methods)
|
||||
|
||||
#### Optional Commands
|
||||
- **None**: No other external command dependencies
|
||||
|
||||
### Internal Dependencies
|
||||
|
||||
#### Environment Variables from Other Scripts
|
||||
- **build.func**: Provides container creation variables
|
||||
- **vm-core.func**: Provides VM creation variables
|
||||
- **core.func**: Provides system information variables
|
||||
- **Installation scripts**: Provide application-specific variables
|
||||
|
||||
## Integration Points
|
||||
|
||||
### With build.func
|
||||
|
||||
#### LXC Container Reporting
|
||||
```bash
|
||||
# build.func uses api.func for container reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source build.func
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Container creation with API reporting
|
||||
create_container() {
|
||||
# Set container parameters
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE="$var_disk"
|
||||
export CORE_COUNT="$var_cpu"
|
||||
export RAM_SIZE="$var_ram"
|
||||
export var_os="$var_os"
|
||||
export var_version="$var_version"
|
||||
export NSAPP="$APP"
|
||||
export METHOD="install"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Container creation using build.func
|
||||
# ... build.func container creation logic ...
|
||||
|
||||
# Report completion
|
||||
if [[ $? -eq 0 ]]; then
|
||||
post_update_to_api "success" 0
|
||||
else
|
||||
post_update_to_api "failed" $?
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
#### Error Reporting Integration
|
||||
```bash
|
||||
# build.func uses api.func for error reporting
|
||||
handle_container_error() {
|
||||
local exit_code=$1
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
|
||||
echo "Container creation failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
}
|
||||
```
|
||||
|
||||
### With vm-core.func
|
||||
|
||||
#### VM Installation Reporting
|
||||
```bash
|
||||
# vm-core.func uses api.func for VM reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source vm-core.func
|
||||
|
||||
# Set up VM API reporting
|
||||
mkdir -p /usr/local/community-scripts
|
||||
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics
|
||||
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# VM creation with API reporting
|
||||
create_vm() {
|
||||
# Set VM parameters
|
||||
export DISK_SIZE="${var_disk}G"
|
||||
export CORE_COUNT="$var_cpu"
|
||||
export RAM_SIZE="$var_ram"
|
||||
export var_os="$var_os"
|
||||
export var_version="$var_version"
|
||||
export NSAPP="$APP"
|
||||
export METHOD="install"
|
||||
|
||||
# Report VM installation start
|
||||
post_to_api_vm
|
||||
|
||||
# VM creation using vm-core.func
|
||||
# ... vm-core.func VM creation logic ...
|
||||
|
||||
# Report completion
|
||||
post_update_to_api "success" 0
|
||||
}
|
||||
```
|
||||
|
||||
### With core.func
|
||||
|
||||
#### System Information Integration
|
||||
```bash
|
||||
# core.func provides system information for api.func
|
||||
source core.func
|
||||
source api.func
|
||||
|
||||
# Get system information for API reporting
|
||||
get_system_info_for_api() {
|
||||
# Get PVE version using core.func utilities
|
||||
local pve_version=$(pveversion | awk -F'[/ ]' '{print $2}')
|
||||
|
||||
# Set API parameters
|
||||
export var_os="$var_os"
|
||||
export var_version="$var_version"
|
||||
|
||||
# Use core.func error handling with api.func reporting
|
||||
if silent apt-get update; then
|
||||
post_update_to_api "success" 0
|
||||
else
|
||||
post_update_to_api "failed" $?
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
### With error_handler.func
|
||||
|
||||
#### Error Description Integration
|
||||
```bash
|
||||
# error_handler.func uses api.func for error descriptions
|
||||
source core.func
|
||||
source error_handler.func
|
||||
source api.func
|
||||
|
||||
# Enhanced error handler with API reporting
|
||||
enhanced_error_handler() {
|
||||
local exit_code=${1:-$?}
|
||||
local command=${2:-${BASH_COMMAND:-unknown}}
|
||||
|
||||
# Get error description from api.func
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
|
||||
# Display error information
|
||||
echo "Error $exit_code: $error_msg"
|
||||
echo "Command: $command"
|
||||
|
||||
# Report error to API
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
post_update_to_api "failed" $exit_code
|
||||
|
||||
# Use standard error handler
|
||||
error_handler $exit_code $command
|
||||
}
|
||||
```
|
||||
|
||||
### With install.func
|
||||
|
||||
#### Installation Process Reporting
|
||||
```bash
|
||||
# install.func uses api.func for installation reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source install.func
|
||||
|
||||
# Installation with API reporting
|
||||
install_package_with_reporting() {
|
||||
local package="$1"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="$package"
|
||||
export METHOD="install"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Package installation using install.func
|
||||
if install_package "$package"; then
|
||||
echo "$package installed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "$package installation failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
### With alpine-install.func
|
||||
|
||||
#### Alpine Installation Reporting
|
||||
```bash
|
||||
# alpine-install.func uses api.func for Alpine reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source alpine-install.func
|
||||
|
||||
# Alpine installation with API reporting
|
||||
install_alpine_with_reporting() {
|
||||
local app="$1"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="$app"
|
||||
export METHOD="install"
|
||||
export var_os="alpine"
|
||||
|
||||
# Report Alpine installation start
|
||||
post_to_api
|
||||
|
||||
# Alpine installation using alpine-install.func
|
||||
if install_alpine_app "$app"; then
|
||||
echo "Alpine $app installed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Alpine $app installation failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
### With alpine-tools.func
|
||||
|
||||
#### Alpine Tools Reporting
|
||||
```bash
|
||||
# alpine-tools.func uses api.func for Alpine tools reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source alpine-tools.func
|
||||
|
||||
# Alpine tools with API reporting
|
||||
run_alpine_tool_with_reporting() {
|
||||
local tool="$1"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="alpine-tools"
|
||||
export METHOD="tool"
|
||||
|
||||
# Report tool execution start
|
||||
post_to_api
|
||||
|
||||
# Run Alpine tool using alpine-tools.func
|
||||
if run_alpine_tool "$tool"; then
|
||||
echo "Alpine tool $tool executed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Alpine tool $tool failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
### With passthrough.func
|
||||
|
||||
#### Hardware Passthrough Reporting
|
||||
```bash
|
||||
# passthrough.func uses api.func for hardware reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source passthrough.func
|
||||
|
||||
# Hardware passthrough with API reporting
|
||||
configure_passthrough_with_reporting() {
|
||||
local hardware_type="$1"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="passthrough"
|
||||
export METHOD="hardware"
|
||||
|
||||
# Report passthrough configuration start
|
||||
post_to_api
|
||||
|
||||
# Configure passthrough using passthrough.func
|
||||
if configure_passthrough "$hardware_type"; then
|
||||
echo "Hardware passthrough configured successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Hardware passthrough failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
### With tools.func
|
||||
|
||||
#### Maintenance Operations Reporting
|
||||
```bash
|
||||
# tools.func uses api.func for maintenance reporting
|
||||
source core.func
|
||||
source api.func
|
||||
source tools.func
|
||||
|
||||
# Maintenance operations with API reporting
|
||||
run_maintenance_with_reporting() {
|
||||
local operation="$1"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="maintenance"
|
||||
export METHOD="tool"
|
||||
|
||||
# Report maintenance start
|
||||
post_to_api
|
||||
|
||||
# Run maintenance using tools.func
|
||||
if run_maintenance_operation "$operation"; then
|
||||
echo "Maintenance operation $operation completed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Maintenance operation $operation failed: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
## Data Flow
|
||||
|
||||
### Input Data
|
||||
|
||||
#### Environment Variables from Other Scripts
|
||||
- **`CT_TYPE`**: Container type (1 for LXC, 2 for VM)
|
||||
- **`DISK_SIZE`**: Disk size in GB
|
||||
- **`CORE_COUNT`**: Number of CPU cores
|
||||
- **`RAM_SIZE`**: RAM size in MB
|
||||
- **`var_os`**: Operating system type
|
||||
- **`var_version`**: OS version
|
||||
- **`DISABLEIP6`**: IPv6 disable setting
|
||||
- **`NSAPP`**: Namespace application name
|
||||
- **`METHOD`**: Installation method
|
||||
- **`DIAGNOSTICS`**: Enable/disable diagnostic reporting
|
||||
- **`RANDOM_UUID`**: Unique identifier for tracking
|
||||
|
||||
#### Function Parameters
|
||||
- **Exit codes**: Passed to `get_error_description()` and `post_update_to_api()`
|
||||
- **Status information**: Passed to `post_update_to_api()`
|
||||
- **API endpoints**: Hardcoded in functions
|
||||
|
||||
#### System Information
|
||||
- **PVE version**: Retrieved from `pveversion` command
|
||||
- **Disk size processing**: Processed for VM API (removes 'G' suffix)
|
||||
- **Error codes**: Retrieved from command exit codes
|
||||
|
||||
### Processing Data
|
||||
|
||||
#### API Request Preparation
|
||||
- **JSON payload creation**: Format data for API consumption
|
||||
- **Data validation**: Ensure required fields are present
|
||||
- **Error handling**: Handle missing or invalid data
|
||||
- **Content type setting**: Set appropriate HTTP headers
|
||||
|
||||
#### Error Processing
|
||||
- **Error code mapping**: Map numeric codes to descriptions
|
||||
- **Error message formatting**: Format error descriptions
|
||||
- **Unknown error handling**: Handle unrecognized error codes
|
||||
- **Fallback messages**: Provide default error messages
|
||||
|
||||
#### API Communication
|
||||
- **HTTP request preparation**: Prepare curl commands
|
||||
- **Response handling**: Capture HTTP response codes
|
||||
- **Error handling**: Handle network and API errors
|
||||
- **Duplicate prevention**: Prevent duplicate status updates
|
||||
|
||||
### Output Data
|
||||
|
||||
#### API Communication
|
||||
- **HTTP requests**: Sent to community-scripts.org API
|
||||
- **Response codes**: Captured from API responses
|
||||
- **Error information**: Reported to API
|
||||
- **Status updates**: Sent to API
|
||||
|
||||
#### Error Information
|
||||
- **Error descriptions**: Human-readable error messages
|
||||
- **Error codes**: Mapped to descriptions
|
||||
- **Context information**: Error context and details
|
||||
- **Fallback messages**: Default error messages
|
||||
|
||||
#### System State
|
||||
- **POST_UPDATE_DONE**: Prevents duplicate updates
|
||||
- **RESPONSE**: Stores API response
|
||||
- **JSON_PAYLOAD**: Stores formatted API data
|
||||
- **API_URL**: Stores API endpoint
|
||||
|
||||
## API Surface
|
||||
|
||||
### Public Functions
|
||||
|
||||
#### Error Description
|
||||
- **`get_error_description()`**: Convert exit codes to explanations
|
||||
- **Parameters**: Exit code to explain
|
||||
- **Returns**: Human-readable explanation string
|
||||
- **Usage**: Called by other functions and scripts
|
||||
|
||||
#### API Communication
|
||||
- **`post_to_api()`**: Send LXC installation data
|
||||
- **`post_to_api_vm()`**: Send VM installation data
|
||||
- **`post_update_to_api()`**: Send status updates
|
||||
- **Parameters**: Status and exit code (for updates)
|
||||
- **Returns**: None
|
||||
- **Usage**: Called by installation scripts
|
||||
|
||||
### Internal Functions
|
||||
|
||||
#### None
|
||||
- All functions in api.func are public
|
||||
- No internal helper functions
|
||||
- Direct implementation of all functionality
|
||||
|
||||
### Global Variables
|
||||
|
||||
#### Configuration Variables
|
||||
- **`DIAGNOSTICS`**: Diagnostic reporting setting
|
||||
- **`RANDOM_UUID`**: Unique tracking identifier
|
||||
- **`POST_UPDATE_DONE`**: Duplicate update prevention
|
||||
|
||||
#### Data Variables
|
||||
- **`CT_TYPE`**: Container type
|
||||
- **`DISK_SIZE`**: Disk size
|
||||
- **`CORE_COUNT`**: CPU core count
|
||||
- **`RAM_SIZE`**: RAM size
|
||||
- **`var_os`**: Operating system
|
||||
- **`var_version`**: OS version
|
||||
- **`DISABLEIP6`**: IPv6 setting
|
||||
- **`NSAPP`**: Application namespace
|
||||
- **`METHOD`**: Installation method
|
||||
|
||||
#### Internal Variables
|
||||
- **`API_URL`**: API endpoint URL
|
||||
- **`JSON_PAYLOAD`**: API request payload
|
||||
- **`RESPONSE`**: API response
|
||||
- **`DISK_SIZE_API`**: Processed disk size for VM API
|
||||
|
||||
## Integration Patterns
|
||||
|
||||
### Standard Integration Pattern
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Standard integration pattern
|
||||
|
||||
# 1. Source core.func first
|
||||
source core.func
|
||||
|
||||
# 2. Source api.func
|
||||
source api.func
|
||||
|
||||
# 3. Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# 4. Set application parameters
|
||||
export NSAPP="$APP"
|
||||
export METHOD="install"
|
||||
|
||||
# 5. Report installation start
|
||||
post_to_api
|
||||
|
||||
# 6. Perform installation
|
||||
# ... installation logic ...
|
||||
|
||||
# 7. Report completion
|
||||
post_update_to_api "success" 0
|
||||
```
|
||||
|
||||
### Minimal Integration Pattern
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Minimal integration pattern
|
||||
|
||||
source api.func
|
||||
|
||||
# Basic error reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Report failure
|
||||
post_update_to_api "failed" 127
|
||||
```
|
||||
|
||||
### Advanced Integration Pattern
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Advanced integration pattern
|
||||
|
||||
source core.func
|
||||
source api.func
|
||||
source error_handler.func
|
||||
|
||||
# Set up comprehensive API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE=8
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export METHOD="install"
|
||||
|
||||
# Enhanced error handling with API reporting
|
||||
enhanced_error_handler() {
|
||||
local exit_code=${1:-$?}
|
||||
local command=${2:-${BASH_COMMAND:-unknown}}
|
||||
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Error $exit_code: $error_msg"
|
||||
|
||||
post_update_to_api "failed" $exit_code
|
||||
error_handler $exit_code $command
|
||||
}
|
||||
|
||||
trap 'enhanced_error_handler' ERR
|
||||
|
||||
# Advanced operations with API reporting
|
||||
post_to_api
|
||||
# ... operations ...
|
||||
post_update_to_api "success" 0
|
||||
```
|
||||
|
||||
## Error Handling Integration
|
||||
|
||||
### Automatic Error Reporting
|
||||
- **Error Descriptions**: Provides human-readable error messages
|
||||
- **API Integration**: Reports errors to community-scripts.org API
|
||||
- **Error Tracking**: Tracks error patterns for project improvement
|
||||
- **Diagnostic Data**: Contributes to anonymous usage analytics
|
||||
|
||||
### Manual Error Reporting
|
||||
- **Custom Error Codes**: Use appropriate error codes for different scenarios
|
||||
- **Error Context**: Provide context information for errors
|
||||
- **Status Updates**: Report both success and failure cases
|
||||
- **Error Analysis**: Analyze error patterns and trends
|
||||
|
||||
### API Communication Errors
|
||||
- **Network Failures**: Handle API communication failures gracefully
|
||||
- **Missing Prerequisites**: Check prerequisites before API calls
|
||||
- **Duplicate Prevention**: Prevent duplicate status updates
|
||||
- **Error Recovery**: Handle API errors without blocking installation
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### API Communication Overhead
|
||||
- **Minimal Impact**: API calls add minimal overhead
|
||||
- **Asynchronous**: API calls don't block installation process
|
||||
- **Error Handling**: API failures don't affect installation
|
||||
- **Optional**: API reporting is optional and can be disabled
|
||||
|
||||
### Memory Usage
|
||||
- **Minimal Footprint**: API functions use minimal memory
|
||||
- **Variable Reuse**: Global variables reused across functions
|
||||
- **No Memory Leaks**: Proper cleanup prevents memory leaks
|
||||
- **Efficient Processing**: Efficient JSON payload creation
|
||||
|
||||
### Execution Speed
|
||||
- **Fast API Calls**: Quick API communication
|
||||
- **Efficient Error Processing**: Fast error code processing
|
||||
- **Minimal Delay**: Minimal delay in API operations
|
||||
- **Non-blocking**: API calls don't block installation
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Data Privacy
|
||||
- **Anonymous Reporting**: Only anonymous data is sent
|
||||
- **No Sensitive Data**: No sensitive information is transmitted
|
||||
- **User Control**: Users can disable diagnostic reporting
|
||||
- **Data Minimization**: Only necessary data is sent
|
||||
|
||||
### API Security
|
||||
- **HTTPS**: API communication uses secure protocols
|
||||
- **Data Validation**: API data is validated before sending
|
||||
- **Error Handling**: API errors are handled securely
|
||||
- **No Credentials**: No authentication credentials are sent
|
||||
|
||||
### Network Security
|
||||
- **Secure Communication**: Uses secure HTTP protocols
|
||||
- **Error Handling**: Network errors are handled gracefully
|
||||
- **No Data Leakage**: No sensitive data is leaked
|
||||
- **Secure Endpoints**: Uses trusted API endpoints
|
||||
|
||||
## Future Integration Considerations
|
||||
|
||||
### Extensibility
|
||||
- **New API Endpoints**: Easy to add new API endpoints
|
||||
- **Additional Data**: Easy to add new data fields
|
||||
- **Error Codes**: Easy to add new error code descriptions
|
||||
- **API Versions**: Easy to support new API versions
|
||||
|
||||
### Compatibility
|
||||
- **API Versioning**: Compatible with different API versions
|
||||
- **Data Format**: Compatible with different data formats
|
||||
- **Error Codes**: Compatible with different error code systems
|
||||
- **Network Protocols**: Compatible with different network protocols
|
||||
|
||||
### Performance
|
||||
- **Optimization**: API communication can be optimized
|
||||
- **Caching**: API responses can be cached
|
||||
- **Batch Operations**: Multiple operations can be batched
|
||||
- **Async Processing**: API calls can be made asynchronous
|
||||
@@ -1,794 +0,0 @@
|
||||
# api.func Usage Examples
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides practical usage examples for `api.func` functions, covering common scenarios, integration patterns, and best practices.
|
||||
|
||||
## Basic API Setup
|
||||
|
||||
### Standard API Initialization
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Standard API setup for LXC containers
|
||||
|
||||
source api.func
|
||||
|
||||
# Set up diagnostic reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Set container parameters
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE=8
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export NSAPP="plex"
|
||||
export METHOD="install"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Your installation code here
|
||||
# ... installation logic ...
|
||||
|
||||
# Report completion
|
||||
if [[ $? -eq 0 ]]; then
|
||||
post_update_to_api "success" 0
|
||||
else
|
||||
post_update_to_api "failed" $?
|
||||
fi
|
||||
```
|
||||
|
||||
### VM API Setup
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# API setup for VMs
|
||||
|
||||
source api.func
|
||||
|
||||
# Create diagnostics file for VM
|
||||
mkdir -p /usr/local/community-scripts
|
||||
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics
|
||||
|
||||
# Set up VM parameters
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export DISK_SIZE="20G"
|
||||
export CORE_COUNT=4
|
||||
export RAM_SIZE=4096
|
||||
export var_os="ubuntu"
|
||||
export var_version="22.04"
|
||||
export NSAPP="nextcloud"
|
||||
export METHOD="install"
|
||||
|
||||
# Report VM installation start
|
||||
post_to_api_vm
|
||||
|
||||
# Your VM installation code here
|
||||
# ... VM creation logic ...
|
||||
|
||||
# Report completion
|
||||
post_update_to_api "success" 0
|
||||
```
|
||||
|
||||
## Error Description Examples
|
||||
|
||||
### Basic Error Explanation
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Explain common error codes
|
||||
echo "Error 0: '$(get_error_description 0)'"
|
||||
echo "Error 1: $(get_error_description 1)"
|
||||
echo "Error 127: $(get_error_description 127)"
|
||||
echo "Error 200: $(get_error_description 200)"
|
||||
echo "Error 255: $(get_error_description 255)"
|
||||
```
|
||||
|
||||
### Error Code Testing
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Test all error codes
|
||||
test_error_codes() {
|
||||
local codes=(0 1 2 127 128 130 137 139 143 200 203 205 255)
|
||||
|
||||
for code in "${codes[@]}"; do
|
||||
echo "Code $code: $(get_error_description $code)"
|
||||
done
|
||||
}
|
||||
|
||||
test_error_codes
|
||||
```
|
||||
|
||||
### Error Handling with Descriptions
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Function with error handling
|
||||
run_command_with_error_handling() {
|
||||
local command="$1"
|
||||
local description="$2"
|
||||
|
||||
echo "Running: $description"
|
||||
|
||||
if $command; then
|
||||
echo "Success: $description"
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Error $exit_code: $error_msg"
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage
|
||||
run_command_with_error_handling "apt-get update" "Package list update"
|
||||
run_command_with_error_handling "nonexistent_command" "Test command"
|
||||
```
|
||||
|
||||
## API Communication Examples
|
||||
|
||||
### LXC Installation Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Complete LXC installation with API reporting
|
||||
install_lxc_with_reporting() {
|
||||
local app="$1"
|
||||
local ctid="$2"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE=10
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export NSAPP="$app"
|
||||
export METHOD="install"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Installation process
|
||||
echo "Installing $app container (ID: $ctid)..."
|
||||
|
||||
# Simulate installation
|
||||
sleep 2
|
||||
|
||||
# Check if installation succeeded
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "Installation completed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
echo "Installation failed"
|
||||
post_update_to_api "failed" $?
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install multiple containers
|
||||
install_lxc_with_reporting "plex" "100"
|
||||
install_lxc_with_reporting "nextcloud" "101"
|
||||
install_lxc_with_reporting "nginx" "102"
|
||||
```
|
||||
|
||||
### VM Installation Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Complete VM installation with API reporting
|
||||
install_vm_with_reporting() {
|
||||
local app="$1"
|
||||
local vmid="$2"
|
||||
|
||||
# Create diagnostics file
|
||||
mkdir -p /usr/local/community-scripts
|
||||
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics
|
||||
|
||||
# Set up API reporting
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export DISK_SIZE="20G"
|
||||
export CORE_COUNT=4
|
||||
export RAM_SIZE=4096
|
||||
export var_os="ubuntu"
|
||||
export var_version="22.04"
|
||||
export NSAPP="$app"
|
||||
export METHOD="install"
|
||||
|
||||
# Report VM installation start
|
||||
post_to_api_vm
|
||||
|
||||
# VM installation process
|
||||
echo "Installing $app VM (ID: $vmid)..."
|
||||
|
||||
# Simulate VM creation
|
||||
sleep 3
|
||||
|
||||
# Check if VM creation succeeded
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "VM installation completed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
echo "VM installation failed"
|
||||
post_update_to_api "failed" $?
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install multiple VMs
|
||||
install_vm_with_reporting "nextcloud" "200"
|
||||
install_vm_with_reporting "wordpress" "201"
|
||||
```
|
||||
|
||||
## Status Update Examples
|
||||
|
||||
### Success Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Report successful installation
|
||||
report_success() {
|
||||
local operation="$1"
|
||||
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
echo "Reporting successful $operation"
|
||||
post_update_to_api "success" 0
|
||||
}
|
||||
|
||||
# Usage
|
||||
report_success "container installation"
|
||||
report_success "package installation"
|
||||
report_success "service configuration"
|
||||
```
|
||||
|
||||
### Failure Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Report failed installation
|
||||
report_failure() {
|
||||
local operation="$1"
|
||||
local exit_code="$2"
|
||||
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Reporting failed $operation: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
}
|
||||
|
||||
# Usage
|
||||
report_failure "container creation" 200
|
||||
report_failure "package installation" 127
|
||||
report_failure "service start" 1
|
||||
```
|
||||
|
||||
### Conditional Status Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Conditional status reporting
|
||||
report_installation_status() {
|
||||
local operation="$1"
|
||||
local exit_code="$2"
|
||||
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
if [[ $exit_code -eq 0 ]]; then
|
||||
echo "Reporting successful $operation"
|
||||
post_update_to_api "success" 0
|
||||
else
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Reporting failed $operation: $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage
|
||||
report_installation_status "container creation" 0
|
||||
report_installation_status "package installation" 127
|
||||
```
|
||||
|
||||
## Advanced Usage Examples
|
||||
|
||||
### Batch Installation with API Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Batch installation with comprehensive API reporting
|
||||
batch_install_with_reporting() {
|
||||
local apps=("plex" "nextcloud" "nginx" "mysql")
|
||||
local ctids=(100 101 102 103)
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE=8
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export METHOD="install"
|
||||
|
||||
local success_count=0
|
||||
local failure_count=0
|
||||
|
||||
for i in "${!apps[@]}"; do
|
||||
local app="${apps[$i]}"
|
||||
local ctid="${ctids[$i]}"
|
||||
|
||||
echo "Installing $app (ID: $ctid)..."
|
||||
|
||||
# Set app-specific parameters
|
||||
export NSAPP="$app"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Simulate installation
|
||||
if install_app "$app" "$ctid"; then
|
||||
echo "$app installed successfully"
|
||||
post_update_to_api "success" 0
|
||||
((success_count++))
|
||||
else
|
||||
echo "$app installation failed"
|
||||
post_update_to_api "failed" $?
|
||||
((failure_count++))
|
||||
fi
|
||||
|
||||
echo "---"
|
||||
done
|
||||
|
||||
echo "Batch installation completed: $success_count successful, $failure_count failed"
|
||||
}
|
||||
|
||||
# Mock installation function
|
||||
install_app() {
|
||||
local app="$1"
|
||||
local ctid="$2"
|
||||
|
||||
# Simulate installation
|
||||
sleep 1
|
||||
|
||||
# Simulate occasional failures
|
||||
if [[ $((RANDOM % 10)) -eq 0 ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
batch_install_with_reporting
|
||||
```
|
||||
|
||||
### Error Analysis and Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Analyze and report errors
|
||||
analyze_and_report_errors() {
|
||||
local log_file="$1"
|
||||
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
if [[ ! -f "$log_file" ]]; then
|
||||
echo "Log file not found: $log_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract error codes from log
|
||||
local error_codes=$(grep -o 'exit code [0-9]\+' "$log_file" | grep -o '[0-9]\+' | sort -u)
|
||||
|
||||
if [[ -z "$error_codes" ]]; then
|
||||
echo "No errors found in log"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Found error codes: $error_codes"
|
||||
|
||||
# Report each unique error
|
||||
for code in $error_codes; do
|
||||
local error_msg=$(get_error_description $code)
|
||||
echo "Error $code: $error_msg"
|
||||
post_update_to_api "failed" $code
|
||||
done
|
||||
}
|
||||
|
||||
# Usage
|
||||
analyze_and_report_errors "/var/log/installation.log"
|
||||
```
|
||||
|
||||
### API Health Check
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Check API connectivity and functionality
|
||||
check_api_health() {
|
||||
echo "Checking API health..."
|
||||
|
||||
# Test prerequisites
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "ERROR: curl not available"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Test error description function
|
||||
local test_error=$(get_error_description 127)
|
||||
if [[ -z "$test_error" ]]; then
|
||||
echo "ERROR: Error description function not working"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Error description test: $test_error"
|
||||
|
||||
# Test API connectivity (without sending data)
|
||||
local api_url="https://api.community-scripts.org/dev/upload"
|
||||
if curl -s --head "$api_url" >/dev/null 2>&1; then
|
||||
echo "API endpoint is reachable"
|
||||
else
|
||||
echo "WARNING: API endpoint not reachable"
|
||||
fi
|
||||
|
||||
echo "API health check completed"
|
||||
}
|
||||
|
||||
check_api_health
|
||||
```
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### With build.func
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Integration with build.func
|
||||
|
||||
source core.func
|
||||
source api.func
|
||||
source build.func
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Container creation with API reporting
|
||||
create_container_with_reporting() {
|
||||
local app="$1"
|
||||
local ctid="$2"
|
||||
|
||||
# Set container parameters
|
||||
export APP="$app"
|
||||
export CTID="$ctid"
|
||||
export var_hostname="${app}-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.$ctid"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Create container using build.func
|
||||
if source build.func; then
|
||||
echo "Container $app created successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
echo "Container $app creation failed"
|
||||
post_update_to_api "failed" $?
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Create containers
|
||||
create_container_with_reporting "plex" "100"
|
||||
create_container_with_reporting "nextcloud" "101"
|
||||
```
|
||||
|
||||
### With vm-core.func
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Integration with vm-core.func
|
||||
|
||||
source core.func
|
||||
source api.func
|
||||
source vm-core.func
|
||||
|
||||
# Set up VM API reporting
|
||||
mkdir -p /usr/local/community-scripts
|
||||
echo "DIAGNOSTICS=yes" > /usr/local/community-scripts/diagnostics
|
||||
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# VM creation with API reporting
|
||||
create_vm_with_reporting() {
|
||||
local app="$1"
|
||||
local vmid="$2"
|
||||
|
||||
# Set VM parameters
|
||||
export APP="$app"
|
||||
export VMID="$vmid"
|
||||
export var_hostname="${app}-vm"
|
||||
export var_os="ubuntu"
|
||||
export var_version="22.04"
|
||||
export var_cpu="4"
|
||||
export var_ram="4096"
|
||||
export var_disk="20"
|
||||
|
||||
# Report VM installation start
|
||||
post_to_api_vm
|
||||
|
||||
# Create VM using vm-core.func
|
||||
if source vm-core.func; then
|
||||
echo "VM $app created successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
echo "VM $app creation failed"
|
||||
post_update_to_api "failed" $?
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Create VMs
|
||||
create_vm_with_reporting "nextcloud" "200"
|
||||
create_vm_with_reporting "wordpress" "201"
|
||||
```
|
||||
|
||||
### With error_handler.func
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Integration with error_handler.func
|
||||
|
||||
source core.func
|
||||
source error_handler.func
|
||||
source api.func
|
||||
|
||||
# Enhanced error handling with API reporting
|
||||
enhanced_error_handler() {
|
||||
local exit_code=${1:-$?}
|
||||
local command=${2:-${BASH_COMMAND:-unknown}}
|
||||
|
||||
# Get error description from api.func
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
|
||||
# Display error information
|
||||
echo "Error $exit_code: $error_msg"
|
||||
echo "Command: $command"
|
||||
|
||||
# Report error to API
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
post_update_to_api "failed" $exit_code
|
||||
|
||||
# Use standard error handler
|
||||
error_handler $exit_code $command
|
||||
}
|
||||
|
||||
# Set up enhanced error handling
|
||||
trap 'enhanced_error_handler' ERR
|
||||
|
||||
# Test enhanced error handling
|
||||
nonexistent_command
|
||||
```
|
||||
|
||||
## Best Practices Examples
|
||||
|
||||
### Comprehensive API Integration
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Comprehensive API integration example
|
||||
|
||||
source core.func
|
||||
source api.func
|
||||
|
||||
# Set up comprehensive API reporting
|
||||
setup_api_reporting() {
|
||||
# Enable diagnostics
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Set common parameters
|
||||
export CT_TYPE=1
|
||||
export DISK_SIZE=8
|
||||
export CORE_COUNT=2
|
||||
export RAM_SIZE=2048
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export METHOD="install"
|
||||
|
||||
echo "API reporting configured"
|
||||
}
|
||||
|
||||
# Installation with comprehensive reporting
|
||||
install_with_comprehensive_reporting() {
|
||||
local app="$1"
|
||||
local ctid="$2"
|
||||
|
||||
# Set up API reporting
|
||||
setup_api_reporting
|
||||
export NSAPP="$app"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Installation process
|
||||
echo "Installing $app..."
|
||||
|
||||
# Simulate installation steps
|
||||
local steps=("Downloading" "Installing" "Configuring" "Starting")
|
||||
for step in "${steps[@]}"; do
|
||||
echo "$step $app..."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Check installation result
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo "$app installation completed successfully"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
echo "$app installation failed"
|
||||
post_update_to_api "failed" $?
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Install multiple applications
|
||||
apps=("plex" "nextcloud" "nginx" "mysql")
|
||||
ctids=(100 101 102 103)
|
||||
|
||||
for i in "${!apps[@]}"; do
|
||||
install_with_comprehensive_reporting "${apps[$i]}" "${ctids[$i]}"
|
||||
echo "---"
|
||||
done
|
||||
```
|
||||
|
||||
### Error Recovery with API Reporting
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Error recovery with API reporting
|
||||
retry_with_api_reporting() {
|
||||
local operation="$1"
|
||||
local max_attempts=3
|
||||
local attempt=1
|
||||
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
while [[ $attempt -le $max_attempts ]]; do
|
||||
echo "Attempt $attempt of $max_attempts: $operation"
|
||||
|
||||
if $operation; then
|
||||
echo "Operation succeeded on attempt $attempt"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "Attempt $attempt failed: $error_msg"
|
||||
|
||||
post_update_to_api "failed" $exit_code
|
||||
|
||||
((attempt++))
|
||||
|
||||
if [[ $attempt -le $max_attempts ]]; then
|
||||
echo "Retrying in 5 seconds..."
|
||||
sleep 5
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Operation failed after $max_attempts attempts"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Usage
|
||||
retry_with_api_reporting "apt-get update"
|
||||
retry_with_api_reporting "apt-get install -y package"
|
||||
```
|
||||
|
||||
### API Reporting with Logging
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# API reporting with detailed logging
|
||||
install_with_logging_and_api() {
|
||||
local app="$1"
|
||||
local log_file="/var/log/${app}_installation.log"
|
||||
|
||||
# Set up API reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
export NSAPP="$app"
|
||||
|
||||
# Start logging
|
||||
exec > >(tee -a "$log_file")
|
||||
exec 2>&1
|
||||
|
||||
echo "Starting $app installation at $(date)"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
|
||||
# Installation process
|
||||
echo "Installing $app..."
|
||||
|
||||
# Simulate installation
|
||||
if install_app "$app"; then
|
||||
echo "$app installation completed successfully at $(date)"
|
||||
post_update_to_api "success" 0
|
||||
return 0
|
||||
else
|
||||
local exit_code=$?
|
||||
local error_msg=$(get_error_description $exit_code)
|
||||
echo "$app installation failed at $(date): $error_msg"
|
||||
post_update_to_api "failed" $exit_code
|
||||
return $exit_code
|
||||
fi
|
||||
}
|
||||
|
||||
# Mock installation function
|
||||
install_app() {
|
||||
local app="$1"
|
||||
echo "Installing $app..."
|
||||
sleep 2
|
||||
return 0
|
||||
}
|
||||
|
||||
# Install with logging and API reporting
|
||||
install_with_logging_and_api "plex"
|
||||
```
|
||||
@@ -1,199 +0,0 @@
|
||||
# api.func Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
The `api.func` file provides Proxmox API integration and diagnostic reporting functionality for the Community Scripts project. It handles API communication, error reporting, and status updates to the community-scripts.org API.
|
||||
|
||||
## Purpose and Use Cases
|
||||
|
||||
- **API Communication**: Send installation and status data to community-scripts.org API
|
||||
- **Diagnostic Reporting**: Report installation progress and errors for analytics
|
||||
- **Error Description**: Provide detailed error code explanations
|
||||
- **Status Updates**: Track installation success/failure status
|
||||
- **Analytics**: Contribute anonymous usage data for project improvement
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Key Function Groups
|
||||
- **Error Handling**: `get_error_description()` - Convert exit codes to human-readable messages
|
||||
- **API Communication**: `post_to_api()`, `post_to_api_vm()` - Send installation data
|
||||
- **Status Updates**: `post_update_to_api()` - Report installation completion status
|
||||
|
||||
### Dependencies
|
||||
- **External**: `curl` command for HTTP requests
|
||||
- **Internal**: Uses environment variables from other scripts
|
||||
|
||||
### Integration Points
|
||||
- Used by: All installation scripts for diagnostic reporting
|
||||
- Uses: Environment variables from build.func and other scripts
|
||||
- Provides: API communication and error reporting services
|
||||
|
||||
## Documentation Files
|
||||
|
||||
### 📊 [API_FLOWCHART.md](./API_FLOWCHART.md)
|
||||
Visual execution flows showing API communication processes and error handling.
|
||||
|
||||
### 📚 [API_FUNCTIONS_REFERENCE.md](./API_FUNCTIONS_REFERENCE.md)
|
||||
Complete alphabetical reference of all functions with parameters, dependencies, and usage details.
|
||||
|
||||
### 💡 [API_USAGE_EXAMPLES.md](./API_USAGE_EXAMPLES.md)
|
||||
Practical examples showing how to use API functions and common patterns.
|
||||
|
||||
### 🔗 [API_INTEGRATION.md](./API_INTEGRATION.md)
|
||||
How api.func integrates with other components and provides API services.
|
||||
|
||||
## Key Features
|
||||
|
||||
### Error Code Descriptions
|
||||
- **Comprehensive Coverage**: 50+ error codes with detailed explanations
|
||||
- **LXC-Specific Errors**: Container creation and management errors
|
||||
- **System Errors**: General system and network errors
|
||||
- **Signal Errors**: Process termination and signal errors
|
||||
|
||||
### API Communication
|
||||
- **LXC Reporting**: Send LXC container installation data
|
||||
- **VM Reporting**: Send VM installation data
|
||||
- **Status Updates**: Report installation success/failure
|
||||
- **Diagnostic Data**: Anonymous usage analytics
|
||||
|
||||
### Diagnostic Integration
|
||||
- **Optional Reporting**: Only sends data when diagnostics enabled
|
||||
- **Privacy Respect**: Respects user privacy settings
|
||||
- **Error Tracking**: Tracks installation errors for improvement
|
||||
- **Usage Analytics**: Contributes to project statistics
|
||||
|
||||
## Common Usage Patterns
|
||||
|
||||
### Basic API Setup
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# Basic API setup
|
||||
|
||||
source api.func
|
||||
|
||||
# Set up diagnostic reporting
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
|
||||
# Report installation start
|
||||
post_to_api
|
||||
```
|
||||
|
||||
### Error Reporting
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Get error description
|
||||
error_msg=$(get_error_description 127)
|
||||
echo "Error 127: $error_msg"
|
||||
# Output: Error 127: Command not found: Incorrect path or missing dependency.
|
||||
```
|
||||
|
||||
### Status Updates
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
source api.func
|
||||
|
||||
# Report successful installation
|
||||
post_update_to_api "success" 0
|
||||
|
||||
# Report failed installation
|
||||
post_update_to_api "failed" 127
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
### Required Variables
|
||||
- `DIAGNOSTICS`: Enable/disable diagnostic reporting ("yes"/"no")
|
||||
- `RANDOM_UUID`: Unique identifier for tracking
|
||||
|
||||
### Optional Variables
|
||||
- `CT_TYPE`: Container type (1 for LXC, 2 for VM)
|
||||
- `DISK_SIZE`: Disk size in GB
|
||||
- `CORE_COUNT`: Number of CPU cores
|
||||
- `RAM_SIZE`: RAM size in MB
|
||||
- `var_os`: Operating system type
|
||||
- `var_version`: OS version
|
||||
- `DISABLEIP6`: IPv6 disable setting
|
||||
- `NSAPP`: Namespace application name
|
||||
- `METHOD`: Installation method
|
||||
|
||||
### Internal Variables
|
||||
- `POST_UPDATE_DONE`: Prevents duplicate status updates
|
||||
- `API_URL`: Community scripts API endpoint
|
||||
- `JSON_PAYLOAD`: API request payload
|
||||
- `RESPONSE`: API response
|
||||
|
||||
## Error Code Categories
|
||||
|
||||
### General System Errors
|
||||
- **0-9**: Basic system errors
|
||||
- **18, 22, 28, 35**: Network and I/O errors
|
||||
- **56, 60**: TLS/SSL errors
|
||||
- **125-128**: Command execution errors
|
||||
- **129-143**: Signal errors
|
||||
- **152**: Resource limit errors
|
||||
- **255**: Unknown critical errors
|
||||
|
||||
### LXC-Specific Errors
|
||||
- **100-101**: LXC installation errors
|
||||
- **200-209**: LXC creation and management errors
|
||||
|
||||
### Docker Errors
|
||||
- **125**: Docker container start errors
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Diagnostic Reporting
|
||||
1. Always check if diagnostics are enabled
|
||||
2. Respect user privacy settings
|
||||
3. Use unique identifiers for tracking
|
||||
4. Report both success and failure cases
|
||||
|
||||
### Error Handling
|
||||
1. Use appropriate error codes
|
||||
2. Provide meaningful error descriptions
|
||||
3. Handle API communication failures gracefully
|
||||
4. Don't block installation on API failures
|
||||
|
||||
### API Usage
|
||||
1. Check for curl availability
|
||||
2. Handle network failures gracefully
|
||||
3. Use appropriate HTTP methods
|
||||
4. Include all required data
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
1. **API Communication Fails**: Check network connectivity and curl availability
|
||||
2. **Diagnostics Not Working**: Verify DIAGNOSTICS setting and RANDOM_UUID
|
||||
3. **Missing Error Descriptions**: Check error code coverage
|
||||
4. **Duplicate Updates**: POST_UPDATE_DONE prevents duplicates
|
||||
|
||||
### Debug Mode
|
||||
Enable diagnostic reporting for debugging:
|
||||
```bash
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="$(uuidgen)"
|
||||
```
|
||||
|
||||
### API Testing
|
||||
Test API communication:
|
||||
```bash
|
||||
source api.func
|
||||
export DIAGNOSTICS="yes"
|
||||
export RANDOM_UUID="test-$(date +%s)"
|
||||
post_to_api
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [core.func](../core.func/) - Core utilities and error handling
|
||||
- [error_handler.func](../error_handler.func/) - Error handling utilities
|
||||
- [build.func](../build.func/) - Container creation with API integration
|
||||
- [tools.func](../tools.func/) - Extended utilities with API integration
|
||||
|
||||
---
|
||||
|
||||
*This documentation covers the api.func file which provides API communication and diagnostic reporting for all Proxmox Community Scripts.*
|
||||
@@ -1,164 +0,0 @@
|
||||
# Advanced Settings Wizard Reference
|
||||
|
||||
## Overview
|
||||
|
||||
The Advanced Settings wizard provides a 28-step interactive configuration for LXC container creation. It allows users to customize every aspect of the container while inheriting sensible defaults from the CT script.
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Inherit App Defaults**: All `var_*` values from CT scripts pre-populate wizard fields
|
||||
- **Back Navigation**: Press Cancel/Back to return to previous step
|
||||
- **App Default Hints**: Each dialog shows `(App default: X)` to indicate script defaults
|
||||
- **Full Customization**: Every configurable option is accessible
|
||||
|
||||
## Wizard Steps
|
||||
|
||||
| Step | Title | Variable(s) | Description |
|
||||
| ---- | ------------------------ | --------------------------------- | ----------------------------------------------------- |
|
||||
| 1 | Container Type | `var_unprivileged` | Privileged (0) or Unprivileged (1) container |
|
||||
| 2 | Root Password | `var_pw` | Set password or use automatic login |
|
||||
| 3 | Container ID | `var_ctid` | Unique container ID (auto-suggested) |
|
||||
| 4 | Hostname | `var_hostname` | Container hostname |
|
||||
| 5 | Disk Size | `var_disk` | Disk size in GB |
|
||||
| 6 | CPU Cores | `var_cpu` | Number of CPU cores |
|
||||
| 7 | RAM Size | `var_ram` | RAM size in MiB |
|
||||
| 8 | Network Bridge | `var_brg` | Network bridge (vmbr0, etc.) |
|
||||
| 9 | IPv4 Configuration | `var_net`, `var_gateway` | DHCP or static IP with gateway |
|
||||
| 10 | IPv6 Configuration | `var_ipv6_method` | Auto, DHCP, Static, or None |
|
||||
| 11 | MTU Size | `var_mtu` | Network MTU (default: 1500) |
|
||||
| 12 | DNS Search Domain | `var_searchdomain` | DNS search domain |
|
||||
| 13 | DNS Server | `var_ns` | Custom DNS server IP |
|
||||
| 14 | MAC Address | `var_mac` | Custom MAC address (auto-generated if empty) |
|
||||
| 15 | VLAN Tag | `var_vlan` | VLAN tag ID |
|
||||
| 16 | Tags | `var_tags` | Container tags (comma/semicolon separated) |
|
||||
| 17 | SSH Settings | `var_ssh` | SSH key selection and root access |
|
||||
| 18 | FUSE Support | `var_fuse` | Enable FUSE for rclone, mergerfs, AppImage |
|
||||
| 19 | TUN/TAP Support | `var_tun` | Enable for VPN apps (WireGuard, OpenVPN, Tailscale) |
|
||||
| 20 | Nesting Support | `var_nesting` | Enable for Docker, LXC in LXC, Podman |
|
||||
| 21 | GPU Passthrough | `var_gpu` | Auto-detect and pass through Intel/AMD/NVIDIA GPUs |
|
||||
| 22 | Keyctl Support | `var_keyctl` | Enable for Docker, systemd-networkd |
|
||||
| 23 | APT Cacher Proxy | `var_apt_cacher`, `var_apt_cacher_ip` | Use apt-cacher-ng for faster downloads |
|
||||
| 24 | Container Timezone | `var_timezone` | Set timezone (e.g., Europe/Berlin) |
|
||||
| 25 | Container Protection | `var_protection` | Prevent accidental deletion |
|
||||
| 26 | Device Node Creation | `var_mknod` | Allow mknod (experimental, kernel 5.3+) |
|
||||
| 27 | Mount Filesystems | `var_mount_fs` | Allow specific mounts: nfs, cifs, fuse, etc. |
|
||||
| 28 | Verbose Mode & Confirm | `var_verbose` | Enable verbose output + final confirmation |
|
||||
|
||||
## Default Value Inheritance
|
||||
|
||||
The wizard inherits defaults from multiple sources:
|
||||
|
||||
```text
|
||||
CT Script (var_*) → default.vars → app.vars → User Input
|
||||
```
|
||||
|
||||
### Example: VPN Container (alpine-wireguard.sh)
|
||||
|
||||
```bash
|
||||
# CT script sets:
|
||||
var_tun="${var_tun:-1}" # TUN enabled by default
|
||||
|
||||
# In Advanced Settings Step 19:
|
||||
# Dialog shows: "(App default: 1)" and pre-selects "Yes"
|
||||
```
|
||||
|
||||
### Example: Media Server (jellyfin.sh)
|
||||
|
||||
```bash
|
||||
# CT script sets:
|
||||
var_gpu="${var_gpu:-yes}" # GPU enabled by default
|
||||
|
||||
# In Advanced Settings Step 21:
|
||||
# Dialog shows: "(App default: yes)" and pre-selects "Yes"
|
||||
```
|
||||
|
||||
## Feature Matrix
|
||||
|
||||
| Feature | Variable | When to Enable |
|
||||
| ----------------- | ---------------- | --------------------------------------------------- |
|
||||
| FUSE | `var_fuse` | rclone, mergerfs, AppImage, SSHFS |
|
||||
| TUN/TAP | `var_tun` | WireGuard, OpenVPN, Tailscale, VPN containers |
|
||||
| Nesting | `var_nesting` | Docker, Podman, LXC-in-LXC, systemd-nspawn |
|
||||
| GPU Passthrough | `var_gpu` | Plex, Jellyfin, Emby, Frigate, Ollama, ComfyUI |
|
||||
| Keyctl | `var_keyctl` | Docker (unprivileged), systemd-networkd |
|
||||
| Protection | `var_protection` | Production containers, prevent accidental deletion |
|
||||
| Mknod | `var_mknod` | Device node creation (experimental) |
|
||||
| Mount FS | `var_mount_fs` | NFS mounts, CIFS shares, custom filesystems |
|
||||
| APT Cacher | `var_apt_cacher` | Speed up downloads with local apt-cacher-ng |
|
||||
|
||||
## Confirmation Summary
|
||||
|
||||
Step 28 displays a comprehensive summary before creation:
|
||||
|
||||
```text
|
||||
Container Type: Unprivileged
|
||||
Container ID: 100
|
||||
Hostname: jellyfin
|
||||
|
||||
Resources:
|
||||
Disk: 8 GB
|
||||
CPU: 2 cores
|
||||
RAM: 2048 MiB
|
||||
|
||||
Network:
|
||||
Bridge: vmbr0
|
||||
IPv4: dhcp
|
||||
IPv6: auto
|
||||
|
||||
Features:
|
||||
FUSE: no | TUN: no
|
||||
Nesting: Enabled | Keyctl: Disabled
|
||||
GPU: yes | Protection: No
|
||||
|
||||
Advanced:
|
||||
Timezone: Europe/Berlin
|
||||
APT Cacher: no
|
||||
Verbose: no
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Skip to Advanced Settings
|
||||
|
||||
```bash
|
||||
# Run script, select "Advanced" from menu
|
||||
bash -c "$(curl -fsSL https://...jellyfin.sh)"
|
||||
# Then select option 3 "Advanced"
|
||||
```
|
||||
|
||||
### Pre-set Defaults via Environment
|
||||
|
||||
```bash
|
||||
# Set defaults before running
|
||||
export var_cpu=4
|
||||
export var_ram=4096
|
||||
export var_gpu=yes
|
||||
bash -c "$(curl -fsSL https://...jellyfin.sh)"
|
||||
# Advanced settings will inherit these values
|
||||
```
|
||||
|
||||
### Non-Interactive with All Options
|
||||
|
||||
```bash
|
||||
# Set all variables for fully automated deployment
|
||||
export var_unprivileged=1
|
||||
export var_cpu=2
|
||||
export var_ram=2048
|
||||
export var_disk=8
|
||||
export var_net=dhcp
|
||||
export var_fuse=no
|
||||
export var_tun=no
|
||||
export var_gpu=yes
|
||||
export var_nesting=1
|
||||
export var_protection=no
|
||||
export var_verbose=no
|
||||
bash -c "$(curl -fsSL https://...jellyfin.sh)"
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- **Cancel at Step 1**: Exits the script entirely
|
||||
- **Cancel at Steps 2-28**: Goes back to previous step
|
||||
- **Empty fields**: Use default value
|
||||
- **Keyctl**: Automatically enabled for unprivileged containers
|
||||
- **Nesting**: Enabled by default (required for many apps)
|
||||
@@ -1,410 +0,0 @@
|
||||
# build.func Architecture Guide
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a high-level architectural overview of `build.func`, including module dependencies, data flow, integration points, and system architecture.
|
||||
|
||||
## High-Level Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Proxmox Host System │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ build.func │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────────┐ │ │
|
||||
│ │ │ Entry Point │ │ Configuration │ │ Container Creation │ │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ │ • start() │ │ • variables() │ │ • build_container() │ │ │
|
||||
│ │ │ • install_ │ │ • base_ │ │ • create_lxc_container() │ │ │
|
||||
│ │ │ script() │ │ settings() │ │ • configure_gpu_ │ │ │
|
||||
│ │ │ • advanced_ │ │ • select_ │ │ passthrough() │ │ │
|
||||
│ │ │ settings() │ │ storage() │ │ • fix_gpu_gids() │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Module Dependencies │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────────┐ │ │
|
||||
│ │ │ core.func │ │ error_handler. │ │ api.func │ │ │
|
||||
│ │ │ │ │ func │ │ │ │ │
|
||||
│ │ │ • Basic │ │ • Error │ │ • Proxmox API │ │ │
|
||||
│ │ │ utilities │ │ handling │ │ interactions │ │ │
|
||||
│ │ │ • Common │ │ • Error │ │ • Container │ │ │
|
||||
│ │ │ functions │ │ recovery │ │ management │ │ │
|
||||
│ │ │ • System │ │ • Cleanup │ │ • Status │ │ │
|
||||
│ │ │ utilities │ │ functions │ │ monitoring │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────────────────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ tools.func │ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ │ • Additional utilities │ │ │
|
||||
│ │ │ • Helper functions │ │ │
|
||||
│ │ │ • System tools │ │ │
|
||||
│ │ └─────────────────────────────────────────────────────────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Module Dependencies
|
||||
|
||||
### Core Dependencies
|
||||
|
||||
```
|
||||
build.func Dependencies:
|
||||
├── core.func
|
||||
│ ├── Basic system utilities
|
||||
│ ├── Common functions
|
||||
│ ├── System information
|
||||
│ └── File operations
|
||||
├── error_handler.func
|
||||
│ ├── Error handling
|
||||
│ ├── Error recovery
|
||||
│ ├── Cleanup functions
|
||||
│ └── Error logging
|
||||
├── api.func
|
||||
│ ├── Proxmox API interactions
|
||||
│ ├── Container management
|
||||
│ ├── Status monitoring
|
||||
│ └── Configuration updates
|
||||
└── tools.func
|
||||
├── Additional utilities
|
||||
├── Helper functions
|
||||
├── System tools
|
||||
└── Custom functions
|
||||
```
|
||||
|
||||
### Dependency Flow
|
||||
|
||||
```
|
||||
Dependency Flow:
|
||||
├── build.func
|
||||
│ ├── Sources core.func
|
||||
│ ├── Sources error_handler.func
|
||||
│ ├── Sources api.func
|
||||
│ └── Sources tools.func
|
||||
├── core.func
|
||||
│ ├── Basic utilities
|
||||
│ └── System functions
|
||||
├── error_handler.func
|
||||
│ ├── Error management
|
||||
│ └── Recovery functions
|
||||
├── api.func
|
||||
│ ├── Proxmox integration
|
||||
│ └── Container operations
|
||||
└── tools.func
|
||||
├── Additional tools
|
||||
└── Helper functions
|
||||
```
|
||||
|
||||
## Data Flow Architecture
|
||||
|
||||
### Configuration Data Flow
|
||||
|
||||
```
|
||||
Configuration Data Flow:
|
||||
├── Environment Variables
|
||||
│ ├── Hard environment variables
|
||||
│ ├── App-specific .vars
|
||||
│ ├── Global default.vars
|
||||
│ └── Built-in defaults
|
||||
├── Variable Resolution
|
||||
│ ├── Apply precedence chain
|
||||
│ ├── Validate settings
|
||||
│ └── Resolve conflicts
|
||||
├── Configuration Storage
|
||||
│ ├── Memory variables
|
||||
│ ├── Temporary files
|
||||
│ └── Persistent storage
|
||||
└── Configuration Usage
|
||||
├── Container creation
|
||||
├── Feature configuration
|
||||
└── Settings persistence
|
||||
```
|
||||
|
||||
### Container Data Flow
|
||||
|
||||
```
|
||||
Container Data Flow:
|
||||
├── Input Data
|
||||
│ ├── Configuration variables
|
||||
│ ├── Resource specifications
|
||||
│ ├── Network settings
|
||||
│ └── Storage requirements
|
||||
├── Processing
|
||||
│ ├── Validation
|
||||
│ ├── Conflict resolution
|
||||
│ ├── Resource allocation
|
||||
│ └── Configuration generation
|
||||
├── Container Creation
|
||||
│ ├── LXC container creation
|
||||
│ ├── Network configuration
|
||||
│ ├── Storage setup
|
||||
│ └── Feature configuration
|
||||
└── Output
|
||||
├── Container status
|
||||
├── Access information
|
||||
├── Configuration files
|
||||
└── Log files
|
||||
```
|
||||
|
||||
## Integration Architecture
|
||||
|
||||
### With Proxmox System
|
||||
|
||||
```
|
||||
Proxmox Integration:
|
||||
├── Proxmox Host
|
||||
│ ├── LXC container management
|
||||
│ ├── Storage management
|
||||
│ ├── Network management
|
||||
│ └── Resource management
|
||||
├── Proxmox API
|
||||
│ ├── Container operations
|
||||
│ ├── Configuration updates
|
||||
│ ├── Status monitoring
|
||||
│ └── Error handling
|
||||
├── Proxmox Configuration
|
||||
│ ├── /etc/pve/lxc/<ctid>.conf
|
||||
│ ├── Storage configuration
|
||||
│ ├── Network configuration
|
||||
│ └── Resource configuration
|
||||
└── Proxmox Services
|
||||
├── Container services
|
||||
├── Network services
|
||||
├── Storage services
|
||||
└── Monitoring services
|
||||
```
|
||||
|
||||
### With Install Scripts
|
||||
|
||||
```
|
||||
Install Script Integration:
|
||||
├── build.func
|
||||
│ ├── Creates container
|
||||
│ ├── Configures basic settings
|
||||
│ ├── Starts container
|
||||
│ └── Provides access
|
||||
├── Install Scripts
|
||||
│ ├── <app>-install.sh
|
||||
│ ├── Downloads application
|
||||
│ ├── Configures application
|
||||
│ └── Sets up services
|
||||
├── Container
|
||||
│ ├── Running application
|
||||
│ ├── Configured services
|
||||
│ ├── Network access
|
||||
│ └── Storage access
|
||||
└── Integration Points
|
||||
├── Container creation
|
||||
├── Network configuration
|
||||
├── Storage setup
|
||||
└── Service configuration
|
||||
```
|
||||
|
||||
## System Architecture Components
|
||||
|
||||
### Core Components
|
||||
|
||||
```
|
||||
System Components:
|
||||
├── Entry Point
|
||||
│ ├── start() function
|
||||
│ ├── Context detection
|
||||
│ ├── Environment capture
|
||||
│ └── Workflow routing
|
||||
├── Configuration Management
|
||||
│ ├── Variable resolution
|
||||
│ ├── Settings persistence
|
||||
│ ├── Default management
|
||||
│ └── Validation
|
||||
├── Container Creation
|
||||
│ ├── LXC container creation
|
||||
│ ├── Network configuration
|
||||
│ ├── Storage setup
|
||||
│ └── Feature configuration
|
||||
├── Hardware Integration
|
||||
│ ├── GPU passthrough
|
||||
│ ├── USB passthrough
|
||||
│ ├── Storage management
|
||||
│ └── Network management
|
||||
└── Error Handling
|
||||
├── Error detection
|
||||
├── Error recovery
|
||||
├── Cleanup functions
|
||||
└── User notification
|
||||
```
|
||||
|
||||
### User Interface Components
|
||||
|
||||
```
|
||||
UI Components:
|
||||
├── Menu System
|
||||
│ ├── Installation mode selection
|
||||
│ ├── Configuration menus
|
||||
│ ├── Storage selection
|
||||
│ └── GPU configuration
|
||||
├── Interactive Elements
|
||||
│ ├── Whiptail menus
|
||||
│ ├── User prompts
|
||||
│ ├── Confirmation dialogs
|
||||
│ └── Error messages
|
||||
├── Non-Interactive Mode
|
||||
│ ├── Environment variable driven
|
||||
│ ├── Silent execution
|
||||
│ ├── Automated configuration
|
||||
│ └── Error handling
|
||||
└── Output
|
||||
├── Status messages
|
||||
├── Progress indicators
|
||||
├── Completion information
|
||||
└── Access details
|
||||
```
|
||||
|
||||
## Security Architecture
|
||||
|
||||
### Security Considerations
|
||||
|
||||
```
|
||||
Security Architecture:
|
||||
├── Container Security
|
||||
│ ├── Unprivileged containers (default)
|
||||
│ ├── Privileged containers (when needed)
|
||||
│ ├── Resource limits
|
||||
│ └── Access controls
|
||||
├── Network Security
|
||||
│ ├── Network isolation
|
||||
│ ├── VLAN support
|
||||
│ ├── Firewall integration
|
||||
│ └── Access controls
|
||||
├── Storage Security
|
||||
│ ├── Storage isolation
|
||||
│ ├── Access controls
|
||||
│ ├── Encryption support
|
||||
│ └── Backup integration
|
||||
├── GPU Security
|
||||
│ ├── Device isolation
|
||||
│ ├── Permission management
|
||||
│ ├── Access controls
|
||||
│ └── Security validation
|
||||
└── API Security
|
||||
├── Authentication
|
||||
├── Authorization
|
||||
├── Input validation
|
||||
└── Error handling
|
||||
```
|
||||
|
||||
## Performance Architecture
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
```
|
||||
Performance Architecture:
|
||||
├── Execution Optimization
|
||||
│ ├── Parallel operations
|
||||
│ ├── Efficient algorithms
|
||||
│ ├── Minimal user interaction
|
||||
│ └── Optimized validation
|
||||
├── Resource Management
|
||||
│ ├── Memory efficiency
|
||||
│ ├── CPU optimization
|
||||
│ ├── Disk usage optimization
|
||||
│ └── Network efficiency
|
||||
├── Caching
|
||||
│ ├── Configuration caching
|
||||
│ ├── Template caching
|
||||
│ ├── Storage caching
|
||||
│ └── GPU detection caching
|
||||
└── Monitoring
|
||||
├── Performance monitoring
|
||||
├── Resource monitoring
|
||||
├── Error monitoring
|
||||
└── Status monitoring
|
||||
```
|
||||
|
||||
## Deployment Architecture
|
||||
|
||||
### Deployment Scenarios
|
||||
|
||||
```
|
||||
Deployment Scenarios:
|
||||
├── Single Container
|
||||
│ ├── Individual application
|
||||
│ ├── Standard configuration
|
||||
│ ├── Basic networking
|
||||
│ └── Standard storage
|
||||
├── Multiple Containers
|
||||
│ ├── Application stack
|
||||
│ ├── Shared networking
|
||||
│ ├── Shared storage
|
||||
│ └── Coordinated deployment
|
||||
├── High Availability
|
||||
│ ├── Redundant containers
|
||||
│ ├── Load balancing
|
||||
│ ├── Failover support
|
||||
│ └── Monitoring integration
|
||||
└── Development Environment
|
||||
├── Development containers
|
||||
├── Testing containers
|
||||
├── Staging containers
|
||||
└── Production containers
|
||||
```
|
||||
|
||||
## Maintenance Architecture
|
||||
|
||||
### Maintenance Components
|
||||
|
||||
```
|
||||
Maintenance Architecture:
|
||||
├── Updates
|
||||
│ ├── Container updates
|
||||
│ ├── Application updates
|
||||
│ ├── Configuration updates
|
||||
│ └── Security updates
|
||||
├── Monitoring
|
||||
│ ├── Container monitoring
|
||||
│ ├── Resource monitoring
|
||||
│ ├── Performance monitoring
|
||||
│ └── Error monitoring
|
||||
├── Backup
|
||||
│ ├── Configuration backup
|
||||
│ ├── Container backup
|
||||
│ ├── Storage backup
|
||||
│ └── Recovery procedures
|
||||
└── Troubleshooting
|
||||
├── Error diagnosis
|
||||
├── Log analysis
|
||||
├── Performance analysis
|
||||
└── Recovery procedures
|
||||
```
|
||||
|
||||
## Future Architecture Considerations
|
||||
|
||||
### Scalability
|
||||
|
||||
```
|
||||
Scalability Considerations:
|
||||
├── Horizontal Scaling
|
||||
│ ├── Multiple containers
|
||||
│ ├── Load balancing
|
||||
│ ├── Distributed deployment
|
||||
│ └── Resource distribution
|
||||
├── Vertical Scaling
|
||||
│ ├── Resource scaling
|
||||
│ ├── Performance optimization
|
||||
│ ├── Capacity planning
|
||||
│ └── Resource management
|
||||
├── Automation
|
||||
│ ├── Automated deployment
|
||||
│ ├── Automated scaling
|
||||
│ ├── Automated monitoring
|
||||
│ └── Automated recovery
|
||||
└── Integration
|
||||
├── External systems
|
||||
├── Cloud integration
|
||||
├── Container orchestration
|
||||
└── Service mesh
|
||||
```
|
||||
@@ -1,294 +0,0 @@
|
||||
# build.func Environment Variables Reference
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a comprehensive reference of all environment variables used in `build.func`, organized by category and usage context.
|
||||
|
||||
## Variable Categories
|
||||
|
||||
### Core Container Variables
|
||||
|
||||
| Variable | Description | Default | Set In | Used In |
|
||||
| --------- | -------------------------------------------- | --------- | ----------- | ------------------ |
|
||||
| `APP` | Application name (e.g., "plex", "nextcloud") | - | Environment | Throughout |
|
||||
| `NSAPP` | Namespace application name | `$APP` | Environment | Throughout |
|
||||
| `CTID` | Container ID | - | Environment | Container creation |
|
||||
| `CT_TYPE` | Container type ("install" or "update") | "install" | Environment | Entry point |
|
||||
| `CT_NAME` | Container name | `$APP` | Environment | Container creation |
|
||||
|
||||
### Operating System Variables
|
||||
|
||||
| Variable | Description | Default | Set In | Used In |
|
||||
| -------------- | -------------------------- | -------------- | --------------- | ------------------ |
|
||||
| `var_os` | Operating system selection | "debian" | base_settings() | OS selection |
|
||||
| `var_version` | OS version | "12" | base_settings() | Template selection |
|
||||
| `var_template` | Template name | Auto-generated | base_settings() | Template download |
|
||||
|
||||
### Resource Configuration Variables
|
||||
|
||||
| Variable | Description | Default | Set In | Used In |
|
||||
| ------------ | ----------------------- | ----------- | --------------- | ------------------ |
|
||||
| `var_cpu` | CPU cores | "2" | base_settings() | Container creation |
|
||||
| `var_ram` | RAM in MB | "2048" | base_settings() | Container creation |
|
||||
| `var_disk` | Disk size in GB | "8" | base_settings() | Container creation |
|
||||
| `DISK_SIZE` | Disk size (alternative) | `$var_disk` | Environment | Container creation |
|
||||
| `CORE_COUNT` | CPU cores (alternative) | `$var_cpu` | Environment | Container creation |
|
||||
| `RAM_SIZE` | RAM size (alternative) | `$var_ram` | Environment | Container creation |
|
||||
|
||||
### Network Configuration Variables
|
||||
|
||||
| Variable | Description | Default | Set In | Used In |
|
||||
| ------------- | ------------------------------- | -------------- | --------------- | -------------- |
|
||||
| `var_net` | Network interface | "vmbr0" | base_settings() | Network config |
|
||||
| `var_bridge` | Bridge interface | "vmbr0" | base_settings() | Network config |
|
||||
| `var_gateway` | Gateway IP | "192.168.1.1" | base_settings() | Network config |
|
||||
| `var_ip` | Container IP address | - | User input | Network config |
|
||||
| `var_ipv6` | IPv6 address | - | User input | Network config |
|
||||
| `var_vlan` | VLAN ID | - | User input | Network config |
|
||||
| `var_mtu` | MTU size | "1500" | base_settings() | Network config |
|
||||
| `var_mac` | MAC address | Auto-generated | base_settings() | Network config |
|
||||
| `NET` | Network interface (alternative) | `$var_net` | Environment | Network config |
|
||||
| `BRG` | Bridge interface (alternative) | `$var_bridge` | Environment | Network config |
|
||||
| `GATE` | Gateway IP (alternative) | `$var_gateway` | Environment | Network config |
|
||||
| `IPV6_METHOD` | IPv6 configuration method | "none" | Environment | Network config |
|
||||
| `VLAN` | VLAN ID (alternative) | `$var_vlan` | Environment | Network config |
|
||||
| `MTU` | MTU size (alternative) | `$var_mtu` | Environment | Network config |
|
||||
| `MAC` | MAC address (alternative) | `$var_mac` | Environment | Network config |
|
||||
|
||||
### Storage Configuration Variables
|
||||
|
||||
| Variable | Description | Default | Set In | Used In |
|
||||
| ----------------------- | ------------------------------- | ------------------------ | ---------------- | ----------------- |
|
||||
| `var_template_storage` | Storage for templates | - | select_storage() | Template storage |
|
||||
| `var_container_storage` | Storage for container disks | - | select_storage() | Container storage |
|
||||
| `TEMPLATE_STORAGE` | Template storage (alternative) | `$var_template_storage` | Environment | Template storage |
|
||||
| `CONTAINER_STORAGE` | Container storage (alternative) | `$var_container_storage` | Environment | Container storage |
|
||||
|
||||
### Feature Flags
|
||||
|
||||
| Variable | Description | Default | Set In | Used In |
|
||||
| ---------------- | ------------------------------ | ------- | ------------------------------- | ------------------ |
|
||||
| `var_fuse` | Enable FUSE support | "no" | CT script / Advanced Settings | Container features |
|
||||
| `var_tun` | Enable TUN/TAP support | "no" | CT script / Advanced Settings | Container features |
|
||||
| `var_nesting` | Enable nesting support | "1" | CT script / Advanced Settings | Container features |
|
||||
| `var_keyctl` | Enable keyctl support | "0" | CT script / Advanced Settings | Container features |
|
||||
| `var_mknod` | Allow device node creation | "0" | CT script / Advanced Settings | Container features |
|
||||
| `var_mount_fs` | Allowed filesystem mounts | "" | CT script / Advanced Settings | Container features |
|
||||
| `var_protection` | Enable container protection | "no" | CT script / Advanced Settings | Container creation |
|
||||
| `var_timezone` | Container timezone | "" | CT script / Advanced Settings | Container creation |
|
||||
| `var_verbose` | Enable verbose output | "no" | Environment / Advanced Settings | Logging |
|
||||
| `var_ssh` | Enable SSH key provisioning | "no" | CT script / Advanced Settings | SSH setup |
|
||||
| `ENABLE_FUSE` | FUSE flag (internal) | "no" | Advanced Settings | Container creation |
|
||||
| `ENABLE_TUN` | TUN/TAP flag (internal) | "no" | Advanced Settings | Container creation |
|
||||
| `ENABLE_NESTING` | Nesting flag (internal) | "1" | Advanced Settings | Container creation |
|
||||
| `ENABLE_KEYCTL` | Keyctl flag (internal) | "0" | Advanced Settings | Container creation |
|
||||
| `ENABLE_MKNOD` | Mknod flag (internal) | "0" | Advanced Settings | Container creation |
|
||||
| `PROTECT_CT` | Protection flag (internal) | "no" | Advanced Settings | Container creation |
|
||||
| `CT_TIMEZONE` | Timezone setting (internal) | "" | Advanced Settings | Container creation |
|
||||
| `VERBOSE` | Verbose mode flag | "no" | Environment | Logging |
|
||||
| `SSH` | SSH access flag | "no" | Advanced Settings | SSH setup |
|
||||
|
||||
### APT Cacher Configuration
|
||||
|
||||
| Variable | Description | Default | Set In | Used In |
|
||||
| ------------------ | ------------------------ | ------- | ----------------------------- | ------------------- |
|
||||
| `var_apt_cacher` | Enable APT cacher proxy | "no" | CT script / Advanced Settings | Package management |
|
||||
| `var_apt_cacher_ip`| APT cacher server IP | "" | CT script / Advanced Settings | Package management |
|
||||
| `APT_CACHER` | APT cacher flag | "no" | Advanced Settings | Container creation |
|
||||
| `APT_CACHER_IP` | APT cacher IP (internal) | "" | Advanced Settings | Container creation |
|
||||
|
||||
### GPU Passthrough Variables
|
||||
|
||||
| Variable | Description | Default | Set In | Used In |
|
||||
| ------------ | ------------------------------- | ------- | ------------------------------------------- | ------------------ |
|
||||
| `var_gpu` | Enable GPU passthrough | "no" | CT script / Environment / Advanced Settings | GPU passthrough |
|
||||
| `ENABLE_GPU` | GPU passthrough flag (internal) | "no" | Advanced Settings | Container creation |
|
||||
|
||||
**Note**: GPU passthrough is controlled via `var_gpu`. Apps that benefit from GPU acceleration (media servers, AI/ML, transcoding) have `var_gpu=yes` as default in their CT scripts.
|
||||
|
||||
**Apps with GPU enabled by default**:
|
||||
|
||||
- Media: jellyfin, plex, emby, channels, ersatztv, tunarr, immich
|
||||
- Transcoding: tdarr, unmanic, fileflows
|
||||
- AI/ML: ollama, openwebui
|
||||
- NVR: frigate
|
||||
|
||||
**Usage Examples**:
|
||||
|
||||
```bash
|
||||
# Disable GPU for a specific installation
|
||||
var_gpu=no bash -c "$(curl -fsSL https://...jellyfin.sh)"
|
||||
|
||||
# Enable GPU for apps without default GPU support
|
||||
var_gpu=yes bash -c "$(curl -fsSL https://...debian.sh)"
|
||||
|
||||
# Set in default.vars for all apps
|
||||
echo "var_gpu=yes" >> /usr/local/community-scripts/default.vars
|
||||
```
|
||||
|
||||
### API and Diagnostics Variables
|
||||
|
||||
| Variable | Description | Default | Set In | Used In |
|
||||
| ------------- | ------------------------ | --------- | ----------- | ----------------- |
|
||||
| `DIAGNOSTICS` | Enable diagnostics mode | "false" | Environment | Diagnostics |
|
||||
| `METHOD` | Installation method | "install" | Environment | Installation flow |
|
||||
| `RANDOM_UUID` | Random UUID for tracking | - | Environment | Logging |
|
||||
| `API_TOKEN` | Proxmox API token | - | Environment | API calls |
|
||||
| `API_USER` | Proxmox API user | - | Environment | API calls |
|
||||
|
||||
### Settings Persistence Variables
|
||||
|
||||
| Variable | Description | Default | Set In | Used In |
|
||||
| ------------------- | -------------------------- | ------------------------------------------------- | ----------- | -------------------- |
|
||||
| `SAVE_DEFAULTS` | Save settings as defaults | "false" | User input | Settings persistence |
|
||||
| `SAVE_APP_DEFAULTS` | Save app-specific defaults | "false" | User input | Settings persistence |
|
||||
| `DEFAULT_VARS_FILE` | Path to default.vars | "/usr/local/community-scripts/default.vars" | Environment | Settings persistence |
|
||||
| `APP_DEFAULTS_FILE` | Path to app.vars | "/usr/local/community-scripts/defaults/$APP.vars" | Environment | Settings persistence |
|
||||
|
||||
## Variable Precedence Chain
|
||||
|
||||
Variables are resolved in the following order (highest to lowest priority):
|
||||
|
||||
1. **Hard Environment Variables**: Set before script execution
|
||||
2. **App-specific .vars file**: `/usr/local/community-scripts/defaults/<app>.vars`
|
||||
3. **Global default.vars file**: `/usr/local/community-scripts/default.vars`
|
||||
4. **Built-in defaults**: Set in `base_settings()` function
|
||||
|
||||
## Critical Variables for Non-Interactive Use
|
||||
|
||||
For silent/non-interactive execution, these variables must be set:
|
||||
|
||||
```bash
|
||||
# Core container settings
|
||||
export APP="plex"
|
||||
export CTID="100"
|
||||
export var_hostname="plex-server"
|
||||
|
||||
# OS selection
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
|
||||
# Resource allocation
|
||||
export var_cpu="4"
|
||||
export var_ram="4096"
|
||||
export var_disk="20"
|
||||
|
||||
# Network configuration
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.100"
|
||||
|
||||
# Storage selection
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
|
||||
# Feature flags
|
||||
export ENABLE_FUSE="true"
|
||||
export ENABLE_TUN="true"
|
||||
export SSH="true"
|
||||
```
|
||||
|
||||
## Environment Variable Usage Patterns
|
||||
|
||||
### 1. Container Creation
|
||||
|
||||
```bash
|
||||
# Basic container creation
|
||||
export APP="nextcloud"
|
||||
export CTID="101"
|
||||
export var_hostname="nextcloud-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.101"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
```
|
||||
|
||||
### 2. GPU Passthrough
|
||||
|
||||
```bash
|
||||
# Enable GPU passthrough
|
||||
export GPU_APPS="plex,jellyfin,emby"
|
||||
export var_gpu="intel"
|
||||
export ENABLE_PRIVILEGED="true"
|
||||
```
|
||||
|
||||
### 3. Advanced Network Configuration
|
||||
|
||||
```bash
|
||||
# VLAN and IPv6 configuration
|
||||
export var_vlan="100"
|
||||
export var_ipv6="2001:db8::100"
|
||||
export IPV6_METHOD="static"
|
||||
export var_mtu="9000"
|
||||
```
|
||||
|
||||
### 4. Storage Configuration
|
||||
|
||||
```bash
|
||||
# Custom storage locations
|
||||
export var_template_storage="nfs-storage"
|
||||
export var_container_storage="ssd-storage"
|
||||
```
|
||||
|
||||
## Variable Validation
|
||||
|
||||
The script validates variables at several points:
|
||||
|
||||
1. **Container ID validation**: Must be unique and within valid range
|
||||
2. **IP address validation**: Must be valid IPv4/IPv6 format
|
||||
3. **Storage validation**: Must exist and support required content types
|
||||
4. **Resource validation**: Must be within reasonable limits
|
||||
5. **Network validation**: Must be valid network configuration
|
||||
|
||||
## Common Variable Combinations
|
||||
|
||||
### Development Container
|
||||
|
||||
```bash
|
||||
export APP="dev-container"
|
||||
export CTID="200"
|
||||
export var_hostname="dev-server"
|
||||
export var_os="ubuntu"
|
||||
export var_version="22.04"
|
||||
export var_cpu="4"
|
||||
export var_ram="4096"
|
||||
export var_disk="20"
|
||||
export ENABLE_NESTING="true"
|
||||
export ENABLE_PRIVILEGED="true"
|
||||
```
|
||||
|
||||
### Media Server with GPU
|
||||
|
||||
```bash
|
||||
export APP="plex"
|
||||
export CTID="300"
|
||||
export var_hostname="plex-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="6"
|
||||
export var_ram="8192"
|
||||
export var_disk="50"
|
||||
export GPU_APPS="plex"
|
||||
export var_gpu="nvidia"
|
||||
export ENABLE_PRIVILEGED="true"
|
||||
```
|
||||
|
||||
### Lightweight Service
|
||||
|
||||
```bash
|
||||
export APP="nginx"
|
||||
export CTID="400"
|
||||
export var_hostname="nginx-proxy"
|
||||
export var_os="alpine"
|
||||
export var_version="3.18"
|
||||
export var_cpu="1"
|
||||
export var_ram="512"
|
||||
export var_disk="2"
|
||||
export ENABLE_UNPRIVILEGED="true"
|
||||
```
|
||||
@@ -1,413 +0,0 @@
|
||||
# build.func Execution Flows
|
||||
|
||||
## Overview
|
||||
|
||||
This document details the execution flows for different installation modes and scenarios in `build.func`, including variable precedence, decision trees, and workflow patterns.
|
||||
|
||||
## Installation Modes
|
||||
|
||||
### 1. Default Install Flow
|
||||
|
||||
**Purpose**: Uses built-in defaults with minimal user interaction
|
||||
**Use Case**: Quick container creation with standard settings
|
||||
|
||||
```
|
||||
Default Install Flow:
|
||||
├── start()
|
||||
│ ├── Detect execution context
|
||||
│ ├── Capture hard environment variables
|
||||
│ └── Set CT_TYPE="install"
|
||||
├── install_script()
|
||||
│ ├── Display installation mode menu
|
||||
│ ├── User selects "Default Install"
|
||||
│ └── Proceed with defaults
|
||||
├── variables()
|
||||
│ ├── base_settings() # Set built-in defaults
|
||||
│ ├── Load app.vars (if exists)
|
||||
│ ├── Load default.vars (if exists)
|
||||
│ └── Apply variable precedence
|
||||
├── build_container()
|
||||
│ ├── validate_settings()
|
||||
│ ├── check_conflicts()
|
||||
│ └── create_lxc_container()
|
||||
└── default_var_settings()
|
||||
└── Offer to save as defaults
|
||||
```
|
||||
|
||||
**Key Characteristics**:
|
||||
- Minimal user prompts
|
||||
- Uses built-in defaults
|
||||
- Fast execution
|
||||
- Suitable for standard deployments
|
||||
|
||||
### 2. Advanced Install Flow
|
||||
|
||||
**Purpose**: Full interactive configuration via whiptail menus
|
||||
**Use Case**: Custom container configuration with full control
|
||||
|
||||
```
|
||||
Advanced Install Flow:
|
||||
├── start()
|
||||
│ ├── Detect execution context
|
||||
│ ├── Capture hard environment variables
|
||||
│ └── Set CT_TYPE="install"
|
||||
├── install_script()
|
||||
│ ├── Display installation mode menu
|
||||
│ ├── User selects "Advanced Install"
|
||||
│ └── Proceed with advanced configuration
|
||||
├── variables()
|
||||
│ ├── base_settings() # Set built-in defaults
|
||||
│ ├── Load app.vars (if exists)
|
||||
│ ├── Load default.vars (if exists)
|
||||
│ └── Apply variable precedence
|
||||
├── advanced_settings()
|
||||
│ ├── OS Selection Menu
|
||||
│ ├── Resource Configuration Menu
|
||||
│ ├── Network Configuration Menu
|
||||
│ ├── select_storage()
|
||||
│ │ ├── resolve_storage_preselect()
|
||||
│ │ └── choose_and_set_storage_for_file()
|
||||
│ ├── GPU Configuration Menu
|
||||
│ │ └── detect_gpu_devices()
|
||||
│ └── Feature Flags Menu
|
||||
├── build_container()
|
||||
│ ├── validate_settings()
|
||||
│ ├── check_conflicts()
|
||||
│ └── create_lxc_container()
|
||||
└── default_var_settings()
|
||||
└── Offer to save as defaults
|
||||
```
|
||||
|
||||
**Key Characteristics**:
|
||||
- Full interactive configuration
|
||||
- Whiptail menus for all options
|
||||
- Complete control over settings
|
||||
- Suitable for custom deployments
|
||||
|
||||
### 3. My Defaults Flow
|
||||
|
||||
**Purpose**: Loads settings from global default.vars file
|
||||
**Use Case**: Using previously saved global defaults
|
||||
|
||||
```
|
||||
My Defaults Flow:
|
||||
├── start()
|
||||
│ ├── Detect execution context
|
||||
│ ├── Capture hard environment variables
|
||||
│ └── Set CT_TYPE="install"
|
||||
├── install_script()
|
||||
│ ├── Display installation mode menu
|
||||
│ ├── User selects "My Defaults"
|
||||
│ └── Proceed with loaded defaults
|
||||
├── variables()
|
||||
│ ├── base_settings() # Set built-in defaults
|
||||
│ ├── Load app.vars (if exists)
|
||||
│ ├── Load default.vars # Load global defaults
|
||||
│ └── Apply variable precedence
|
||||
├── build_container()
|
||||
│ ├── validate_settings()
|
||||
│ ├── check_conflicts()
|
||||
│ └── create_lxc_container()
|
||||
└── default_var_settings()
|
||||
└── Offer to save as defaults
|
||||
```
|
||||
|
||||
**Key Characteristics**:
|
||||
- Uses global default.vars file
|
||||
- Minimal user interaction
|
||||
- Consistent with previous settings
|
||||
- Suitable for repeated deployments
|
||||
|
||||
### 4. App Defaults Flow
|
||||
|
||||
**Purpose**: Loads settings from app-specific .vars file
|
||||
**Use Case**: Using previously saved app-specific defaults
|
||||
|
||||
```
|
||||
App Defaults Flow:
|
||||
├── start()
|
||||
│ ├── Detect execution context
|
||||
│ ├── Capture hard environment variables
|
||||
│ └── Set CT_TYPE="install"
|
||||
├── install_script()
|
||||
│ ├── Display installation mode menu
|
||||
│ ├── User selects "App Defaults"
|
||||
│ └── Proceed with app-specific defaults
|
||||
├── variables()
|
||||
│ ├── base_settings() # Set built-in defaults
|
||||
│ ├── Load app.vars # Load app-specific defaults
|
||||
│ ├── Load default.vars (if exists)
|
||||
│ └── Apply variable precedence
|
||||
├── build_container()
|
||||
│ ├── validate_settings()
|
||||
│ ├── check_conflicts()
|
||||
│ └── create_lxc_container()
|
||||
└── default_var_settings()
|
||||
└── Offer to save as defaults
|
||||
```
|
||||
|
||||
**Key Characteristics**:
|
||||
- Uses app-specific .vars file
|
||||
- Minimal user interaction
|
||||
- App-optimized settings
|
||||
- Suitable for app-specific deployments
|
||||
|
||||
## Variable Precedence Chain
|
||||
|
||||
### Precedence Order (Highest to Lowest)
|
||||
|
||||
1. **Hard Environment Variables**: Set before script execution
|
||||
2. **App-specific .vars file**: `/usr/local/community-scripts/defaults/<app>.vars`
|
||||
3. **Global default.vars file**: `/usr/local/community-scripts/default.vars`
|
||||
4. **Built-in defaults**: Set in `base_settings()` function
|
||||
|
||||
### Variable Resolution Process
|
||||
|
||||
```
|
||||
Variable Resolution:
|
||||
├── Capture hard environment variables at start()
|
||||
├── Load built-in defaults in base_settings()
|
||||
├── Load global default.vars (if exists)
|
||||
├── Load app-specific .vars (if exists)
|
||||
└── Apply precedence chain
|
||||
├── Hard env vars override all
|
||||
├── App.vars override default.vars and built-ins
|
||||
├── Default.vars override built-ins
|
||||
└── Built-ins are fallback defaults
|
||||
```
|
||||
|
||||
## Storage Selection Logic
|
||||
|
||||
### Storage Resolution Flow
|
||||
|
||||
```
|
||||
Storage Selection:
|
||||
├── Check if storage is preselected
|
||||
│ ├── var_template_storage set? → Validate and use
|
||||
│ └── var_container_storage set? → Validate and use
|
||||
├── Count available storage options
|
||||
│ ├── Only 1 option → Auto-select
|
||||
│ └── Multiple options → Prompt user
|
||||
├── User selection via whiptail
|
||||
│ ├── Template storage selection
|
||||
│ └── Container storage selection
|
||||
└── Validate selected storage
|
||||
├── Check availability
|
||||
├── Check content type support
|
||||
└── Proceed with selection
|
||||
```
|
||||
|
||||
### Storage Validation
|
||||
|
||||
```
|
||||
Storage Validation:
|
||||
├── Check storage exists
|
||||
├── Check storage is online
|
||||
├── Check content type support
|
||||
│ ├── Template storage: vztmpl support
|
||||
│ └── Container storage: rootdir support
|
||||
├── Check available space
|
||||
└── Validate permissions
|
||||
```
|
||||
|
||||
## GPU Passthrough Flow
|
||||
|
||||
### GPU Detection and Configuration
|
||||
|
||||
```
|
||||
GPU Passthrough Flow:
|
||||
├── detect_gpu_devices()
|
||||
│ ├── Scan for Intel GPUs
|
||||
│ │ ├── Check i915 driver
|
||||
│ │ └── Detect devices
|
||||
│ ├── Scan for AMD GPUs
|
||||
│ │ ├── Check AMDGPU driver
|
||||
│ │ └── Detect devices
|
||||
│ └── Scan for NVIDIA GPUs
|
||||
│ ├── Check NVIDIA driver
|
||||
│ ├── Detect devices
|
||||
│ └── Check CUDA support
|
||||
├── Check GPU passthrough eligibility
|
||||
│ ├── Is app in GPU_APPS list?
|
||||
│ ├── Is container privileged?
|
||||
│ └── Proceed if eligible
|
||||
├── GPU selection logic
|
||||
│ ├── Single GPU type → Auto-select
|
||||
│ └── Multiple GPU types → Prompt user
|
||||
├── configure_gpu_passthrough()
|
||||
│ ├── Add GPU device entries
|
||||
│ ├── Configure permissions
|
||||
│ └── Update container config
|
||||
└── fix_gpu_gids()
|
||||
├── Update GPU group IDs
|
||||
└── Configure access permissions
|
||||
```
|
||||
|
||||
### GPU Eligibility Check
|
||||
|
||||
```
|
||||
GPU Eligibility:
|
||||
├── Check app support
|
||||
│ ├── Is APP in GPU_APPS list?
|
||||
│ └── Proceed if supported
|
||||
├── Check container privileges
|
||||
│ ├── Is ENABLE_PRIVILEGED="true"?
|
||||
│ └── Proceed if privileged
|
||||
└── Check hardware availability
|
||||
├── Are GPUs detected?
|
||||
└── Proceed if available
|
||||
```
|
||||
|
||||
## Network Configuration Flow
|
||||
|
||||
### Network Setup Process
|
||||
|
||||
```
|
||||
Network Configuration:
|
||||
├── Basic network settings
|
||||
│ ├── var_net (network interface)
|
||||
│ ├── var_bridge (bridge interface)
|
||||
│ └── var_gateway (gateway IP)
|
||||
├── IP configuration
|
||||
│ ├── var_ip (IPv4 address)
|
||||
│ ├── var_ipv6 (IPv6 address)
|
||||
│ └── IPV6_METHOD (IPv6 method)
|
||||
├── Advanced network settings
|
||||
│ ├── var_vlan (VLAN ID)
|
||||
│ ├── var_mtu (MTU size)
|
||||
│ └── var_mac (MAC address)
|
||||
└── Network validation
|
||||
├── Check IP format
|
||||
├── Check gateway reachability
|
||||
└── Validate network configuration
|
||||
```
|
||||
|
||||
## Container Creation Flow
|
||||
|
||||
### LXC Container Creation Process
|
||||
|
||||
```
|
||||
Container Creation:
|
||||
├── create_lxc_container()
|
||||
│ ├── Create basic container
|
||||
│ ├── Configure network
|
||||
│ ├── Set up storage
|
||||
│ ├── Configure features
|
||||
│ ├── Set resource limits
|
||||
│ ├── Configure startup
|
||||
│ └── Start container
|
||||
├── Post-creation configuration
|
||||
│ ├── Wait for network
|
||||
│ ├── Configure GPU (if enabled)
|
||||
│ ├── Set up SSH keys
|
||||
│ └── Run post-install scripts
|
||||
└── Finalization
|
||||
├── Display container info
|
||||
├── Show access details
|
||||
└── Provide next steps
|
||||
```
|
||||
|
||||
## Error Handling Flows
|
||||
|
||||
### Validation Error Flow
|
||||
|
||||
```
|
||||
Validation Error Flow:
|
||||
├── validate_settings()
|
||||
│ ├── Check configuration validity
|
||||
│ └── Return error if invalid
|
||||
├── check_conflicts()
|
||||
│ ├── Check for conflicts
|
||||
│ └── Return error if conflicts found
|
||||
├── Error handling
|
||||
│ ├── Display error message
|
||||
│ ├── cleanup_on_error()
|
||||
│ └── Exit with error code
|
||||
└── User notification
|
||||
├── Show error details
|
||||
└── Suggest fixes
|
||||
```
|
||||
|
||||
### Storage Error Flow
|
||||
|
||||
```
|
||||
Storage Error Flow:
|
||||
├── Storage selection fails
|
||||
├── Retry storage selection
|
||||
│ ├── Show available options
|
||||
│ └── Allow user to retry
|
||||
├── Storage validation fails
|
||||
│ ├── Show validation errors
|
||||
│ └── Allow user to fix
|
||||
└── Fallback to default storage
|
||||
├── Use fallback storage
|
||||
└── Continue with creation
|
||||
```
|
||||
|
||||
### GPU Error Flow
|
||||
|
||||
```
|
||||
GPU Error Flow:
|
||||
├── GPU detection fails
|
||||
├── Fall back to no GPU
|
||||
│ ├── Disable GPU passthrough
|
||||
│ └── Continue without GPU
|
||||
├── GPU configuration fails
|
||||
│ ├── Show configuration errors
|
||||
│ └── Allow user to retry
|
||||
└── GPU permission errors
|
||||
├── Fix GPU permissions
|
||||
└── Retry configuration
|
||||
```
|
||||
|
||||
## Integration Flows
|
||||
|
||||
### With Install Scripts
|
||||
|
||||
```
|
||||
Install Script Integration:
|
||||
├── build.func creates container
|
||||
├── Container starts successfully
|
||||
├── Install script execution
|
||||
│ ├── Download and install app
|
||||
│ ├── Configure app settings
|
||||
│ └── Set up services
|
||||
└── Post-installation configuration
|
||||
├── Verify installation
|
||||
├── Configure access
|
||||
└── Display completion info
|
||||
```
|
||||
|
||||
### With Proxmox API
|
||||
|
||||
```
|
||||
Proxmox API Integration:
|
||||
├── API authentication
|
||||
├── Container creation via API
|
||||
├── Configuration updates via API
|
||||
├── Status monitoring via API
|
||||
└── Error handling via API
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Execution Time Optimization
|
||||
|
||||
```
|
||||
Performance Optimization:
|
||||
├── Parallel operations where possible
|
||||
├── Minimal user interaction in default mode
|
||||
├── Efficient storage selection
|
||||
├── Optimized GPU detection
|
||||
└── Streamlined validation
|
||||
```
|
||||
|
||||
### Resource Usage
|
||||
|
||||
```
|
||||
Resource Usage:
|
||||
├── Minimal memory footprint
|
||||
├── Efficient disk usage
|
||||
├── Optimized network usage
|
||||
└── Minimal CPU overhead
|
||||
```
|
||||
@@ -1,244 +0,0 @@
|
||||
# build.func Execution Flowchart
|
||||
|
||||
## Main Execution Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ START() │
|
||||
│ Entry point when build.func is sourced or executed │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Check Environment │
|
||||
│ • Detect if running on Proxmox host vs inside container │
|
||||
│ • Capture hard environment variables │
|
||||
│ • Set CT_TYPE based on context │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Determine Action │
|
||||
│ • If CT_TYPE="update" → update_script() │
|
||||
│ • If CT_TYPE="install" → install_script() │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ INSTALL_SCRIPT() │
|
||||
│ Main container creation workflow │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Installation Mode Selection │
|
||||
│ │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
|
||||
│ │ Default │ │ Advanced │ │ My Defaults │ │ App Defaults│ │
|
||||
│ │ Install │ │ Install │ │ │ │ │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ • Use built-in │ │ • Full whiptail │ │ • Load from │ │ • Load from │ │
|
||||
│ │ defaults │ │ menus │ │ default.vars │ │ app.vars │ │
|
||||
│ │ • Minimal │ │ • Interactive │ │ • Override │ │ • App- │ │
|
||||
│ │ prompts │ │ configuration │ │ built-ins │ │ specific │ │
|
||||
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────┘ │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ VARIABLES() │
|
||||
│ • Load variable precedence chain: │
|
||||
│ 1. Hard environment variables │
|
||||
│ 2. App-specific .vars file │
|
||||
│ 3. Global default.vars file │
|
||||
│ 4. Built-in defaults in base_settings() │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ BASE_SETTINGS() │
|
||||
│ • Set core container parameters │
|
||||
│ • Configure OS selection │
|
||||
│ • Set resource defaults (CPU, RAM, Disk) │
|
||||
│ • Configure network defaults │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Storage Selection Logic │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ SELECT_STORAGE() │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │ │
|
||||
│ │ │ Template │ │ Container │ │ Resolution │ │ │
|
||||
│ │ │ Storage │ │ Storage │ │ Logic │ │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Check if │ │ • Check if │ │ 1. Only 1 storage │ │ │
|
||||
│ │ │ preselected │ │ preselected │ │ → Auto-select │ │ │
|
||||
│ │ │ • Validate │ │ • Validate │ │ 2. Preselected │ │ │
|
||||
│ │ │ availability │ │ availability │ │ → Validate & use │ │ │
|
||||
│ │ │ • Prompt if │ │ • Prompt if │ │ 3. Multiple options │ │ │
|
||||
│ │ │ needed │ │ needed │ │ → Prompt user │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ BUILD_CONTAINER() │
|
||||
│ • Validate all settings │
|
||||
│ • Check for conflicts │
|
||||
│ • Prepare container configuration │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ CREATE_LXC_CONTAINER() │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Container Creation Process │ │
|
||||
│ │ │ │
|
||||
│ │ 1. Create LXC container with basic configuration │ │
|
||||
│ │ 2. Configure network settings │ │
|
||||
│ │ 3. Set up storage and mount points │ │
|
||||
│ │ 4. Configure features (FUSE, TUN, etc.) │ │
|
||||
│ │ 5. Set resource limits │ │
|
||||
│ │ 6. Configure startup options │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ GPU Passthrough Decision Tree │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ DETECT_GPU_DEVICES() │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐ │ │
|
||||
│ │ │ Intel GPU │ │ AMD GPU │ │ NVIDIA GPU │ │ │
|
||||
│ │ │ │ │ │ │ │ │ │
|
||||
│ │ │ • Check i915 │ │ • Check AMDGPU │ │ • Check NVIDIA │ │ │
|
||||
│ │ │ driver │ │ driver │ │ driver │ │ │
|
||||
│ │ │ • Detect │ │ • Detect │ │ • Detect devices │ │ │
|
||||
│ │ │ devices │ │ devices │ │ • Check CUDA support │ │ │
|
||||
│ │ └─────────────────┘ └─────────────────┘ └─────────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ GPU Selection Logic │ │
|
||||
│ │ │ │
|
||||
│ │ • Is app in GPU_APPS list? OR Is container privileged? │ │
|
||||
│ │ └─ YES → Proceed with GPU configuration │ │
|
||||
│ │ └─ NO → Skip GPU passthrough │ │
|
||||
│ │ │ │
|
||||
│ │ • Single GPU type detected? │ │
|
||||
│ │ └─ YES → Auto-select and configure │ │
|
||||
│ │ └─ NO → Prompt user for selection │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ CONFIGURE_GPU_PASSTHROUGH() │
|
||||
│ • Add GPU device entries to /etc/pve/lxc/<ctid>.conf │
|
||||
│ • Configure proper device permissions │
|
||||
│ • Set up device mapping │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Container Finalization │
|
||||
│ • Start container │
|
||||
│ • Wait for network connectivity │
|
||||
│ • Fix GPU GIDs (if GPU passthrough enabled) │
|
||||
│ • Configure SSH keys (if enabled) │
|
||||
│ • Run post-installation scripts │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ Settings Persistence │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
|
||||
│ │ DEFAULT_VAR_SETTINGS() │ │
|
||||
│ │ │ │
|
||||
│ │ • Offer to save current settings as defaults │ │
|
||||
│ │ • Save to /usr/local/community-scripts/default.vars │ │
|
||||
│ │ • Save to /usr/local/community-scripts/defaults/<app>.vars │ │
|
||||
│ └─────────────────────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────┬───────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────────────────┐
|
||||
│ COMPLETION │
|
||||
│ • Display container information │
|
||||
│ • Show access details │
|
||||
│ • Provide next steps │
|
||||
└─────────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Key Decision Points
|
||||
|
||||
### 1. Installation Mode Selection
|
||||
- **Default**: Uses built-in defaults, minimal user interaction
|
||||
- **Advanced**: Full interactive configuration via whiptail menus
|
||||
- **My Defaults**: Loads settings from global default.vars file
|
||||
- **App Defaults**: Loads settings from app-specific .vars file
|
||||
|
||||
### 2. Storage Selection Logic
|
||||
```
|
||||
Storage Selection Flow:
|
||||
├── Check if storage is preselected via environment variables
|
||||
│ ├── YES → Validate availability and use
|
||||
│ └── NO → Continue to resolution logic
|
||||
├── Count available storage options for content type
|
||||
│ ├── Only 1 option → Auto-select
|
||||
│ └── Multiple options → Prompt user via whiptail
|
||||
└── Validate selected storage and proceed
|
||||
```
|
||||
|
||||
### 3. GPU Passthrough Decision Tree
|
||||
```
|
||||
GPU Passthrough Flow:
|
||||
├── Detect available GPU hardware
|
||||
│ ├── Intel GPU detected
|
||||
│ ├── AMD GPU detected
|
||||
│ └── NVIDIA GPU detected
|
||||
├── Check if GPU passthrough should be enabled
|
||||
│ ├── App is in GPU_APPS list? → YES
|
||||
│ ├── Container is privileged? → YES
|
||||
│ └── Neither? → Skip GPU passthrough
|
||||
├── Configure GPU passthrough
|
||||
│ ├── Single GPU type → Auto-configure
|
||||
│ └── Multiple GPU types → Prompt user
|
||||
└── Fix GPU GIDs post-creation
|
||||
```
|
||||
|
||||
### 4. Variable Precedence Chain
|
||||
```
|
||||
Variable Resolution Order:
|
||||
1. Hard environment variables (captured at start)
|
||||
2. App-specific .vars file (/usr/local/community-scripts/defaults/<app>.vars)
|
||||
3. Global default.vars file (/usr/local/community-scripts/default.vars)
|
||||
4. Built-in defaults in base_settings() function
|
||||
```
|
||||
|
||||
## Error Handling Flow
|
||||
|
||||
```
|
||||
Error Handling:
|
||||
├── Validation errors → Display error message and exit
|
||||
├── Storage errors → Retry storage selection
|
||||
├── Network errors → Retry network configuration
|
||||
├── GPU errors → Fall back to no GPU passthrough
|
||||
└── Container creation errors → Cleanup and exit
|
||||
```
|
||||
|
||||
## Integration Points
|
||||
|
||||
- **Core Functions**: Depends on core.func for basic utilities
|
||||
- **Error Handling**: Uses error_handler.func for error management
|
||||
- **API Functions**: Uses api.func for Proxmox API interactions
|
||||
- **Tools**: Uses tools.func for additional utilities
|
||||
- **Install Scripts**: Integrates with <app>-install.sh scripts
|
||||
@@ -1,489 +0,0 @@
|
||||
# build.func Functions Reference
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a comprehensive reference of all functions in `build.func`, organized alphabetically with detailed descriptions, parameters, and usage information.
|
||||
|
||||
## Function Categories
|
||||
|
||||
### Initialization Functions
|
||||
|
||||
#### `start()`
|
||||
|
||||
**Purpose**: Main entry point when build.func is sourced or executed
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Detects execution context (Proxmox host vs container)
|
||||
- Captures hard environment variables
|
||||
- Sets CT_TYPE based on context
|
||||
- Routes to appropriate workflow (install_script or update_script)
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: `CT_TYPE`, `APP`, `CTID`
|
||||
|
||||
#### `variables()`
|
||||
|
||||
**Purpose**: Load and resolve all configuration variables using precedence chain
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Loads app-specific .vars file
|
||||
- Loads global default.vars file
|
||||
- Applies variable precedence chain
|
||||
- Sets all configuration variables
|
||||
**Dependencies**: `base_settings()`
|
||||
**Environment Variables Used**: All configuration variables
|
||||
|
||||
#### `base_settings()`
|
||||
|
||||
**Purpose**: Set built-in default values for all configuration variables
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**: Sets default values for all variables
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: All configuration variables
|
||||
|
||||
### UI and Menu Functions
|
||||
|
||||
#### `install_script()`
|
||||
|
||||
**Purpose**: Main installation workflow coordinator
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Displays installation mode selection menu
|
||||
- Coordinates the entire installation process
|
||||
- Handles user interaction and validation
|
||||
**Dependencies**: `variables()`, `build_container()`, `default_var_settings()`
|
||||
**Environment Variables Used**: `APP`, `CTID`, `var_hostname`
|
||||
|
||||
#### `advanced_settings()`
|
||||
|
||||
**Purpose**: Provide advanced configuration options via whiptail menus
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Displays whiptail menus for configuration
|
||||
- Updates configuration variables based on user input
|
||||
- Validates user selections
|
||||
**Dependencies**: `select_storage()`, `detect_gpu_devices()`
|
||||
**Environment Variables Used**: All configuration variables
|
||||
|
||||
#### `settings_menu()`
|
||||
|
||||
**Purpose**: Display and handle settings configuration menu
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**: Updates configuration variables
|
||||
**Dependencies**: `advanced_settings()`
|
||||
**Environment Variables Used**: All configuration variables
|
||||
|
||||
### Storage Functions
|
||||
|
||||
#### `select_storage()`
|
||||
|
||||
**Purpose**: Handle storage selection for templates and containers
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Resolves storage preselection
|
||||
- Prompts user for storage selection if needed
|
||||
- Validates storage availability
|
||||
- Sets var_template_storage and var_container_storage
|
||||
**Dependencies**: `resolve_storage_preselect()`, `choose_and_set_storage_for_file()`
|
||||
**Environment Variables Used**: `var_template_storage`, `var_container_storage`, `TEMPLATE_STORAGE`, `CONTAINER_STORAGE`
|
||||
|
||||
#### `resolve_storage_preselect()`
|
||||
|
||||
**Purpose**: Resolve preselected storage options
|
||||
**Parameters**:
|
||||
|
||||
- `storage_type`: Type of storage (template or container)
|
||||
**Returns**: Storage name if valid, empty if invalid
|
||||
**Side Effects**: Validates storage availability
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: `var_template_storage`, `var_container_storage`
|
||||
|
||||
#### `choose_and_set_storage_for_file()`
|
||||
|
||||
**Purpose**: Interactive storage selection via whiptail
|
||||
**Parameters**:
|
||||
|
||||
- `storage_type`: Type of storage (template or container)
|
||||
- `content_type`: Content type (vztmpl or rootdir)
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
- Displays whiptail menu
|
||||
- Updates storage variables
|
||||
- Validates selection
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: `var_template_storage`, `var_container_storage`
|
||||
|
||||
### Container Creation Functions
|
||||
|
||||
#### `build_container()`
|
||||
|
||||
**Purpose**: Validate settings and prepare container creation
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Validates all configuration
|
||||
- Checks for conflicts
|
||||
- Prepares container configuration
|
||||
- Calls create_lxc_container()
|
||||
**Dependencies**: `create_lxc_container()`
|
||||
**Environment Variables Used**: All configuration variables
|
||||
|
||||
#### `create_lxc_container()`
|
||||
|
||||
**Purpose**: Create the actual LXC container
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Creates LXC container with basic configuration
|
||||
- Configures network settings
|
||||
- Sets up storage and mount points
|
||||
- Configures features (FUSE, TUN, etc.)
|
||||
- Sets resource limits
|
||||
- Configures startup options
|
||||
- Starts container
|
||||
**Dependencies**: `configure_gpu_passthrough()`, `fix_gpu_gids()`
|
||||
**Environment Variables Used**: All configuration variables
|
||||
|
||||
### GPU and Hardware Functions
|
||||
|
||||
#### `detect_gpu_devices()`
|
||||
|
||||
**Purpose**: Detect available GPU hardware on the system
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Scans for Intel, AMD, and NVIDIA GPUs
|
||||
- Updates var_gpu_type and var_gpu_devices
|
||||
- Determines GPU capabilities
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: `var_gpu_type`, `var_gpu_devices`, `GPU_APPS`
|
||||
|
||||
#### `configure_gpu_passthrough()`
|
||||
|
||||
**Purpose**: Configure GPU passthrough for the container
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Adds GPU device entries to container config
|
||||
- Configures proper device permissions
|
||||
- Sets up device mapping
|
||||
- Updates /etc/pve/lxc/<ctid>.conf
|
||||
**Dependencies**: `detect_gpu_devices()`
|
||||
**Environment Variables Used**: `var_gpu`, `var_gpu_type`, `var_gpu_devices`, `CTID`
|
||||
|
||||
#### `fix_gpu_gids()`
|
||||
|
||||
**Purpose**: Fix GPU group IDs after container creation
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Updates GPU group IDs in container
|
||||
- Ensures proper GPU access permissions
|
||||
- Configures video and render groups
|
||||
**Dependencies**: `configure_gpu_passthrough()`
|
||||
**Environment Variables Used**: `CTID`, `var_gpu_type`
|
||||
|
||||
### SSH Configuration Functions
|
||||
|
||||
#### `configure_ssh_settings()`
|
||||
|
||||
**Purpose**: Interactive SSH key and access configuration wizard
|
||||
**Parameters**:
|
||||
|
||||
- `step_info` (optional): Step indicator string (e.g., "Step 17/19") for consistent dialog headers
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
- Creates temporary file for SSH keys
|
||||
- Discovers and presents available SSH keys from host
|
||||
- Allows manual key entry or folder/glob scanning
|
||||
- Sets `SSH` variable to "yes" or "no" based on user selection
|
||||
- Sets `SSH_AUTHORIZED_KEY` if manual key provided
|
||||
- Populates `SSH_KEYS_FILE` with selected keys
|
||||
**Dependencies**: `ssh_discover_default_files()`, `ssh_build_choices_from_files()`
|
||||
**Environment Variables Used**: `SSH`, `SSH_AUTHORIZED_KEY`, `SSH_KEYS_FILE`
|
||||
|
||||
**SSH Key Source Options**:
|
||||
|
||||
1. `found` - Select from auto-detected host keys
|
||||
2. `manual` - Paste a single public key
|
||||
3. `folder` - Scan custom folder or glob pattern
|
||||
4. `none` - No SSH keys
|
||||
|
||||
**Note**: The "Enable root SSH access?" dialog is always shown, regardless of whether SSH keys or password are configured. This ensures users can always enable SSH access even with automatic login.
|
||||
|
||||
#### `ssh_discover_default_files()`
|
||||
|
||||
**Purpose**: Discover SSH public key files on the host system
|
||||
**Parameters**: None
|
||||
**Returns**: Array of discovered key file paths
|
||||
**Side Effects**: Scans common SSH key locations
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: `var_ssh_import_glob`
|
||||
|
||||
#### `ssh_build_choices_from_files()`
|
||||
|
||||
**Purpose**: Build whiptail checklist choices from SSH key files
|
||||
**Parameters**:
|
||||
|
||||
- Array of file paths to process
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
- Sets `CHOICES` array for whiptail checklist
|
||||
- Sets `COUNT` variable with number of keys found
|
||||
- Creates `MAPFILE` for key tag to content mapping
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: `CHOICES`, `COUNT`, `MAPFILE`
|
||||
|
||||
### Settings Persistence Functions
|
||||
|
||||
#### `default_var_settings()`
|
||||
|
||||
**Purpose**: Offer to save current settings as defaults
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Prompts user to save settings
|
||||
- Saves to default.vars file
|
||||
- Saves to app-specific .vars file
|
||||
**Dependencies**: `maybe_offer_save_app_defaults()`
|
||||
**Environment Variables Used**: All configuration variables
|
||||
|
||||
#### `maybe_offer_save_app_defaults()`
|
||||
|
||||
**Purpose**: Offer to save app-specific defaults
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Prompts user to save app-specific settings
|
||||
- Saves to app.vars file
|
||||
- Updates app-specific configuration
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: `APP`, `SAVE_APP_DEFAULTS`
|
||||
|
||||
### Utility Functions
|
||||
|
||||
#### `validate_settings()`
|
||||
|
||||
**Purpose**: Validate all configuration settings
|
||||
**Parameters**: None
|
||||
**Returns**: 0 if valid, 1 if invalid
|
||||
**Side Effects**:
|
||||
|
||||
- Checks for configuration conflicts
|
||||
- Validates resource limits
|
||||
- Validates network configuration
|
||||
- Validates storage configuration
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: All configuration variables
|
||||
|
||||
#### `check_conflicts()`
|
||||
|
||||
**Purpose**: Check for configuration conflicts
|
||||
**Parameters**: None
|
||||
**Returns**: 0 if no conflicts, 1 if conflicts found
|
||||
**Side Effects**:
|
||||
|
||||
- Checks for conflicting settings
|
||||
- Validates resource allocation
|
||||
- Checks network configuration
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: All configuration variables
|
||||
|
||||
#### `cleanup_on_error()`
|
||||
|
||||
**Purpose**: Clean up resources on error
|
||||
**Parameters**: None
|
||||
**Returns**: None
|
||||
**Side Effects**:
|
||||
|
||||
- Removes partially created containers
|
||||
- Cleans up temporary files
|
||||
- Resets configuration
|
||||
**Dependencies**: None
|
||||
**Environment Variables Used**: `CTID`
|
||||
|
||||
## Function Call Flow
|
||||
|
||||
### Main Installation Flow
|
||||
|
||||
```
|
||||
start()
|
||||
├── variables()
|
||||
│ ├── base_settings()
|
||||
│ ├── Load app.vars
|
||||
│ └── Load default.vars
|
||||
├── install_script()
|
||||
│ ├── advanced_settings()
|
||||
│ │ ├── select_storage()
|
||||
│ │ │ ├── resolve_storage_preselect()
|
||||
│ │ │ └── choose_and_set_storage_for_file()
|
||||
│ │ └── detect_gpu_devices()
|
||||
│ ├── build_container()
|
||||
│ │ ├── validate_settings()
|
||||
│ │ ├── check_conflicts()
|
||||
│ │ └── create_lxc_container()
|
||||
│ │ ├── configure_gpu_passthrough()
|
||||
│ │ └── fix_gpu_gids()
|
||||
│ └── default_var_settings()
|
||||
│ └── maybe_offer_save_app_defaults()
|
||||
```
|
||||
|
||||
### Error Handling Flow
|
||||
|
||||
```
|
||||
Error Detection
|
||||
├── validate_settings()
|
||||
│ └── check_conflicts()
|
||||
├── Error Handling
|
||||
│ └── cleanup_on_error()
|
||||
└── Exit with error code
|
||||
```
|
||||
|
||||
## Function Dependencies
|
||||
|
||||
### Core Dependencies
|
||||
|
||||
- `start()` → `install_script()` → `build_container()` → `create_lxc_container()`
|
||||
- `variables()` → `base_settings()`
|
||||
- `advanced_settings()` → `select_storage()` → `detect_gpu_devices()`
|
||||
|
||||
### Storage Dependencies
|
||||
|
||||
- `select_storage()` → `resolve_storage_preselect()`
|
||||
- `select_storage()` → `choose_and_set_storage_for_file()`
|
||||
|
||||
### GPU Dependencies
|
||||
|
||||
- `configure_gpu_passthrough()` → `detect_gpu_devices()`
|
||||
- `fix_gpu_gids()` → `configure_gpu_passthrough()`
|
||||
|
||||
### Settings Dependencies
|
||||
|
||||
- `default_var_settings()` → `maybe_offer_save_app_defaults()`
|
||||
|
||||
## Function Usage Examples
|
||||
|
||||
### Basic Container Creation
|
||||
|
||||
```bash
|
||||
# Set required variables
|
||||
export APP="plex"
|
||||
export CTID="100"
|
||||
export var_hostname="plex-server"
|
||||
|
||||
# Call main functions
|
||||
start() # Entry point
|
||||
# → variables() # Load configuration
|
||||
# → install_script() # Main workflow
|
||||
# → build_container() # Create container
|
||||
# → create_lxc_container() # Actual creation
|
||||
```
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
```bash
|
||||
# Set advanced variables
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="4"
|
||||
export var_ram="4096"
|
||||
export var_disk="20"
|
||||
|
||||
# Call advanced functions
|
||||
advanced_settings() # Interactive configuration
|
||||
# → select_storage() # Storage selection
|
||||
# → detect_gpu_devices() # GPU detection
|
||||
```
|
||||
|
||||
### GPU Passthrough
|
||||
|
||||
```bash
|
||||
# Enable GPU passthrough
|
||||
export GPU_APPS="plex"
|
||||
export var_gpu="nvidia"
|
||||
|
||||
# Call GPU functions
|
||||
detect_gpu_devices() # Detect hardware
|
||||
configure_gpu_passthrough() # Configure passthrough
|
||||
fix_gpu_gids() # Fix permissions
|
||||
```
|
||||
|
||||
### Settings Persistence
|
||||
|
||||
```bash
|
||||
# Save settings as defaults
|
||||
export SAVE_DEFAULTS="true"
|
||||
export SAVE_APP_DEFAULTS="true"
|
||||
|
||||
# Call persistence functions
|
||||
default_var_settings() # Save global defaults
|
||||
maybe_offer_save_app_defaults() # Save app defaults
|
||||
```
|
||||
|
||||
### Container Resource & ID Management
|
||||
|
||||
#### `validate_container_id()`
|
||||
**Purpose**: Validates if a container ID is available for use.
|
||||
**Parameters**: `ctid` (Integer)
|
||||
**Returns**: `0` if available, `1` if already in use or invalid.
|
||||
**Description**: Checks for existing config files in `/etc/pve/lxc/` or `/etc/pve/qemu-server/`, and verifies LVM logical volumes.
|
||||
|
||||
#### `get_valid_container_id()`
|
||||
**Purpose**: Returns the next available, unused container ID.
|
||||
**Parameters**: `suggested_id` (Optional)
|
||||
**Returns**: A valid container ID string.
|
||||
**Description**: If the suggested ID is taken, it increments until it finds an available one.
|
||||
|
||||
#### `maxkeys_check()`
|
||||
**Purpose**: Ensures host kernel parameters support high numbers of keys (required for some apps).
|
||||
**Parameters**: None
|
||||
**Description**: Checks and optionally updates `kernel.keys.maxkeys` and `kernel.keys.maxbytes`.
|
||||
|
||||
#### `get_current_ip()`
|
||||
**Purpose**: Retrieves the current IP address of the container.
|
||||
**Parameters**: `ctid` (Integer)
|
||||
**Returns**: IP address string.
|
||||
|
||||
#### `update_motd_ip()`
|
||||
**Purpose**: Updates the Message of the Day (MOTD) file with the container's IP.
|
||||
**Parameters**: None
|
||||
|
||||
## Function Error Handling
|
||||
|
||||
### Validation Functions
|
||||
|
||||
- `validate_settings()`: Returns 0 for valid, 1 for invalid
|
||||
- `check_conflicts()`: Returns 0 for no conflicts, 1 for conflicts
|
||||
|
||||
### Error Recovery
|
||||
|
||||
- `cleanup_on_error()`: Cleans up on any error
|
||||
- Error codes are propagated up the call stack
|
||||
- Critical errors cause script termination
|
||||
|
||||
### Error Types
|
||||
|
||||
1. **Configuration Errors**: Invalid settings or conflicts
|
||||
2. **Resource Errors**: Insufficient resources or conflicts
|
||||
3. **Network Errors**: Invalid network configuration
|
||||
4. **Storage Errors**: Storage not available or invalid
|
||||
5. **GPU Errors**: GPU configuration failures
|
||||
6. **Container Creation Errors**: LXC creation failures
|
||||
@@ -1,600 +0,0 @@
|
||||
# build.func Usage Examples
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides practical usage examples for `build.func`, covering common scenarios, CLI examples, and environment variable combinations.
|
||||
|
||||
## Basic Usage Examples
|
||||
|
||||
### 1. Simple Container Creation
|
||||
|
||||
**Scenario**: Create a basic Plex media server container
|
||||
|
||||
```bash
|
||||
# Set basic environment variables
|
||||
export APP="plex"
|
||||
export CTID="100"
|
||||
export var_hostname="plex-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="4"
|
||||
export var_ram="4096"
|
||||
export var_disk="20"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.100"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
|
||||
# Execute build.func
|
||||
source build.func
|
||||
```
|
||||
|
||||
**Expected Output**:
|
||||
```
|
||||
Creating Plex container...
|
||||
Container ID: 100
|
||||
Hostname: plex-server
|
||||
OS: Debian 12
|
||||
Resources: 4 CPU, 4GB RAM, 20GB Disk
|
||||
Network: 192.168.1.100/24
|
||||
Container created successfully!
|
||||
```
|
||||
|
||||
### 2. Advanced Configuration
|
||||
|
||||
**Scenario**: Create a Nextcloud container with custom settings
|
||||
|
||||
```bash
|
||||
# Set advanced environment variables
|
||||
export APP="nextcloud"
|
||||
export CTID="101"
|
||||
export var_hostname="nextcloud-server"
|
||||
export var_os="ubuntu"
|
||||
export var_version="22.04"
|
||||
export var_cpu="6"
|
||||
export var_ram="8192"
|
||||
export var_disk="50"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.101"
|
||||
export var_vlan="100"
|
||||
export var_mtu="9000"
|
||||
export var_template_storage="ssd-storage"
|
||||
export var_container_storage="ssd-storage"
|
||||
export var_fuse="yes"
|
||||
export var_tun="yes"
|
||||
export SSH="true"
|
||||
|
||||
# Execute build.func
|
||||
source build.func
|
||||
```
|
||||
|
||||
### 3. GPU Passthrough Configuration
|
||||
|
||||
**Scenario**: Create a Jellyfin container with NVIDIA GPU passthrough
|
||||
|
||||
```bash
|
||||
# Set GPU passthrough variables
|
||||
export APP="jellyfin"
|
||||
export CTID="102"
|
||||
export var_hostname="jellyfin-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="8"
|
||||
export var_ram="16384"
|
||||
export var_disk="30"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.102"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
export GPU_APPS="jellyfin"
|
||||
export var_gpu="nvidia"
|
||||
export ENABLE_PRIVILEGED="true"
|
||||
export ENABLE_FUSE="true"
|
||||
export ENABLE_TUN="true"
|
||||
|
||||
# Execute build.func
|
||||
source build.func
|
||||
```
|
||||
|
||||
## Silent/Non-Interactive Examples
|
||||
|
||||
### 1. Automated Deployment
|
||||
|
||||
**Scenario**: Deploy multiple containers without user interaction
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Automated deployment script
|
||||
|
||||
# Function to create container
|
||||
create_container() {
|
||||
local app=$1
|
||||
local ctid=$2
|
||||
local ip=$3
|
||||
|
||||
export APP="$app"
|
||||
export CTID="$ctid"
|
||||
export var_hostname="${app}-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="$ip"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
export ENABLE_FUSE="true"
|
||||
export ENABLE_TUN="true"
|
||||
export SSH="true"
|
||||
|
||||
source build.func
|
||||
}
|
||||
|
||||
# Create multiple containers
|
||||
create_container "plex" "100" "192.168.1.100"
|
||||
create_container "nextcloud" "101" "192.168.1.101"
|
||||
create_container "nginx" "102" "192.168.1.102"
|
||||
```
|
||||
|
||||
### 2. Development Environment Setup
|
||||
|
||||
**Scenario**: Create development containers with specific configurations
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Development environment setup
|
||||
|
||||
# Development container configuration
|
||||
export APP="dev-container"
|
||||
export CTID="200"
|
||||
export var_hostname="dev-server"
|
||||
export var_os="ubuntu"
|
||||
export var_version="22.04"
|
||||
export var_cpu="4"
|
||||
export var_ram="4096"
|
||||
export var_disk="20"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.200"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
export ENABLE_NESTING="true"
|
||||
export ENABLE_PRIVILEGED="true"
|
||||
export ENABLE_FUSE="true"
|
||||
export ENABLE_TUN="true"
|
||||
export SSH="true"
|
||||
|
||||
# Execute build.func
|
||||
source build.func
|
||||
```
|
||||
|
||||
## Network Configuration Examples
|
||||
|
||||
### 1. VLAN Configuration
|
||||
|
||||
**Scenario**: Create container with VLAN support
|
||||
|
||||
```bash
|
||||
# VLAN configuration
|
||||
export APP="web-server"
|
||||
export CTID="300"
|
||||
export var_hostname="web-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.100.1"
|
||||
export var_ip="192.168.100.100"
|
||||
export var_vlan="100"
|
||||
export var_mtu="1500"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
|
||||
source build.func
|
||||
```
|
||||
|
||||
### 2. IPv6 Configuration
|
||||
|
||||
**Scenario**: Create container with IPv6 support
|
||||
|
||||
```bash
|
||||
# IPv6 configuration
|
||||
export APP="ipv6-server"
|
||||
export CTID="301"
|
||||
export var_hostname="ipv6-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.101"
|
||||
export var_ipv6="2001:db8::101"
|
||||
export IPV6_METHOD="static"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
|
||||
source build.func
|
||||
```
|
||||
|
||||
## Storage Configuration Examples
|
||||
|
||||
### 1. Custom Storage Locations
|
||||
|
||||
**Scenario**: Use different storage for templates and containers
|
||||
|
||||
```bash
|
||||
# Custom storage configuration
|
||||
export APP="storage-test"
|
||||
export CTID="400"
|
||||
export var_hostname="storage-test"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.140"
|
||||
export var_template_storage="nfs-storage"
|
||||
export var_container_storage="ssd-storage"
|
||||
|
||||
source build.func
|
||||
```
|
||||
|
||||
### 2. High-Performance Storage
|
||||
|
||||
**Scenario**: Use high-performance storage for resource-intensive applications
|
||||
|
||||
```bash
|
||||
# High-performance storage configuration
|
||||
export APP="database-server"
|
||||
export CTID="401"
|
||||
export var_hostname="database-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="8"
|
||||
export var_ram="16384"
|
||||
export var_disk="100"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.141"
|
||||
export var_template_storage="nvme-storage"
|
||||
export var_container_storage="nvme-storage"
|
||||
|
||||
source build.func
|
||||
```
|
||||
|
||||
## Feature Configuration Examples
|
||||
|
||||
### 1. Privileged Container
|
||||
|
||||
**Scenario**: Create privileged container for system-level access
|
||||
|
||||
```bash
|
||||
# Privileged container configuration
|
||||
export APP="system-container"
|
||||
export CTID="500"
|
||||
export var_hostname="system-container"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="4"
|
||||
export var_ram="4096"
|
||||
export var_disk="20"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.150"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
export ENABLE_PRIVILEGED="true"
|
||||
export ENABLE_FUSE="true"
|
||||
export ENABLE_TUN="true"
|
||||
export ENABLE_KEYCTL="true"
|
||||
export ENABLE_MOUNT="true"
|
||||
|
||||
source build.func
|
||||
```
|
||||
|
||||
### 2. Unprivileged Container
|
||||
|
||||
**Scenario**: Create secure unprivileged container
|
||||
|
||||
```bash
|
||||
# Unprivileged container configuration
|
||||
export APP="secure-container"
|
||||
export CTID="501"
|
||||
export var_hostname="secure-container"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.151"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
export ENABLE_UNPRIVILEGED="true"
|
||||
export ENABLE_FUSE="true"
|
||||
export ENABLE_TUN="true"
|
||||
|
||||
source build.func
|
||||
```
|
||||
|
||||
## Settings Persistence Examples
|
||||
|
||||
### 1. Save Global Defaults
|
||||
|
||||
**Scenario**: Save current settings as global defaults
|
||||
|
||||
```bash
|
||||
# Save global defaults
|
||||
export APP="default-test"
|
||||
export CTID="600"
|
||||
export var_hostname="default-test"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.160"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
export SAVE_DEFAULTS="true"
|
||||
|
||||
source build.func
|
||||
```
|
||||
|
||||
### 2. Save App-Specific Defaults
|
||||
|
||||
**Scenario**: Save settings as app-specific defaults
|
||||
|
||||
```bash
|
||||
# Save app-specific defaults
|
||||
export APP="plex"
|
||||
export CTID="601"
|
||||
export var_hostname="plex-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="4"
|
||||
export var_ram="4096"
|
||||
export var_disk="20"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.161"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
export SAVE_APP_DEFAULTS="true"
|
||||
|
||||
source build.func
|
||||
```
|
||||
|
||||
## Error Handling Examples
|
||||
|
||||
### 1. Validation Error Handling
|
||||
|
||||
**Scenario**: Handle configuration validation errors
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Error handling example
|
||||
|
||||
# Set invalid configuration
|
||||
export APP="error-test"
|
||||
export CTID="700"
|
||||
export var_hostname="error-test"
|
||||
export var_os="invalid-os"
|
||||
export var_version="invalid-version"
|
||||
export var_cpu="invalid-cpu"
|
||||
export var_ram="invalid-ram"
|
||||
export var_disk="invalid-disk"
|
||||
export var_net="invalid-network"
|
||||
export var_gateway="invalid-gateway"
|
||||
export var_ip="invalid-ip"
|
||||
|
||||
# Execute with error handling
|
||||
if source build.func; then
|
||||
echo "Container created successfully!"
|
||||
else
|
||||
echo "Error: Container creation failed!"
|
||||
echo "Please check your configuration and try again."
|
||||
fi
|
||||
```
|
||||
|
||||
### 2. Storage Error Handling
|
||||
|
||||
**Scenario**: Handle storage selection errors
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Storage error handling
|
||||
|
||||
# Set invalid storage
|
||||
export APP="storage-error-test"
|
||||
export CTID="701"
|
||||
export var_hostname="storage-error-test"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.170"
|
||||
export var_template_storage="nonexistent-storage"
|
||||
export var_container_storage="nonexistent-storage"
|
||||
|
||||
# Execute with error handling
|
||||
if source build.func; then
|
||||
echo "Container created successfully!"
|
||||
else
|
||||
echo "Error: Storage not available!"
|
||||
echo "Please check available storage and try again."
|
||||
fi
|
||||
```
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### 1. With Install Scripts
|
||||
|
||||
**Scenario**: Integrate with application install scripts
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Integration with install scripts
|
||||
|
||||
# Create container
|
||||
export APP="plex"
|
||||
export CTID="800"
|
||||
export var_hostname="plex-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="4"
|
||||
export var_ram="4096"
|
||||
export var_disk="20"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.180"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
|
||||
# Create container
|
||||
source build.func
|
||||
|
||||
# Run install script
|
||||
if [ -f "plex-install.sh" ]; then
|
||||
source plex-install.sh
|
||||
else
|
||||
echo "Install script not found!"
|
||||
fi
|
||||
```
|
||||
|
||||
### 2. With Monitoring
|
||||
|
||||
**Scenario**: Integrate with monitoring systems
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Monitoring integration
|
||||
|
||||
# Create container with monitoring
|
||||
export APP="monitored-app"
|
||||
export CTID="801"
|
||||
export var_hostname="monitored-app"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.181"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
export DIAGNOSTICS="true"
|
||||
|
||||
# Create container
|
||||
source build.func
|
||||
|
||||
# Set up monitoring
|
||||
if [ -f "monitoring-setup.sh" ]; then
|
||||
source monitoring-setup.sh
|
||||
fi
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Environment Variable Management
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Best practice: Environment variable management
|
||||
|
||||
# Set configuration file
|
||||
CONFIG_FILE="/etc/build.func.conf"
|
||||
|
||||
# Load configuration if exists
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
source "$CONFIG_FILE"
|
||||
fi
|
||||
|
||||
# Set required variables
|
||||
export APP="${APP:-plex}"
|
||||
export CTID="${CTID:-100}"
|
||||
export var_hostname="${var_hostname:-plex-server}"
|
||||
export var_os="${var_os:-debian}"
|
||||
export var_version="${var_version:-12}"
|
||||
export var_cpu="${var_cpu:-2}"
|
||||
export var_ram="${var_ram:-2048}"
|
||||
export var_disk="${var_disk:-10}"
|
||||
export var_net="${var_net:-vmbr0}"
|
||||
export var_gateway="${var_gateway:-192.168.1.1}"
|
||||
export var_ip="${var_ip:-192.168.1.100}"
|
||||
export var_template_storage="${var_template_storage:-local}"
|
||||
export var_container_storage="${var_container_storage:-local}"
|
||||
|
||||
# Execute build.func
|
||||
source build.func
|
||||
```
|
||||
|
||||
### 2. Error Handling and Logging
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Best practice: Error handling and logging
|
||||
|
||||
# Set log file
|
||||
LOG_FILE="/var/log/build.func.log"
|
||||
|
||||
# Function to log messages
|
||||
log_message() {
|
||||
echo "$(date): $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Function to create container with error handling
|
||||
create_container() {
|
||||
local app=$1
|
||||
local ctid=$2
|
||||
|
||||
log_message "Starting container creation for $app (ID: $ctid)"
|
||||
|
||||
# Set variables
|
||||
export APP="$app"
|
||||
export CTID="$ctid"
|
||||
export var_hostname="${app}-server"
|
||||
export var_os="debian"
|
||||
export var_version="12"
|
||||
export var_cpu="2"
|
||||
export var_ram="2048"
|
||||
export var_disk="10"
|
||||
export var_net="vmbr0"
|
||||
export var_gateway="192.168.1.1"
|
||||
export var_ip="192.168.1.$ctid"
|
||||
export var_template_storage="local"
|
||||
export var_container_storage="local"
|
||||
|
||||
# Create container
|
||||
if source build.func; then
|
||||
log_message "Container $app created successfully (ID: $ctid)"
|
||||
return 0
|
||||
else
|
||||
log_message "Error: Failed to create container $app (ID: $ctid)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Create containers
|
||||
create_container "plex" "100"
|
||||
create_container "nextcloud" "101"
|
||||
create_container "nginx" "102"
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user