0.16.1-2 Installer Fix

This commit is contained in:
2026-04-29 10:25:41 +00:00
parent c978bcc4ef
commit a6ff18c8c3
8 changed files with 134 additions and 26 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "ripster-backend",
"version": "0.16.1-1",
"version": "0.16.1-2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ripster-backend",
"version": "0.16.1-1",
"version": "0.16.1-2",
"dependencies": {
"archiver": "^7.0.1",
"cors": "^2.8.5",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ripster-backend",
"version": "0.16.1-1",
"version": "0.16.1-2",
"private": true,
"type": "commonjs",
"scripts": {
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "ripster-frontend",
"version": "0.16.1-1",
"version": "0.16.1-2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ripster-frontend",
"version": "0.16.1-1",
"version": "0.16.1-2",
"dependencies": {
"primeicons": "^7.0.0",
"primereact": "^10.9.2",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ripster-frontend",
"version": "0.16.1-1",
"version": "0.16.1-2",
"private": true,
"type": "module",
"scripts": {
+35 -2
View File
@@ -36,6 +36,17 @@ function normalizeStage(value) {
return String(value || '').trim().toUpperCase();
}
function isRunningStage(value) {
const normalized = normalizeStage(value);
return normalized === 'ANALYZING'
|| normalized === 'RIPPING'
|| normalized === 'MEDIAINFO_CHECK'
|| normalized === 'ENCODING'
|| normalized === 'CD_ANALYZING'
|| normalized === 'CD_RIPPING'
|| normalized === 'CD_ENCODING';
}
function isTerminalStage(value) {
const normalized = normalizeStage(value);
return normalized === 'FINISHED' || normalized === 'ERROR' || normalized === 'CANCELLED';
@@ -315,17 +326,24 @@ function App() {
const isCdProgressStage = progressStage === 'CD_ANALYZING'
|| progressStage === 'CD_RIPPING'
|| progressStage === 'CD_ENCODING';
const incomingIsRunning = isRunningStage(progressStage);
const incomingIsTerminal = isTerminalStage(progressStage);
const prevActiveJobId = normalizeJobId(prev?.activeJobId || prev?.context?.jobId);
const prevJobProgress = normalizedProgressJobId
? (prev?.jobProgress?.[normalizedProgressJobId] || null)
: null;
const prevJobProgressState = normalizeStage(prevJobProgress?.state);
const prevJobProgressIsRunning = isRunningStage(prevJobProgressState);
const prevJobProgressIsTerminal = isTerminalStage(prevJobProgressState);
const matchingCdDriveEntry = normalizedProgressJobId
? Object.values(prev?.cdDrives || {}).find((driveState) => normalizeJobId(driveState?.jobId) === normalizedProgressJobId)
: null;
const matchingCdDriveState = normalizeStage(matchingCdDriveEntry?.state);
const matchingCdDriveIsRunning = isRunningStage(matchingCdDriveState);
const matchingCdDriveIsTerminal = isTerminalStage(matchingCdDriveEntry?.state);
const previousGlobalStage = normalizeStage(prev?.state);
const previousGlobalIsRunning = isRunningStage(previousGlobalStage);
const previousGlobalIsTerminal = isTerminalStage(previousGlobalStage);
const hasKnownBinding = Boolean(
normalizedProgressJobId
&& (
@@ -334,9 +352,24 @@ function App() {
|| matchingCdDriveEntry
)
);
const regressesStableJobState = Boolean(
normalizedProgressJobId
&& incomingIsRunning
&& (
(prevJobProgressState && !prevJobProgressIsRunning && !prevJobProgressIsTerminal)
|| (matchingCdDriveState && !matchingCdDriveIsRunning && !matchingCdDriveIsTerminal)
|| (
prevActiveJobId === normalizedProgressJobId
&& previousGlobalStage
&& !previousGlobalIsRunning
&& !previousGlobalIsTerminal
)
)
);
// Ignore late/stale progress packets that arrive after a terminal state
// or for jobs that are no longer bound in pipeline state.
// or regress a job from an interactive/ready state back into an
// earlier running stage because an older progress packet arrived late.
if (
normalizedProgressJobId
&& !incomingIsTerminal
@@ -344,6 +377,7 @@ function App() {
prevJobProgressIsTerminal
|| matchingCdDriveIsTerminal
|| !hasKnownBinding
|| regressesStableJobState
)
) {
return prev;
@@ -376,7 +410,6 @@ function App() {
};
}
if (progressJobId === prev?.activeJobId || progressJobId == null) {
const previousGlobalStage = normalizeStage(prev?.state);
const keepPreviousGlobalStage = isTerminalStage(previousGlobalStage) && !incomingIsTerminal;
next.state = keepPreviousGlobalStage ? prev?.state : (payload.state ?? prev?.state);
next.progress = keepPreviousGlobalStage ? prev?.progress : (payload.progress ?? prev?.progress);
+83 -8
View File
@@ -55,6 +55,11 @@ SKIP_HANDBRAKE=false
HANDBRAKE_INSTALL_MODE=""
SKIP_NGINX=false
REINSTALL=false
GIT_COMMAND_TIMEOUT_SEC=180
# Keine interaktiven Git-Prompts im Installer (z.B. Credentials) - stattdessen
# sauber mit Fehler abbrechen.
export GIT_TERMINAL_PROMPT=0
# --- Container-Optionen -------------------------------------------------------
CONTAINER_TYPE="none"
@@ -135,6 +140,30 @@ detect_container_env() {
command_exists() { command -v "$1" &>/dev/null; }
run_git_command() {
local description="$1"
shift
local status=0
info "$description..."
if command_exists timeout; then
timeout --foreground "${GIT_COMMAND_TIMEOUT_SEC}" "$@"
status=$?
if [[ "$status" -ne 0 ]]; then
if [[ "$status" -eq 124 ]]; then
fatal "Git-Kommando lief in Timeout (${GIT_COMMAND_TIMEOUT_SEC}s): $*"
fi
fatal "Git-Kommando fehlgeschlagen (Exit $status): $*"
fi
else
"$@"
status=$?
if [[ "$status" -ne 0 ]]; then
fatal "Git-Kommando fehlgeschlagen (Exit $status): $*"
fi
fi
}
service_unit_exists() {
local unit="$1"
systemctl list-unit-files --type=service --all --no-legend 2>/dev/null \
@@ -188,6 +217,36 @@ backup_and_remove_backend_src() {
fi
}
backup_persistent_backend_data() {
local src_dir="$INSTALL_DIR/backend/data"
local backup_root="/tmp/ripster-data-backup"
local backup_dir="${backup_root}/data_bak_$(date +%Y%m%d%H%M%S)"
local copied_any=false
local candidate
if [[ ! -d "$src_dir" ]]; then
warn "Kein Backend-Datenverzeichnis gefunden: $src_dir"
return 0
fi
# Nur kleine, kritische Metadaten sichern. Medienordner bleiben im
# Installationspfad bestehen und werden hier bewusst nicht kopiert.
mkdir -p "$backup_dir"
for candidate in "ripster.db" "ripster.db-shm" "ripster.db-wal" "thumbnails"; do
if [[ -e "${src_dir}/${candidate}" ]]; then
cp -a "${src_dir}/${candidate}" "$backup_dir/"
copied_any=true
fi
done
if [[ "$copied_any" == true ]]; then
DATA_BACKUP="$backup_dir"
ok "Persistente Backend-Daten gesichert nach: $DATA_BACKUP"
else
warn "Keine zu sichernden Kern-Daten in $src_dir gefunden (ripster.db/thumbnails)."
fi
}
enforce_default_output_dirs_permissions() {
local default_dirs=(
"$INSTALL_DIR/backend/data/output/raw"
@@ -823,10 +882,24 @@ header "Repository holen (Git)"
info "Prüfe Branch '$GIT_BRANCH' auf Remote..."
branch_check_output=""
branch_check_status=0
if ! branch_check_output=$(git ls-remote --exit-code --heads "$REPO_URL" "$GIT_BRANCH" 2>&1); then
branch_check_status=$?
if command_exists timeout; then
branch_check_output=$(timeout --foreground "${GIT_COMMAND_TIMEOUT_SEC}" \
git ls-remote --exit-code --heads "$REPO_URL" "$GIT_BRANCH" 2>&1) || branch_check_status=$?
else
branch_check_output=$(git ls-remote --exit-code --heads "$REPO_URL" "$GIT_BRANCH" 2>&1) || branch_check_status=$?
fi
if [[ "$branch_check_status" -ne 0 ]]; then
if [[ "$branch_check_status" -eq 124 ]]; then
fatal "Timeout beim Prüfen des Branches '${GIT_BRANCH}' (${GIT_COMMAND_TIMEOUT_SEC}s)."
fi
if [[ "$branch_check_status" -eq 2 ]]; then
if command_exists timeout; then
available_branches=$(timeout --foreground "${GIT_COMMAND_TIMEOUT_SEC}" \
git ls-remote --heads "$REPO_URL" 2>/dev/null | awk '{print $2}' | sed 's|refs/heads/||' | tr '\n' ' ')
else
available_branches=$(git ls-remote --heads "$REPO_URL" 2>/dev/null | awk '{print $2}' | sed 's|refs/heads/||' | tr '\n' ' ')
fi
fatal "Branch '$GIT_BRANCH' existiert nicht im Repository $REPO_URL.\nVerfügbare Branches: ${available_branches:-keine oder Remote nicht erreichbar}"
fi
fatal "Remote $REPO_URL ist nicht erreichbar.\nGit-Fehler: ${branch_check_output:-unbekannt}"
@@ -836,21 +909,23 @@ ok "Branch '$GIT_BRANCH' gefunden"
if [[ -d "$INSTALL_DIR/.git" ]]; then
if [[ "$REINSTALL" == true ]]; then
info "Aktualisiere bestehendes Repository..."
# Daten sichern
if [[ -d "$INSTALL_DIR/backend/data" ]]; then
DATA_BACKUP="/tmp/ripster-data-backup-$(date +%Y%m%d%H%M%S)"
cp -a "$INSTALL_DIR/backend/data" "$DATA_BACKUP"
info "Datenbank gesichert nach: $DATA_BACKUP"
fi
info "Sichere persistente Backend-Daten (ohne große Medienordner)..."
backup_persistent_backend_data
backup_and_remove_backend_src
# safe.directory nötig wenn das Verzeichnis einem anderen User gehört
# (z.B. ripster-Serviceuser nach erstem Install)
git config --global --add safe.directory "$INSTALL_DIR" 2>/dev/null || true
run_git_command "Setze Git-Remote-URL" \
git -C "$INSTALL_DIR" remote set-url origin "$REPO_URL"
run_git_command "Aktualisiere Remote-Branch-Mapping" \
git -C "$INSTALL_DIR" remote set-branches origin '*'
run_git_command "Hole Änderungen vom Remote" \
git -C "$INSTALL_DIR" fetch --quiet origin
run_git_command "Setze Arbeitsverzeichnis auf aktuellen Stand (HEAD)" \
git -C "$INSTALL_DIR" reset --hard HEAD
run_git_command "Checkout Branch '$GIT_BRANCH'" \
git -C "$INSTALL_DIR" checkout --quiet -B "$GIT_BRANCH" "origin/$GIT_BRANCH"
run_git_command "Setze Branch auf origin/$GIT_BRANCH" \
git -C "$INSTALL_DIR" reset --hard "origin/$GIT_BRANCH"
ok "Repository aktualisiert auf Branch '$GIT_BRANCH'"
else
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "ripster",
"version": "0.16.1-1",
"version": "0.16.1-2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ripster",
"version": "0.16.1-1",
"version": "0.16.1-2",
"devDependencies": {
"concurrently": "^9.1.2"
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "ripster",
"private": true,
"version": "0.16.1-1",
"version": "0.16.1-2",
"scripts": {
"dev": "concurrently \"npm run dev --prefix backend\" \"npm run dev --prefix frontend\"",
"dev:backend": "npm run dev --prefix backend",