fixop — Infrastructure Fix Operations
AI Cost Tracking
This project uses AI-generated code. Total cost: $1.9107 with 9 AI commits.
Generated on 2026-06-29 using openrouter/qwen/qwen3-coder-next
Detect and repair DNS, firewall, containers, TLS, systemd issues on local and remote servers. Zero external dependencies — uses only Python stdlib.
Install
pip install fixop
Usage as CLI
# Check remote server
fixop check --host myserver.com --user root
# Check specific categories
fixop check --host myserver.com --category dns,firewall,tls
# Auto-fix what can be fixed
fixop fix --host myserver.com --auto
# Interactive fix (confirm each)
fixop fix --host myserver.com --interactive
# Validate deploy artifacts locally
fixop validate deploy/
# Check TLS certificates
fixop check-tls app.example.com api.example.com
# Full diagnostic + fix pipeline
fixop doctor --host myserver.com --fix
# JSON output (for CI)
fixop check --host myserver.com --format json
Usage as Library
from fixop import HostContext, check_host_dns, check_ufw_forward_policy, fix_resolv_conf
ctx = HostContext(host="myserver.com", user="root")
# Detect issues
issues = check_host_dns(ctx)
for issue in issues:
print(issue) # [dns] Host DNS cannot resolve acme-v02.api.letsencrypt.org
# Run all checks at once
from fixop import check_all
issues = check_all(ctx, domains=["app.example.com"], containers=["traefik", "web"])
# Fix issues
result = fix_resolv_conf(ctx, nameservers=["8.8.8.8", "1.1.1.1"])
print(result) # Set /etc/resolv.conf to 8.8.8.8, 1.1.1.1
# Classify runtime errors
from fixop import classify_error
issue = classify_error(exit_code=137, stderr="", cmd="podman run app")
print(issue) # [container] Container killed (OOM or SIGKILL) (exit 137)
# Validate deploy files locally
from fixop import check_unresolved_vars, check_placeholders
issues = check_unresolved_vars(["deploy/traefik.yml", "deploy/web.container"])
issues += check_placeholders(["deploy/config.yml"])
Modules
| Module | Purpose |
|---|---|
ssh.py |
SSH transport + connectivity checks |
dns.py |
DNS resolution + resolv.conf + systemd-resolved |
firewall.py |
UFW forward policy + iptables NAT masquerade |
containers.py |
Podman/Docker: health, running status, disk, memory |
systemd.py |
Unit management, graceful restart, daemon-reload |
tls.py |
Certificate validation (Let's Encrypt, self-signed) |
ports.py |
Port conflict detection + resolution |
deploy.py |
Deploy artifact validation (unresolved vars, placeholders) |
health.py |
HTTP/TCP endpoint health checks |
classify.py |
Runtime error classification (exit codes, stderr patterns) |
cli.py |
Standalone CLI |
Key Design Principles
- Zero dependencies — stdlib only (
subprocess,socket,ssl,pathlib,re,json) - SSH via subprocess — uses the
sshcommand, not paramiko (optional extra) - Taskfile-agnostic — operates on infrastructure primitives, not Taskfile.yml format
- Dispatch tables — uses data-driven classification instead of if/elif chains
License
Licensed under Apache-2.0.
Author
Tom Sapletta
Metadata
Release files for fixop 0.1.18
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fixop-0.1.18.tar.gz | 453.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fixop-0.1.18-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 491.9 kB
Release files / fixop-0.1.18.tar.gz
| Download URL | fixop-0.1.18.tar.gz |
|---|---|
| Size | 453.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
57cb70d28a20d768afa25c8d47c23b3e083725a4bb836e68306ac9d2ad2d8297
|
|
BLAKE2b-256 checksum How to use checksums |
56a75645d2504221daad4daa179d87322285d642f7ea0cbde79d9ba1a813a7a8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / fixop-0.1.18-py3-none-any.whl
| Download URL | fixop-0.1.18-py3-none-any.whl |
|---|---|
| Size | 38.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
283307adb9b43ddb4bc9fa90fe2587eedc39f7ef68bc63d3b7bd946539c9f9ed
|
|
BLAKE2b-256 checksum How to use checksums |
0c9292b2ae71c043479f1bec3e85941202441233d34cb5e2f82ee86844d71736
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|