How to Extend ChaosBlade with Custom Matchers and Flags: A Complete Guide

You can extend ChaosBlade with custom matchers and flags by editing YAML specification files in $HOME/.chaosblade/spec without recompiling the binary, as the CLI dynamically builds its command tree from these specs at runtime.

ChaosBlade is an open-source chaos engineering platform that uses a specification-driven architecture to define experiments. Understanding how to extend ChaosBlade with custom matchers and flags allows you to tailor resource selection and experiment parameters to your specific infrastructure needs without modifying the core Go source code.

Understanding ChaosBlade's Specification-Driven Architecture

ChaosBlade constructs its entire command-line interface from YAML specification files that describe experiments, actions, flags, and matchers. When the CLI initializes, it loads these specifications and dynamically registers commands using Cobra.

How the CLI Builds Commands from YAML

The entry point for command registration occurs in cli/cmd/exp.go. The process follows three distinct phases:

  1. Specification Loading: The system loads YAML files from the directory returned by specutil.GetYamlHome() (default: $HOME/.chaosblade/spec):
models, err := specutil.ParseSpecsToModel(file, os.NewExecutor())
// cli/cmd/exp.go: 38-42
  1. Command Registration: For each experiment model, the system registers a top-level command:
command := ec.registerExpCommand(model, "")
// cli/cmd/exp.go: 48-55
  1. Flag Binding: The system binds both action flags and matcher flags to the command:
// bind matcher flags
ec.bindFlagsFunc(command.MatcherFlags, command.command, actionCommandSpec.Matchers())
// cli/cmd/exp.go: 400-402

The Role of Matchers and Flags

In ChaosBlade's architecture, matchers function as specialized flags used for resource selection (such as --process or --container), while flags define experiment parameters (such as --time or --duration). Both follow the same ExpFlagSpec schema defined in the chaosblade-spec-go library, but matchers are processed separately to facilitate resource targeting.

Adding Custom Matchers to ChaosBlade Experiments

Extending ChaosBlade with custom matchers requires creating or modifying YAML specification files. This approach requires no recompilation of the binary.

Creating or Editing YAML Specification Files

Create a new YAML file or edit an existing spec in $HOME/.chaosblade/spec/. The filename typically follows the pattern chaosblade-<target>-spec-<version>.yaml.

For example, to add a custom matcher for process selection:


# $HOME/.chaosblade/spec/chaosblade-os-spec-1.9.0.yaml

- name: process
  scope: host
  actions:
    - name: kill
      flags:
        - name: signal
          desc: signal to send (default: SIGKILL)
      matchers:
        - name: process
          desc: name of the process to kill
          required: true
        - name: mylabel
          desc: custom label matcher for process selection
          required: false

Defining Matcher Properties

Matchers support the same properties as standard flags:

  • name: The flag name used on the CLI (e.g., --mylabel)
  • desc: Description shown in help text
  • required: Boolean indicating if the matcher must be provided
  • default: Optional default value

Using Custom Matchers in Commands

After saving the YAML file, the CLI automatically discovers the new matcher. Execute the experiment using your custom matcher:

cb create process kill --mylabel myapp-tier --signal SIGTERM

The matcher value is passed to the executor via expModel.ActionFlags["mylabel"], as implemented in exec/os/executor.go at line 313 within the convertFlagsToResourceFlags function.

Implementing Custom Flags for Experiment Actions

Custom flags follow the same YAML-based approach as matchers but are declared under the flags section rather than matchers.

Declaring Action-Level Flags

Add flags to any action in your YAML specification:

- name: network
  scope: host
  actions:
    - name: delay
      flags:
        - name: time
          desc: delay time in ms
          required: true
        - name: duration
          desc: how long the delay lasts (seconds)
          required: false
        - name: jitter
          desc: network jitter in ms
          required: false

These flags become standard Cobra command-line flags accessible via --time, --duration, and --jitter.

Accessing Flag Values in Executors

When the experiment executes, flag values are available in the ExpModel structure:

// Inside your executor implementation
func (e *executor) Exec(expModel *spec.ExpModel) (*spec.Response, error) {
    delayTime := expModel.ActionFlags["time"]
    duration := expModel.ActionFlags["duration"]
    
    // Implementation logic using these values
}

