fix: notification history, Ctrl+D in web terminals, repository and VFIO rule fixes, translation corrections

- Notification settings show the last 20 notifications with the result of each send, the error when one failed and every daily digest run, also on days with nothing to send; the history is read without the flag the API never returned, and the page does not offer to erase it, as Audit & Report reads it.
- The Ctrl menu of the three web terminals sends Ctrl+D, which ends a text pasted in the terminal, also from a phone or a tablet.
- The repository check lists every Proxmox VE or Enterprise Ceph repository whose suite does not match the installed version, with its channel and file, and says where to disable it; repository addresses are never shown.
- Adding an NVIDIA GPU to a VM writes its VFIO udev rule again when it is missing or was edited, and the pre-check counts a missing rule as a pending host change.
- New texts in English and Spanish, modelled in the translation steady-state test, and the notifications docs page describes the history section.
- Corrected the automatic translations of the new LXC update and power control texts, and the start, shutdown, reboot and stop buttons of VMs and LXCs in German, French, Portuguese and Swedish.
- Tests for the history panel, the terminal Ctrl+D, the repository message and the VFIO rule.
This commit is contained in:
MacRimi
2026-10-15 18:30:53 +02:00
parent 983ed38e3b
commit 89fdfd0952
21 changed files with 389 additions and 136 deletions
+30 -14
View File
@@ -456,6 +456,34 @@ PROXMENUX_NVIDIA_SERVICE_LEGACY_STATE="${PROXMENUX_NVIDIA_SERVICE_LEGACY_STATE:-
# remove them when migrating a host that ran the older init-top hook.
PROXMENUX_VFIO_BIND_LEGACY_HOOK="${PROXMENUX_VFIO_BIND_LEGACY_HOOK:-${PROXMENUX_ETC_ROOT}/initramfs-tools/scripts/init-top/proxmenux-vfio-bind}"
# The udev rule the state file asks for.
_proxmenux_vfio_bind_render_udev_rule() {
{
echo "# ProxMenux: per-BDF VFIO driver override"
echo "# Auto-generated from $PROXMENUX_VFIO_BIND_STATE"
echo "# DO NOT EDIT MANUALLY — regenerated by add_gpu_vm.sh / switch_gpu_mode*.sh"
while IFS= read -r bdf; do
[[ -z "$bdf" ]] && continue
[[ "$bdf" == \#* ]] && continue
# KERNEL match expects the "0000:XX:YY.Z" form
local full="$bdf"
[[ "$full" != 0000:* ]] && full="0000:${full}"
echo "SUBSYSTEM==\"pci\", KERNEL==\"${full}\", ATTR{driver_override}=\"vfio-pci\""
done < "$PROXMENUX_VFIO_BIND_STATE"
}
}
# True when the udev rule on disk is the one the state file asks for, so a
# rule removed or edited by hand is written again on the next run.
_proxmenux_vfio_bind_udev_rule_current() {
if [[ ! -s "$PROXMENUX_VFIO_BIND_STATE" ]]; then
[[ ! -e "$PROXMENUX_VFIO_BIND_UDEV_RULE" ]]
return
fi
[[ -f "$PROXMENUX_VFIO_BIND_UDEV_RULE" ]] \
&& cmp -s <(_proxmenux_vfio_bind_render_udev_rule) "$PROXMENUX_VFIO_BIND_UDEV_RULE"
}
_proxmenux_vfio_bind_write_udev_rule() {
# Always nuke the obsolete init-top hook from earlier attempts (if it
# still exists) so a stale copy in initramfs can't run alongside the
@@ -470,19 +498,7 @@ _proxmenux_vfio_bind_write_udev_rule() {
fi
mkdir -p "$(dirname "$PROXMENUX_VFIO_BIND_UDEV_RULE")"
{
echo "# ProxMenux: per-BDF VFIO driver override"
echo "# Auto-generated from $PROXMENUX_VFIO_BIND_STATE"
echo "# DO NOT EDIT MANUALLY — regenerated by add_gpu_vm.sh / switch_gpu_mode*.sh"
while IFS= read -r bdf; do
[[ -z "$bdf" ]] && continue
[[ "$bdf" == \#* ]] && continue
# KERNEL match expects the "0000:XX:YY.Z" form
local full="$bdf"
[[ "$full" != 0000:* ]] && full="0000:${full}"
echo "SUBSYSTEM==\"pci\", KERNEL==\"${full}\", ATTR{driver_override}=\"vfio-pci\""
done < "$PROXMENUX_VFIO_BIND_STATE"
} > "$PROXMENUX_VFIO_BIND_UDEV_RULE"
_proxmenux_vfio_bind_render_udev_rule > "$PROXMENUX_VFIO_BIND_UDEV_RULE"
udevadm control --reload-rules >/dev/null 2>&1 || true
}
@@ -549,7 +565,7 @@ _proxmenux_vfio_bind_add_bdfs() {
changed=true
fi
done
if $changed; then
if $changed || ! _proxmenux_vfio_bind_udev_rule_current; then
_proxmenux_vfio_bind_write_udev_rule
_proxmenux_nvidia_vfio_policy_sync || true
_proxmenux_mark_host_config_changed
+11 -2
View File
@@ -96,20 +96,29 @@ def evaluate(suite, apply=False):
pve = []
ceph = []
debian = False
wrong_pve = []
wrong_ceph = []
for path, index, row in entries:
if not row['Enabled'] or 'deb' not in row['Types']:
continue
components = set(row['Components'])
if components & PVE_CHANNELS:
if suite not in row['Suites']:
raise ValueError('PVE repository suite does not match the installed version; no repository changed.')
wrong_pve.append(f"{' '.join(sorted(components & PVE_CHANNELS))} in {path} (suite {' '.join(row['Suites'])})")
pve.append((path, index, row))
if 'main' in components and suite in row['Suites'] and not components & PVE_CHANNELS:
debian = True
if 'enterprise' in components and any('/ceph-' in uri for uri in row['URIs']):
if suite not in row['Suites']:
raise ValueError('Enterprise Ceph repository suite does not match this PVE version; correct it in the Proxmox repository UI before switching.')
wrong_ceph.append(f"{path} (suite {' '.join(row['Suites'])})")
ceph.append((path, index, row))
# Name the stale sources, never their URIs: those can carry credentials.
if wrong_pve:
raise ValueError(f"This host runs Proxmox VE on {suite}, but these Proxmox VE repositories are for another suite: "
f"{'; '.join(wrong_pve)}. Disable or remove them in Node > Updates > Repositories and run the update again; no repository changed.")
if wrong_ceph:
raise ValueError(f"This host runs Proxmox VE on {suite}, but these Enterprise Ceph repositories are for another suite: "
f"{'; '.join(wrong_ceph)}. Correct them in Node > Updates > Repositories before switching; no repository changed.")
if any(set(row['Components']) & {'pve-no-subscription', 'pve-test', 'pvetest'} for _, _, row in pve):
return 'preserve'
+5
View File
@@ -339,6 +339,11 @@ evaluate_host_reboot_requirement() {
needs_change=true
fi
done
# The state alone is not enough: its udev rule may have been removed.
if declare -F _proxmenux_vfio_bind_udev_rule_current >/dev/null 2>&1 \
&& ! _proxmenux_vfio_bind_udev_rule_current; then
needs_change=true
fi
_file_has_exact_line "softdep nvidia pre: vfio-pci" "$vfio_conf" || needs_change=true
_file_has_exact_line "softdep nvidia_drm pre: vfio-pci" "$vfio_conf" || needs_change=true
_file_has_exact_line "softdep nvidia_modeset pre: vfio-pci" "$vfio_conf" || needs_change=true
@@ -67,6 +67,28 @@ grep -q 'ids=8086:7ad0' "$PROXMENUX_VFIO_CONF"
! grep -qi '10de:228b' "$PROXMENUX_VFIO_CONF"
_proxmenux_all_nvidia_in_vfio
[[ -f "$PROXMENUX_NVIDIA_VFIO_BLACKLIST" ]]
_proxmenux_vfio_bind_udev_rule_current
# A rule removed by hand while the state still lists the GPU is written again
# when the GPU is added once more, and the host is marked for a reboot.
rm -f "$PROXMENUX_VFIO_BIND_UDEV_RULE"
! _proxmenux_vfio_bind_udev_rule_current
HOST_CONFIG_CHANGED=false
_proxmenux_vfio_bind_add_bdfs 0000:01:00.0 0000:01:00.1
grep -qF 'KERNEL=="0000:01:00.0"' "$PROXMENUX_VFIO_BIND_UDEV_RULE"
grep -qF 'KERNEL=="0000:02:00.1"' "$PROXMENUX_VFIO_BIND_UDEV_RULE"
_proxmenux_vfio_bind_udev_rule_current
[[ "$HOST_CONFIG_CHANGED" == true ]]
# A rule that already matches the state is left alone.
HOST_CONFIG_CHANGED=false
_proxmenux_vfio_bind_add_bdfs 0000:01:00.0
[[ "$HOST_CONFIG_CHANGED" == false ]]
# A rule edited by hand is replaced by the one the state asks for.
echo '# edited' >> "$PROXMENUX_VFIO_BIND_UDEV_RULE"
_proxmenux_vfio_bind_add_bdfs 0000:01:00.0
! grep -qF '# edited' "$PROXMENUX_VFIO_BIND_UDEV_RULE"
# Returning only one GPU to the host must keep the other exact BDF in VFIO,
# remove the global NVIDIA blacklist, retain NVIDIA softdeps, and restore any