Add context listing and switching to the TUI
Press c to list cv4pve-cli contexts and switch between them. The active context is always shown in the header. - Switching runs `cv4pve-cli config use`, which changes the global current context. cv4pve-cli 2.4.0 has no per-call context option. - `config list` has no JSON output, so its text lines are parsed. - The guest table is cleared as soon as another context is chosen, so the old cluster's guests cannot be acted on. - A generation counter drops guest listings that started before a switch, and g and c are refused while a switch runs. Without this, a reload already in flight could refill the table with the old cluster's guests, and VMIDs collide across clusters. 103 tests pass. The switch was tested live from mainframe to mainframe-edge and back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit was merged in pull request #1.
This commit is contained in:
1 parent
f51aff3db5
commit
62b79ab29e
6 files changed
+543
-9
No files matched your search
@@ -370,3 +370,52 @@ def test_status_reads_live_status_current(fake):
|
||||
"-o",
|
||||
"json",
|
||||
]
|
||||
|
||||
|
||||
# --- contexts / use_context (spec: "Context switching" > cli.py) -------------
|
||||
|
||||
CONTEXT_LIST = (
|
||||
"* mainframe mainframe.iot.home.arpa:8006 (api-token)\n"
|
||||
" mainframe-edge mainframe-edge.home.arpa:8006 (api-token)\n"
|
||||
)
|
||||
|
||||
|
||||
def test_contexts_parses_current_name_host_auth(fake):
|
||||
fake.result = (CONTEXT_LIST, "", 0)
|
||||
assert cli.contexts() == [
|
||||
{"name": "mainframe", "host": "mainframe.iot.home.arpa:8006",
|
||||
"auth": "api-token", "current": True},
|
||||
{"name": "mainframe-edge", "host": "mainframe-edge.home.arpa:8006",
|
||||
"auth": "api-token", "current": False},
|
||||
] # fmt: skip
|
||||
|
||||
|
||||
def test_contexts_runs_config_list(fake):
|
||||
fake.result = (CONTEXT_LIST, "", 0)
|
||||
cli.contexts()
|
||||
assert fake.argv == ["cv4pve-cli", "config", "list"]
|
||||
|
||||
|
||||
def test_contexts_ignores_junk_and_empty_lines(fake):
|
||||
fake.result = (
|
||||
"\nContexts:\n" + CONTEXT_LIST + "\n \nnot a context line\n",
|
||||
"",
|
||||
0,
|
||||
)
|
||||
assert [c["name"] for c in cli.contexts()] == ["mainframe", "mainframe-edge"]
|
||||
|
||||
|
||||
def test_contexts_empty_output_gives_empty_list(fake):
|
||||
assert cli.contexts() == []
|
||||
|
||||
|
||||
def test_use_context_runs_config_use_with_name(fake):
|
||||
cli.use_context("mainframe-edge")
|
||||
assert fake.argv == ["cv4pve-cli", "config", "use", "mainframe-edge"]
|
||||
|
||||
|
||||
def test_use_context_unknown_name_raises_clierror(monkeypatch):
|
||||
FakeRun(monkeypatch, "Error: Context 'x' not found.\n", returncode=3)
|
||||
with pytest.raises(cli.CliError) as exc:
|
||||
cli.use_context("x")
|
||||
assert "Context 'x' not found" in str(exc.value)
|
||||
Reference in new issue
Block a user