f on the info screen runs fstrim in a running VM that has the guest agent enabled.
Not eligible: a container gets an info note (containers have no guest agent, so use pct fstrim on the node). A stopped VM, or one without the agent, gets a warning, and nothing runs.
Eligible VM: a confirm comes first, then agent ping, then fstrim. The result reports the trimmed total in GiB or MiB, the number of paths, and any per-path errors.
Review fixes
Odd agent output: it no longer turns a finished trim into "fstrim failed".
Unreadable output gives "no results".
Odd entries are repaired: entries that are not dicts are dropped, a non-integer trimmed becomes 0, and a missing path becomes "?".
Well-formed entries are returned unchanged.
Timeout: fstrim gets a 30-minute CLI timeout instead of 330 s, because a large disk can take longer.
Markup in notifications: notifications are never parsed as markup (GuestApp.notify defaults to markup=False). Guest names, paths and CLI or agent errors are untrusted text, and a [/b] in them could break the toast.
Before load: pressing f before the info screen has loaded says "still loading" instead of a wrong "not running".
Wording: "1 path" in the singular.
Verification
608 tests pass.
ruff check and ruff format --check report no issues.
betterleaks found no secrets.
Not run live, because the issue asks for approval before running fstrim on VM 108. Only the harmless agent ping was run there, and it answered {"result": "{}"}.
## What
`f` on the info screen runs fstrim in a running VM that has the guest agent enabled.
- **Not eligible:** a container gets an info note (containers have no guest agent, so use `pct fstrim` on the node). A stopped VM, or one without the agent, gets a warning, and nothing runs.
- **Eligible VM:** a confirm comes first, then `agent ping`, then `fstrim`. The result reports the trimmed total in GiB or MiB, the number of paths, and any per-path errors.
## Review fixes
- **Odd agent output:** it no longer turns a finished trim into "fstrim failed".
- Unreadable output gives "no results".
- Odd entries are repaired: entries that are not dicts are dropped, a non-integer `trimmed` becomes 0, and a missing `path` becomes "?".
- Well-formed entries are returned unchanged.
- **Timeout:** fstrim gets a 30-minute CLI timeout instead of 330 s, because a large disk can take longer.
- **Markup in notifications:** notifications are never parsed as markup (`GuestApp.notify` defaults to `markup=False`). Guest names, paths and CLI or agent errors are untrusted text, and a `[/b]` in them could break the toast.
- **Before load:** pressing `f` before the info screen has loaded says "still loading" instead of a wrong "not running".
- **Wording:** "1 path" in the singular.
## Verification
- 608 tests pass.
- `ruff check` and `ruff format --check` report no issues.
- `betterleaks` found no secrets.
- Not run live, because the issue asks for approval before running fstrim on VM 108. Only the harmless `agent ping` was run there, and it answered `{"result": "{}"}`.
This PR is stacked on #30 → #29 → #28 → #27.
Closes #19
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
At startup the app runs `cv4pve-cli --version`. If it differs from
cli.TESTED_VERSION (2.4.0), a warning says which version was found
and which one was tested. The app parses output formats that are not
a stable API: the config list text, prune-backups as a JSON string,
the CT ip-addresses JSON string and the exit codes with --wait. A
newer cv4pve-cli could break them in confusing ways.
If cv4pve-cli cannot be run at all, an error says so once, instead of
every later call failing without explanation. The README notes the
tested version.
Closes#14
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README gets an "Install" section: install with uv tool from the
Gitea repo or from a local checkout, then upgrade and uninstall. The
"Run" section says to use `cv4pve-tui` when installed and
`uv run cv4pve-tui` from a checkout.
Verified by installing into throwaway tool dirs (UV_TOOL_DIR and
UV_TOOL_BIN_DIR under /tmp): `uv tool install .` gave a cv4pve-tui
binary. Started from /tmp in a pseudo-terminal, it drew the guest
frame and ran until it was stopped. The pyproject metadata (entry
point, readme, requires-python) was already enough.
Closes#17
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/ opens a filter box under the guest table, and the table filters as
you type. Terms are separated by spaces, all must match, and case is
ignored:
- a plain term matches part of the name, the VMID or a tag
- is:running and is:stopped match the status
- type:lxc/ct and type:vm/qemu match the guest type
Enter keeps the filter and goes back to the table. Escape clears it,
from the box or from the table. The frame shows
"· filter: <text> · N of M". Actions only ever see the visible rows,
and the filter survives reloads and context switches.
Review fixes:
- Typing "[/b]" or "[/]" crashed the app, because the filter text went
into the border subtitle, which Textual parses as markup. The
subtitle is now plain text, so "[red]" is also shown literally.
- Escape on the table now clears a filter that was applied with Enter.
- guest_matches tolerates a None status or type.
Read-only live check on mainframe: "debian" gives 104, "type:vm" gives
108, "community-script is:running" gives 14 of 19, and "is:stopped"
gives 0 of 19.
Closes#16
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The info screen's Resources table shows Autostart (yes/no), Startup
(order, up and down delays) and Tags. o opens a dialog to change them.
Only keys that differ are sent, in one `set <kind> config` call
through the existing set_net. A confirm lists the old and new value
of each key.
Tags are removed with `--delete tags` on set config. The CLI also has
a `delete ct|vm ... tags` command, but it shares the form that
destroys the whole guest, so the app never uses it; nothing in the
code builds a delete ct|vm argv. Inputs are validated before sending:
startup values must be ints >= 0, and tags must match
[A-Za-z0-9_][A-Za-z0-9_+.-]*. They are split on ; , or whitespace and
deduplicated.
Live test on CT 104: onboot 1 -> 0, startup order=5,up=10, tag
tui-test added, then all set back through the dialog. The config
ended identical to the baseline.
Closes#18
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
f on the info screen runs fstrim in a running VM with the guest agent
enabled. A container gets an info note (no guest agent; use pct
fstrim on the node). A stopped VM or one without an agent gets a
warning, and nothing runs. Otherwise a confirm comes first, then
agent ping and fstrim. The result reports the trimmed total
(GiB/MiB), the number of paths and any per-path errors.
Review fixes:
- Odd agent output no longer turns a finished trim into "fstrim
failed". Unreadable output gives "no results". Odd entries are
repaired: non-dict entries are dropped, a non-int trimmed becomes 0
and a missing path becomes "?". Well-formed entries are returned
unchanged.
- fstrim gets a 30-minute CLI timeout instead of 330 s, because a big
disk can take longer.
- Notifications are never parsed as markup (GuestApp.notify defaults
to markup=False). Guest names, paths and CLI or agent errors are
untrusted text, so a "[/b]" in them could break the toast.
- f before the info screen has loaded says "still loading" instead of
a wrong "not running".
- "1 path" in the singular.
Not run live: the issue asks for approval before fstrim on VM 108.
Only the harmless agent ping was run there, and it answered.
Closes#19
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What
fon the info screen runs fstrim in a running VM that has the guest agent enabled.pct fstrimon the node). A stopped VM, or one without the agent, gets a warning, and nothing runs.agent ping, thenfstrim. The result reports the trimmed total in GiB or MiB, the number of paths, and any per-path errors.Review fixes
trimmedbecomes 0, and a missingpathbecomes "?".GuestApp.notifydefaults tomarkup=False). Guest names, paths and CLI or agent errors are untrusted text, and a[/b]in them could break the toast.fbefore the info screen has loaded says "still loading" instead of a wrong "not running".Verification
ruff checkandruff format --checkreport no issues.betterleaksfound no secrets.agent pingwas run there, and it answered{"result": "{}"}.This PR is stacked on #30 → #29 → #28 → #27.
Closes #19
Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com