mayhem-cli 0.5.1__py3-none-any.whl
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.
- mayhem/agent/__init__.py +1 -0
- mayhem/agent/cli.py +36 -0
- mayhem/agents/__init__.py +1 -0
- mayhem/agents/capabilities.py +106 -0
- mayhem/agents/executors.py +430 -0
- mayhem/agents/impact.py +729 -0
- mayhem/agents/lease_client.py +141 -0
- mayhem/agents/probes.py +284 -0
- mayhem/agents/protocol.py +134 -0
- mayhem/agents/server.py +281 -0
- mayhem/agents/sinks.py +60 -0
- mayhem/agents/transports.py +134 -0
- mayhem/agents/watchdog.py +140 -0
- mayhem/cli/__init__.py +11 -0
- mayhem/cli/app.py +154 -0
- mayhem/cli/campaign.py +496 -0
- mayhem/cli/config_cmd.py +47 -0
- mayhem/cli/context.py +23 -0
- mayhem/cli/dependency.py +429 -0
- mayhem/cli/exit_codes.py +24 -0
- mayhem/cli/experiment.py +24 -0
- mayhem/cli/lifecycle.py +805 -0
- mayhem/cli/resolver.py +72 -0
- mayhem/cli/services.py +459 -0
- mayhem/cli/style.py +101 -0
- mayhem/cli/toolkit.py +41 -0
- mayhem/cli/topology.py +127 -0
- mayhem/config.py +208 -0
- mayhem/controller/__init__.py +1 -0
- mayhem/controller/compensation.py +2156 -0
- mayhem/controller/executor.py +1719 -0
- mayhem/controller/janitor.py +196 -0
- mayhem/controller/observability_collector.py +382 -0
- mayhem/controller/observations.py +102 -0
- mayhem/controller/planner.py +715 -0
- mayhem/controller/recovery.py +245 -0
- mayhem/controller/resilience_report.py +585 -0
- mayhem/controller/resource_manager.py +457 -0
- mayhem/controller/safety.py +392 -0
- mayhem/domain/__init__.py +6 -0
- mayhem/domain/campaigns.py +118 -0
- mayhem/domain/cancellation.py +110 -0
- mayhem/domain/candidates.py +101 -0
- mayhem/domain/capabilities.py +86 -0
- mayhem/domain/catalog.py +727 -0
- mayhem/domain/checks.py +173 -0
- mayhem/domain/common.py +104 -0
- mayhem/domain/coverage.py +106 -0
- mayhem/domain/decisions.py +57 -0
- mayhem/domain/errors.py +87 -0
- mayhem/domain/events.py +61 -0
- mayhem/domain/execution_context.py +120 -0
- mayhem/domain/execution_loci.py +94 -0
- mayhem/domain/experiments.py +370 -0
- mayhem/domain/faults.py +239 -0
- mayhem/domain/identity.py +200 -0
- mayhem/domain/k8s_adapter.py +132 -0
- mayhem/domain/leases.py +186 -0
- mayhem/domain/load_strategy.py +98 -0
- mayhem/domain/m5_campaign.py +120 -0
- mayhem/domain/maniac.py +93 -0
- mayhem/domain/observability.py +146 -0
- mayhem/domain/outcomes.py +92 -0
- mayhem/domain/remote_agent_interface.py +70 -0
- mayhem/domain/resources.py +245 -0
- mayhem/domain/risks.py +61 -0
- mayhem/domain/run_outcome.py +146 -0
- mayhem/domain/runtime_adapter.py +256 -0
- mayhem/domain/success.py +329 -0
- mayhem/domain/topology.py +452 -0
- mayhem/infra/__init__.py +1 -0
- mayhem/infra/campaign_engine.py +205 -0
- mayhem/infra/candidate_gates.py +124 -0
- mayhem/infra/candidate_generator.py +110 -0
- mayhem/infra/coverage_repository.py +101 -0
- mayhem/infra/lease_repository.py +129 -0
- mayhem/infra/maniac.py +103 -0
- mayhem/infra/migrations.py +596 -0
- mayhem/infra/migrator.py +149 -0
- mayhem/infra/report.py +227 -0
- mayhem/infra/store.py +200 -0
- mayhem/py.typed +0 -0
- mayhem/spec.py +52 -0
- mayhem/toolkit/__init__.py +1 -0
- mayhem/toolkit/fingerprint.py +69 -0
- mayhem/toolkit/hashing.py +32 -0
- mayhem/toolkit/manifests/docker.yaml +11 -0
- mayhem/toolkit/manifests/podman.yaml +11 -0
- mayhem/toolkit/manifests/stress-ng.yaml +11 -0
- mayhem/toolkit/manifests/tc-netem.yaml +11 -0
- mayhem/toolkit/manifests/toxiproxy.yaml +10 -0
- mayhem/toolkit/registry.py +185 -0
- mayhem/toolkit/tool_runner.py +129 -0
- mayhem/topology/__init__.py +10 -0
- mayhem/topology/providers/__init__.py +0 -0
- mayhem/topology/providers/adapter_registry.py +60 -0
- mayhem/topology/providers/base.py +31 -0
- mayhem/topology/providers/compose.py +207 -0
- mayhem/topology/providers/docker_adapter.py +277 -0
- mayhem/topology/providers/docker_runtime.py +461 -0
- mayhem/topology/providers/podman_adapter.py +328 -0
- mayhem/topology/resolve.py +196 -0
- mayhem/topology/service.py +158 -0
- mayhem_cli-0.5.1.dist-info/METADATA +555 -0
- mayhem_cli-0.5.1.dist-info/RECORD +107 -0
- mayhem_cli-0.5.1.dist-info/WHEEL +4 -0
- mayhem_cli-0.5.1.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: mayhem-cli
|
|
3
|
+
Version: 0.5.1
|
|
4
|
+
Summary: General-purpose chaos engineering and resilience-testing framework: a chaos experiment orchestration engine.
|
|
5
|
+
Author: Mayhem Engineering
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Requires-Dist: click>=8.1
|
|
9
|
+
Requires-Dist: pydantic>=2.9
|
|
10
|
+
Requires-Dist: pyyaml>=6.0
|
|
11
|
+
Requires-Dist: structlog>=24.1
|
|
12
|
+
Requires-Dist: typer>=0.12
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# Mayhem
|
|
16
|
+
|
|
17
|
+
**Chaos engineering for Docker & Podman (Kubernetes on the roadmap): discover
|
|
18
|
+
your system, break it on purpose, prove it recovers — every time, with
|
|
19
|
+
evidence.**
|
|
20
|
+
|
|
21
|
+
Mayhem is a drill engine, not a command library. It turns your
|
|
22
|
+
`docker-compose` blueprint into a live topology graph, compiles one declarative
|
|
23
|
+
`kind: drill` YAML file into a frozen, safety-gated execution plan, injects
|
|
24
|
+
faults through a capability-aware toolkit, and ends every run with a machine
|
|
25
|
+
verdict derived from the observations it actually recorded. Steps, probes,
|
|
26
|
+
criteria evaluations, and decisions all land in SQLite — nothing is "trust me,
|
|
27
|
+
it worked."
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
compose blueprint ─▶ topology graph ─▶ compile drill spec ─▶ frozen plan
|
|
31
|
+
│
|
|
32
|
+
verdict ◀── machine criteria ◀── inject → observe → recover
|
|
33
|
+
│
|
|
34
|
+
SQLite evidence + decision trace
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Contents**
|
|
38
|
+
- [Installation](#installation)
|
|
39
|
+
- [Why Mayhem](#why-mayhem)
|
|
40
|
+
- [What a Run Looks Like](#what-a-run-looks-like)
|
|
41
|
+
- [Quickstart](#quickstart)
|
|
42
|
+
- [Authoring a Drill](#authoring-a-drill)
|
|
43
|
+
- [CLI Reference](#cli-reference)
|
|
44
|
+
- [Configuration](#configuration)
|
|
45
|
+
- [Safety Model](#safety-model)
|
|
46
|
+
- [Exit Codes](#exit-codes)
|
|
47
|
+
- [Architecture](#architecture)
|
|
48
|
+
- [Development](#development)
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
Mayhem publishes to PyPI **as `mayhem-cli`** — the bare `mayhem` name is
|
|
55
|
+
taken, so you install the CLI under that name. The console commands it puts on
|
|
56
|
+
your `PATH` are still `mayhem` (and `mayhem-agent`).
|
|
57
|
+
|
|
58
|
+
Requires **Python 3.12+**.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install mayhem-cli
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
That is it — `mayhem` is now on your `PATH`:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
mayhem --help
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Isolated installs (recommended on macOS/Linux)** — keeps the CLI out of your
|
|
71
|
+
global Python:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pipx install mayhem-cli # or: uv tool install mayhem-cli
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Upgrading** — each git tag (`v0.5.0` or `0.5.0`) publishes that exact version:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install -U mayhem-cli
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Need the source checkout instead? See [Development](#development).
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Why Mayhem
|
|
88
|
+
|
|
89
|
+
Most chaos tooling hands you a list of commands — "kill this container," "add
|
|
90
|
+
latency here" — and leaves you to figure out the blast radius, the cleanup, and
|
|
91
|
+
what "healthy" means. Mayhem treats a drill as a **planned, gated, evidenced
|
|
92
|
+
experiment** instead.
|
|
93
|
+
|
|
94
|
+
| | Hand-rolled chaos scripts | Mayhem |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| **Targeting** | You pick a container and hope | Faults plan against a discovered topology graph, so targets stay real |
|
|
97
|
+
| **Safety** | Your discipline | Risk ceiling, `max_faults` budget, and an impact gate that re-proves every fault before anything is injected |
|
|
98
|
+
| **Definition** | Throwaway shell one-liners | One `kind: drill` YAML: per-container faults, ordering, checks, success criteria, observability |
|
|
99
|
+
| **Cleanup** | You remember to | Every fault ships a compensation contract; the janitor sweeps dirty leases after crashes |
|
|
100
|
+
| **Verdict** | Eyeball the dashboards | `PASS`/`FAIL` from typed success criteria evaluated over recorded observations |
|
|
101
|
+
| **Evidence** | Shell history | Immutable SQLite journal: steps, probes, decisions, outcome |
|
|
102
|
+
|
|
103
|
+
Concretely:
|
|
104
|
+
|
|
105
|
+
1. **Topology-aware planning.** Mayhem reads your compose blueprint and
|
|
106
|
+
discovers the live services, hosts, and dependencies to build a graph.
|
|
107
|
+
Faults are planned against that graph, not applied blind; compose project
|
|
108
|
+
filtering keeps unrelated stacks out.
|
|
109
|
+
|
|
110
|
+
2. **Drill specs, not scripts.** One YAML file declares everything — faults,
|
|
111
|
+
cross-container ordering, checks, success criteria, observability sources —
|
|
112
|
+
and you define what "healthy" looks like *before* you break anything.
|
|
113
|
+
|
|
114
|
+
3. **Machine verdicts.** Optional typed success criteria turn every run into a
|
|
115
|
+
`PASS`/`FAIL` verdict derived from the observations actually recorded — no
|
|
116
|
+
eyeballing.
|
|
117
|
+
|
|
118
|
+
4. **Automatic recovery.** Every fault ships a compensation contract: an undo
|
|
119
|
+
op plus a verification probe generated from the same plan parameters, so
|
|
120
|
+
what was injected is exactly what gets removed and re-proven healthy. If a
|
|
121
|
+
round fails or the controller crashes, the janitor sweeps dirty leases and
|
|
122
|
+
reconciles the workload — no manual cleanup. The per-fault lifecycle is
|
|
123
|
+
documented in [`docs/compensation.md`](docs/compensation.md).
|
|
124
|
+
|
|
125
|
+
5. **Honest evidence.** Runs persist an immutable event journal, criteria
|
|
126
|
+
evaluations, and a governing-decision trace in SQLite. No "trust me, it
|
|
127
|
+
worked."
|
|
128
|
+
|
|
129
|
+
6. **Prefix-shortened CLI.** Type `mayhem r` instead of `mayhem run`;
|
|
130
|
+
`mayhem e v` means `mayhem experiment validate`. Every command abbreviates
|
|
131
|
+
to any unique prefix.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## What a Run Looks Like
|
|
136
|
+
|
|
137
|
+
A clean run needs no interpretation — the verdict is one line away. Truncated
|
|
138
|
+
for readability:
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
$ mayhem run mayhem.yaml --compose docker-compose.yml
|
|
142
|
+
|
|
143
|
+
# Run r-process-drill-8f2a1c
|
|
144
|
+
**status**: completed
|
|
145
|
+
**verdict**: pass
|
|
146
|
+
**success criteria**: ALL PASS
|
|
147
|
+
- [PASS] status:api-up.status PASS (expected 200, got 200)
|
|
148
|
+
- [PASS] latency:api-up.latency_ms PASS (31.2 <= 500.0)
|
|
149
|
+
**observations**: 2/2 sources collected
|
|
150
|
+
**decisions**: 5 governing decision revisions (snapshot in the run row)
|
|
151
|
+
**wall**: 32.4s
|
|
152
|
+
|
|
153
|
+
run r-process-drill-8f2a1c — inspect with `mayhem history r-process-drill-8f2a1c`
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Reading the transcript, top to bottom:
|
|
157
|
+
|
|
158
|
+
1. **Status** — the run's machine state: `completed` (or `failed`/`aborted`
|
|
159
|
+
with a non-zero exit and dirty-lease warnings).
|
|
160
|
+
2. **Verdict** — `pass`/`fail` derived from the success criteria you declared
|
|
161
|
+
in the spec; `undecided` when a run aborts or the spec has no success block.
|
|
162
|
+
3. **Success criteria** — every criterion evaluated against real observations,
|
|
163
|
+
one line each, so a failure tells you exactly what drifted.
|
|
164
|
+
4. **Observations** — how many configured evidence sources actually delivered
|
|
165
|
+
data (probes, logs, metrics …).
|
|
166
|
+
5. **Decisions** — the governing decision revisions that shaped this run; the
|
|
167
|
+
decision trace is queryable afterward via `mayhem history`.
|
|
168
|
+
6. **Copy-paste handle** — the run id for the follow-up commands below.
|
|
169
|
+
|
|
170
|
+
From there: `mayhem status` lists recent runs, `mayhem status --run <run-id>`
|
|
171
|
+
shows full recorded metadata, and `mayhem history <run-id>` replays the
|
|
172
|
+
complete event journal (every step, probe sample, and lease for that run).
|
|
173
|
+
Add `--debug` to `mayhem run` to stream each step live as it happens (`[ok]
|
|
174
|
+
injected proc.pause 10s into testcase-api`, `[ok] recovered ... (compensation
|
|
175
|
+
ok)`).
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Quickstart
|
|
180
|
+
|
|
181
|
+
**Prerequisites**
|
|
182
|
+
|
|
183
|
+
- Python 3.12+
|
|
184
|
+
- Docker with Compose v2 (or Podman, used via the `--podman` flag)
|
|
185
|
+
- No host tooling required up front: `mayhem toolkit list` probes for the
|
|
186
|
+
capabilities (docker, podman, network tooling, `k6`, …) each fault needs,
|
|
187
|
+
and the impact gate refuses to run anything it cannot prove.
|
|
188
|
+
|
|
189
|
+
**Install**
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
pip install mayhem-cli
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
> The PyPI package is **`mayhem-cli`** (`mayhem` is taken); the console command
|
|
196
|
+
> remains `mayhem`. Full instructions in
|
|
197
|
+
> [Installation](#installation). For a source checkout use
|
|
198
|
+
> `pip install -e .` (see [Development](#development)).
|
|
199
|
+
|
|
200
|
+
**Run the bundled example**
|
|
201
|
+
|
|
202
|
+
A complete, self-contained example lives in `examples/testCase/` — a
|
|
203
|
+
six-service compose stack (API, web, load balancer, dual download builders, and
|
|
204
|
+
Postgres), its drill spec, and the fixtures it relies on.
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# 0. Bring the stack up.
|
|
208
|
+
cd examples/testCase
|
|
209
|
+
docker compose up -d
|
|
210
|
+
|
|
211
|
+
# 1. See the topology Mayhem will plan against (blueprint ─▶ live graph).
|
|
212
|
+
mayhem topology discover --compose docker-compose.yml
|
|
213
|
+
|
|
214
|
+
# 2. Compile the spec and run every safety gate — injects nothing.
|
|
215
|
+
mayhem validate mayhem.yaml --compose docker-compose.yml
|
|
216
|
+
|
|
217
|
+
# 3. Print the frozen execution plan as JSON.
|
|
218
|
+
mayhem plan mayhem.yaml --compose docker-compose.yml
|
|
219
|
+
|
|
220
|
+
# 4. Execute the drill and print the run summary.
|
|
221
|
+
mayhem run mayhem.yaml --compose docker-compose.yml
|
|
222
|
+
|
|
223
|
+
# (Variant) limit a run to ONE container — the pinned container's faults run,
|
|
224
|
+
# every other container's rounds are dropped from the frozen plan.
|
|
225
|
+
mayhem run mayhem.yaml --compose docker-compose.yml --ctr testcase-api
|
|
226
|
+
|
|
227
|
+
# (Variant) `maniac` draws its random rounds against a single container too —
|
|
228
|
+
# handy when you want to chaos-test one container without touching the others.
|
|
229
|
+
mayhem maniac --compose docker-compose.yml --ctr testcase-api
|
|
230
|
+
|
|
231
|
+
# 5. Replay any run's evidence.
|
|
232
|
+
mayhem status --run <run-id>
|
|
233
|
+
mayhem history <run-id>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
`mayhem run` prints a copy-paste `run <run-id> — inspect with mayhem history
|
|
237
|
+
<run-id>` line at the end; that id is all you need for the evidence commands.
|
|
238
|
+
|
|
239
|
+
The example spec exercises **38 distinct faults** (every catalog entry that
|
|
240
|
+
applies to a Docker/Podman compose service) across the `testcase-lb`
|
|
241
|
+
load-balancer — CPU/memory/fd/disk pressure, load spikes, protocol abuse,
|
|
242
|
+
network latency/bandwidth/packet-loss, dependency and database and DNS faults,
|
|
243
|
+
TLS failure, container kill/restart/pause, HTTP error injection —
|
|
244
|
+
capped at one concurrent fault (`max_faults: 1`, `risk_ceiling: critical`)
|
|
245
|
+
with auto-recovery off (`recovery: false`), so the downstream checks observe
|
|
246
|
+
whether the stack self-heals on its own. The remaining nine `k8s.*` catalog
|
|
247
|
+
faults are exercised against a Kubernetes blueprint in
|
|
248
|
+
[`examples/k8s`](examples/k8s) (planning-only until the M8 driver lands), so
|
|
249
|
+
**every fault in the catalog has an example**.
|
|
250
|
+
|
|
251
|
+
Omit `--compose` and Mayhem auto-detects `docker-compose.yml` (or
|
|
252
|
+
`compose.yml`) in the current directory.
|
|
253
|
+
|
|
254
|
+
> `validate` and `plan` work against the blueprint alone and never touch live
|
|
255
|
+
> containers. `run` re-proves every fault at the impact gate against the live
|
|
256
|
+
> graph and bypasses — or, without `--skip-gate`, refuses — anything it cannot
|
|
257
|
+
> prove injectable.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Authoring a Drill
|
|
262
|
+
|
|
263
|
+
A drill is one `kind: drill` YAML file — the DSL reference lives in
|
|
264
|
+
[`docs/drill-spec.md`](docs/drill-spec.md). The shape:
|
|
265
|
+
|
|
266
|
+
```yaml
|
|
267
|
+
apiVersion: "mayhem/v1"
|
|
268
|
+
kind: drill
|
|
269
|
+
name: checkout-recovery
|
|
270
|
+
hypothesis: "checkout stays available while cart writes are throttled"
|
|
271
|
+
|
|
272
|
+
config:
|
|
273
|
+
risk_ceiling: high # refuse faults riskier than this (policy ceilings only tighten)
|
|
274
|
+
max_faults: 1 # never inject more than one fault at once
|
|
275
|
+
timeout: 30m
|
|
276
|
+
|
|
277
|
+
containers:
|
|
278
|
+
cart-api: # keys ARE compose container_name values
|
|
279
|
+
faults:
|
|
280
|
+
- fault: net.latency
|
|
281
|
+
duration: 10s
|
|
282
|
+
params: { seconds: 5s, jitter_ms: 10 }
|
|
283
|
+
|
|
284
|
+
execution:
|
|
285
|
+
- parallel: [cart-api]
|
|
286
|
+
- check_spec: # locus-aware checks
|
|
287
|
+
- id: cart-health
|
|
288
|
+
probe: { type: http, url: http://cart-api:8080/_health, expected_status: 200 }
|
|
289
|
+
execution: service
|
|
290
|
+
target: cart-api
|
|
291
|
+
|
|
292
|
+
success: # machine verdict
|
|
293
|
+
require_all: true
|
|
294
|
+
criteria:
|
|
295
|
+
- type: status
|
|
296
|
+
source_id: cart-health.status
|
|
297
|
+
expected: 200
|
|
298
|
+
- type: latency
|
|
299
|
+
source_id: cart-health.latency_ms
|
|
300
|
+
lt_ms: 800
|
|
301
|
+
|
|
302
|
+
observability: # evidence sources
|
|
303
|
+
sources:
|
|
304
|
+
- kind: logs
|
|
305
|
+
source_id: cart-logs
|
|
306
|
+
container: cart-api
|
|
307
|
+
tail: 200
|
|
308
|
+
- kind: probe
|
|
309
|
+
source_id: cart-probe
|
|
310
|
+
probe: { type: http, url: http://cart-api:8080/_health }
|
|
311
|
+
cadence: 2s
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Validate with `mayhem validate mayhem.yaml`; unknown parameters, out-of-range
|
|
315
|
+
durations, untargetable node kinds, and capability gaps are all compile-time
|
|
316
|
+
errors — before anything is injected.
|
|
317
|
+
|
|
318
|
+
### Campaigns
|
|
319
|
+
|
|
320
|
+
A campaign groups drill specs under one execution umbrella (ADR-0022/0023):
|
|
321
|
+
experiments run sequentially in priority order, and the campaign's failure
|
|
322
|
+
policy and time window govern the whole run.
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
mayhem campaign create black-friday \
|
|
326
|
+
--description "BFCM chaos" --hypothesis "checkout survives every single-fault failure"
|
|
327
|
+
mayhem campaign add-experiment black-friday mayhem.yaml
|
|
328
|
+
mayhem campaign add-experiment black-friday checkout-recovery.yaml
|
|
329
|
+
mayhem campaign start black-friday # draft -> running
|
|
330
|
+
mayhem campaign run black-friday --compose docker-compose.yml
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
A campaign is born `draft` and moves through
|
|
334
|
+
`scheduled → running → paused → completed / aborted` (`archive` closes a
|
|
335
|
+
finished campaign). Per-experiment results land in the observations table
|
|
336
|
+
under the campaign id, and the failure policy selects the next action when
|
|
337
|
+
one experiment fails:
|
|
338
|
+
|
|
339
|
+
| `on_experiment_failure` | Meaning |
|
|
340
|
+
|-------------------------|---------|
|
|
341
|
+
| `abort_campaign` (default) | Stop the remaining experiments. |
|
|
342
|
+
| `skip_and_continue` | Record the failure and run the next experiment. |
|
|
343
|
+
| `retry_then_abort` | Retry the failed experiment once, then abort the campaign. |
|
|
344
|
+
|
|
345
|
+
Window fields (`window_json`): `start_epoch_s` / `end_epoch_s`,
|
|
346
|
+
`max_duration_s` (hard stop), and `cooldown_between_experiments_s` between
|
|
347
|
+
successive experiments.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## CLI Reference
|
|
352
|
+
|
|
353
|
+
Global options (accepted at any level, before or after the command):
|
|
354
|
+
|
|
355
|
+
| Option | Meaning |
|
|
356
|
+
|--------|---------|
|
|
357
|
+
| `--db PATH` | SQLite database path (default `mayhem.db`). |
|
|
358
|
+
| `--config PATH` | Path to `mayhem.yaml` (overrides auto-detection). |
|
|
359
|
+
| `--profile NAME` | Configuration profile to merge. |
|
|
360
|
+
| `--allow-critical` | Acknowledge `critical`-risk faults (e.g. `k8s.node_drain`). |
|
|
361
|
+
| `--skip-gate` | Run even when the impact gate proved some faults inert. |
|
|
362
|
+
| `--podman` | Use Podman instead of Docker. |
|
|
363
|
+
| `--debug` | Re-raise errors instead of rendering them. |
|
|
364
|
+
|
|
365
|
+
Commands:
|
|
366
|
+
|
|
367
|
+
| Command | Description |
|
|
368
|
+
|---------|-------------|
|
|
369
|
+
| `mayhem topology discover` | Discover live services/hosts and the dependency edges from the blueprint. |
|
|
370
|
+
| `mayhem validate SPEC` | Compile a drill spec and run every safety gate without injecting. |
|
|
371
|
+
| `mayhem plan SPEC` | Compile against the topology and print the frozen plan JSON. |
|
|
372
|
+
| `mayhem run SPEC` | Compile and execute a drill; print the run summary. `--ctr CONTAINER` scopes execution to one container (any `container_name:` value or runtime container name from the blueprint). |
|
|
373
|
+
| `mayhem maniac SPEC` | Compile and execute a random-injection drill — draws `run_level` single-fault rounds governed by the maniac seed/level (spec `config.maniac`, falling back to the `maniac:` layer of `mayhem.yaml`). `--ctr CONTAINER` narrows every draw (and the zero-config synthesized pool) to one container. |
|
|
374
|
+
| `mayhem status` | Show runs recorded in the database (`--json` supported). |
|
|
375
|
+
| `mayhem history RUN_ID` | Replay steps, events, and leases recorded for one run. |
|
|
376
|
+
| `mayhem recover RUN_ID` | Recover every orphaned fault lease belonging to a run. |
|
|
377
|
+
| `mayhem janitor` | Sweep leases past their TTL; expire pending runs; compensate. |
|
|
378
|
+
| `mayhem toolkit faults` | List the fault catalog with risk and compensatability. |
|
|
379
|
+
| `mayhem toolkit list` | Probe the host for the tools/capabilities faults require. |
|
|
380
|
+
| `mayhem experiment show SPEC` | Print the parsed drill spec as JSON. |
|
|
381
|
+
| `mayhem experiment validate` | Alias of `validate`. |
|
|
382
|
+
| `mayhem config show` / `mayhem config validate` | Inspect / validate the effective layered configuration (alias `cfg`). `show --json` also reports each section's provenance. |
|
|
383
|
+
| `mayhem campaign list` | List campaigns (draft/scheduled/running/…; `--json`). |
|
|
384
|
+
| `mayhem campaign create NAME` | Create a draft campaign (`--description`, `--hypothesis`). |
|
|
385
|
+
| `mayhem campaign show / status / delete ID` | Inspect, poll, or delete a campaign. |
|
|
386
|
+
| `mayhem campaign add-experiment ID SPEC` | Append a drill spec file to a campaign. |
|
|
387
|
+
| `mayhem campaign start / abort / archive ID` | Move a campaign through its lifecycle. |
|
|
388
|
+
| `mayhem campaign run ID` | Execute every experiment sequentially against the compose topology, honoring the campaign policy and window (`--no-gate` bypasses the impact gate). |
|
|
389
|
+
|
|
390
|
+
Every command (and the whole tree) abbreviates to any unique prefix: `mayhem
|
|
391
|
+
ex valid`, `mayhem t f`.
|
|
392
|
+
|
|
393
|
+
---
|
|
394
|
+
|
|
395
|
+
## Configuration
|
|
396
|
+
|
|
397
|
+
Runtime policies live in `mayhem.yaml` — the *configuration* file, distinct
|
|
398
|
+
from a `kind: drill` spec — auto-detected in the cwd or given with
|
|
399
|
+
`--config`. The effective view is one command away: `mayhem config show`
|
|
400
|
+
(alias `cfg`) prints the resolved configuration and the provenance of every
|
|
401
|
+
section; `mayhem config validate` refuses unknown keys, a missing or wrong
|
|
402
|
+
`apiVersion`, and out-of-range sections before anything runs.
|
|
403
|
+
|
|
404
|
+
```yaml
|
|
405
|
+
apiVersion: mayhem/v1 # required; anything else is rejected
|
|
406
|
+
policy:
|
|
407
|
+
allow_faults: null # null = whole catalog; set to restrict
|
|
408
|
+
deny_faults: [] # fault ids never injectable
|
|
409
|
+
risk_ceiling: null # tightened by the drill ceiling at plan time
|
|
410
|
+
allow_critical: false # config-side half of the critical opt-in
|
|
411
|
+
blast_radius:
|
|
412
|
+
max_services_pct: 50.0
|
|
413
|
+
max_hosts: 2
|
|
414
|
+
max_concurrent_faults: 3
|
|
415
|
+
max_duration_per_fault_s: 300.0
|
|
416
|
+
forbidden_fault_pairs: [] # e.g. ["net.packet_loss", "net.bandwidth"]
|
|
417
|
+
storage:
|
|
418
|
+
path: mayhem.db # SQLite database (same default as --db)
|
|
419
|
+
artifacts_dir: .mayhem/artifacts
|
|
420
|
+
toolkit:
|
|
421
|
+
binaries: {} # pin a named tool's binary, keyed by fault backend
|
|
422
|
+
runtime: docker # docker | podman (CLI: --podman)
|
|
423
|
+
target:
|
|
424
|
+
containers: [] # explicit targets when no compose file is used
|
|
425
|
+
log_level: INFO # DEBUG | INFO | WARNING | ERROR
|
|
426
|
+
maniac: # fallback for `mayhem maniac` when the spec omits config.maniac
|
|
427
|
+
level: 2
|
|
428
|
+
run_level: 10
|
|
429
|
+
seed: null # null = fresh random seed each run
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
Layering, in increasing precedence: **built-in defaults → `mayhem.yaml` →
|
|
433
|
+
`mayhem.{profile}.yaml` → environment variables → CLI flags**. Profile
|
|
434
|
+
overlays are separate per-profile files (selected with `--profile NAME`) —
|
|
435
|
+
there is no `profiles:` key inside `mayhem.yaml`. The environment layer only
|
|
436
|
+
honours allowlisted variables: `MAYHEM_STORAGE_PATH`,
|
|
437
|
+
`MAYHEM_ARTIFACTS_DIR`, `MAYHEM_LOG_LEVEL`.
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
mayhem config show # YAML + sourced-from comments
|
|
441
|
+
mayhem config show --json # {"config": …, "sources": …}
|
|
442
|
+
mayhem config validate # exit 0 / 3 on invalid layers
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
Drill-level `config.risk_ceiling` composes with the policy ceiling and can
|
|
446
|
+
only tighten it.
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## Safety Model
|
|
451
|
+
|
|
452
|
+
- **Risk ceilings.** Every catalog fault carries a risk level; injection is
|
|
453
|
+
refused when either the policy or the drill ceiling is exceeded.
|
|
454
|
+
`--allow-critical` is the operator-side acknowledgment.
|
|
455
|
+
- **Concurrency budget.** `max_faults` caps simultaneously-injected faults;
|
|
456
|
+
a wider `parallel:` step queues into rounds.
|
|
457
|
+
- **Duration caps.** Per-fault `duration` beyond the catalog maximum is a
|
|
458
|
+
compile error.
|
|
459
|
+
- **Capability gating.** Faults declare the capabilities they need
|
|
460
|
+
(docker engine, net_admin, process control, …); the plan is proven against
|
|
461
|
+
the live graph by the impact gate before run — never assumed.
|
|
462
|
+
- **Compensation contracts.** Reversible faults run their declared inverse;
|
|
463
|
+
irreversible ones are followed by workload reconciliation. A failed round
|
|
464
|
+
aborts-and-recovers its own faults first, then propagates.
|
|
465
|
+
- **Lease hygiene.** Fault rounds hold leases with a TTL; `mayhem janitor`
|
|
466
|
+
sweeps orphaned leases and expires pending runs, `mayhem recover` repairs a
|
|
467
|
+
run's orphans on demand.
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## Exit Codes
|
|
472
|
+
|
|
473
|
+
Stable contract for scripts and CI (definition:
|
|
474
|
+
[`src/mayhem/cli/exit_codes.py`](src/mayhem/cli/exit_codes.py)):
|
|
475
|
+
|
|
476
|
+
| Code | Meaning |
|
|
477
|
+
|------|---------|
|
|
478
|
+
| 0 | Success |
|
|
479
|
+
| 1 | General failure |
|
|
480
|
+
| 2 | Usage error (bad flags/arguments) |
|
|
481
|
+
| 3 | Configuration layering/validation failed |
|
|
482
|
+
| 4 | Spec/target validation failed |
|
|
483
|
+
| 5 | A safety gate refused the operation |
|
|
484
|
+
| 6 | Experiment ran and did not complete |
|
|
485
|
+
| 7 | Recovery/janitor left dirty state behind |
|
|
486
|
+
| 8 | Agent transport/runtime failure |
|
|
487
|
+
| 9 | External tool invocation failed structurally |
|
|
488
|
+
| 10 | Command prefix matched multiple commands |
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
## Architecture
|
|
493
|
+
|
|
494
|
+
The pipeline is staged so everything expensive is done up front and execution
|
|
495
|
+
is as small as possible:
|
|
496
|
+
|
|
497
|
+
1. **Discover** — the topology provider builds a graph (services, hosts,
|
|
498
|
+
dependency edges) from the compose blueprint and live containers.
|
|
499
|
+
2. **Prepare** — `mayhem config` layering (defaults → `mayhem.yaml` → profile →
|
|
500
|
+
env → flags) plus topology, drift detection, and target revalidation.
|
|
501
|
+
3. **Compile & plan** — the drill spec becomes a frozen `ExecutionPlan` with
|
|
502
|
+
step sequences, per-fault compensations, success criteria, and observability
|
|
503
|
+
sources; every fault, target kind, capability, and duration is validated
|
|
504
|
+
against the catalog.
|
|
505
|
+
4. **Execute** — the engine runs rounds (inject → observe → compensate) through
|
|
506
|
+
the runtime adapter, evaluates criteria, collects observability, and writes
|
|
507
|
+
step/event/lease rows with the governing-decision trace.
|
|
508
|
+
5. **Recover & report** — the janitor sweeps orphaned leases; `status`,
|
|
509
|
+
`history`, and run summaries replay the evidence.
|
|
510
|
+
|
|
511
|
+
### Documentation
|
|
512
|
+
|
|
513
|
+
| Document | Contents |
|
|
514
|
+
|----------|----------|
|
|
515
|
+
| [README.md](README.md) | This file. |
|
|
516
|
+
| [docs/drill-spec.md](docs/drill-spec.md) | **The drill DSL reference** — config, containers, execution, checks, success criteria, observability, and the full fault catalog. |
|
|
517
|
+
| [docs/compensation.md](docs/compensation.md) | **Fault compensation lifecycle** — inject / undo / verify contracts, executor routing, marker conventions, and the per-fault template table. |
|
|
518
|
+
|
|
519
|
+
### Status
|
|
520
|
+
|
|
521
|
+
| Area | Status |
|
|
522
|
+
|------|--------|
|
|
523
|
+
| Domain models, configuration system | Complete |
|
|
524
|
+
| Topology discovery (Docker/Podman) + compose project filtering + drift detection | Complete |
|
|
525
|
+
| Fault catalog + registry + capability probing (`toolkit`) | Complete |
|
|
526
|
+
| Drill spec DSL (config / containers / execution / checks) | Complete |
|
|
527
|
+
| Deterministic + random planners, frozen plans | Complete |
|
|
528
|
+
| Success criteria + machine verdict | Complete |
|
|
529
|
+
| Declarative observability sources | Complete |
|
|
530
|
+
| Run engine with compensation + leases + janitor + recover | Complete |
|
|
531
|
+
| Safety gates + impact gate | Complete |
|
|
532
|
+
| CLI with prefix abbreviation, stable exit codes | Complete |
|
|
533
|
+
| SQLite persistence + restart, migrations (schema freeze) | Complete |
|
|
534
|
+
| Campaigns (multi-spec runs) | Complete |
|
|
535
|
+
| Tests (859 collected: 752 unit + 95 e2e + 12 integration), ruff, mypy (per-file strict) | Complete |
|
|
536
|
+
| Kubernetes execution | Planned (interface-only; see [`examples/k8s`](examples/k8s)) |
|
|
537
|
+
| Web UI / REST API | Planned |
|
|
538
|
+
|
|
539
|
+
---
|
|
540
|
+
|
|
541
|
+
## Development
|
|
542
|
+
|
|
543
|
+
```bash
|
|
544
|
+
# Clone, then sync the dev dependency group (requires https://docs.astral.sh/uv/):
|
|
545
|
+
uv sync --group dev
|
|
546
|
+
|
|
547
|
+
# Run all tests
|
|
548
|
+
uv run pytest
|
|
549
|
+
|
|
550
|
+
# Lint
|
|
551
|
+
uv run ruff check src/
|
|
552
|
+
|
|
553
|
+
# Type check (strict is configured per module)
|
|
554
|
+
uv run mypy
|
|
555
|
+
```
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
mayhem/config.py,sha256=dJhQ4oLFL57imYs3aU2QUhcL1qhZv_gH7oFsC6yuslQ,7715
|
|
2
|
+
mayhem/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
mayhem/spec.py,sha256=QxhE90OzkUBJX03WGFkdBRGmN7PkO2_FzPQJb2NNLnU,1876
|
|
4
|
+
mayhem/agent/__init__.py,sha256=GFXICPnXKO0n3rUtwCHDLdBa_wLlcVEBs_Aczu8jS-w,65
|
|
5
|
+
mayhem/agent/cli.py,sha256=LIA6jGn-PkR3vMNZGUJXiegwYp0gHWFmKsPqJQUxLRk,1040
|
|
6
|
+
mayhem/agents/__init__.py,sha256=HLHzcJE2hy4NSKvS9GL_mv5LPS-b16_RzYS2hBdf8Ro,71
|
|
7
|
+
mayhem/agents/capabilities.py,sha256=bS2kF6xJSs-8EAYPuX4ctxQZS6yJteCx2YwPx8YdYG0,4045
|
|
8
|
+
mayhem/agents/executors.py,sha256=I6A7j5xm00Fxnx8qc0uQ1rsnsTU9cL2lxnAJpeVsAq8,17745
|
|
9
|
+
mayhem/agents/impact.py,sha256=VswHeBaUDtgaap0M1EVjWXleNXQPjemRme_cFM5JDpE,29834
|
|
10
|
+
mayhem/agents/lease_client.py,sha256=G0x7PXHAaO9S1VJ8Hs_VQvVs0TywXq_Thlx_C7H4uIA,5289
|
|
11
|
+
mayhem/agents/probes.py,sha256=RtLYSbcpqzNBiQQhKjM1bERZbPohvcHyFg9FIJ0Kt_E,11377
|
|
12
|
+
mayhem/agents/protocol.py,sha256=0m-yevK1ymNlFfm16o3N8L2sXIA9Jqdksop0UJXtSCA,4212
|
|
13
|
+
mayhem/agents/server.py,sha256=uW1Lmh7XWSItYYB3wiaJ2cyJaiW3WH-95GnJIJsigSQ,10530
|
|
14
|
+
mayhem/agents/sinks.py,sha256=MmueFAXYr-h1xJ_D7CxC3atejw8_uMVnxck2FNxMi-0,1907
|
|
15
|
+
mayhem/agents/transports.py,sha256=nPqvmhQd4MMAKLyvGTIoTosJp4-2bE7pWHitcjqJ6AQ,4863
|
|
16
|
+
mayhem/agents/watchdog.py,sha256=15TawWyU5K7F71bI026LsPXXVJpY85fqI5dLvaMWxZM,4888
|
|
17
|
+
mayhem/cli/__init__.py,sha256=8YnPhmrUa_FXrXGf_59KzLlKEu68o0AU3kD2Ogmnwus,315
|
|
18
|
+
mayhem/cli/app.py,sha256=0K-pb2P1Vo5lPIBBYi0dSmRRgha1RN_U2am3_ZsJPNU,5086
|
|
19
|
+
mayhem/cli/campaign.py,sha256=40AgPX1Oab9TllVSxZGd2Fje3Jobz1woOUSp3fIZl9o,18951
|
|
20
|
+
mayhem/cli/config_cmd.py,sha256=slnw6gmB2wFt7tkeXNrTkqjfNGNrjG4jfjvrGRW3bOc,1567
|
|
21
|
+
mayhem/cli/context.py,sha256=-rXsb6UxEH6K4GrF2InbmK6NvpbmzrTEo3e1QK2-Nxs,704
|
|
22
|
+
mayhem/cli/dependency.py,sha256=U0eCPy6_M0xbzvIFhW7NgjE8iokLssCtUqcR8p1WFqc,16917
|
|
23
|
+
mayhem/cli/exit_codes.py,sha256=954KstzNhKGNFPq9i3OOSra5v99poHZRRYzzQhj7RaM,1014
|
|
24
|
+
mayhem/cli/experiment.py,sha256=sOEuQZt3NZTFxEdhBPyFvS_VJ9fJ0Rt-hl718XftnnM,730
|
|
25
|
+
mayhem/cli/lifecycle.py,sha256=bTmd66FGjhAIjl7100x00b4i8TjNqc_Ius_AxBu3pgM,30767
|
|
26
|
+
mayhem/cli/resolver.py,sha256=pJLhbiLKuAZfk5yoJMuMZjCuWVf0XwWbbcBa4POB2Rw,2783
|
|
27
|
+
mayhem/cli/services.py,sha256=FqHPbraiJDVbM34bL4Luw_eypGiDNRQ0Y4tW0uBUkK0,15418
|
|
28
|
+
mayhem/cli/style.py,sha256=Jb5DDvbVCQrKX-Mk61RTmWdJJOSd1x0EUPieZrM4CbA,3227
|
|
29
|
+
mayhem/cli/toolkit.py,sha256=2DGjNfQyTfB-K4n_zpjEphInFZoBHpCh4UkOF65De7o,1649
|
|
30
|
+
mayhem/cli/topology.py,sha256=xUXn27wR_7-2igPyT0Ksw4jymFed-djVMkuEljM9K2o,4217
|
|
31
|
+
mayhem/controller/__init__.py,sha256=JV0geUIkFwcZZRgUnVi-1bd5RlBKq4yyo-aTwF8IxpM,74
|
|
32
|
+
mayhem/controller/compensation.py,sha256=ZSBeLMGZbPZmEgj8jneedGCk8q1cxYsuhQokBxJPBu0,77435
|
|
33
|
+
mayhem/controller/executor.py,sha256=3-eorfOLlVsnLswvpFIVD04nlBd9n-i3nKFKwARsqmU,73628
|
|
34
|
+
mayhem/controller/janitor.py,sha256=rmOfOjhp6Ut_9txhS1LjLBGOLxEA8zk9UEBALZYciX4,7590
|
|
35
|
+
mayhem/controller/observability_collector.py,sha256=W83v4JMyKLXLn01pHhVGGXkeZUUZdXKEkgAh8_yZibw,13331
|
|
36
|
+
mayhem/controller/observations.py,sha256=lIUkUnnmxhS370433rOYDHhQpqLkTfHyqd-a4yKUa-U,3543
|
|
37
|
+
mayhem/controller/planner.py,sha256=J30hm-kynaqDJeAy2PfKuFhDyP2GNqUp0BueO5DgeR0,28776
|
|
38
|
+
mayhem/controller/recovery.py,sha256=pSZq2gLsUXqJT7XzXWqv7p7PLgMKKvM289VxAIVYuiw,9313
|
|
39
|
+
mayhem/controller/resilience_report.py,sha256=9I3UTHY_N637bekMowQBqM2kKl2BnDV57Yx09YTSZTs,21702
|
|
40
|
+
mayhem/controller/resource_manager.py,sha256=deyOrA82079-8h6HMQn-QyA6lk1t9xrYXAHIhaxKP64,18590
|
|
41
|
+
mayhem/controller/safety.py,sha256=4DtQfKHthh_fpbQNoEVLE_iorRge8y4UM-SPJNcHhdk,14644
|
|
42
|
+
mayhem/domain/__init__.py,sha256=RuJsWAUWymDh8uoK0cjR4FlDRsV1ERphhdM1z6Aok9Y,254
|
|
43
|
+
mayhem/domain/campaigns.py,sha256=DhcIW81sIDk11Z4G8a5uw5ZMs96XKaLWW5cSSa3Yzz0,3773
|
|
44
|
+
mayhem/domain/cancellation.py,sha256=HHou6pHbPZHo1x7adgWwTpQahPLc-Glv7xRjrlpzDBI,3524
|
|
45
|
+
mayhem/domain/candidates.py,sha256=7g7t5s0O0vsN7aqFVQMeg_eTHN4WHxsp4TnMj0kuw_8,3172
|
|
46
|
+
mayhem/domain/capabilities.py,sha256=gqVNUO0PTPy2theCuigPHPI29fYU2oTjDHrIIdEGYko,2723
|
|
47
|
+
mayhem/domain/catalog.py,sha256=YqRErJLqCXmEUx4m9A8iJFsVHapi9zaOp_lKPC2BMK0,27770
|
|
48
|
+
mayhem/domain/checks.py,sha256=gcU9gBfPx3rhibp112XE1W3N_8BgJvKJ9DYeKkBrA3w,4810
|
|
49
|
+
mayhem/domain/common.py,sha256=j4G1OzKU4Mr4pfSU4GKaUgL2sON6PMH9VUFaoZEDAa0,3601
|
|
50
|
+
mayhem/domain/coverage.py,sha256=cEJKCBVBDK5aavTyh9ealnGZ1KFfK6NT-vjR8n6ONtQ,3355
|
|
51
|
+
mayhem/domain/decisions.py,sha256=IRLrrNqwVP_LucxzQYMGHnc54GkbEn8phTGFikHw3Lw,1754
|
|
52
|
+
mayhem/domain/errors.py,sha256=dCaLQ5Hzc2qzjbk1n5leM8eCNAt5_nWh1k-CJk84mbU,2779
|
|
53
|
+
mayhem/domain/events.py,sha256=xBGMBXfC4eFKvKBCkqY7OGwAE_R2xfNx4JkgwR5q7To,2039
|
|
54
|
+
mayhem/domain/execution_context.py,sha256=GvLTYRzzaTCgia0MJc1nUmuhvdSjv1GsJ2xK7G8YeTE,4576
|
|
55
|
+
mayhem/domain/execution_loci.py,sha256=zQWLUP_MRd8ik736Zk3MzFWqOhlrS43mJ5YjSRXichw,3360
|
|
56
|
+
mayhem/domain/experiments.py,sha256=4sVfvcIk5deUdvIorbHopfi_7luKzMc9pEF5GGqeo44,13914
|
|
57
|
+
mayhem/domain/faults.py,sha256=Ls-w8K1Gm1EM6f1dHfPXS3PURVWdfRldCrRuFZRrDmw,8308
|
|
58
|
+
mayhem/domain/identity.py,sha256=G4hP-wBsi2JIzBg-qiNJe00ITB-_9_sdR48Xrv0yBXM,7540
|
|
59
|
+
mayhem/domain/k8s_adapter.py,sha256=5JfhR1l8LHcHJ1JR1aGIfaAncnFS8qUs398nyh1p-D0,4919
|
|
60
|
+
mayhem/domain/leases.py,sha256=uMqM9BowwrTKA8bn1T2Z-mw550jWubLiW-uFTeWfDN0,7371
|
|
61
|
+
mayhem/domain/load_strategy.py,sha256=HyEBm4kPTOevS9zULeQG3_bGm04IrMzW_Bnc90o0XJ8,3461
|
|
62
|
+
mayhem/domain/m5_campaign.py,sha256=7i3fsT1fNxh4EzVswqv1ssrBA6C_lt0Ncz8adaaKrTI,3740
|
|
63
|
+
mayhem/domain/maniac.py,sha256=JU61KL92gcx9ZMNnlqEpptg6uO_3QvwGGWJhYTaL5o8,3548
|
|
64
|
+
mayhem/domain/observability.py,sha256=8IboJIIuifCWrzyGkGYjL7_nOkAxntaZBtUmn9M1iAM,5281
|
|
65
|
+
mayhem/domain/outcomes.py,sha256=K5m-NAv59Cs6We2uFXUbwvL6GYkD3eoesxu4BD9pFHo,3269
|
|
66
|
+
mayhem/domain/remote_agent_interface.py,sha256=xAJbeTJWhjg2azDLwXEDDtsgsR-s1ftugSZUKxwFQoQ,2216
|
|
67
|
+
mayhem/domain/resources.py,sha256=Nem2hibXe3-nfUWGsIkdD34fM7Urleg7tSpIyvJ497w,9035
|
|
68
|
+
mayhem/domain/risks.py,sha256=FgkVP-tFjz2bkAECwY57PuiSXJV-CwhyGM3AQKvXGhY,1585
|
|
69
|
+
mayhem/domain/run_outcome.py,sha256=ZHZCsTXvmFvkkAQxN2WMTM5N1lIVOEtKW89O1Axwv8E,4521
|
|
70
|
+
mayhem/domain/runtime_adapter.py,sha256=1-TMz9nkR0RvM7Sk67nUc37mavuEJZmeQw7skfNgnRw,9003
|
|
71
|
+
mayhem/domain/success.py,sha256=dlStGb1csg_QvlzvsGkyyeiOx8YEHLdrh04MCL_Q1xA,11614
|
|
72
|
+
mayhem/domain/topology.py,sha256=a0F8pwi9GkE9X9h26QwxTMt-mt_NdN3MOXuLPP_O-sE,16787
|
|
73
|
+
mayhem/infra/__init__.py,sha256=Jx4vcGjUyoY73TtMU3rHb10hO7ZS9zPK5pB7dnP3CqA,84
|
|
74
|
+
mayhem/infra/campaign_engine.py,sha256=7TgXYxuB2-dJxEAqwE90qqL1mbS1XgKRQ8r-Wk4MrOY,8215
|
|
75
|
+
mayhem/infra/candidate_gates.py,sha256=7XcwhtNXP_t-I1qf89nxfrOXEqI47v9yq83mCrmEktE,4489
|
|
76
|
+
mayhem/infra/candidate_generator.py,sha256=yT_7jTRgqD2ZB40qMYqPmQrJwq9TGWqCSflKbnz1NAY,3914
|
|
77
|
+
mayhem/infra/coverage_repository.py,sha256=ONOqLcTh28ZRJXOUuwiCOLYET1u3kOKOCyoa1DpUD5Y,3582
|
|
78
|
+
mayhem/infra/lease_repository.py,sha256=cot8vrNQEWM0SheaMmlr_dIyjt_UK_XIzK24JgesKvw,5147
|
|
79
|
+
mayhem/infra/maniac.py,sha256=RSt8H60_Vs6SEHj6OBsj_rEuOFsNK2uabdDbIXmwJns,3552
|
|
80
|
+
mayhem/infra/migrations.py,sha256=kvLSq9zapCYCXI-QYr_xfN51f-e-sY757l_Zs5S6NwI,22669
|
|
81
|
+
mayhem/infra/migrator.py,sha256=F5A-PPXHqEObETLqsFXpKxk2mkU-kOOLBLVFZlsK6yY,5884
|
|
82
|
+
mayhem/infra/report.py,sha256=AlWvAsLmIFd8PASC3UBfa9NMkYwCuLDGrlW73uKC1xw,7709
|
|
83
|
+
mayhem/infra/store.py,sha256=5zhb2s2KVAb2Ki6NIHZbBc5HYfqoErpML_g5rN1u9ao,7389
|
|
84
|
+
mayhem/toolkit/__init__.py,sha256=FWrlzKn-WTsGvnWGV4dygf0HW2CVQXxumNSYQ5WsgWg,83
|
|
85
|
+
mayhem/toolkit/fingerprint.py,sha256=4bK80htc7bOg5MNh7FscWyyDmcJqWpEEySVXNTGuJvk,2411
|
|
86
|
+
mayhem/toolkit/hashing.py,sha256=Of2_uekYbs5D14YgScBoUv5ObCEA9h0Dw_srB_k_COI,811
|
|
87
|
+
mayhem/toolkit/registry.py,sha256=5hcAldr058fTRpB_LGp5DOqc4s7XyOuOTwmIMeKcBbw,6830
|
|
88
|
+
mayhem/toolkit/tool_runner.py,sha256=ZN3pFsbEs_Hac9L97ngq6tZeJu52r0IEpEia3QwR5Us,4108
|
|
89
|
+
mayhem/toolkit/manifests/docker.yaml,sha256=ESmpaHX0ZEw59uCd8AQp8wTujippzttYrMPO5obnAeo,293
|
|
90
|
+
mayhem/toolkit/manifests/podman.yaml,sha256=dRiqQkahxso7cOKfIqRskec1c6R58rcCWhQqw-OHwcQ,281
|
|
91
|
+
mayhem/toolkit/manifests/stress-ng.yaml,sha256=kkWbIJerjV-KGMdQ6QEcoy8CGDYePKedfMAdc4wwuhY,261
|
|
92
|
+
mayhem/toolkit/manifests/tc-netem.yaml,sha256=MZte3N9F3NGQQKnCl2IEga6oa4o_NCBpe9vqz9Z1cQc,258
|
|
93
|
+
mayhem/toolkit/manifests/toxiproxy.yaml,sha256=FeKYlD2uSOSNzlR_XpLSftavA2wxUE9tqP6Q0e5sTqM,233
|
|
94
|
+
mayhem/topology/__init__.py,sha256=Z8CgpWmlNmI6RgJC_FfuB4Kg8dvUszliBB8kXtTO-T0,355
|
|
95
|
+
mayhem/topology/resolve.py,sha256=u_cuhamktbn-Iao5sVv1VeGxESaRbvDL57CVRtEbw0w,7283
|
|
96
|
+
mayhem/topology/service.py,sha256=upu-9J23z_lWueJkIWf_M6dwO0Opt6R5upBjuNe5EHw,6130
|
|
97
|
+
mayhem/topology/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
98
|
+
mayhem/topology/providers/adapter_registry.py,sha256=gUxoiVNXAehhyGERzUidf474i-XFRKEsDyvuhUXoBJ0,2146
|
|
99
|
+
mayhem/topology/providers/base.py,sha256=yh1sJHX8NkHZbBls59tntEXePEEMfTyQ5qJ_0_7Emko,931
|
|
100
|
+
mayhem/topology/providers/compose.py,sha256=yf-SnOW1jyYycsxu2w2M57Dd7Uq3HluBjz23-tQKsBs,7341
|
|
101
|
+
mayhem/topology/providers/docker_adapter.py,sha256=A829Uj8wKj4mVHwpyKiVjToPs2v02P7pwO4a3dDhjiw,9473
|
|
102
|
+
mayhem/topology/providers/docker_runtime.py,sha256=g15opOT_QIchKl1_4tp6tp92noXfq3OXJaDo9aaDvRs,17183
|
|
103
|
+
mayhem/topology/providers/podman_adapter.py,sha256=5yqaDaMH2ElJSgoFeIDF60ScAtgAW8ohLCk-m0ornIU,11525
|
|
104
|
+
mayhem_cli-0.5.1.dist-info/METADATA,sha256=35wD1r-CzSLYES5N_iXRznzXyTXTIo-Isdsh0C9G8nU,22966
|
|
105
|
+
mayhem_cli-0.5.1.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
106
|
+
mayhem_cli-0.5.1.dist-info/entry_points.txt,sha256=pCxl4SlE4VmN5Hl34n9Yyb5EFFGKGzWnSAnQb-KI9Bw,83
|
|
107
|
+
mayhem_cli-0.5.1.dist-info/RECORD,,
|