Skip to content

feat(tasks): add run_network_disruption task and rewrite blackout playbook#219

Open
parithosh wants to merge 2 commits into
masterfrom
pk/run-network-disruption-task
Open

feat(tasks): add run_network_disruption task and rewrite blackout playbook#219
parithosh wants to merge 2 commits into
masterfrom
pk/run-network-disruption-task

Conversation

@parithosh

Copy link
Copy Markdown
Member

What

Adds a native run_network_disruption task that drives a disruptoor instance declaratively from playbooks — the task type planned as step 3 of disruptoor's design doc — and rewrites playbooks/dev/single-node-blackout-recovery.yaml (#218) on top of it.

- name: run_network_disruption
  title: "Black out the target beacon node"
  config:
    disruptoorUrl: "http://disruptoor:7700"
    isolations:
      - name: blackout-target-cl
        target: { node-index: 1, client-type: beacon }
        scope: [cl_p2p, el_p2p, include_control]

- name: run_network_disruption
  config: { disruptoorUrl: "http://disruptoor:7700", action: clear }

Task design

  • Actions: set (replace the whole disruptoor state), update (read-merge-write: replaces entries by name, appends new ones, drops names in removeNames; guarded by If-Match and retried on concurrent writes — lets playbooks compose disruptions, e.g. keep a baseline jitter while toggling a blackout), clear (heal everything).
  • Passthrough entries: partitions / isolations / shaping go to disruptoor verbatim (wire format of PUT /v1/state), so new disruptoor fields never require assertoor changes. Assertoor only enforces unique non-empty entry names (needed for merge); disruptoor's precise validation errors are surfaced in the task failure.
  • Built-in API wait: awaitApiTimeout / pollInterval poll healthz before acting, replacing sleep + curl shell tasks.
  • Outputs: appliedState (read back via GET /v1/state, which reflects applied reality) plus partitionCount / isolationCount / shapingCount.

Playbook rewrite

Supersedes the run_shell/curl/jq version from #218: the two-partition workaround and the jq counterparty enumeration (with its totalCount output dependency) collapse into a single disruptoor isolation, whose counterparty group disruptoor computes as the complement of the target — 193 → 135 lines, zero shell, works unchanged on any topology. A leading action: clear task doubles as a fail-fast health check and stale-state cleanup. Runtime semantics are identical to what was validated on glamsterdam-devnet-7 in #218: the target CL loses all traffic including to its own EL/VC, while the target's EL keeps its network peers.

Dependencies

Testing

  • go build ./... and the full go test ./... suite green; golangci-lint run --new-from-rev=origin/master reports 0 issues.
  • New unit tests (21 cases): config validation table, ETag 412 retry, update merge/remove semantics, server-error surfacing, healthz probe, and a test exercising the exact playbook pattern of building isolations via a configVars jq expression through the vars system.
  • Playbook passes assertoor validate; playbook index regenerated via make generate-playbook-index.

🤖 Generated with Claude Code

parithosh and others added 2 commits July 14, 2026 08:22
New task driving disruptoor declaratively from playbooks:

- actions: set (replace whole state), update (ETag-guarded merge by
  entry name with removeNames support, retried on concurrent writes),
  clear (heal everything)
- partition/isolation/shaping entries are passed through verbatim
  (wire format of PUT /v1/state), so new disruptoor fields need no
  assertoor changes; server-side validation errors are surfaced in
  the task failure
- built-in healthz wait (awaitApiTimeout/pollInterval) before acting
- outputs read back via GET /v1/state (reflects applied reality):
  appliedState + partition/isolation/shaping counts

Rewrites playbooks/dev/single-node-blackout-recovery.yaml on top of
it: the two-partition workaround plus jq counterparty enumeration
collapse into a single disruptoor isolation, and all run_shell/curl
plumbing disappears (193 -> 135 lines, zero shell).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A target matching multiple containers is isolated as a group (traffic
among its members keeps flowing); per-container blackouts need one
isolation each. Also add whole-participant and variable-driven-target
examples to the task README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant