feat(process): resolve uid -> username from /etc/passwd in processlist (VA-5) #16

Merged
David merged 2 commits from feat/uid-to-username-va-5 into main 2026-05-17 14:31:57 +02:00
Owner

Summary

processlist populated uid but always left username blank. This PR resolves the uid via a per-snapshot /etc/passwd read.

Changes

  • ProcessInfo grows username: Option<String>.
  • read_passwd(path) parses /etc/passwd (skips blank / comment / malformed lines).
  • snapshot_from_paths(proc_root, passwd_path) test seam.
  • dispatch.rs::reply_processlist ships the new field.

Performance

One passwd read per snapshot, not per process. A 1000-process scan stays a single file read.

Test plan

  • cargo test -p meshagent --lib host::process (11/11 passing, 4 new).
  • cargo check -p meshagent clean.
  • Reviewer: run a live agent and confirm the SPA Processes panel shows usernames next to uids.

Closes VA-5.

## Summary `processlist` populated `uid` but always left `username` blank. This PR resolves the uid via a per-snapshot `/etc/passwd` read. ## Changes - `ProcessInfo` grows `username: Option<String>`. - `read_passwd(path)` parses `/etc/passwd` (skips blank / comment / malformed lines). - `snapshot_from_paths(proc_root, passwd_path)` test seam. - `dispatch.rs::reply_processlist` ships the new field. ## Performance One passwd read per snapshot, not per process. A 1000-process scan stays a single file read. ## Test plan - [x] `cargo test -p meshagent --lib host::process` (11/11 passing, 4 new). - [x] `cargo check -p meshagent` clean. - [ ] Reviewer: run a live agent and confirm the SPA Processes panel shows usernames next to uids. Closes VA-5.
feat(process): resolve uid -> username from /etc/passwd in processlist (VA-5)
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 1m38s
3e6ca5ac4f
`processlist` populated the `uid` field but left username blank because the deferral comment said "/etc/passwd parsing not worth the cost." It is now: the dispatcher emits the field, the SPA's processes panel renders it, and the cost is one passwd read per snapshot.

Adds:

- `ProcessInfo::username: Option<String>`.
- `read_passwd(path)` parses passwd into a `uid -> name` map, skipping blank / comment lines and malformed entries.
- `snapshot_from_paths(proc_root, passwd_path)` so tests can drive a synthetic passwd without touching `/etc`.
- `snapshot_from_proc(root)` keeps its signature and defaults the passwd to `/etc/passwd`.
- `dispatch.rs::reply_processlist` ships the new field.
- 4 new tests: passwd parse (blank/comment/malformed), username resolution, missing-uid -> None, plus the existing ProcessInfo literals in dispatch.rs's tests updated.

`/etc/passwd` is read once per snapshot rather than once per process, so a 1000-process scan stays a single file read.

#VA-5 State Done
Merge branch 'main' into feat/uid-to-username-va-5
Some checks failed
Check / clippy + fmt + tests (pull_request) Failing after 1m40s
3ba02915f6
David merged commit 6fdeaf773a into main 2026-05-17 14:31:57 +02:00
David deleted branch feat/uid-to-username-va-5 2026-05-17 14:31:57 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/vervain-agent!16
No description provided.