update fix
This commit is contained in:
@@ -20,7 +20,9 @@ update every online cluster node over Proxmox's root SSH trust, then update the
|
||||
initiating node. Each node independently performs the same clean-worktree,
|
||||
branch, and fast-forward safety checks. Offline, unreachable, dirty, ahead, or
|
||||
diverged nodes are never overwritten and are reported as failures. Standalone
|
||||
hosts retain the local-only update behavior.
|
||||
hosts retain the local-only update behavior. The menu reloads the locally installed
|
||||
code and version after an update attempt, including when another node fails.
|
||||
Failures remain visible until you press Enter to continue.
|
||||
|
||||
Legacy installations automatically update from the published `main` branch.
|
||||
On their first launch after receiving this version, control is handed to the
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
action="${1:-}"
|
||||
FOLDER='/opt/idssys/ta-proxmenu'
|
||||
VERS='2026.9.22-2'
|
||||
VERS='2026.9.22-3'
|
||||
|
||||
noupdate=' '
|
||||
|
||||
|
||||
Regular → Executable
+1
@@ -112,6 +112,7 @@ def scan(root=Path('/etc/pve/nodes'), get=api):
|
||||
refs, errors, before = references(root, nodes, guests)
|
||||
warnings.extend(errors)
|
||||
shared_done = set()
|
||||
echo
|
||||
for node in sorted(nodes, key=lambda item: item['node']):
|
||||
name = node['node']
|
||||
if node.get('status') != 'online':
|
||||
|
||||
+12
-3
@@ -2678,6 +2678,16 @@ BRANCH_MANAGEMENT_MENU() {
|
||||
done
|
||||
}
|
||||
|
||||
TAPM_INSTALL_MENU_UPDATE() {
|
||||
if ! /opt/idssys/ta-proxmenu/run.sh update; then
|
||||
printf '\nUpdate reported failures; review the node results above. TAPM will reload the locally installed version.\n'
|
||||
ENTER2CONTINUE
|
||||
fi
|
||||
# A remote failure can coexist with a successful local update. Reload the
|
||||
# full menu, including functions and defaults, regardless of cluster status.
|
||||
exec /opt/idssys/ta-proxmenu/run.sh
|
||||
}
|
||||
|
||||
UTILITIES_MENU() {
|
||||
local -a labels
|
||||
local -a values=("install_update" "check_update" "branches" "about")
|
||||
@@ -2727,9 +2737,8 @@ UTILITIES_MENU() {
|
||||
echo -en "\n${idsCL[LightCyan]}Install the update for the current branch (y/N)?${idsCL[Default]} "
|
||||
read -r -n 1 choice
|
||||
echo
|
||||
if [[ "$choice" =~ ^[Yy]$ ]] &&
|
||||
/opt/idssys/ta-proxmenu/run.sh update; then
|
||||
exec /opt/idssys/ta-proxmenu/run.sh
|
||||
if [[ "$choice" =~ ^[Yy]$ ]]; then
|
||||
TAPM_INSTALL_MENU_UPDATE
|
||||
fi
|
||||
ENTER2CONTINUE
|
||||
;;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Exercise menu reloads after successful and partially failed updates."""
|
||||
from pathlib import Path
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class MenuUpdateTests(unittest.TestCase):
|
||||
def test_reload_after_success_or_failure(self):
|
||||
source = (ROOT / 'proxmenu-scripts.sh').read_text()
|
||||
function = source.split('TAPM_INSTALL_MENU_UPDATE() {', 1)[1].split('\n}\n', 1)[0]
|
||||
for status in (0, 1):
|
||||
with self.subTest(update_status=status), tempfile.TemporaryDirectory() as directory:
|
||||
launcher = Path(directory) / 'run.sh'
|
||||
log = Path(directory) / 'calls'
|
||||
launcher.write_text('''#!/bin/bash
|
||||
if [[ "${1:-}" == update ]]; then
|
||||
echo update >> "$TEST_LOG"
|
||||
exit "$TEST_STATUS"
|
||||
fi
|
||||
echo reload >> "$TEST_LOG"
|
||||
''')
|
||||
launcher.chmod(0o700)
|
||||
script = 'ENTER2CONTINUE() { echo pause >> "$TEST_LOG"; }\n'
|
||||
script += 'TAPM_INSTALL_MENU_UPDATE() {' + function.replace(
|
||||
'/opt/idssys/ta-proxmenu/run.sh', '"' + str(launcher) + '"') + '\n}\n'
|
||||
script += 'TAPM_INSTALL_MENU_UPDATE\necho stale-menu >> "$TEST_LOG"\n'
|
||||
result = subprocess.run(['bash', '-c', script], capture_output=True, text=True,
|
||||
env=dict(os.environ, TEST_LOG=str(log), TEST_STATUS=str(status)))
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertEqual(log.read_text().splitlines(),
|
||||
['update', 'reload'] if status == 0 else ['update', 'pause', 'reload'])
|
||||
if status:
|
||||
self.assertIn('reported failures', result.stdout)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user