Advanced: Creating Custom Executors for Complex Matchers

When custom matchers require specialized processing logic beyond standard resource selection, implement a custom spec.Executor.

Implementing the spec.Executor Interface

Create a new executor struct that implements the interface defined in the chaosblade-spec-go library:

package myexecutor

import (
    "github.com/chaosblade-io/chaosblade-spec-go/spec"
)

type customExecutor struct{}

// Exec implements spec.Executor
func (e *customExecutor) Exec(expModel *spec.ExpModel) (*spec.Response, error) {
    // Retrieve custom matcher values
    customMatcher := expModel.ActionFlags["mylabel"]
    
    // Implement custom resource selection logic
    // Return spec.Response with success or failure details
    return spec.Success(), nil
}

// SetChannel implements spec.Executor (required for some implementations)
func (e *customExecutor) SetChannel(channel spec.Channel) {}

Registering Your Executor

Register the executor in the appropriate register*ExpCommands function within cli/cmd/exp.go:

// In your command registration logic
executors[createExecutorKey("mytarget", "host", "myaction")] = &myexecutor.customExecutor{}

This registration pattern follows the existing implementation at line 69 of cli/cmd/exp.go where executors are mapped to specific target-scope-action combinations.

Key Source Files and Implementation Details

Understanding these specific source files helps when debugging or extending ChaosBlade:

File Purpose Key Lines
cli/cmd/exp.go Core command registration and flag binding 38-42 (spec loading), 48-55 (command registration), 400-402 (matcher binding)
cli/cmd/check_os.go Demonstrates matcher and flag merging logic mergeMatchesAndFlags function
exec/os/executor.go Consumes matcher values during execution 313 (convertFlagsToResourceFlags)
build/spec/spec.go Programmatic spec generation 168-172 (ActionMatchers field)
spec/util/parse.go YAML parsing into Go structs External library: chaosblade-spec-go
spec/exp_flag.go Flag and matcher schema definition External library: chaosblade-spec-go

Summary

  • ChaosBlade uses YAML specifications located in $HOME/.chaosblade/spec to dynamically build its CLI, eliminating the need for recompilation when adding matchers or flags.
  • Custom matchers are defined under the matchers: section in action specifications and function as specialized resource selectors passed to executors via expModel.ActionFlags.
  • Custom flags follow the same YAML schema as matchers but reside under flags: and define experiment parameters rather than resource selection criteria.
  • Implementation details center on cli/cmd/exp.go for command registration (lines 400-402 for matcher binding) and exec/os/executor.go for flag consumption at runtime.
  • Advanced extensions require implementing the spec.Executor interface and registering the executor in the command initialization map for custom processing logic.

Frequently Asked Questions

Do I need to recompile ChaosBlade to add custom matchers?

No, you do not need to recompile the binary. ChaosBlade loads experiment specifications from YAML files in $HOME/.chaosblade/spec at runtime. Simply create or edit a spec file, add your matcher under the matchers: section of the desired action, and the CLI will automatically expose it as a new flag.

What is the difference between a matcher and a flag in ChaosBlade?

While both use the same underlying ExpFlagSpec schema, matchers are specialized flags used for resource selection (such as --process or --container) and are processed separately to identify target resources. Flags define experiment parameters (such as --duration or --time) that control how the action behaves. Matchers are defined under matchers: in the YAML, while flags are defined under flags:.

How do I access custom matcher values in my experiment executor?

Custom matcher values are accessible via the ActionFlags map in the ExpModel struct passed to your executor's Exec method. For example, if you defined a matcher named mylabel, you retrieve it in Go code using expModel.ActionFlags["mylabel"]. The executor at exec/os/executor.go demonstrates this pattern in the convertFlagsToResourceFlags function around line 313.

Can I add custom matchers to existing ChaosBlade experiments like network or CPU?

Yes, you can extend existing experiments by modifying their specification files. Locate the YAML spec for the target (such as chaosblade-os-spec.yaml for OS-level experiments), find the action you want to extend (like delay for network or fullload for CPU), and add your custom matcher under the matchers: section. The ChaosBlade CLI will automatically merge your custom matcher with the existing command structure when it parses the specification on startup.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →