mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-06-12 11:27:01 +00:00
update 1.2.2.2 beta
This commit is contained in:
@@ -228,12 +228,11 @@ ConditionPathExists=/var/lib/proxmenux/cluster-apply-pending
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/local/share/proxmenux/scripts/backup_restore/apply_cluster_postboot.sh
|
||||
# 15-min cap to fit update-initramfs -u -k all (5-10 min for
|
||||
# 3 kernels) + update-grub (~30s) on top of the (fast) cluster
|
||||
# config apply. The unit runs AFTER pve-cluster is up so the
|
||||
# user is already at the login prompt and using the system —
|
||||
# this just chugs in the background.
|
||||
TimeoutStartSec=900
|
||||
# Cap sized for the worst case: update-initramfs across all
|
||||
# kernels + update-grub + cluster apply + component auto-reinstall
|
||||
# (NVIDIA driver download + kernel-module build is the long pole).
|
||||
# Service runs after pve-cluster is up, so this is purely background.
|
||||
TimeoutStartSec=3600
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -1431,11 +1431,8 @@ _rs_show_plan_summary() {
|
||||
local staging_root="$1"
|
||||
local meta="$staging_root/metadata"
|
||||
|
||||
# dialog --colors only fires inside --msgbox / --yesno / --infobox, not
|
||||
# --textbox, so we build the body as a string. Color codes match the
|
||||
# complete-restore confirm dialog for visual consistency. Leading blank
|
||||
# line matches the convention used in info-style dialogs (compat report,
|
||||
# etc.) — keeps the title from feeling glued to the first text line.
|
||||
# dialog --colors needs --msgbox/--yesno/--infobox (not --textbox),
|
||||
# so we build the body as a string.
|
||||
local body
|
||||
body=$'\n'"\Zb═══ $(translate "Restore plan summary") ═══\ZB"$'\n\n'
|
||||
|
||||
@@ -1793,15 +1790,9 @@ _rs_run_complete_guided() {
|
||||
plan_body="\Zb$(translate "Smart restore plan — hardware compatibility check")\ZB"$'\n\n'
|
||||
plan_body+="$(translate "The backup metadata was compared against this host. The following items will be SKIPPED to keep the boot safe:")"$'\n\n'
|
||||
|
||||
# Identifier-based skips (ZFS pool GUID, boot EFI UUID, fstab
|
||||
# UUID) ALWAYS fire on a cross-host restore — those identifiers
|
||||
# are unique per disk/pool. Showing them in the dialog is noise
|
||||
# the operator can't act on. We still apply the skips (that's
|
||||
# what protects against, e.g., restoring zpool.cache pointing at
|
||||
# a ghost pool), just without the dialog when only this noise
|
||||
# would be shown. The signal-bearing skips (component drift —
|
||||
# NVIDIA in backup, no NVIDIA card here) still trigger the dialog
|
||||
# so the operator can decide.
|
||||
# Identifier-based skips (ZFS pool GUID, boot EFI UUID, fstab UUID)
|
||||
# always fire on cross-host restores. The skip itself still applies
|
||||
# — only the dialog is suppressed when nothing else is signal-bearing.
|
||||
local -A _IDENTIFIER_PATHS=(
|
||||
["/etc/zfs/zpool.cache"]=1
|
||||
["/etc/kernel/proxmox-boot-uuids"]=1
|
||||
@@ -1820,10 +1811,6 @@ _rs_run_complete_guided() {
|
||||
dialog_signal=1
|
||||
else
|
||||
skip_paths+="${key}"$'\n'
|
||||
# Identifier-based paths on cross-host: skip silently
|
||||
# (the path goes into RS_SKIP_PATHS but stays out of
|
||||
# the dialog body, and dialog_signal stays 0 if every
|
||||
# skip is of this kind).
|
||||
if [[ "${HB_COMPAT_SAME_HOST:-1}" == "0" ]] \
|
||||
&& [[ -n "${_IDENTIFIER_PATHS[$key]:-}" ]]; then
|
||||
continue
|
||||
@@ -2252,12 +2239,8 @@ _rs_run_complete_extras() {
|
||||
rm -f "$cur_pkgs_file"
|
||||
if [[ ${#missing[@]} -gt 0 ]]; then
|
||||
echo
|
||||
# Pre-filter to packages apt actually knows about — otherwise a
|
||||
# single typo or repo-renamed pkg in packages.manual.list (e.g.
|
||||
# `lifnet-subnet-perl` from a hand-typo'd apt-mark) makes
|
||||
# `apt-get install` exit with E_UNRESOLVABLE and the entire
|
||||
# batch is skipped. Do this BEFORE the "installing N packages"
|
||||
# message so the count is honest about what we'll actually try.
|
||||
# Split into apt-known vs unknown so the install count
|
||||
# announced below matches what apt-get will actually attempt.
|
||||
local -a installable=() unknown=()
|
||||
local pkg
|
||||
for pkg in "${missing[@]}"; do
|
||||
@@ -2269,9 +2252,6 @@ _rs_run_complete_extras() {
|
||||
done
|
||||
|
||||
if (( ${#installable[@]} > 0 )); then
|
||||
# Preview so the operator can see (and ^C if surprised by)
|
||||
# what's about to land. First six is enough — anyone needing
|
||||
# the full list goes to the apt log we write below.
|
||||
local _preview="${installable[*]:0:6}"
|
||||
(( ${#installable[@]} > 6 )) && _preview+=" … (+ $((${#installable[@]} - 6)) more)"
|
||||
echo -e "${TAB}${BGN}$(translate "Packages from backup to install:")${CL} ${BL}${_preview}${CL}"
|
||||
@@ -2285,20 +2265,10 @@ _rs_run_complete_extras() {
|
||||
msg_ok "$(translate "apt cache refreshed.")"
|
||||
|
||||
msg_info "$(translate "Installing") ${#installable[@]} $(translate "packages (this may take a few minutes)...")"
|
||||
# Silent install — full output goes to $apt_log so the
|
||||
# spinner keeps turning and the operator sees ongoing
|
||||
# activity. Without this redirect, dpkg's "Setting up..."
|
||||
# spew would buffer and dump at the very end after a long
|
||||
# silent stall, looking like a hang followed by a wall of
|
||||
# text appearing from nowhere.
|
||||
# DEBIAN_FRONTEND=noninteractive + --force-conf prevents
|
||||
# apt from blocking on `*** log2ram.conf (Y/I/N/O/D/Z) ?`
|
||||
# type prompts (which would leave the package in
|
||||
# half-installed `iU` state and ultimately produce the
|
||||
# same boot-hang problem we're trying to FIX with this
|
||||
# restore). Confnew/confold both work; we pick confold
|
||||
# so the keepers from the BACKUP's restored configs win,
|
||||
# matching what the operator implicitly asked for.
|
||||
# Full output to $apt_log so the spinner keeps turning
|
||||
# instead of stalling silently then dumping at the end.
|
||||
# --force-confold keeps the restored configs over any
|
||||
# ucf prompts that would otherwise block dpkg.
|
||||
DEBIAN_FRONTEND=noninteractive \
|
||||
apt-get install -y \
|
||||
-o Dpkg::Options::="--force-confdef" \
|
||||
|
||||
@@ -1165,10 +1165,8 @@ hb_ensure_borg() {
|
||||
|
||||
hb_borg_init_if_needed() {
|
||||
local borg_bin="$1" repo="$2" encrypt_mode="$3"
|
||||
# Borg reads passphrase prompts from /dev/tty even when stdout/stderr
|
||||
# are redirected — so `>/dev/null 2>&1` is not enough to silence it.
|
||||
# Close stdin (`</dev/null`) so any prompt fails fast instead of
|
||||
# hijacking the operator's input under the active dialog window.
|
||||
# `</dev/null` because borg reads passphrase prompts from /dev/tty,
|
||||
# which `>/dev/null 2>&1` does not suppress.
|
||||
if "$borg_bin" list "$repo" </dev/null >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
@@ -1193,11 +1191,6 @@ hb_prepare_borg_passphrase() {
|
||||
return 0
|
||||
fi
|
||||
# Saved target, no pw yet — ask once and persist next to its config.
|
||||
# The title is explicit about which passphrase: operators were typing
|
||||
# their SSH/server password here, which silently persisted as the
|
||||
# repokey passphrase and made every subsequent `borg list` fail with
|
||||
# "passphrase ... is incorrect", dropping them back to the menu with
|
||||
# only a one-second red flash for feedback.
|
||||
local sel_pass
|
||||
sel_pass=$(dialog --backtitle "ProxMenux" --colors --insecure \
|
||||
--title "$(hb_translate "Borg repository passphrase")" \
|
||||
@@ -1802,11 +1795,8 @@ hb_select_borg_repo() {
|
||||
|
||||
if [[ "$choice" == "$add_idx" ]]; then
|
||||
hb_configure_borg_manual _borg_repo_ref || return 1
|
||||
# The new target is saved under HB_BORG_LAST_SAVED_NAME. Promote
|
||||
# it to SELECTED so hb_prepare_borg_passphrase enters the saved-
|
||||
# target branch (one passphrase prompt, then persist), instead
|
||||
# of the brand-new branch (the "¿Cifrar?" yes/no flow that also
|
||||
# races with borg picking up the repokey prompt on the TTY).
|
||||
# Promote the freshly-saved target so hb_prepare_borg_passphrase
|
||||
# takes the saved-target branch (single prompt + persist).
|
||||
if [[ -n "${HB_BORG_LAST_SAVED_NAME:-}" ]]; then
|
||||
HB_BORG_SELECTED_NAME="$HB_BORG_LAST_SAVED_NAME"
|
||||
HB_BORG_SELECTED_PASS=""
|
||||
@@ -1848,11 +1838,8 @@ hb_select_borg_repo() {
|
||||
else
|
||||
unset BORG_RSH
|
||||
fi
|
||||
# Saved URL may differ from the repo's recorded location by one
|
||||
# trailing slash (e.g. ssh://host//path vs ssh://host/path). Borg
|
||||
# prompts y/N to confirm — without a TTY the answer is empty and
|
||||
# borg aborts with a red one-liner, dropping the user back to the
|
||||
# menu. Trust the saved target.
|
||||
# Trust the saved URL/key — skip borg's interactive y/N confirmations
|
||||
# when the recorded repo location or encryption status drifts.
|
||||
export BORG_RELOCATED_REPO_ACCESS_IS_OK=yes
|
||||
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK=yes
|
||||
HB_BORG_SELECTED_NAME="${HB_BORG_NAMES[$sel]}"
|
||||
@@ -2597,9 +2584,6 @@ hb_show_compat_report() {
|
||||
|
||||
local tmpfile
|
||||
tmpfile=$(mktemp)
|
||||
# Leading blank line before the summary — dialog's --textbox draws the
|
||||
# title flush to the top border, and stacking the summary directly under
|
||||
# it looks cramped. One empty line gives the eye a break before the data.
|
||||
{
|
||||
printf '\n%s\n' "$summary"
|
||||
printf '%s\n\n' "────────────────────────────────────────────────────────────"
|
||||
|
||||
@@ -1150,12 +1150,8 @@ EOF
|
||||
}
|
||||
|
||||
apply_nvidia_patch_if_needed() {
|
||||
# NVIDIA_PATCH_AUTO lets non-interactive callers (the post-restore
|
||||
# auto-reinstall path in particular) skip the yes/no:
|
||||
# yes → apply the patch silently (the operator decided "true" was
|
||||
# the recorded state in the backup we just restored from)
|
||||
# no → don't apply, mark as not patched (recorded state was false)
|
||||
# unset → ask, as before (interactive use from the menu)
|
||||
# NVIDIA_PATCH_AUTO=yes|no skips the yes/no prompt for non-interactive
|
||||
# callers; unset preserves the interactive menu behavior.
|
||||
case "${NVIDIA_PATCH_AUTO:-}" in
|
||||
yes) : ;;
|
||||
no)
|
||||
@@ -1663,13 +1659,8 @@ auto_reinstall_from_state() {
|
||||
fi
|
||||
install_udev_rules_and_persistenced >>"$LOG_FILE" 2>&1
|
||||
|
||||
# If the backup said the driver was patched, re-apply the keylase
|
||||
# patch in non-interactive mode (NVIDIA_PATCH_AUTO=yes bypasses the
|
||||
# yes/no prompt and goes straight to clone+apply). The patch helper
|
||||
# writes its own update_component_status with {"patched":true} on
|
||||
# success, so we don't overwrite it below. If the backup said the
|
||||
# driver was NOT patched, write {"patched":false} explicitly so the
|
||||
# operator's recorded preference doesn't silently flip.
|
||||
# Preserve the recorded patched state across the reinstall. The patch
|
||||
# helper writes its own update_component_status on success.
|
||||
CURRENT_DRIVER_VERSION="$DRIVER_VERSION"
|
||||
if [[ "$recorded_patched" == "true" ]]; then
|
||||
echo "Recorded state had patched=true — re-applying NVIDIA patch..." | tee -a "$LOG_FILE"
|
||||
|
||||
Reference in New Issue
Block a user