`restore preflight <loc_idx> <host>` reads every app's manifest out of its
own snapshot (engineDumpFile pulls a single file without restoring) and
checks it against this machine before anything is written:
* an app this version no longer ships is skipped — restoring one
produces a directory that can never start, and looks like success
until someone opens it
* an app that will not fit is skipped individually, because filling the
disk part-way through takes the apps that already landed with it
* a manifest naming a storage location this machine lacks falls back to
the default, and says which app moved where
The installer's restore path runs it and asks once before continuing.
Two bugs found by running it against the live repository rather than
reading it:
The CLI dispatcher calls handlers with NO arguments, so `shift 4; "$@"`
inside one operates on an empty list. `restore first-run bulk` has always
had this — a bulk restore silently received zero apps. Fixed at the entry
point: start.sh now captures LP_CLI_ARGS from "$@", and both call sites
use it.
And the wrapper fills unset argv slots with the literal string "empty"
(${5:-empty} … ${9:-empty}), so a trailing slot arrives as a five-
character app name rather than a blank. Filtering on -n alone let five
phantom apps through and reported each as "no longer shipped". Both call
sites now drop the sentinel. That also caps any explicit list at five, so
preflight discovers the host's apps itself when given none.
Verified against the live repository: 13 apps discovered and checked.
Sizes read "?" there because those snapshots predate manifests carrying
size_bytes — the intended graceful fallback, not a refusal.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
93 lines
3.8 KiB
Bash
Executable File
93 lines
3.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Used for mainly CLI
|
|
initial_command1="$1"
|
|
initial_command2="$2"
|
|
initial_command3="$3"
|
|
initial_command4="$4"
|
|
initial_command5="$5"
|
|
initial_command6="$6"
|
|
initial_command7="$7"
|
|
# The full argument vector, for commands that take an open-ended list (restore
|
|
# preflight / first-run bulk take any number of app names). The CLI dispatcher
|
|
# calls its handlers with NO arguments, so "$@" and `shift` inside a handler
|
|
# operate on an empty list — which silently truncated those lists to nothing.
|
|
declare -a LP_CLI_ARGS=("$@")
|
|
|
|
displayLibrePortalLogo()
|
|
{
|
|
[[ "$LIBREPORTAL_SKIP_LOGO" == "1" ]] && return
|
|
local hbar; hbar=$(printf '═%.0s' $(seq 1 50))
|
|
printf '\n╔%s╗\n' "$hbar"
|
|
printf '║%6s%s%8s║\n' '' '╦ ┬┌┐ ┬─┐┌─┐ ╭─╮ ╔═╗┌─┐┬─┐┌┬┐┌─┐┬' ''
|
|
printf '║%6s%s%8s║\n' '' '║ │├┴┐├┬┘├┤ │◉│ ╠═╝│ │├┬┘ │ ├─┤│' ''
|
|
printf '║%6s%s%6s║\n' '' '╩═╝┴└─┘┴└─└─┘ ╨─╨ ╩ └─┘┴└─ ┴ ┴ ┴┴─┘' ''
|
|
printf '╚%s╝\n\n' "$hbar"
|
|
}
|
|
|
|
showRunHelp()
|
|
{
|
|
displayLibrePortalLogo;
|
|
echo "Available Run Commands:"
|
|
echo ""
|
|
echo " libreportal run install - Run the automated installer (WebUI flow)"
|
|
echo " libreportal run terminal - Open the terminal menu / Setup Wizard"
|
|
echo ""
|
|
echo "Pick one to continue."
|
|
echo ""
|
|
}
|
|
|
|
initLibrePortal()
|
|
{
|
|
# Load the relocatable path roots up front (sets logs_dir/docker_dir/…) — the
|
|
# install-log below needs logs_dir before load_sources runs. cwd is the install
|
|
# dir, so the relative path resolves.
|
|
[[ -f "scripts/source/paths.sh" ]] && source "scripts/source/paths.sh"
|
|
|
|
# Internal launcher: the systemd unit starts the task processor through this
|
|
# stable entry (`libreportal __task-processor`) so the unit never bakes the
|
|
# processor's in-tree path — only this hand-off knows where the script lives.
|
|
# paths.sh above resolved install_scripts_dir; export it so the exec'd
|
|
# processor inherits the roots and skips its own self-location. Intercept here,
|
|
# before the heavy load_sources — we only need to hand off to the daemon.
|
|
if [[ "$initial_command1" == "__task-processor" ]]; then
|
|
export install_scripts_dir
|
|
exec "${install_scripts_dir}task/crontab_task_processor.sh" start_script
|
|
fi
|
|
|
|
# For the full application loading
|
|
if [[ "$initial_command1" == "run" ]]; then
|
|
if [[ -z "$initial_command2" ]]; then
|
|
showRunHelp;
|
|
exit 0
|
|
fi
|
|
|
|
init_run_flag="true"
|
|
|
|
# Capture the install run to a log so credentials/URLs can be recovered
|
|
# after we clear the screen at the end.
|
|
if [[ "$initial_command2" == "install" ]]; then
|
|
install_log_path="${logs_dir:-/libreportal-system/logs/}install-$(date +%Y%m%d-%H%M%S).log"
|
|
sudo mkdir -p "${logs_dir:-/libreportal-system/logs/}" 2>/dev/null
|
|
sudo touch "$install_log_path" 2>/dev/null
|
|
# Own it by whoever runs the install (the manager under Model A) so the
|
|
# tee below — which runs as that user, not root — can append. A
|
|
# sudo-touched file is root:root 644, leaving the manager unable to
|
|
# write it → the empty install-*.log files.
|
|
sudo chown "$(id -un):$(id -gn)" "$install_log_path" 2>/dev/null
|
|
sudo chmod 644 "$install_log_path" 2>/dev/null
|
|
export install_log_path
|
|
exec > >(tee -a "$install_log_path") 2>&1
|
|
fi
|
|
|
|
displayLibrePortalLogo;
|
|
source "scripts/source/load_sources.sh"
|
|
else
|
|
# For the CLI loading
|
|
init_run_flag="false"
|
|
displayLibrePortalLogo;
|
|
source "scripts/source/load_sources.sh"
|
|
fi
|
|
}
|
|
|
|
initLibrePortal; |