wtftools 0.0.1__tar.gz → 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wtftools-0.0.1 → wtftools-0.0.2}/CHANGELOG.md +95 -2
- {wtftools-0.0.1 → wtftools-0.0.2}/MANIFEST.in +2 -1
- wtftools-0.0.2/PKG-INFO +184 -0
- wtftools-0.0.2/README.md +145 -0
- wtftools-0.0.1/scripts/wtf.bash-completion → wtftools-0.0.2/completions/wtf +25 -6
- {wtftools-0.0.1 → wtftools-0.0.2}/pyproject.toml +8 -4
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_audit.py +4 -1
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_audit_extras.py +3 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_colors.py +11 -12
- wtftools-0.0.2/tests/test_completion.py +56 -0
- wtftools-0.0.1/tests/test_iteration5.py → wtftools-0.0.2/tests/test_conntrack_alert_explain.py +1 -5
- wtftools-0.0.2/tests/test_disk_usage.py +194 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_explain_deep.py +2 -2
- wtftools-0.0.1/tests/test_iteration10.py → wtftools-0.0.2/tests/test_llm_html_output.py +29 -5
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_main.py +80 -2
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_main_extras.py +0 -3
- wtftools-0.0.1/tests/test_iteration2_extras.py → wtftools-0.0.2/tests/test_net_restart_checks.py +1 -6
- wtftools-0.0.2/tests/test_port_docker.py +542 -0
- wtftools-0.0.1/tests/test_iteration8.py → wtftools-0.0.2/tests/test_probes_smart_diff.py +1 -1
- wtftools-0.0.1/tests/test_iteration4.py → wtftools-0.0.2/tests/test_psi_cert_logs_parallel.py +1 -1
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_public_api.py +15 -12
- wtftools-0.0.1/tests/test_iteration6.py → wtftools-0.0.2/tests/test_snapshot_docker_ntp.py +12 -7
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_sysinfo.py +1 -0
- wtftools-0.0.1/tests/test_iteration3.py → wtftools-0.0.2/tests/test_tcp_services_config.py +1 -1
- wtftools-0.0.2/tests/test_temp.py +66 -0
- wtftools-0.0.1/tests/test_iteration7.py → wtftools-0.0.2/tests/test_temp_dns_top_ports.py +6 -27
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/colors.py +6 -16
- wtftools-0.0.2/wtftools/completion.py +217 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/llm.py +15 -10
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/main.py +338 -57
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/sections.py +95 -27
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/snapshot.py +6 -2
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/sysinfo.py +244 -16
- wtftools-0.0.2/wtftools.egg-info/PKG-INFO +184 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools.egg-info/SOURCES.txt +14 -9
- wtftools-0.0.1/PKG-INFO +0 -307
- wtftools-0.0.1/README.md +0 -267
- wtftools-0.0.1/wtftools.egg-info/PKG-INFO +0 -307
- {wtftools-0.0.1 → wtftools-0.0.2}/LICENSE +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/scripts/build-deb.sh +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/setup.cfg +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_config.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_cron.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_info.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/tests/test_plain_formats.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/__init__.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/__main__.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/audit.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/config.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/cron.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/events.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/explain.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools/info.py +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools.egg-info/dependency_links.txt +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools.egg-info/entry_points.txt +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools.egg-info/requires.txt +0 -0
- {wtftools-0.0.1 → wtftools-0.0.2}/wtftools.egg-info/top_level.txt +0 -0
|
@@ -6,8 +6,102 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.0.2] - 2026-07-01
|
|
10
|
+
|
|
11
|
+
### Docs
|
|
12
|
+
- README is now a concise landing page (what it is, capabilities, install, a
|
|
13
|
+
linked command reference). The detailed per-command examples moved into
|
|
14
|
+
`docs/AUDIT.md`, `docs/RESOURCES.md`, `docs/OUTPUT.md` and `docs/CONFIG.md`,
|
|
15
|
+
linked from the command tables. Translations mirror the landing README;
|
|
16
|
+
the deep reference pages are English.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- `wtf completion [bash|zsh]` — print a shell-completion script to enable
|
|
20
|
+
`<Tab>` completion (`eval "$(wtf completion bash)"`); bare `wtf completion`
|
|
21
|
+
prints setup instructions. The bash script lives in `wtftools/completion.py`
|
|
22
|
+
as the single source of truth; `completions/wtf` is a generated mirror
|
|
23
|
+
(a test guards against drift), installed to bash-completion's system dir.
|
|
24
|
+
|
|
25
|
+
### Changed — `wtf disk` folder usage
|
|
26
|
+
- `wtf disk <path>` now breaks a directory down by folder size, biggest first
|
|
27
|
+
(like `du -sh <path>/* | sort`), as `# DISK USAGE <path>` rows of
|
|
28
|
+
`path/ size % of analysed root depth` (the depth index is the last
|
|
29
|
+
column). `wtf disk` with no path still shows the per-mount overview, now laid
|
|
30
|
+
out as `full path used/total percent bar` (full mount paths, no
|
|
31
|
+
truncation).
|
|
32
|
+
- `--tree [N]` drills into the N largest folders at each level (bare `--tree` =
|
|
33
|
+
1 → a single dominant chain); `--depth D` sets how deep (default 3). Output
|
|
34
|
+
is parse-first: `plain` is `bytes<TAB>percent<TAB>abspath<TAB>depth`, `json`
|
|
35
|
+
is a flat `entries` list with absolute `path` + relative `rel`.
|
|
36
|
+
- **Breaking:** `--tree` used to take a PATH (`wtf disk --tree /var`); the path
|
|
37
|
+
is now the positional argument (`wtf disk /var --tree`) and `--tree` is the
|
|
38
|
+
expansion count. The `du` scan timeout was raised (30→120s) so large
|
|
39
|
+
filesystems no longer return an empty result.
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
- `wtf ports` and `wtf top` JSON is now an object carrying `schema_version`
|
|
43
|
+
(was a bare array), consistent with `disk`/`net`; `wtf audit` JSON carries
|
|
44
|
+
`schema_version` too.
|
|
45
|
+
- README documentation links are absolute so they resolve on the PyPI project
|
|
46
|
+
page; the translated READMEs no longer link to a non-existent `docs/docs/`
|
|
47
|
+
path.
|
|
48
|
+
- `.deb` install instructions use the actual package name
|
|
49
|
+
(`python3-wtftools_*.deb`).
|
|
50
|
+
- Unexpected errors now print a one-line message instead of dumping a raw
|
|
51
|
+
Python traceback; set `WTFTOOLS_DEBUG=1` or pass `--verbose` for the trace.
|
|
52
|
+
- `requirements.txt` no longer pulls `psutil` — the core install stays
|
|
53
|
+
dependency-free; use `pip install "wtftools[full]"` for psutil.
|
|
54
|
+
- The packaged bash-completion installs as `completions/wtf`, so it is
|
|
55
|
+
auto-loaded system-wide (the previous file name prevented auto-loading; the
|
|
56
|
+
`eval "$(wtf completion bash)"` path was unaffected).
|
|
57
|
+
- The Docker base image is pinned by digest for reproducible builds.
|
|
58
|
+
- Minimum Python raised to 3.9 (`requires-python`): the build needs
|
|
59
|
+
setuptools>=77, which dropped the EOL Python 3.8. The source stays
|
|
60
|
+
3.8-compatible in style; only the packaged build floor moved.
|
|
61
|
+
|
|
62
|
+
### Security
|
|
63
|
+
- `wtf explain --llm claude|openai` discloses (to stderr) that the host name
|
|
64
|
+
and audit findings are sent to the vendor, and asks for confirmation on an
|
|
65
|
+
interactive terminal (`--yes` / `WTFTOOLS_LLM_YES=1` to skip). `--llm auto`
|
|
66
|
+
no longer silently escalates to a remote model — it uses local `ollama` only.
|
|
67
|
+
- `wtf audit --format csv` escapes cells beginning with `= + - @` to prevent
|
|
68
|
+
spreadsheet formula injection.
|
|
69
|
+
- Snapshot files and their directory are created `0600`/`0700`, so root's audit
|
|
70
|
+
history is not world-readable on a multi-user host.
|
|
71
|
+
- `wtf crontab -u <user>` validates the username (same rule as positional
|
|
72
|
+
targets) before shelling out to `crontab -l -u`, avoiding argument injection.
|
|
73
|
+
|
|
9
74
|
## [0.0.1] - 2026-06-14
|
|
10
75
|
|
|
76
|
+
### Added — port, docker and temperature views
|
|
77
|
+
- `wtf port <N>` (alias of `wtf ports <N>`) — drill into a single port:
|
|
78
|
+
which process holds it (PID, user, command), the exact executable file
|
|
79
|
+
behind it and its working directory, via `lsof` with `/proc` enrichment
|
|
80
|
+
and psutil/`ss` fallbacks. text/plain/json output.
|
|
81
|
+
- `wtf docker [NAME]` — where a container was started from: the compose
|
|
82
|
+
project working directory and config files read from the container's
|
|
83
|
+
labels, plus on-disk sizes (image layers, writable container layer and
|
|
84
|
+
json log). With no name it lists running containers as a table with
|
|
85
|
+
image/container/log size columns and a TOTAL row. Sizes use decimal units
|
|
86
|
+
(1GB = 1000MB) to match `docker container ls --size`. The image total
|
|
87
|
+
dedupes by image id (one image shared by many containers counted once); it is
|
|
88
|
+
the logical unique-images size, and since different images still share base
|
|
89
|
+
layers on disk, the real layer-deduplicated disk is shown alongside it from
|
|
90
|
+
`docker system df`. Container (writable layer) and log totals are exact. Log
|
|
91
|
+
sizes need read access under `/var/lib/docker` (run with `sudo`); otherwise
|
|
92
|
+
the column and its total show `?`, not a misleading `0B`.
|
|
93
|
+
- `wtf temp` (aliases `temps`, `temperature`) — hardware temperatures from
|
|
94
|
+
`/sys/class/hwmon` sensors, sorted hottest-first and colored against the
|
|
95
|
+
configured warn/fail thresholds. text/plain/json output.
|
|
96
|
+
|
|
97
|
+
### Changed — output
|
|
98
|
+
- Section headers are now plain `# TITLE` lines instead of full-width
|
|
99
|
+
centered box-drawing rules, so the output greps cleanly (`grep '^#'`).
|
|
100
|
+
|
|
101
|
+
### CI
|
|
102
|
+
- Bumped GitHub Actions to the Node.js 24 majors (checkout v6,
|
|
103
|
+
setup-python v6, action-gh-release v3).
|
|
104
|
+
|
|
11
105
|
### Added — per-resource subcommands
|
|
12
106
|
- `wtf disk` — per-mount usage with inode percent and read-only flags;
|
|
13
107
|
`--tree [PATH]` lists the largest directories (du-based, `--depth`,
|
|
@@ -54,7 +148,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
54
148
|
- `wtftools/checks/plugins.py` — discovery / executor / parser for
|
|
55
149
|
`/etc/wtf/checks.d/` scripts (bash + Python).
|
|
56
150
|
- `_plugin_to_check` + `_all_check_callables` glue in `wtftools/audit.py`.
|
|
57
|
-
- `tests/test_plugins.py`, `tests/test_iteration16.py`.
|
|
58
151
|
- README's «Plugins» section and QUICKSTART's «Custom checks (plugins)»
|
|
59
152
|
section.
|
|
60
153
|
|
|
@@ -127,7 +220,7 @@ Initial public release. Highlights:
|
|
|
127
220
|
release workflow.
|
|
128
221
|
- **724 tests, 92.6 % coverage.**
|
|
129
222
|
|
|
130
|
-
### Added — Plugin SDK & docs
|
|
223
|
+
### Added — Plugin SDK & docs
|
|
131
224
|
- **`wtftools.plugin_sdk`** — tiny helper module so Python plugins don't have
|
|
132
225
|
to remember exit codes or hand-roll JSON:
|
|
133
226
|
|
wtftools-0.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wtftools
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: One command to see what is going on with your Linux server right now.
|
|
5
|
+
Author-email: Aleksandr Pimenov <wachawo@gmail.com>
|
|
6
|
+
Maintainer-email: Aleksandr Pimenov <wachawo@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/wachawo/wtftools
|
|
9
|
+
Project-URL: Repository, https://github.com/wachawo/wtftools.git
|
|
10
|
+
Project-URL: Documentation, https://github.com/wachawo/wtftools#readme
|
|
11
|
+
Project-URL: Bug Reports, https://github.com/wachawo/wtftools/issues
|
|
12
|
+
Keywords: devops,sre,linux,diagnostics,monitoring,cron,system,audit,cli
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
22
|
+
Classifier: Topic :: System :: Systems Administration
|
|
23
|
+
Classifier: Topic :: System :: Monitoring
|
|
24
|
+
Classifier: Topic :: Utilities
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Provides-Extra: full
|
|
29
|
+
Requires-Dist: psutil>=5.9.0; extra == "full"
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: coverage>=7.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: ruff>=0.4.0; extra == "dev"
|
|
35
|
+
Requires-Dist: build>=1.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: stdeb>=0.10.0; extra == "dev"
|
|
37
|
+
Requires-Dist: pre-commit>=3.0.0; extra == "dev"
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
|
|
40
|
+
# wtftools
|
|
41
|
+
|
|
42
|
+
[](https://github.com/wachawo/wtftools/actions/workflows/ci.yml)
|
|
43
|
+
[](https://pypi.org/project/wtftools/)
|
|
44
|
+
[](https://pypi.org/project/wtftools/)
|
|
45
|
+
[](https://github.com/wachawo/wtftools/blob/main/LICENSE)
|
|
46
|
+
[](https://pypi.org/project/wtftools/)
|
|
47
|
+
|
|
48
|
+
> One command to see what is going on with your Linux server right now.
|
|
49
|
+
|
|
50
|
+
**English** | [Español](https://github.com/wachawo/wtftools/blob/main/docs/README_ES.md) | [Português](https://github.com/wachawo/wtftools/blob/main/docs/README_PT.md) | [Français](https://github.com/wachawo/wtftools/blob/main/docs/README_FR.md) | [Deutsch](https://github.com/wachawo/wtftools/blob/main/docs/README_DE.md) | [Italiano](https://github.com/wachawo/wtftools/blob/main/docs/README_IT.md) | [Русский](https://github.com/wachawo/wtftools/blob/main/docs/README_RU.md) | [中文](https://github.com/wachawo/wtftools/blob/main/docs/README_ZH.md) | [日本語](https://github.com/wachawo/wtftools/blob/main/docs/README_JA.md) | [हिन्दी](https://github.com/wachawo/wtftools/blob/main/docs/README_HI.md) | [한국어](https://github.com/wachawo/wtftools/blob/main/docs/README_KR.md)
|
|
51
|
+
|
|
52
|
+
You log in to a server and something feels wrong. Instead of running ten
|
|
53
|
+
commands (`htop`, `df -h`, `journalctl`, `systemctl --failed`, …) you run one:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
$ wtf
|
|
57
|
+
# AUDIT
|
|
58
|
+
[ OK ] uptime 3d 4h 12m
|
|
59
|
+
[ OK ] load average 0.42 0.51 0.55 / 8 CPU
|
|
60
|
+
[ OK ] memory 4.1GB / 16.0GB used (25%)
|
|
61
|
+
[WARN] disk /var 17.0GB / 20.0GB used (85%)
|
|
62
|
+
[FAIL] failed systemd units 1 failed unit(s)
|
|
63
|
+
|
|
64
|
+
Summary: 12 ok · 1 warn · 1 fail · 2 skip
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Green is fine, yellow needs a look, red needs fixing. `wtftools` is a
|
|
68
|
+
**read-only, dependency-free CLI** (Python standard library only; `psutil`
|
|
69
|
+
optional) that turns a pile of diagnostic commands into one readable answer —
|
|
70
|
+
and a machine-readable one when you pipe it.
|
|
71
|
+
|
|
72
|
+
## What it can do
|
|
73
|
+
|
|
74
|
+
- **Health audit** — 35+ checks (disk, memory, swap, load, PSI, OOM kills,
|
|
75
|
+
failed units, cert expiry, SMART, temperatures, DNS, …) as a
|
|
76
|
+
green / yellow / red checklist.
|
|
77
|
+
- **Per-resource views** — ask about one thing at a time, like `show` commands
|
|
78
|
+
on a switch: `wtf disk`, `wtf cpu`, `wtf mem`, `wtf net`, `wtf docker`, …
|
|
79
|
+
- **Incident triage** — `wtf problems`, `wtf events`, `wtf logs`,
|
|
80
|
+
`wtf services <unit>`, `wtf explain` (optionally through a local or hosted LLM).
|
|
81
|
+
- **Trends & alerting** — `wtf daily`, snapshots + `wtf diff`, cron alerts —
|
|
82
|
+
no monitoring stack required.
|
|
83
|
+
- **Scriptable** — `-f json` on every command and `-f plain` (tab-separated) on
|
|
84
|
+
the resource and audit views; the JSON carries a `schema_version` so scripts
|
|
85
|
+
survive upgrades — for grep / awk / jq.
|
|
86
|
+
- **Beginner-friendly** — `--show-commands` prints the classic commands each
|
|
87
|
+
view replaces, so you can learn them by hand.
|
|
88
|
+
|
|
89
|
+
## Install
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pipx install wtftools # recommended — works on any modern distro
|
|
93
|
+
pip install wtftools # or classic pip (core, no dependencies)
|
|
94
|
+
pip install wtftools[full] # + psutil for richer process/socket info
|
|
95
|
+
sudo dpkg -i python3-wtftools_*.deb # Debian/Ubuntu package (see Releases)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
After install you have the `wtf` command. Enable `<Tab>` completion by adding
|
|
99
|
+
one line to your shell rc:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
echo 'eval "$(wtf completion bash)"' >> ~/.bashrc # bash
|
|
103
|
+
echo 'eval "$(wtf completion zsh)"' >> ~/.zshrc # zsh
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
New here? Start with the [5-minute quickstart](https://github.com/wachawo/wtftools/blob/main/docs/QUICKSTART.md).
|
|
107
|
+
|
|
108
|
+
## Commands
|
|
109
|
+
|
|
110
|
+
Run `wtf <command> --help` for flags. Each command links to its reference page
|
|
111
|
+
with examples.
|
|
112
|
+
|
|
113
|
+
### Health & monitoring — [docs/AUDIT.md](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md)
|
|
114
|
+
|
|
115
|
+
| command | what it does |
|
|
116
|
+
|---------|--------------|
|
|
117
|
+
| [`wtf` / `wtf audit`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-audit) | green/yellow/red checklist of what is OK and what is not |
|
|
118
|
+
| [`wtf problems`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-problems) | only the WARN+FAIL rows |
|
|
119
|
+
| [`wtf daily`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-daily) | morning check: audit + diff vs last run + events |
|
|
120
|
+
| [`wtf explain`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-explain) | actionable advice per finding; `--llm` to pipe to an LLM |
|
|
121
|
+
| [`wtf events`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-events) | timeline: reboots, OOM kills, failed units, … |
|
|
122
|
+
| [`wtf logs`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-logs) | recent ERROR+ journal entries grouped by service |
|
|
123
|
+
| [`wtf services`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-services) | drill into one unit: state, restarts, ports, journal |
|
|
124
|
+
| [`wtf diff`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-diff) | compare current state to a saved snapshot |
|
|
125
|
+
| [`wtf history`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-history) | list saved audit snapshots |
|
|
126
|
+
| [`wtf crontab`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-crontab) | validate system + per-user crontabs |
|
|
127
|
+
| [`wtf doctor`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-doctor) | self-diagnostic: which tools/files wtf can use |
|
|
128
|
+
|
|
129
|
+
### Resource views — [docs/RESOURCES.md](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md)
|
|
130
|
+
|
|
131
|
+
| command | what it does |
|
|
132
|
+
|---------|--------------|
|
|
133
|
+
| [`wtf disk [PATH]`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-disk) | mounts overview; with a PATH, the largest folders; `--tree` drills in |
|
|
134
|
+
| [`wtf cpu`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-cpu) | load, iowait, pressure, top CPU consumers |
|
|
135
|
+
| [`wtf mem`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-mem) | RAM/swap, OOM kills, top memory consumers |
|
|
136
|
+
| [`wtf net`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-net) | interfaces, gateway, DNS, errors, listening ports |
|
|
137
|
+
| [`wtf io`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-io) | per-device IO rates, pressure, stuck processes |
|
|
138
|
+
| [`wtf who`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-who) | logged-in users, recent logins, failed auth |
|
|
139
|
+
| [`wtf temp`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-temp) | hardware temperatures from /sys/class/hwmon |
|
|
140
|
+
| [`wtf info`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-info) | one-page snapshot: all of the above at once |
|
|
141
|
+
| [`wtf top`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-top) | focused process top: sort by cpu/rss, filter by user/name |
|
|
142
|
+
| [`wtf ports` / `wtf port N`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-ports) | listening sockets; drill one port to PID, exe, cwd |
|
|
143
|
+
| [`wtf docker [NAME]`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-docker) | container compose dir + image/container/log sizes |
|
|
144
|
+
|
|
145
|
+
### Output & configuration
|
|
146
|
+
|
|
147
|
+
| command | what it does |
|
|
148
|
+
|---------|--------------|
|
|
149
|
+
| [`wtf config`](https://github.com/wachawo/wtftools/blob/main/docs/CONFIG.md#wtf-config) | show effective config / print a commented example |
|
|
150
|
+
| [`wtf completion`](#install) | print a bash/zsh `<Tab>`-completion script |
|
|
151
|
+
| [machine output](https://github.com/wachawo/wtftools/blob/main/docs/OUTPUT.md) | `plain`/`json` formats and a grep·awk·jq cookbook |
|
|
152
|
+
|
|
153
|
+
`wtftools` absorbs and supersedes
|
|
154
|
+
[`checkcrontab`](https://github.com/wachawo/checkcrontab) — the same cron
|
|
155
|
+
validator now lives at `wtf crontab`.
|
|
156
|
+
|
|
157
|
+
## Documentation
|
|
158
|
+
|
|
159
|
+
- [QUICKSTART.md](https://github.com/wachawo/wtftools/blob/main/docs/QUICKSTART.md) — 5-minute onboarding and a cheat sheet
|
|
160
|
+
- [AUDIT.md](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md) — health checks, monitoring, exit codes, the full check list
|
|
161
|
+
- [RESOURCES.md](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md) — per-resource views with examples
|
|
162
|
+
- [OUTPUT.md](https://github.com/wachawo/wtftools/blob/main/docs/OUTPUT.md) — `plain`/`json` formats and the scripting cookbook
|
|
163
|
+
- [CONFIG.md](https://github.com/wachawo/wtftools/blob/main/docs/CONFIG.md) — config file, thresholds, ignoring checks
|
|
164
|
+
|
|
165
|
+
## Compatibility
|
|
166
|
+
|
|
167
|
+
- Python 3.9+
|
|
168
|
+
- Linux (systemd distributions are the happy path; the tool degrades
|
|
169
|
+
gracefully when `systemctl` / `journalctl` / `psutil` are missing)
|
|
170
|
+
- No network access required for the core CLI; optional network only for
|
|
171
|
+
`wtf explain --llm …` and `wtf doctor --check-updates`
|
|
172
|
+
|
|
173
|
+
## From source
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
git clone https://github.com/wachawo/wtftools
|
|
177
|
+
cd wtftools
|
|
178
|
+
pip install -e .
|
|
179
|
+
python3 wtf.py audit # or run it without installing
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## License
|
|
183
|
+
|
|
184
|
+
MIT
|
wtftools-0.0.2/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# wtftools
|
|
2
|
+
|
|
3
|
+
[](https://github.com/wachawo/wtftools/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/wtftools/)
|
|
5
|
+
[](https://pypi.org/project/wtftools/)
|
|
6
|
+
[](https://github.com/wachawo/wtftools/blob/main/LICENSE)
|
|
7
|
+
[](https://pypi.org/project/wtftools/)
|
|
8
|
+
|
|
9
|
+
> One command to see what is going on with your Linux server right now.
|
|
10
|
+
|
|
11
|
+
**English** | [Español](https://github.com/wachawo/wtftools/blob/main/docs/README_ES.md) | [Português](https://github.com/wachawo/wtftools/blob/main/docs/README_PT.md) | [Français](https://github.com/wachawo/wtftools/blob/main/docs/README_FR.md) | [Deutsch](https://github.com/wachawo/wtftools/blob/main/docs/README_DE.md) | [Italiano](https://github.com/wachawo/wtftools/blob/main/docs/README_IT.md) | [Русский](https://github.com/wachawo/wtftools/blob/main/docs/README_RU.md) | [中文](https://github.com/wachawo/wtftools/blob/main/docs/README_ZH.md) | [日本語](https://github.com/wachawo/wtftools/blob/main/docs/README_JA.md) | [हिन्दी](https://github.com/wachawo/wtftools/blob/main/docs/README_HI.md) | [한국어](https://github.com/wachawo/wtftools/blob/main/docs/README_KR.md)
|
|
12
|
+
|
|
13
|
+
You log in to a server and something feels wrong. Instead of running ten
|
|
14
|
+
commands (`htop`, `df -h`, `journalctl`, `systemctl --failed`, …) you run one:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
$ wtf
|
|
18
|
+
# AUDIT
|
|
19
|
+
[ OK ] uptime 3d 4h 12m
|
|
20
|
+
[ OK ] load average 0.42 0.51 0.55 / 8 CPU
|
|
21
|
+
[ OK ] memory 4.1GB / 16.0GB used (25%)
|
|
22
|
+
[WARN] disk /var 17.0GB / 20.0GB used (85%)
|
|
23
|
+
[FAIL] failed systemd units 1 failed unit(s)
|
|
24
|
+
|
|
25
|
+
Summary: 12 ok · 1 warn · 1 fail · 2 skip
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Green is fine, yellow needs a look, red needs fixing. `wtftools` is a
|
|
29
|
+
**read-only, dependency-free CLI** (Python standard library only; `psutil`
|
|
30
|
+
optional) that turns a pile of diagnostic commands into one readable answer —
|
|
31
|
+
and a machine-readable one when you pipe it.
|
|
32
|
+
|
|
33
|
+
## What it can do
|
|
34
|
+
|
|
35
|
+
- **Health audit** — 35+ checks (disk, memory, swap, load, PSI, OOM kills,
|
|
36
|
+
failed units, cert expiry, SMART, temperatures, DNS, …) as a
|
|
37
|
+
green / yellow / red checklist.
|
|
38
|
+
- **Per-resource views** — ask about one thing at a time, like `show` commands
|
|
39
|
+
on a switch: `wtf disk`, `wtf cpu`, `wtf mem`, `wtf net`, `wtf docker`, …
|
|
40
|
+
- **Incident triage** — `wtf problems`, `wtf events`, `wtf logs`,
|
|
41
|
+
`wtf services <unit>`, `wtf explain` (optionally through a local or hosted LLM).
|
|
42
|
+
- **Trends & alerting** — `wtf daily`, snapshots + `wtf diff`, cron alerts —
|
|
43
|
+
no monitoring stack required.
|
|
44
|
+
- **Scriptable** — `-f json` on every command and `-f plain` (tab-separated) on
|
|
45
|
+
the resource and audit views; the JSON carries a `schema_version` so scripts
|
|
46
|
+
survive upgrades — for grep / awk / jq.
|
|
47
|
+
- **Beginner-friendly** — `--show-commands` prints the classic commands each
|
|
48
|
+
view replaces, so you can learn them by hand.
|
|
49
|
+
|
|
50
|
+
## Install
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pipx install wtftools # recommended — works on any modern distro
|
|
54
|
+
pip install wtftools # or classic pip (core, no dependencies)
|
|
55
|
+
pip install wtftools[full] # + psutil for richer process/socket info
|
|
56
|
+
sudo dpkg -i python3-wtftools_*.deb # Debian/Ubuntu package (see Releases)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
After install you have the `wtf` command. Enable `<Tab>` completion by adding
|
|
60
|
+
one line to your shell rc:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
echo 'eval "$(wtf completion bash)"' >> ~/.bashrc # bash
|
|
64
|
+
echo 'eval "$(wtf completion zsh)"' >> ~/.zshrc # zsh
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
New here? Start with the [5-minute quickstart](https://github.com/wachawo/wtftools/blob/main/docs/QUICKSTART.md).
|
|
68
|
+
|
|
69
|
+
## Commands
|
|
70
|
+
|
|
71
|
+
Run `wtf <command> --help` for flags. Each command links to its reference page
|
|
72
|
+
with examples.
|
|
73
|
+
|
|
74
|
+
### Health & monitoring — [docs/AUDIT.md](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md)
|
|
75
|
+
|
|
76
|
+
| command | what it does |
|
|
77
|
+
|---------|--------------|
|
|
78
|
+
| [`wtf` / `wtf audit`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-audit) | green/yellow/red checklist of what is OK and what is not |
|
|
79
|
+
| [`wtf problems`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-problems) | only the WARN+FAIL rows |
|
|
80
|
+
| [`wtf daily`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-daily) | morning check: audit + diff vs last run + events |
|
|
81
|
+
| [`wtf explain`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-explain) | actionable advice per finding; `--llm` to pipe to an LLM |
|
|
82
|
+
| [`wtf events`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-events) | timeline: reboots, OOM kills, failed units, … |
|
|
83
|
+
| [`wtf logs`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-logs) | recent ERROR+ journal entries grouped by service |
|
|
84
|
+
| [`wtf services`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-services) | drill into one unit: state, restarts, ports, journal |
|
|
85
|
+
| [`wtf diff`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-diff) | compare current state to a saved snapshot |
|
|
86
|
+
| [`wtf history`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-history) | list saved audit snapshots |
|
|
87
|
+
| [`wtf crontab`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-crontab) | validate system + per-user crontabs |
|
|
88
|
+
| [`wtf doctor`](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md#wtf-doctor) | self-diagnostic: which tools/files wtf can use |
|
|
89
|
+
|
|
90
|
+
### Resource views — [docs/RESOURCES.md](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md)
|
|
91
|
+
|
|
92
|
+
| command | what it does |
|
|
93
|
+
|---------|--------------|
|
|
94
|
+
| [`wtf disk [PATH]`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-disk) | mounts overview; with a PATH, the largest folders; `--tree` drills in |
|
|
95
|
+
| [`wtf cpu`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-cpu) | load, iowait, pressure, top CPU consumers |
|
|
96
|
+
| [`wtf mem`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-mem) | RAM/swap, OOM kills, top memory consumers |
|
|
97
|
+
| [`wtf net`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-net) | interfaces, gateway, DNS, errors, listening ports |
|
|
98
|
+
| [`wtf io`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-io) | per-device IO rates, pressure, stuck processes |
|
|
99
|
+
| [`wtf who`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-who) | logged-in users, recent logins, failed auth |
|
|
100
|
+
| [`wtf temp`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-temp) | hardware temperatures from /sys/class/hwmon |
|
|
101
|
+
| [`wtf info`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-info) | one-page snapshot: all of the above at once |
|
|
102
|
+
| [`wtf top`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-top) | focused process top: sort by cpu/rss, filter by user/name |
|
|
103
|
+
| [`wtf ports` / `wtf port N`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-ports) | listening sockets; drill one port to PID, exe, cwd |
|
|
104
|
+
| [`wtf docker [NAME]`](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md#wtf-docker) | container compose dir + image/container/log sizes |
|
|
105
|
+
|
|
106
|
+
### Output & configuration
|
|
107
|
+
|
|
108
|
+
| command | what it does |
|
|
109
|
+
|---------|--------------|
|
|
110
|
+
| [`wtf config`](https://github.com/wachawo/wtftools/blob/main/docs/CONFIG.md#wtf-config) | show effective config / print a commented example |
|
|
111
|
+
| [`wtf completion`](#install) | print a bash/zsh `<Tab>`-completion script |
|
|
112
|
+
| [machine output](https://github.com/wachawo/wtftools/blob/main/docs/OUTPUT.md) | `plain`/`json` formats and a grep·awk·jq cookbook |
|
|
113
|
+
|
|
114
|
+
`wtftools` absorbs and supersedes
|
|
115
|
+
[`checkcrontab`](https://github.com/wachawo/checkcrontab) — the same cron
|
|
116
|
+
validator now lives at `wtf crontab`.
|
|
117
|
+
|
|
118
|
+
## Documentation
|
|
119
|
+
|
|
120
|
+
- [QUICKSTART.md](https://github.com/wachawo/wtftools/blob/main/docs/QUICKSTART.md) — 5-minute onboarding and a cheat sheet
|
|
121
|
+
- [AUDIT.md](https://github.com/wachawo/wtftools/blob/main/docs/AUDIT.md) — health checks, monitoring, exit codes, the full check list
|
|
122
|
+
- [RESOURCES.md](https://github.com/wachawo/wtftools/blob/main/docs/RESOURCES.md) — per-resource views with examples
|
|
123
|
+
- [OUTPUT.md](https://github.com/wachawo/wtftools/blob/main/docs/OUTPUT.md) — `plain`/`json` formats and the scripting cookbook
|
|
124
|
+
- [CONFIG.md](https://github.com/wachawo/wtftools/blob/main/docs/CONFIG.md) — config file, thresholds, ignoring checks
|
|
125
|
+
|
|
126
|
+
## Compatibility
|
|
127
|
+
|
|
128
|
+
- Python 3.9+
|
|
129
|
+
- Linux (systemd distributions are the happy path; the tool degrades
|
|
130
|
+
gracefully when `systemctl` / `journalctl` / `psutil` are missing)
|
|
131
|
+
- No network access required for the core CLI; optional network only for
|
|
132
|
+
`wtf explain --llm …` and `wtf doctor --check-updates`
|
|
133
|
+
|
|
134
|
+
## From source
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
git clone https://github.com/wachawo/wtftools
|
|
138
|
+
cd wtftools
|
|
139
|
+
pip install -e .
|
|
140
|
+
python3 wtf.py audit # or run it without installing
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# bash completion for `wtf` / `wtftools`
|
|
2
|
-
#
|
|
2
|
+
# Enable: eval "$(wtf completion bash)" (add that line to ~/.bashrc),
|
|
3
|
+
# or copy this script to /etc/bash_completion.d/wtf
|
|
3
4
|
|
|
4
5
|
_wtf_complete() {
|
|
5
6
|
local cur prev cmd
|
|
@@ -7,7 +8,7 @@ _wtf_complete() {
|
|
|
7
8
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
|
8
9
|
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
9
10
|
|
|
10
|
-
local subcommands="info disk cpu mem net io who daily audit problems crontab doctor services service config logs explain history diff top ports events"
|
|
11
|
+
local subcommands="info disk cpu mem net io who temp temps temperature daily audit problems crontab doctor services service config logs explain history diff top ports port docker events completion"
|
|
11
12
|
local global_opts="-h --help -V --version -f --format --no-color -v --verbose -q --quiet --config"
|
|
12
13
|
|
|
13
14
|
if [[ $COMP_CWORD -eq 1 ]]; then
|
|
@@ -29,10 +30,14 @@ _wtf_complete() {
|
|
|
29
30
|
disk)
|
|
30
31
|
local opts="--tree --depth --top --format --show-commands"
|
|
31
32
|
case "$prev" in
|
|
32
|
-
--
|
|
33
|
-
--
|
|
33
|
+
--format) COMPREPLY=( $(compgen -W "text plain json" -- "$cur") ); return 0 ;;
|
|
34
|
+
--tree|--depth|--top) return 0 ;;
|
|
34
35
|
esac
|
|
35
|
-
|
|
36
|
+
if [[ "$cur" == -* ]]; then
|
|
37
|
+
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
38
|
+
else
|
|
39
|
+
COMPREPLY=( $(compgen -d -- "$cur") ) # a PATH to break down
|
|
40
|
+
fi
|
|
36
41
|
;;
|
|
37
42
|
cpu|net|io)
|
|
38
43
|
COMPREPLY=( $(compgen -W "--format --show-commands" -- "$cur") )
|
|
@@ -42,6 +47,10 @@ _wtf_complete() {
|
|
|
42
47
|
COMPREPLY=( $(compgen -W "--since --format --show-commands" -- "$cur") )
|
|
43
48
|
[[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text plain json" -- "$cur") )
|
|
44
49
|
;;
|
|
50
|
+
temp|temps|temperature)
|
|
51
|
+
COMPREPLY=( $(compgen -W "--format" -- "$cur") )
|
|
52
|
+
[[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text plain json" -- "$cur") )
|
|
53
|
+
;;
|
|
45
54
|
audit|problems)
|
|
46
55
|
local opts="--format --strict --exit-zero --check --only --since --list-checks --brief -b --ignore --serial --check-timeout --alert --alert-on --save --output -o"
|
|
47
56
|
case "$prev" in
|
|
@@ -97,7 +106,7 @@ updates reboot cron-daemon crontab docker hw-temp smart dns http-probes tcp-prob
|
|
|
97
106
|
esac
|
|
98
107
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
99
108
|
;;
|
|
100
|
-
ports)
|
|
109
|
+
ports|port)
|
|
101
110
|
local opts="--proto --public-only --format"
|
|
102
111
|
case "$prev" in
|
|
103
112
|
--proto) COMPREPLY=( $(compgen -W "tcp udp all" -- "$cur") ); return 0 ;;
|
|
@@ -105,6 +114,13 @@ updates reboot cron-daemon crontab docker hw-temp smart dns http-probes tcp-prob
|
|
|
105
114
|
esac
|
|
106
115
|
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
107
116
|
;;
|
|
117
|
+
docker)
|
|
118
|
+
case "$prev" in
|
|
119
|
+
--format) COMPREPLY=( $(compgen -W "text plain json" -- "$cur") ); return 0 ;;
|
|
120
|
+
esac
|
|
121
|
+
local names=$(docker ps --format '{{.Names}}' 2>/dev/null)
|
|
122
|
+
COMPREPLY=( $(compgen -W "--format $names" -- "$cur") )
|
|
123
|
+
;;
|
|
108
124
|
services|service)
|
|
109
125
|
local opts="-n --lines --format"
|
|
110
126
|
case "$prev" in
|
|
@@ -147,6 +163,9 @@ updates reboot cron-daemon crontab docker hw-temp smart dns http-probes tcp-prob
|
|
|
147
163
|
COMPREPLY=( $(compgen -W "--example --format" -- "$cur") )
|
|
148
164
|
[[ "$prev" == "--format" ]] && COMPREPLY=( $(compgen -W "text json" -- "$cur") )
|
|
149
165
|
;;
|
|
166
|
+
completion)
|
|
167
|
+
COMPREPLY=( $(compgen -W "bash zsh" -- "$cur") )
|
|
168
|
+
;;
|
|
150
169
|
esac
|
|
151
170
|
}
|
|
152
171
|
|
|
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "wtftools"
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.2"
|
|
8
8
|
description = "One command to see what is going on with your Linux server right now."
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
license = "MIT"
|
|
11
11
|
license-files = ["LICENSE"]
|
|
12
|
-
requires-python = ">=3.
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
13
|
authors = [{ name = "Aleksandr Pimenov", email = "wachawo@gmail.com" }]
|
|
14
14
|
maintainers = [{ name = "Aleksandr Pimenov", email = "wachawo@gmail.com" }]
|
|
15
15
|
keywords = ["devops", "sre", "linux", "diagnostics", "monitoring", "cron", "system", "audit", "cli"]
|
|
@@ -18,7 +18,6 @@ classifiers = [
|
|
|
18
18
|
"Intended Audience :: System Administrators",
|
|
19
19
|
"Intended Audience :: Developers",
|
|
20
20
|
"Programming Language :: Python :: 3",
|
|
21
|
-
"Programming Language :: Python :: 3.8",
|
|
22
21
|
"Programming Language :: Python :: 3.9",
|
|
23
22
|
"Programming Language :: Python :: 3.10",
|
|
24
23
|
"Programming Language :: Python :: 3.11",
|
|
@@ -59,12 +58,14 @@ include = ["wtftools*"]
|
|
|
59
58
|
include-package-data = true
|
|
60
59
|
|
|
61
60
|
[tool.setuptools.data-files]
|
|
62
|
-
"share/bash-completion/completions" = ["
|
|
61
|
+
"share/bash-completion/completions" = ["completions/wtf"]
|
|
63
62
|
|
|
64
63
|
[tool.black]
|
|
65
64
|
line-length = 180
|
|
66
65
|
target-version = ["py38"]
|
|
67
66
|
|
|
67
|
+
# Lint/format target stays py38 so the source keeps 3.8-compatible style; the
|
|
68
|
+
# packaged build floor is 3.9 (requires-python) due to build-time setuptools.
|
|
68
69
|
[tool.ruff]
|
|
69
70
|
line-length = 180
|
|
70
71
|
target-version = "py38"
|
|
@@ -91,6 +92,9 @@ testpaths = ["tests"]
|
|
|
91
92
|
python_files = ["test_*.py"]
|
|
92
93
|
required_plugins = ["pytest-cov"]
|
|
93
94
|
addopts = "-v --tb=short --cov=wtftools --cov-report=term-missing --cov-fail-under=80"
|
|
95
|
+
markers = [
|
|
96
|
+
"integration: exercises real host tools (docker/systemctl/smartctl/journalctl, /proc). Runs by default; skip fast local runs with -m 'not integration'.",
|
|
97
|
+
]
|
|
94
98
|
|
|
95
99
|
[tool.coverage.run]
|
|
96
100
|
branch = true
|
|
@@ -6,6 +6,8 @@ import logging
|
|
|
6
6
|
import types
|
|
7
7
|
from unittest import mock
|
|
8
8
|
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
9
11
|
from wtftools import audit
|
|
10
12
|
|
|
11
13
|
|
|
@@ -39,7 +41,7 @@ def test_check_load_levels(monkeypatch):
|
|
|
39
41
|
monkeypatch.setattr(audit.sysinfo, "get_loadavg", lambda: (1.0, 1.0, 1.0))
|
|
40
42
|
assert audit._check_load().status == "ok"
|
|
41
43
|
monkeypatch.setattr(audit.sysinfo, "get_loadavg", lambda: (5.0, 5.0, 5.0))
|
|
42
|
-
assert audit._check_load().status == "
|
|
44
|
+
assert audit._check_load().status == "warn" # 5.0 / 4 CPUs = 1.25x → warn band
|
|
43
45
|
monkeypatch.setattr(audit.sysinfo, "get_loadavg", lambda: (10.0, 10.0, 10.0))
|
|
44
46
|
assert audit._check_load().status == "fail"
|
|
45
47
|
|
|
@@ -324,6 +326,7 @@ def test_run_audit_list_outcome(monkeypatch):
|
|
|
324
326
|
assert len(results) == 2
|
|
325
327
|
|
|
326
328
|
|
|
329
|
+
@pytest.mark.integration
|
|
327
330
|
def test_run_audit_full_runs():
|
|
328
331
|
# Smoke: real run_audit must not crash on the host running tests
|
|
329
332
|
results = audit.run_audit()
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
"""Tests for new audit-module surface: registry, filter, since-hours, run_audit(names)."""
|
|
4
4
|
|
|
5
|
+
import pytest
|
|
5
6
|
|
|
6
7
|
from wtftools import audit
|
|
7
8
|
|
|
@@ -35,6 +36,7 @@ def test_run_audit_with_unknown_name(monkeypatch):
|
|
|
35
36
|
assert "unknown" in results[0].message
|
|
36
37
|
|
|
37
38
|
|
|
39
|
+
@pytest.mark.integration
|
|
38
40
|
def test_run_audit_full_still_works():
|
|
39
41
|
results = audit.run_audit()
|
|
40
42
|
assert len(results) >= 15
|
|
@@ -102,6 +104,7 @@ def test_since_hours_used_by_auth(monkeypatch):
|
|
|
102
104
|
audit.set_since_hours(24)
|
|
103
105
|
|
|
104
106
|
|
|
107
|
+
@pytest.mark.integration
|
|
105
108
|
def test_check_registry_callables():
|
|
106
109
|
"""All registered checks must be callable and not crash on smoke invocation."""
|
|
107
110
|
for name, fn in audit.CHECK_REGISTRY.items():
|