An end-to-end run restored 4 of 13 apps and reported
"First-run restore complete — 4 apps restored" as a success.
Two truncations, and fixing the first had hidden the second:
* the CLI dispatcher calls handlers with no arguments, so "$@"/shift inside
one operate on an empty list. Fixed earlier with LP_CLI_ARGS.
* LP_CLI_ARGS was built from start.sh's "$@" — but the root wrapper invokes
start.sh with exactly nine hardcoded positional slots. So the array could
never hold more than nine entries, and `${LP_CLI_ARGS[@]:5}` yielded at
most four app names.
The wrapper now forwards the real argv after those nine slots (they stay
untouched: every dispatcher reads them, and unset ones must keep arriving as
the literal "empty"), and start.sh reads it back as "${@:10}". Verified: a
preflight given six apps checks six, where five was the previous ceiling.
footprint_version 7 -> 8, since the wrapper is root-owned and baked at install.
Two further fixes so a truncation cannot pass as success again:
* restoreFirstRunBulk with no app list is now a whole-host restore — it
discovers the host's apps and re-applies the preflight. The installer's
report runs in its own process, so without this an app the user was told
would be skipped got restored anyway. init.sh now passes no list, so a
whole-host restore builds nothing that can be truncated.
* it counts what actually landed and returns non-zero naming the failures,
instead of reporting the length of the list it was handed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
102 lines
4.3 KiB
Bash
Executable File
102 lines
4.3 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). Two separate
|
|
# truncations conspired here, and fixing only the first hid the second:
|
|
#
|
|
# * the CLI dispatcher calls its handlers with NO arguments, so "$@" and
|
|
# `shift` inside a handler operate on an empty list
|
|
# * the root wrapper invokes this script with exactly nine positional slots,
|
|
# so reading "$@" here caps any list at nine — which for `first-run bulk`
|
|
# meant four app names. A 13-app restore quietly restored four and then
|
|
# reported "First-run restore complete — 4 apps restored" as a success.
|
|
#
|
|
# So the wrapper now appends the real argv after those nine slots, and this is
|
|
# where it is read back. Offsets below are into the true argv, unchanged.
|
|
declare -a LP_CLI_ARGS=("${@:10}")
|
|
|
|
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; |