mirror of
https://github.com/soulis-1256/assemblrr.git
synced 2026-10-20 11:31:52 +00:00
Tick elapsed seconds on blocking waits, not just API polls
Recyclarr sync, backup/restore archives, git fetches, and Prowlarr indexer sync now use wait_while/wait_inline. Compose up/pull keep their own progress instead of a fake overlay.
This commit is contained in:
parent
1149dfaae4
commit
bdd5f263b5
7 changed files with 59 additions and 20 deletions
28
bin/cli.sh
28
bin/cli.sh
|
|
@ -289,7 +289,6 @@ backup_app() {
|
|||
"${DC[@]}" stop > /dev/null 2>&1 || log_error "Failed to stop services"
|
||||
|
||||
echo -e "\nBacking up ${APP_DISPLAY_NAME} to $destination..."
|
||||
echo "This may take a while depending on the size of your installation."
|
||||
|
||||
# Copy current CLI script and lib modules, create backup (skip copy if running from install dir)
|
||||
local running_cli; running_cli="$(realpath "${BASH_SOURCE[0]}" 2>/dev/null || echo "${_cli_self}/cli.sh")"
|
||||
|
|
@ -304,11 +303,12 @@ backup_app() {
|
|||
fi
|
||||
|
||||
# Run tar inside an alpine container bound to the INSTALL_DIR and the destination (excluding temp/cache and sockets)
|
||||
run_docker run --rm \
|
||||
if ! wait_while "Creating backup archive" run_docker run --rm \
|
||||
-v "$INSTALL_DIR:/source" \
|
||||
-v "$(dirname "$backup_file"):/backup" \
|
||||
alpine tar --exclude='./transcoding-temp' --exclude='./config/jellyfin/cache' --exclude='ipc-socket' -czf "/backup/$(basename "$backup_file")" -C /source . ||
|
||||
alpine tar --exclude='./transcoding-temp' --exclude='./config/jellyfin/cache' --exclude='ipc-socket' -czf "/backup/$(basename "$backup_file")" -C /source .; then
|
||||
log_error "Failed to create backup archive"
|
||||
fi
|
||||
|
||||
echo -e "\nStarting ${APP_DISPLAY_NAME} services..."
|
||||
"${DC[@]}" start > /dev/null 2>&1 || log_warning "Failed to restart services"
|
||||
|
|
@ -842,22 +842,22 @@ restore_app() {
|
|||
local backup_dir="${INSTALL_DIR}_backup_${timestamp}"
|
||||
|
||||
echo "Creating safety snapshot of current state at ${backup_dir}..."
|
||||
# Use alpine container to copy the snapshot safely
|
||||
run_docker run --rm \
|
||||
wait_while "Creating safety snapshot" run_docker run --rm \
|
||||
-v "$(dirname "$INSTALL_DIR"):/target_parent" \
|
||||
alpine cp -r "/target_parent/$(basename "$INSTALL_DIR")" "/target_parent/$(basename "$backup_dir")" || log_warning "Failed to create safety snapshot"
|
||||
|
||||
# Remove files using alpine so we don't hit permission denied issues
|
||||
run_docker run --rm \
|
||||
alpine cp -r "/target_parent/$(basename "$INSTALL_DIR")" "/target_parent/$(basename "$backup_dir")" \
|
||||
|| log_warning "Failed to create safety snapshot"
|
||||
|
||||
wait_while "Clearing install directory" run_docker run --rm \
|
||||
-v "$INSTALL_DIR:/target" \
|
||||
alpine sh -c 'find /target -mindepth 1 -maxdepth 1 ! -name "media" ! -name "downloads" -exec rm -rf {} +'
|
||||
|
||||
# Extract using alpine
|
||||
|
||||
local abs_backup_file; abs_backup_file=$(realpath "$backup_file")
|
||||
run_docker run --rm \
|
||||
if ! wait_while "Restoring from backup" run_docker run --rm \
|
||||
-v "$INSTALL_DIR:/target" \
|
||||
-v "$(dirname "$abs_backup_file"):/backup" \
|
||||
alpine tar -xzf "/backup/$(basename "$abs_backup_file")" -C /target || log_error "Failed to extract backup"
|
||||
alpine tar -xzf "/backup/$(basename "$abs_backup_file")" -C /target; then
|
||||
log_error "Failed to extract backup"
|
||||
fi
|
||||
|
||||
echo "Starting ${APP_DISPLAY_NAME} services..."
|
||||
"${DC[@]}" up -d --remove-orphans || log_warning "Failed to start services"
|
||||
|
|
@ -921,7 +921,7 @@ update_cli() {
|
|||
local tmp_dir
|
||||
tmp_dir=$(mktemp -d)
|
||||
|
||||
if ! git clone --depth=1 "${APP_REPO_URL}" "$tmp_dir/assemblrr" 2>/dev/null; then
|
||||
if ! wait_while "Updating CLI from git" git clone --depth=1 "${APP_REPO_URL}" "$tmp_dir/assemblrr"; then
|
||||
log_error "Failed to clone ${APP_REPO_URL}. Check your internet connection and repository access."
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -715,7 +715,7 @@ install_cli
|
|||
set_permissions
|
||||
|
||||
log_success "Install files ready — starting services..."
|
||||
log_info "Starting ${APP_DISPLAY_NAME} services (this may take a while)..."
|
||||
log_info "Starting ${APP_DISPLAY_NAME} services..."
|
||||
# Ensure mounts still exist/owned immediately before the full stack comes up
|
||||
prepare_install_dirs "$install_directory" "$puid" "$pgid"
|
||||
build_compose_args "$install_directory" "${setup_vpn,,}"
|
||||
|
|
|
|||
|
|
@ -724,11 +724,14 @@ wait_for_arr_indexer_sync() {
|
|||
local rc
|
||||
rc=$(api_get "7878" "/api/v3/indexer" "$radarr_key" | jq 'length' 2>/dev/null || echo 0)
|
||||
if [ "${rc:-0}" -gt 0 ]; then
|
||||
[ "$waited" -gt 0 ] && echo >&2
|
||||
return 0
|
||||
fi
|
||||
wait_inline "Waiting for Radarr indexers from Prowlarr" "$waited"
|
||||
sleep 2
|
||||
waited=$((waited + 2))
|
||||
done
|
||||
echo >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
|
|||
31
lib/core.sh
31
lib/core.sh
|
|
@ -37,6 +37,37 @@ wait_inline() {
|
|||
printf '\r%s (%ss) ' "$label" "$secs" >&2
|
||||
}
|
||||
|
||||
# Run a command while updating wait_inline every second.
|
||||
# Captures stdout+stderr in WAIT_WHILE_OUTPUT. Returns the command's exit status.
|
||||
wait_while() {
|
||||
local label="$1"
|
||||
shift
|
||||
local out ticker rc=0 had_errexit=0
|
||||
[ $# -gt 0 ] || return 1
|
||||
out=$(mktemp)
|
||||
[[ $- == *e* ]] && had_errexit=1
|
||||
(
|
||||
secs=0
|
||||
trap 'exit 0' TERM INT
|
||||
while true; do
|
||||
wait_inline "$label" "$secs"
|
||||
sleep 1
|
||||
secs=$((secs + 1))
|
||||
done
|
||||
) &
|
||||
ticker=$!
|
||||
set +e
|
||||
"$@" >"$out" 2>&1
|
||||
rc=$?
|
||||
[ "$had_errexit" = 1 ] && set -e
|
||||
kill "$ticker" 2>/dev/null || true
|
||||
wait "$ticker" 2>/dev/null || true
|
||||
echo >&2
|
||||
WAIT_WHILE_OUTPUT=$(cat "$out" 2>/dev/null || true)
|
||||
rm -f "$out"
|
||||
return "$rc"
|
||||
}
|
||||
|
||||
# --- Safe source ---
|
||||
# Safely source a config file — validates that it contains only KEY=VALUE
|
||||
# assignments (no command substitution, pipes, etc.) before sourcing
|
||||
|
|
|
|||
|
|
@ -235,11 +235,11 @@ configure_recyclarr() {
|
|||
pack_count=$(find "$recyclarr_config_dir/includes" -maxdepth 1 -name '*.yml' | wc -l | tr -d ' ')
|
||||
log_step "Recyclarr: generated config (${pack_count} include packs; Seerr default: ${default_label})"
|
||||
|
||||
_cfg_log_info "Recyclarr: syncing TRaSH Guides to Radarr and Sonarr... this might take a moment"
|
||||
local sync_out
|
||||
if sync_out=$(docker exec recyclarr recyclarr sync 2>&1); then
|
||||
if wait_while "Syncing Recyclarr (TRaSH Guides)" docker exec recyclarr recyclarr sync; then
|
||||
log_step "Recyclarr: synced Custom Formats and Quality Profiles successfully"
|
||||
else
|
||||
sync_out="${WAIT_WHILE_OUTPUT:-}"
|
||||
log_step_fail "Recyclarr: failed to sync to Radarr/Sonarr"
|
||||
echo "$sync_out" | grep -E '•|Error|error|Invalid|YAML' | head -5 | while IFS= read -r line; do
|
||||
_cfg_log_info " $line"
|
||||
|
|
|
|||
|
|
@ -63,11 +63,10 @@ resolve_upgrade_source() {
|
|||
local repo="${APP_REPO_URL:-https://github.com/soulis-1256/assemblrr}"
|
||||
tmp=$(mktemp -d)
|
||||
UPGRADE_SOURCE_TEMP="$tmp"
|
||||
log_info "Fetching ${repo} @ ${ref}..."
|
||||
if ! git clone --depth=1 --branch "$ref" "$repo" "$tmp/assemblrr" 2>/dev/null; then
|
||||
if ! wait_while "Fetching assemblrr @ ${ref}" git clone --depth=1 --branch "$ref" "$repo" "$tmp/assemblrr"; then
|
||||
# branch might be a commit or default branch name failed; try without --branch then checkout
|
||||
rm -rf "$tmp/assemblrr"
|
||||
if ! git clone --depth=1 "$repo" "$tmp/assemblrr" 2>/dev/null; then
|
||||
if ! wait_while "Fetching assemblrr (default branch)" git clone --depth=1 "$repo" "$tmp/assemblrr"; then
|
||||
[ -n "$UPGRADE_SOURCE_TEMP" ] && rm -rf "$UPGRADE_SOURCE_TEMP"
|
||||
log_error "Failed to clone ${repo}. Check network and APP_REPO_URL."
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@ trap 'rm -rf "$tmp"' EXIT
|
|||
test_suite "wait_inline"
|
||||
assert_contains "$(wait_inline "Waiting for Radarr API" 12 2>&1)" \
|
||||
"Waiting for Radarr API (12s)" "shows elapsed seconds"
|
||||
WAIT_WHILE_OUTPUT=""
|
||||
wait_while "unit-test" bash -c 'printf hi' >/dev/null 2>&1
|
||||
assert_eq "hi" "$WAIT_WHILE_OUTPUT" "captures command output"
|
||||
rc=0
|
||||
wait_while "unit-fail" bash -c 'exit 3' >/dev/null 2>&1 || rc=$?
|
||||
assert_eq "3" "$rc" "propagates exit status"
|
||||
|
||||
# --- expand_path ---
|
||||
test_suite "expand_path"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue