11 Commits

Author SHA1 Message Date
librelad
7988778f73 refactor(task): move processor out of crontab/ + launch via stable CLI entry
The task processor is a systemd-service daemon, not a cron job — move it out
of the misleadingly-named scripts/crontab/task/ to scripts/task/.

To stop the systemd unit from baking the processor's in-tree path (the footprint
coupling that forces a reinstall on every reorg), the unit now ExecStarts the
stable wrapper: /usr/local/bin/libreportal __task-processor. start.sh intercepts
that early (after paths.sh, before the heavy load), exports install_scripts_dir,
and exec's the processor with start_script. Future moves/renames need only the
one hand-off updated + a regen — no footprint bump.

- git mv scripts/crontab/task -> scripts/task (filenames kept; cron-watchdog grep
  + function names unchanged)
- libreportal-svc: ExecStart -> stable wrapper launcher
- start.sh: __task-processor internal launcher (export install_scripts_dir; exec)
- crontab_task_processor.sh: fix self-location ../.. -> .. for the new 1-level
  depth (latent bug the move would otherwise have introduced)
- regen files_*/function_manifest; add task_scripts to the app/cli aggregates
- footprint_version 3 -> 4 (root-owned svc unit changed -> needs a root reinstall)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-31 01:52:33 +01:00
librelad
e4872ab511 refactor(paths): single source of truth for a relocatable, split layout (phase 1)
Introduce scripts/source/paths.sh as the canonical path resolver for three
independently-relocatable roots:
  LP_SYSTEM_DIR      manager-owned control plane (configs/logs/install/db/ssl/ssh/migrate)
  LP_CONTAINERS_DIR  container-user-owned live app data
  LP_BACKUPS_DIR     container-user-owned backup repos (own mount-able)

Roots come from the environment when set (install bakes them; CLI/app inherit
from init.sh), else default to /libreportal-*. A transitional compat default
keeps EXISTING installs (legacy single /docker tree, by config marker) on /docker
until a deliberate reinstall, so deploying this never strands a running box.

- init.sh derives the same vars inline (self-contained for the bare /root/init.sh
  reinstall case); paths.sh mirrors it for the standalone task/check processors,
  which now self-locate their scripts dir and source it.
- Replace functional /docker literals with the derived vars across runtime,
  install, backup, crontab, crowdsec/restic, headscale, and reinstall paths;
  clean the inert '== /docker/containers/*' guard fallbacks to the variable form.
- backend: CONTAINERS_DIR now from LP_CONTAINERS_DIR (compose env, filled at
  generation via a new CONTAINERS_DIR_TAG), legacy-safe default for un-recreated
  containers.
- backup default path falls back to the backups root; exclude paths.sh from the
  sourced-file arrays (bootstrap file, sourced explicitly).

The CLI-wrapper heredoc + root helpers still reference /docker; those get baked
in phase 3. No layout/ownership change yet (phase 2).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-25 15:09:39 +01:00
librelad
a978749ee8 fix(install): bridge cross-owner folder copies + writable install log
Two pre-existing bugs a genuinely-clean rootless install exposes:

copyFolder picked the copy user by destination only: a manager-owned
source (e.g. the install dir) copied into the dockerinstall-owned
containers/ ran the cp AS dockerinstall, which can't read the source ->
"cp: Permission denied". The `local result=$(...)` then masked the
failure (local returns 0) so checkSuccess printed success. This broke
installLibrePortalImageWebUI: the WebUI dir wasn't populated, so
initializeAppVariables couldn't read libreportal.config ("No app name
provided"), compose tags were never substituted, and the WebUI container
couldn't start (user: "USER_DATA"). Fix: when source and destination
owners differ (manager -> container), bridge with a tar pipe — the
manager reads, dockerinstall writes — with pipefail so a read-side
failure is no longer masked.

start.sh created the per-run install log with `sudo touch` (root:root
644) but tee's to it as the manager -> "tee: Permission denied" -> every
install-*.log was empty. Fix: chown the log to the user running the
install so the tee can append.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-24 21:20:48 +01:00
librelad
f7240cd096 style(cli): box section headers and the logo in double-line borders
Swap the ### hash headers (isHeader) for a ╔═╗ ║ ╚═╝ double-line box and
wrap the LibrePortal logo in a matching 52-wide box. Build the rule with
printf-repeat and fixed pad widths instead of tr/${#} so multibyte box
chars stay aligned regardless of locale. Mirrors the credentials panel.

Applied to all three copies (markers.sh, init.sh, generate_arrays.sh).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-22 11:50:45 +01:00
librelad
7ec1e33b56 style(branding): drop the divider line under the logo
Keep just the wordmark + portal; the underline read poorly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-22 00:34:14 +01:00
librelad
0c7eac89fc style(branding): revert divider to low marks, keep top blank line
The raised (‾▔) divider read strangely; go back to the low _▁ step-ticks
the prior look used and restore the leading blank line. Keep the divider
extended to the end of the final letter.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-22 00:26:53 +01:00
librelad
77d9cf9809 style(branding): raise divider, extend to last glyph, drop top blank line
Raise the underline to high marks (‾▔) so it tucks under the wordmark,
extend it to reach the end of the final letter, and remove the leading
blank line so the banner starts flush.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-22 00:24:34 +01:00
librelad
d6b6b1ef8a style(branding): indent logo + add step-tick divider
Add a small left gap before the wordmark and a step-tick underline
(_▁ repeated) matched to the logo width.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-22 00:20:25 +01:00
librelad
e7e9a8ce5c fix(branding): portal glyph stands on feet + wider spacing
The portal between Libre/Portal was a closed ring ("just a circle"); give it
two feet (╨─╨) and a touch more breathing room on each side.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-22 00:13:41 +01:00
librelad
e2d9e701b9 feat(branding): replace EasyDocker ASCII logo with LibrePortal wordmark
The startup banner (displayLibrePortalLogo in init.sh/start.sh and the
generate_arrays.sh splash) still rendered the old "EASY DOCKER" figlet art.
Swap it for a LibrePortal wordmark — Calvin S mixed-case "Libre"/"Portal"
with a small framed portal glyph between the two words.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-22 00:07:55 +01:00
librelad
875a60f90f LibrePortal v0.1.0 — initial release
A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys,
Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun
VPN routing, and a web dashboard to manage it all.

Free & open forever to self-host; optional paid hosted services fund it.
See PROMISE.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-21 20:37:54 +01:00