feat: add process monitoring to Monitor panel
User asked for process monitoring. Added:
1. core/monitor.py:
- Extended _LINUX_METRICS_SCRIPT with ===PROC=== section
- ps -e -o stat= | awk counts total/running/sleep/disk-sleep/zombie
- ps -eo pid,user,pcpu,pmem,vsz,rss,stat,etimes,times,args
Uses etimes/times (numeric) instead of start/time (string with
spaces) to avoid column-shift bugs. awk joins 10th col onwards
with spaces so comm retains its full command line.
- New empty-dict fields: proc_total, proc_running, proc_sleep,
proc_disk, proc_zombie, processes
- New processes[] array with full per-process fields
2. ui/widgets.py MonitorPanel:
- New _build_proc_summary() - 4-stat overview card (total/running/
sleep/zombie, color-coded)
- New _build_proc_table() - 9-column process list with:
* Search box (multi-keyword AND match across pid/user/stat/comm)
* Sort dropdown (CPU / MEM / PID / start time / user)
* Color-coded CPU% (red >=50%, orange >=20%)
* Color-coded MEM% (red >=10%, orange >=5%)
* Color-coded STAT (red for zombie)
* RSS formatted with format_bytes
* ETIME / TIME formatted as 5d3h / 2h15m / 45s
- _apply_proc_filter() - filter + sort + render in one pass
- _proc_context_menu() - right-click menu:
* kill (SIGTERM) | kill -9 (SIGKILL) | copy PID | copy cmd |
filter by this command
- _proc_kill_selected() / _proc_kill() - sends kill over SSH
with confirmation dialog, shows remote exit code in result
- Splitter: 4 metric cards + proc summary + disk + net on top,
process list on bottom. User-draggable.
3. New test_process_monitor.py (5 tests, all pass):
- Real SSH connection, collects process data
- Renders MonitorPanel with 200 rows
- Tests search filter / sort change / clear
- Tests killing a real sleep process: starts sleep 60, finds it
in the table, calls _proc_kill (with QMessageBox monkey-patched
to auto-yes), verifies remote kill -0 returns 'No such process'
- Also fixed passwords in test_e2e.py + test_terminal.py to match
the working local sshd credentials
All tests pass: core 6/6 + UI 3/3 + E2E 6/6 + terminal 5/5 + proc 5/5
Build: 57 MB single-file exe.
This commit is contained in:
+2
-2
@@ -23,7 +23,7 @@ def get_local_ssh_auth():
|
||||
"""探测本机 SSH 登录方式:测试密码"""
|
||||
# 优先尝试 root 密码(如果测试环境设了)
|
||||
candidates = [
|
||||
{"host": "127.0.0.1", "port": 22, "username": "root", "password": "testpass"},
|
||||
{"host": "127.0.0.1", "port": 22, "username": "root", "password": "sshclient_test_pwd_2026"},
|
||||
{"host": "127.0.0.1", "port": 22, "username": "root", "password": ""},
|
||||
]
|
||||
for c in candidates:
|
||||
@@ -170,7 +170,7 @@ def test_real_ssh_workflow():
|
||||
|
||||
conn3, msg3 = try_connect(auth)
|
||||
if not conn3:
|
||||
conn3, msg3 = try_connect({"host": "127.0.0.1", "port": 22, "username": "root", "password": "testpass"})
|
||||
conn3, msg3 = try_connect({"host": "127.0.0.1", "port": 22, "username": "root", "password": "sshclient_test_pwd_2026"})
|
||||
def mock_tool(name, args):
|
||||
if name == "exec_ssh_command":
|
||||
if conn3 and conn3.connected:
|
||||
|
||||
Reference in New Issue
Block a user