FROps (Field Reliability Ops) is a small command-line helper for triaging
CoreWeave bare-metal node (BMN) workflow failures. It wraps kubectl, yq,
and awxstat calls into ergonomic subcommands so you can list and inspect
nodes in various FLCC failure states without remembering long label selectors.
frops view <fail_type>— list BMNs in a given failure state (zap, test, field-diag, etc.), optionally filtered by ownership label.frops view sku <SKU>— list BMNs of a given SKU that need attention (i.e. not inproduction/ready/rma/broken/dev/debugstate).frops analyze bmn <name>— run an ordered set of inspection commands against a specific BMN and print labeled output sections.
Terminal colors emitted by kubectl / kubecolor / yq are preserved
end-to-end — frops streams command output rather than capturing it.
- Python 3.10+
kubectlconfigured against the relevant clusteryq(mikefarah/yq)awxstat(internal CoreWeave tool, available on jump hosts)
git clone https://github.com/alcala-dev/frops.git
cd frops
pip install .This installs the frops console script onto your PATH.
pip install -e ".[dev]"
pre-commit install# All failed BMNs
frops view fails
# Only zap failures (node-zap or dpu-zap)
frops view zapfails
# Filter by ownership label
frops view testfails -u jdoeAvailable fail types: fails, zapfails, nodezapfails, dpuzapfails,
testfails, fielddiagfails.
# All GH200 nodes that aren't in production/ready/rma/broken/dev/debug
frops view sku GPU-GH200-01
# Same query, scoped to one owner
frops view sku GPU-GH200-01 -u jdoeThe excluded states are production, ready, rma, broken, dev,
debug. To adjust the list, edit SKU_EXCLUDED_STATES in
src/frops/catalog.py.
frops view sku <SKU> --action shows the existing colored table, then
inspects each returned BMN's AWX jobs and prints a per-node remediation
plan. By default it stops there and asks you to pick which group(s) to
run; passing --yes (or -y) skips the prompt and runs every available
group. Use --dry-run if you want the plan without any prompt or
execution.
# Plan only, then prompt for which groups to run
frops view sku GPU-GH200-01 --action
# Plan and run everything available without prompting (CI / scripted use)
frops view sku GPU-GH200-01 --action --yes
# Plan only, never prompt or execute
frops --dry-run view sku GPU-GH200-01 --actionThe prompt looks like:
Run? [a]ll / [p]ower-drain (3) / [h]o-ticket (1) / [n]oop-access (6) / Enter to abort:
Only groups present in the plan are offered. Pick one letter, or several
comma-separated (p,h runs power-drain + ho-ticket but skips the NOOP
access check). Empty input — or Ctrl-C — aborts; nothing runs.
What --action does, per BMN with a non-empty CW-NODE:
- Captures
awxstat -l mgmt <BMN>andawxstat -l bmc <BMN>. - Parses each output's
cw_error_codes={…}block forCWXXXXcodes. - Classifies the BMN:
CW0211orCW0102on SKUGPU-GH200-01→ power-drain viacwctl flcc node --one-off -w orphan -s power-drain …CW0201→ search theHOJIRA project for an open ticket inAwaiting Supportwhose summary mentions the BMN name, CW-NODE (gmac), or hardware serial. If found, the action becomes "append a status block to that ticket's Description". If nothing matches (or JIRA creds aren't set), falls back tocwctl flcc node -w return-to-triage ….- Other / no codes → no-op (eligible for the access check).
- XID-109 detour (any SKU): for BMNs currently in
CWNC-STATE= triage, looks up the matching open HO ticket and checks its description for anXID 109mention. Matches split byPhaseState.reason:reason=nlcc(both flcc and nlcc have reached triage) → reclassified asxid-109-return-to-readywith thecwctl flcc node -w return-to-ready …command.- any other reason → rendered above the plan in
=== XID 109 BMNs waiting for return-to-fleetops ===, not actionable until propagation completes. Power-drain still takes precedence — a BMN already classified aspower-drainis never reclassified.
- Prints a grouped plan with the exact commands that would run and a totals line.
- Prompts you to pick which groups to execute. The prompt offers
[a]ll,[p]ower-drain,[h]o-ticket,[x]id-109-return, and[n]oop-access— only groups present in the plan appear. Multi-pick via comma (e.g.p,x). With--yes, runs every group. - For each selected actionable group (
p,h,x): runs eachcwctlcommand in order, streaming its output. A failure on one BMN does not abort the rest — the run continues and the worst exit code propagates as the process exit. An=== Execution summary ===block at the end lists any failures with theircwctlexit codes. - If
nis selected (or under--yeswhen NOOP-clean BMNs exist): runs a diagnostic access pass —jumpipmitool -c "chassis power status"per node, plusbmns -o widefor the canonical workflow / state / TS display — and prints an=== Access check ===table. Reachability failures are reported but don't affect the process exit code. Runs in parallel (8-thread pool).
BMNs without a CW-NODE are listed as skipped — there's nothing to
action on a node that hasn't joined a cluster.
The HO-ticket resolver authenticates to JIRA Cloud via HTTP Basic with your Atlassian account email and an API token:
export JIRA_EMAIL=you@coreweave.com
export JIRA_TOKEN=<your-api-token>Generate a token at
https://id.atlassian.com/manage-profile/security/api-tokens. If either
var is unset, --action still runs — it just skips the HO lookup and
falls back to cwctl return-to-triage for CW0201 BMNs (a one-line
note explains why on stderr).
The policy lives in src/frops/action.py and the
AWX parser in src/frops/awx.py; see those modules
to add new CW-code mappings or extend the eligible SKU list.
frops analyze bmn ss929610x4724071Output is grouped into labeled sections: Overview, Messages, AWX Mgmt, and AWX BMC.
python -m frops view failsCommon tasks are wired into a Makefile:
make install # editable install with dev extras
make lint # ruff lint + format check
make format # ruff format
make typecheck # mypy
make test # pytest with coverage
make check # lint + typecheck + test
make build # build sdist + wheelOr run the tools directly:
ruff check .
ruff format .
mypy
pytestfrops/
├── src/frops/ # package source
│ ├── cli.py # argparse setup + subcommand handlers
│ └── commands.py # subprocess helpers (run, capture)
├── tests/ # pytest suite
├── pyproject.toml # build, deps, and tool configs
└── .github/workflows/ci.yml
See CONTRIBUTING.md. Changelog: CHANGELOG.md.