Compare commits

..

96 Commits

Author SHA1 Message Date
CanbiZ (MickLesk) 27190a1fcc Update script messages for GitLab installation 2026-08-10 08:47:09 +02:00
push-app-to-main[bot] ec74ef5be6 Add gitlab (ct) 2026-08-10 06:36:24 +00:00
community-scripts-pr-app[bot] 6ae19c8a22 Update CHANGELOG.md (#16381)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-10 00:05:16 +00:00
push-app-to-main[bot] d734d2204f Add post-pdm-install (pve) (#16368)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2026-08-10 10:04:51 +10:00
community-scripts-pr-app[bot] 43e3f5215d Update CHANGELOG.md (#16378)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-09 18:23:08 +00:00
CanbiZ (MickLesk) 3ed946390f Portainer: Update existing CE and BE installations (#16357) 2026-08-09 20:22:40 +02:00
community-scripts-pr-app[bot] 4626ec8845 Update CHANGELOG.md (#16377)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-09 18:09:09 +00:00
fudian 579c1b6b26 Fix: CouchDB Erlang cookie breaks vm.args (use hex) (#16361)
* CouchDB: generate an Erlang-safe (hex) cookie

ERLANG_COOKIE was generated with `openssl rand -base64 32`, whose output
contains +, / and = (e.g. "+w2dDazB/CrIZMsZu8edX4hn55QeRXOCi+hom25Lmm8=").
CouchDB writes the cookie into /opt/couchdb/etc/vm.args as
`-setcookie '<cookie>'`, and those characters break Erlang's vm.args
parsing, so couchdb.service fails to start on a fresh install (#16360).

Use `openssl rand -hex 32` instead: a 64-char hex string is alphanumeric,
needs no quoting, and is always a valid Erlang cookie. (Same 256-bit
entropy as the base64 of 32 bytes.)

Closes #16360

* Update install/apache-couchdb-install.sh

---------

Co-authored-by: Sam Heinz <sam@samheinz.com>
2026-08-09 20:08:41 +02:00
community-scripts-pr-app[bot] 5264fc5897 Update CHANGELOG.md (#16374)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-09 16:50:47 +00:00
community-scripts-pr-app[bot] 6063f0747d Update CHANGELOG.md (#16373)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-09 16:50:32 +00:00
CanbiZ (MickLesk) 5374826753 SparkyFitness: Install Git for frontend builds (#16352) 2026-08-09 18:50:22 +02:00
community-scripts-pr-app[bot] b32071de43 Update CHANGELOG.md (#16372)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-09 16:50:12 +00:00
CanbiZ (MickLesk) af10e10f20 Byparr: Use invisible-playwright browser setup (#16353) 2026-08-09 18:50:05 +02:00
CanbiZ (MickLesk) ad09299de7 Crafty Controller: Restore ownership after updates (#16354) 2026-08-09 18:49:50 +02:00
community-scripts-pr-app[bot] 5f71caac5b Update CHANGELOG.md (#16371)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-09 16:49:48 +00:00
CanbiZ (MickLesk) 87db412709 Webtrees: Fix schema check in silent mode (#16355) 2026-08-09 18:49:38 +02:00
CanbiZ (MickLesk) 83ad1c972d SigNoz: Allow legacy metadata schema on ClickHouse 26 (#16356) 2026-08-09 18:49:26 +02:00
community-scripts-pr-app[bot] d11d3156db Update CHANGELOG.md (#16369)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-09 14:19:55 +00:00
CanbiZ (MickLesk) 773b46c969 github: update Star History links and image sources (#16367) 2026-08-09 16:19:29 +02:00
community-scripts-pr-app[bot] d87e59f626 Update CHANGELOG.md (#16363)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-09 00:07:00 +00:00
community-scripts-pr-app[bot] d69579d477 Archive old changelog entries (#16362)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-09 00:06:30 +00:00
community-scripts-pr-app[bot] 8386465a92 Update CHANGELOG.md (#16338)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-08 02:38:26 +00:00
push-app-to-main[bot] bcec3c405a Ignis (#16330)
* Add ignis (ct)

* Fix source line to always use community scripts URL

Updated the source line to always fetch from the community scripts repository.

* Apply suggestion from @tremor021

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
2026-08-08 12:37:57 +10:00
community-scripts-pr-app[bot] 4c8f5bd1f0 Update CHANGELOG.md (#16337)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-08 02:35:25 +00:00
CanbiZ (MickLesk) d87fef0892 core - setup_nodejs: bypass npm allowScripts policy globally on npm >=11 (#16280)
* setup_nodejs: bypass npm allowScripts policy globally on npm >=11

* Update misc/tools.func

Co-authored-by: Sam Heinz <sam@samheinz.com>

---------

Co-authored-by: Sam Heinz <sam@samheinz.com>
2026-08-08 12:35:03 +10:00
community-scripts-pr-app[bot] 5d14989682 Update CHANGELOG.md (#16334)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-07 17:46:02 +00:00
Tom Frenzel a296ccfc7e HortusFox: start applying db migrations (#16324) 2026-08-07 19:45:32 +02:00
community-scripts-pr-app[bot] f0fc577d79 Update CHANGELOG.md (#16333)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-07 17:43:02 +00:00
push-app-to-main[bot] fbd9d24966 NetworkOptimizer (#16328)
* Add networkoptimizer (ct)

* Update source line for build.func in networkoptimizer.sh

Updated the source line to always use the latest build.func script from the community scripts repository.

* Apply suggestion from @tremor021

* Apply suggestion from @tremor021

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
2026-08-07 19:42:34 +02:00
community-scripts-pr-app[bot] 347e0e6ff0 Update CHANGELOG.md (#16332)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-07 17:42:05 +00:00
push-app-to-main[bot] 4adea9666e Orb (#16329)
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
2026-08-07 19:41:33 +02:00
community-scripts-pr-app[bot] 1d94e50601 Update CHANGELOG.md (#16326)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-07 09:44:04 +00:00
CanbiZ (MickLesk) 0092fa8b54 Docker: report container updates instead of prompting, stop auto-updating Portainer Agent, fix addon detection of legacy Portainer (#16298)
* Docker: report container updates instead of prompting, stop auto-updating Portainer Agent, fix addon detection of legacy Portainer

* Update portainer.sh
2026-08-07 19:43:32 +10:00
community-scripts-pr-app[bot] e00d4c6e51 Update CHANGELOG.md (#16322)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-07 08:11:07 +00:00
community-scripts-pr-app[bot] c1d5bfdb83 Update CHANGELOG.md (#16321)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-07 08:10:44 +00:00
CanbiZ (MickLesk) 33de14e45c Immich: retry mise install on transient npm download failures (#16301) 2026-08-07 10:10:35 +02:00
Austin 156f5ae16f changedetection: remove msttcorefonts to fix install hang (#16319) 2026-08-07 10:10:15 +02:00
community-scripts-pr-app[bot] 7100e1679e Update CHANGELOG.md (#16320)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-07 02:50:12 +00:00
CanbiZ (MickLesk) 63e4ea1396 core: extend new vars and pocketbase values (#16313)
* Let docker-install.sh take its three answers up front

The script asked three questions with no way to answer them in advance,
so a Docker container could not be deployed unattended: Portainer, the
Portainer Agent, and whether to expose the TCP socket.

Each now reads a variable and prompts only when it is unset, the same
shape install/forgejo-runner-install.sh already uses:

  var_portainer         yes | no
  var_portainer_agent   yes | no
  var_docker_socket     n | l (127.0.0.1) | a (0.0.0.0)

Interactive behaviour is unchanged — with nothing set, all three still
ask exactly as before.

The matching declaration for the script's PocketBase record, which the
website generator reads to offer these as form fields:

  "app_vars": [
    {"name":"var_portainer","label":"Install Portainer","type":"boolean","default":"no"},
    {"name":"var_portainer_agent","label":"Install Portainer Agent","type":"boolean","default":"no",
     "help":"Only used when Portainer itself is not installed"},
    {"name":"var_docker_socket","label":"Expose Docker TCP socket","type":"select",
     "options":["n","l","a"],"default":"n",
     "help":"l = 127.0.0.1 only, a = all interfaces (insecure)"}
  ]

CONTRIBUTING.md documents the convention so the next script follows it.

* Let docker-install.sh take its three answers up front

The script asked three questions with no way to answer them in advance,
so a Docker container could not be deployed unattended: Portainer, the
Portainer Agent, and whether to expose the TCP socket.

Each now reads a variable and prompts only when it is unset, the same
shape install/forgejo-runner-install.sh already uses:

  var_portainer         yes | no
  var_portainer_agent   yes | no
  var_docker_socket     n | l (127.0.0.1) | a (0.0.0.0)

Interactive behaviour is unchanged — with nothing set, all three still
ask exactly as before.

The matching declaration for the script's PocketBase record, which the
website generator reads to offer these as form fields:

  "app_vars": [
    {"name":"var_portainer","label":"Install Portainer","type":"boolean","default":"no"},
    {"name":"var_portainer_agent","label":"Install Portainer Agent","type":"boolean","default":"no",
     "help":"Only used when Portainer itself is not installed"},
    {"name":"var_docker_socket","label":"Expose Docker TCP socket","type":"select",
     "options":["n","l","a"],"default":"n",
     "help":"l = 127.0.0.1 only, a = all interfaces (insecure)"}
  ]

CONTRIBUTING.md documents the convention so the next script follows it.

* Let forgejo-runner and pangolin take their answers up front

forgejo-runner already exported two of the three values its install
script requires, but not var_forgejo_runner_uuid — so an unattended
install passed the ct-level guard and then stopped at a prompt inside
the container, which is the one place nobody can answer it. The guard
missed it for the same reason.

pangolin asked for its URL and email with no way to supply them. Both
sides are needed: the read in install/ now only fires when the variable
is unset, and ct/ exports it, because lxc-attach carries the caller's
environment but only what was exported.

Reverts the docker change from the previous commit; it is superseded by
work on another branch.

* Teach the PocketBase workflows the capability fields

All three wrote fields the site no longer reads. The slash bot and the
AI bot accepted has_arm=true and github=owner/repo; push-json mapped
has_arm into the payload. After the schema change those writes would
have gone to columns that are not there.

architectures and platforms are multi-selects over a closed set, so
both bots reject an unknown value instead of storing it — the same
guarantee the field type gives in the admin UI.

push-json still reads has_arm when architectures is absent, because
ProxmoxVED's json files carry the old key until they are converted.

* Drop the docker change again

It came back through the merge in 35735dae: the branch was pushed
before the revert, so merging the remote copy restored it. Removing it
forward rather than rewriting history that is already published.
2026-08-07 12:49:45 +10:00
rcourtman 63a91c8d93 fix(tools): stop a failed deploy from wiping the existing install (#16312) 2026-08-06 21:50:12 +02:00
CanbiZ (MickLesk) 590d638094 build.func: fix pveam arch filter for extra whitespace column (#16315) 2026-08-06 21:03:28 +02:00
Sam Heinz fb1d670158 dont skip enterprise repo setup on arm64 (#16307) 2026-08-06 21:02:43 +02:00
community-scripts-pr-app[bot] 5ddc4a2a41 Update CHANGELOG.md (#16309)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-06 12:33:52 +00:00
CanbiZ (MickLesk) 448a080970 build.func: filter templates by host architecture during search (#16302) 2026-08-06 22:33:22 +10:00
community-scripts-pr-app[bot] c45c3f3a6c Update CHANGELOG.md (#16308)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-06 12:29:33 +00:00
CanbiZ (MickLesk) 12f228da1c paperless: change update abort message (endless spinner) (#16299) 2026-08-06 14:28:58 +02:00
community-scripts-pr-app[bot] ecd115c279 Update CHANGELOG.md (#16306)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-06 12:27:06 +00:00
CanbiZ (MickLesk) 288a130fe7 Vikunja: remove version pin, v2.5.0 fixes the systemd syscall filter crash (#16300) 2026-08-06 14:26:40 +02:00
community-scripts-pr-app[bot] d53486c86e Update CHANGELOG.md (#16294)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-05 20:36:09 +00:00
community-scripts-pr-app[bot] 4f80c217fc Update CHANGELOG.md (#16293)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-05 20:35:38 +00:00
jomplox f4afdfcd0c fix(monitor-all): reduce polling CPU overhead (#15907) 2026-08-05 22:35:03 +02:00
MickLesk 3865f855f0 qf 2026-08-05 17:35:32 +02:00
MickLesk 94da6eeb83 qf 2026-08-05 15:00:34 +02:00
MickLesk 078a76f263 Extract reclaim_tty into reusable function
Move the inline TTY reclamation logic from build.func into a standalone reclaim_tty() function in core.func. This improves code reusability, as the function now needs to be called before each interactive prompt (not just after install) since pct exec/pull/enter can take the terminal away again. The function also includes better error handling with checks for perl availability and /dev/tty existence, and explicitly sets SIGTTOU to IGNORE in perl.
2026-08-05 14:57:15 +02:00
community-scripts-pr-app[bot] 58d819b2f4 Update CHANGELOG.md (#16290)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-05 12:04:43 +00:00
CanbiZ (MickLesk) 1c03d0506c NextcloudPI: Bump to Debian Trixie & Tweak broken SSH (#15957)
* Pin NextCloudPi installer to last known-good stable release

The floating "master" branch of nextcloud/nextcloudpi's install.sh
started rejecting our default Debian 12 base with "distro not
supported" (#15944) after a regression landed upstream; the script
is third-party code we don't audit or control. Pin to v1.57.1, the
latest stable (non-prerelease) release, which explicitly targets
Debian bookworm and predates the regression.

* Actually pin the branch nextcloudpi's install.sh clones internally

install.sh is only a thin bootstrapper: it clones BRANCH (default
"master") of the nextcloudpi repo itself and runs the real installer
from that fresh checkout, including the distro-support check. Fetching
install.sh from a pinned tag alone left BRANCH defaulting to "master",
so the internally-cloned code was unaffected and still failed with
"distro not supported" - confirmed by testing the previous fix. Pass
BRANCH explicitly so the internal clone also targets the pinned tag.

* Bump NextCloudPi to Debian 13, matching upstream's trixie move

Upstream's master ncp.cfg now targets release "trixie" (Debian 13);
bookworm (Debian 12) is no longer in the supported check_distro list
at all. Move our own default to Debian 13 and pin the installer ref
to v1.58.0-rc1, the only tagged ref with release=trixie so far (no
stable trixie release exists yet upstream).

* Revert installer pin, track master again

master now targets trixie itself (matches the Debian 13 bump), and
the only tagged trixie ref was an RC explicitly marked "expect bugs".
Tracking master gets upstream trixie fixes as they land instead of
being stuck on a stale test release.

* Work around nextcloudpi's broken ssh.socket restart on Debian 13

Debian 13's openssh-server ships socket-activated by default. NCP's
own bin/ncp/NETWORKING/SSH.sh detects that (systemctl is-active
ssh.socket) but then runs "systemctl restart ssh" in that branch
instead of reloading, which collides with the port ssh.socket already
holds and fails with "Job for ssh.service failed" (#15944). Switch the
container to classic ssh.service before handing off to their
installer so it takes the safe "systemctl reload ssh" branch instead.
2026-08-05 22:04:16 +10:00
community-scripts-pr-app[bot] 27f66a8016 Update CHANGELOG.md (#16285)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 22:27:13 +00:00
CanbiZ (MickLesk) e3e29667c6 Actual Budget: allow native module install scripts under npm 11 (Node 24) (#16277) 2026-08-05 00:26:46 +02:00
community-scripts-pr-app[bot] 3921f03b73 Update CHANGELOG.md (#16284)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 22:26:30 +00:00
CanbiZ (MickLesk) 1336b44a26 Heimdall-Dashboard: run full composer install on update, force production env (#16278) 2026-08-05 00:26:12 +02:00
community-scripts-pr-app[bot] 419f9e397e Update CHANGELOG.md (#16283)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 22:25:59 +00:00
CanbiZ (MickLesk) fcbaedf7d8 xyOps: rebuild xySat satellite during update (#16279) 2026-08-05 00:25:29 +02:00
community-scripts-pr-app[bot] 4eb022fceb Update CHANGELOG.md (#16282)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 22:25:24 +00:00
CanbiZ (MickLesk) 6f4d3b4841 HAOS: remove non-ASCII dash from CPU model dialog text (#16276) 2026-08-05 00:24:56 +02:00
community-scripts-pr-app[bot] a4f893eb7c Update CHANGELOG.md (#16281)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 22:01:31 +00:00
Luke Gustafson 44589819d1 fix: back up Termix db/data so the update stops destroying encryption keys (#16275) 2026-08-05 00:01:02 +02:00
community-scripts-pr-app[bot] 33bfae30e0 Update CHANGELOG.md (#16274)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 21:03:00 +00:00
push-app-to-main[bot] 3fa516f94b Hister (#16259)
* Add hister (ct)

* Update source command in hister.sh

Replace local source with direct curl command for build.func.

* Update ct/hister.sh

* Update install/hister-install.sh

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
Co-authored-by: Sam Heinz <sam@samheinz.com>
2026-08-04 23:02:28 +02:00
community-scripts-pr-app[bot] 26abc114fd Update .app files (#16269)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2026-08-04 21:06:45 +02:00
community-scripts-pr-app[bot] 5202ffcea2 Update CHANGELOG.md (#16270)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 19:02:39 +00:00
CanbiZ (MickLesk) 86d67affa3 Refactor: harmonize tools/addon and move boilerplate into core.func (#16202) 2026-08-04 21:02:03 +02:00
community-scripts-pr-app[bot] e489c7f00b Update CHANGELOG.md (#16268)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 18:51:34 +00:00
community-scripts-pr-app[bot] 9df4cca7e8 Update CHANGELOG.md (#16267)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 18:51:11 +00:00
CanbiZ (MickLesk) f219707efd Bump NodeJS Versions of several scripts (#16230) 2026-08-04 20:51:02 +02:00
Copilot 77eece6f40 passwordpusher: dynamically read Ruby version from .ruby-version file (#16242)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-08-04 20:50:40 +02:00
community-scripts-pr-app[bot] 7b168d4986 Update CHANGELOG.md (#16266)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 18:50:12 +00:00
TowyTowy 64ae6241eb fix(salt): write version cache to ~/.salt, not /~.salt (#16265)
Co-authored-by: Claude <noreply@anthropic.com>
2026-08-04 20:49:50 +02:00
community-scripts-pr-app[bot] 3ef8dc8312 Update CHANGELOG.md (#16264)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 14:56:12 +00:00
community-scripts-pr-app[bot] 53df629af3 Update CHANGELOG.md (#16263)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 14:55:50 +00:00
community-scripts-pr-app[bot] 5271863a59 Update CHANGELOG.md (#16262)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 14:55:40 +00:00
push-app-to-main[bot] 468dba3f24 Obsidian-LiveSync (#16233)
* Add obsidian-livesync (ct)

* Update ct/obsidian-livesync.sh

Co-authored-by: Sam Heinz <sam@samheinz.com>

* Fix source line for build.func in obsidian-livesync.sh

Updated the source line to always fetch build.func from the specified URL.

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: CanbiZ (MickLesk) <47820557+MickLesk@users.noreply.github.com>
Co-authored-by: Sam Heinz <sam@samheinz.com>
2026-08-04 16:55:37 +02:00
community-scripts-pr-app[bot] 09e9918b8a Update CHANGELOG.md (#16261)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 14:55:18 +00:00
CanbiZ (MickLesk) 64cd328363 tools.func: never delete ubuntu.sources (or other distro base sources) as orphaned (#16250) 2026-08-04 16:55:08 +02:00
CanbiZ (MickLesk) 6d63e3e476 AFFiNE: fix version and build type reported by the app itself (#16251) 2026-08-04 16:54:46 +02:00
community-scripts-pr-app[bot] 3a846721ec Update CHANGELOG.md (#16260)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 14:54:35 +00:00
Chris ac866bf816 Opencloud: Pin version to 7.4.0 (#16257) 2026-08-04 16:54:31 +02:00
CanbiZ (MickLesk) 5d202e2a4a tools.func: complete a stale/partial backup manifest instead of trusting it as-is (#16252) 2026-08-04 16:54:05 +02:00
community-scripts-pr-app[bot] 888dfae126 Update CHANGELOG.md (#16253)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 10:14:20 +00:00
CanbiZ (MickLesk) 60e8ed77c4 Passbolt: fetch GPG key from Passbolt's own host instead of the flaky keyserver (#16248) 2026-08-04 12:13:49 +02:00
community-scripts-pr-app[bot] cf942fb445 Update CHANGELOG.md (#16245)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-03 21:24:22 +00:00
jsspen 0c24310e90 Correction to link displayed when old data structure is detected during an attempted update (#16241) 2026-08-03 23:23:59 +02:00
CanbiZ (MickLesk) 336cdda47d termix: add env backup 2026-08-03 22:56:27 +02:00
community-scripts-pr-app[bot] 268a6957a7 Update CHANGELOG.md (#16236)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-03 14:58:21 +00:00
CanbiZ (MickLesk) e21a11c190 misc: read all interactive prompts from /dev/tty, drain leftover input on read failure (#16235) 2026-08-03 16:57:55 +02:00
community-scripts-pr-app[bot] 9debedc386 Update CHANGELOG.md (#16231)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-03 09:27:00 +00:00
Johann Grobe 64448c0ded fix restore env in split pro (#16228)
* fix restore env in split pro

* use create_backup and restore_backup
2026-08-03 19:26:29 +10:00
128 changed files with 3386 additions and 1728 deletions
+139
View File
@@ -1,3 +1,142 @@
## 2026-08-08
### 🆕 New Scripts
- Ignis ([#16330](https://github.com/community-scripts/ProxmoxVE/pull/16330))
### 💾 Core
- #### ✨ New Features
- core - setup_nodejs: bypass npm allowScripts policy globally on npm >=11 [@MickLesk](https://github.com/MickLesk) ([#16280](https://github.com/community-scripts/ProxmoxVE/pull/16280))
## 2026-08-07
### 🆕 New Scripts
- NetworkOptimizer ([#16328](https://github.com/community-scripts/ProxmoxVE/pull/16328))
- Orb ([#16329](https://github.com/community-scripts/ProxmoxVE/pull/16329))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- HortusFox: start applying db migrations [@tomfrenzel](https://github.com/tomfrenzel) ([#16324](https://github.com/community-scripts/ProxmoxVE/pull/16324))
- Docker: report container updates instead of prompting, stop auto-updating Portainer Agent, fix addon detection of legacy Portainer [@MickLesk](https://github.com/MickLesk) ([#16298](https://github.com/community-scripts/ProxmoxVE/pull/16298))
- Immich: retry mise install on transient npm download failures [@MickLesk](https://github.com/MickLesk) ([#16301](https://github.com/community-scripts/ProxmoxVE/pull/16301))
- changedetection: remove msttcorefonts to fix install hang [@austinpilz](https://github.com/austinpilz) ([#16319](https://github.com/community-scripts/ProxmoxVE/pull/16319))
- #### 🔧 Refactor
- core: extend new vars and pocketbase values [@MickLesk](https://github.com/MickLesk) ([#16313](https://github.com/community-scripts/ProxmoxVE/pull/16313))
## 2026-08-06
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- paperless: change update abort message (endless spinner) [@MickLesk](https://github.com/MickLesk) ([#16299](https://github.com/community-scripts/ProxmoxVE/pull/16299))
- #### ✨ New Features
- Vikunja: remove version pin, v2.5.0 fixes the systemd syscall filter crash [@MickLesk](https://github.com/MickLesk) ([#16300](https://github.com/community-scripts/ProxmoxVE/pull/16300))
### 💾 Core
- #### 🔧 Refactor
- build.func: filter templates by host architecture during search [@MickLesk](https://github.com/MickLesk) ([#16302](https://github.com/community-scripts/ProxmoxVE/pull/16302))
## 2026-08-05
### 🚀 Updated Scripts
- #### ✨ New Features
- NextcloudPI: Bump to Debian Trixie & Tweak broken SSH [@MickLesk](https://github.com/MickLesk) ([#15957](https://github.com/community-scripts/ProxmoxVE/pull/15957))
### 🧰 Tools
- #### 🐞 Bug Fixes
- fix(monitor-all): reduce polling CPU overhead [@jomplox](https://github.com/jomplox) ([#15907](https://github.com/community-scripts/ProxmoxVE/pull/15907))
## 2026-08-04
### 🆕 New Scripts
- Hister ([#16259](https://github.com/community-scripts/ProxmoxVE/pull/16259))
- Obsidian-LiveSync ([#16233](https://github.com/community-scripts/ProxmoxVE/pull/16233))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Actual Budget: allow native module install scripts under npm 11 (Node24) [@MickLesk](https://github.com/MickLesk) ([#16277](https://github.com/community-scripts/ProxmoxVE/pull/16277))
- Heimdall-Dashboard: run full composer install on update, force production env [@MickLesk](https://github.com/MickLesk) ([#16278](https://github.com/community-scripts/ProxmoxVE/pull/16278))
- xyOps: rebuild xySat satellite during update [@MickLesk](https://github.com/MickLesk) ([#16279](https://github.com/community-scripts/ProxmoxVE/pull/16279))
- HAOS: remove non-ASCII dash from CPU model dialog text [@MickLesk](https://github.com/MickLesk) ([#16276](https://github.com/community-scripts/ProxmoxVE/pull/16276))
- fix: back up Termix db/data so the update stops destroying encryption keys [@LukeGus](https://github.com/LukeGus) ([#16275](https://github.com/community-scripts/ProxmoxVE/pull/16275))
- passwordpusher: dynamically read Ruby version from .ruby-version file [@Copilot](https://github.com/Copilot) ([#16242](https://github.com/community-scripts/ProxmoxVE/pull/16242))
- fix(salt): write version cache to ~/.salt, not /~.salt [@TowyTowy](https://github.com/TowyTowy) ([#16265](https://github.com/community-scripts/ProxmoxVE/pull/16265))
- AFFiNE: fix version and build type reported by the app itself [@MickLesk](https://github.com/MickLesk) ([#16251](https://github.com/community-scripts/ProxmoxVE/pull/16251))
- Passbolt: fetch GPG key from Passbolt's own host instead of the flaky keyserver [@MickLesk](https://github.com/MickLesk) ([#16248](https://github.com/community-scripts/ProxmoxVE/pull/16248))
- #### ✨ New Features
- Opencloud: Pin version to 7.4.0 [@vhsdream](https://github.com/vhsdream) ([#16257](https://github.com/community-scripts/ProxmoxVE/pull/16257))
- #### 🔧 Refactor
- Bump NodeJS Versions of several scripts [@MickLesk](https://github.com/MickLesk) ([#16230](https://github.com/community-scripts/ProxmoxVE/pull/16230))
### 💾 Core
- #### 🐞 Bug Fixes
- tools.func: never delete ubuntu.sources (or other distro base sources) as orphaned [@MickLesk](https://github.com/MickLesk) ([#16250](https://github.com/community-scripts/ProxmoxVE/pull/16250))
- tools.func: complete a stale/partial backup manifest instead of trusting it as-is [@MickLesk](https://github.com/MickLesk) ([#16252](https://github.com/community-scripts/ProxmoxVE/pull/16252))
- #### 🔧 Refactor
- Refactor: harmonize tools/addon and move boilerplate into core.func [@MickLesk](https://github.com/MickLesk) ([#16202](https://github.com/community-scripts/ProxmoxVE/pull/16202))
## 2026-08-03
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Correction to link in Paperless-NGX update script [@jsspen](https://github.com/jsspen) ([#16241](https://github.com/community-scripts/ProxmoxVE/pull/16241))
- fix restore env in split pro [@johanngrobe](https://github.com/johanngrobe) ([#16228](https://github.com/community-scripts/ProxmoxVE/pull/16228))
### 💾 Core
- #### 🔧 Refactor
- core: read all interactive prompts from /dev/tty, drain leftover input on read failure (hotfix) [@MickLesk](https://github.com/MickLesk) ([#16235](https://github.com/community-scripts/ProxmoxVE/pull/16235))
## 2026-08-02
### 🆕 New Scripts
- Portainer as Addon [@MickLesk](https://github.com/MickLesk) ([#16200](https://github.com/community-scripts/ProxmoxVE/pull/16200))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- LibreNMS: Ensure ipmitool dependency is installed [@tremor021](https://github.com/tremor021) ([#16219](https://github.com/community-scripts/ProxmoxVE/pull/16219))
- Bitfocus Companion: add libatomic1 dependency [@tremor021](https://github.com/tremor021) ([#16212](https://github.com/community-scripts/ProxmoxVE/pull/16212))
- fix(dispatcharr): add recordings and dvr queues to celery worker [@eXistC](https://github.com/eXistC) ([#16204](https://github.com/community-scripts/ProxmoxVE/pull/16204))
- add retry for uv - same as immich [@asylumexp](https://github.com/asylumexp) ([#16203](https://github.com/community-scripts/ProxmoxVE/pull/16203))
- Fix for cross-seed node version regression [@TorinFrancis](https://github.com/TorinFrancis) ([#16209](https://github.com/community-scripts/ProxmoxVE/pull/16209))
- #### 🔧 Refactor
- chore: remove portainer setup from several scripts (moved to addon) [@MickLesk](https://github.com/MickLesk) ([#16201](https://github.com/community-scripts/ProxmoxVE/pull/16201))
## 2026-08-01 ## 2026-08-01
### 🚀 Updated Scripts ### 🚀 Updated Scripts
+2
View File
@@ -6,6 +6,8 @@ on:
- main - main
paths: paths:
- "ct/**.sh" - "ct/**.sh"
- "tools/**.sh"
- "vm/**.sh"
workflow_dispatch: workflow_dispatch:
jobs: jobs:
+18 -2
View File
@@ -314,12 +314,17 @@ jobs:
// ── Allow-lists (mirror the slash bot) ───────────────────────────── // ── Allow-lists (mirror the slash bot) ─────────────────────────────
const ALLOWED_FIELDS = { const ALLOWED_FIELDS = {
name: 'string', description: 'string', logo: 'string', documentation: 'string', name: 'string', description: 'string', logo: 'string', documentation: 'string',
website: 'string', project_url: 'string', github: 'string', config_path: 'string', website: 'string', project_url: 'string', repository: 'string', config_path: 'string',
tags: 'string', port: 'number', default_user: 'nullable_string', default_passwd: 'nullable_string', tags: 'string', port: 'number', default_user: 'nullable_string', default_passwd: 'nullable_string',
unprivileged: 'number', updateable: 'boolean', privileged: 'boolean', has_arm: 'boolean', unprivileged: 'number', updateable: 'boolean', privileged: 'boolean',
architectures: 'select_list', platforms: 'select_list',
is_dev: 'boolean', is_disabled: 'boolean', disable_message: 'string', is_dev: 'boolean', is_disabled: 'boolean', disable_message: 'string',
is_deleted: 'boolean', deleted_message: 'string' is_deleted: 'boolean', deleted_message: 'string'
}; };
const SELECT_VALUES = {
architectures: ['amd64', 'arm64'],
platforms: ['pve', 'incus'],
};
const FIELD_TO_CT_VAR = { tags: 'var_tags', unprivileged: 'var_unprivileged' }; const FIELD_TO_CT_VAR = { tags: 'var_tags', unprivileged: 'var_unprivileged' };
const RESOURCE_KEYS = { cpu: 'number', ram: 'number', hdd: 'number', os: 'string', version: 'string' }; const RESOURCE_KEYS = { cpu: 'number', ram: 'number', hdd: 'number', os: 'string', version: 'string' };
const METHOD_KEYS = { config_path: 'string', script: 'string' }; const METHOD_KEYS = { config_path: 'string', script: 'string' };
@@ -339,6 +344,17 @@ jobs:
if (isNaN(n)) return { error: '`' + key + '` must be a number' }; if (isNaN(n)) return { error: '`' + key + '` must be a number' };
return { value: n }; return { value: n };
} }
if (type === 'select_list') {
// architectures/platforms are multi-selects over a closed set,
// so an unknown value is rejected rather than stored. The model
// may hand back an array or a comma-separated string.
const allowed = SELECT_VALUES[key] || [];
const raw = Array.isArray(rawVal) ? rawVal : String(rawVal == null ? '' : rawVal).split(',');
const values = raw.map(function (v) { return String(v).trim(); }).filter(Boolean);
const bad = values.filter(function (v) { return allowed.indexOf(v) === -1; });
if (bad.length > 0) return { error: '`' + key + '` accepts ' + allowed.join(', ') + ' — got: ' + bad.join(', ') };
return { value: values };
}
if (type === 'nullable_string') return { value: rawVal === '' || rawVal == null ? null : String(rawVal) }; if (type === 'nullable_string') return { value: rawVal === '' || rawVal == null ? null : String(rawVal) };
return { value: String(rawVal) }; return { value: String(rawVal) };
} }
+25 -6
View File
@@ -323,9 +323,10 @@ jobs:
'/pocketbase <slug> method remove <type>\n' + '/pocketbase <slug> method remove <type>\n' +
'```\n' + '```\n' +
'Method fields: `cpu` `ram` `hdd` `os` `version` `config_path` `script`\n\n' + 'Method fields: `cpu` `ram` `hdd` `os` `version` `config_path` `script`\n\n' +
'**Editable fields:** `name` `description` `logo` `documentation` `website` `project_url` `github` ' + '**Editable fields:** `name` `description` `logo` `documentation` `website` `project_url` `repository` ' +
'`config_path` `port` `default_user` `default_passwd` ' + '`config_path` `port` `default_user` `default_passwd` ' +
'`updateable` `privileged` `has_arm` `is_dev` ' + '`updateable` `privileged` `is_dev` ' +
'`architectures` (amd64,arm64) `platforms` (pve,incus) ' +
'`is_disabled` `disable_message` `is_deleted` `deleted_message`'; '`is_disabled` `disable_message` `is_deleted` `deleted_message`';
if (!withoutCmd) { if (!withoutCmd) {
@@ -504,7 +505,8 @@ jobs:
out.push('- **Port:** ' + (record.port != null ? '`' + record.port + '`' : '—')); out.push('- **Port:** ' + (record.port != null ? '`' + record.port + '`' : '—'));
out.push('- **Updateable:** ' + (record.updateable ? 'Yes' : 'No')); out.push('- **Updateable:** ' + (record.updateable ? 'Yes' : 'No'));
out.push('- **Privileged:** ' + (record.privileged ? 'Yes' : 'No')); out.push('- **Privileged:** ' + (record.privileged ? 'Yes' : 'No'));
out.push('- **ARM:** ' + (record.has_arm ? 'Yes' : 'No')); out.push('- **Architectures:** ' + ((record.architectures || []).join(', ') || 'amd64'));
out.push('- **Platforms:** ' + ((record.platforms || []).join(', ') || 'pve'));
if (record.is_dev) out.push('- **Dev:** Yes'); if (record.is_dev) out.push('- **Dev:** Yes');
if (record.is_disabled) out.push('- **Disabled:** Yes' + (record.disable_message ? ' — ' + record.disable_message : '')); if (record.is_disabled) out.push('- **Disabled:** Yes' + (record.disable_message ? ' — ' + record.disable_message : ''));
if (record.is_deleted) out.push('- **Deleted:** Yes' + (record.deleted_message ? ' — ' + record.deleted_message : '')); if (record.is_deleted) out.push('- **Deleted:** Yes' + (record.deleted_message ? ' — ' + record.deleted_message : ''));
@@ -838,7 +840,7 @@ jobs:
const fieldName = setMatch[1].toLowerCase(); const fieldName = setMatch[1].toLowerCase();
const SET_ALLOWED = { const SET_ALLOWED = {
name: 'string', description: 'string', logo: 'string', name: 'string', description: 'string', logo: 'string',
documentation: 'string', website: 'string', project_url: 'string', github: 'string', documentation: 'string', website: 'string', project_url: 'string', repository: 'string',
config_path: 'string', disable_message: 'string', deleted_message: 'string' config_path: 'string', disable_message: 'string', deleted_message: 'string'
}; };
if (!SET_ALLOWED[fieldName]) { if (!SET_ALLOWED[fieldName]) {
@@ -888,7 +890,7 @@ jobs:
documentation: 'string', documentation: 'string',
website: 'string', website: 'string',
project_url: 'string', project_url: 'string',
github: 'string', repository: 'string',
config_path: 'string', config_path: 'string',
tags: 'string', tags: 'string',
port: 'number', port: 'number',
@@ -897,7 +899,8 @@ jobs:
unprivileged: 'number', unprivileged: 'number',
updateable: 'boolean', updateable: 'boolean',
privileged: 'boolean', privileged: 'boolean',
has_arm: 'boolean', architectures: 'select_list',
platforms: 'select_list',
is_dev: 'boolean', is_dev: 'boolean',
is_disabled: 'boolean', is_disabled: 'boolean',
disable_message: 'string', disable_message: 'string',
@@ -924,6 +927,10 @@ jobs:
} }
// Cast values to correct types // Cast values to correct types
const SELECT_VALUES = {
architectures: ['amd64', 'arm64'],
platforms: ['pve', 'incus'],
};
const payload = {}; const payload = {};
for (const [key, rawVal] of Object.entries(parsedFields)) { for (const [key, rawVal] of Object.entries(parsedFields)) {
const type = ALLOWED_FIELDS[key]; const type = ALLOWED_FIELDS[key];
@@ -943,6 +950,18 @@ jobs:
process.exit(0); process.exit(0);
} }
payload[key] = n; payload[key] = n;
} else if (type === 'select_list') {
// architectures/platforms are multi-selects over a closed set,
// so an unknown value is rejected rather than stored.
const allowed = SELECT_VALUES[key] || [];
const values = rawVal.split(',').map(function (v) { return v.trim(); }).filter(Boolean);
const bad = values.filter(function (v) { return allowed.indexOf(v) === -1; });
if (bad.length > 0) {
await addReaction('-1');
await postComment('❌ **PocketBase Bot**: `' + key + '` accepts ' + allowed.join(', ') + ' — got: `' + bad.join(', ') + '`');
process.exit(0);
}
payload[key] = values;
} else if (type === 'nullable_string') { } else if (type === 'nullable_string') {
payload[key] = rawVal === '' ? null : rawVal; payload[key] = rawVal === '' ? null : rawVal;
} else { } else {
+13 -1
View File
@@ -179,7 +179,19 @@ jobs:
if (resolvedType) payload.type = resolvedType; if (resolvedType) payload.type = resolvedType;
var resolvedCats = (data.categories || []).map(function(n) { return categoryNameToPbId[categoryIdToName[n]]; }).filter(Boolean); var resolvedCats = (data.categories || []).map(function(n) { return categoryNameToPbId[categoryIdToName[n]]; }).filter(Boolean);
if (resolvedCats.length) payload.categories = resolvedCats; if (resolvedCats.length) payload.categories = resolvedCats;
if (data.has_arm !== undefined) payload.has_arm = data.has_arm === true || data.has_arm === 'true'; // architectures replaces has_arm: a boolean could say "also ARM" but
// not "ARM only" or "amd64 only". A record written before the field
// existed is read through the old key so nothing silently drops.
if (Array.isArray(data.architectures)) {
payload.architectures = data.architectures.filter(function (a) { return a === 'amd64' || a === 'arm64'; });
} else if (data.has_arm !== undefined) {
payload.architectures = (data.has_arm === true || data.has_arm === 'true') ? ['amd64', 'arm64'] : ['amd64'];
}
if (Array.isArray(data.platforms)) {
payload.platforms = data.platforms.filter(function (p) { return p === 'pve' || p === 'incus'; });
}
if (Array.isArray(data.app_vars)) payload.app_vars = data.app_vars;
if (data.repository !== undefined) payload.repository = data.repository;
if (data.version !== undefined) payload.version = data.version; if (data.version !== undefined) payload.version = data.version;
if (data.changelog !== undefined) payload.changelog = data.changelog; if (data.changelog !== undefined) payload.changelog = data.changelog;
if (data.screenshots !== undefined) payload.screenshots = data.screenshots; if (data.screenshots !== undefined) payload.screenshots = data.screenshots;
+3 -1
View File
@@ -24,7 +24,9 @@ generate_headers() {
app_name=$(grep -oP '^APP="\K[^"]+' "$script" 2>/dev/null) app_name=$(grep -oP '^APP="\K[^"]+' "$script" 2>/dev/null)
if [[ -n "$app_name" ]]; then if [[ -n "$app_name" ]]; then
output_file="${headers_dir}/$(basename "${script%.*}")" # core.func/vm-core.func look the header up as "${APP,,}" without spaces,
# so the generated file has to be named after APP - not after the script.
output_file="${headers_dir}/$(echo "${app_name,,}" | tr -d ' ')"
figlet_output=$(figlet -w 500 -f slant "$app_name") figlet_output=$(figlet -w 500 -f slant "$app_name")
if [[ -n "$figlet_output" ]]; then if [[ -n "$figlet_output" ]]; then
echo "$figlet_output" >"$output_file" echo "$figlet_output" >"$output_file"
+153 -92
View File
@@ -86,6 +86,9 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
@@ -99,7 +102,7 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
<details> <details>
<summary><h4>August (1 entries)</h4></summary> <summary><h4>August (8 entries)</h4></summary>
[View August 2026 Changelog](.github/changelogs/2026/08.md) [View August 2026 Changelog](.github/changelogs/2026/08.md)
@@ -518,6 +521,154 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
</details> </details>
## 2026-08-10
### 🧰 Tools
- post-pdm-install ([#16368](https://github.com/community-scripts/ProxmoxVE/pull/16368))
## 2026-08-09
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Fix: CouchDB Erlang cookie breaks vm.args (use hex) [@fudianchn](https://github.com/fudianchn) ([#16361](https://github.com/community-scripts/ProxmoxVE/pull/16361))
- SparkyFitness: Install Git for frontend builds [@MickLesk](https://github.com/MickLesk) ([#16352](https://github.com/community-scripts/ProxmoxVE/pull/16352))
- Byparr: Use invisible-playwright browser setup [@MickLesk](https://github.com/MickLesk) ([#16353](https://github.com/community-scripts/ProxmoxVE/pull/16353))
- Crafty Controller: Restore ownership after updates [@MickLesk](https://github.com/MickLesk) ([#16354](https://github.com/community-scripts/ProxmoxVE/pull/16354))
- Webtrees: Fix schema check in silent mode [@MickLesk](https://github.com/MickLesk) ([#16355](https://github.com/community-scripts/ProxmoxVE/pull/16355))
- SigNoz: Allow legacy metadata schema on ClickHouse 26 [@MickLesk](https://github.com/MickLesk) ([#16356](https://github.com/community-scripts/ProxmoxVE/pull/16356))
### 🧰 Tools
- #### ✨ New Features
- Portainer: Update existing CE and BE installations [@MickLesk](https://github.com/MickLesk) ([#16357](https://github.com/community-scripts/ProxmoxVE/pull/16357))
### 📚 Documentation
- github: update Star History links and image sources [@MickLesk](https://github.com/MickLesk) ([#16367](https://github.com/community-scripts/ProxmoxVE/pull/16367))
## 2026-08-08
### 🆕 New Scripts
- Ignis ([#16330](https://github.com/community-scripts/ProxmoxVE/pull/16330))
### 💾 Core
- #### ✨ New Features
- core - setup_nodejs: bypass npm allowScripts policy globally on npm >=11 [@MickLesk](https://github.com/MickLesk) ([#16280](https://github.com/community-scripts/ProxmoxVE/pull/16280))
## 2026-08-07
### 🆕 New Scripts
- NetworkOptimizer ([#16328](https://github.com/community-scripts/ProxmoxVE/pull/16328))
- Orb ([#16329](https://github.com/community-scripts/ProxmoxVE/pull/16329))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- HortusFox: start applying db migrations [@tomfrenzel](https://github.com/tomfrenzel) ([#16324](https://github.com/community-scripts/ProxmoxVE/pull/16324))
- Docker: report container updates instead of prompting, stop auto-updating Portainer Agent, fix addon detection of legacy Portainer [@MickLesk](https://github.com/MickLesk) ([#16298](https://github.com/community-scripts/ProxmoxVE/pull/16298))
- Immich: retry mise install on transient npm download failures [@MickLesk](https://github.com/MickLesk) ([#16301](https://github.com/community-scripts/ProxmoxVE/pull/16301))
- changedetection: remove msttcorefonts to fix install hang [@austinpilz](https://github.com/austinpilz) ([#16319](https://github.com/community-scripts/ProxmoxVE/pull/16319))
- #### 🔧 Refactor
- core: extend new vars and pocketbase values [@MickLesk](https://github.com/MickLesk) ([#16313](https://github.com/community-scripts/ProxmoxVE/pull/16313))
## 2026-08-06
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- paperless: change update abort message (endless spinner) [@MickLesk](https://github.com/MickLesk) ([#16299](https://github.com/community-scripts/ProxmoxVE/pull/16299))
- #### ✨ New Features
- Vikunja: remove version pin, v2.5.0 fixes the systemd syscall filter crash [@MickLesk](https://github.com/MickLesk) ([#16300](https://github.com/community-scripts/ProxmoxVE/pull/16300))
### 💾 Core
- #### 🔧 Refactor
- build.func: filter templates by host architecture during search [@MickLesk](https://github.com/MickLesk) ([#16302](https://github.com/community-scripts/ProxmoxVE/pull/16302))
## 2026-08-05
### 🚀 Updated Scripts
- #### ✨ New Features
- NextcloudPI: Bump to Debian Trixie & Tweak broken SSH [@MickLesk](https://github.com/MickLesk) ([#15957](https://github.com/community-scripts/ProxmoxVE/pull/15957))
### 🧰 Tools
- #### 🐞 Bug Fixes
- fix(monitor-all): reduce polling CPU overhead [@jomplox](https://github.com/jomplox) ([#15907](https://github.com/community-scripts/ProxmoxVE/pull/15907))
## 2026-08-04
### 🆕 New Scripts
- Hister ([#16259](https://github.com/community-scripts/ProxmoxVE/pull/16259))
- Obsidian-LiveSync ([#16233](https://github.com/community-scripts/ProxmoxVE/pull/16233))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Actual Budget: allow native module install scripts under npm 11 (Node24) [@MickLesk](https://github.com/MickLesk) ([#16277](https://github.com/community-scripts/ProxmoxVE/pull/16277))
- Heimdall-Dashboard: run full composer install on update, force production env [@MickLesk](https://github.com/MickLesk) ([#16278](https://github.com/community-scripts/ProxmoxVE/pull/16278))
- xyOps: rebuild xySat satellite during update [@MickLesk](https://github.com/MickLesk) ([#16279](https://github.com/community-scripts/ProxmoxVE/pull/16279))
- HAOS: remove non-ASCII dash from CPU model dialog text [@MickLesk](https://github.com/MickLesk) ([#16276](https://github.com/community-scripts/ProxmoxVE/pull/16276))
- fix: back up Termix db/data so the update stops destroying encryption keys [@LukeGus](https://github.com/LukeGus) ([#16275](https://github.com/community-scripts/ProxmoxVE/pull/16275))
- passwordpusher: dynamically read Ruby version from .ruby-version file [@Copilot](https://github.com/Copilot) ([#16242](https://github.com/community-scripts/ProxmoxVE/pull/16242))
- fix(salt): write version cache to ~/.salt, not /~.salt [@TowyTowy](https://github.com/TowyTowy) ([#16265](https://github.com/community-scripts/ProxmoxVE/pull/16265))
- AFFiNE: fix version and build type reported by the app itself [@MickLesk](https://github.com/MickLesk) ([#16251](https://github.com/community-scripts/ProxmoxVE/pull/16251))
- Passbolt: fetch GPG key from Passbolt's own host instead of the flaky keyserver [@MickLesk](https://github.com/MickLesk) ([#16248](https://github.com/community-scripts/ProxmoxVE/pull/16248))
- #### ✨ New Features
- Opencloud: Pin version to 7.4.0 [@vhsdream](https://github.com/vhsdream) ([#16257](https://github.com/community-scripts/ProxmoxVE/pull/16257))
- #### 🔧 Refactor
- Bump NodeJS Versions of several scripts [@MickLesk](https://github.com/MickLesk) ([#16230](https://github.com/community-scripts/ProxmoxVE/pull/16230))
### 💾 Core
- #### 🐞 Bug Fixes
- tools.func: never delete ubuntu.sources (or other distro base sources) as orphaned [@MickLesk](https://github.com/MickLesk) ([#16250](https://github.com/community-scripts/ProxmoxVE/pull/16250))
- tools.func: complete a stale/partial backup manifest instead of trusting it as-is [@MickLesk](https://github.com/MickLesk) ([#16252](https://github.com/community-scripts/ProxmoxVE/pull/16252))
- #### 🔧 Refactor
- Refactor: harmonize tools/addon and move boilerplate into core.func [@MickLesk](https://github.com/MickLesk) ([#16202](https://github.com/community-scripts/ProxmoxVE/pull/16202))
## 2026-08-03
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Correction to link in Paperless-NGX update script [@jsspen](https://github.com/jsspen) ([#16241](https://github.com/community-scripts/ProxmoxVE/pull/16241))
- fix restore env in split pro [@johanngrobe](https://github.com/johanngrobe) ([#16228](https://github.com/community-scripts/ProxmoxVE/pull/16228))
### 💾 Core
- #### 🔧 Refactor
- core: read all interactive prompts from /dev/tty, drain leftover input on read failure (hotfix) [@MickLesk](https://github.com/MickLesk) ([#16235](https://github.com/community-scripts/ProxmoxVE/pull/16235))
## 2026-08-02 ## 2026-08-02
### 🆕 New Scripts ### 🆕 New Scripts
@@ -1047,94 +1198,4 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- Adapt to new artifact filename format for pocket id [@wollew](https://github.com/wollew) ([#15689](https://github.com/community-scripts/ProxmoxVE/pull/15689)) - Adapt to new artifact filename format for pocket id [@wollew](https://github.com/wollew) ([#15689](https://github.com/community-scripts/ProxmoxVE/pull/15689))
- Fireshare: Fix for install and upgrade to v1.7.3 [@tremor021](https://github.com/tremor021) ([#15673](https://github.com/community-scripts/ProxmoxVE/pull/15673)) - Fireshare: Fix for install and upgrade to v1.7.3 [@tremor021](https://github.com/tremor021) ([#15673](https://github.com/community-scripts/ProxmoxVE/pull/15673))
- Endurain: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15674](https://github.com/community-scripts/ProxmoxVE/pull/15674)) - Endurain: Fix update procedure [@tremor021](https://github.com/tremor021) ([#15674](https://github.com/community-scripts/ProxmoxVE/pull/15674))
## 2026-07-09
### 🚀 Updated Scripts
- fix(pihole): repair Unbound DNS-over-TLS (DoT) forwarding config [@TowyTowy](https://github.com/TowyTowy) ([#15654](https://github.com/community-scripts/ProxmoxVE/pull/15654))
## 2026-07-08
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Opencloud: Bump version to 7.2.1 [@vhsdream](https://github.com/vhsdream) ([#15655](https://github.com/community-scripts/ProxmoxVE/pull/15655))
- BabyBuddy: Harden update script [@MickLesk](https://github.com/MickLesk) ([#15642](https://github.com/community-scripts/ProxmoxVE/pull/15642))
## 2026-07-07
### 🆕 New Scripts
- Forgejo-Runner ([#15046](https://github.com/community-scripts/ProxmoxVE/pull/15046))
## 2026-07-06
### 🚀 Updated Scripts
- Fix alignment in various ct end messages [@tremor021](https://github.com/tremor021) ([#15632](https://github.com/community-scripts/ProxmoxVE/pull/15632))
- Immich: Update libvips to 8.18.4 [@vhsdream](https://github.com/vhsdream) ([#15619](https://github.com/community-scripts/ProxmoxVE/pull/15619))
- #### 🐞 Bug Fixes
- Wizarr: Build JS and CSS static assets [@vhsdream](https://github.com/vhsdream) ([#15634](https://github.com/community-scripts/ProxmoxVE/pull/15634))
- RustDesk Server: Update URL format in rustdeskserver.sh [@tremor021](https://github.com/tremor021) ([#15626](https://github.com/community-scripts/ProxmoxVE/pull/15626))
- attempt to port docker-vm to support arm64 [@asylumexp](https://github.com/asylumexp) ([#15611](https://github.com/community-scripts/ProxmoxVE/pull/15611))
- fix(plane): don't clobber global app var, breaking /usr/bin/update [@asylumexp](https://github.com/asylumexp) ([#15612](https://github.com/community-scripts/ProxmoxVE/pull/15612))
- #### 🔧 Refactor
- cliproxyapi: point setup message at /management.html [@austinpilz](https://github.com/austinpilz) ([#15628](https://github.com/community-scripts/ProxmoxVE/pull/15628))
### 🗑️ Deleted Scripts
- Remove: FlowiseAI [@MickLesk](https://github.com/MickLesk) ([#15624](https://github.com/community-scripts/ProxmoxVE/pull/15624))
## 2026-07-05
### 🆕 New Scripts
- excalidash ([#15604](https://github.com/community-scripts/ProxmoxVE/pull/15604))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- fix: homarr: cli [@CrazyWolf13](https://github.com/CrazyWolf13) ([#15603](https://github.com/community-scripts/ProxmoxVE/pull/15603))
- immich: vacuum smart_search/face_search before VectorChord bump [@irishpadres](https://github.com/irishpadres) ([#15607](https://github.com/community-scripts/ProxmoxVE/pull/15607))
## 2026-07-04
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Element Synapse: Fix heredoc syntax in elementsynapse-install.sh [@tremor021](https://github.com/tremor021) ([#15594](https://github.com/community-scripts/ProxmoxVE/pull/15594))
- Twenty: Fix backup restore [@tremor021](https://github.com/tremor021) ([#15586](https://github.com/community-scripts/ProxmoxVE/pull/15586))
- fix(endurain): update frontend dist path after upstream restructure [@joaovitoriasilva](https://github.com/joaovitoriasilva) ([#15590](https://github.com/community-scripts/ProxmoxVE/pull/15590))
## 2026-07-03
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Immich: handle mise monorepo_root rename correctly | bump to 3.0.1 [@MickLesk](https://github.com/MickLesk) ([#15557](https://github.com/community-scripts/ProxmoxVE/pull/15557))
- #### ✨ New Features
- Opencloud: bump to v7.2.0 [@vhsdream](https://github.com/vhsdream) ([#15575](https://github.com/community-scripts/ProxmoxVE/pull/15575))
### 💾 Core
- #### 🔧 Refactor
- tools.func: fix corepack/pnpm install flow in setup_nodejs [@MickLesk](https://github.com/MickLesk) ([#15579](https://github.com/community-scripts/ProxmoxVE/pull/15579))
### 🧰 Tools
- #### 🐞 Bug Fixes
- Removed deprecated parameter in Filebrowser Quantum configuration [@alpargatagazer](https://github.com/alpargatagazer) ([#15573](https://github.com/community-scripts/ProxmoxVE/pull/15573))
+49
View File
@@ -103,6 +103,55 @@ Key rules at a glance:
- Quote all variables: `"$VAR"` not `$VAR` - Quote all variables: `"$VAR"` not `$VAR`
- Use lowercase variable names - Use lowercase variable names
- Do not hardcode credentials or sensitive values - Do not hardcode credentials or sensitive values
- Never prompt without an escape hatch — see below
### Answering a prompt up front
An install script that only asks cannot be deployed unattended. Read the
variable first and prompt only when it is unset:
```bash
if [[ -z "${var_admin_user:-}" ]]; then
read -r -p "${TAB3}Admin username: " var_admin_user
fi
var_admin_user="${var_admin_user:-admin}"
```
Name them `var_<something>`, the same namespace the container variables use.
`install/forgejo-runner-install.sh`, `install/pangolin-install.sh`, and `install/docker-install.sh` all
follow this.
The variable also has to be exported from `ct/<app>.sh`, or it never reaches
the container — `lxc-attach` carries the caller's environment, but only for
what was actually exported:
```bash
export var_admin_user="${var_admin_user:-}"
```
Declare them on the script's PocketBase record in `app_vars` so the website's
generator can offer them as fields:
```json
"app_vars": [
{
"name": "var_admin_user",
"label": "Admin Username",
"type": "text",
"default": "admin"
},
{
"name": "var_admin_pass",
"label": "Admin Password",
"type": "password",
"secret": true
}
]
```
`type` is one of `text`, `password`, `number`, `boolean` (`yes`/`no`) or
`select` (with `options`). Mark anything credential-like `secret` — the
generator keeps those out of shareable links and out of the on-screen summary.
Full standards and examples: **[community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution)** Full standards and examples: **[community-scripts.org/docs/contribution](https://community-scripts.org/docs/contribution)**
+14 -4
View File
@@ -171,11 +171,21 @@ This project runs on community contributions. Whether you want to write new scri
</p> </p>
<p align="center"> <p align="center">
<a href="https://star-history.com/#community-scripts/ProxmoxVE&Date"> <a href="https://www.star-history.com/?repos=community-scripts%2FProxmoxVE&type=date&legend=top-left">
<picture> <picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date&theme=dark" /> <source
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" /> media="(prefers-color-scheme: dark)"
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=community-scripts/ProxmoxVE&type=Date" width="700" /> srcset="https://api.star-history.com/chart?repos=community-scripts/ProxmoxVE&type=date&theme=dark&legend=top-left&sealed_token=-lUy2KH6pJryUyLCbiWRwFz3ilXMDFVFHm0lJcqh-Hl5e0QNNKjINNcXzULhaZVpBugN_TDaxOawEAuzwBc5Sjqa2mCRw9K6TdCioKRDsS_qXUwhkLQSCMRSg1schCdl4rQD8qEj7PWBjin-fyHnDm7NnM6akZp59jndG7qV7PrvG8nLBgDIuuA-wAI3"
/>
<source
media="(prefers-color-scheme: light)"
srcset="https://api.star-history.com/chart?repos=community-scripts/ProxmoxVE&type=date&legend=top-left&sealed_token=-lUy2KH6pJryUyLCbiWRwFz3ilXMDFVFHm0lJcqh-Hl5e0QNNKjINNcXzULhaZVpBugN_TDaxOawEAuzwBc5Sjqa2mCRw9K6TdCioKRDsS_qXUwhkLQSCMRSg1schCdl4rQD8qEj7PWBjin-fyHnDm7NnM6akZp59jndG7qV7PrvG8nLBgDIuuA-wAI3"
/>
<img
alt="Star History Chart"
src="https://api.star-history.com/chart?repos=community-scripts/ProxmoxVE&type=date&legend=top-left&sealed_token=-lUy2KH6pJryUyLCbiWRwFz3ilXMDFVFHm0lJcqh-Hl5e0QNNKjINNcXzULhaZVpBugN_TDaxOawEAuzwBc5Sjqa2mCRw9K6TdCioKRDsS_qXUwhkLQSCMRSg1schCdl4rQD8qEj7PWBjin-fyHnDm7NnM6akZp59jndG7qV7PrvG8nLBgDIuuA-wAI3"
width="700"
/>
</picture> </picture>
</a> </a>
</p> </p>
+3 -1
View File
@@ -30,7 +30,7 @@ function update_script() {
exit exit
fi fi
NODE_VERSION="22" setup_nodejs NODE_VERSION="24" setup_nodejs
RELEASE=$(get_latest_github_release "actualbudget/actual") RELEASE=$(get_latest_github_release "actualbudget/actual")
if [[ -f /opt/actualbudget-data/config.json ]]; then if [[ -f /opt/actualbudget-data/config.json ]]; then
if check_for_gh_release "actualbudget" "actualbudget/actual"; then if check_for_gh_release "actualbudget" "actualbudget/actual"; then
@@ -39,7 +39,9 @@ function update_script() {
msg_ok "Stopped Service" msg_ok "Stopped Service"
msg_info "Updating Actual Budget to ${RELEASE}" msg_info "Updating Actual Budget to ${RELEASE}"
$STD npm config set allow-scripts=bcrypt,better-sqlite3,argon2 --location=global
$STD npm update -g @actual-app/sync-server $STD npm update -g @actual-app/sync-server
$STD npm rebuild -g
echo "${RELEASE}" >~/.actualbudget echo "${RELEASE}" >~/.actualbudget
msg_ok "Updated Actual Budget to ${RELEASE}" msg_ok "Updated Actual Budget to ${RELEASE}"
+2
View File
@@ -81,6 +81,8 @@ TURBO
export NODE_OPTIONS="--max-old-space-size=2048" export NODE_OPTIONS="--max-old-space-size=2048"
$STD yarn install $STD yarn install
$STD bash ./scripts/set-version.sh "$(cat ~/.affine_app)"
export BUILD_TYPE=stable
$STD npm install -g typescript $STD npm install -g typescript
$STD yarn affine @affine/native build $STD yarn affine @affine/native build
+1 -1
View File
@@ -81,7 +81,7 @@ function update_script() {
msg_info "Configuring Byparr" msg_info "Configuring Byparr"
cd /opt/Byparr cd /opt/Byparr
$STD uv sync --link-mode copy $STD uv sync --link-mode copy
$STD uv run camoufox fetch $STD uv run python -m invisible_playwright fetch
msg_ok "Configured Byparr" msg_ok "Configured Byparr"
msg_info "Starting Service" msg_info "Starting Service"
+1 -1
View File
@@ -44,6 +44,7 @@ function update_script() {
CLEAN_INSTALL=1 fetch_and_deploy_gl_release "Crafty-Controller" "crafty-controller/crafty-4" "tarball" "latest" "/opt/crafty-controller/crafty/crafty-4" CLEAN_INSTALL=1 fetch_and_deploy_gl_release "Crafty-Controller" "crafty-controller/crafty-4" "tarball" "latest" "/opt/crafty-controller/crafty/crafty-4"
chown -R crafty:crafty /opt/crafty-controller
restore_backup restore_backup
msg_info "Updating TemurinJDK" msg_info "Updating TemurinJDK"
@@ -53,7 +54,6 @@ function update_script() {
msg_ok "Updated TemurinJDK" msg_ok "Updated TemurinJDK"
msg_info "Updating Python dependencies" msg_info "Updating Python dependencies"
chown -R crafty:crafty /opt/crafty-controller
cd /opt/crafty-controller/crafty/crafty-4 cd /opt/crafty-controller/crafty/crafty-4
$STD sudo -u crafty bash -c ' $STD sudo -u crafty bash -c '
source /opt/crafty-controller/crafty/.venv/bin/activate source /opt/crafty-controller/crafty/.venv/bin/activate
-14
View File
@@ -42,20 +42,6 @@ function update_script() {
echo -e "${TAB}${TAB}${GN}bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/portainer.sh)\"${CL}" echo -e "${TAB}${TAB}${GN}bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/portainer.sh)\"${CL}"
fi fi
if docker ps -a --format '{{.Names}}' | grep -q '^portainer_agent$'; then
msg_info "Updating Portainer Agent"
$STD docker pull portainer/agent:latest
$STD docker stop portainer_agent
$STD docker rm portainer_agent
$STD docker run -d \
-p 9001:9001 \
--name=portainer_agent \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
portainer/agent
msg_ok "Updated Portainer Agent"
fi
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
exit exit
} }
+5
View File
@@ -18,6 +18,7 @@ var_nesting="${var_nesting:-1}"
var_keyctl="${var_keyctl:-1}" var_keyctl="${var_keyctl:-1}"
export var_forgejo_instance="${var_forgejo_instance:-}" export var_forgejo_instance="${var_forgejo_instance:-}"
export var_forgejo_runner_uuid="${var_forgejo_runner_uuid:-}"
export var_forgejo_runner_token="${var_forgejo_runner_token:-}" export var_forgejo_runner_token="${var_forgejo_runner_token:-}"
export var_runner_labels="${var_runner_labels:-}" export var_runner_labels="${var_runner_labels:-}"
@@ -64,6 +65,10 @@ if [[ -n "${mode:-}" ]]; then
msg_error "var_forgejo_instance is required for unattended installs." msg_error "var_forgejo_instance is required for unattended installs."
exit 1 exit 1
fi fi
if [[ -z "${var_forgejo_runner_uuid:-}" ]]; then
msg_error "var_forgejo_runner_uuid is required for unattended installs."
exit 1
fi
if [[ -z "${var_forgejo_runner_token:-}" ]]; then if [[ -z "${var_forgejo_runner_token:-}" ]]; then
msg_error "var_forgejo_runner_token is required for unattended installs." msg_error "var_forgejo_runner_token is required for unattended installs."
exit 1 exit 1
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://about.gitlab.com/
APP="GitLab"
var_tags="${var_tags:-git;devtools}"
var_cpu="${var_cpu:-4}"
var_ram="${var_ram:-8192}"
var_disk="${var_disk:-40}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
#var_arm64="${var_arm64:-no}" # unset = ask the user; set yes/no only when verified
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/gitlab ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating GitLab (Patience)"
$STD apt update
$STD apt install -y gitlab-ce
msg_ok "Updated GitLab"
msg_info "Reconfiguring GitLab (Patience)"
$STD gitlab-ctl reconfigure
msg_ok "Reconfigured GitLab"
msg_ok "Updated successfully!"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}${CL}"
echo -e "${INFO}${YW}The initial root password is valid for 24 hours:${CL}"
echo -e "${TAB}${DEFAULT}${BGN}cat /etc/gitlab/initial_root_password${CL}"
+6
View File
@@ -0,0 +1,6 @@
_______ __ __ __
/ ____(_) /_/ / ____ _/ /_
/ / __/ / __/ / / __ `/ __ \
/ /_/ / / /_/ /___/ /_/ / /_/ /
\____/_/\__/_____/\__,_/_.___/
+6
View File
@@ -0,0 +1,6 @@
__ ___ __
/ / / (_)____/ /____ _____
/ /_/ / / ___/ __/ _ \/ ___/
/ __ / (__ ) /_/ __/ /
/_/ /_/_/____/\__/\___/_/
+6
View File
@@ -0,0 +1,6 @@
____ _
/ _/___ _____ (_)____
/ // __ `/ __ \/ / ___/
_/ // /_/ / / / / (__ )
/___/\__, /_/ /_/_/____/
/____/
-6
View File
@@ -1,6 +0,0 @@
_____
/ ___/_________ _____ ____ ____ __ __
\__ \/ ___/ __ `/ __ \/ __ \/ __ \/ / / /
___/ / /__/ /_/ / / / / /_/ / /_/ / /_/ /
/____/\___/\__,_/_/ /_/\____/ .___/\__, /
/_/ /____/
+6
View File
@@ -0,0 +1,6 @@
_ __ __ __ ____ __ _ _
/ | / /__ / /__ ______ _____/ /__/ __ \____ / /_(_)___ ___ (_)___ ___ _____
/ |/ / _ \/ __/ | /| / / __ \/ ___/ //_/ / / / __ \/ __/ / __ `__ \/ /_ / / _ \/ ___/
/ /| / __/ /_ | |/ |/ / /_/ / / / ,< / /_/ / /_/ / /_/ / / / / / / / / /_/ __/ /
/_/ |_/\___/\__/ |__/|__/\____/_/ /_/|_|\____/ .___/\__/_/_/ /_/ /_/_/ /___/\___/_/
/_/
+6
View File
@@ -0,0 +1,6 @@
____ __ _ ___ __ _ _____
/ __ \/ /_ _____(_)___/ (_)___ _____ / / (_) _____ / ___/__ ______ _____
/ / / / __ \/ ___/ / __ / / __ `/ __ \______/ / / / | / / _ \\__ \/ / / / __ \/ ___/
/ /_/ / /_/ (__ ) / /_/ / / /_/ / / / /_____/ /___/ /| |/ / __/__/ / /_/ / / / / /__
\____/_.___/____/_/\__,_/_/\__,_/_/ /_/ /_____/_/ |___/\___/____/\__, /_/ /_/\___/
/____/
+6
View File
@@ -0,0 +1,6 @@
____ __
/ __ \_____/ /_
/ / / / ___/ __ \
/ /_/ / / / /_/ /
\____/_/ /_.___/
+4 -1
View File
@@ -46,8 +46,11 @@ function update_script() {
msg_info "Updating Heimdall-Dashboard" msg_info "Updating Heimdall-Dashboard"
cd /opt/Heimdall cd /opt/Heimdall
sed -i 's/^APP_ENV=.*/APP_ENV=production/' .env
rm -f bootstrap/cache/*.php
export COMPOSER_ALLOW_SUPERUSER=1 export COMPOSER_ALLOW_SUPERUSER=1
$STD composer dump-autoload $STD composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
$STD php artisan optimize:clear
msg_ok "Updated Heimdall-Dashboard" msg_ok "Updated Heimdall-Dashboard"
msg_info "Restoring Data" msg_info "Restoring Data"
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/asciimoo/hister
APP="Hister"
var_tags="${var_tags:-search;browser-history;personal}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-20}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /usr/local/bin/hister ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "hister" "asciimoo/hister"; then
msg_info "Stopping Service"
systemctl stop hister
msg_ok "Stopped Service"
fetch_and_deploy_gh_release "hister" "asciimoo/hister" "singlefile" "latest" "/usr/local/bin" "hister_*_linux_$(arch_resolve)"
msg_info "Starting Service"
systemctl start hister
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:4433${CL}"
+36 -9
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ) # Author: MickLesk (CanbiZ) | Co-Author: Tom Frenzel (tomfrenzel)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/danielbrendel/hortusfox-web # Source: https://github.com/danielbrendel/hortusfox-web
@@ -34,29 +34,56 @@ function update_script() {
systemctl stop apache2 systemctl stop apache2
msg_ok "Stopped Service" msg_ok "Stopped Service"
msg_info "Backing up current HortusFox installation" cd /opt/hortusfox
cd /opt if [[ ! -s app/migrations/migrations.list ]]; then
mv /opt/hortusfox/ /opt/hortusfox-backup msg_info "Rebuilding HortusFox migration history"
msg_ok "Backed up current HortusFox installation" local database_tables
database_tables="$(mariadb -u root -D hortusfox -NBe "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE();")"
: >app/migrations/migrations.list
local migration migration_file table_name
for migration in app/migrations/*.php; do
migration_file="${migration##*/}"
table_name="${migration_file%.php}"
if [[ "$migration_file" == "VersionModel.php" ]] || grep -Fxq "$table_name" <<<"$database_tables"; then
php -r 'echo hash("sha512", $argv[1]), PHP_EOL;' -- "$migration_file" >>app/migrations/migrations.list
fi
done
msg_ok "Rebuilt HortusFox migration history"
fi
if [[ ! -f app/migrations/verhist.json && -f ~/.hortusfox ]]; then
printf '["%s"]\n' "$(<~/.hortusfox)" >app/migrations/verhist.json
fi
create_backup \
/opt/hortusfox/.env \
/opt/hortusfox/app/migrations/migrations.list \
/opt/hortusfox/app/migrations/verhist.json \
/opt/hortusfox/public/img \
/opt/hortusfox/public/attachments \
/opt/hortusfox/public/backup \
/opt/hortusfox/public/exports \
/opt/hortusfox/public/snd \
/opt/hortusfox/public/themes
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "hortusfox" "danielbrendel/hortusfox-web" "tarball" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "hortusfox" "danielbrendel/hortusfox-web" "tarball"
restore_backup
msg_info "Updating HortusFox" msg_info "Updating HortusFox"
cd /opt/hortusfox cd /opt/hortusfox
cp /opt/hortusfox-backup/.env /opt/hortusfox/.env
cp -a /opt/hortusfox-backup/public/img/. /opt/hortusfox/public/img/
export COMPOSER_ALLOW_SUPERUSER=1 export COMPOSER_ALLOW_SUPERUSER=1
$STD composer install --no-dev --optimize-autoloader $STD composer install --no-dev --optimize-autoloader
$STD php asatru migrate:list
$STD php asatru migrate:upgrade $STD php asatru migrate:upgrade
$STD php asatru plants:attributes
$STD php asatru calendar:classes $STD php asatru calendar:classes
$STD php asatru plants:attributes
$STD php asatru aquashell:config
chown -R www-data:www-data /opt/hortusfox chown -R www-data:www-data /opt/hortusfox
rm -r /opt/hortusfox-backup
msg_ok "Updated HortusFox" msg_ok "Updated HortusFox"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start apache2 systemctl start apache2
msg_ok "Started Service" msg_ok "Started Service"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
fi fi
exit exit
+79
View File
@@ -0,0 +1,79 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Nystik-gh/ignis
APP="Ignis"
var_tags="${var_tags:-notes;obsidian}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-10}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_unprivileged="${var_unprivileged:-1}"
var_arm64="${var_arm64:-yes}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/ignis ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "ignis" "Nystik-gh/ignis"; then
msg_info "Stopping Service"
systemctl stop ignis
msg_ok "Stopped Service"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "ignis" "Nystik-gh/ignis" "tarball"
msg_info "Building Ignis"
cd /opt/ignis
export NODE_OPTIONS="--max-old-space-size=4096"
export IGNIS_BUILD="$(cat ~/.ignis)"
$STD npm ci --ignore-scripts
$STD npm run build
$STD npm install -g @electron/asar
msg_ok "Built Ignis"
msg_info "Checking Obsidian Web Assets"
OBSIDIAN_VERSION=$(grep -oP 'OBSIDIAN_VERSION=\K[0-9.]+' /opt/ignis/apps/ignis-server/Dockerfile | head -n1)
[[ -z "$OBSIDIAN_VERSION" ]] && OBSIDIAN_VERSION="$(cat /opt/ignis_data/obsidian.version 2>/dev/null)"
if [[ -n "$OBSIDIAN_VERSION" && "$OBSIDIAN_VERSION" != "$(cat /opt/ignis_data/obsidian.version 2>/dev/null)" ]]; then
rm -rf /opt/ignis_data/obsidian-app
mkdir -p /opt/ignis_data/obsidian-app
curl -fsSL -o /tmp/obsidian.asar.gz "https://github.com/obsidianmd/obsidian-releases/releases/download/v${OBSIDIAN_VERSION}/obsidian-${OBSIDIAN_VERSION}.asar.gz"
gunzip -f /tmp/obsidian.asar.gz
$STD asar extract /tmp/obsidian.asar /opt/ignis_data/obsidian-app
rm -f /tmp/obsidian.asar
echo "${OBSIDIAN_VERSION}" >/opt/ignis_data/obsidian.version
fi
msg_ok "Checked Obsidian Web Assets"
msg_info "Starting Service"
systemctl start ignis
systemctl reload nginx
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}https://${IP}${CL}"
+10 -1
View File
@@ -214,7 +214,16 @@ EOF
cd "$SRC_DIR" cd "$SRC_DIR"
export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg
$STD mise install mise_ok=0
for i in 1 2 3; do
$STD mise install && {
mise_ok=1
break
}
msg_warn "mise install failed (attempt $i/3) - retrying"
sleep 5
done
[[ "$mise_ok" -eq 1 ]] || exit 1
export PATH="$(mise bin-paths 2>/dev/null | tr '\n' ':')$PATH" export PATH="$(mise bin-paths 2>/dev/null | tr '\n' ':')$PATH"
if ! command -v extism-js >/dev/null 2>&1; then if ! command -v extism-js >/dev/null 2>&1; then
# extism-js ships as a bare gzip-compressed single binary (.gz) that # extism-js ships as a bare gzip-compressed single binary (.gz) that
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Ozark-Connect/NetworkOptimizer
APP="NetworkOptimizer"
var_tags="${var_tags:-network;monitoring;unifi}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-4096}"
var_disk="${var_disk:-12}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/networkoptimizer ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "networkoptimizer" "Ozark-Connect/NetworkOptimizer"; then
msg_info "Stopping Service"
systemctl stop networkoptimizer
msg_ok "Stopped Service"
create_backup /opt/networkoptimizer/networkoptimizer.env
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "networkoptimizer" "Ozark-Connect/NetworkOptimizer" "tarball"
msg_info "Rebuilding NetworkOptimizer"
RID="linux-x64"
[[ "$(dpkg --print-architecture)" == "arm64" ]] && RID="linux-arm64"
cd /opt/networkoptimizer
$STD dotnet publish src/NetworkOptimizer.Web -c Release -r "$RID" --self-contained -o /opt/networkoptimizer/publish
chmod +x /opt/networkoptimizer/publish/NetworkOptimizer.Web
mkdir -p /opt/networkoptimizer/publish/tools
cd /opt/networkoptimizer/src/uwnspeedtest
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $STD go build -trimpath -ldflags "-s -w" -o /opt/networkoptimizer/publish/tools/uwnspeedtest-linux-arm64 .
msg_ok "Rebuilt NetworkOptimizer"
restore_backup
msg_info "Starting Service"
systemctl start networkoptimizer
msg_ok "Started Service"
msg_ok "Updated successfully!"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:8042${CL}"
+1 -1
View File
@@ -11,7 +11,7 @@ var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}" var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}" var_disk="${var_disk:-8}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-12}" var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}" var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/vrtmrz/obsidian-livesync | https://couchdb.apache.org/
APP="Obsidian-LiveSync"
var_tags="${var_tags:-documents;notes}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /opt/couchdb/etc/local.d/obsidian-livesync.ini ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Stopping CouchDB"
systemctl stop couchdb
msg_ok "Stopped CouchDB"
create_backup /var/lib/couchdb /opt/couchdb/etc/local.d/obsidian-livesync.ini /opt/obsidian-livesync/.env
msg_info "Updating Container OS"
$STD apt update
$STD apt upgrade -y
msg_ok "Updated Container OS"
systemctl stop couchdb
restore_backup
msg_info "Starting CouchDB"
systemctl start couchdb
msg_ok "Started CouchDB"
msg_ok "Updated successfully!"
exit
}
start
build_container
description
msg_ok "Completed successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Configure the Self-hosted LiveSync plugin with the credentials in /opt/obsidian-livesync/.env${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:5984/_utils/${CL}"
+2
View File
@@ -43,6 +43,8 @@ function update_script() {
fi fi
msg_ok "New version available: ${LATEST}" msg_ok "New version available: ${LATEST}"
NODE_VERSION="26" setup_nodejs
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop omniroute systemctl stop omniroute
msg_ok "Stopped Service" msg_ok "Stopped Service"
+1 -1
View File
@@ -30,7 +30,7 @@ function update_script() {
exit exit
fi fi
RELEASE="v7.3.0" RELEASE="v7.4.0"
if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then if check_for_gh_release "OpenCloud" "opencloud-eu/opencloud" "${RELEASE}" "each release is tested individually before the version is updated. Please do not open issues for this"; then
msg_info "Stopping services" msg_info "Stopping services"
systemctl stop opencloud opencloud-wopi systemctl stop opencloud opencloud-wopi
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2026 community-scripts ORG
# Author: angusmaul
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://orb.net/
APP="Orb"
var_tags="${var_tags:-network;monitoring}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-512}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if ! dpkg -s orb >/dev/null 2>&1; then
msg_error "No ${APP} Installation Found!"
exit 233
fi
msg_info "Updating Orb"
$STD apt update
$STD apt install -y --only-upgrade orb
msg_ok "Updated successfully!"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${TAB}${GATEWAY}${BGN}To link the sensor to your orb account run:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}pct exec ${CTID} -- runuser -u orb -- orb link${CL}"
+3
View File
@@ -17,6 +17,9 @@ var_arm64="${var_arm64:-yes}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
var_tun="${var_tun:-1}" var_tun="${var_tun:-1}"
export var_pangolin_url="${var_pangolin_url:-}"
export var_pangolin_email="${var_pangolin_email:-}"
header_info "$APP" header_info "$APP"
variables variables
color color
+2 -2
View File
@@ -42,7 +42,7 @@ function update_script() {
echo -e "" echo -e ""
msg_custom "🔄" "Migration required to new data structure (/opt/paperless_data/)" msg_custom "🔄" "Migration required to new data structure (/opt/paperless_data/)"
msg_custom "📖" "Please follow the migration guide:" msg_custom "📖" "Please follow the migration guide:"
echo -e "${GATEWAY}${BGN}https://github.com/community-scripts/ProxmoxVE/discussions/9223${CL}" echo -e "${GATEWAY}${BGN}https://github.com/community-scripts/ProxmoxVE/pull/9223${CL}"
echo -e "" echo -e ""
msg_custom "⚠️" "Update aborted. Please migrate your data first." msg_custom "⚠️" "Update aborted. Please migrate your data first."
exit 253 exit 253
@@ -65,7 +65,7 @@ function update_script() {
read -rp "Do you want to continue with the update? (y/N): " MIGRATE read -rp "Do you want to continue with the update? (y/N): " MIGRATE
echo echo
if [[ ! "$MIGRATE" =~ ^[Yy]$ ]]; then if [[ ! "$MIGRATE" =~ ^[Yy]$ ]]; then
msg_info "Update aborted. Decrypt all documents before upgrading to v3." msg_custom "⚠️" "Update aborted. Decrypt all documents before upgrading to v3."
exit 0 exit 0
fi fi
fi fi
+1
View File
@@ -38,6 +38,7 @@ function update_script() {
create_backup /opt/passwordpusher/storage /opt/passwordpusher/.env.production create_backup /opt/passwordpusher/storage /opt/passwordpusher/.env.production
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "passwordpusher" "pglombardo/PasswordPusher" "tarball" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "passwordpusher" "pglombardo/PasswordPusher" "tarball"
RUBY_VERSION="$(cat /opt/passwordpusher/.ruby-version)" RUBY_INSTALL_RAILS="false" setup_ruby
msg_info "Installing Gem Dependencies" msg_info "Installing Gem Dependencies"
cd /opt/passwordpusher cd /opt/passwordpusher
+1 -1
View File
@@ -36,7 +36,7 @@ function update_script() {
sed -i "s/^\(Pin: version \).*/\1${RELEASE}/" /etc/apt/preferences.d/salt-pin-1001 sed -i "s/^\(Pin: version \).*/\1${RELEASE}/" /etc/apt/preferences.d/salt-pin-1001
$STD apt update $STD apt update
$STD apt upgrade -y $STD apt upgrade -y
echo "${RELEASE}" >/~.salt echo "${RELEASE}" >~/.salt
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
fi fi
exit exit
+1
View File
@@ -30,6 +30,7 @@ function update_script() {
exit exit
fi fi
ensure_dependencies git
if check_for_gh_release "sparkyfitness" "CodeWithCJ/SparkyFitness"; then if check_for_gh_release "sparkyfitness" "CodeWithCJ/SparkyFitness"; then
msg_info "Stopping Services" msg_info "Stopping Services"
systemctl stop sparkyfitness-server nginx systemctl stop sparkyfitness-server nginx
+3 -5
View File
@@ -35,18 +35,16 @@ function update_script() {
systemctl stop split-pro systemctl stop split-pro
msg_ok "Stopped Service" msg_ok "Stopped Service"
msg_info "Backing up Data" create_backup /opt/split-pro/.env
cp /opt/split-pro/.env /opt/split-pro.env
msg_ok "Backed up Data"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "split-pro" "oss-apps/split-pro" "tarball" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "split-pro" "oss-apps/split-pro" "tarball"
restore_backup
msg_info "Building Application" msg_info "Building Application"
cd /opt/split-pro cd /opt/split-pro
$STD pnpm install --frozen-lockfile $STD pnpm install --frozen-lockfile
$STD pnpm build $STD pnpm build
cp /opt/split-pro.env /opt/split-pro/.env
rm -f /opt/split-pro.env
ln -sf /opt/split-pro_data/uploads /opt/split-pro/uploads ln -sf /opt/split-pro_data/uploads /opt/split-pro/uploads
$STD pnpm exec prisma migrate deploy $STD pnpm exec prisma migrate deploy
msg_ok "Built Application" msg_ok "Built Application"
+38 -10
View File
@@ -112,14 +112,33 @@ EOF
msg_ok "Stopped Termix" msg_ok "Stopped Termix"
msg_info "Migrating Configuration" msg_info "Migrating Configuration"
if [[ ! -f /opt/termix/.env ]]; then mkdir -p /opt/termix/db/data
cat <<EOF >/opt/termix/.env
if [[ -f /opt/termix/data/db.sqlite.encrypted && ! -f /opt/termix/db/data/db.sqlite.encrypted ]]; then
cp -a /opt/termix/data/db.sqlite.encrypted /opt/termix/db/data/db.sqlite.encrypted
[[ -f /opt/termix/data/db.sqlite.encrypted.meta ]] &&
cp -a /opt/termix/data/db.sqlite.encrypted.meta /opt/termix/db/data/db.sqlite.encrypted.meta
[[ -f /opt/termix/data/db.sqlite ]] &&
cp -a /opt/termix/data/db.sqlite /opt/termix/db/data/db.sqlite
fi
if [[ -f /opt/termix/data/.env && ! -f /opt/termix/db/data/.env ]]; then
cp -a /opt/termix/data/.env /opt/termix/db/data/.env
fi
for sub in ssl session_logs session_recordings acme-webroot certbot uploads; do
if [[ -d /opt/termix/data/$sub && ! -d /opt/termix/db/data/$sub ]]; then
cp -a "/opt/termix/data/$sub" "/opt/termix/db/data/$sub"
fi
done
cat <<EOF >/opt/termix/.env
NODE_ENV=production NODE_ENV=production
DATA_DIR=/opt/termix/data DATA_DIR=/opt/termix/db/data
GUACD_HOST=127.0.0.1 GUACD_HOST=127.0.0.1
GUACD_PORT=4822 GUACD_PORT=4822
EOF EOF
fi
if ! grep -q "EnvironmentFile" /etc/systemd/system/termix.service 2>/dev/null; then if ! grep -q "EnvironmentFile" /etc/systemd/system/termix.service 2>/dev/null; then
cat <<EOF >/etc/systemd/system/termix.service cat <<EOF >/etc/systemd/system/termix.service
[Unit] [Unit]
@@ -143,7 +162,11 @@ EOF
fi fi
msg_ok "Migrated Configuration" msg_ok "Migrated Configuration"
create_backup /opt/termix/data /opt/termix/uploads create_backup \
/opt/termix/db/data \
/opt/termix/data \
/opt/termix/uploads \
/opt/termix/.env
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "termix" "Termix-SSH/Termix" "tarball" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "termix" "Termix-SSH/Termix" "tarball"
@@ -158,10 +181,10 @@ EOF
/opt/termix/db/data /opt/termix/db/data
msg_ok "Recreated Directories" msg_ok "Recreated Directories"
if [[ -f /opt/termix/data/db.sqlite.encrypted && ! -f /opt/termix/db/data/db.sqlite.encrypted ]]; then if [[ -f /opt/termix/db/data/db.sqlite.encrypted && ! -f /opt/termix/db/data/.env ]]; then
msg_info "Migrating Database to new layout" msg_error "Encrypted database restored without its keys (/opt/termix/db/data/.env is missing)"
cp -a /opt/termix/data/db.sqlite.encrypted /opt/termix/db/data/db.sqlite.encrypted msg_custom "🛟" "Restore the container from a backup and report this at https://github.com/community-scripts/ProxmoxVE/issues"
msg_ok "Migrated Database to new layout" exit 1
fi fi
msg_info "Building Frontend" msg_info "Building Frontend"
@@ -237,7 +260,12 @@ EOF
fi fi
msg_info "Starting Termix" msg_info "Starting Termix"
systemctl start termix systemctl daemon-reload
if ! systemctl start termix; then
msg_error "Termix failed to start"
journalctl -u termix -n 30 --no-pager || true
exit 1
fi
msg_ok "Started Termix" msg_ok "Started Termix"
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
fi fi
+2 -3
View File
@@ -46,8 +46,7 @@ function update_script() {
[[ "$CONFIRM2" =~ ^[yY]$ ]] || exit 0 [[ "$CONFIRM2" =~ ^[yY]$ ]] || exit 0
fi fi
RELEASE="v2.3.0" if check_for_gh_release "vikunja" "go-vikunja/vikunja"; then
if check_for_gh_release "vikunja" "go-vikunja/vikunja" "${RELEASE}" "v2.4.0 is killed at startup by the systemd SystemCallFilter shipped in the .deb (upstream go-vikunja/vikunja#3252); pinned until a fixed release is out"; then
echo echo
msg_warn "The package update may include config file changes." msg_warn "The package update may include config file changes."
echo -e "${TAB}${YW}How do you want to handle /etc/vikunja/config.yml?${CL}" echo -e "${TAB}${YW}How do you want to handle /etc/vikunja/config.yml?${CL}"
@@ -66,7 +65,7 @@ function update_script() {
systemctl stop vikunja systemctl stop vikunja
msg_ok "Stopped Service" msg_ok "Stopped Service"
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "${RELEASE}" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb" fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "latest" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
$STD systemctl daemon-reload $STD systemctl daemon-reload
msg_info "Starting Service" msg_info "Starting Service"
+2
View File
@@ -34,6 +34,8 @@ function update_script() {
systemctl stop watcharr systemctl stop watcharr
msg_ok "Stopped Service" msg_ok "Stopped Service"
NODE_VERSION="24" setup_nodejs
create_backup /opt/watcharr/server/data create_backup /opt/watcharr/server/data
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "watcharr" "sbondCo/Watcharr" "tarball" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "watcharr" "sbondCo/Watcharr" "tarball"
restore_backup restore_backup
+7
View File
@@ -48,6 +48,13 @@ function update_script() {
chmod 644 /opt/xyops/node_modules/useragent-ng/lib/regexps.js chmod 644 /opt/xyops/node_modules/useragent-ng/lib/regexps.js
msg_ok "Rebuilt Application" msg_ok "Rebuilt Application"
fetch_and_deploy_gh_release "xysat" "pixlcore/xysat" "tarball" "latest" "/opt/xyops/satellite"
msg_info "Building xySat Satellite"
cd /opt/xyops/satellite
$STD npm install
msg_ok "Built xySat Satellite"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start xyops systemctl start xyops
msg_ok "Started Service" msg_ok "Started Service"
+2 -1
View File
@@ -19,7 +19,7 @@ $STD apt install -y \
g++ g++
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
NODE_VERSION="22" setup_nodejs NODE_VERSION="24" setup_nodejs
create_self_signed_cert create_self_signed_cert
msg_info "Installing Actual Budget" msg_info "Installing Actual Budget"
@@ -51,6 +51,7 @@ cat <<EOF >/opt/actualbudget-data/config.json
EOF EOF
mkdir -p /opt/actualbudget mkdir -p /opt/actualbudget
cd /opt/actualbudget cd /opt/actualbudget
$STD npm config set allow-scripts=bcrypt,better-sqlite3,argon2 --location=global
$STD npm install --location=global @actual-app/sync-server $STD npm install --location=global @actual-app/sync-server
echo "${RELEASE}" >~/.actualbudget echo "${RELEASE}" >~/.actualbudget
msg_ok "Installed Actual Budget" msg_ok "Installed Actual Budget"
+2
View File
@@ -78,6 +78,8 @@ $STD yarn config set enableTelemetry 0
export NODE_OPTIONS="--max-old-space-size=4096" export NODE_OPTIONS="--max-old-space-size=4096"
export TSC_COMPILE_ON_ERROR=true export TSC_COMPILE_ON_ERROR=true
$STD yarn install $STD yarn install
$STD bash ./scripts/set-version.sh "$(cat ~/.affine_app)"
export BUILD_TYPE=stable
$STD npm install -g typescript $STD npm install -g typescript
$STD yarn affine @affine/native build $STD yarn affine @affine/native build
$STD yarn affine @affine/server-native build $STD yarn affine @affine/server-native build
+1 -1
View File
@@ -14,7 +14,7 @@ network_check
update_os update_os
msg_info "Installing Apache CouchDB" msg_info "Installing Apache CouchDB"
ERLANG_COOKIE=$(openssl rand -base64 32) ERLANG_COOKIE=$(openssl rand -hex 32)
ADMIN_PASS="$(openssl rand -base64 18 | cut -c1-13)" ADMIN_PASS="$(openssl rand -base64 18 | cut -c1-13)"
debconf-set-selections <<<"couchdb couchdb/cookie string $ERLANG_COOKIE" debconf-set-selections <<<"couchdb couchdb/cookie string $ERLANG_COOKIE"
debconf-set-selections <<<"couchdb couchdb/mode select standalone" debconf-set-selections <<<"couchdb couchdb/mode select standalone"
+1 -1
View File
@@ -58,7 +58,7 @@ fetch_and_deploy_gh_release "Byparr" "ThePhaseless/Byparr" "tarball" "latest"
msg_info "Configuring Byparr" msg_info "Configuring Byparr"
cd /opt/Byparr cd /opt/Byparr
$STD uv sync --link-mode copy $STD uv sync --link-mode copy
$STD uv run camoufox fetch $STD uv run python -m invisible_playwright fetch
msg_ok "Configured Byparr" msg_ok "Configured Byparr"
msg_info "Creating Service" msg_info "Creating Service"
-1
View File
@@ -83,7 +83,6 @@ $STD apt-get install -y \
fonts-kacst fonts-liberation \ fonts-kacst fonts-liberation \
fonts-noto-cjk \ fonts-noto-cjk \
fonts-noto-color-emoji \ fonts-noto-color-emoji \
msttcorefonts \
fonts-roboto \ fonts-roboto \
fonts-thai-tlwg \ fonts-thai-tlwg \
fonts-wqy-zenhei fonts-wqy-zenhei
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://about.gitlab.com/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
openssh-server \
perl \
tzdata
msg_ok "Installed Dependencies"
setup_deb822_repo \
"gitlab-ce" \
"https://packages.gitlab.com/gitlab/gitlab-ce/gpgkey" \
"https://packages.gitlab.com/gitlab/gitlab-ce/debian" \
"$(get_os_info codename)" \
"main"
msg_info "Configuring GitLab"
mkdir -p /etc/gitlab
cat <<EOF >/etc/gitlab/gitlab.rb
external_url 'http://${LOCAL_IP}'
# Omnibus runs 'sysctl -e --system' during reconfigure, which fails in an
# unprivileged LXC because most kernel keys are not writable.
package['modify_kernel_parameters'] = false
EOF
msg_ok "Configured GitLab"
msg_info "Installing GitLab CE (Patience)"
$STD apt install -y gitlab-ce
msg_ok "Installed GitLab CE"
msg_info "Reconfiguring GitLab (Patience)"
$STD gitlab-ctl reconfigure
msg_ok "Reconfigured GitLab"
motd_ssh
customize
cleanup_lxc
+1
View File
@@ -24,6 +24,7 @@ fetch_and_deploy_gh_release "Heimdall" "linuxserver/Heimdall" "tarball"
msg_info "Setting up Heimdall-Dashboard" msg_info "Setting up Heimdall-Dashboard"
cd /opt/Heimdall cd /opt/Heimdall
cp .env.example .env cp .env.example .env
sed -i 's/^APP_ENV=.*/APP_ENV=production/' .env
$STD php artisan key:generate $STD php artisan key:generate
msg_ok "Setup Heimdall-Dashboard" msg_ok "Setup Heimdall-Dashboard"
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/asciimoo/hister
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
fetch_and_deploy_gh_release "hister" "asciimoo/hister" "singlefile" "latest" "/usr/local/bin" "hister_*_linux_$(arch_resolve)"
msg_info "Configuring Hister"
mkdir -p /opt/hister/data /etc/hister
LOCAL_IP=$(hostname -I | awk '{print $1}')
cat <<EOF >/etc/hister/config.yaml
app:
directory: '/opt/hister/data'
server:
address: '0.0.0.0:4433'
base_url: 'http://${LOCAL_IP}:4433'
EOF
msg_ok "Configured Hister"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/hister.service
[Unit]
Description=Hister Search Engine
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/hister listen --config /etc/hister/config.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now hister
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+5 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG # Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ) # Author: MickLesk (CanbiZ) | Co-Author: Tom Frenzel (tomfrenzel)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/danielbrendel/hortusfox-web # Source: https://github.com/danielbrendel/hortusfox-web
@@ -36,12 +36,15 @@ msg_ok "Composer dependencies installed"
msg_info "Running DB migration" msg_info "Running DB migration"
$STD php asatru migrate:fresh $STD php asatru migrate:fresh
HORTUSFOX_VERSION="$(<~/.hortusfox)"
printf '["%s"]\n' "$HORTUSFOX_VERSION" >/opt/hortusfox/app/migrations/verhist.json
msg_ok "Migration finished" msg_ok "Migration finished"
msg_info "Setting up HortusFox" msg_info "Setting up HortusFox"
$STD mariadb -u root -D $MARIADB_DB_NAME -e "INSERT IGNORE INTO AppModel (workspace, language, created_at) VALUES ('Default Workspace', 'en', NOW());" $STD mariadb -u root -D $MARIADB_DB_NAME -e "INSERT IGNORE INTO AppModel (workspace, language, created_at) VALUES ('Default Workspace', 'en', NOW());"
$STD php asatru plants:attributes
$STD php asatru calendar:classes $STD php asatru calendar:classes
$STD php asatru plants:attributes
$STD php asatru aquashell:config
ADMIN_EMAIL="admin@example.com" ADMIN_EMAIL="admin@example.com"
ADMIN_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)" ADMIN_PASS="$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13)"
ADMIN_HASH=$(php -r "echo password_hash('$ADMIN_PASS', PASSWORD_BCRYPT);") ADMIN_HASH=$(php -r "echo password_hash('$ADMIN_PASS', PASSWORD_BCRYPT);")
+113
View File
@@ -0,0 +1,113 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Nystik-gh/ignis
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y nginx
msg_ok "Installed Dependencies"
NODE_VERSION="22" setup_nodejs
fetch_and_deploy_gh_release "ignis" "Nystik-gh/ignis" "tarball"
msg_info "Building Ignis"
cd /opt/ignis
export NODE_OPTIONS="--max-old-space-size=4096"
export IGNIS_BUILD="$(cat ~/.ignis)"
$STD npm ci --ignore-scripts
$STD npm run build
$STD npm install -g @electron/asar
msg_ok "Built Ignis"
msg_info "Downloading Obsidian Web Assets"
mkdir -p /opt/ignis_data/{obsidian-app,vaults,data}
OBSIDIAN_VERSION=$(grep -oP 'OBSIDIAN_VERSION=\K[0-9.]+' /opt/ignis/apps/ignis-server/Dockerfile | head -n1)
[[ -z "$OBSIDIAN_VERSION" ]] && OBSIDIAN_VERSION="1.12.7"
curl -fsSL -o /tmp/obsidian.asar.gz "https://github.com/obsidianmd/obsidian-releases/releases/download/v${OBSIDIAN_VERSION}/obsidian-${OBSIDIAN_VERSION}.asar.gz"
gunzip -f /tmp/obsidian.asar.gz
$STD asar extract /tmp/obsidian.asar /opt/ignis_data/obsidian-app
rm -f /tmp/obsidian.asar
echo "${OBSIDIAN_VERSION}" >/opt/ignis_data/obsidian.version
msg_ok "Downloaded Obsidian Web Assets"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/ignis.service
[Unit]
Description=Ignis (Obsidian in the browser)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/ignis
Environment=NODE_ENV=production
Environment=PORT=8080
Environment=VAULT_ROOT=/opt/ignis_data/vaults
Environment=DATA_ROOT=/opt/ignis_data/data
Environment=OBSIDIAN_ASSETS_PATH=/opt/ignis_data/obsidian-app
Environment=AUTO_CREATE_DEFAULT=true
ExecStart=/usr/bin/node /opt/ignis/apps/ignis-server/server/index.js
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now ignis
msg_ok "Created Service"
msg_info "Generating Self-Signed Certificate"
create_self_signed_cert "ignis"
msg_ok "Generated Self-Signed Certificate"
msg_info "Configuring Nginx"
cat <<'EOF' >/etc/nginx/sites-available/ignis.conf
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
http2 on;
server_name _;
ssl_certificate /etc/ssl/ignis/ignis.crt;
ssl_certificate_key /etc/ssl/ignis/ignis.key;
client_max_body_size 1024m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
}
}
EOF
ln -sf /etc/nginx/sites-available/ignis.conf /etc/nginx/sites-enabled/ignis.conf
rm -f /etc/nginx/sites-enabled/default
systemctl restart nginx
msg_ok "Configured Nginx"
motd_ssh
customize
cleanup_lxc
+10 -1
View File
@@ -355,7 +355,16 @@ cp LICENSE "$APP_DIR"
cd "$SRC_DIR" cd "$SRC_DIR"
export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml export MISE_TRUSTED_CONFIG_PATHS="$SRC_DIR"/mise.toml
export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg export MISE_DISABLE_TOOLS=github:jellyfin/jellyfin-ffmpeg
$STD mise install mise_ok=0
for i in 1 2 3; do
$STD mise install && {
mise_ok=1
break
}
msg_warn "mise install failed (attempt $i/3) - retrying"
sleep 5
done
[[ "$mise_ok" -eq 1 ]] || exit 1
export PATH="$(mise bin-paths 2>/dev/null | tr '\n' ':')$PATH" export PATH="$(mise bin-paths 2>/dev/null | tr '\n' ':')$PATH"
if ! command -v extism-js >/dev/null 2>&1; then if ! command -v extism-js >/dev/null 2>&1; then
# extism-js is published as a bare gzip-compressed single binary (.gz), which # extism-js is published as a bare gzip-compressed single binary (.gz), which
+79
View File
@@ -0,0 +1,79 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/Ozark-Connect/NetworkOptimizer
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
msg_info "Installing Dependencies"
$STD apt install -y \
git \
sshpass \
iperf3
setup_deb822_repo \
"microsoft" \
"https://packages.microsoft.com/keys/microsoft-2025.asc" \
"https://packages.microsoft.com/debian/13/prod/" \
"trixie"
$STD apt install -y dotnet-sdk-10.0
msg_ok "Installed Dependencies"
setup_go
fetch_and_deploy_gh_release "networkoptimizer" "Ozark-Connect/NetworkOptimizer" "tarball"
msg_info "Building NetworkOptimizer"
RID="linux-x64"
[[ "$(dpkg --print-architecture)" == "arm64" ]] && RID="linux-arm64"
cd /opt/networkoptimizer
export MinVerVersionOverride="$(cat ~/.networkoptimizer)"
$STD dotnet publish src/NetworkOptimizer.Web -c Release -r "$RID" --self-contained -o /opt/networkoptimizer/publish
chmod +x /opt/networkoptimizer/publish/NetworkOptimizer.Web
msg_ok "Built NetworkOptimizer"
msg_info "Building Gateway Speed Test Binary"
mkdir -p /opt/networkoptimizer/publish/tools
cd /opt/networkoptimizer/src/uwnspeedtest
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $STD go build -trimpath -ldflags "-s -w" -o /opt/networkoptimizer/publish/tools/uwnspeedtest-linux-arm64 .
msg_ok "Built Gateway Speed Test Binary"
msg_info "Configuring NetworkOptimizer"
cat <<EOF >/opt/networkoptimizer/networkoptimizer.env
ASPNETCORE_URLS=http://*:8042
HOST_IP=${LOCAL_IP}
Iperf3Server__Enabled=true
EOF
msg_ok "Configured NetworkOptimizer"
msg_info "Creating Service"
cat <<EOF >/etc/systemd/system/networkoptimizer.service
[Unit]
Description=NetworkOptimizer
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/networkoptimizer/publish
EnvironmentFile=/opt/networkoptimizer/networkoptimizer.env
ExecStart=/opt/networkoptimizer/publish/NetworkOptimizer.Web
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now networkoptimizer
msg_ok "Created Service"
motd_ssh
customize
cleanup_lxc
+10
View File
@@ -24,6 +24,16 @@ if [[ ! "$CONFIRM" =~ ^([yY][eE][sS]|[yY])$ ]]; then
exit 10 exit 10
fi fi
msg_info "Making ssh.service reloads behave like restarts"
mkdir -p /etc/systemd/system/ssh.service.d
cat <<'EOF' >/etc/systemd/system/ssh.service.d/reload-as-restart.conf
[Service]
ExecReload=
ExecReload=/usr/bin/systemd-run --no-block --quiet /bin/systemctl restart ssh.service
EOF
systemctl daemon-reload
msg_ok "Made ssh.service reloads behave like restarts"
msg_info "Installing NextCloudPi (Patience)" msg_info "Installing NextCloudPi (Patience)"
$STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh) $STD bash <(curl -fsSL https://raw.githubusercontent.com/nextcloud/nextcloudpi/master/install.sh)
msg_ok "Installed NextCloudPi" msg_ok "Installed NextCloudPi"
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: MickLesk (CanbiZ)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/vrtmrz/obsidian-livesync | https://couchdb.apache.org/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
setup_deb822_repo \
"couchdb" \
"https://couchdb.apache.org/repo/keys.asc" \
"https://apache.jfrog.io/artifactory/couchdb-deb/" \
"$(get_os_info codename)" \
"main"
msg_info "Installing CouchDB"
COUCHDB_ADMIN_USER="admin"
COUCHDB_PASSWORD="$(openssl rand -hex 24)"
COUCHDB_COOKIE="$(openssl rand -hex 16)"
cat <<EOF | debconf-set-selections
couchdb couchdb/mode select standalone
couchdb couchdb/mode seen true
couchdb couchdb/bindaddress string 0.0.0.0
couchdb couchdb/bindaddress seen true
couchdb couchdb/cookie string ${COUCHDB_COOKIE}
couchdb couchdb/cookie seen true
couchdb couchdb/adminpass password ${COUCHDB_PASSWORD}
couchdb couchdb/adminpass seen true
couchdb couchdb/adminpass_again password ${COUCHDB_PASSWORD}
couchdb couchdb/adminpass_again seen true
EOF
DEBIAN_FRONTEND=noninteractive $STD apt-get install -y couchdb
cat <<EOF >/root/.couchdb.credentials
COUCHDB_ADMIN_USER="${COUCHDB_ADMIN_USER}"
COUCHDB_ADMIN_PASSWORD="${COUCHDB_PASSWORD}"
COUCHDB_COOKIE="${COUCHDB_COOKIE}"
EOF
msg_ok "Installed CouchDB"
msg_info "Configuring CouchDB"
mkdir -p /opt/couchdb/etc/local.d /opt/obsidian-livesync
cat <<EOF >/opt/couchdb/etc/local.d/obsidian-livesync.ini
[couchdb]
single_node = true
max_document_size = 50000000
[admins]
admin = ${COUCHDB_PASSWORD}
[chttpd]
bind_address = 0.0.0.0
port = 5984
max_http_request_size = 4294967296
[chttpd_auth]
require_valid_user = true
[httpd]
enable_cors = true
WWW-Authenticate = Basic realm="couchdb"
[cors]
credentials = true
origins = app://obsidian.md,capacitor://localhost,http://localhost
headers = accept, authorization, content-type, origin, referer
methods = GET, PUT, POST, HEAD, DELETE
max_age = 3600
EOF
cat <<EOF >/opt/obsidian-livesync/.env
COUCHDB_URL=http://${LOCAL_IP}:5984
COUCHDB_USER=admin
COUCHDB_PASSWORD=${COUCHDB_PASSWORD}
COUCHDB_DATABASE=obsidiannotes
EOF
chmod 600 /opt/obsidian-livesync/.env
msg_ok "Configured CouchDB"
msg_info "Creating LiveSync Database"
systemctl enable -q couchdb
systemctl restart couchdb
for _ in {1..30}; do
curl -fsS -u "admin:${COUCHDB_PASSWORD}" -X PUT http://127.0.0.1:5984/obsidiannotes >/dev/null 2>&1 && break
sleep 1
done
msg_ok "Created LiveSync Database"
motd_ssh
customize
cleanup_lxc
+1 -1
View File
@@ -13,7 +13,7 @@ setting_up_container
network_check network_check
update_os update_os
NODE_VERSION="24" setup_nodejs NODE_VERSION="26" setup_nodejs
msg_info "Installing OmniRoute" msg_info "Installing OmniRoute"
$STD npm install -g omniroute@latest $STD npm install -g omniroute@latest
+1 -1
View File
@@ -64,7 +64,7 @@ $STD sudo -u cool coolconfig set-admin-password --user=admin --password="$COOLPA
echo "$COOLPASS" >~/.coolpass echo "$COOLPASS" >~/.coolpass
msg_ok "Installed Collabora Online" msg_ok "Installed Collabora Online"
fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "v7.3.0" "/usr/bin" "opencloud-*-linux-$(arch_resolve)" fetch_and_deploy_gh_release "OpenCloud" "opencloud-eu/opencloud" "singlefile" "v7.4.0" "/usr/bin" "opencloud-*-linux-$(arch_resolve)"
mv /usr/bin/OpenCloud /usr/bin/opencloud mv /usr/bin/OpenCloud /usr/bin/opencloud
msg_info "Configuring OpenCloud" msg_info "Configuring OpenCloud"
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# Author: angusmaul
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://orb.net/
source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os
setup_deb822_repo \
"orb" \
"https://pkgs.orb.net/stable/debian/orbforge.noarmor.gpg" \
"https://pkgs.orb.net/stable/debian" \
"orb" \
"main"
msg_info "Installing Orb"
$STD apt install -y orb
msg_ok "Installed Orb"
msg_info "Enabling Service"
systemctl enable -q --now orb
msg_ok "Enabled Service"
motd_ssh
customize
cleanup_lxc
+11 -2
View File
@@ -27,9 +27,18 @@ fetch_and_deploy_gh_release "pangolin" "fosrl/pangolin" "tarball" "$PANGOLIN_VER
fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)" fetch_and_deploy_gh_release "gerbil" "fosrl/gerbil" "singlefile" "latest" "/usr/bin" "gerbil_linux_$(arch_resolve)"
fetch_and_deploy_gh_release "traefik" "traefik/traefik" "prebuild" "latest" "/usr/bin" "traefik_v*_linux_$(arch_resolve).tar.gz" fetch_and_deploy_gh_release "traefik" "traefik/traefik" "prebuild" "latest" "/usr/bin" "traefik_v*_linux_$(arch_resolve).tar.gz"
read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " pango_url # Read the variable first and prompt only when it is unset, so the install can
# be supplied up front. Same convention as install/forgejo-runner-install.sh.
pango_url="${var_pangolin_url:-}"
if [[ -z "$pango_url" ]]; then
read -rp "${TAB3}Enter your Pangolin URL (ex: https://pangolin.example.com): " pango_url
fi
[[ "$pango_url" != https://* && "$pango_url" != http://* ]] && pango_url="https://${pango_url}" [[ "$pango_url" != https://* && "$pango_url" != http://* ]] && pango_url="https://${pango_url}"
read -rp "${TAB3}Enter your email address: " pango_email
pango_email="${var_pangolin_email:-}"
if [[ -z "$pango_email" ]]; then
read -rp "${TAB3}Enter your email address: " pango_email
fi
msg_info "Setup Pangolin" msg_info "Setup Pangolin"
SECRET_KEY=$(openssl rand -base64 48 | tr -dc 'A-Za-z0-9' | head -c 32) SECRET_KEY=$(openssl rand -base64 48 | tr -dc 'A-Za-z0-9' | head -c 32)
+1 -1
View File
@@ -26,7 +26,7 @@ create_self_signed_cert
setup_deb822_repo \ setup_deb822_repo \
"passbolt" \ "passbolt" \
"https://keys.openpgp.org/pks/lookup?op=get&options=mr&search=0x3D1A0346C8E1802F774AEF21DE8B853FC155581D" \ "https://download.passbolt.com/pub.key" \
"https://download.passbolt.com/ce/debian" \ "https://download.passbolt.com/ce/debian" \
"buster" \ "buster" \
"stable" "stable"
+3 -2
View File
@@ -22,12 +22,13 @@ $STD apt install -y \
pkg-config pkg-config
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
RUBY_VERSION="4.0.5" RUBY_INSTALL_RAILS="false" setup_ruby
NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs NODE_VERSION="22" NODE_MODULE="yarn" setup_nodejs
export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"
fetch_and_deploy_gh_release "passwordpusher" "pglombardo/PasswordPusher" "tarball" fetch_and_deploy_gh_release "passwordpusher" "pglombardo/PasswordPusher" "tarball"
RUBY_VERSION="$(cat /opt/passwordpusher/.ruby-version)" RUBY_INSTALL_RAILS="false" setup_ruby
export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:$PATH"
msg_info "Installing Gem Dependencies" msg_info "Installing Gem Dependencies"
cd /opt/passwordpusher cd /opt/passwordpusher
$STD bundle config set --local without 'development test' $STD bundle config set --local without 'development test'
+1 -1
View File
@@ -29,7 +29,7 @@ Pin: version ${RELEASE}
Pin-Priority: 1001 Pin-Priority: 1001
EOF EOF
$STD apt install -y salt-master $STD apt install -y salt-master
echo "${RELEASE}" >/~.salt echo "${RELEASE}" >~/.salt
msg_ok "Installed Salt" msg_ok "Installed Salt"
motd_ssh motd_ssh
+3
View File
@@ -103,6 +103,9 @@ cat <<EOF >/etc/clickhouse-server/config.d/cluster.xml
<shard>01</shard> <shard>01</shard>
<replica>01</replica> <replica>01</replica>
</macros> </macros>
<merge_tree>
<allow_dimensions_outside_sorting_key>1</allow_dimensions_outside_sorting_key>
</merge_tree>
</clickhouse> </clickhouse>
EOF EOF
systemctl enable -q --now clickhouse-server systemctl enable -q --now clickhouse-server
+1 -1
View File
@@ -14,7 +14,7 @@ network_check
update_os update_os
msg_info "Installing Dependencies" msg_info "Installing Dependencies"
$STD apt install -y nginx $STD apt install -y git nginx
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
PG_VERSION="18" setup_postgresql PG_VERSION="18" setup_postgresql
+1 -1
View File
@@ -125,7 +125,7 @@ EOF
cat <<EOF >/opt/termix/.env cat <<EOF >/opt/termix/.env
NODE_ENV=production NODE_ENV=production
DATA_DIR=/opt/termix/data DATA_DIR=/opt/termix/db/data
GUACD_HOST=127.0.0.1 GUACD_HOST=127.0.0.1
GUACD_PORT=4822 GUACD_PORT=4822
EOF EOF
+1 -2
View File
@@ -13,8 +13,7 @@ setting_up_container
network_check network_check
update_os update_os
RELEASE="v2.3.0" fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "latest" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
fetch_and_deploy_gh_release "vikunja" "go-vikunja/vikunja" "binary" "${RELEASE}" "" "vikunja-*-$(arch_resolve "x86_64" "aarch64").deb"
msg_info "Setting up Vikunja" msg_info "Setting up Vikunja"
sed -i 's|^# \(service:\)|\1|' /etc/vikunja/config.yml sed -i 's|^# \(service:\)|\1|' /etc/vikunja/config.yml
+1 -1
View File
@@ -18,7 +18,7 @@ $STD apt install -y gcc
msg_ok "Installed Dependencies" msg_ok "Installed Dependencies"
setup_go setup_go
NODE_VERSION="22" setup_nodejs NODE_VERSION="24" setup_nodejs
fetch_and_deploy_gh_release "watcharr" "sbondCo/Watcharr" "tarball" fetch_and_deploy_gh_release "watcharr" "sbondCo/Watcharr" "tarball"
msg_info "Setup Watcharr" msg_info "Setup Watcharr"
+1 -1
View File
@@ -66,7 +66,7 @@ for i in {1..15}; do
fi fi
sleep 2 sleep 2
done done
$STD mariadb -u webtrees -p"${MARIADB_DB_PASS}" -h 127.0.0.1 webtrees -e "SHOW TABLES LIKE 'wt_user';" | grep -q wt_user mariadb -u webtrees -p"${MARIADB_DB_PASS}" -h 127.0.0.1 webtrees -e "SHOW TABLES LIKE 'wt_user';" | grep -q wt_user
msg_ok "Initialized Webtrees database schema" msg_ok "Initialized Webtrees database schema"
$STD sudo -u www-data php /opt/webtrees/index.php user Admin \ $STD sudo -u www-data php /opt/webtrees/index.php user Admin \
--create \ --create \
+1 -1
View File
@@ -126,7 +126,7 @@ network_check() {
fi fi
if [[ $ipv4_connected == false ]]; then if [[ $ipv4_connected == false ]]; then
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt </dev/tty
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}" echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
else else
+18 -13
View File
@@ -922,8 +922,10 @@ choose_and_set_storage_for_file() {
_list_os_versions() { _list_os_versions() {
local ostype="${1:-}" local ostype="${1:-}"
[[ -n "$ostype" ]] || return 0 [[ -n "$ostype" ]] || return 0
local arch
arch="$(dpkg --print-architecture 2>/dev/null || echo amd64)"
pveam available -section system 2>/dev/null | pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | grep -E "_${arch}\.(tar\.zst|tar\.xz|tar\.gz)([[:space:]]|$)" |
awk '{print $2}' | awk '{print $2}' |
sed -nE "s/^${ostype}-([0-9]+(\.[0-9]+)?).*/\1/p" | sed -nE "s/^${ostype}-([0-9]+(\.[0-9]+)?).*/\1/p" |
sort -u -V || true sort -u -V || true
@@ -936,8 +938,10 @@ _list_os_versions() {
_list_templates() { _list_templates() {
local search="${1:-}" pattern="${2:-}" local search="${1:-}" pattern="${2:-}"
[[ -n "$search" ]] || return 0 [[ -n "$search" ]] || return 0
local arch
arch="$(dpkg --print-architecture 2>/dev/null || echo amd64)"
pveam available -section system 2>/dev/null | pveam available -section system 2>/dev/null |
grep -E '\.(tar\.zst|tar\.xz|tar\.gz)$' | grep -E "_${arch}\.(tar\.zst|tar\.xz|tar\.gz)([[:space:]]|$)" |
awk '{print $2}' | awk '{print $2}' |
grep -E "^${search}.*${pattern}" | grep -E "^${search}.*${pattern}" |
sort -t - -k 2 -V || true sort -t - -k 2 -V || true
@@ -3917,7 +3921,7 @@ run_addon_updates() {
name="${a##*/update_}" name="${a##*/update_}"
printf 'Do you also want to update addon "%s"? (y/N) [60s]: ' "$name" printf 'Do you also want to update addon "%s"? (y/N) [60s]: ' "$name"
ans="" ans=""
if read -r -t 60 ans; then :; else echo; fi if read -r -t 60 ans </dev/tty; then :; else echo; fi
case "${ans,,}" in case "${ans,,}" in
y | yes) y | yes)
bash "$a" || msg_warn "Addon update for $name failed (rc=$?)" bash "$a" || msg_warn "Addon update for $name failed (rc=$?)"
@@ -5200,15 +5204,11 @@ EOF
# TSTP = Ctrl+Z, TTIN = bg read from tty, TTOU = bg write to tty (tostop) # TSTP = Ctrl+Z, TTIN = bg read from tty, TTOU = bg write to tty (tostop)
trap '' TSTP TTIN TTOU trap '' TSTP TTIN TTOU
# lxc-attach takes the controlling terminal while the install runs and does # lxc-attach left us in a background process group - claim the terminal back
# not hand it back, leaving us in a background process group. Reading from # before we print anything. Note this does NOT hold: the log collection
# the terminal then returns EIO instead of blocking, because SIGTTIN is # below uses pct pull/exec, which take it away again, so every interactive
# ignored above - so every recovery prompt fails before the user can answer. # prompt has to reclaim it again right before its read.
# Redirecting to /dev/tty does not help: the rule applies to the terminal, reclaim_tty
# not the file descriptor. Claim the foreground group back; SIGTTOU is
# ignored too, so tcsetpgrp() succeeds instead of stopping us. No-op when we
# already are in the foreground. perl is a hard dependency of Proxmox VE.
perl -e 'use POSIX; open(my $t, "+<", "/dev/tty") or exit 1; POSIX::tcsetpgrp(fileno($t), getpgrp()) or exit 1;' 2>/dev/null || true
msg_error "Installation failed in container ${CTID} (exit code: ${install_exit_code})" msg_error "Installation failed in container ${CTID} (exit code: ${install_exit_code})"
@@ -5338,6 +5338,7 @@ EOF
pct enter "$CTID" pct enter "$CTID"
echo "" echo ""
echo -en "${YW}Container ${CTID} still running. Remove now? (y/N): ${CL}" echo -en "${YW}Container ${CTID} still running. Remove now? (y/N): ${CL}"
reclaim_tty
if read -r response </dev/tty && [[ "$response" =~ ^[Yy]$ ]]; then if read -r response </dev/tty && [[ "$response" =~ ^[Yy]$ ]]; then
pct stop "$CTID" &>/dev/null || true pct stop "$CTID" &>/dev/null || true
pct destroy "$CTID" &>/dev/null || true pct destroy "$CTID" &>/dev/null || true
@@ -5497,6 +5498,7 @@ EOF
local response="" local response=""
local read_rc local read_rc
reclaim_tty
read -t 60 -r response </dev/tty read -t 60 -r response </dev/tty
read_rc=$? read_rc=$?
if [[ $read_rc -eq 0 ]]; then if [[ $read_rc -eq 0 ]]; then
@@ -5729,6 +5731,7 @@ EOF
# read itself failed (e.g. broken/closed stdin, I/O error) rather than # read itself failed (e.g. broken/closed stdin, I/O error) rather than
# timing out - don't guess and destroy the container on a read we # timing out - don't guess and destroy the container on a read we
# couldn't actually capture; keep it since that's the reversible choice. # couldn't actually capture; keep it since that's the reversible choice.
while read -r -t 0.1 -n 1 _ </dev/tty 2>/dev/null; do :; done
echo "" echo ""
msg_error "Could not read your response (stdin error) - keeping container ${CTID} for safety." msg_error "Could not read your response (stdin error) - keeping container ${CTID} for safety."
msg_error "Remove it manually if not needed: pct destroy ${CTID}" msg_error "Remove it manually if not needed: pct destroy ${CTID}"
@@ -5760,6 +5763,7 @@ destroy_lxc() {
trap 'echo; msg_error "Aborted by user (SIGINT/SIGQUIT)"; return 130' INT QUIT trap 'echo; msg_error "Aborted by user (SIGINT/SIGQUIT)"; return 130' INT QUIT
local prompt local prompt
reclaim_tty
if ! read -rp "Remove this Container? <y/N> " prompt </dev/tty; then if ! read -rp "Remove this Container? <y/N> " prompt </dev/tty; then
# read returns non-zero on Ctrl-D/ESC # read returns non-zero on Ctrl-D/ESC
msg_error "Aborted input (Ctrl-D/ESC)" msg_error "Aborted input (Ctrl-D/ESC)"
@@ -6721,7 +6725,8 @@ create_lxc_container() {
# Step 1: Check local templates first (instant) # Step 1: Check local templates first (instant)
mapfile -t LOCAL_TEMPLATES < <( mapfile -t LOCAL_TEMPLATES < <(
pveam list "$TEMPLATE_STORAGE" 2>/dev/null | pveam list "$TEMPLATE_STORAGE" 2>/dev/null |
awk -v search="${TEMPLATE_SEARCH}" -v pattern="${TEMPLATE_PATTERN}" '$1 ~ search && $1 ~ pattern {print $1}' | awk -v search="${TEMPLATE_SEARCH}" -v pattern="${TEMPLATE_PATTERN}" -v arch="${ARCH}" \
'$1 ~ search && $1 ~ pattern && $1 ~ ("_" arch "\\.(tar\\.zst|tar\\.xz|tar\\.gz)$") {print $1}' |
sed 's|.*/||' | sort -t - -k 2 -V sed 's|.*/||' | sort -t - -k 2 -V
) )
+110 -7
View File
@@ -299,6 +299,72 @@ root_check() {
fi fi
} }
# ------------------------------------------------------------------------------
# on_pve_host()
#
# - Returns 0 when executed on a Proxmox VE node, 1 otherwise
# - Cheap probe used by the guards below; never exits on its own
# ------------------------------------------------------------------------------
on_pve_host() {
command -v pveversion &>/dev/null
}
# ------------------------------------------------------------------------------
# require_pve_host()
#
# - Guard for tools that drive the node itself (pct/pveam/pvesm/pvesh/qm)
# - Aborts when not on a PVE node, then validates the PVE version
# ------------------------------------------------------------------------------
require_pve_host() {
if ! on_pve_host; then
msg_error "${APP:-This script} must be run on the Proxmox VE host."
msg_error "Proxmox tooling (pct/pveam/pvesm/qm) is not available here."
exit 232
fi
pve_check
}
# ------------------------------------------------------------------------------
# confirm_not_pve_host()
#
# - Guard for tools that belong inside an LXC/VM but would technically run
# on the node as well
# - Warns and asks for confirmation instead of hard-failing
# ------------------------------------------------------------------------------
confirm_not_pve_host() {
on_pve_host || return 0
msg_error "Running on the Proxmox VE host is NOT recommended!"
msg_error "${APP:-This script} is meant to be executed inside an LXC container."
echo ""
echo -n "${TAB:- }Continue anyway? (y/N): "
local confirm
read -r confirm
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
msg_warn "Aborted. Please run this inside an LXC container."
exit 0
fi
msg_warn "Proceeding on the Proxmox VE host at your own risk!"
}
# ------------------------------------------------------------------------------
# require_debian_like()
#
# - Guard for addons that have no Alpine code path
# - Aborts early instead of failing halfway through with apt/systemd errors
# ------------------------------------------------------------------------------
require_debian_like() {
if is_alpine; then
msg_error "${APP:-This script} does not support Alpine Linux."
msg_error "Please use a Debian or Ubuntu based LXC container."
exit 238
fi
if ! command -v apt-get &>/dev/null; then
msg_error "${APP:-This script} requires a Debian or Ubuntu based system."
exit 238
fi
}
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# pve_check() # pve_check()
# #
@@ -308,6 +374,10 @@ root_check() {
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
pve_check() { pve_check() {
local PVE_VER local PVE_VER
if ! on_pve_host; then
msg_error "${APP:-This script} must be run on the Proxmox VE host."
exit 232
fi
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')" PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
# Check for Proxmox VE 8.x: allow 8.08.9 # Check for Proxmox VE 8.x: allow 8.08.9
@@ -754,7 +824,7 @@ msg_info() {
# Pause mode: Wait for Enter after each step # Pause mode: Wait for Enter after each step
if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then
echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2 echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2
read -r read -r </dev/tty
fi fi
return return
fi fi
@@ -769,7 +839,7 @@ msg_info() {
if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then if [[ "${DEV_MODE_PAUSE:-false}" == "true" ]]; then
stop_spinner stop_spinner
echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2 echo -en "\n${YWB}[PAUSE]${CL} Press Enter to continue..." >&2
read -r read -r </dev/tty
fi fi
} }
@@ -972,6 +1042,39 @@ ensure_tput() {
fi fi
} }
# ------------------------------------------------------------------------------
# reclaim_tty()
#
# - Reclaims the controlling terminal's foreground process group
# - lxc-attach takes the terminal and does not hand it back, leaving us in a
# background process group. Reading from the terminal then returns EIO
# instead of blocking, because SIGTTIN is ignored during recovery - so the
# prompt fails before the user can answer and their keystroke leaks into the
# parent shell. Redirecting to /dev/tty does not help: the rule applies to
# the terminal, not to the file descriptor.
# - pct exec/pull/enter use lxc-attach internally, so the terminal can be taken
# away again at any point. Call this immediately before each interactive
# read, not once after the install.
# - SIGTTOU is ignored inside perl so tcsetpgrp() succeeds instead of stopping
# us. No-op when we already are in the foreground or there is no terminal.
# perl is a hard dependency of Proxmox VE.
# ------------------------------------------------------------------------------
reclaim_tty() {
command -v perl >/dev/null 2>&1 || return 0
[[ -e /dev/tty ]] || return 0
local pgid
pgid=$(ps -o pgid= -p $$ 2>/dev/null | tr -d ' ') || true
perl -e '
use POSIX;
$SIG{TTOU} = "IGNORE";
my $pgid = $ARGV[0] || POSIX::getpgrp();
open(my $t, "+<", "/dev/tty") or exit 1;
POSIX::tcsetpgrp(fileno($t), $pgid) or exit 1;
' "${pgid:-0}" 2>/dev/null || true
}
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# is_alpine() # is_alpine()
# #
@@ -1217,7 +1320,7 @@ prompt_confirm() {
# Interactive prompt with timeout # Interactive prompt with timeout
echo -en "${YW}${message} ${hint} (auto-${default} in ${timeout}s): ${CL}" echo -en "${YW}${message} ${hint} (auto-${default} in ${timeout}s): ${CL}"
if read -t "$timeout" -r response; then if read -t "$timeout" -r response </dev/tty; then
# User provided input # User provided input
response="${response,,}" # lowercase response="${response,,}" # lowercase
case "$response" in case "$response" in
@@ -1310,7 +1413,7 @@ prompt_input() {
# Interactive prompt with timeout # Interactive prompt with timeout
echo -en "${YW}${message}${hint} (auto-default in ${timeout}s): ${CL}" >&2 echo -en "${YW}${message}${hint} (auto-default in ${timeout}s): ${CL}" >&2
if read -t "$timeout" -r response; then if read -t "$timeout" -r response </dev/tty; then
# User provided input (or pressed Enter for empty) # User provided input (or pressed Enter for empty)
if [[ -n "$response" ]]; then if [[ -n "$response" ]]; then
echo "$response" echo "$response"
@@ -1412,7 +1515,7 @@ prompt_input_required() {
echo -en "${YW}${message} (required, timeout ${timeout}s): ${CL}" >&2 echo -en "${YW}${message} (required, timeout ${timeout}s): ${CL}" >&2
if read -t "$timeout" -r response; then if read -t "$timeout" -r response </dev/tty; then
if [[ -z "$response" ]]; then if [[ -z "$response" ]]; then
echo -e "${YW}This field is required. Please enter a value. (attempt ${attempts}/3)${CL}" >&2 echo -e "${YW}This field is required. Please enter a value. (attempt ${attempts}/3)${CL}" >&2
fi fi
@@ -1507,7 +1610,7 @@ prompt_select() {
echo -en "${YW}Select [1-${num_options}] (auto-select ${default} in ${timeout}s): ${CL}" >&2 echo -en "${YW}Select [1-${num_options}] (auto-select ${default} in ${timeout}s): ${CL}" >&2
local response local response
if read -t "$timeout" -r response; then if read -t "$timeout" -r response </dev/tty; then
if [[ -z "$response" ]]; then if [[ -z "$response" ]]; then
# Empty response, use default # Empty response, use default
echo "${options[$((default - 1))]}" echo "${options[$((default - 1))]}"
@@ -1590,7 +1693,7 @@ prompt_password() {
# Interactive prompt with timeout (silent input) # Interactive prompt with timeout (silent input)
echo -en "${YW}${message}${hint} (timeout ${timeout}s): ${CL}" >&2 echo -en "${YW}${message}${hint} (timeout ${timeout}s): ${CL}" >&2
if read -t "$timeout" -rs response; then if read -t "$timeout" -rs response </dev/tty; then
echo "" >&2 # Newline after hidden input echo "" >&2 # Newline after hidden input
if [[ -n "$response" ]]; then if [[ -n "$response" ]]; then
# Validate minimum length # Validate minimum length
+3 -1
View File
@@ -499,7 +499,8 @@ error_handler() {
local response="" local response=""
local read_rc local read_rc
read -t 60 -r response declare -f reclaim_tty >/dev/null 2>&1 && reclaim_tty
read -t 60 -r response </dev/tty
read_rc=$? read_rc=$?
if [[ $read_rc -eq 0 ]]; then if [[ $read_rc -eq 0 ]]; then
if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then if [[ -z "$response" || "$response" =~ ^[Yy]$ ]]; then
@@ -543,6 +544,7 @@ error_handler() {
# read itself failed (e.g. broken/closed stdin, I/O error) rather than # read itself failed (e.g. broken/closed stdin, I/O error) rather than
# timing out - don't guess and destroy the container on a read we # timing out - don't guess and destroy the container on a read we
# couldn't actually capture; keep it since that's the reversible choice. # couldn't actually capture; keep it since that's the reversible choice.
while read -r -t 0.1 -n 1 _ </dev/tty 2>/dev/null; do :; done
echo "" echo ""
if declare -f msg_error >/dev/null 2>&1; then if declare -f msg_error >/dev/null 2>&1; then
msg_error "Could not read your response (stdin error) - keeping container ${CTID} for safety." msg_error "Could not read your response (stdin error) - keeping container ${CTID} for safety."
+1 -1
View File
@@ -201,7 +201,7 @@ network_check() {
# If both IPv4 and IPv6 checks fail, prompt the user # If both IPv4 and IPv6 checks fail, prompt the user
if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then if [[ $ipv4_connected == false && $ipv6_connected == false ]]; then
read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt read -r -p "No Internet detected, would you like to continue anyway? <y/N> " prompt </dev/tty
if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then if [[ "${prompt,,}" =~ ^(y|yes)$ ]]; then
echo -e "${INFO}${RD}Expect Issues Without Internet${CL}" echo -e "${INFO}${RD}Expect Issues Without Internet${CL}"
else else
+110 -84
View File
@@ -1292,14 +1292,17 @@ create_temp_dir() {
# - Copies each given file/directory into a persistent store at # - Copies each given file/directory into a persistent store at
# /opt/<NSAPP>.backup, mirroring its absolute path inside the store, and # /opt/<NSAPP>.backup, mirroring its absolute path inside the store, and
# records it in a manifest so restore_backup needs no arguments. # records it in a manifest so restore_backup needs no arguments.
# - Idempotent: if a store from a previous (failed) run already exists, it is # - Idempotent per path: a path already recorded in the manifest (from this
# left untouched and no new backup is taken. This keeps the last-known-good # run or a previous failed one) is left untouched, keeping the
# data instead of overwriting it with now-partially-updated data on retry. # last-known-good copy instead of overwriting it with now-partially-updated
# data on retry. Any requested path NOT yet in the manifest is backed up
# now and appended - so a manifest left incomplete by an interrupted prior
# run gets completed instead of silently missing paths on restore.
# - Missing source paths are skipped with a warning (not fatal). # - Missing source paths are skipped with a warning (not fatal).
# - Aborts the update on copy failure: if any file/dir cannot be backed up, # - Aborts the update on copy failure: if any file/dir cannot be backed up,
# the half-written store is removed and the script exits, so the update # the script exits before the update runs against unprotected data (the
# never runs against unprotected data (and a retry re-attempts a clean # paths already recorded are left in place, so a retry only redoes the one
# backup rather than skipping it). # that failed).
# #
# restore_backup # restore_backup
# - Copies every path recorded in the manifest back to its origin (replacing # - Copies every path recorded in the manifest back to its origin (replacing
@@ -1318,19 +1321,17 @@ create_backup() {
return 0 return 0
} }
if [[ -f "$manifest" ]]; then if ! mkdir -p "$store" || ! touch "$manifest"; then
msg_ok "Existing backup found at ${store}, skipping backup" msg_error "Backup failed: could not create store at ${store} - aborting update"
return 0 exit 1
fi fi
msg_info "Backing up data" msg_info "Backing up data"
if ! mkdir -p "$store" || ! : >"$manifest"; then
msg_error "Backup failed: could not create store at ${store} - aborting update"
rm -rf "$store"
exit 1
fi
for path in "$@"; do for path in "$@"; do
path="${path%/}" path="${path%/}"
if grep -qxF "$path" "$manifest" 2>/dev/null; then
continue
fi
if [[ ! -e "$path" ]]; then if [[ ! -e "$path" ]]; then
msg_warn "Skipping backup of '${path}' (not found)" msg_warn "Skipping backup of '${path}' (not found)"
continue continue
@@ -1338,7 +1339,6 @@ create_backup() {
dest="${store}/files${path}" dest="${store}/files${path}"
if ! mkdir -p "$(dirname "$dest")" || ! cp -a "$path" "$dest"; then if ! mkdir -p "$(dirname "$dest")" || ! cp -a "$path" "$dest"; then
msg_error "Backup of '${path}' failed - aborting update" msg_error "Backup of '${path}' failed - aborting update"
rm -rf "$store"
exit 1 exit 1
fi fi
echo "$path" >>"$manifest" echo "$path" >>"$manifest"
@@ -1466,7 +1466,7 @@ prompt_for_github_token() {
fi fi
local reply local reply
read -rp "${TAB}Would you like to enter a GitHub Personal Access Token (PAT)? [y/N]: " reply read -rp "${TAB}Would you like to enter a GitHub Personal Access Token (PAT)? [y/N]: " reply </dev/tty
reply="${reply:-n}" reply="${reply:-n}"
if [[ ! "${reply,,}" =~ ^(y|yes)$ ]]; then if [[ ! "${reply,,}" =~ ^(y|yes)$ ]]; then
@@ -1475,7 +1475,7 @@ prompt_for_github_token() {
local token local token
while true; do while true; do
read -rp "${TAB}Enter your GitHub PAT: " token read -rp "${TAB}Enter your GitHub PAT: " token </dev/tty
# Trim leading/trailing whitespace # Trim leading/trailing whitespace
token="$(echo "$token" | xargs)" token="$(echo "$token" | xargs)"
if [[ -z "$token" ]]; then if [[ -z "$token" ]]; then
@@ -2040,8 +2040,9 @@ cleanup_orphaned_sources() {
local basename_file local basename_file
basename_file=$(basename "$sources_file") basename_file=$(basename "$sources_file")
# NEVER remove debian.sources - this is the standard Debian repository # NEVER remove the distro's own base sources file (debian.sources,
if [[ "$basename_file" == "debian.sources" ]]; then # ubuntu.sources, ...)
if [[ "$basename_file" == "$(get_os_info id).sources" ]]; then
continue continue
fi fi
@@ -2113,7 +2114,7 @@ ensure_apt_working() {
# Step 4: More aggressive - remove all third-party sources # Step 4: More aggressive - remove all third-party sources
msg_warn "APT update still failing, removing third-party sources" msg_warn "APT update still failing, removing third-party sources"
find /etc/apt/sources.list.d/ -type f \( -name "*.sources" -o -name "*.list" \) \ find /etc/apt/sources.list.d/ -type f \( -name "*.sources" -o -name "*.list" \) \
! -name "debian.sources" -delete 2>/dev/null || true ! -name "$(get_os_info id).sources" -delete 2>/dev/null || true
# Final attempt # Final attempt
if ! $STD apt update; then if ! $STD apt update; then
@@ -2575,11 +2576,6 @@ _deploy_unpacked_archive() {
local archive="$1" target="$2" workdir="$3" local archive="$1" target="$2" workdir="$3"
local filename="${archive##*/}" local filename="${archive##*/}"
mkdir -p "$target"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
find "${target:?}" -mindepth 1 -delete
fi
if [[ "$filename" == *.zip ]]; then if [[ "$filename" == *.zip ]]; then
ensure_dependencies unzip ensure_dependencies unzip
unzip -q "$archive" -d "$workdir" || { unzip -q "$archive" -d "$workdir" || {
@@ -2606,38 +2602,44 @@ _deploy_unpacked_archive() {
return 65 return 65
fi fi
local top_entries inner_dir local top_entries inner_dir source_dir
top_entries=$(find "$workdir" -mindepth 1 -maxdepth 1) top_entries=$(find "$workdir" -mindepth 1 -maxdepth 1)
if [[ "$(echo "$top_entries" | wc -l)" -eq 1 && -d "$top_entries" ]]; then if [[ "$(echo "$top_entries" | wc -l)" -eq 1 && -d "$top_entries" ]]; then
inner_dir="$top_entries" inner_dir="$top_entries"
shopt -s dotglob nullglob source_dir="$inner_dir"
if compgen -G "$inner_dir/*" >/dev/null; then
cp -r "$inner_dir"/* "$target/" || {
msg_error "Failed to copy contents from $inner_dir to $target"
shopt -u dotglob nullglob
return 252
}
else
msg_error "Inner directory is empty: $inner_dir"
shopt -u dotglob nullglob
return 252
fi
shopt -u dotglob nullglob
else else
shopt -s dotglob nullglob source_dir="$workdir"
if compgen -G "$workdir/*" >/dev/null; then fi
cp -r "$workdir"/* "$target/" || {
msg_error "Failed to copy contents to $target" shopt -s dotglob nullglob
shopt -u dotglob nullglob if ! compgen -G "$source_dir/*" >/dev/null; then
return 252 if [[ -n "$inner_dir" ]]; then
} msg_error "Inner directory is empty: $inner_dir"
else else
msg_error "Unpacked archive is empty" msg_error "Unpacked archive is empty"
shopt -u dotglob nullglob
return 252
fi fi
shopt -u dotglob nullglob shopt -u dotglob nullglob
return 252
fi fi
# <target> is only touched once the payload is known good. Wiping earlier left
# CLEAN_INSTALL callers with an empty target directory whenever the download
# was truncated, the archive was unreadable, or it unpacked to nothing.
mkdir -p "$target"
if [[ "${CLEAN_INSTALL:-0}" == "1" ]]; then
find "${target:?}" -mindepth 1 -delete
fi
if ! cp -r "$source_dir"/* "$target/"; then
if [[ -n "$inner_dir" ]]; then
msg_error "Failed to copy contents from $inner_dir to $target"
else
msg_error "Failed to copy contents to $target"
fi
shopt -u dotglob nullglob
return 252
fi
shopt -u dotglob nullglob
return 0 return 0
} }
@@ -3973,7 +3975,7 @@ _gh_scan_older_releases() {
local use_fallback="y" local use_fallback="y"
if [[ -t 0 ]]; then if [[ -t 0 ]]; then
msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset." msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset."
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback || use_fallback="y" read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback </dev/tty || use_fallback="y"
use_fallback="${use_fallback:-y}" use_fallback="${use_fallback:-y}"
fi fi
@@ -4627,6 +4629,53 @@ _docker_is_noninteractive() {
[[ "${DOCKER_NONINTERACTIVE:-}" == "1" || "${DOCKER_NONINTERACTIVE:-}" == "true" || "${DOCKER_NONINTERACTIVE:-}" == "TRUE" ]] || [[ ! -t 0 ]] [[ "${DOCKER_NONINTERACTIVE:-}" == "1" || "${DOCKER_NONINTERACTIVE:-}" == "true" || "${DOCKER_NONINTERACTIVE:-}" == "TRUE" ]] || [[ ! -t 0 ]]
} }
# ------------------------------------------------------------------------------
# ensure_docker()
#
# - Docker precondition for addon scripts that ship a compose stack
# - Reuses an existing installation, otherwise offers to install Docker
# (Debian/Ubuntu via setup_docker, Alpine via apk)
# - Aborts when the user declines or Compose is unavailable afterwards
# ------------------------------------------------------------------------------
ensure_docker() {
if command -v docker &>/dev/null; then
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
if docker compose version &>/dev/null; then
msg_ok "Docker Compose is available"
return 0
fi
msg_error "Docker Compose plugin is not available. Please install it."
exit 237
fi
msg_warn "Docker is not installed."
echo -n "${TAB:- }Install Docker now? (y/N): "
local install_docker_prompt
read -r install_docker_prompt
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_error "Docker is required for ${APP:-this script}. Exiting."
exit 254
fi
if is_alpine; then
msg_info "Installing Docker"
$STD apk add --no-cache docker docker-cli-compose
$STD rc-update add docker default
$STD rc-service docker start
msg_ok "Installed Docker"
else
setup_docker || {
msg_error "Docker installation failed."
exit 237
}
fi
if ! command -v docker &>/dev/null || ! docker compose version &>/dev/null; then
msg_error "Docker or the Compose plugin is still unavailable after installation."
exit 237
fi
}
setup_docker() { setup_docker() {
local docker_installed=false local docker_installed=false
local USE_DOCKER_REPO="${USE_DOCKER_REPO:-true}" local USE_DOCKER_REPO="${USE_DOCKER_REPO:-true}"
@@ -4753,8 +4802,8 @@ EOF
# Container Update Check # Container Update Check
# - Skipped entirely when running unattended / non-interactive # - Skipped entirely when running unattended / non-interactive
# - Compose-managed containers: offered via Y/N → docker compose pull + up -d # - Lists containers with a newer image available and the command to update
# - Standalone containers: offered via Y/N → image pull only (no stop/rm) # them; does not pull/recreate anything itself
if [ "$docker_installed" = true ] && ! _docker_is_noninteractive; then if [ "$docker_installed" = true ] && ! _docker_is_noninteractive; then
msg_info "Checking for container updates" msg_info "Checking for container updates"
@@ -4792,41 +4841,14 @@ EOF
if [[ ${#compose_updates[@]} -eq 0 && ${#standalone_updates[@]} -eq 0 ]]; then if [[ ${#compose_updates[@]} -eq 0 && ${#standalone_updates[@]} -eq 0 ]]; then
msg_ok "All containers are up-to-date" msg_ok "All containers are up-to-date"
else else
local reply msg_warn "Updates available (not applied automatically):"
for entry in "${compose_updates[@]}"; do for entry in "${compose_updates[@]}"; do
IFS='|' read -r name image compose_workdir compose_service <<<"$entry" IFS='|' read -r name image compose_workdir compose_service <<<"$entry"
reply="" echo -e "${TAB3}${name} (${image}) — update via: cd ${compose_workdir} && docker compose pull ${compose_service} && docker compose up -d ${compose_service}"
if read -r -t 60 -p "${TAB3}Update ${name} (${image}) via Compose? <y/N> (auto-no in 60s): " reply; then
echo ""
else
echo ""
fi
if [[ "${reply,,}" =~ ^(y|yes)$ ]]; then
msg_info "Updating $name"
if (cd "$compose_workdir" && $STD docker compose pull "$compose_service" && $STD docker compose up -d "$compose_service"); then
msg_ok "Updated $name"
else
msg_warn "Could not update $name — try manually in $compose_workdir"
fi
fi
done done
for entry in "${standalone_updates[@]}"; do for entry in "${standalone_updates[@]}"; do
IFS='|' read -r name image <<<"$entry" IFS='|' read -r name image <<<"$entry"
reply="" echo -e "${TAB3}${name} (${image}) — update via: docker pull ${image} && docker restart ${name}"
if read -r -t 60 -p "${TAB3}Pull new image for ${name} (${image})? <y/N> (auto-no in 60s): " reply; then
echo ""
else
echo ""
fi
if [[ "${reply,,}" =~ ^(y|yes)$ ]]; then
msg_info "Pulling new image for $name"
if $STD docker pull "$image"; then
msg_ok "New image available for $name — recreate the container to apply the update"
else
msg_warn "Failed to pull image for $name"
fi
fi
done done
fi fi
fi fi
@@ -5409,7 +5431,7 @@ setup_hwaccel() {
# Read with 60 second timeout # Read with 60 second timeout
local selection="" local selection=""
echo -n "Select GPU(s) to configure (1-${gpu_count}, A=all) [timeout 60s, default=all]: " echo -n "Select GPU(s) to configure (1-${gpu_count}, A=all) [timeout 60s, default=all]: "
if read -r -t 60 selection; then if read -r -t 60 selection </dev/tty; then
selection="${selection^^}" # uppercase selection="${selection^^}" # uppercase
else else
echo "" echo ""
@@ -5457,7 +5479,7 @@ setup_hwaccel() {
echo "" echo ""
msg_custom "🎮" "${GN}" "NVIDIA GPU passthrough detected" msg_custom "🎮" "${GN}" "NVIDIA GPU passthrough detected"
local nvidia_reply="" local nvidia_reply=""
read -r -t 60 -p "${TAB3}⚙️ Install NVIDIA driver libraries in the container? [Y/n] (auto-yes in 60s): " nvidia_reply || nvidia_reply="" read -r -t 60 -p "${TAB3}⚙️ Install NVIDIA driver libraries in the container? [Y/n] (auto-yes in 60s): " nvidia_reply </dev/tty || nvidia_reply=""
case "${nvidia_reply,,}" in case "${nvidia_reply,,}" in
n | no) install_nvidia_drivers="no" ;; n | no) install_nvidia_drivers="no" ;;
*) install_nvidia_drivers="yes" ;; *) install_nvidia_drivers="yes" ;;
@@ -7684,6 +7706,10 @@ setup_nodejs() {
fi fi
fi fi
if [[ "$(npm -v 2>/dev/null | cut -d. -f1)" -ge 11 ]]; then
$STD npm config set dangerously-allow-all-scripts true --location=global 2>/dev/null || true
fi
# Set a safe default heap limit for Node.js builds if not explicitly provided. # Set a safe default heap limit for Node.js builds if not explicitly provided.
# Priority: # Priority:
# 1) NODE_OPTIONS (caller/user override) # 1) NODE_OPTIONS (caller/user override)
@@ -9755,7 +9781,7 @@ _gl_scan_older_releases() {
local use_fallback="y" local use_fallback="y"
if [[ -t 0 ]]; then if [[ -t 0 ]]; then
msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset." msg_warn "Release ${skip_tag} has no matching asset. Previous release ${rel_tag} has a compatible asset."
read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback || use_fallback="y" read -rp "Use version ${rel_tag} instead? [Y/n] (auto-yes in 60s): " -t 60 use_fallback </dev/tty || use_fallback="y"
use_fallback="${use_fallback:-y}" use_fallback="${use_fallback:-y}"
fi fi
@@ -7,8 +7,13 @@
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1 if [[ -f /etc/alpine-release ]]; then
apt-get install -y curl >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -20,6 +25,7 @@ declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "actual-budget
set -Eeuo pipefail set -Eeuo pipefail
trap 'error_handler' ERR trap 'error_handler' ERR
load_functions load_functions
require_debian_like
# ============================================================================== # ==============================================================================
# CONFIGURATION # CONFIGURATION
@@ -31,14 +37,6 @@ INSTALL_PATH="/opt/actual-budget-prometheus-exporter"
CONFIG_PATH="/opt/actual-budget-prometheus-exporter.env" CONFIG_PATH="/opt/actual-budget-prometheus-exporter.env"
SERVICE_PATH="/etc/systemd/system/actual-budget-prometheus-exporter.service" SERVICE_PATH="/etc/systemd/system/actual-budget-prometheus-exporter.service"
# ==============================================================================
# OS DETECTION
# ==============================================================================
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
exit 238
fi
# ============================================================================== # ==============================================================================
# UNINSTALL # UNINSTALL
# ============================================================================== # ==============================================================================
+56 -37
View File
@@ -6,39 +6,45 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://netbird.io/ | Github: https://github.com/netbirdio/netbird # Source: https://netbird.io/ | Github: https://github.com/netbirdio/netbird
function header_info { APP="add-netbird-lxc"
clear APP_TYPE="addon"
cat <<"EOF"
_ __ __ ____ _ __
/ | / /__ / /_/ __ )(_)________/ /
/ |/ / _ \/ __/ __ / / ___/ __ /
/ /| / __/ /_/ /_/ / / / / /_/ /
/_/ |_/\___/\__/_____/_/_/ \__,_/
EOF if ! command -v curl &>/dev/null; then
} printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
header_info if [[ -f /etc/alpine-release ]]; then
set -e apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
# Telemetry else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-netbird-lxc" "addon" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-netbird-lxc" "addon"
# Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
header_info
require_pve_host
while true; do while true; do
read -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)?" yn read -r -p "This will add NetBird to an existing LXC Container ONLY. Proceed(y/n)? " yn
case $yn in case $yn in
[Yy]*) break ;; [Yy]*) break ;;
[Nn]*) exit ;; [Nn]*) exit 0 ;;
*) echo "Please answer yes or no." ;; *) echo "Please answer yes or no." ;;
esac esac
done done
header_info
echo "Loading..."
function msg() { echo -e "Loading container list..."
local TEXT="$1"
echo -e "$TEXT"
}
NODE=$(hostname) NODE=$(hostname)
MSG_MAX_LENGTH=0 MSG_MAX_LENGTH=0
@@ -61,37 +67,51 @@ done
LXC_STATUS=$(pct status "$CTID" | awk '{print $2}') LXC_STATUS=$(pct status "$CTID" | awk '{print $2}')
if [[ "$LXC_STATUS" != "running" ]]; then if [[ "$LXC_STATUS" != "running" ]]; then
msg "\e[1;33m The container $CTID is not running. Starting it now...\e[0m" msg_info "Container $CTID is not running. Starting it now..."
pct start "$CTID" pct start "$CTID"
while [[ "$(pct status "$CTID" | awk '{print $2}')" != "running" ]]; do while [[ "$(pct status "$CTID" | awk '{print $2}')" != "running" ]]; do
msg "\e[1;33m Waiting for the container to start...\e[0m" msg_info "Waiting for the container to start..."
sleep 2 sleep 2
done done
msg "\e[1;32m Container $CTID is now running.\e[0m" msg_ok "Container $CTID is now running."
fi fi
DISTRO=$(pct exec "$CTID" -- cat /etc/os-release | grep -w "ID" | cut -d'=' -f2 | tr -d '"') DISTRO=$(pct exec "$CTID" -- cat /etc/os-release | grep -w "ID" | cut -d'=' -f2 | tr -d '"')
if [[ "$DISTRO" != "debian" && "$DISTRO" != "ubuntu" ]]; then if [[ "$DISTRO" != "debian" && "$DISTRO" != "ubuntu" ]]; then
msg "\e[1;31m Error: This script only supports Debian or Ubuntu LXC containers. Detected: $DISTRO. Aborting...\e[0m" msg_error "This script only supports Debian or Ubuntu LXC containers. Detected: $DISTRO. Aborting..."
exit 238 exit 238
fi fi
CTID_CONFIG_PATH=/etc/pve/lxc/${CTID}.conf CTID_CONFIG_PATH="/etc/pve/lxc/${CTID}.conf"
cat <<EOF >>$CTID_CONFIG_PATH cat <<EOF >>"$CTID_CONFIG_PATH"
lxc.cgroup2.devices.allow: c 10:200 rwm lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file
EOF EOF
header_info
msg "Installing NetBird..." msg_info "Installing NetBird"
pct exec "$CTID" -- bash -c ' pct exec "$CTID" -- bash -c '
set -e
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
apt-get update -qq apt-get update -qq
apt-get install -y curl >/dev/null apt-get install -y curl >/dev/null
fi fi
apt install -y ca-certificates gpg &>/dev/null apt-get install -y ca-certificates gpg &>/dev/null
curl -fsSL "https://pkgs.netbird.io/debian/public.key" | gpg --dearmor >/usr/share/keyrings/netbird-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/netbird-archive-keyring.gpg] https://pkgs.netbird.io/debian stable main" >/etc/apt/sources.list.d/netbird.list # Reuse the shared repository helper instead of hand-rolling the sources entry
apt-get update &>/dev/null source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
load_functions
# Drop the legacy keyring from the pre-deb822 layout
rm -f /usr/share/keyrings/netbird-archive-keyring.gpg
setup_deb822_repo \
"netbird" \
"https://pkgs.netbird.io/debian/public.key" \
"https://pkgs.netbird.io/debian" \
"stable" \
"main"
apt-get install -y netbird-ui &>/dev/null apt-get install -y netbird-ui &>/dev/null
if systemctl list-unit-files docker.service &>/dev/null; then if systemctl list-unit-files docker.service &>/dev/null; then
mkdir -p /etc/systemd/system/netbird.service.d mkdir -p /etc/systemd/system/netbird.service.d
@@ -103,6 +123,5 @@ OVERRIDE
systemctl daemon-reload systemctl daemon-reload
fi fi
' '
msg "\e[1;32m ✔ Installed NetBird.\e[0m" msg_ok "Installed NetBird."
sleep 2 echo -e "${YW}Reboot ${CTID} LXC${CL} to apply the changes, then run 'netbird up' in the LXC console"
msg "\e[1;31m Reboot ${CTID} LXC to apply the changes, then run netbird up in the LXC console\e[0m"
+37 -35
View File
@@ -5,35 +5,34 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://tailscale.com/ | Github: https://github.com/tailscale/tailscale # Source: https://tailscale.com/ | Github: https://github.com/tailscale/tailscale
set -Eeuo pipefail APP="add-tailscale-lxc"
trap 'echo -e "\n[ERROR] in line $LINENO: exit code $?"' ERR APP_TYPE="addon"
function header_info() { if ! command -v curl &>/dev/null; then
clear printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
cat <<"EOF" if [[ -f /etc/alpine-release ]]; then
______ _ __ __ apk update >/dev/null 2>&1
/_ __/___ _(_) /_____________ _/ /__ apk add --no-cache curl >/dev/null 2>&1
/ / / __ `/ / / ___/ ___/ __ `/ / _ \ else
/ / / /_/ / / (__ ) /__/ /_/ / / __/ apt-get update >/dev/null 2>&1
/_/ \__,_/_/_/____/\___/\__,_/_/\___/ apt-get install -y curl >/dev/null 2>&1
fi
EOF fi
} source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
function msg_info() { echo -e " \e[1;36m➤\e[0m $1"; } source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
function msg_ok() { echo -e " \e[1;32m✔\e[0m $1"; }
function msg_error() { echo -e " \e[1;31m✖\e[0m $1"; }
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-tailscale-lxc" "addon" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "add-tailscale-lxc" "addon"
header_info # Enable error handling
set -Eeuo pipefail
trap 'error_handler' ERR
if ! command -v pveversion &>/dev/null; then # Initialize all core functions (colors, formatting, icons, STD mode)
msg_error "This script must be run on the Proxmox VE host (not inside an LXC container)" load_functions
exit 232
fi header_info
require_pve_host
while true; do while true; do
read -rp "This will add Tailscale to an existing LXC Container ONLY. Proceed (y/n)? " yn read -rp "This will add Tailscale to an existing LXC Container ONLY. Proceed (y/n)? " yn
@@ -44,7 +43,6 @@ while true; do
esac esac
done done
header_info
msg_info "Loading container list..." msg_info "Loading container list..."
NODE=$(hostname) NODE=$(hostname)
@@ -73,10 +71,9 @@ CTID_CONFIG_PATH="/etc/pve/lxc/${CTID}.conf"
grep -q "lxc.cgroup2.devices.allow: c 10:200 rwm" "$CTID_CONFIG_PATH" || echo "lxc.cgroup2.devices.allow: c 10:200 rwm" >>"$CTID_CONFIG_PATH" grep -q "lxc.cgroup2.devices.allow: c 10:200 rwm" "$CTID_CONFIG_PATH" || echo "lxc.cgroup2.devices.allow: c 10:200 rwm" >>"$CTID_CONFIG_PATH"
grep -q "lxc.mount.entry: /dev/net/tun" "$CTID_CONFIG_PATH" || echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file" >>"$CTID_CONFIG_PATH" grep -q "lxc.mount.entry: /dev/net/tun" "$CTID_CONFIG_PATH" || echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file" >>"$CTID_CONFIG_PATH"
header_info
msg_info "Installing Tailscale in CT $CTID" msg_info "Installing Tailscale in CT $CTID"
pct exec "$CTID" -- sh -c ' pct exec "$CTID" -- bash -c '
set -e set -e
# Detect OS inside container # Detect OS inside container
@@ -144,16 +141,21 @@ else
apt-get install -y curl >/dev/null apt-get install -y curl >/dev/null
fi fi
# Ensure keyrings directory exists # Reuse the shared repository helper instead of hand-rolling the sources entry
mkdir -p /usr/share/keyrings source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
load_functions
curl -fsSL "https://pkgs.tailscale.com/stable/${ID}/${VERSION_CODENAME}.noarmor.gpg" \ # Drop the legacy keyring from the pre-deb822 layout
| tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null rm -f /usr/share/keyrings/tailscale-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${ID} ${VERSION_CODENAME} main" \ setup_deb822_repo \
>/etc/apt/sources.list.d/tailscale.list "tailscale" \
"https://pkgs.tailscale.com/stable/${ID}/${VERSION_CODENAME}.noarmor.gpg" \
"https://pkgs.tailscale.com/stable/${ID}" \
"${VERSION_CODENAME}" \
"main"
apt-get update -qq
apt-get install -y tailscale >/dev/null apt-get install -y tailscale >/dev/null
if [ -f /tmp/resolv.conf.backup ]; then if [ -f /tmp/resolv.conf.backup ]; then
@@ -168,4 +170,4 @@ TAGS="${TAGS:+$TAGS; }tailscale"
pct set "$CTID" -tags "$TAGS" pct set "$CTID" -tags "$TAGS"
msg_ok "Tailscale installed on CT $CTID" msg_ok "Tailscale installed on CT $CTID"
msg_info "Reboot the container, then run 'tailscale up' inside the container to activate." echo -e "${YW}Reboot the container${CL}, then run 'tailscale up' inside the container to activate."
+13 -40
View File
@@ -7,8 +7,9 @@
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
if [[ -f "/etc/alpine-release" ]]; then if [[ -f /etc/alpine-release ]]; then
apk -U add curl >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else else
apt-get update >/dev/null 2>&1 apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1 apt-get install -y curl >/dev/null 2>&1
@@ -36,28 +37,6 @@ DEFAULT_PORT=8080
# Initialize all core functions (colors, formatting, icons, STD mode) # Initialize all core functions (colors, formatting, icons, STD mode)
load_functions load_functions
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
___ __ ____ __ _____
/ | ____/ /___ ___ ______ __________/ / / / /___ ____ ___ ___ / ___/__ ______ _____
/ /| |/ __ / __ `/ / / / __ `/ ___/ __ / /_/ / __ \/ __ `__ \/ _ \ \__ \/ / / / __ \/ ___/
/ ___ / /_/ / /_/ / /_/ / /_/ / / / /_/ / __ / /_/ / / / / / / __/ ___/ / /_/ / / / / /__
/_/ |_\__,_/\__, /\__,_/\__,_/_/ \__,_/_/ /_/\____/_/ /_/ /_/\___/ /____/\__, /_/ /_/\___/
/____/ /____/
EOF
}
# ==============================================================================
# HELPER FUNCTIONS
# ==============================================================================
get_ip() {
hostname -I 2>/dev/null | awk '{print $1}' || ip -4 addr show scope global 2>/dev/null | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1 || echo "127.0.0.1"
}
# ============================================================================== # ==============================================================================
# OS DETECTION # OS DETECTION
# ============================================================================== # ==============================================================================
@@ -114,16 +93,12 @@ function update() {
fi fi
msg_ok "Stopped service" msg_ok "Stopped service"
msg_info "Backing up configuration" BACKUP_DIR="/opt/adguardhome-sync_backup"
cp "$CONFIG_PATH" /tmp/adguardhome-sync.yaml.bak 2>/dev/null || true create_backup "$CONFIG_PATH"
msg_ok "Backed up configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_amd64.tar.gz" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_$(arch_resolve).tar.gz"
msg_info "Restoring configuration" restore_backup
cp /tmp/adguardhome-sync.yaml.bak "$CONFIG_PATH" 2>/dev/null || true
rm -f /tmp/adguardhome-sync.yaml.bak
msg_ok "Restored configuration"
msg_info "Starting service" msg_info "Starting service"
if [[ "$OS" == "Alpine" ]]; then if [[ "$OS" == "Alpine" ]]; then
@@ -141,10 +116,7 @@ function update() {
# INSTALL # INSTALL
# ============================================================================== # ==============================================================================
function install() { function install() {
local ip fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_$(arch_resolve).tar.gz"
ip=$(get_ip)
fetch_and_deploy_gh_release "adguardhome-sync" "bakito/adguardhome-sync" "prebuild" "latest" "$INSTALL_PATH" "adguardhome-sync_*_linux_amd64.tar.gz"
# Gather configuration from user # Gather configuration from user
echo "" echo ""
@@ -153,7 +125,7 @@ function install() {
echo "" echo ""
# Origin instance # Origin instance
echo -e "${YW}── Origin (Primary) Instance ──${CL}" echo -e "${YW}── Origin (Primary) Instance ──${CL}"
local origin_url origin_user origin_pass local origin_url origin_user origin_pass
read -rp " Origin URL (e.g., http://192.168.1.1): " origin_url read -rp " Origin URL (e.g., http://192.168.1.1): " origin_url
origin_url="${origin_url:-http://192.168.1.1}" origin_url="${origin_url:-http://192.168.1.1}"
@@ -167,7 +139,7 @@ function install() {
# Replica instance # Replica instance
echo "" echo ""
echo -e "${YW}── Replica Instance ──${CL}" echo -e "${YW}── Replica Instance ──${CL}"
local replica_url replica_user replica_pass local replica_url replica_user replica_pass
read -rp " Replica URL (e.g., http://192.168.1.2): " replica_url read -rp " Replica URL (e.g., http://192.168.1.2): " replica_url
replica_url="${replica_url:-http://192.168.1.2}" replica_url="${replica_url:-http://192.168.1.2}"
@@ -293,7 +265,7 @@ UPDATEEOF
echo "" echo ""
msg_ok "${APP} installed successfully" msg_ok "${APP} installed successfully"
msg_ok "Web UI: ${BL}http://${ip}:${DEFAULT_PORT}${CL}" msg_ok "Web UI: ${BL}http://${IP}:${DEFAULT_PORT}${CL}"
msg_ok "Config: ${BL}${CONFIG_PATH}${CL}" msg_ok "Config: ${BL}${CONFIG_PATH}${CL}"
echo "" echo ""
msg_warn "Edit the config file to add your AdGuardHome instances!" msg_warn "Edit the config file to add your AdGuardHome instances!"
@@ -319,7 +291,8 @@ fi
header_info header_info
IP=$(get_ip) get_lxc_ip
IP="$LOCAL_IP"
# Check if already installed # Check if already installed
if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/adguardhome-sync" ]]; then if [[ -d "$INSTALL_PATH" && -f "$INSTALL_PATH/adguardhome-sync" ]]; then
+74 -70
View File
@@ -1,52 +1,40 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Copyright (c) 2021-2026 tteck # Copyright (c) 2021-2026 tteck
# Author: tteck (tteckster) # Author: tteck (tteckster)
# License: MIT # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
function header_info { APP="all-templates"
clear APP_TYPE="addon"
cat <<"EOF"
___ ____ ______ __ __
/ _ | / / / /_ __/__ __ _ ___ / /__ _/ /____ ___
/ __ |/ / / / / / -_) ' \/ _ \/ / _ `/ __/ -_|_-<
/_/ |_/_/_/ /_/ \__/_/_/_/ .__/_/\_,_/\__/\__/___/
/_/
EOF
}
set -eEuo pipefail if ! command -v curl &>/dev/null; then
shopt -s expand_aliases printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
alias die='EXIT=$? LINE=$LINENO error_exit' if [[ -f /etc/alpine-release ]]; then
trap die ERR apk update >/dev/null 2>&1
function error_exit() { apk add --no-cache curl >/dev/null 2>&1
trap - ERR else
local DEFAULT='Unknown failure occured.' apt-get update >/dev/null 2>&1
local REASON="\e[97m${1:-$DEFAULT}\e[39m" apt-get install -y curl >/dev/null 2>&1
local FLAG="\e[91m[ERROR] \e[93m$EXIT@$LINE" fi
msg "$FLAG $REASON" 1>&2 fi
[ ! -z ${CTID-} ] && cleanup_ctid source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
exit $EXIT source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
} source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
function warn() {
local REASON="\e[97m$1\e[39m"
local FLAG="\e[93m[WARNING]\e[39m"
msg "$FLAG $REASON"
}
function info() {
local REASON="$1"
local FLAG="\e[36m[INFO]\e[39m"
msg "$FLAG $REASON"
}
function msg() {
local TEXT="$1"
echo -e "$TEXT"
}
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "all-templates" "addon" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "all-templates" "addon"
# Enable error handling; destroy any partially-created container before reporting the error
set -Eeuo pipefail
function _cleanup_on_error() {
local ec=$? cmd="$BASH_COMMAND"
[[ -n "${CTID:-}" ]] && cleanup_ctid
error_handler "$ec" "$cmd"
}
trap '_cleanup_on_error' ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
function validate_container_id() { function validate_container_id() {
local ctid="$1" local ctid="$1"
# Check if ID is numeric # Check if ID is numeric
@@ -79,12 +67,14 @@ function cleanup_ctid() {
fi fi
} }
header_info
require_pve_host
# Stop Proxmox VE Monitor-All if running # Stop Proxmox VE Monitor-All if running
if systemctl is-active -q ping-instances.service; then if systemctl is-active -q ping-instances.service; then
systemctl stop ping-instances.service systemctl stop ping-instances.service
fi fi
header_info msg_info "Loading"
echo "Loading..."
pveam update >/dev/null 2>&1 pveam update >/dev/null 2>&1
whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Templates" --yesno "This will allow for the creation of one of the many Template LXC Containers. Proceed?" 10 68 whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Templates" --yesno "This will allow for the creation of one of the many Template LXC Containers. Proceed?" 10 68
TEMPLATE_MENU=() TEMPLATE_MENU=()
@@ -97,8 +87,8 @@ done < <(pveam available)
TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Template LXCs" --radiolist "\nSelect a Template LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 10 "${TEMPLATE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"') TEMPLATE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "All Template LXCs" --radiolist "\nSelect a Template LXC to create:\n" 16 $((MSG_MAX_LENGTH + 58)) 10 "${TEMPLATE_MENU[@]}" 3>&1 1>&2 2>&3 | tr -d '"')
[ -z "$TEMPLATE" ] && { [ -z "$TEMPLATE" ] && {
whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Template LXC Selected" --msgbox "It appears that no Template LXC container was selected" 10 68 whiptail --backtitle "Proxmox VE Helper Scripts" --title "No Template LXC Selected" --msgbox "It appears that no Template LXC container was selected" 10 68
msg "Done" echo "Done"
exit exit 0
} }
# Setup script environment # Setup script environment
@@ -108,9 +98,9 @@ PASS="$(openssl rand -base64 8)"
# Get valid Container ID # Get valid Container ID
CTID=$(pvesh get /cluster/nextid) CTID=$(pvesh get /cluster/nextid)
if ! validate_container_id "$CTID"; then if ! validate_container_id "$CTID"; then
warn "Container ID $CTID is already in use." msg_warn "Container ID $CTID is already in use."
CTID=$(get_valid_container_id "$CTID") CTID=$(get_valid_container_id "$CTID")
info "Using next available ID: $CTID" msg_info "Using next available ID: $CTID"
fi fi
PCT_OPTIONS=" PCT_OPTIONS="
@@ -142,7 +132,10 @@ function select_storage() {
CONTENT='vztmpl' CONTENT='vztmpl'
CONTENT_LABEL='Container template' CONTENT_LABEL='Container template'
;; ;;
*) false || die "Invalid storage class." ;; *)
msg_error "Invalid storage class."
exit 112
;;
esac esac
# Query all storage locations # Query all storage locations
@@ -161,8 +154,9 @@ function select_storage() {
# Select storage location # Select storage location
if [ $((${#MENU[@]} / 3)) -eq 0 ]; then if [ $((${#MENU[@]} / 3)) -eq 0 ]; then
warn "'$CONTENT_LABEL' needs to be selected for at least one storage location." msg_warn "'$CONTENT_LABEL' needs to be selected for at least one storage location."
die "Unable to detect valid storage location." msg_error "Unable to detect valid storage location."
if [[ "$CONTENT" == "rootdir" ]]; then exit 119; else exit 120; fi
elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then elif [ $((${#MENU[@]} / 3)) -eq 1 ]; then
printf ${MENU[0]} printf ${MENU[0]}
else else
@@ -171,43 +165,54 @@ function select_storage() {
STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \ STORAGE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Storage Pools" --radiolist \
"Which storage pool would you like to use for the ${CONTENT_LABEL,,}?\n\n" \ "Which storage pool would you like to use for the ${CONTENT_LABEL,,}?\n\n" \
16 $(($MSG_MAX_LENGTH + 23)) 6 \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \
"${MENU[@]}" 3>&1 1>&2 2>&3) || die "Menu aborted." "${MENU[@]}" 3>&1 1>&2 2>&3) || {
msg_error "Menu aborted."
exit 254
}
done done
printf $STORAGE printf $STORAGE
fi fi
} }
header_info
# Get template storage # Get template storage
TEMPLATE_STORAGE=$(select_storage template) TEMPLATE_STORAGE=$(select_storage template)
info "Using '$TEMPLATE_STORAGE' for template storage." msg_info "Using '$TEMPLATE_STORAGE' for template storage."
# Get container storage # Get container storage
CONTAINER_STORAGE=$(select_storage container) CONTAINER_STORAGE=$(select_storage container)
info "Using '$CONTAINER_STORAGE' for container storage." msg_info "Using '$CONTAINER_STORAGE' for container storage."
# Download template # Download template
msg "Downloading LXC template (Patience)..." msg_info "Downloading LXC template (Patience)"
pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || die "A problem occured while downloading the LXC template." pveam download $TEMPLATE_STORAGE $TEMPLATE >/dev/null || {
msg_error "A problem occured while downloading the LXC template."
exit 222
}
msg_ok "Downloaded LXC template"
# Create variable for 'pct' options # Create variable for 'pct' options
PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}}) PCT_OPTIONS=(${PCT_OPTIONS[@]:-${DEFAULT_PCT_OPTIONS[@]}})
[[ " ${PCT_OPTIONS[@]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8}) [[ " ${PCT_OPTIONS[*]} " =~ " -rootfs " ]] || PCT_OPTIONS+=(-rootfs $CONTAINER_STORAGE:${PCT_DISK_SIZE:-8})
# Create LXC # Create LXC
msg "Creating LXC container..." msg_info "Creating LXC container"
pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} ${PCT_OPTIONS[@]} >/dev/null || pct create $CTID ${TEMPLATE_STORAGE}:vztmpl/${TEMPLATE} "${PCT_OPTIONS[@]}" >/dev/null || {
die "A problem occured while trying to create container." msg_error "A problem occured while trying to create container."
exit 209
}
msg_ok "Created LXC container"
# Save password # Save password
echo "$NAME password: ${PASS}" >>~/$NAME.creds # file is located in the Proxmox root directory echo "$NAME password: ${PASS}" >>~/$NAME.creds # file is located in the Proxmox root directory
# Start container # Start container
msg "Starting LXC Container..." msg_info "Starting LXC Container"
pct start "$CTID" pct start "$CTID"
sleep 5 sleep 5
msg_ok "Started LXC Container"
# Get container IP # Get container IP
set +eEuo pipefail set +Eeuo pipefail
max_attempts=5 max_attempts=5
attempt=1 attempt=1
IP="" IP=""
@@ -216,30 +221,29 @@ while [[ $attempt -le $max_attempts ]]; do
if [[ -n $IP ]]; then if [[ -n $IP ]]; then
break break
else else
warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..." msg_warn "Attempt $attempt: IP address not found. Pausing for 5 seconds..."
sleep 5 sleep 5
((attempt++)) ((attempt++))
fi fi
done done
if [[ -z $IP ]]; then if [[ -z $IP ]]; then
warn "Maximum number of attempts reached. IP address not found." msg_warn "Maximum number of attempts reached. IP address not found."
IP="NOT FOUND" IP="NOT FOUND"
fi fi
set -eEuo pipefail set -Eeuo pipefail
# Start Proxmox VE Monitor-All if available # Start Proxmox VE Monitor-All if available
if [[ -f /etc/systemd/system/ping-instances.service ]]; then if [[ -f /etc/systemd/system/ping-instances.service ]]; then
systemctl start ping-instances.service systemctl start ping-instances.service
fi fi
# Success message # Success message
header_info
echo echo
info "LXC container '$CTID' was successfully created, and its IP address is ${IP}." msg_ok "LXC container '$CTID' was successfully created, and its IP address is ${IP}."
echo echo
info "Proceed to the LXC console to complete the setup." echo -e "${YW}Proceed to the LXC console to complete the setup.${CL}"
echo echo
info "login: root" echo -e "${YW}login: root${CL}"
info "password: $PASS" echo -e "${YW}password: $PASS${CL}"
echo echo
+9 -33
View File
@@ -6,8 +6,13 @@
# Source: https://github.com/getarcaneapp/arcane # Source: https://github.com/getarcaneapp/arcane
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1 if [[ -f /etc/alpine-release ]]; then
apt-get install -y curl >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -32,21 +37,6 @@ DEFAULT_PORT=3552
# Initialize all core functions (colors, formatting, icons, STD mode) # Initialize all core functions (colors, formatting, icons, STD mode)
load_functions load_functions
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
___ ____ _________ _ ________
/ | / __ \/ ____/ | / | / / ____/
/ /| | / /_/ / / / /| | / |/ / __/
/ ___ |/ _, _/ /___/ ___ |/ /| / /___
/_/ |_/_/ |_|\____/_/ |_/_/ |_/_____/
EOF
}
# ============================================================================== # ==============================================================================
# UNINSTALL # UNINSTALL
# ============================================================================== # ==============================================================================
@@ -82,26 +72,11 @@ function update() {
exit exit
} }
# ==============================================================================
# CHECK DOCKER
# ==============================================================================
function check_docker() {
if ! command -v docker &>/dev/null; then
msg_error "Docker is not installed. This script requires an existing Docker LXC. Exiting."
exit 10
fi
if ! docker compose version &>/dev/null; then
msg_error "Docker Compose plugin is not available. Please install it before running this script. Exiting."
exit 10
fi
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') and Docker Compose are available"
}
# ============================================================================== # ==============================================================================
# INSTALL # INSTALL
# ============================================================================== # ==============================================================================
function install() { function install() {
check_docker ensure_docker
msg_info "Creating install directory" msg_info "Creating install directory"
mkdir -p "$INSTALL_PATH" mkdir -p "$INSTALL_PATH"
@@ -178,6 +153,7 @@ if [[ "${type:-}" == "update" ]]; then
fi fi
header_info header_info
confirm_not_pve_host
get_lxc_ip get_lxc_ip
# Check if already installed # Check if already installed
+140 -98
View File
@@ -5,62 +5,153 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://coder.com/ | Github: https://github.com/coder/code-server # Source: https://coder.com/ | Github: https://github.com/coder/code-server
function header_info { if ! command -v curl &>/dev/null; then
cat <<"EOF" printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
______ __ _____ if [[ -f /etc/alpine-release ]]; then
/ ____/___ ____/ /__ / ___/___ ______ _____ _____ apk update >/dev/null 2>&1
/ / / __ \/ __ / _ \ \__ \/ _ \/ ___/ | / / _ \/ ___/ apk add --no-cache curl >/dev/null 2>&1
/ /___/ /_/ / /_/ / __/ ___/ / __/ / | |/ / __/ / else
\____/\____/\__,_/\___/ /____/\___/_/ |___/\___/_/ apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
EOF fi
} fi
IP=$(hostname -I | awk '{print $1}') source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
YW=$(echo "\033[33m") source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
BL=$(echo "\033[36m") source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
RD=$(echo "\033[01;31m")
BGN=$(echo "\033[4;92m")
GN=$(echo "\033[1;92m")
DGN=$(echo "\033[32m")
CL=$(echo "\033[m")
BFR="\\r\\033[K"
HOLD="-"
CM="${GN}${CL}"
APP="Coder Code Server"
hostname="$(hostname)"
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "coder-code-server" "addon" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "coder-code-server" "addon"
set -o errexit # Enable error handling
set -o errtrace set -Eeuo pipefail
set -o nounset trap 'error_handler' ERR
set -o pipefail
shopt -s expand_aliases APP="Coder Code Server"
alias die='EXIT=$? LINE=$LINENO error_exit' APP_TYPE="addon"
trap die ERR
# Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
function error_exit() {
trap - ERR
local reason="Unknown failure occured."
local msg="${1:-$reason}"
local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE"
echo -e "$flag $msg" 1>&2
exit "$EXIT"
}
clear
header_info header_info
if command -v pveversion >/dev/null 2>&1; then ensure_usr_local_bin_persist
echo -e "⚠️ Can't Install on Proxmox " get_lxc_ip
exit IP="$LOCAL_IP"
confirm_not_pve_host
require_debian_like
# ==============================================================================
# UNINSTALL
# ==============================================================================
function uninstall() {
msg_info "Uninstalling ${APP}"
systemctl disable --now code-server@"$USER" &>/dev/null || true
$STD apt remove -y code-server
rm -f "$HOME/.coder-code-server"
msg_ok "${APP} has been uninstalled"
}
# ==============================================================================
# UPDATE
# ==============================================================================
function update() {
if check_for_gh_release "coder-code-server" "coder/code-server"; then
msg_info "Updating ${APP}"
fetch_and_deploy_gh_release "coder-code-server" "coder/code-server" "binary" "latest" "/opt/coder-code-server" "code-server_*_$(arch_resolve).deb"
systemctl restart code-server@"$USER"
msg_ok "Updated successfully!"
exit
fi
}
# ==============================================================================
# INSTALL
# ==============================================================================
function install() {
msg_info "Installing Dependencies"
$STD apt update
$STD apt install -y \
curl \
git
msg_ok "Installed Dependencies"
msg_info "Installing ${APP}"
config_path="${HOME}/.config/code-server/config.yaml"
preexisting_config=false
if [ -f "$config_path" ]; then
preexisting_config=true
fi
fetch_and_deploy_gh_release "coder-code-server" "coder/code-server" "binary" "latest" "/opt/coder-code-server" "code-server_*_$(arch_resolve).deb"
mkdir -p "${HOME}/.config/code-server/"
if [ "$preexisting_config" = false ]; then
cat <<EOF >"$config_path"
bind-addr: 0.0.0.0:8680
auth: none
password:
cert: false
EOF
fi
systemctl enable -q --now code-server@"$USER"
systemctl restart code-server@"$USER"
if ! systemctl is-active --quiet code-server@"$USER"; then
msg_error "code-server service failed to start."
exit 150
fi
msg_ok "Installed ${APP}"
msg_info "Creating update script"
ensure_usr_local_bin_persist
cat <<'EOF' >/usr/local/bin/update_coder-code-server
#!/usr/bin/env bash
# Coder Code Server Update Script
type=update bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/tools/addon/coder-code-server.sh)"
EOF
chmod +x /usr/local/bin/update_coder-code-server
msg_ok "Created update script (/usr/local/bin/update_coder-code-server)"
echo -e "${APP} should be reachable by going to the following URL.
${BL}http://${IP}:8680${CL} \n"
}
# ==============================================================================
# MAIN
# ==============================================================================
# Handle type=update (called from update script)
if [[ "${type:-}" == "update" ]]; then
if command -v code-server &>/dev/null; then
update
else
msg_error "${APP} is not installed. Nothing to update."
exit 233
fi
exit 0
fi fi
if [ -e /etc/alpine-release ]; then
echo -e "⚠️ Can't Install on Alpine" if [[ -d "$HOME" && -f "$HOME/.coder-code-server" ]] || command -v code-server &>/dev/null; then
exit msg_warn "${APP} is already installed."
echo -n "${TAB}Uninstall ${APP}? (y/N): "
read -r uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
uninstall
exit 0
fi
echo -n "${TAB}Update ${APP}? (y/N): "
read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
update
exit 0
fi
msg_warn "No action selected. Exiting."
exit 0
fi fi
while true; do while true; do
read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn echo -n "${TAB}This will Install ${APP}. Proceed (y/n)? "
read -r yn
case $yn in case $yn in
[Yy]*) break ;; [Yy]*) break ;;
[Nn]*) exit ;; [Nn]*) exit ;;
@@ -68,53 +159,4 @@ while true; do
esac esac
done done
function msg_info() { install
local msg="$1"
echo -ne " ${HOLD} ${YW}${msg}..."
}
function msg_ok() {
local msg="$1"
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
msg_info "Installing Dependencies"
apt-get update &>/dev/null
apt-get install -y curl &>/dev/null
apt-get install -y git &>/dev/null
msg_ok "Installed Dependencies"
VERSION=$(curl -fsSL https://api.github.com/repos/coder/code-server/releases/latest |
grep "tag_name" |
awk '{print substr($2, 3, length($2)-4) }')
msg_info "Installing Code-Server v${VERSION}"
config_path="${HOME}/.config/code-server/config.yaml"
preexisting_config=false
if [ -f "$config_path" ]; then
preexisting_config=true
fi
curl -fOL https://github.com/coder/code-server/releases/download/v"$VERSION"/code-server_"${VERSION}"_amd64.deb &>/dev/null
dpkg -i code-server_"${VERSION}"_amd64.deb &>/dev/null
rm -rf code-server_"${VERSION}"_amd64.deb
mkdir -p "${HOME}/.config/code-server/"
if [ "$preexisting_config" = false ]; then
cat <<EOF >"$config_path"
bind-addr: 0.0.0.0:8680
auth: none
password:
cert: false
EOF
fi
systemctl enable -q --now code-server@"$USER"
systemctl restart code-server@"$USER"
if ! systemctl is-active --quiet code-server@"$USER"; then
error_exit "code-server service failed to start."
fi
msg_ok "Installed Code-Server v${VERSION} on $hostname"
echo -e "${APP} should be reachable by going to the following URL.
${BL}http://$IP:8680${CL} \n"
+2 -57
View File
@@ -66,66 +66,11 @@ function update() {
exit exit
} }
# ==============================================================================
# PROXMOX HOST CHECK
# ==============================================================================
function check_proxmox_host() {
if command -v pveversion &>/dev/null; then
msg_error "Running on the Proxmox host is NOT recommended!"
msg_error "This should be executed inside an LXC container."
echo ""
echo -n "${TAB}Continue anyway? (y/N): "
read -r confirm
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
msg_warn "Aborted. Please run this inside an LXC container."
exit 0
fi
msg_warn "Proceeding on Proxmox host at your own risk!"
fi
}
# ==============================================================================
# CHECK / INSTALL DOCKER
# ==============================================================================
function check_or_install_docker() {
if command -v docker &>/dev/null; then
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
if docker compose version &>/dev/null; then
msg_ok "Docker Compose is available"
else
msg_error "Docker Compose plugin is not available. Please install it."
exit 10
fi
return
fi
msg_warn "Docker is not installed."
echo -n "${TAB}Install Docker now? (y/N): "
read -r install_docker_prompt
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_error "Docker is required for ${APP}. Exiting."
exit 10
fi
msg_info "Installing Docker"
if [[ -f /etc/alpine-release ]]; then
$STD apk add docker docker-cli-compose
$STD rc-service docker start
$STD rc-update add docker default
else
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
$STD sh <(curl -fsSL https://get.docker.com)
fi
msg_ok "Installed Docker"
}
# ============================================================================== # ==============================================================================
# INSTALL # INSTALL
# ============================================================================== # ==============================================================================
function install() { function install() {
check_or_install_docker ensure_docker
msg_info "Installing dependencies" msg_info "Installing dependencies"
if [[ -f /etc/alpine-release ]]; then if [[ -f /etc/alpine-release ]]; then
@@ -172,7 +117,7 @@ if [[ "${type:-}" == "update" ]]; then
fi fi
header_info header_info
check_proxmox_host confirm_not_pve_host
get_lxc_ip get_lxc_ip
# Check if already installed # Check if already installed
+18 -20
View File
@@ -7,8 +7,13 @@
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1 if [[ -f /etc/alpine-release ]]; then
apt-get install -y curl >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -45,28 +50,13 @@ if [[ -f "/etc/alpine-release" ]]; then
SERVICE_PATH="/etc/init.d/copyparty" SERVICE_PATH="/etc/init.d/copyparty"
elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
OS="Debian" OS="Debian"
PKG_MANAGER="apt-get install -y" PKG_MANAGER="apt install -y"
SERVICE_PATH="/etc/systemd/system/copyparty.service" SERVICE_PATH="/etc/systemd/system/copyparty.service"
else else
msg_error "Unsupported OS detected. Exiting." msg_error "Unsupported OS detected. Exiting."
exit 238 exit 238
fi fi
# ==============================================================================
# HEADER
# ==============================================================================
function header_info() {
clear
cat <<"EOF"
______ ____ __
/ ____/___ ____ __ __/ __ \____ ______/ /___ __
/ / / __ \/ __ \/ / / / /_/ / __ `/ ___/ __/ / / /
/ /___/ /_/ / /_/ / /_/ / ____/ /_/ / / / /_/ /_/ /
\____/\____/ .___/\__, /_/ \__,_/_/ \__/\__, /
/_/ /____/ /____/
EOF
}
# ============================================================================== # ==============================================================================
# HELPER FUNCTIONS # HELPER FUNCTIONS
# ============================================================================== # ==============================================================================
@@ -173,9 +163,17 @@ function install() {
msg_info "Installing dependencies" msg_info "Installing dependencies"
if [[ "$OS" == "Debian" ]]; then if [[ "$OS" == "Debian" ]]; then
$STD $PKG_MANAGER python3 python3-pil ffmpeg curl $STD $PKG_MANAGER \
python3 \
python3-pil \
ffmpeg \
curl
else else
$STD $PKG_MANAGER python3 py3-pillow ffmpeg curl $STD $PKG_MANAGER \
python3 \
py3-pillow \
ffmpeg \
curl
fi fi
msg_ok "Dependencies installed (with thumbnail support)" msg_ok "Dependencies installed (with thumbnail support)"
+11 -32
View File
@@ -7,8 +7,13 @@
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1 if [[ -f /etc/alpine-release ]]; then
apt-get install -y curl >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -20,6 +25,7 @@ declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "cronmaster" "
set -Eeuo pipefail set -Eeuo pipefail
trap 'error_handler' ERR trap 'error_handler' ERR
load_functions load_functions
require_debian_like
# ============================================================================== # ==============================================================================
# CONFIGURATION # CONFIGURATION
@@ -31,29 +37,6 @@ CONFIG_PATH="/opt/cronmaster/.env"
SERVICE_PATH="/etc/systemd/system/cronmaster.service" SERVICE_PATH="/etc/systemd/system/cronmaster.service"
DEFAULT_PORT=3000 DEFAULT_PORT=3000
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
______ __ ___ __
/ ____/________ ____ / |/ /___ ______/ /____ _____
/ / / ___/ __ \/ __ \/ /|_/ / __ `/ ___/ __/ _ \/ ___/
/ /___/ / / /_/ / / / / / / / /_/ (__ ) /_/ __/ /
\____/_/ \____/_/ /_/_/ /_/\__,_/____/\__/\___/_/
EOF
}
# ==============================================================================
# OS DETECTION
# ==============================================================================
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
exit 238
fi
# ============================================================================== # ==============================================================================
# UNINSTALL # UNINSTALL
# ============================================================================== # ==============================================================================
@@ -77,16 +60,12 @@ function update() {
systemctl stop cronmaster.service &>/dev/null || true systemctl stop cronmaster.service &>/dev/null || true
msg_ok "Stopped service" msg_ok "Stopped service"
msg_info "Backing up configuration" BACKUP_DIR="/opt/cronmaster_backup"
cp "$CONFIG_PATH" /tmp/cronmaster.env.bak 2>/dev/null || true create_backup "$CONFIG_PATH"
msg_ok "Backed up configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cronmaster" "fccview/cronmaster" "prebuild" "latest" "$INSTALL_PATH" "cronmaster_*_prebuild.tar.gz" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "cronmaster" "fccview/cronmaster" "prebuild" "latest" "$INSTALL_PATH" "cronmaster_*_prebuild.tar.gz"
msg_info "Restoring configuration" restore_backup
cp /tmp/cronmaster.env.bak "$CONFIG_PATH" 2>/dev/null || true
rm -f /tmp/cronmaster.env.bak
msg_ok "Restored configuration"
msg_info "Starting service" msg_info "Starting service"
systemctl start cronmaster systemctl start cronmaster
+35 -63
View File
@@ -5,89 +5,61 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.crowdsec.net/ | Github: https://github.com/crowdsecurity/crowdsec # Source: https://www.crowdsec.net/ | Github: https://github.com/crowdsecurity/crowdsec
YW=$(echo "\033[33m")
BL=$(echo "\033[36m")
RD=$(echo "\033[01;31m")
BGN=$(echo "\033[4;92m")
GN=$(echo "\033[1;92m")
DGN=$(echo "\033[32m")
CL=$(echo "\033[m")
BFR="\\r\\033[K"
HOLD="-"
CM="${GN}${CL}"
APP="CrowdSec" APP="CrowdSec"
hostname="$(hostname)" APP_TYPE="addon"
# Telemetry if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
if [[ -f /etc/alpine-release ]]; then
apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "crowdsec" "addon" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "crowdsec" "addon"
set -o errexit # Enable error handling
set -o errtrace set -Eeuo pipefail
set -o nounset trap 'error_handler' ERR
set -o pipefail
shopt -s expand_aliases # Initialize all core functions (colors, formatting, icons, STD mode)
alias die='EXIT=$? LINE=$LINENO error_exit' load_functions
trap die ERR require_debian_like
header_info
confirm_not_pve_host
function error_exit() {
trap - ERR
local reason="Unknown failure occured."
local msg="${1:-$reason}"
local flag="${RD}‼ ERROR ${CL}$EXIT@$LINE"
echo -e "$flag $msg" 1>&2
exit "$EXIT"
}
if command -v pveversion >/dev/null 2>&1; then
echo -e "⚠️ Can't Install on Proxmox "
exit
fi
while true; do while true; do
read -p "This will Install ${APP} on $hostname. Proceed(y/n)?" yn echo -n "${TAB}This will Install ${APP}. Proceed (y/n)? "
read -r yn
case $yn in case $yn in
[Yy]*) break ;; [Yy]*) break ;;
[Nn]*) exit ;; [Nn]*) exit ;;
*) echo "Please answer yes or no." ;; *) echo "Please answer yes or no." ;;
esac esac
done done
clear
function header_info() {
echo -e "${BL}
_____ _ _____
/ ____| | |/ ____|
| | _ __ _____ ____| | (___ ___ ___
| | | __/ _ \ \ /\ / / _ |\___ \ / _ \/ __|
| |____| | | (_) \ V V / (_| |____) | __/ (__
\_____|_| \___/ \_/\_/ \__ _|_____/ \___|\___|
${CL}"
}
header_info
function msg_info() {
local msg="$1"
echo -ne " ${HOLD} ${YW}${msg}..."
}
function msg_ok() {
local msg="$1"
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
msg_info "Setting up ${APP} Repository" msg_info "Setting up ${APP} Repository"
apt-get update &>/dev/null $STD apt update
apt-get install -y curl &>/dev/null $STD apt install -y \
apt-get install -y gnupg &>/dev/null curl \
curl -fsSL "https://install.crowdsec.net" | bash &>/dev/null gnupg
$STD bash -c "curl -fsSL https://install.crowdsec.net | bash"
msg_ok "Setup ${APP} Repository" msg_ok "Setup ${APP} Repository"
msg_info "Installing ${APP}" msg_info "Installing ${APP}"
apt-get update &>/dev/null $STD apt update
apt-get install -y crowdsec &>/dev/null $STD apt install -y crowdsec
msg_ok "Installed ${APP} on $hostname" msg_ok "Installed ${APP}"
msg_info "Installing ${APP} Common Bouncer" msg_info "Installing ${APP} Common Bouncer"
apt-get install -y crowdsec-firewall-bouncer-iptables &>/dev/null $STD apt install -y crowdsec-firewall-bouncer-iptables
msg_ok "Installed ${APP} Common Bouncer" msg_ok "Installed ${APP} Common Bouncer"
msg_ok "Completed successfully!\n" msg_ok "Completed successfully!\n"
+2 -57
View File
@@ -72,66 +72,11 @@ function update() {
exit exit
} }
# ==============================================================================
# PROXMOX HOST CHECK
# ==============================================================================
function check_proxmox_host() {
if command -v pveversion &>/dev/null; then
msg_error "Running on the Proxmox host is NOT recommended!"
msg_error "This should be executed inside an LXC container."
echo ""
echo -n "${TAB}Continue anyway? (y/N): "
read -r confirm
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
msg_warn "Aborted. Please run this inside an LXC container."
exit 0
fi
msg_warn "Proceeding on Proxmox host at your own risk!"
fi
}
# ==============================================================================
# CHECK / INSTALL DOCKER
# ==============================================================================
function check_or_install_docker() {
if command -v docker &>/dev/null; then
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
if docker compose version &>/dev/null; then
msg_ok "Docker Compose is available"
else
msg_error "Docker Compose plugin is not available. Please install it."
exit 10
fi
return
fi
msg_warn "Docker is not installed."
echo -n "${TAB}Install Docker now? (y/N): "
read -r install_docker_prompt
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_error "Docker is required for ${APP}. Exiting."
exit 10
fi
msg_info "Installing Docker"
if [[ -f /etc/alpine-release ]]; then
$STD apk add docker docker-cli-compose
$STD rc-service docker start
$STD rc-update add docker default
else
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
$STD sh <(curl -fsSL https://get.docker.com)
fi
msg_ok "Installed Docker"
}
# ============================================================================== # ==============================================================================
# INSTALL # INSTALL
# ============================================================================== # ==============================================================================
function install() { function install() {
check_or_install_docker ensure_docker
msg_info "Creating install directories" msg_info "Creating install directories"
mkdir -p "$INSTALL_PATH" "$STACKS_PATH" mkdir -p "$INSTALL_PATH" "$STACKS_PATH"
@@ -167,7 +112,7 @@ if [[ "${type:-}" == "update" ]]; then
fi fi
header_info header_info
check_proxmox_host confirm_not_pve_host
get_lxc_ip get_lxc_ip
# Check if already installed # Check if already installed
+2 -57
View File
@@ -65,66 +65,11 @@ function update() {
exit exit
} }
# ==============================================================================
# PROXMOX HOST CHECK
# ==============================================================================
function check_proxmox_host() {
if command -v pveversion &>/dev/null; then
msg_error "Running on the Proxmox host is NOT recommended!"
msg_error "This should be executed inside an LXC container."
echo ""
echo -n "${TAB}Continue anyway? (y/N): "
read -r confirm
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
msg_warn "Aborted. Please run this inside an LXC container."
exit 0
fi
msg_warn "Proceeding on Proxmox host at your own risk!"
fi
}
# ==============================================================================
# CHECK / INSTALL DOCKER
# ==============================================================================
function check_or_install_docker() {
if command -v docker &>/dev/null; then
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
if docker compose version &>/dev/null; then
msg_ok "Docker Compose is available"
else
msg_error "Docker Compose plugin is not available. Please install it."
exit 10
fi
return
fi
msg_warn "Docker is not installed."
echo -n "${TAB}Install Docker now? (y/N): "
read -r install_docker_prompt
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_error "Docker is required for ${APP}. Exiting."
exit 10
fi
msg_info "Installing Docker"
if [[ -f /etc/alpine-release ]]; then
$STD apk add docker docker-cli-compose
$STD rc-service docker start
$STD rc-update add docker default
else
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
$STD sh <(curl -fsSL https://get.docker.com)
fi
msg_ok "Installed Docker"
}
# ============================================================================== # ==============================================================================
# INSTALL # INSTALL
# ============================================================================== # ==============================================================================
function install() { function install() {
check_or_install_docker ensure_docker
msg_info "Installing dependencies" msg_info "Installing dependencies"
if [[ -f /etc/alpine-release ]]; then if [[ -f /etc/alpine-release ]]; then
@@ -170,7 +115,7 @@ if [[ "${type:-}" == "update" ]]; then
fi fi
header_info header_info
check_proxmox_host confirm_not_pve_host
get_lxc_ip get_lxc_ip
# Check if already installed # Check if already installed
+66 -74
View File
@@ -5,55 +5,51 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/filebrowserspace/quantum # Source: https://github.com/filebrowserspace/quantum
function header_info() {
clear
cat <<"EOF"
_______ __ ____ ____ __
/ ____(_) /__ / __ )_________ _ __________ _____ / __ \__ ______ _____ / /___ ______ ___
/ /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/ / / / / / / / __ `/ __ \/ __/ / / / __ `__ \
/ __/ / / / __/ /_/ / / / /_/ / |/ |/ (__ ) __/ / / /_/ / /_/ / /_/ / / / / /_/ /_/ / / / / / /
/_/ /_/_/\___/_____/_/ \____/|__/|__/____/\___/_/ \___\_\__,_/\__,_/_/ /_/\__/\__,_/_/ /_/ /_/
EOF
}
YW=$(echo "\033[33m")
GN=$(echo "\033[1;92m")
RD=$(echo "\033[01;31m")
BL=$(echo "\033[36m")
CL=$(echo "\033[m")
CM="${GN}✔️${CL}"
CROSS="${RD}✖️${CL}"
INFO="${BL}${CL}"
APP="FileBrowser Quantum" APP="FileBrowser Quantum"
APP_TYPE="addon"
INSTALL_PATH="/usr/local/bin/filebrowser" INSTALL_PATH="/usr/local/bin/filebrowser"
CONFIG_PATH="/usr/local/community-scripts/fq-config.yaml" CONFIG_PATH="/usr/local/community-scripts/fq-config.yaml"
DEFAULT_PORT=8080 DEFAULT_PORT=8080
SRC_DIR="/" SRC_DIR="/"
TMP_BIN="/tmp/filebrowser.$$"
# Telemetry if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
if [[ -f /etc/alpine-release ]]; then
apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "filebrowser-quantum" "addon" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "filebrowser-quantum" "addon"
# Get primary IP # Enable error handling
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}') set -Eeuo pipefail
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) trap 'error_handler' ERR
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}')
[[ -z "$IP" ]] && IP="127.0.0.1" # Initialize all core functions (colors, formatting, icons, STD mode)
load_functions
header_info
get_lxc_ip
IP="$LOCAL_IP"
# Proxmox Host Warning # Proxmox Host Warning
if [[ -d "/etc/pve" ]]; then if [[ -d "/etc/pve" ]]; then
echo -e "${RD}⚠️ Warning: Running this addon directly on the Proxmox host is not recommended!${CL}" msg_warn "Running this addon directly on the Proxmox host is not recommended!"
echo -e "${YW} Only the boot disk will be visible passthrough drives will not be indexed.${CL}" msg_warn "Only the boot disk will be visible — passthrough drives will not be indexed."
echo -e "${YW} This causes incorrect disk usage stats and incomplete file browsing.${CL}" msg_warn "This causes incorrect disk usage stats and incomplete file browsing."
echo -e "${YW} Run this addon inside an LXC or VM instead and mount your drives there.${CL}" msg_warn "Run this addon inside an LXC or VM instead and mount your drives there."
echo "" echo ""
echo -n "Continue anyway on the Proxmox host? (y/N): " echo -n "${TAB}Continue anyway on the Proxmox host? (y/N): "
read -r host_confirm read -r host_confirm
if [[ ! "${host_confirm,,}" =~ ^(y|yes)$ ]]; then if [[ ! "${host_confirm,,}" =~ ^(y|yes)$ ]]; then
echo -e "${YW}Aborted.${CL}" msg_error "Aborted."
exit 0 exit 0
fi fi
fi fi
@@ -66,18 +62,12 @@ if [[ -f "/etc/alpine-release" ]]; then
elif [[ -f "/etc/debian_version" ]]; then elif [[ -f "/etc/debian_version" ]]; then
OS="Debian" OS="Debian"
SERVICE_PATH="/etc/systemd/system/filebrowser.service" SERVICE_PATH="/etc/systemd/system/filebrowser.service"
PKG_MANAGER="apt-get install -y" PKG_MANAGER="apt install -y"
else else
echo -e "${CROSS} Unsupported OS detected. Exiting." msg_error "Unsupported OS detected. Exiting."
exit 238 exit 238
fi fi
header_info
function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; }
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; }
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; }
# Detect legacy FileBrowser installation # Detect legacy FileBrowser installation
LEGACY_DB="/usr/local/community-scripts/filebrowser.db" LEGACY_DB="/usr/local/community-scripts/filebrowser.db"
LEGACY_BIN="/usr/local/bin/filebrowser" LEGACY_BIN="/usr/local/bin/filebrowser"
@@ -85,80 +75,82 @@ LEGACY_SERVICE_DEB="/etc/systemd/system/filebrowser.service"
LEGACY_SERVICE_ALP="/etc/init.d/filebrowser" LEGACY_SERVICE_ALP="/etc/init.d/filebrowser"
if [[ -f "$LEGACY_DB" || -f "$LEGACY_BIN" && ! -f "$CONFIG_PATH" ]]; then if [[ -f "$LEGACY_DB" || -f "$LEGACY_BIN" && ! -f "$CONFIG_PATH" ]]; then
echo -e "${YW}⚠️ Detected legacy FileBrowser installation.${CL}" msg_warn "Detected legacy FileBrowser installation."
echo -n "Uninstall legacy FileBrowser and continue with Quantum install? (y/n): " echo -n "${TAB}Uninstall legacy FileBrowser and continue with Quantum install? (y/n): "
read -r remove_legacy read -r remove_legacy
if [[ "${remove_legacy,,}" =~ ^(y|yes)$ ]]; then if [[ "${remove_legacy,,}" =~ ^(y|yes)$ ]]; then
msg_info "Uninstalling legacy FileBrowser" msg_info "Uninstalling legacy FileBrowser"
if [[ -f "$LEGACY_SERVICE_DEB" ]]; then if [[ -f "$LEGACY_SERVICE_DEB" ]]; then
systemctl disable --now filebrowser.service &>/dev/null systemctl disable --now filebrowser.service &>/dev/null || true
rm -f "$LEGACY_SERVICE_DEB" rm -f "$LEGACY_SERVICE_DEB"
elif [[ -f "$LEGACY_SERVICE_ALP" ]]; then elif [[ -f "$LEGACY_SERVICE_ALP" ]]; then
rc-service filebrowser stop &>/dev/null rc-service filebrowser stop &>/dev/null || true
rc-update del filebrowser &>/dev/null rc-update del filebrowser &>/dev/null || true
rm -f "$LEGACY_SERVICE_ALP" rm -f "$LEGACY_SERVICE_ALP"
fi fi
rm -f "$LEGACY_BIN" "$LEGACY_DB" rm -f "$LEGACY_BIN" "$LEGACY_DB"
msg_ok "Legacy FileBrowser removed" msg_ok "Legacy FileBrowser removed"
else else
echo -e "${YW}Installation aborted by user.${CL}" msg_error "Installation aborted by user."
exit 0 exit 0
fi fi
fi fi
# Existing installation # Existing installation
if [[ -f "$INSTALL_PATH" ]]; then if [[ -f "$INSTALL_PATH" ]]; then
echo -e "${YW}⚠️ ${APP} is already installed.${CL}" msg_warn "${APP} is already installed."
echo -n "Uninstall ${APP}? (y/N): " echo -n "${TAB}Uninstall ${APP}? (y/N): "
read -r uninstall_prompt read -r uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Uninstalling ${APP}" msg_info "Uninstalling ${APP}"
if [[ "$OS" == "Debian" ]]; then if [[ "$OS" == "Debian" ]]; then
systemctl disable --now filebrowser.service &>/dev/null systemctl disable --now filebrowser.service &>/dev/null || true
rm -f "$SERVICE_PATH" rm -f "$SERVICE_PATH"
else else
rc-service filebrowser stop &>/dev/null rc-service filebrowser stop &>/dev/null || true
rc-update del filebrowser &>/dev/null rc-update del filebrowser &>/dev/null || true
rm -f "$SERVICE_PATH" rm -f "$SERVICE_PATH"
fi fi
rm -f "$INSTALL_PATH" "$CONFIG_PATH" rm -f "$INSTALL_PATH" "$CONFIG_PATH" "$HOME/.filebrowser-quantum"
msg_ok "${APP} has been uninstalled." msg_ok "${APP} has been uninstalled."
exit 0 exit 0
fi fi
echo -n "Update ${APP}? (y/N): " echo -n "${TAB}Update ${APP}? (y/N): "
read -r update_prompt read -r update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Updating ${APP}" if check_for_gh_release "filebrowser-quantum" "gtsteffaniak/filebrowser"; then
if ! command -v curl &>/dev/null; then $PKG_MANAGER curl &>/dev/null; fi msg_info "Updating ${APP}"
curl -fsSL https://github.com/gtsteffaniak/filebrowser/releases/latest/download/linux-amd64-filebrowser -o "$TMP_BIN" if ! command -v curl &>/dev/null; then $STD $PKG_MANAGER curl; fi
chmod +x "$TMP_BIN" fetch_and_deploy_gh_release "filebrowser-quantum" "gtsteffaniak/filebrowser" "singlefile" "latest" "/usr/local/bin" "linux-$(arch_resolve)-filebrowser"
mv -f "$TMP_BIN" /usr/local/bin/filebrowser mv -f /usr/local/bin/filebrowser-quantum "$INSTALL_PATH"
msg_ok "Updated ${APP}" msg_ok "Updated ${APP}"
fi
exit 0 exit 0
else else
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}" msg_warn "Update skipped. Exiting."
exit 0 exit 0
fi fi
fi fi
echo -e "${YW}⚠️ ${APP} is not installed.${CL}" msg_warn "${APP} is not installed."
echo -n "Enter port number (Default: ${DEFAULT_PORT}): " echo -n "${TAB}Enter port number (Default: ${DEFAULT_PORT}): "
read -r PORT read -r PORT
PORT=${PORT:-$DEFAULT_PORT} PORT=${PORT:-$DEFAULT_PORT}
echo -n "Install ${APP}? (y/n): " echo -n "${TAB}Install ${APP}? (y/n): "
read -r install_prompt read -r install_prompt
if ! [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then if ! [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}" msg_warn "Installation skipped. Exiting."
exit 0 exit 0
fi fi
msg_info "Installing ${APP} on ${OS}" msg_info "Installing ${APP} on ${OS}"
$PKG_MANAGER curl ffmpeg &>/dev/null $STD $PKG_MANAGER \
curl -fsSL https://github.com/gtsteffaniak/filebrowser/releases/latest/download/linux-amd64-filebrowser -o "$TMP_BIN" curl \
chmod +x "$TMP_BIN" ffmpeg
mv -f "$TMP_BIN" /usr/local/bin/filebrowser fetch_and_deploy_gh_release "filebrowser-quantum" "gtsteffaniak/filebrowser" "singlefile" "latest" "/usr/local/bin" "linux-$(arch_resolve)-filebrowser"
mv -f /usr/local/bin/filebrowser-quantum "$INSTALL_PATH"
msg_ok "Installed ${APP}" msg_ok "Installed ${APP}"
msg_info "Preparing configuration directory" msg_info "Preparing configuration directory"
@@ -167,7 +159,7 @@ chown root:root /usr/local/community-scripts
chmod 755 /usr/local/community-scripts chmod 755 /usr/local/community-scripts
msg_ok "Directory prepared" msg_ok "Directory prepared"
echo -n "Use No Authentication? (y/N): " echo -n "${TAB}Use No Authentication? (y/N): "
read -r noauth_prompt read -r noauth_prompt
# === YAML CONFIG GENERATION === # === YAML CONFIG GENERATION ===
@@ -251,9 +243,9 @@ depend() {
} }
EOF EOF
chmod +x "$SERVICE_PATH" chmod +x "$SERVICE_PATH"
rc-update add filebrowser default &>/dev/null $STD rc-update add filebrowser default
rc-service filebrowser start &>/dev/null $STD rc-service filebrowser start
fi fi
msg_ok "Service created successfully" msg_ok "Service created successfully"
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://$IP:$PORT${CL}" msg_ok "${APP} is reachable at: ${BL}http://${IP}:${PORT}${CL}"
+62 -77
View File
@@ -5,53 +5,50 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://filebrowser.org/ | Github: https://github.com/filebrowser/filebrowser # Source: https://filebrowser.org/ | Github: https://github.com/filebrowser/filebrowser
function header_info {
clear
cat <<"EOF"
_______ __ ____
/ ____(_) /__ / __ )_________ _ __________ _____
/ /_ / / / _ \/ __ / ___/ __ \ | /| / / ___/ _ \/ ___/
/ __/ / / / __/ /_/ / / / /_/ / |/ |/ (__ ) __/ /
/_/ /_/_/\___/_____/_/ \____/|__/|__/____/\___/_/
EOF
}
YW=$(echo "\033[33m")
GN=$(echo "\033[1;92m")
RD=$(echo "\033[01;31m")
BL=$(echo "\033[36m")
CL=$(echo "\033[m")
CM="${GN}✔️${CL}"
CROSS="${RD}✖️${CL}"
INFO="${BL}${CL}"
APP="FileBrowser" APP="FileBrowser"
APP_TYPE="addon"
INSTALL_PATH="/usr/local/bin/filebrowser" INSTALL_PATH="/usr/local/bin/filebrowser"
DB_PATH="/usr/local/community-scripts/filebrowser.db" DB_PATH="/usr/local/community-scripts/filebrowser.db"
DEFAULT_PORT=8080 DEFAULT_PORT=8080
# Telemetry if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
if [[ -f /etc/alpine-release ]]; then
apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "filebrowser" "addon" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "filebrowser" "addon"
# Get first non-loopback IP & Detect primary network interface dynamically # Enable error handling
IFACE=$(ip -4 route | awk '/default/ {print $5; exit}') set -Eeuo pipefail
IP=$(ip -4 addr show "$IFACE" | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1) trap 'error_handler' ERR
[[ -z "$IP" ]] && IP=$(hostname -I | awk '{print $1}') # Initialize all core functions (colors, formatting, icons, STD mode)
[[ -z "$IP" ]] && IP="127.0.0.1" load_functions
header_info
get_lxc_ip
IP="$LOCAL_IP"
# Proxmox Host Warning # Proxmox Host Warning
if [[ -d "/etc/pve" ]]; then if [[ -d "/etc/pve" ]]; then
echo -e "${RD}⚠️ Warning: Running this addon directly on the Proxmox host is not recommended!${CL}" msg_warn "Running this addon directly on the Proxmox host is not recommended!"
echo -e "${YW} Only the boot disk will be visible — passthrough drives will not be indexed.${CL}" msg_warn "Only the boot disk will be visible — passthrough drives will not be indexed."
echo -e "${YW} This causes incorrect disk usage stats and incomplete file browsing.${CL}" msg_warn "This causes incorrect disk usage stats and incomplete file browsing."
echo -e "${YW} Run this addon inside an LXC or VM instead and mount your drives there.${CL}" msg_warn "Run this addon inside an LXC or VM instead and mount your drives there."
echo "" echo ""
echo -n "Continue anyway on the Proxmox host? (y/N): " echo -n "${TAB}Continue anyway on the Proxmox host? (y/N): "
read -r host_confirm read -r host_confirm
if [[ ! "${host_confirm,,}" =~ ^(y|yes)$ ]]; then if [[ ! "${host_confirm,,}" =~ ^(y|yes)$ ]]; then
echo -e "${YW}Aborted.${CL}" msg_error "Aborted."
exit 0 exit 0
fi fi
fi fi
@@ -64,71 +61,59 @@ if [[ -f "/etc/alpine-release" ]]; then
elif [[ -f "/etc/debian_version" ]]; then elif [[ -f "/etc/debian_version" ]]; then
OS="Debian" OS="Debian"
SERVICE_PATH="/etc/systemd/system/filebrowser.service" SERVICE_PATH="/etc/systemd/system/filebrowser.service"
PKG_MANAGER="apt-get install -y" PKG_MANAGER="apt install -y"
else else
echo -e "${CROSS} Unsupported OS detected. Exiting." msg_error "Unsupported OS detected. Exiting."
exit 238 exit 238
fi fi
header_info
function msg_info() {
local msg="$1"
echo -e "${INFO} ${YW}${msg}...${CL}"
}
function msg_ok() {
local msg="$1"
echo -e "${CM} ${GN}${msg}${CL}"
}
function msg_error() {
local msg="$1"
echo -e "${CROSS} ${RD}${msg}${CL}"
}
if [ -f "$INSTALL_PATH" ]; then if [ -f "$INSTALL_PATH" ]; then
echo -e "${YW}⚠️ ${APP} is already installed.${CL}" msg_warn "${APP} is already installed."
read -r -p "Would you like to uninstall ${APP}? (y/N): " uninstall_prompt read -r -p "Would you like to uninstall ${APP}? (y/N): " uninstall_prompt
if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then if [[ "${uninstall_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Uninstalling ${APP}" msg_info "Uninstalling ${APP}"
if [[ "$OS" == "Debian" ]]; then if [[ "$OS" == "Debian" ]]; then
systemctl disable --now filebrowser.service &>/dev/null systemctl disable --now filebrowser.service &>/dev/null || true
rm -f "$SERVICE_PATH" rm -f "$SERVICE_PATH"
else else
rc-service filebrowser stop &>/dev/null rc-service filebrowser stop &>/dev/null || true
rc-update del filebrowser &>/dev/null rc-update del filebrowser &>/dev/null || true
rm -f "$SERVICE_PATH" rm -f "$SERVICE_PATH"
fi fi
rm -f "$INSTALL_PATH" "$DB_PATH" rm -f "$INSTALL_PATH" "$DB_PATH" "$HOME/.filebrowser"
msg_ok "${APP} has been uninstalled." msg_ok "${APP} has been uninstalled."
exit 0 exit 0
fi fi
read -r -p "Would you like to update ${APP}? (y/N): " update_prompt read -r -p "Would you like to update ${APP}? (y/N): " update_prompt
if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then if [[ "${update_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Updating ${APP}" if check_for_gh_release "filebrowser" "filebrowser/filebrowser"; then
if ! command -v curl &>/dev/null; then $PKG_MANAGER curl &>/dev/null; fi msg_info "Updating ${APP}"
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null fetch_and_deploy_gh_release "filebrowser" "filebrowser/filebrowser" "prebuild" "latest" "/opt/filebrowser-dist" "linux-$(arch_resolve)-filebrowser.tar.gz"
chmod +x "$INSTALL_PATH" install -m 755 /opt/filebrowser-dist/filebrowser "$INSTALL_PATH"
msg_ok "Updated ${APP}" rm -rf /opt/filebrowser-dist
msg_ok "Updated ${APP}"
fi
exit 0 exit 0
else else
echo -e "${YW}⚠️ Update skipped. Exiting.${CL}" msg_warn "Update skipped. Exiting."
exit 0 exit 0
fi fi
fi fi
echo -e "${YW}⚠️ ${APP} is not installed.${CL}" msg_warn "${APP} is not installed."
read -r -p "Enter port number (Default: ${DEFAULT_PORT}): " PORT read -r -p "Enter port number (Default: ${DEFAULT_PORT}): " PORT
PORT=${PORT:-$DEFAULT_PORT} PORT=${PORT:-$DEFAULT_PORT}
read -r -p "Would you like to install ${APP}? (y/n): " install_prompt read -r -p "Would you like to install ${APP}? (y/n): " install_prompt
if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Installing ${APP} on ${OS}" msg_info "Installing ${APP} on ${OS}"
$PKG_MANAGER wget tar curl &>/dev/null $STD $PKG_MANAGER \
curl -fsSL "https://github.com/filebrowser/filebrowser/releases/latest/download/linux-amd64-filebrowser.tar.gz" | tar -xzv -C /usr/local/bin &>/dev/null tar \
chmod +x "$INSTALL_PATH" curl
fetch_and_deploy_gh_release "filebrowser" "filebrowser/filebrowser" "prebuild" "latest" "/opt/filebrowser-dist" "linux-$(arch_resolve)-filebrowser.tar.gz"
install -m 755 /opt/filebrowser-dist/filebrowser "$INSTALL_PATH"
rm -rf /opt/filebrowser-dist
msg_ok "Installed ${APP}" msg_ok "Installed ${APP}"
msg_info "Creating FileBrowser directory" msg_info "Creating FileBrowser directory"
@@ -144,19 +129,19 @@ if [[ "${install_prompt,,}" =~ ^(y|yes)$ ]]; then
if [[ "${auth_prompt,,}" =~ ^(y|yes)$ ]]; then if [[ "${auth_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_info "Configuring No Authentication" msg_info "Configuring No Authentication"
cd /usr/local/community-scripts cd /usr/local/community-scripts
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null $STD filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null $STD filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
filebrowser config set --auth.method=noauth --database "$DB_PATH" &>/dev/null $STD filebrowser config set --auth.method=noauth --database "$DB_PATH"
if ! filebrowser users update 1 --perm.admin --database "$DB_PATH" &>/dev/null; then if ! filebrowser users update 1 --perm.admin --database "$DB_PATH" &>/dev/null; then
filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH" &>/dev/null $STD filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH"
fi fi
msg_ok "No Authentication configured" msg_ok "No Authentication configured"
else else
msg_info "Setting up default authentication" msg_info "Setting up default authentication"
cd /usr/local/community-scripts cd /usr/local/community-scripts
filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null $STD filebrowser config init -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH" &>/dev/null $STD filebrowser config set -a '0.0.0.0' -p "$PORT" -d "$DB_PATH"
filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH" &>/dev/null $STD filebrowser users add admin community-scripts.org --perm.admin --database "$DB_PATH"
msg_ok "Default authentication configured (admin:community-scripts.org)" msg_ok "Default authentication configured (admin:community-scripts.org)"
fi fi
@@ -194,13 +179,13 @@ depend() {
} }
EOF EOF
chmod +x "$SERVICE_PATH" chmod +x "$SERVICE_PATH"
rc-update add filebrowser default &>/dev/null $STD rc-update add filebrowser default
rc-service filebrowser start &>/dev/null $STD rc-service filebrowser start
fi fi
msg_ok "Service created successfully" msg_ok "Service created successfully"
echo -e "${CM} ${GN}${APP} is reachable at: ${BL}http://$IP:$PORT${CL}" msg_ok "${APP} is reachable at: ${BL}http://${IP}:${PORT}${CL}"
else else
echo -e "${YW}⚠️ Installation skipped. Exiting.${CL}" msg_warn "Installation skipped. Exiting."
exit 0 exit 0
fi fi
+41 -50
View File
@@ -5,55 +5,47 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://nicolargo.github.io/glances/ | Github: https://github.com/nicolargo/glances # Source: https://nicolargo.github.io/glances/ | Github: https://github.com/nicolargo/glances
function header_info {
clear
cat <<"EOF"
________
/ ____/ /___ _____ ________ _____
/ / __/ / __ `/ __ \/ ___/ _ \/ ___/
/ /_/ / / /_/ / / / / /__/ __(__ )
\____/_/\__,_/_/ /_/\___/\___/____/
EOF
}
APP="Glances" APP="Glances"
YW=$(echo "\033[33m") APP_TYPE="addon"
GN=$(echo "\033[1;92m")
RD=$(echo "\033[01;31m")
BL=$(echo "\033[36m")
CL=$(echo "\033[m")
CM="${GN}✔️${CL}"
CROSS="${RD}✖️${CL}"
INFO="${BL}${CL}"
function msg_info() { echo -e "${INFO} ${YW}$1...${CL}"; } if ! command -v curl &>/dev/null; then
function msg_ok() { echo -e "${CM} ${GN}$1${CL}"; } printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
function msg_error() { echo -e "${CROSS} ${RD}$1${CL}"; } if [[ -f /etc/alpine-release ]]; then
apk update >/dev/null 2>&1
# Telemetry apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "glances" "addon" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "glances" "addon"
get_lxc_ip() { # Enable error handling
if command -v hostname >/dev/null 2>&1 && hostname -I 2>/dev/null; then set -Eeuo pipefail
hostname -I | awk '{print $1}' trap 'error_handler' ERR
elif command -v ip >/dev/null 2>&1; then
ip -4 addr show scope global | awk '/inet / {print $2}' | cut -d/ -f1 | head -n1 # Initialize all core functions (colors, formatting, icons, STD mode)
else load_functions
echo "127.0.0.1"
fi header_info
} get_lxc_ip
IP=$(get_lxc_ip) IP="$LOCAL_IP"
install_glances_debian() { install_glances_debian() {
msg_info "Installing dependencies" msg_info "Installing dependencies"
apt-get update >/dev/null 2>&1 $STD apt update
apt-get install -y gcc lm-sensors wireless-tools curl >/dev/null 2>&1 $STD apt install -y \
gcc \
lm-sensors \
wireless-tools \
curl
msg_ok "Installed dependencies" msg_ok "Installed dependencies"
msg_info "Setting up Python + uv" msg_info "Setting up Python + uv"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
setup_uv PYTHON_VERSION="3.12" setup_uv PYTHON_VERSION="3.12"
msg_ok "Setup Python + uv" msg_ok "Setup Python + uv"
@@ -61,10 +53,10 @@ install_glances_debian() {
cd /opt cd /opt
mkdir -p glances mkdir -p glances
cd glances cd glances
uv venv --clear $STD uv venv --clear
source .venv/bin/activate >/dev/null 2>&1 source .venv/bin/activate >/dev/null 2>&1
uv pip install --upgrade pip wheel setuptools >/dev/null 2>&1 $STD uv pip install --upgrade pip wheel setuptools
uv pip install "glances[web]" >/dev/null 2>&1 $STD uv pip install "glances[web]"
deactivate deactivate
msg_ok "Installed $APP" msg_ok "Installed $APP"
@@ -86,7 +78,7 @@ EOF
systemctl enable -q --now glances systemctl enable -q --now glances
msg_ok "Created systemd service" msg_ok "Created systemd service"
echo -e "\n$APP is now running at: http://$IP:61208\n" msg_ok "$APP is now running at: http://${IP}:61208"
} }
# update on Debian/Ubuntu # update on Debian/Ubuntu
@@ -98,7 +90,7 @@ update_glances_debian() {
msg_info "Updating $APP" msg_info "Updating $APP"
cd /opt/glances cd /opt/glances
source .venv/bin/activate source .venv/bin/activate
uv pip install --upgrade "glances[web]" >/dev/null 2>&1 $STD uv pip install --upgrade "glances[web]"
deactivate deactivate
systemctl restart glances systemctl restart glances
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
@@ -116,14 +108,13 @@ uninstall_glances_debian() {
# install on Alpine # install on Alpine
install_glances_alpine() { install_glances_alpine() {
msg_info "Installing dependencies" msg_info "Installing dependencies"
apk update >/dev/null 2>&1 $STD apk update
$STD apk add --no-cache \ $STD apk add --no-cache \
gcc musl-dev linux-headers python3-dev \ gcc musl-dev linux-headers python3-dev \
python3 py3-pip py3-virtualenv lm-sensors wireless-tools curl >/dev/null 2>&1 python3 py3-pip py3-virtualenv lm-sensors wireless-tools curl
msg_ok "Installed dependencies" msg_ok "Installed dependencies"
msg_info "Setting up Python + uv" msg_info "Setting up Python + uv"
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
setup_uv PYTHON_VERSION="3.12" setup_uv PYTHON_VERSION="3.12"
msg_ok "Setup Python + uv" msg_ok "Setup Python + uv"
@@ -131,10 +122,10 @@ install_glances_alpine() {
cd /opt cd /opt
mkdir -p glances mkdir -p glances
cd glances cd glances
uv venv --clear $STD uv venv --clear
source .venv/bin/activate source .venv/bin/activate
uv pip install --upgrade pip wheel setuptools >/dev/null 2>&1 $STD uv pip install --upgrade pip wheel setuptools
uv pip install "glances[web]" >/dev/null 2>&1 $STD uv pip install "glances[web]"
deactivate deactivate
msg_ok "Installed $APP" msg_ok "Installed $APP"
@@ -165,7 +156,7 @@ update_glances_alpine() {
msg_info "Updating $APP" msg_info "Updating $APP"
cd /opt/glances cd /opt/glances
source .venv/bin/activate source .venv/bin/activate
uv pip install --upgrade "glances[web]" >/dev/null 2>&1 $STD uv pip install --upgrade "glances[web]"
deactivate deactivate
rc-service glances restart rc-service glances restart
msg_ok "Updated successfully!" msg_ok "Updated successfully!"
+10 -16
View File
@@ -7,8 +7,13 @@
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1 if [[ -f /etc/alpine-release ]]; then
apt-get install -y curl >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -19,7 +24,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
set -Eeuo pipefail set -Eeuo pipefail
trap 'error_handler' ERR trap 'error_handler' ERR
load_functions load_functions
init_tool_telemetry "" "addon" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "homebrew" "addon"
# ============================================================================== # ==============================================================================
# CONFIGURATION # CONFIGURATION
@@ -29,18 +34,7 @@ APP="homebrew"
APP_TYPE="tools" APP_TYPE="tools"
INSTALL_PATH="/home/linuxbrew/.linuxbrew" INSTALL_PATH="/home/linuxbrew/.linuxbrew"
# ============================================================================== require_debian_like
# OS DETECTION
# ==============================================================================
if [[ -f "/etc/alpine-release" ]]; then
echo -e "${CROSS} Alpine is not supported by Homebrew. Exiting."
exit 1
elif grep -qE 'ID=debian|ID=ubuntu' /etc/os-release; then
OS="Debian"
else
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 1
fi
# ============================================================================== # ==============================================================================
# UNINSTALL # UNINSTALL
@@ -81,7 +75,7 @@ function install() {
msg_ok "Created user 'brew'" msg_ok "Created user 'brew'"
else else
msg_error "Cannot install Homebrew without a non-root user. Exiting." msg_error "Cannot install Homebrew without a non-root user. Exiting."
exit 1 exit 254
fi fi
fi fi
msg_ok "Detected User: $BREW_USER" msg_ok "Detected User: $BREW_USER"
+12 -40
View File
@@ -7,8 +7,13 @@
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1 if [[ -f /etc/alpine-release ]]; then
apt-get install -y curl >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -27,39 +32,12 @@ APP="Immich Public Proxy"
APP_TYPE="addon" APP_TYPE="addon"
INSTALL_PATH="/opt/immich-proxy" INSTALL_PATH="/opt/immich-proxy"
CONFIG_PATH="/opt/immich-proxy/app" CONFIG_PATH="/opt/immich-proxy/app"
SERVICE_PATH="/etc/systemd/system/immich-proxy.service"
DEFAULT_PORT=3000 DEFAULT_PORT=3000
# Initialize all core functions (colors, formatting, icons, $STD mode) # Initialize all core functions (colors, formatting, icons, $STD mode)
load_functions load_functions
require_debian_like
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
____ _ __ ____
/ _/___ ___ ____ ___ (_)____/ /_ / __ \_________ _ ____ __
/ // __ `__ \/ __ `__ \/ / ___/ __ \______/ /_/ / ___/ __ \| |/_/ / / /
_/ // / / / / / / / / / / / /__/ / / /_____/ ____/ / / /_/ /> </ /_/ /
/___/_/ /_/ /_/_/ /_/ /_/_/\___/_/ /_/ /_/ /_/ \____/_/|_|\__, /
/____/
EOF
}
# ==============================================================================
# OS DETECTION
# ==============================================================================
if [[ -f "/etc/alpine-release" ]]; then
msg_error "Alpine is not supported for ${APP}. Use Debian."
exit 238
elif [[ -f "/etc/debian_version" ]]; then
OS="Debian"
SERVICE_PATH="/etc/systemd/system/immich-proxy.service"
else
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 238
fi
# ============================================================================== # ==============================================================================
# UNINSTALL # UNINSTALL
@@ -83,19 +61,13 @@ function update() {
systemctl stop immich-proxy.service &>/dev/null || true systemctl stop immich-proxy.service &>/dev/null || true
msg_ok "Stopped service" msg_ok "Stopped service"
msg_info "Backing up configuration" BACKUP_DIR="/opt/immich-public-proxy_backup"
cp "$CONFIG_PATH"/.env /tmp/ipp.env.bak 2>/dev/null || true create_backup "$CONFIG_PATH"/.env "$CONFIG_PATH"/config.json
cp "$CONFIG_PATH"/config.json /tmp/ipp.config.json.bak 2>/dev/null || true
msg_ok "Backed up configuration"
NODE_VERSION="24" setup_nodejs NODE_VERSION="24" setup_nodejs
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "Immich Public Proxy" "alangrainger/immich-public-proxy" "tarball" "latest" "$INSTALL_PATH"
msg_info "Restoring configuration" restore_backup
cp /tmp/ipp.env.bak "$CONFIG_PATH"/.env 2>/dev/null || true
cp /tmp/ipp.config.json.bak "$CONFIG_PATH"/config.json 2>/dev/null || true
rm -f /tmp/ipp.*.bak
msg_ok "Restored configuration"
msg_info "Installing dependencies" msg_info "Installing dependencies"
cd "$CONFIG_PATH" cd "$CONFIG_PATH"
+12 -38
View File
@@ -7,8 +7,13 @@
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1 if [[ -f /etc/alpine-release ]]; then
apt-get install -y curl >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -27,39 +32,12 @@ APP="Jellystat"
APP_TYPE="addon" APP_TYPE="addon"
INSTALL_PATH="/opt/jellystat" INSTALL_PATH="/opt/jellystat"
CONFIG_PATH="/opt/jellystat/.env" CONFIG_PATH="/opt/jellystat/.env"
SERVICE_PATH="/etc/systemd/system/jellystat.service"
DEFAULT_PORT=3000 DEFAULT_PORT=3000
# Initialize all core functions (colors, formatting, icons, STD mode) # Initialize all core functions (colors, formatting, icons, STD mode)
load_functions load_functions
require_debian_like
# ==============================================================================
# HEADER
# ==============================================================================
function header_info {
clear
cat <<"EOF"
__ ____ __ __
/ /__ / / /_ _______/ /_____ _/ /_
__ / / _ \/ / / / / / ___/ __/ __ `/ __/
/ /_/ / __/ / / /_/ (__ ) /_/ /_/ / /_
\____/\___/_/_/\__, /____/\__/\__,_/\__/
/____/
EOF
}
# ==============================================================================
# OS DETECTION
# ==============================================================================
if [[ -f "/etc/alpine-release" ]]; then
msg_error "Alpine is not supported for ${APP}. Use Debian/Ubuntu."
exit 238
elif [[ -f "/etc/debian_version" ]]; then
OS="Debian"
SERVICE_PATH="/etc/systemd/system/jellystat.service"
else
echo -e "${CROSS} Unsupported OS detected. Exiting."
exit 238
fi
# ============================================================================== # ==============================================================================
# UNINSTALL # UNINSTALL
@@ -102,16 +80,12 @@ function update() {
systemctl stop jellystat.service &>/dev/null || true systemctl stop jellystat.service &>/dev/null || true
msg_ok "Stopped service" msg_ok "Stopped service"
msg_info "Backing up configuration" BACKUP_DIR="/opt/jellystat_backup"
cp "$CONFIG_PATH" /tmp/jellystat.env.bak 2>/dev/null || true create_backup "$CONFIG_PATH"
msg_ok "Backed up configuration"
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "jellystat" "CyferShepard/Jellystat" "tarball" "latest" "$INSTALL_PATH" CLEAN_INSTALL=1 fetch_and_deploy_gh_release "jellystat" "CyferShepard/Jellystat" "tarball" "latest" "$INSTALL_PATH"
msg_info "Restoring configuration" restore_backup
cp /tmp/jellystat.env.bak "$CONFIG_PATH" 2>/dev/null || true
rm -f /tmp/jellystat.env.bak
msg_ok "Restored configuration"
msg_info "Installing dependencies" msg_info "Installing dependencies"
cd "$INSTALL_PATH" cd "$INSTALL_PATH"
+12 -61
View File
@@ -6,8 +6,13 @@
# Source: https://komo.do/ | Github: https://github.com/moghtech/komodo # Source: https://komo.do/ | Github: https://github.com/moghtech/komodo
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1 || apk update >/dev/null 2>&1 if [[ -f /etc/alpine-release ]]; then
apt-get install -y curl >/dev/null 2>&1 || apk add --no-cache curl >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -131,25 +136,7 @@ function update() {
} }
# ============================================================================== # ==============================================================================
# PROXMOX HOST CHECK # DEPENDENCIES
# ==============================================================================
function check_proxmox_host() {
if command -v pveversion &>/dev/null; then
msg_error "Running on the Proxmox host is NOT recommended!"
msg_error "This should be executed inside an LXC container."
echo ""
echo -n "${TAB}Continue anyway? (y/N): "
read -r confirm
if [[ ! "${confirm,,}" =~ ^(y|yes)$ ]]; then
msg_warn "Aborted. Please run this inside an LXC container."
exit 0
fi
msg_warn "Proceeding on Proxmox host at your own risk!"
fi
}
# ==============================================================================
# CHECK / INSTALL DOCKER
# ============================================================================== # ==============================================================================
function ensure_openssl() { function ensure_openssl() {
if command -v openssl &>/dev/null; then if command -v openssl &>/dev/null; then
@@ -163,53 +150,17 @@ function ensure_openssl() {
$STD apt-get install -y openssl $STD apt-get install -y openssl
else else
msg_error "openssl is required but could not be installed automatically." msg_error "openssl is required but could not be installed automatically."
exit 10 exit 237
fi fi
msg_ok "Installed openssl" msg_ok "Installed openssl"
} }
function check_or_install_docker() {
if command -v docker &>/dev/null; then
msg_ok "Docker $(docker --version | cut -d' ' -f3 | tr -d ',') is available"
if docker compose version &>/dev/null; then
msg_ok "Docker Compose is available"
else
msg_error "Docker Compose plugin is not available. Please install it."
exit 10
fi
ensure_openssl
return
fi
msg_warn "Docker is not installed."
echo -n "${TAB}Install Docker now? (y/N): "
read -r install_docker_prompt
if [[ ! "${install_docker_prompt,,}" =~ ^(y|yes)$ ]]; then
msg_error "Docker is required for ${APP}. Exiting."
exit 10
fi
msg_info "Installing Docker"
if [[ -f /etc/alpine-release ]]; then
$STD apk add docker docker-cli-compose
$STD rc-service docker start
$STD rc-update add docker default
else
DOCKER_CONFIG_PATH='/etc/docker/daemon.json'
mkdir -p "$(dirname "$DOCKER_CONFIG_PATH")"
echo -e '{\n "log-driver": "journald"\n}' >"$DOCKER_CONFIG_PATH"
$STD sh <(curl -fsSL https://get.docker.com)
fi
msg_ok "Installed Docker"
ensure_openssl
}
# ============================================================================== # ==============================================================================
# INSTALL # INSTALL
# ============================================================================== # ==============================================================================
function install() { function install() {
check_or_install_docker ensure_docker
ensure_openssl
echo -e "${TAB}Choose the database for Komodo:" echo -e "${TAB}Choose the database for Komodo:"
echo -e "${TAB} 1) MongoDB (recommended)" echo -e "${TAB} 1) MongoDB (recommended)"
@@ -292,7 +243,7 @@ if [[ "${type:-}" == "update" ]]; then
fi fi
header_info header_info
check_proxmox_host confirm_not_pve_host
get_lxc_ip get_lxc_ip
# Declare variables used by find_compose_file # Declare variables used by find_compose_file
+40 -89
View File
@@ -5,74 +5,31 @@
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.netdata.cloud/ | Github: https://github.com/netdata/netdata # Source: https://www.netdata.cloud/ | Github: https://github.com/netdata/netdata
function header_info { APP="Netdata"
clear APP_TYPE="addon"
cat <<"EOF"
_ __ __ ____ __
/ | / /__ / /_/ __ \____ _/ /_____ _
/ |/ / _ \/ __/ / / / __ `/ __/ __ `/
/ /| / __/ /_/ /_/ / /_/ / /_/ /_/ /
/_/ |_/\___/\__/_____/\__,_/\__/\__,_/
EOF if ! command -v curl &>/dev/null; then
} printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
if [[ -f /etc/alpine-release ]]; then
YW=$(echo "\033[33m") apk update >/dev/null 2>&1
BL=$(echo "\033[36m") apk add --no-cache curl >/dev/null 2>&1
RD=$(echo "\033[01;31m") else
GN=$(echo "\033[1;92m") apt-get update >/dev/null 2>&1
CL=$(echo "\033[m") apt-get install -y curl >/dev/null 2>&1
BFR="\\r\\033[K" fi
HOLD="-" fi
CM="${GN}${CL}" source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
silent() { "$@" >/dev/null 2>&1; } source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/error_handler.func)
# Telemetry
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/api.func) 2>/dev/null || true
declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "netdata" "addon" declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "netdata" "addon"
set -e # Enable error handling
header_info set -Eeuo pipefail
echo "Loading..." trap 'error_handler' ERR
function msg_info() {
local msg="$1"
echo -ne " ${HOLD} ${YW}${msg}..."
}
function msg_ok() { # Initialize all core functions (colors, formatting, icons, STD mode)
local msg="$1" load_functions
echo -e "${BFR} ${CM} ${GN}${msg}${CL}"
}
function msg_error() { echo -e "${RD}$1${CL}"; }
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
# Supported: Proxmox VE 8.0.x 8.9.x and 9.09.x
pve_check() {
local PVE_VER
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
# Check for Proxmox VE 8.x: allow 8.08.9
if [[ "$PVE_VER" =~ ^8\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR < 0 || MINOR > 9)); then
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported: Proxmox VE version 8.0 8.9"
exit 105
fi
return 0
fi
# Check for Proxmox VE 9.x: allow 9.09.x
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
return 0
fi
# All other unsupported versions
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported versions: Proxmox VE 8.0 8.9 or 9.09.x"
exit 105
}
detect_codename() { detect_codename() {
source /etc/os-release source /etc/os-release
@@ -83,7 +40,7 @@ detect_codename() {
CODENAME="${VERSION_CODENAME:-}" CODENAME="${VERSION_CODENAME:-}"
if [[ -z "$CODENAME" ]]; then if [[ -z "$CODENAME" ]]; then
msg_error "Could not detect Debian codename." msg_error "Could not detect Debian codename."
exit 71 exit 238
fi fi
echo "$CODENAME" echo "$CODENAME"
} }
@@ -97,9 +54,8 @@ get_latest_repo_pkg() {
} }
install() { install() {
header_info
while true; do while true; do
read -p "Are you sure you want to install NetData on Proxmox VE host. Proceed(y/n)? " yn read -r -p "Are you sure you want to install ${APP} on Proxmox VE host. Proceed(y/n)? " yn
case $yn in case $yn in
[Yy]*) break ;; [Yy]*) break ;;
[Nn]*) exit ;; [Nn]*) exit ;;
@@ -107,56 +63,51 @@ install() {
esac esac
done done
read -r -p "Verbose mode? <y/N> " prompt
[[ ${prompt,,} =~ ^(y|yes)$ ]] && STD="" || STD="silent"
CODENAME=$(detect_codename) CODENAME=$(detect_codename)
REPO_URL="https://repo.netdata.cloud/repos/repoconfig/debian/${CODENAME}/" REPO_URL="https://repo.netdata.cloud/repos/repoconfig/debian/${CODENAME}/"
msg_info "Setting up repository" msg_info "Setting up repository"
$STD apt-get install -y debian-keyring $STD apt install -y debian-keyring
PKG=$(get_latest_repo_pkg "$REPO_URL") PKG=$(get_latest_repo_pkg "$REPO_URL")
if [[ -z "$PKG" ]]; then if [[ -z "$PKG" ]]; then
msg_error "Could not find netdata-repo package for Debian $CODENAME" msg_error "Could not find netdata-repo package for Debian $CODENAME"
exit 237 exit 237
fi fi
curl -fsSL "${REPO_URL}${PKG}" -o "$PKG" TMP_DEB=$(mktemp --suffix=.deb)
$STD dpkg -i "$PKG" curl -fsSL "${REPO_URL}${PKG}" -o "$TMP_DEB"
rm -f "$PKG" $STD dpkg -i "$TMP_DEB"
rm -f "$TMP_DEB"
msg_ok "Set up repository" msg_ok "Set up repository"
msg_info "Installing Netdata" msg_info "Installing ${APP}"
$STD apt-get update $STD apt update
$STD apt-get install -y netdata $STD apt install -y netdata
msg_ok "Installed Netdata" msg_ok "Installed ${APP}"
msg_ok "Completed successfully!\n" msg_ok "Completed successfully!\n"
echo -e "\n Netdata should be reachable at${BL} http://$(hostname -I | awk '{print $1}'):19999 ${CL}\n" get_lxc_ip
echo -e "\n${APP} should be reachable at${BL} http://${LOCAL_IP}:19999 ${CL}\n"
} }
uninstall() { uninstall() {
header_info msg_info "Uninstalling ${APP}"
read -r -p "Verbose mode? <y/N> " prompt
[[ ${prompt,,} =~ ^(y|yes)$ ]] && STD="" || STD="silent"
msg_info "Uninstalling Netdata"
systemctl stop netdata || true systemctl stop netdata || true
rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d rm -rf /var/log/netdata /var/lib/netdata /var/cache/netdata /etc/netdata/go.d
rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list rm -rf /etc/apt/trusted.gpg.d/netdata-archive-keyring.gpg /etc/apt/sources.list.d/netdata.list
$STD apt-get remove --purge -y netdata netdata-repo $STD apt remove --purge -y netdata netdata-repo
systemctl daemon-reload systemctl daemon-reload
$STD apt autoremove -y $STD apt autoremove -y
$STD userdel netdata || true $STD userdel netdata || true
msg_ok "Uninstalled Netdata" msg_ok "Uninstalled ${APP}"
msg_ok "Completed successfully!\n" msg_ok "Completed successfully!\n"
} }
header_info header_info
pve_check require_pve_host
OPTIONS=(Install "Install NetData on Proxmox VE" OPTIONS=(Install "Install ${APP} on Proxmox VE"
Uninstall "Uninstall NetData from Proxmox VE") Uninstall "Uninstall ${APP} from Proxmox VE")
CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NetData" \ CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "${APP}" \
--menu "Select an option:" 10 58 2 "${OPTIONS[@]}" 3>&1 1>&2 2>&3) --menu "Select an option:" 10 58 2 "${OPTIONS[@]}" 3>&1 1>&2 2>&3)
case $CHOICE in case $CHOICE in
+8 -10
View File
@@ -7,8 +7,13 @@
if ! command -v curl &>/dev/null; then if ! command -v curl &>/dev/null; then
printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2 printf "\r\e[2K%b" '\033[93m Setup Source \033[m' >&2
apt-get update >/dev/null 2>&1 if [[ -f /etc/alpine-release ]]; then
apt-get install -y curl >/dev/null 2>&1 apk update >/dev/null 2>&1
apk add --no-cache curl >/dev/null 2>&1
else
apt-get update >/dev/null 2>&1
apt-get install -y curl >/dev/null 2>&1
fi
fi fi
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/core.func)
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func)
@@ -20,6 +25,7 @@ declare -f init_tool_telemetry &>/dev/null && init_tool_telemetry "nextcloud-exp
set -Eeuo pipefail set -Eeuo pipefail
trap 'error_handler' ERR trap 'error_handler' ERR
load_functions load_functions
require_debian_like
# ============================================================================== # ==============================================================================
# CONFIGURATION # CONFIGURATION
@@ -31,14 +37,6 @@ BINARY_PATH="/usr/bin/nextcloud-exporter"
CONFIG_PATH="/etc/nextcloud-exporter.env" CONFIG_PATH="/etc/nextcloud-exporter.env"
SERVICE_PATH="/etc/systemd/system/nextcloud-exporter.service" SERVICE_PATH="/etc/systemd/system/nextcloud-exporter.service"
# ==============================================================================
# OS DETECTION
# ==============================================================================
if ! grep -qE 'ID=debian|ID=ubuntu' /etc/os-release 2>/dev/null; then
echo -e "${CROSS} Unsupported OS detected. This script only supports Debian and Ubuntu."
exit 238
fi
# ============================================================================== # ==============================================================================
# UNINSTALL # UNINSTALL
# ============================================================================== # ==============================================================================

Some files were not shown because too many files have changed in this diff Show More