Showing preview only (1,183K chars total). Download the full file or copy to clipboard to get everything.
Repository: chaosblade-io/chaosblade-operator
Branch: master
Commit: 7609cdab1287
Files: 179
Total size: 1.1 MB
Directory structure:
gitextract_bd7o2tq4/
├── .gitattributes
├── .github/
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── issue_template.md
│ └── workflows/
│ ├── ci.yml
│ └── release.yml
├── .gitignore
├── BUILD.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── README_CN.md
├── build/
│ ├── bin/
│ │ ├── entrypoint
│ │ └── user_setup
│ ├── image/
│ │ ├── amd/
│ │ │ └── Dockerfile
│ │ └── arm/
│ │ └── Dockerfile
│ ├── musl/
│ │ └── Dockerfile
│ └── spec.go
├── channel/
│ ├── client.go
│ └── client_test.go
├── cmd/
│ ├── hookfs/
│ │ └── main.go
│ └── manager/
│ └── main.go
├── deploy/
│ ├── crds/
│ │ └── chaosblade.io_chaosblades_crd.yaml
│ ├── helm/
│ │ ├── chaosblade-operator/
│ │ │ ├── .helmignore
│ │ │ ├── Chart.yaml
│ │ │ ├── crds/
│ │ │ │ └── crd.yaml
│ │ │ ├── templates/
│ │ │ │ ├── NOTES.txt
│ │ │ │ ├── _helpers.tpl
│ │ │ │ ├── daemonset.yaml
│ │ │ │ ├── deployment.yaml
│ │ │ │ ├── rbac.yaml
│ │ │ │ ├── secret.yaml
│ │ │ │ └── service.yaml
│ │ │ └── values.yaml
│ │ └── chaosblade-operator-arm64/
│ │ ├── .helmignore
│ │ ├── Chart.yaml
│ │ ├── crds/
│ │ │ └── crd.yaml
│ │ ├── templates/
│ │ │ ├── NOTES.txt
│ │ │ ├── _helpers.tpl
│ │ │ ├── daemonset.yaml
│ │ │ ├── deployment.yaml
│ │ │ ├── rbac.yaml
│ │ │ ├── secret.yaml
│ │ │ └── service.yaml
│ │ └── values.yaml
│ ├── olm/
│ │ ├── Makefile
│ │ └── deploy/
│ │ ├── crd.yaml
│ │ ├── crds/
│ │ │ └── chaosblade_v1alpha1_chaosblade_crd.yaml
│ │ ├── olm-catalog/
│ │ │ └── chaosblade-operator/
│ │ │ ├── 0.5.1/
│ │ │ │ ├── chaosblade-operator.v0.5.1.clusterserviceversion.yaml
│ │ │ │ └── chaosblade_v1alpha1_chaosblade_crd.yaml
│ │ │ ├── 0.6.0/
│ │ │ │ ├── chaosblade-operator.v0.6.0.clusterserviceversion.yaml
│ │ │ │ └── chaosblade_v1alpha1_chaosblade_crd.yaml
│ │ │ └── chaosblade-operator.package.yaml
│ │ ├── operator.yaml
│ │ ├── role.yaml
│ │ ├── role_binding.yaml
│ │ └── service_account.yaml
│ └── oss/
│ ├── crd.yaml
│ ├── operator.yaml
│ ├── rbac.yaml
│ ├── service.yaml
│ └── webhook-cert-job.yaml
├── examples/
│ ├── create_services_in_batch.yaml
│ ├── delay_pod_network_by_names.yaml
│ ├── delete_pod_by_labels.yaml
│ ├── delete_pod_by_names.yaml
│ ├── fail_pod_by_labels.yaml
│ ├── increase_container_cpu_load_by_id.yaml
│ ├── kill_container_process_by_id.yaml
│ ├── modify_service_traffic_policy.yaml
│ ├── node-cpu-load.yml
│ ├── node-disk-load-burn-read.yml
│ ├── node-disk-load-burn-write.yml
│ ├── node-disk-load-fill.yml
│ ├── node-mem-load.yml
│ ├── node-network-delay-by-names.yml
│ ├── node-network-loss-by-names.yml
│ ├── pod-bad-resource-size-cpu-mem.yaml
│ ├── pod-bad-resource-size-cpu.yaml
│ ├── pod-bad-resource-size-mem.yaml
│ ├── pod-configmap-delete.yaml
│ ├── pod-containercreating-by-pvc-error.yaml
│ ├── pod-containercreating-disk.yaml
│ ├── pod-cpu-load-by-names.yml
│ ├── pod-delete_by_names.yaml
│ ├── pod-failedmount-configmap.yaml
│ ├── pod-failedmount-pvc.yaml
│ ├── pod-failedmount-secret.yaml
│ ├── pod-imagepullsecretserror-by-auth-corruption.yaml
│ ├── pod-scheduling-failure.yaml
│ ├── pod-taint-node.yaml
│ ├── pod-terminating-by-finalizer.yaml
│ ├── remove_container_by_id.yaml
│ ├── tamper_container_dns_by_id.yaml
│ └── test-configmap-delete.yaml
├── exec/
│ ├── container/
│ │ ├── application.go
│ │ ├── container.go
│ │ └── controller.go
│ ├── controller.go
│ ├── model/
│ │ ├── category.go
│ │ ├── context.go
│ │ ├── controller.go
│ │ ├── controller_test.go
│ │ ├── copy.go
│ │ ├── deploy.go
│ │ ├── download.go
│ │ ├── executor.go
│ │ ├── executor_copy.go
│ │ ├── executor_nsexec.go
│ │ ├── filter.go
│ │ ├── filter_pod.go
│ │ ├── filter_pod_test.go
│ │ ├── model.go
│ │ ├── osexp.go
│ │ └── parallelizer.go
│ ├── node/
│ │ ├── cniexp.go
│ │ ├── controller.go
│ │ ├── exec_helper.go
│ │ ├── filter.go
│ │ └── node.go
│ ├── pod/
│ │ ├── badresourcesize.go
│ │ ├── configmapdeleteexp.go
│ │ ├── configmapdeleteexp_test.go
│ │ ├── containercreating.go
│ │ ├── containercreatingdisk.go
│ │ ├── containercreatingdisk_test.go
│ │ ├── controller.go
│ │ ├── delete.go
│ │ ├── failedmount.go
│ │ ├── failexp.go
│ │ ├── fsexp.go
│ │ ├── imageconfigexp.go
│ │ ├── imageconfigexp_test.go
│ │ ├── imagepullsecretserror.go
│ │ ├── imagepullsecretserror_test.go
│ │ ├── pod.go
│ │ ├── schedulingfailure.go
│ │ ├── taintnode.go
│ │ ├── taintnode_test.go
│ │ └── terminating.go
│ └── service/
│ ├── controller.go
│ ├── create.go
│ ├── modify.go
│ └── service.go
├── go.mod
├── go.sum
├── hack/
│ ├── init.sh
│ ├── update-gofmt.sh
│ ├── update-imports.sh
│ ├── verify-gofmt.sh
│ └── verify-imports.sh
├── licenserc.toml
├── pkg/
│ ├── apis/
│ │ ├── addtoscheme_chaosblade_v1alpha1.go
│ │ ├── apis.go
│ │ └── chaosblade/
│ │ ├── group.go
│ │ └── v1alpha1/
│ │ ├── doc.go
│ │ ├── register.go
│ │ ├── types.go
│ │ └── zz_generated.deepcopy.go
│ ├── controller/
│ │ ├── add_chaosblade.go
│ │ ├── chaosblade/
│ │ │ ├── controller.go
│ │ │ ├── daemonset.go
│ │ │ └── predicate.go
│ │ └── controller.go
│ ├── hookfs/
│ │ ├── client.go
│ │ ├── hook.go
│ │ ├── server.go
│ │ └── types.go
│ ├── runtime/
│ │ ├── chaosblade/
│ │ │ └── chaosblade.go
│ │ ├── product/
│ │ │ ├── aliyun/
│ │ │ │ └── aliyun.go
│ │ │ └── community/
│ │ │ └── community.go
│ │ └── runtime.go
│ └── webhook/
│ ├── pod/
│ │ ├── mutator.go
│ │ └── mutator_test.go
│ └── webhook.go
├── scripts/
│ ├── show-version.sh
│ └── version.sh
└── version/
└── version.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!-- Thanks for submitting a pull request! Here are some tips for you:
1. Please make sure you have read and understood the contributing guidelines: https://github.com/chaosblade-io/chaosblade/blob/master/CONTRIBUTING.md
2. Please make sure the PR has a corresponding issue.
-->
### Describe what this PR does / why we need it
### Does this pull request fix one issue?
<!--If that, add "Fixes #xxxx" below in the next line. For example, Fixes #15. Otherwise, add "NONE" -->
### Describe how you did it
### Describe how to verify it
### Special notes for reviews
================================================
FILE: .github/issue_template.md
================================================
<!--
Please try to use English to describe your issue, or at least provide a snippet of English translation.
-->
## Issue Description
Type: *bug report* or *feature request*
### Describe what happened (or what feature you want)
### Describe what you expected to happen
### How to reproduce it (as minimally and precisely as possible)
1.
2.
3.
### Tell us your environment
### Anything else we need to know?
================================================
FILE: .github/workflows/ci.yml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: CI
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
workflow_dispatch:
jobs:
test:
name: ${{ matrix.os }} - Test - Go ${{ matrix.go_version }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
go_version:
- "1.25"
os:
- ubuntu-latest
steps:
- name: Set Up Go ${{ matrix.go_version }}
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go_version }}
id: go
- name: Checkout
id: checkout
uses: actions/checkout@v4
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Run code style and import order verification
run: make verify
- name: Check License Header
uses: korandoru/hawkeye@v6
- name: Tests
id: test
run: |
make test
build-matrix:
name: Build on ${{ matrix.os }} (${{ matrix.goos }}/${{ matrix.goarch }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
goos: linux
goarch: amd64
platform: linux_amd64
runner_arch: x64
- os: ubuntu-latest
goos: linux
goarch: arm64
platform: linux_arm64
runner_arch: arm64
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整的 Git 历史用于版本信息
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y musl-tools build-essential
# Install ARM64 cross-compilation tools if needed
if [ "${{ matrix.goarch }}" = "arm64" ] && [ "$(uname -m)" != "aarch64" ]; then
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
fi
- name: Build ${{ matrix.platform }}
id: build
run: |
make ${{ matrix.platform }}
- name: Verify Build Output
id: verify
run: |
echo "Verifying build output for ${{ matrix.platform }}..."
echo "Build architecture: $(uname -m)"
# 检查 chaosblade-operator 二进制文件
if [ -f "build/_output/bin/chaosblade-operator" ]; then
echo "✅ chaosblade-operator binary found"
file build/_output/bin/chaosblade-operator
ls -lh build/_output/bin/chaosblade-operator
else
echo "❌ chaosblade-operator binary not found"
exit 1
fi
# 检查 chaos_fuse 二进制文件
BLADE_VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo '0.0.0')
BUILD_DIR="target/chaosblade-${BLADE_VERSION}"
if [ -f "${BUILD_DIR}/bin/chaos_fuse" ]; then
echo "✅ chaos_fuse binary found in ${BUILD_DIR}/bin/"
file "${BUILD_DIR}/bin/chaos_fuse"
ls -lh "${BUILD_DIR}/bin/chaos_fuse"
else
echo "❌ chaos_fuse binary not found in ${BUILD_DIR}/bin/"
ls -la "${BUILD_DIR}/bin/" || echo "Build directory not found"
exit 1
fi
# 检查 YAML 文件
if [ -f "${BUILD_DIR}/yaml/chaosblade-k8s-spec-${BLADE_VERSION}.yaml" ]; then
echo "✅ YAML specification file found"
ls -lh "${BUILD_DIR}/yaml/"
else
echo "❌ YAML specification file not found"
ls -la "${BUILD_DIR}/yaml/" || echo "YAML directory not found"
exit 1
fi
echo "=== Build Summary for ${{ matrix.platform }} ==="
echo "All required files built successfully!"
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.platform }}-binaries
path: |
build/_output/bin/chaosblade-operator
target/chaosblade-*/bin/
target/chaosblade-*/yaml/
retention-days: 7
================================================
FILE: .github/workflows/release.yml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
version:
description: 'Version number (e.g: 1.8.0)'
required: true
default: '1.8.0'
draft:
description: 'Create as draft release'
required: false
type: boolean
default: false
env:
REGISTRY: ghcr.io
IMAGE_NAME: chaosblade-io/chaosblade-operator
GO_VERSION: '1.25'
permissions:
contents: write
packages: write
jobs:
build-and-push-images:
name: Build and Push Images
runs-on: ${{ matrix.runs-on }}
strategy:
matrix:
include:
- os: linux
arch: amd64
runs-on: ubuntu-latest
dockerfile: build/image/amd/Dockerfile
image_suffix: ""
image_tag: "ghcr.io/chaosblade-io/chaosblade-operator"
- os: linux
arch: arm64
runs-on: ubuntu-24.04-arm
dockerfile: build/image/arm/Dockerfile
image_suffix: "-arm64"
image_tag: "ghcr.io/chaosblade-io/chaosblade-operator-arm64"
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Extract version from tag
id: version
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="${{ github.event.inputs.version }}"
else
VERSION="${GITHUB_REF#refs/tags/}"
VERSION="${VERSION#v}"
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "tag=v${VERSION}" >> $GITHUB_OUTPUT
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}
cache: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.GHCR_USER }}
password: ${{ secrets.GHCR_PASSWORD }}
- name: Build and Push ${{ matrix.arch }} image
env:
BLADE_VERSION: ${{ steps.version.outputs.version }}
run: |
echo "Building ${{ matrix.arch }} image..."
echo "BLADE_VERSION: $BLADE_VERSION"
echo "Image tag: ${{ matrix.image_tag }}:${{ steps.version.outputs.version }}"
make build_linux_${{ matrix.arch }}_image
echo "Built images:"
podman images | grep chaosblade-operator
echo "Pushing ${{ matrix.arch }} image..."
podman push ${{ matrix.image_tag }}:${{ steps.version.outputs.version }}
# Only push latest tag if version doesn't contain 'dev'
if [[ "${{ steps.version.outputs.version }}" != *"dev"* ]]; then
echo "Pushing latest tag..."
podman tag ${{ matrix.image_tag }}:${{ steps.version.outputs.version }} ${{ matrix.image_tag }}:latest
podman push ${{ matrix.image_tag }}:latest
else
echo "Skipping latest tag push for dev version: ${{ steps.version.outputs.version }}"
fi
package-and-upload-helm:
name: Package and Upload Helm Charts
runs-on: ubuntu-latest
needs: build-and-push-images
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get version from previous job
id: version
run: |
echo "version=${{ needs.build-and-push-images.outputs.version }}" >> $GITHUB_OUTPUT
- name: Install Helm
uses: azure/setup-helm@v3
with:
version: v3.9.3
- name: Package Helm Charts
env:
BLADE_VERSION: ${{ steps.version.outputs.version }}
run: |
echo "Packaging Helm charts for version ${BLADE_VERSION}..."
# Use Makefile tasks to build and package Helm charts
make build_linux_amd64_helm
make build_linux_arm64_helm
echo "Generated Helm packages:"
ls -la target/*.tgz
- name: Setup OSSUTIL environment
uses: yizhoumo/setup-ossutil@v1.1.3
env:
BINARY_TAG: ${{ steps.version.outputs.version }}
with:
endpoint: ${{ secrets.OSS_ENDPOINT }}
access-key-id: ${{ secrets.OSS_ACCESS_KEY_ID }}
access-key-secret: ${{ secrets.OSS_ACCESS_KEY_SECRET }}
ossutil-version: '1.7.14'
- name: Upload Helm packages to OSS
env:
BINARY_TAG: ${{ steps.version.outputs.version }}
run: |
echo "Uploading Helm packages to OSS..."
ossutil cp -f target/chaosblade-operator-amd64-${BINARY_TAG}.tgz oss://chaosblade/agent/github/${BINARY_TAG}/chaosblade-operator-amd64-${BINARY_TAG}.tgz
ossutil cp -f target/chaosblade-operator-arm64-${BINARY_TAG}.tgz oss://chaosblade/agent/github/${BINARY_TAG}/chaosblade-operator-arm64-${BINARY_TAG}.tgz
echo "Helm packages uploaded successfully"
- name: Upload Helm packages as artifacts
uses: actions/upload-artifact@v4
with:
name: helm-packages
path: |
target/chaosblade-operator-amd64-${{ steps.version.outputs.version }}.tgz
target/chaosblade-operator-arm64-${{ steps.version.outputs.version }}.tgz
retention-days: 30
create-release:
name: Create GitHub Release
needs: [build-and-push-images, package-and-upload-helm]
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Get version from previous job
id: version
run: |
echo "version=${{ needs.build-and-push-images.outputs.version }}" >> $GITHUB_OUTPUT
- name: Download Helm packages
uses: actions/download-artifact@v4
with:
name: helm-packages
- name: List downloaded files for debugging
run: |
echo "Current directory contents:"
ls -la
echo "Looking for .tgz files:"
find . -name "*.tgz" -type f
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ steps.version.outputs.version }}
name: v${{ steps.version.outputs.version }}
generate_release_notes: true
body: |
### Helm Package Downloads
- [chaosblade-operator-amd64 (AMD64)](https://github.com/${{ github.repository }}/releases/download/v${{ steps.version.outputs.version }}/chaosblade-operator-amd64-${{ steps.version.outputs.version }}.tgz)
- [chaosblade-operator-arm64 (ARM64)](https://github.com/${{ github.repository }}/releases/download/v${{ steps.version.outputs.version }}/chaosblade-operator-arm64-${{ steps.version.outputs.version }}.tgz)
### Docker Images
```bash
# AMD64
docker pull ghcr.io/chaosblade-io/chaosblade-operator:v${{ steps.version.outputs.version }}
# ARM64
docker pull ghcr.io/chaosblade-io/chaosblade-operator-arm64:v${{ steps.version.outputs.version }}
```
### Helm Installation
```bash
# AMD64
helm install chaosblade-operator ./chaosblade-operator-amd64-${{ steps.version.outputs.version }}.tgz
# ARM64
helm install chaosblade-operator ./chaosblade-operator-arm64-${{ steps.version.outputs.version }}.tgz
```
### OSS Download Links
- [chaosblade-operator-amd64-${{ steps.version.outputs.version }}.tgz](https://chaosblade.oss-cn-hangzhou.aliyuncs.com/agent/github/${{ steps.version.outputs.version }}/chaosblade-operator-amd64-${{ steps.version.outputs.version }}.tgz)
- [chaosblade-operator-arm64-${{ steps.version.outputs.version }}.tgz](https://chaosblade.oss-cn-hangzhou.aliyuncs.com/agent/github/${{ steps.version.outputs.version }}/chaosblade-operator-arm64-${{ steps.version.outputs.version }}.tgz)
files: |
chaosblade-operator-amd64-${{ steps.version.outputs.version }}.tgz
chaosblade-operator-arm64-${{ steps.version.outputs.version }}.tgz
draft: ${{ github.event.inputs.draft == 'true' }}
prerelease: false
================================================
FILE: .gitignore
================================================
# Temporary Build Files
build/_output
build/_test
target
# Created by https://www.gitignore.io/api/go,vim,emacs,visualstudiocode
### Emacs ###
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*
# Org-mode
.org-id-locations
*_archive
# flymake-mode
*_flymake.*
# eshell files
/eshell/history
/eshell/lastdir
# elpa packages
/elpa/
# reftex files
*.rel
# AUCTeX auto folder
/auto/
# cask packages
.cask/
dist/
# Flycheck
flycheck_*.el
# server auth directory
/server/
# projectiles files
.projectile
projectile-bookmarks.eld
deploy/helm/chaosblade-operator-*.tgz
# directory configuration
.dir-locals.el
# saveplace
places
# url cache
url/cache/
# cedet
ede-projects.el
# smex
smex-items
# company-statistics
company-statistics-cache.el
# anaconda-mode
anaconda-mode/
### Go ###
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
.DS_Store
# Test binary, build with 'go test -c'
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
vendor
coverage.txt
### Vim ###
# swap
.sw[a-p]
.*.sw[a-p]
# session
Session.vim
# temporary
.netrwhist
# auto-generated tag files
tags
### VisualStudioCode ###
.vscode/*
.history
# End of https://www.gitignore.io/api/go,vim,emacs,visualstudiocode
### Goland ###
.idea
### vendor ###
vendor
### project ###
build/cache
================================================
FILE: BUILD.md
================================================
# ChaosBlade Operator Build Guide
This document describes how to build the ChaosBlade Operator project. The project supports multi-platform builds, including Linux AMD64 and ARM64 architectures.
## Table of Contents
- [Prerequisites](#prerequisites)
- [Environment Variables](#environment-variables)
- [Build Targets](#build-targets)
- [Container Image Building](#container-image-building)
- [Testing](#testing)
- [Cleanup](#cleanup)
- [Troubleshooting](#troubleshooting)
## Prerequisites
### Basic Requirements
- **Go 1.21+**: For compiling Go code
- **Git**: For retrieving version information
- **Make**: For executing build scripts
### Container Runtime (Optional)
The project automatically detects available container runtimes:
- **Docker**: Recommended
- **Podman**: As an alternative to Docker
### Cross-compilation Toolchain (Optional)
For Linux builds of the `chaos_fuse` component, one of the following tools is required:
#### Linux Systems
```bash
# Ubuntu/Debian - Basic build tools
sudo apt-get install musl-tools build-essential
# For ARM64 cross-compilation (when building on x86_64 for ARM64)
sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
# For native ARM64 compilation (when building on ARM64 for ARM64)
# The standard gcc from build-essential is sufficient
```
#### macOS Systems
```bash
# Install musl cross-compiler using Homebrew
brew install FiloSottile/musl-cross/musl-cross
```
### Platform Compatibility
- **Build Platforms**: macOS, Linux
- **Target Platforms**: Linux AMD64, Linux ARM64
- **Container Platforms**: Multi-architecture container builds supported
## Environment Variables
### Version-related
| Variable | Description | Default | Example |
|----------|-------------|---------|----------|
| `BLADE_VERSION` | Version number | Git tag (e.g., `1.7.4`) | `1.8.0` |
| `BLADE_VENDOR` | Vendor identifier | `community` | `enterprise` |
### Build-related
| Variable | Description | Default | Example |
|----------|-------------|---------|----------|
| `CONTAINER_RUNTIME` | Container runtime | Auto-detected | `docker`, `podman` |
| `JVM_SPEC_PATH` | JVM specification file path | None | `/path/to/jvm/spec` |
### Example Configuration
```bash
export BLADE_VERSION=1.8.0
export BLADE_VENDOR=community
export CONTAINER_RUNTIME=docker
```
## Build Targets
### View Help Information
```bash
make help
```
Displays all available build targets and environment variable descriptions.
### View Version Information
```bash
make show-version
```
Displays current build version information, including:
- Version number
- Vendor
- Git commit hash
- Git branch
- Build time
- Go version
- Target platform
### Complete Platform Builds
#### Linux AMD64 Platform
```bash
make linux_amd64
```
Builds:
- `chaosblade-operator` (Linux AMD64)
- `chaos_fuse` (Linux AMD64)
- YAML specification files
#### Linux ARM64 Platform
```bash
make linux_arm64
```
Builds:
- `chaosblade-operator` (Linux ARM64)
- `chaos_fuse` (Linux ARM64)
- YAML specification files
### Individual Component Builds
#### Build Operator
```bash
make operator GOOS=linux GOARCH=amd64
```
#### Build chaos_fuse
```bash
make chaos_fuse GOOS=linux GOARCH=amd64
```
#### Generate YAML Specifications
```bash
make yaml
# Or generate YAML only
make only_yaml
```
#### Build Local Binary
```bash
make build_binary
```
## Container Image Building
### Linux AMD64 Image
```bash
make build_linux_amd64_image
```
Builds and tags as: `ghcr.io/chaosblade-io/chaosblade-operator:${BLADE_VERSION}`
### Linux ARM64 Image
```bash
make build_linux_arm64_image
```
Builds and tags as: `ghcr.io/chaosblade-io/chaosblade-operator-arm64:${BLADE_VERSION}`
### Push Images
```bash
make push_image
```
Pushes the built images to GitHub Container Registry.
## Testing
Run the project test suite:
```bash
make test
```
This command will:
- Run all test cases
- Enable race detection
- Generate code coverage report (`coverage.txt`)
## Cleanup
Clean all build artifacts:
```bash
make clean
```
Cleans:
- Go build cache
- `target/` directory
- Build image directories
## Build Output
### Directory Structure
```
target/chaosblade-${BLADE_VERSION}/
├── bin/
│ └── chaos_fuse # File system hook tool
└── yaml/
└── chaosblade-k8s-spec-${BLADE_VERSION}.yaml # Kubernetes specification file
```
### Temporary Build Files
```
build/_output/bin/
├── chaosblade-operator # Temporarily built operator file
└── spec # Specification generator tool
```
### File Description
* `chaos_fuse` and `chaosblade-k8s-spec-${BLADE_VERSION}.yaml` need to be packaged into chaosblade for use (can be compiled and packaged directly in the chaosblade project);
* `chaosblade-operator` needs to be packaged into the chaosblade-operator image for use (can be compiled directly using build_linux_xxx_image tasks);
## Troubleshooting
### chaos_fuse Build Failure
**Issue**: Missing cross-compilation toolchain
**Solutions**:
1. **Preferred approach**: Install appropriate cross-compiler
```bash
# macOS
brew install FiloSottile/musl-cross/musl-cross
# Linux
sudo apt-get install musl-tools
```
2. **Alternative approach**: Use container build
```bash
# Ensure Docker/Podman is running
docker info # or podman info
```
3. **Manually specify container runtime**:
```bash
CONTAINER_RUNTIME=podman make chaos_fuse GOOS=linux GOARCH=amd64
```
### Container Build Failure
**Issue**: Container runtime unavailable
**Solutions**:
1. Check Docker/Podman status
```bash
docker info
# or
podman info
```
2. Start Docker service
```bash
# macOS/Linux
sudo systemctl start docker
# or use Docker Desktop
```
### Version Information Retrieval Failure
**Issue**: Git repository information unavailable
**Solutions**:
1. Ensure running build within Git repository
2. Manually specify version:
```bash
BLADE_VERSION=1.8.0 make linux_amd64
```
### Permission Issues
**Issue**: File permission errors
**Solutions**:
1. Check directory permissions
2. Run build with appropriate user permissions
3. For container builds, ensure SELinux compatibility (`:Z` flag)
## Advanced Usage
### Custom Build Flags
```bash
# Add custom ldflags
GO_FLAGS="-ldflags '-X main.customFlag=value'" make operator
```
### Parallel Builds
```bash
# Use parallel builds for acceleration
make -j4 linux_amd64
```
### Debug Builds
```bash
# Enable verbose output
make V=1 linux_amd64
```
## Contributing Guidelines
When building new features or fixes:
1. Ensure all build targets work properly
2. Run complete test suite: `make test`
3. Verify cross-platform builds: `make linux_amd64 linux_arm64`
4. Check code coverage reports
## Related Documentation
- [Contributing Guide](CONTRIBUTING.md)
- [Changelog](CHANGELOG.md)
================================================
FILE: CHANGELOG.md
================================================
# ChaosBlade Operator 变更日志
本文档记录了 ChaosBlade Operator 的所有重要变更。
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/),
并且本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
## [未发布]
### 新增
- 支持 Git Tag 自动化构建流程
- 增强版本信息展示,包含构建时间、Git提交等
- 新增版本命令支持 (`--version` 标志)
### 变更
- 优化 Makefile 构建流程
- 改进版本信息注入机制
### 修复
- 修复版本信息显示问题
## [1.7.4] - 2024-01-01
### 新增
- 初始版本发布
- 支持基本的混沌工程功能
- 支持 Kubernetes 环境
### 变更
- 基础架构搭建
- 核心功能实现
---
## 变更类型说明
- **新增**: 新功能
- **变更**: 现有功能的变更
- **弃用**: 即将移除的功能
- **移除**: 已移除的功能
- **修复**: Bug修复
- **安全**: 安全相关修复
## 如何贡献
1. 在 `## [未发布]` 部分添加你的变更
2. 使用上述变更类型标签
3. 提供清晰的变更描述
4. 如果是重大变更,请提供迁移指南
## 版本发布流程
1. 创建 Git 标签: `git tag v1.8.0`
2. 推送标签: `git push origin v1.8.0`
3. GitHub Actions 自动触发构建
4. 自动创建 Release 和上传构建产物
5. 更新 CHANGELOG.md 中的版本信息
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to chaosblade
Welcome to ChaosBlade world, here is a list of contributing guide for you. If you find something incorrect or missing
content in the page, please submit an issue or PR to fix it.
## What can you do
Every action to make the project better is encouraged. On GitHub, every improvement for the project could be via a PR
(short for pull request).
* If you find a typo, try to fix it!
* If you find a bug, try to fix it!
* If you find some redundant codes, try to remove them!
* If you find some test cases missing, try to add them!
* If you could enhance a feature, please **DO NOT** hesitate!
* If you find code implicit, try to add comments to make it clear!
* If you find code ugly, try to refactor that!
* If you can help to improve documents, it could not be better!
* If you find document incorrect, just do it and fix that!
* ...
Actually, it is impossible to list them completely. Just remember one principle:
**WE ARE LOOKING FORWARD TO ANY PR FROM YOU.**
## Contributing
### Preparation
Before you contribute, you need to register a Github ID. Prepare the following environment:
* go
* git
### Workflow
We use the `master` branch as the development branch, which indicates that this is an unstable branch.
Here is the workflow for contributors:
1. Fork to your own
2. Clone fork to the local repository
3. Create a new branch and work on it
4. Keep your branch in sync
5. Commit your changes (make sure your commit message concise)
6. Push your commits to your forked repository
7. Create a pull request
Please follow [the pull request template](./.github/PULL_REQUEST_TEMPLATE.md).
Please make sure the PR has a corresponding issue.
After creating a PR, one or more reviewers will be assigned to the pull request.
The reviewers will review the code.
Before merging a PR, squash any fix review feedback, typo, merged, and rebased sorts of commits.
The final commit message should be clear and concise.
### Compile
Go to the project root directory which you cloned and execute compile:
```bash
make
```
If you compile the Linux package on the Mac operating system, you can do:
```bash
make build_linux
```
If you compile the chaosblade image, you can do:
```bash
make build_image
```
clean compilation:
```bash
make clean
```
### Code Style
See details of [CODE STYLE](./docs/code_styles.md)
### Commit Rules
#### Commit Message
Commit message could help reviewers better understand what is the purpose of submitted PR. It could help accelerate the code review procedure as well. We encourage contributors to use **EXPLICIT** commit message rather than an ambiguous message. In general, we advocate the following commit message type:
* feat: A new feature
* fix: A bug fix
* docs: Documentation only changes
* style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
* refactor: A code change that neither fixes a bug or adds a feature
* perf: A code change that improves performance
* test: Adding missing or correcting existing tests
* chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
On the other side, we discourage contributors from committing message like the following ways:
* ~~fix bug~~
* ~~update~~
* ~~add doc~~
If you get lost, please see [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) for a start.
#### Commit Content
Commit content represents all content changes included in one commit. We had better include things in one single commit which could support the reviewer's complete review without any other commits' help. In other word, contents in one single commit can pass the CI to avoid code mess. In brief, there are two minor rules for us to keep in mind:
* avoid very large change in a commit;
* complete and reviewable for each commit.
No matter commit message or commit content, we do take more emphasis on code review.
### Pull Request
We use [GitHub Issues](https://github.com/chaosblade-io/chaosblade-exec-jvm/issues) and [Pull Requests](https://github.com/chaosblade-io/chaosblade-exec-jvm/pulls) for trackers.
If you find a typo in document, find a bug in code, or want new features, or want to give suggestions,
you can [open an issue on GitHub](https://github.com/chaosblade-io/chaosblade-exec-jvm/issues/new) to report it.
Please follow the guideline message in the issue template.
If you want to contribute, please follow the [contribution workflow](#Workflow) and create a new pull request.
If your PR contains large changes, e.g. component refactor or new components, please write detailed documents
about its design and usage.
Note that a single PR should not be too large. If heavy changes are required, it's better to separate the changes
to a few individual PRs.
### Code Review
All code should be well reviewed by one or more committers. Some principles:
- Readability: Important code should be well-documented. Comply with our code style.
- Elegance: New functions, classes or components should be well designed.
- Testability: Important code should be well-tested (high unit test coverage).
## Others
### Code of Conduct
*"In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make
participation in our project and our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education,
socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation..."*
See details of [CONTRIBUTOR COVENANT CODE OF CONDUCT](https://github.com/chaosblade-io/chaosblade-exec-jvm/blob/master/CODE_OF_CONDUCT.md)
### Sign your work
The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an open-source patch.
The rules are pretty simple: if you can certify the below (from [developercertificate.org](http://developercertificate.org/)):
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```
Then you just add a line to every git commit message:
```
Signed-off-by: Joe Smith <joe.smith@email.com>
```
Use your real name (sorry, no pseudonyms or anonymous contributions.)
If you set your `user.name` and `user.email` git configs, you can sign your commit automatically with `git commit -s`.
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 1999-2019 Alibaba Group Holding Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: Makefile
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
.PHONY: show-version linux_amd64 linux_arm64 pre_build operator chaos_fuse yaml build_binary build_linux_amd64_image build_linux_arm64_image build_linux_amd64_helm build_linux_arm64_helm build_linux_amd64_release build_linux_arm64_release push_image test clean help
# Default target - show help when no target is specified
.DEFAULT_GOAL := help
# Container runtime configuration - compatible with Docker and Podman
# Auto-detect available container runtime
ifeq ($(CONTAINER_RUNTIME),)
ifeq ($(shell command -v podman >/dev/null 2>&1 && podman info >/dev/null 2>&1 && echo "podman"),podman)
CONTAINER_RUNTIME := podman
else ifeq ($(shell command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1 && echo "docker"),docker)
CONTAINER_RUNTIME := docker
else
CONTAINER_RUNTIME := docker
endif
endif
# Get current platform information
CURRENT_OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
CURRENT_ARCH := $(shell uname -m)
ifeq ($(CURRENT_ARCH),x86_64)
CURRENT_ARCH := amd64
else ifeq ($(CURRENT_ARCH),aarch64)
CURRENT_ARCH := arm64
endif
GOOS := $(shell go env GOOS)
GOARCH := $(shell go env GOARCH)
UNAME := $(shell uname)
# Version information retrieval
ifeq ($(BLADE_VERSION), )
BLADE_VERSION := $(shell git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//' || echo "0.0.0")
endif
ifeq ($(BLADE_VENDOR), )
BLADE_VENDOR=community
endif
# Dynamically get Git information
GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
BUILD_TIME := $(shell date -u '+%Y-%m-%dT%H:%M:%SZ')
GO_VERSION := $(shell go version | awk '{print $$3}')
PLATFORM := $(shell echo "$(GOOS)/$(GOARCH)")
BUILD_TARGET=target
BUILD_TARGET_DIR_NAME=chaosblade-$(BLADE_VERSION)
BUILD_TARGET_PKG_DIR=$(BUILD_TARGET)/chaosblade-$(BLADE_VERSION)
BUILD_TARGET_BIN=$(BUILD_TARGET_PKG_DIR)/bin
BUILD_TARGET_YAML=$(BUILD_TARGET_PKG_DIR)/yaml
BUILD_IMAGE_PATH=build/image/blade
OS_YAML_FILE_NAME=chaosblade-k8s-spec-$(BLADE_VERSION).yaml
OS_YAML_FILE_PATH=$(BUILD_TARGET_YAML)/$(OS_YAML_FILE_NAME)
VERSION_PKG=github.com/chaosblade-io/chaosblade-operator/version
# Complete version information ldflags
VERSION_LDFLAGS=-X=$(VERSION_PKG).Version=$(BLADE_VERSION) \
-X=$(VERSION_PKG).Product=$(BLADE_VENDOR) \
-X=$(VERSION_PKG).BuildTime=$(BUILD_TIME) \
-X=$(VERSION_PKG).GitCommit=$(GIT_COMMIT) \
-X=$(VERSION_PKG).GitBranch=$(GIT_BRANCH) \
-X=$(VERSION_PKG).GoVersion=$(GO_VERSION) \
-X=$(VERSION_PKG).Platform=$(PLATFORM) \
-X=$(VERSION_PKG).CombinedVersion=$(BLADE_VERSION),$(BLADE_VENDOR)
GO_FLAGS=-ldflags "$(VERSION_LDFLAGS)"
GO_FLAGS_WITH_STATIC=-ldflags="-linkmode external -extldflags -static $(VERSION_LDFLAGS)"
# Cross-compilation CC detection for chaos_fuse
define detect_cc
$(strip $(if $(and $(filter amd64,$(GOARCH)),$(shell command -v musl-gcc 2>/dev/null)),musl-gcc,\
$(if $(and $(filter amd64,$(GOARCH)),$(wildcard /usr/local/musl/bin/musl-gcc)),/usr/local/musl/bin/musl-gcc,\
$(if $(and $(filter amd64,$(GOARCH)),$(shell command -v x86_64-linux-musl-gcc 2>/dev/null)),x86_64-linux-musl-gcc,\
$(if $(and $(filter arm64,$(GOARCH)),$(shell command -v aarch64-linux-musl-gcc 2>/dev/null)),aarch64-linux-musl-gcc,\
$(if $(and $(filter amd64,$(GOARCH)),$(shell command -v gcc 2>/dev/null)),gcc,\
$(if $(and $(filter arm64,$(GOARCH)),$(shell command -v aarch64-linux-gnu-gcc 2>/dev/null)),aarch64-linux-gnu-gcc,\
$(if $(and $(filter arm64,$(GOARCH)),$(shell command -v gcc 2>/dev/null)),gcc,\
container))))))))
endef
CC_FOR_CHAOS_FUSE := $(call detect_cc)
# Display version information
show-version:
@echo "=== Build Version Information ==="
@echo "Version: $(BLADE_VERSION)"
@echo "Vendor: $(BLADE_VENDOR)"
@echo "Git Commit: $(GIT_COMMIT)"
@echo "Git Branch: $(GIT_BRANCH)"
@echo "Build Time: $(BUILD_TIME)"
@echo "Go Version: $(GO_VERSION)"
@echo "Platform: $(PLATFORM)"
@echo "=================="
# Linux AMD64 platform build
linux_amd64: show-version pre_build
@echo "Building Linux AMD64 platform components..."
$(MAKE) operator GOOS=linux GOARCH=amd64
@echo "chaosblade-operator build completed"
$(MAKE) chaos_fuse GOOS=linux GOARCH=amd64
@echo "chaos_fuse build completed"
$(MAKE) yaml GOOS=linux GOARCH=arm64
@echo "YAML specification file generation completed"
@echo "Linux AMD64 platform build completed"
# Linux ARM64 platform build
linux_arm64: show-version pre_build
@echo "Building Linux ARM64 platform components..."
$(MAKE) operator GOOS=linux GOARCH=arm64
@echo "chaosblade-operator build completed"
$(MAKE) chaos_fuse GOOS=linux GOARCH=arm64
@echo "chaos_fuse build completed"
$(MAKE) yaml GOOS=linux GOARCH=arm64
@echo "YAML specification file generation completed"
@echo "Linux ARM64 platform build completed"
pre_build:
@mkdir -p $(BUILD_TARGET_BIN) $(BUILD_TARGET_YAML) build/_output/bin
operator:
@echo "Building chaosblade-operator for $(GOOS)/$(GOARCH)..."
@CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(GO_FLAGS) -o build/_output/bin/chaosblade-operator cmd/manager/main.go
chaos_fuse: ## Build chaos_fuse for Linux (supports cross-compilation from macOS)
ifeq ($(GOOS),linux)
@echo "Detected CC for chaos_fuse: $(CC_FOR_CHAOS_FUSE)"
@if [ "$(CC_FOR_CHAOS_FUSE)" != "container" ]; then \
echo "Building chaos_fuse for Linux $(GOARCH) using $(CC_FOR_CHAOS_FUSE)..."; \
CC=$(CC_FOR_CHAOS_FUSE) CGO_ENABLED=1 go build $(GO_FLAGS) -o $(BUILD_TARGET_BIN)/chaos_fuse cmd/hookfs/main.go; \
elif command -v $(CONTAINER_RUNTIME) >/dev/null 2>&1 && $(CONTAINER_RUNTIME) info >/dev/null 2>&1; then \
echo "Building chaos_fuse for Linux $(GOARCH) using $(CONTAINER_RUNTIME)..."; \
if [ "$(GOARCH)" = "amd64" ]; then \
$(CONTAINER_RUNTIME) run --rm -v $(PWD):/src:Z -w /src --platform linux/amd64 golang:1.21-alpine sh -c "apk add --no-cache musl-dev gcc && cd /src && CGO_ENABLED=1 go build $(GO_FLAGS) -o /src/$(BUILD_TARGET_BIN)/chaos_fuse cmd/hookfs/main.go" >/dev/null 2>&1; \
elif [ "$(GOARCH)" = "arm64" ]; then \
$(CONTAINER_RUNTIME) run --rm -v $(PWD):/src:Z -w /src golang:1.21-alpine sh -c "apk add --no-cache musl-dev gcc && cd /src && CGO_ENABLED=1 GOARCH=arm64 GOOS=linux go build $(GO_FLAGS) -o /src/$(BUILD_TARGET_BIN)/chaos_fuse cmd/hookfs/main.go" >/dev/null 2>&1; \
else \
echo "Unsupported architecture $(GOARCH) for chaos_fuse"; \
fi; \
else \
echo "Warning: No suitable cross-compilation toolchain found for chaos_fuse"; \
echo "Available options:"; \
echo " 1. Install musl-tools: apt-get install musl-tools (Ubuntu/Debian)"; \
echo " 2. Install musl-gcc: brew install FiloSottile/musl-cross/musl-cross (macOS)"; \
echo " 3. Install specific cross-compilers for ARM64: apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu"; \
echo " 4. Use Docker/Podman with proper platform emulation"; \
fi
else
@echo "Skipping chaos_fuse build on $(GOOS) for target - Linux only"
endif
yaml: build/spec.go
@echo "Building spec generator..."
@GOOS=$(CURRENT_OS) GOARCH=$(CURRENT_ARCH) go build $(GO_FLAGS) -o build/_output/bin/spec $<
@echo "Generating YAML specifications..."
@GOOS=$(CURRENT_OS) GOARCH=$(CURRENT_ARCH) build/_output/bin/spec $(OS_YAML_FILE_PATH) $(if $(JVM_SPEC_PATH),$(JVM_SPEC_PATH),)
only_yaml: pre_build yaml
# Build binary files and display version information
build_binary: show-version
CGO_ENABLED=0 go build $(GO_FLAGS) -o $(BUILD_TARGET_BIN)/chaosblade-operator cmd/manager/main.go
@echo "Binary file build completed: $(BUILD_TARGET_BIN)/chaosblade-operator"
@echo "Version information:"
@$(BUILD_TARGET_BIN)/chaosblade-operator version 2>/dev/null || echo "Unable to get version information"
##----------------------------------------------------------------------------
# build image
build_linux_amd64_image:
CGO_ENABLED=0 GOOS="linux" GOARCH="amd64" go build $(GO_FLAGS) -o build/_output/bin/chaosblade-operator cmd/manager/main.go
$(CONTAINER_RUNTIME) buildx build -f build/image/amd/Dockerfile --platform=linux/amd64 -t ghcr.io/chaosblade-io/chaosblade-operator:${BLADE_VERSION} .
build_linux_arm64_image:
CGO_ENABLED=0 GOOS="linux" GOARCH="arm64" go build $(GO_FLAGS) -o build/_output/bin/chaosblade-operator cmd/manager/main.go
$(CONTAINER_RUNTIME) buildx build -f build/image/arm/Dockerfile --platform=linux/arm64 -t ghcr.io/chaosblade-io/chaosblade-operator-arm64:${BLADE_VERSION} .
push_image:
$(CONTAINER_RUNTIME) push ghcr.io/chaosblade-io/chaosblade-operator:${BLADE_VERSION}
$(CONTAINER_RUNTIME) push ghcr.io/chaosblade-io/chaosblade-operator-arm64:${BLADE_VERSION}
# Build Helm packages with version updates
build_linux_amd64_helm: show-version pre_build
@echo "Building Linux AMD64 Helm package..."
@# Update Chart.yaml versions
@sed -i.bak 's/^appVersion: ".*"/appVersion: "$(BLADE_VERSION)"/' deploy/helm/chaosblade-operator/Chart.yaml
@sed -i.bak 's/^version: .*/version: $(BLADE_VERSION)/' deploy/helm/chaosblade-operator/Chart.yaml
@# Update values.yaml versions
@sed -i.bak 's/^ version: .*/ version: $(BLADE_VERSION)/' deploy/helm/chaosblade-operator/values.yaml
@sed -i.bak 's/^ version: .*/ version: $(BLADE_VERSION)/' deploy/helm/chaosblade-operator/values.yaml
@# Clean up backup files
@rm -f deploy/helm/chaosblade-operator/Chart.yaml.bak deploy/helm/chaosblade-operator/values.yaml.bak
@# Package Helm chart
@helm package deploy/helm/chaosblade-operator --destination $(BUILD_TARGET) --version $(BLADE_VERSION) --app-version $(BLADE_VERSION)
@# Rename the package to include architecture
@mv $(BUILD_TARGET)/chaosblade-operator-$(BLADE_VERSION).tgz $(BUILD_TARGET)/chaosblade-operator-amd64-$(BLADE_VERSION).tgz
@echo "Linux AMD64 Helm package created: $(BUILD_TARGET)/chaosblade-operator-amd64-$(BLADE_VERSION).tgz"
build_linux_arm64_helm: show-version pre_build
@echo "Building Linux ARM64 Helm package..."
@# Update Chart.yaml versions
@sed -i.bak 's/^appVersion: ".*"/appVersion: "$(BLADE_VERSION)"/' deploy/helm/chaosblade-operator-arm64/Chart.yaml
@sed -i.bak 's/^version: .*/version: $(BLADE_VERSION)/' deploy/helm/chaosblade-operator-arm64/Chart.yaml
@# Update values.yaml versions
@sed -i.bak 's/^ version: .*/ version: $(BLADE_VERSION)/' deploy/helm/chaosblade-operator-arm64/values.yaml
@sed -i.bak 's/^ version: .*/ version: $(BLADE_VERSION)/' deploy/helm/chaosblade-operator-arm64/values.yaml
@# Clean up backup files
@rm -f deploy/helm/chaosblade-operator-arm64/Chart.yaml.bak deploy/helm/chaosblade-operator-arm64/values.yaml.bak
@# Package Helm chart
@helm package deploy/helm/chaosblade-operator-arm64 --destination $(BUILD_TARGET) --version $(BLADE_VERSION) --app-version $(BLADE_VERSION)
@echo "Linux ARM64 Helm package created: $(BUILD_TARGET)/chaosblade-operator-arm64-$(BLADE_VERSION).tgz"
##----------------------------------------------------------------------------
build_linux_amd64_release: build_linux_amd64_image build_linux_amd64_helm
build_linux_arm64_release: build_linux_arm64_image build_linux_arm64_helm
# test
test:
go test -race -coverprofile=coverage.txt -covermode=atomic ./...
# clean all build result
clean:
go clean ./...
rm -rf $(BUILD_TARGET)
rm -rf $(BUILD_IMAGE_PATH)/$(BUILD_TARGET_DIR_NAME)
.PHONY: format
format: license-format
@echo "Running goimports and gofumpt to format Go code..."
@./hack/update-imports.sh
@./hack/update-gofmt.sh
.PHONY: verify
verify:
@echo "Verifying Go code formatting and import order..."
@./hack/verify-gofmt.sh
@./hack/verify-imports.sh
.PHONY: license-check
license-check:
@echo "Checking license headers..."
docker run -it --rm -v $(shell pwd):/github/workspace ghcr.io/korandoru/hawkeye check
.PHONY: license-format
license-format:
@echo "Formatting license headers..."
docker run -it --rm -v $(shell pwd):/github/workspace ghcr.io/korandoru/hawkeye format
# Help information
help:
@echo "Available build targets:"
@echo " linux_amd64 - Build Linux AMD64 platform components (operator + chaos_fuse + yaml)"
@echo " linux_arm64 - Build Linux ARM64 platform components (operator + chaos_fuse + yaml)"
@echo " build_linux_amd64_image - Build Linux AMD64 Docker image"
@echo " build_linux_arm64_image - Build Linux ARM64 Docker image"
@echo " build_linux_amd64_helm - Build and package Linux AMD64 Helm chart"
@echo " build_linux_arm64_helm - Build and package Linux ARM64 Helm chart"
@echo " build_linux_amd64_release - Build image and Helm package for AMD64"
@echo " build_linux_arm64_release - Build image and Helm package for ARM64"
@echo " push_image - Push images to image registry"
@echo " show-version - Display current version information"
@echo " format - Format Go code using goimports and gofumpt"
@echo " verify - Verify Go code formatting and import order"
@echo " license-check - Check license headers in source files"
@echo " clean - Clean build artifacts"
@echo ""
@echo "Version-related environment variables:"
@echo " BLADE_VERSION - Specify version number (default: Git tag)"
@echo " BLADE_VENDOR - Specify vendor (default: community)"
@echo ""
@echo "Build-related environment variables:"
@echo " JVM_SPEC_PATH - Specify JVM specification file path (for container.JvmSpecFileForYaml)"
@echo " CONTAINER_RUNTIME - Specify container runtime (docker or podman, auto-detected by default)"
@echo ""
================================================
FILE: README.md
================================================
# Chaosblade-operator: A Chaos Engineering Tool for Cloud-native

中文版 [README](README_CN.md)
## Introduction
Chaosblade Operator is a chaos experiments injection tool for cloud-native on kubernetes platform. By defining Kubernetes CRD to manage chaos experiments, each experiment has a very clear execution status. The tool has the characteristics of simple deployment, convenient execution, standardized implementation, and rich experiments. The chaos experimental model in chaosblade is well integrated with Kubernetes, which can realize the reuse of experiments such as basic resources, application services, and containers on the Kubernetes platform, which facilitates the expansion of resource experiments under Kubernetes, and can be executed uniformly through chaosblade cli tool.
## Supported experiments (continuously adding ...)
The current experimental scenarios involve resources including Node, Pod, and Container. The specific supported experimental scenarios are as follows:
* Node:
* CPU: specify CPU usage
* Network: specify network card, port, IP, etc. packet delay, packet loss, packet blocking, packet duplication, packet re-ordering, packet corruption, etc.
* Process: specify process Hang, kill process, etc.
* Disk: specify the directory disk occupation, disk IO read and write load, etc.
* Memory: specify memory usage
* Pod:
* Network: specify network card, port, IP, etc. packet delay, packet loss, packet blocking, packet duplication, packet re-ordering, packet corruption, etc.
* Disk: specify the directory disk occupation, disk IO read and write load, etc.
* Memory: specify memory usage
* Pod: kill pod, make pod stuck in ContainerCreating state by PVC mount failure, make pod stuck in ContainerCreating state by cloud disk PVC creation failure, make pod stuck in Terminating state by finalizer, make pod scheduling fail by injecting unreachable affinity rules, modify workload (Deployment/DaemonSet/StatefulSet) CPU/Memory resource limits to simulate bad resource sizing, mount non-existent ConfigMap/Secret/PVC volume to workload (Deployment/DaemonSet/StatefulSet) to simulate volume mount failure
* IO: specify the file system io exception. Supports 31 file operations and 11 exception scenarios, such as "Too many open files", "Device or resource busy" and so on.
* Container:
* CPU: specify CPU usage
* Network: specify network card, port, IP, etc. packet delay, packet loss, packet blocking, packet duplication, packet re-ordering, packet corruption, etc.
* Process: specify process Hang, kill process, etc.
* Disk: specify the directory disk occupation, disk IO read and write load, etc.
* Memory: specify memory usage
* Container: remove container
* Service:
* Service: create, modify service
## Local Build & Installation
## Build images
```shell
# Under operator's root directory
# For linux/amd64
make build_all
# For linux/arm64
make build_all_amr64
```
### Build and install Helm Chart
```shell
# Under operator's root directory
cd deploy/helm
# For linux/amd64
helm package ./chaosblade-operator
kubectl create ns chaosblade
helm install chaosblade chaosblade-operator-${version}.tgz --namespace chaosblade
# For linux/arm64
helm package ./chaosblade-operator-arm64
kubectl create ns chaosblade
helm install chaosblade chaosblade-operator-arm64-${version}.tgz --namespace chaosblade
```
## Install and uninstall
The lowest version of kubernetes supported is 1.12. Chaosblade operator can be installed through kubectl or helm, the installation method is as follows:
Note: For the following `VERSION`, please use the latest version number instead
### Helm v2
* Download the latest `chaosblade-operator-VERSION-v2.tgz` package at [Release](https://github.com/chaosblade-io/chaosblade-operator/releases)
* Install using `helm install --namespace chaosblade --name chaosblade-operator chaosblade-operator-VERSION-v2.tgz`
* Use `kubectl get pod -l part-of=chaosblade -n chaosblade` to check the installation status of the Pod. If both are running, the installation was successful
* Use the following command to uninstall, pay attention to the execution order:
```shell script
kubectl delete crd chaosblades.chaosblade.io
helm del --purge chaosblade-operator
```
### Helm v3
* Download the latest `chaosblade-operator-VERSION-v3.tgz` package at [Release](https://github.com/chaosblade-io/chaosblade-operator/releases)
* Use `helm install chaosblade-operator chaosblade-operator-VERSION-v3.tgz --namespace chaosblade` command to install
* Use `kubectl get pod -l part-of=chaosblade -n chaosblade` to check the installation status of the Pod. If both are running, the installation was successful
* Use the following command to uninstall, pay attention to the execution order:
```shell script
kubectl delete crd chaosblades.chaosblade.io
helm uninstall chaosblade-operator -n chaosblade
```
### Kubectl
* Download the latest `chaosblade-operator-yaml-VERSION.tar.gz` package at [Release](https://github.com/chaosblade-io/chaosblade-operator/releases)
* After decompression, execute `kubectl apply -f chaosblade-operator-yaml-VERSION/` installation
* Use `kubectl get pod -l part-of=chaosblade -n chaosblade` to check the installation status of the Pod. If both are running, the installation was successful
* Use the following command to uninstall, pay attention to the execution order:
```shell script
kubectl delete crd chaosblades.chaosblade.io
kubectl delete -f chaosblade-operator-yaml-VERSION/
```
## How to use
You can run chaos experiments after installing the chaosblade operator. There are three ways to execute chaos experiments:
* By configuring yaml file, use kubectl to execute
* Executed using chaosblade cli tool
* Use Kubernetes API to execute by writing code
The following uses a specific case to illustrate the use of chaosblade-operator: simulate cn-hangzhou.192.168.0.205 node local port 40690 60% network packet loss.
### By configuring the yaml file, use kubectl to execute
```
apiVersion: chaosblade.io/v1alpha1
kind: ChaosBlade
metadata:
name: loss-node-network-by-names
spec:
experiments:
- scope: node
target: network
action: loss
desc: "node network loss"
matchers:
- name: names
value: ["cn-hangzhou.192.168.0.205"]
- name: percent
value: ["60"]
- name: interface
value: ["eth0"]
- name: local-port
value: ["40690"]
```
Execute experiment:
```
kubectl apply -f loss-node-network-by-names.yaml
```
Query the experimental status, the returned information is as follows (spec and other contents are omitted):
```
~ » kubectl get blade loss-node-network-by-names -o json
{
"apiVersion": "chaosblade.io/v1alpha1",
"kind": "ChaosBlade",
"metadata": {
"creationTimestamp": "2019-11-04T09:56:36Z",
"finalizers": [
"finalizer.chaosblade.io"
],
"generation": 1,
"name": "loss-node-network-by-names",
"resourceVersion": "9262302",
"selfLink": "/apis/chaosblade.io/v1alpha1/chaosblades/loss-node-network-by-names",
"uid": "63a926dd-fee9-11e9-b3be-00163e136d88"
},
"status": {
"expStatuses": [
{
"action": "loss",
"resStatuses": [
{
"id": "057acaa47ae69363",
"kind": "node",
"name": "cn-hangzhou.192.168.0.205",
"nodeName": "cn-hangzhou.192.168.0.205",
"state": "Success",
"success": true,
"uid": "e179b30d-df77-11e9-b3be-00163e136d88"
}
],
"scope": "node",
"state": "Success",
"success": true,
"target": "network"
}
],
"phase": "Running"
}
}
```
From the above, you can clearly see the running status of the chaos experiment. Run the following command to stop the experiment:
```
kubectl delete -f loss-node-network-by-names.yaml
```
Or delete this blade resource directly:
```
kubectl delete blade loss-node-network-by-names
```
You can also edit the yaml file to update the content of the experiment and the chaosblade operator will complete the update of the experiment. See more examples: [Examples](https://github.com/chaosblade-io/chaosblade-operator/tree/master/examples)
### Execute with chaosblade cli tool
```
blade create k8s node-network loss --percent 60 --interface eth0 --local-port 40690 --names cn-hangzhou.192.168.0.205 --kubeconfig config
```
If the execution fails, a detailed error message is returned; if the execution is successful, the experiment UID is returned:
```
{"code":200,"success":true,"result":"e647064f5f20953c"}
```
You can query the status of the experiment with the following command:
```
blade query k8s create e647064f5f20953c --kubeconfig config
{
"code": 200,
"success": true,
"result": {
"uid": "e647064f5f20953c",
"success": true,
"error": "",
"statuses": [
{
"id": "fa471a6285ec45f5",
"uid": "e179b30d-df77-11e9-b3be-00163e136d88",
"name": "cn-hangzhou.192.168.0.205",
"state": "Success",
"kind": "node",
"success": true,
"nodeName": "cn-hangzhou.192.168.0.205"
}
]
}
}
```
Destroy experiment:
```
blade destroy e647064f5f20953c
```
In addition to the above two methods, you can also use the kubernetes client-go api for execution. For details, please refer to: [executor.go](https://github.com/chaosblade-io/chaosblade/blob/master/exec/kubernetes/executor.go) code implementation.
[Chinese documentation](https://chaosblade-io.gitbook.io/chaosblade-help-zh-cn/blade-create-k8s)
## Questions & Suggestions
If you encounter problems during installation and use, or suggestions and new features, all projects (including other projects) can be submitted to [Github Issues](https://github.com/chaosblade-io/chaosblade/issues)
You can also contact us via:
* Dingding group: 23177705
* Gitter room: [chaosblade community](https://gitter.im/chaosblade-io/community)
* Email: chaosblade.io.01@gmail.com
* Twitter: [chaosblade.io](https://twitter.com/ChaosbladeI)
## Contributions
We welcome every issue and PR. Even a punctuation mark, how to participate in the contribution please read the [CONTRIBUTING](CONTRIBUTING.md) document, or contact us through the above method.
## Open source license
Chaosblade-operator is licensed under the Apache 2.0 license. For details, please read [LICENSE](LICENSE)
================================================
FILE: README_CN.md
================================================
# Chaosblade Operator: 面向云原生的混沌工程执行工具

## 介绍
Chaosblade Operator 是混沌工程实验工具 ChaosBlade 下的一款面向云原生领域的混沌实验注入工具,可单独部署使用。通过定义 Kubernetes CRD 来管理混沌实验,每个实验都有非常明确的执行状态。工具具有部署简单、执行便捷、标准化实现、场景丰富等特点。将 ChaosBlade 混沌实验模型与 Kubernetes CRD 很好的结合在一起,可以实现基础资源、应用服务、容器等场景在 Kubernetes 平台上场景复用,方便了 Kubernetes 下资源场景的扩展,而且可通过 chaosblade cli 统一执行调用。
## 支持的场景(持续新增中...)
目前实验场景涉及到资源包含 Node、Pod、Container,具体支持的场景如下:
* Node:
* CPU: 指定 CPU 使用率
* 网络: 指定网卡、端口、IP 等包延迟、丢包、包阻塞、包重复、包乱序、包损坏等
* 进程:指定进程 Hang、强杀指定进程等
* 磁盘:指定目录磁盘填充、磁盘 IO 读写负载等
* 内存:指定内存使用率
* Pod:
* 网络:指定网卡、端口、IP 等包延迟、丢包、包阻塞、包重复、包乱序、包损坏等
* 磁盘:指定目录磁盘填充、磁盘 IO 读写负载等
* 内存:指定内存使用率
* Pod:杀 Pod、通过 PVC 挂载失败使 Pod 卡在 ContainerCreating 状态、通过云盘 PVC 创建失败使 Pod 卡在 ContainerCreating 状态、通过 finalizer 使 Pod 卡在 Terminating 状态、通过注入无法满足的亲和性规则使 Pod 调度失败、修改工作负载(Deployment/DaemonSet/StatefulSet)的 CPU/Memory 资源限制模拟资源配置异常、挂载不存在的 ConfigMap/Secret/PVC 类型 Volume 到工作负载(Deployment/DaemonSet/StatefulSet)模拟卷挂载失败
* Container:
* CPU: 指定 CPU 使用率
* 网络: 指定网卡、端口、IP 等包延迟、丢包、包阻塞、包重复、包乱序、包损坏等
* 进程:指定进程 Hang、强杀指定进程等
* 磁盘:指定目录磁盘填充、磁盘 IO 读写负载等
* 内存:指定内存使用率
* Container: 杀 Container
* Service:
* Service: 创建、修改Service
## 本地构建&安装
### 构造镜像
```shell
# operator 根目录下
# linux/amd64
make build_all
# linux/arm64
make build_all_amr64
```
### 构造并安装 Helm Chart
```shell
# operator 根目录下
cd deploy/helm
# linux/amd64
helm package ./chaosblade-operator
kubectl create ns chaosblade
helm install chaosblade chaosblade-operator-${version}.tgz --namespace chaosblade
# linux/arm64
helm package ./chaosblade-operator-arm64
kubectl create ns chaosblade
helm install chaosblade chaosblade-operator-arm64-${version}.tgz --namespace chaosblade
```
## 安装&卸载
支持的 Kubernetes 最小版本是 v1.12,chaosblade operator 可通过 kubectl 或者 helm 进行安装,安装方式如下:
注意:以下的 `VERSION` 请使用最新的版本号替代
### Helm v2
* 在 [Release](https://github.com/chaosblade-io/chaosblade-operator/releases) 地址下载最新的 `chaosblade-operator-VERSION-v2.tgz` 包
* 使用 `helm install --namespace kube-system --name chaosblade-operator chaosblade-operator-VERSION-v2.tgz` 命令安装
* 使用 `kubectl get pod -l part-of=chaosblade -n kube-system` 查看 Pod 的安装状态,如果都是 running 状态,说明安装成功
* 使用以下命令进行卸载,注意执行顺序:
```shell script
kubectl delete crd chaosblades.chaosblade.io
helm del --purge chaosblade-operator
```
### Helm v3
* 在 [Release](https://github.com/chaosblade-io/chaosblade-operator/releases) 地址下载最新的 `chaosblade-operator-VERSION-v3.tgz` 包
* 使用 `helm install chaosblade-operator chaosblade-operator-VERSION-v3.tgz --namespace kube-system` 命令安装
* 使用 `kubectl get pod -l part-of=chaosblade -n kube-system` 查看 Pod 的安装状态,如果都是 running 状态,说明安装成功
* 使用以下命令卸载,注意执行顺序:
```shell script
kubectl delete crd chaosblades.chaosblade.io
helm uninstall chaosblade-operator -n kube-system
```
### Kubectl
* 在 [Release](https://github.com/chaosblade-io/chaosblade-operator/releases) 地址下载最新的 `chaosblade-operator-yaml-VERSION.tar.gz` 包
* 解压后执行 `kubectl apply -f chaosblade-operator-yaml-VERSION/` 安装
* 使用 `kubectl get pod -l part-of=chaosblade -n kube-system` 查看 Pod 的安装状态,如果都是 running 状态,说明安装成功
* 使用以下命令卸载,注意执行顺序:
```shell script
kubectl delete crd chaosblades.chaosblade.io
kubectl delete -f chaosblade-operator-yaml-VERSION/
```
## 使用
安装 chaosblade operator 后即可执行混沌实验,执行方式有以下三种:
* 通过配置 yaml 方式,使用 kubectl 执行
* 使用 chaosblade cli 工具执行
* 通过编写代码调用 Kubernetes API 执行
下面通过一个具体的案例来说明 chaosblade-operator 的使用:模拟 cn-hangzhou.192.168.0.205 节点本地端口 40690 60% 的网络丢包。
### 通过配置 yaml 方式,使用 kubectl 执行
```
apiVersion: chaosblade.io/v1alpha1
kind: ChaosBlade
metadata:
name: loss-node-network-by-names
spec:
experiments:
- scope: node
target: network
action: loss
desc: "node network loss"
matchers:
- name: names
value: ["cn-hangzhou.192.168.0.205"]
- name: percent
value: ["60"]
- name: interface
value: ["eth0"]
- name: local-port
value: ["40690"]
```
执行实验:
```
kubectl apply -f loss-node-network-by-names.yaml
```
查询实验状态,返回信息如下(省略了 spec 等内容):
```
~ » kubectl get blade loss-node-network-by-names -o json
{
"apiVersion": "chaosblade.io/v1alpha1",
"kind": "ChaosBlade",
"metadata": {
"creationTimestamp": "2019-11-04T09:56:36Z",
"finalizers": [
"finalizer.chaosblade.io"
],
"generation": 1,
"name": "loss-node-network-by-names",
"resourceVersion": "9262302",
"selfLink": "/apis/chaosblade.io/v1alpha1/chaosblades/loss-node-network-by-names",
"uid": "63a926dd-fee9-11e9-b3be-00163e136d88"
},
"status": {
"expStatuses": [
{
"action": "loss",
"resStatuses": [
{
"id": "057acaa47ae69363",
"kind": "node",
"name": "cn-hangzhou.192.168.0.205",
"nodeName": "cn-hangzhou.192.168.0.205",
"state": "Success",
"success": true,
"uid": "e179b30d-df77-11e9-b3be-00163e136d88"
}
],
"scope": "node",
"state": "Success",
"success": true,
"target": "network"
}
],
"phase": "Running"
}
}
```
通过以上内容可以很清晰的看出混沌实验的运行状态,执行以下命令停止实验:
```
kubectl delete -f loss-node-network-by-names.yaml
```
或者直接删除此 blade 资源
```
kubectl delete blade loss-node-network-by-names
```
还可以编辑 yaml 文件,更新实验内容执行,chaosblade operator 会完成实验的更新操作。更多案例请查看 [Examples](https://github.com/chaosblade-io/chaosblade-operator/tree/master/examples)
### 使用 chaosblade cli 工具执行
```
blade create k8s node-network loss --percent 60 --interface eth0 --local-port 40690 --names cn-hangzhou.192.168.0.205 --kubeconfig config
```
如果执行失败,会返回详细的错误信息;如果执行成功,会返回实验的 UID:
```
{"code":200,"success":true,"result":"e647064f5f20953c"}
```
可通过以下命令查询实验状态:
```
blade query k8s create e647064f5f20953c --kubeconfig config
{
"code": 200,
"success": true,
"result": {
"uid": "e647064f5f20953c",
"success": true,
"error": "",
"statuses": [
{
"id": "fa471a6285ec45f5",
"uid": "e179b30d-df77-11e9-b3be-00163e136d88",
"name": "cn-hangzhou.192.168.0.205",
"state": "Success",
"kind": "node",
"success": true,
"nodeName": "cn-hangzhou.192.168.0.205"
}
]
}
}
```
销毁实验:
```
blade destroy e647064f5f20953c
```
除了上述两种方式调用外,还可以使用 kubernetes client-go 方式执行,具体可参考:[executor.go](https://github.com/chaosblade-io/chaosblade/blob/master/exec/kubernetes/executor.go) 代码实现。
[中文使用文档](https://chaosblade-io.gitbook.io/chaosblade-help-zh-cn/blade-create-k8s)
## 问题&建议
如果在安装使用过程中遇到问题,或者建议和新功能,所有项目(包含其他项目)的问题都可以提交到[Github Issues](https://github.com/chaosblade-io/chaosblade/issues)
你也可以通过以下方式联系我们:
* 钉钉群(推荐):23177705
* Gitter room: [chaosblade community](https://gitter.im/chaosblade-io/community)
* 邮箱:chaosblade.io.01@gmail.com
* Twitter: [chaosblade.io](https://twitter.com/ChaosbladeI)
## 参与贡献
我们非常欢迎每个 Issue 和 PR,即使一个标点符号,如何参加贡献请阅读 [CONTRIBUTING](CONTRIBUTING.md) 文档,或者通过上述的方式联系我们。
## 开源许可证
Chaosblade-operator 遵循 Apache 2.0 许可证,详细内容请阅读 [LICENSE](LICENSE)
================================================
FILE: build/bin/entrypoint
================================================
#!/bin/sh -e
# This is documented here:
# https://docs.openshift.com/container-platform/3.11/creating_images/guidelines.html#openshift-specific-guidelines
#if ! whoami &>/dev/null; then
# if [ -w /etc/passwd ]; then
# echo "${USER_NAME:-chaosblade-operator}:x:$(id -u):$(id -g):${USER_NAME:-chaosblade-operator} user:${HOME}:/sbin/nologin" >> /etc/passwd
# fi
#fi
exec ${OPERATOR} $@
================================================
FILE: build/bin/user_setup
================================================
#!/bin/sh
set -x
# ensure $HOME exists and is accessible by group 0 (we don't know what the runtime UID will be)
mkdir -p ${HOME}
chown ${USER_UID}:0 ${HOME}
chmod ug+rwx ${HOME}
# runtime user will need to be able to self-insert in /etc/passwd
chmod g+rw /etc/passwd
# no need for this script to remain in the image after running
rm $0
================================================
FILE: build/image/amd/Dockerfile
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FROM --platform=linux/amd64 alpine:latest as builder
ENV OPERATOR=/usr/local/bin/chaosblade-operator
COPY build/_output/bin/chaosblade-operator /usr/local/bin/
# Build platform-specific scripts for AMD64
FROM --platform=linux/amd64 alpine:latest as script_builder
RUN apk add --no-cache bash
COPY build/bin /tmp/scripts
RUN chmod +x /tmp/scripts/*
FROM --platform=linux/amd64 registry.access.redhat.com/ubi8/ubi-minimal:latest
ENV OPERATOR=/usr/local/bin/chaosblade-operator \
CHAOSBLADE_HOME=/opt/chaosblade
COPY --from=builder ${OPERATOR} /usr/local/bin/
COPY --from=script_builder /tmp/scripts /usr/local/bin
RUN chmod 777 /usr/local/bin/user_setup
RUN /usr/local/bin/user_setup
ENTRYPOINT ["/usr/local/bin/entrypoint"]
================================================
FILE: build/image/arm/Dockerfile
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FROM alpine:latest as builder
ENV OPERATOR=/usr/local/bin/chaosblade-operator
COPY build/_output/bin/chaosblade-operator /usr/local/bin/
# Build platform-specific scripts for ARM64
FROM alpine:latest as script_builder
RUN apk add --no-cache bash
COPY build/bin /tmp/scripts
RUN chmod +x /tmp/scripts/*
FROM registry.access.redhat.com/ubi8/ubi-minimal:latest
ENV OPERATOR=/usr/local/bin/chaosblade-operator \
CHAOSBLADE_HOME=/opt/chaosblade
COPY --from=builder ${OPERATOR} /usr/local/bin/
COPY --from=script_builder /tmp/scripts /usr/local/bin
RUN chmod 777 /usr/local/bin/user_setup
RUN /usr/local/bin/user_setup
ENTRYPOINT ["/usr/local/bin/entrypoint"]
================================================
FILE: build/musl/Dockerfile
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FROM golang:1.20.13
LABEL maintainer="Changjun Xiao"
# # The image is used to build chaosblade for musl
RUN wget http://www.musl-libc.org/releases/musl-1.1.21.tar.gz \
&& tar -zxvf musl-1.1.21.tar.gz \
&& rm musl-1.1.21.tar.gz \
&& cd musl* \
&& ./configure \
&& make \
&& make install \
&& rm -rf musl*
ENV CC /usr/local/musl/bin/musl-gcc
ENV GOOS linux
ENTRYPOINT [ "make" ]
================================================
FILE: build/spec.go
================================================
/*
* Copyright 2025 The ChaosBlade Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package main
import (
"log"
"os"
"github.com/chaosblade-io/chaosblade-operator/exec/container"
"github.com/chaosblade-io/chaosblade-operator/exec/node"
"github.com/chaosblade-io/chaosblade-operator/exec/pod"
"github.com/chaosblade-io/chaosblade-operator/exec/service"
"github.com/chaosblade-io/chaosblade-spec-go/spec"
"github.com/chaosblade-io/chaosblade-spec-go/util"
)
// main creates the yaml file of the experiments about kubernetes
func main() {
if len(os.Args) < 2 {
log.Panicln("less yaml file path")
}
if len(os.Args) == 3 {
container.JvmSpecPathForYaml = os.Args[2]
}
err := util.CreateYamlFile(getModels(), os.Args[1])
if err != nil {
log.Panicf("create yaml file error, %v", err)
}
}
func getModels() *spec.Models {
models := make([]*spec.Models, 0)
nodeResourceModelSpec := node.NewResourceModelSpec(nil)
for _, modelSpec := range nodeResourceModelSpec.ExpModels() {
model := util.ConvertSpecToModels(modelSpec, spec.ExpPrepareModel{}, nodeResourceModelSpec.Scope())
models = append(models, model)
}
podResourceModelSpec := pod.NewResourceModelSpec(nil)
for _, modelSpec := range podResourceModelSpec.ExpModels() {
model := util.ConvertSpecToModels(modelSpec, spec.ExpPrepareModel{}, podResourceModelSpec.Scope())
models = append(models, model)
}
containerResourceModelSpec := container.NewResourceModelSpec(nil)
for _, modelSpec := range containerResourceModelSpec.ExpModels() {
model := util.ConvertSpecToModels(modelSpec, spec.ExpPrepareModel{}, containerResourceModelSpec.Scope())
models = append(models, model)
}
serviceResourceModelSpec := service.NewResourceModelSpec(nil)
for _, modelSpec := range serviceResourceModelSpec.ExpModels() {
model := util.ConvertSpecToModels(modelSpec, spec.ExpPrepareModel{}, serviceResourceModelSpec.Scope())
models = append(models, model)
}
return util.MergeModels(models...)
}
================================================
FILE: channel/client.go
================================================
/*
* Copyright 2025 The ChaosBlade Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package channel
import (
"bytes"
"fmt"
"io"
"net/url"
"strings"
"github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/remotecommand"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// Client contains the kubernetes client, operator client and kubeconfig
type Client struct {
kubernetes.Interface
client.Client
Config *rest.Config
}
// NewClientFunc returns the controller client
func NewClientFunc() client.NewClientFunc {
return func(config *rest.Config, options client.Options) (client.Client, error) {
c, err := client.New(config, options)
if err != nil {
return nil, err
}
return &Client{
Interface: kubernetes.NewForConfigOrDie(config),
Client: c,
Config: config,
}, nil
}
}
type IOStreams struct {
In io.Reader
Out io.Writer
ErrOut io.Writer
}
type StreamOptions struct {
IOStreams
Stdin bool
TTY bool
OutDecoder func(bytes []byte) interface{}
ErrDecoder func(bytes []byte) interface{}
}
type ExecOptions struct {
StreamOptions
PodName string
PodNamespace string
ContainerName string
Command []string
IgnoreOutput bool
}
// Exec command in pod
func (c *Client) Exec(options *ExecOptions) interface{} {
logFields := logrus.WithFields(logrus.Fields{
"command": options.Command,
"podName": options.PodName,
"podNamespace": options.PodNamespace,
"container": options.ContainerName,
})
logFields.Infof("Exec command in pod")
request := c.CoreV1().RESTClient().Post().
Resource("pods").
Name(options.PodName).
Namespace(options.PodNamespace).
SubResource("exec").
VersionedParams(
&corev1.PodExecOptions{
Container: options.ContainerName,
Command: options.Command,
Stdin: options.Stdin,
Stdout: true,
Stderr: true,
TTY: options.TTY,
}, scheme.ParameterCodec,
)
output := bytes.NewBuffer([]byte{})
options.Out = output
errput := bytes.NewBuffer([]byte{})
options.ErrOut = errput
err := execute("POST", request.URL(), c.Config, options)
errMsg := strings.TrimSpace(errput.String())
outMsg := strings.TrimSpace(output.String())
execLog := logFields.WithFields(logrus.Fields{
"err": errMsg,
"out": outMsg,
})
if errMsg != "" {
execLog.Infof("get err message")
return options.ErrDecoder(errput.Bytes())
}
if err != nil {
execLog.WithError(err).Errorln("Invoke exec command error")
return options.ErrDecoder([]byte(err.Error()))
}
if outMsg != "" {
execLog.Infof("get output message")
return options.OutDecoder(output.Bytes())
}
if options.IgnoreOutput {
return nil
}
return options.ErrDecoder([]byte(fmt.Sprintf("cannot get output of pods/%s/exec, maybe kubelet cannot be accessed or container not found",
options.PodName)))
}
// "172.21.1.11:8080/api/v1/namespaces/default/pods/my-nginx-3855515330-l1uqk/exec
// ?container=my-nginx&stdin=1&stdout=1&stderr=1&tty=1&command=%2Fbin%2Fbash"
func execute(method string, url *url.URL, config *rest.Config, options *ExecOptions) error {
exec, err := remotecommand.NewSPDYExecutor(config, method, url)
if err != nil {
return err
}
return exec.Stream(remotecommand.StreamOptions{
Stdin: options.StreamOptions.In,
Stdout: options.StreamOptions.Out,
Stderr: options.StreamOptions.ErrOut,
Tty: options.StreamOptions.TTY,
})
}
================================================
FILE: channel/client_test.go
================================================
/*
* Copyright 2025 The ChaosBlade Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package channel
import (
"testing"
)
func TestClient_Exec(t *testing.T) {
// Skip this test as it requires a real Kubernetes cluster connection
t.Skip("Skipping TestClient_Exec: requires Kubernetes cluster connectivity")
}
================================================
FILE: cmd/hookfs/main.go
================================================
/*
* Copyright 2025 The ChaosBlade Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package main
import (
"context"
"flag"
"fmt"
"math/rand"
"os"
"os/exec"
"time"
"github.com/chaosblade-io/chaosblade-spec-go/util"
"github.com/ethercflow/hookfs/hookfs"
"github.com/sirupsen/logrus"
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
chaosbladehook "github.com/chaosblade-io/chaosblade-operator/pkg/hookfs"
)
var (
address string
pidFile string
original string
mountpoint string
)
func main() {
flag.StringVar(&address, "address", ":65534", "The address to bind")
flag.StringVar(&original, "original", "", "Mapping of the original disk, not affected by the drill")
flag.StringVar(&mountpoint, "mountpoint", "", "The disk of the drill. The affected directories are controlled by the path flag.")
rand.Seed(time.Now().UnixNano())
flag.Parse()
logFields := logrus.WithFields(logrus.Fields{
"address": address,
"original": original,
"mountpoint": mountpoint,
})
stopCtx := signals.SetupSignalHandler()
chaosbladeHookServer := chaosbladehook.NewChaosbladeHookServer(address)
logFields.Infoln("Start chaosblade hook server.")
go chaosbladeHookServer.Start(stopCtx)
logFields.Infoln("Start fuse server.")
if err := startFuseServer(stopCtx); err != nil {
logFields.WithError(err).Fatalln("Start fuse server failed")
}
}
// startFuseServer starts hookfs server
func startFuseServer(stop context.Context) error {
if !util.IsExist(original) {
if err := os.MkdirAll(original, os.FileMode(755)); err != nil {
return fmt.Errorf("create original directory error, %v", err)
}
}
if !util.IsExist(mountpoint) {
if err := os.MkdirAll(mountpoint, os.FileMode(755)); err != nil {
return fmt.Errorf("create mountpoint directory error, %v", err)
}
}
fs, err := hookfs.NewHookFs(original, mountpoint, &chaosbladehook.ChaosbladeHook{MountPoint: mountpoint})
if err != nil {
return fmt.Errorf("create hookfs error, %v", err)
}
errCh := make(chan error)
go func() {
errCh <- fs.Serve()
}()
for {
select {
case <-stop.Done():
logFields := logrus.WithFields(logrus.Fields{
"address": address,
"original": original,
"mountpoint": mountpoint,
})
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
cmd := exec.CommandContext(ctx, "fusermount", "-zu", mountpoint)
logFields.Infof("Start unmount fuse volume, cmd: %v", cmd)
if err := cmd.Run(); err != nil {
logFields.WithError(err).Errorln("Failed to execute fusermount")
}
return err
case err := <-errCh:
if err != nil {
return err
}
}
}
}
================================================
FILE: cmd/manager/main.go
================================================
/*
* Copyright 2025 The ChaosBlade Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package main
import (
"context"
"flag"
"net/http"
"runtime"
"strings"
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
"github.com/operator-framework/operator-sdk/pkg/leader"
"github.com/operator-framework/operator-sdk/pkg/log/zap"
sdkVersion "github.com/operator-framework/operator-sdk/version"
"github.com/sirupsen/logrus"
"github.com/spf13/pflag"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtimeutil "k8s.io/apimachinery/pkg/util/runtime"
"sigs.k8s.io/controller-runtime/pkg/webhook"
apiruntime "k8s.io/apimachinery/pkg/runtime"
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
_ "k8s.io/client-go/plugin/pkg/client/auth"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
"github.com/chaosblade-io/chaosblade-operator/channel"
"github.com/chaosblade-io/chaosblade-operator/pkg/apis"
"github.com/chaosblade-io/chaosblade-operator/pkg/controller"
operator "github.com/chaosblade-io/chaosblade-operator/pkg/runtime"
"github.com/chaosblade-io/chaosblade-operator/pkg/runtime/chaosblade"
webhookcfg "github.com/chaosblade-io/chaosblade-operator/pkg/webhook"
mutator "github.com/chaosblade-io/chaosblade-operator/pkg/webhook/pod"
"github.com/chaosblade-io/chaosblade-operator/version"
)
func printVersion() {
logrus.Infof("Go Version: %s", runtime.Version())
logrus.Infof("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)
logrus.Infof("Version of operator-sdk: %v", sdkVersion.Version)
logrus.Infof("Operator Version: %v", version.Version)
logrus.Infof("Operator Product: %v", version.Product)
logrus.Infof("Build Time: %v", version.BuildTime)
logrus.Infof("Git Commit: %v", version.GitCommit)
logrus.Infof("Git Branch: %v", version.GitBranch)
logrus.Infof("Platform: %v", version.Platform)
logrus.Infof("Daemonset Enable: %t", chaosblade.DaemonsetEnable)
}
func main() {
pflag.CommandLine.AddFlagSet(zap.FlagSet())
pflag.CommandLine.AddFlagSet(operator.FlagSet())
pflag.CommandLine.AddFlagSet(webhookcfg.FlagSet())
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
// 添加版本标志
showVersion := pflag.Bool("version", false, "显示版本信息")
pflag.Parse()
// 如果只是查看版本,则显示后退出
if *showVersion {
printVersion()
return
}
initLogger()
printVersion()
cfg, err := config.GetConfig()
if err != nil {
logrus.Fatalf("Get apiserver config error, %v", err)
}
err = leader.Become(context.Background(), "chaosblade-operator-lock")
if err != nil {
logrus.Fatalf("Become leader error, %v", err)
}
cfg.QPS = operator.QPS
mgr, err := createManager(cfg)
if err != nil {
logrus.Fatalf("Create operator manager error, %v", err)
}
addComponentsToManager(mgr)
logrus.Infoln("Starting the manager.")
if err := mgr.Start(signals.SetupSignalHandler()); err != nil {
logrus.Fatalf("Manager exited non-zero, %v", err)
}
}
func addComponentsToManager(mgr manager.Manager) {
logrus.Infof("Add all resources to scheme")
// Setup Scheme for all resources
if err := apis.AddToScheme(mgr.GetScheme()); err != nil {
logrus.Fatalf("Add all resources to scheme error, %v", err)
}
logrus.Infof("Add all controllers to manager")
// Setup all Controllers
if err := controller.AddToManager(mgr); err != nil {
logrus.Fatalf("Add all controllers to manager error, %v", err)
}
if webhookcfg.Enable {
logrus.Infof("Webhook enabled, add it to manager")
if err := addWebhook(mgr); err != nil {
logrus.Fatalf("Add webhook to manager error, %v", err)
}
}
}
// Init logrus and controller-runtime log
func initLogger() {
level, err := logrus.ParseLevel(operator.LogLevel)
if err != nil {
level = logrus.InfoLevel
}
logrus.SetLevel(level)
log.SetLogger(zap.Logger())
}
func addWebhook(m manager.Manager) error {
server := webhook.NewServer(webhook.Options{
Port: webhookcfg.Port,
})
if err := m.Add(server); err != nil {
return err
}
logrus.Infof("registering %s to the webhook server", "mutating-pods")
server.Register("/mutating-pods", &webhook.Admission{Handler: &mutator.Mutator{}})
return nil
}
// createManager supports multi namespaces configuration
func createManager(cfg *rest.Config) (manager.Manager, error) {
scheme := apiruntime.NewScheme()
runtimeutil.Must(metav1.AddMetaToScheme(scheme))
runtimeutil.Must(corev1.AddToScheme(scheme))
runtimeutil.Must(appsv1.AddToScheme(scheme))
runtimeutil.Must(apis.AddToScheme(scheme))
watchNamespace, err := k8sutil.GetWatchNamespace()
if err != nil {
return nil, err
}
logrus.Infof("Get watch namespace is %s", watchNamespace)
if strings.Contains(watchNamespace, ",") {
defaultNsps := make(map[string]cache.Config)
for _, nsp := range strings.Split(watchNamespace, ",") {
defaultNsps[nsp] = cache.Config{}
}
return manager.New(cfg, manager.Options{
Cache: cache.Options{
Scheme: scheme,
DefaultNamespaces: defaultNsps,
},
Scheme: scheme,
MapperProvider: func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) {
return apiutil.NewDynamicRESTMapper(c, httpClient)
},
NewClient: channel.NewClientFunc(),
})
}
return manager.New(cfg, manager.Options{
Cache: cache.Options{
Scheme: scheme,
DefaultNamespaces: map[string]cache.Config{watchNamespace: {}},
},
Scheme: scheme,
MapperProvider: func(c *rest.Config, httpClient *http.Client) (meta.RESTMapper, error) {
return apiutil.NewDynamicRESTMapper(c, httpClient)
},
NewClient: channel.NewClientFunc(),
})
}
================================================
FILE: deploy/crds/chaosblade.io_chaosblades_crd.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: chaosblades.chaosblade.io
spec:
group: chaosblade.io
names:
kind: ChaosBlade
listKind: ChaosBladeList
plural: chaosblades
singular: chaosblade
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: ChaosBlade is the Schema for the chaosblades API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: ChaosBladeSpec defines the desired state of ChaosBlade
properties:
experiments:
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
Important: Run "operator-sdk generate k8s" to regenerate code after
modifying this file Add custom validation using kubebuilder tags:
https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
items:
properties:
action:
description: Action is the experiment scenario of the target,
such as delay, load
type: string
desc:
description: Desc is the experiment description
type: string
matchers:
description: Matchers is the experiment rules
items:
properties:
name:
description: Name is the name of flag
type: string
value:
description: 'TODO: Temporarily defined as an array for
all flags Value is the value of flag'
items:
type: string
type: array
required:
- name
- value
type: object
type: array
scope:
description: Scope is the area of the experiments, currently support
node, pod and container
type: string
target:
description: Target is the experiment target, such as cpu, network
type: string
required:
- action
- scope
- target
type: object
type: array
required:
- experiments
type: object
status:
description: ChaosBladeStatus defines the observed state of ChaosBlade
properties:
expStatuses:
description: 'Important: Run "operator-sdk generate k8s" to regenerate
code after modifying this file Add custom validation using kubebuilder
tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
items:
properties:
action:
type: string
error:
type: string
resStatuses:
description: ResStatuses is the details of the experiment
items:
properties:
error:
description: experiment error
type: string
id:
description: experiment uid in chaosblade
type: string
identifier:
description: 'Resource identifier, rules as following: container:
Namespace/NodeName/PodName/ContainerName pod: Namespace/NodeName/PodName'
type: string
kind:
description: Kind
type: string
state:
description: experiment state
type: string
success:
description: success
type: boolean
required:
- kind
- state
- success
type: object
type: array
scope:
description: experiment scope for cache
type: string
state:
description: State is used to describe the experiment result
type: string
success:
description: Success is used to judge the experiment result
type: boolean
target:
type: string
required:
- action
- scope
- state
- success
- target
type: object
type: array
phase:
description: Phase indicates the state of the experiment Initial ->
Running -> Updating -> Destroying -> Destroyed
type: string
required:
- expStatuses
type: object
type: object
served: true
storage: true
subresources:
status: {}
================================================
FILE: deploy/helm/chaosblade-operator/.helmignore
================================================
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
================================================
FILE: deploy/helm/chaosblade-operator/Chart.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
appVersion: "1.8.0"
description: ChaosBlade Operator
name: chaosblade-operator
version: 1.8.0
home: https://github.com/chaosblade-io
================================================
FILE: deploy/helm/chaosblade-operator/crds/crd.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: chaosblades.chaosblade.io
spec:
group: chaosblade.io
names:
kind: ChaosBlade
listKind: ChaosBladeList
plural: chaosblades
singular: chaosblade
shortNames: [blade]
scope: Cluster
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: ChaosBlade is the Schema for the chaosblades API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: ChaosBladeSpec defines the desired state of ChaosBlade
properties:
experiments:
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
Important: Run "operator-sdk generate k8s" to regenerate code after
modifying this file Add custom validation using kubebuilder tags:
https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
items:
properties:
action:
description: Action is the experiment scenario of the target,
such as delay, load
type: string
desc:
description: Desc is the experiment description
type: string
matchers:
description: Matchers is the experiment rules
items:
properties:
name:
description: Name is the name of flag
type: string
value:
description: 'TODO: Temporarily defined as an array for
all flags Value is the value of flag'
items:
type: string
type: array
required:
- name
- value
type: object
type: array
scope:
description: Scope is the area of the experiments, currently support
node, pod and container
type: string
target:
description: Target is the experiment target, such as cpu, network
type: string
required:
- action
- scope
- target
type: object
type: array
required:
- experiments
type: object
status:
description: ChaosBladeStatus defines the observed state of ChaosBlade
properties:
expStatuses:
description: 'Important: Run "operator-sdk generate k8s" to regenerate
code after modifying this file Add custom validation using kubebuilder
tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
items:
properties:
action:
type: string
error:
type: string
resStatuses:
description: ResStatuses is the details of the experiment
items:
properties:
error:
description: experiment error
type: string
id:
description: experiment uid in chaosblade
type: string
identifier:
description: 'Resource identifier, rules as following: container:
Namespace/NodeName/PodName/ContainerName pod: Namespace/NodeName/PodName'
type: string
kind:
description: Kind
type: string
state:
description: experiment state
type: string
success:
description: success
type: boolean
required:
- kind
- state
- success
type: object
type: array
scope:
description: experiment scope for cache
type: string
state:
description: State is used to describe the experiment result
type: string
success:
description: Success is used to judge the experiment result
type: boolean
target:
type: string
required:
- action
- scope
- state
- success
- target
type: object
type: array
phase:
description: Phase indicates the state of the experiment Initial ->
Running -> Updating -> Destroying -> Destroyed
type: string
required:
- expStatuses
type: object
type: object
served: true
storage: true
subresources:
status: {}
================================================
FILE: deploy/helm/chaosblade-operator/templates/NOTES.txt
================================================
Thank you for using chaosblade.
================================================
FILE: deploy/helm/chaosblade-operator/templates/_helpers.tpl
================================================
{{/* vim: set filetype=mustache: */}}
================================================
FILE: deploy/helm/chaosblade-operator/templates/daemonset.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{{- if .Values.daemonset.enable }}
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: chaosblade-tool
labels:
name: chaosblade-tool
app: chaosblade-tool
spec:
selector:
matchLabels:
name: chaosblade-tool
app: chaosblade-tool
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
name: chaosblade-tool
app: chaosblade-tool
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: type
operator: NotIn
values:
- virtual-kubelet
containers:
- name: chaosblade-tool
image: {{ .Values.blade.repository }}:{{ .Values.blade.version }}
imagePullPolicy: {{ .Values.blade.pullPolicy }}
env:
- name: KUBERNETES_NODENAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: DOCKER_API_VERSION
value: "1.44"
- name: CGROUP_ROOT
value: "/host-sys/fs/cgroup/"
securityContext:
privileged: true
volumeMounts:
- mountPath: /var/run/docker.sock
name: docker-socket
- mountPath: /opt/chaosblade/chaosblade.dat
name: chaosblade-db-volume
- mountPath: /etc/hosts
name: hosts
- mountPath: /var/log/audit
name: audit
- mountPath: /var/lib/docker
name: docker-lib
- mountPath: /etc/docker
name: docker-etc
- mountPath: /run/containerd
name: containerd
- mountPath: /var/lib/containerd
name: containerd-lib
- mountPath: /etc/containerd
name: containerd-etc
- mountPath: /var/run/netns
name: netns
- mountPath: /host-sys
name: sys
dnsPolicy: ClusterFirstWithHostNet
hostNetwork: true
hostPID: true
tolerations:
- effect: NoSchedule
operator: Exists
volumes:
- hostPath:
path: /var/run/docker.sock
name: docker-socket
- hostPath:
path: /var/run/chaosblade.dat
type: FileOrCreate
name: chaosblade-db-volume
- hostPath:
path: /etc/hosts
name: hosts
- hostPath:
path: /var/lib/docker
name: docker-lib
- hostPath:
path: /etc/docker
name: docker-etc
- hostPath:
path: /var/log/audit
name: audit
- hostPath:
path: /run/containerd
name: containerd
- hostPath:
path: /var/lib/containerd
name: containerd-lib
- hostPath:
path: /etc/containerd
name: containerd-etc
- hostPath:
path: /var/run/netns
name: netns
- hostPath:
path: /sys
name: sys
serviceAccountName: chaosblade
{{- end }}
================================================
FILE: deploy/helm/chaosblade-operator/templates/deployment.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: chaosblade-operator
namespace: {{ .Release.Namespace }}
spec:
replicas: 1
selector:
matchLabels:
name: chaosblade-operator
template:
metadata:
labels:
name: chaosblade-operator
part-of: chaosblade
spec:
dnsPolicy: {{ .Values.network.dns.policy }}
hostNetwork: {{ .Values.network.host }}
serviceAccountName: chaosblade
initContainers:
- name: chaosblade-tool
image: {{ .Values.blade.repository }}:{{ .Values.blade.version }}
imagePullPolicy: {{ .Values.blade.pullPolicy }}
command: [ "cp", "-R","/opt/chaosblade", "/home" ]
volumeMounts:
- mountPath: /home
name: chaosblade
containers:
- name: chaosblade-operator
image: {{ .Values.operator.repository }}:{{ .Values.operator.version }}
command: ["chaosblade-operator"]
args:
{{- if .Values.blade.repository }}
- '--chaosblade-image-repository={{ .Values.blade.repository }}'
{{- end }}
{{- if .Values.blade.version }}
- '--chaosblade-version={{ .Values.blade.version }}'
{{- end }}
{{- if .Values.blade.pullPolicy }}
- '--chaosblade-image-pull-policy={{ .Values.blade.pullPolicy }}'
{{- end }}
{{- if .Values.env.zapLevel }}
- '--zap-level={{ .Values.env.zapLevel }}'
{{- end }}
{{- if .Values.env.logLevel }}
- '--log-level={{ .Values.env.logLevel }}'
{{- end }}
{{- if .Values.webhook.enable }}
- '--webhook-enable'
{{- end }}
{{- if .Values.daemonset.enable }}
- '--daemonset-enable'
{{- end }}
{{- if .Values.remove.blade.interval }}
- '--remove-blade-interval={{ .Values.remove.blade.interval }}'
{{- end }}
{{- if .Values.blade.downloadUrl }}
- '--chaosblade-download-url={{ .Values.blade.downloadUrl }}'
{{- end }}
- '--chaosblade-namespace={{ .Release.Namespace }}'
imagePullPolicy: {{ .Values.operator.pullPolicy }}
env:
- name: WATCH_NAMESPACE
value: ""
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: OPERATOR_NAME
value: "chaosblade-operator"
ports:
- containerPort: 9443
protocol: TCP
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
readOnly: true
- mountPath: /opt
name: chaosblade
volumes:
- name: cert
secret:
defaultMode: 420
secretName: chaosblade-webhook-server-cert
- name: chaosblade
emptyDir: {}
================================================
FILE: deploy/helm/chaosblade-operator/templates/rbac.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
name: chaosblade
labels:
name: chaosblade
namespace: {{ .Release.Namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: chaosblade
labels:
name: chaosblade
rules:
- apiGroups:
- ''
resources:
- pods
- pods/exec
- configmaps
- secrets
- services
- persistentvolumeclaims
- persistentvolumes
verbs:
- "*"
- apiGroups:
- ''
resources:
- nodes
verbs:
- get
- list
- watch
- update
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- statefulsets
verbs:
- "*"
- apiGroups:
- chaosblade.io
resources:
- chaosblades
- chaosblades/status
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: chaosblade
labels:
name: chaosblade
roleRef:
kind: ClusterRole
name: chaosblade
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: chaosblade
namespace: {{ .Release.Namespace }}
================================================
FILE: deploy/helm/chaosblade-operator/templates/secret.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{{- $ca := genCA "chaosblade-webhook-server-ca" 3650 }}
{{- $cn := "chaosblade-webhook-server" }}
{{- $dns1 := printf "%s.%s" $cn .Release.Namespace }}
{{- $dns2 := printf "%s.%s.svc" $cn .Release.Namespace }}
{{- $cert := genSignedCert $cn nil (list $dns1 $dns2) 3650 $ca }}
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: chaosblade-operator
namespace: {{ .Release.Namespace }}
labels:
app: chaosblade-operator
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
webhooks:
- clientConfig:
caBundle: {{ $ca.Cert | b64enc | quote }}
service:
name: chaosblade-webhook-server
namespace: {{ .Release.Namespace }}
path: /mutating-pods
name: "{{ .Chart.Name }}.{{ .Release.Namespace }}.svc"
failurePolicy: Ignore
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- pods
sideEffects: None
admissionReviewVersions: ["v1beta1"]
---
apiVersion: v1
kind: Secret
metadata:
name: chaosblade-webhook-server-cert
namespace: {{ .Release.Namespace }}
labels:
app: chaosblade-operator
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
type: kubernetes.io/tls
data:
tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }}
ca.crt: {{ $ca.Cert | b64enc | quote }}
================================================
FILE: deploy/helm/chaosblade-operator/templates/service.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Service
metadata:
name: chaosblade-webhook-server
namespace: {{ .Release.Namespace }}
spec:
ports:
- port: 443
targetPort: 9443
selector:
name: chaosblade-operator
================================================
FILE: deploy/helm/chaosblade-operator/values.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Default values for chaosblade.
# chaosblade-operator
operator:
repository: ghcr.io/chaosblade-io/chaosblade-operator
version: 1.8.0
# image.pullPolicy: must be Always|IfNotPresent|Never
pullPolicy: IfNotPresent
# qps of kubernetes client
qps: 20
reconcileCount: 20
blade:
repository: ghcr.io/chaosblade-io/chaosblade-tool
version: 1.8.0
pullPolicy: IfNotPresent
downloadUrl: ""
env:
logLevel: info
webhook:
enable: true
daemonset:
enable: true
remove:
blade:
interval: 72h
network:
host: false
dns:
policy: ClusterFirst
================================================
FILE: deploy/helm/chaosblade-operator-arm64/.helmignore
================================================
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
================================================
FILE: deploy/helm/chaosblade-operator-arm64/Chart.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
appVersion: "1.8.0"
description: ChaosBlade Operator
name: chaosblade-operator-arm64
version: 1.8.0
home: https://github.com/chaosblade-io
================================================
FILE: deploy/helm/chaosblade-operator-arm64/crds/crd.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: chaosblades.chaosblade.io
spec:
group: chaosblade.io
names:
kind: ChaosBlade
listKind: ChaosBladeList
plural: chaosblades
singular: chaosblade
shortNames: [blade]
scope: Cluster
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: ChaosBlade is the Schema for the chaosblades API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: ChaosBladeSpec defines the desired state of ChaosBlade
properties:
experiments:
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
Important: Run "operator-sdk generate k8s" to regenerate code after
modifying this file Add custom validation using kubebuilder tags:
https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
items:
properties:
action:
description: Action is the experiment scenario of the target,
such as delay, load
type: string
desc:
description: Desc is the experiment description
type: string
matchers:
description: Matchers is the experiment rules
items:
properties:
name:
description: Name is the name of flag
type: string
value:
description: 'TODO: Temporarily defined as an array for
all flags Value is the value of flag'
items:
type: string
type: array
required:
- name
- value
type: object
type: array
scope:
description: Scope is the area of the experiments, currently support
node, pod and container
type: string
target:
description: Target is the experiment target, such as cpu, network
type: string
required:
- action
- scope
- target
type: object
type: array
required:
- experiments
type: object
status:
description: ChaosBladeStatus defines the observed state of ChaosBlade
properties:
expStatuses:
description: 'Important: Run "operator-sdk generate k8s" to regenerate
code after modifying this file Add custom validation using kubebuilder
tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
items:
properties:
action:
type: string
error:
type: string
resStatuses:
description: ResStatuses is the details of the experiment
items:
properties:
error:
description: experiment error
type: string
id:
description: experiment uid in chaosblade
type: string
identifier:
description: 'Resource identifier, rules as following: container:
Namespace/NodeName/PodName/ContainerName pod: Namespace/NodeName/PodName'
type: string
kind:
description: Kind
type: string
state:
description: experiment state
type: string
success:
description: success
type: boolean
required:
- kind
- state
- success
type: object
type: array
scope:
description: experiment scope for cache
type: string
state:
description: State is used to describe the experiment result
type: string
success:
description: Success is used to judge the experiment result
type: boolean
target:
type: string
required:
- action
- scope
- state
- success
- target
type: object
type: array
phase:
description: Phase indicates the state of the experiment Initial ->
Running -> Updating -> Destroying -> Destroyed
type: string
required:
- expStatuses
type: object
type: object
served: true
storage: true
subresources:
status: {}
================================================
FILE: deploy/helm/chaosblade-operator-arm64/templates/NOTES.txt
================================================
Thank you for using chaosblade.
================================================
FILE: deploy/helm/chaosblade-operator-arm64/templates/_helpers.tpl
================================================
{{/* vim: set filetype=mustache: */}}
================================================
FILE: deploy/helm/chaosblade-operator-arm64/templates/daemonset.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{{- if .Values.daemonset.enable }}
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: chaosblade-tool
labels:
name: chaosblade-tool
app: chaosblade-tool
spec:
selector:
matchLabels:
name: chaosblade-tool
app: chaosblade-tool
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
name: chaosblade-tool
app: chaosblade-tool
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: type
operator: NotIn
values:
- virtual-kubelet
containers:
- name: chaosblade-tool
image: {{ .Values.blade.repository }}:{{ .Values.blade.version }}
imagePullPolicy: {{ .Values.blade.pullPolicy }}
env:
- name: KUBERNETES_NODENAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: DOCKER_API_VERSION
value: "1.14.0"
- name: CGROUP_ROOT
value: "/host-sys/fs/cgroup/"
securityContext:
privileged: true
volumeMounts:
- mountPath: /var/run/docker.sock
name: docker-socket
- mountPath: /opt/chaosblade/chaosblade.dat
name: chaosblade-db-volume
- mountPath: /etc/hosts
name: hosts
- mountPath: /var/log/audit
name: audit
- mountPath: /var/lib/docker
name: docker-lib
- mountPath: /etc/docker
name: docker-etc
- mountPath: /run/containerd
name: containerd
- mountPath: /var/lib/containerd
name: containerd-lib
- mountPath: /etc/containerd
name: containerd-etc
- mountPath: /var/run/netns
name: netns
- mountPath: /host-sys
name: sys
dnsPolicy: ClusterFirstWithHostNet
hostNetwork: true
hostPID: true
tolerations:
- effect: NoSchedule
operator: Exists
volumes:
- hostPath:
path: /var/run/docker.sock
name: docker-socket
- hostPath:
path: /var/run/chaosblade.dat
type: FileOrCreate
name: chaosblade-db-volume
- hostPath:
path: /etc/hosts
name: hosts
- hostPath:
path: /var/lib/docker
name: docker-lib
- hostPath:
path: /etc/docker
name: docker-etc
- hostPath:
path: /var/log/audit
name: audit
- hostPath:
path: /run/containerd
name: containerd
- hostPath:
path: /var/lib/containerd
name: containerd-lib
- hostPath:
path: /etc/containerd
name: containerd-etc
- hostPath:
path: /var/run/netns
name: netns
- hostPath:
path: /sys
name: sys
serviceAccountName: chaosblade
{{- end }}
================================================
FILE: deploy/helm/chaosblade-operator-arm64/templates/deployment.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apps/v1
kind: Deployment
metadata:
name: chaosblade-operator
namespace: {{ .Release.Namespace }}
spec:
replicas: 1
selector:
matchLabels:
name: chaosblade-operator
template:
metadata:
labels:
name: chaosblade-operator
part-of: chaosblade
spec:
dnsPolicy: {{ .Values.network.dns.policy }}
hostNetwork: {{ .Values.network.host }}
serviceAccountName: chaosblade
initContainers:
- name: chaosblade-tool
image: {{ .Values.blade.repository }}:{{ .Values.blade.version }}
imagePullPolicy: {{ .Values.blade.pullPolicy }}
command: [ "cp", "-R","/opt/chaosblade", "/home" ]
volumeMounts:
- mountPath: /home
name: chaosblade
containers:
- name: chaosblade-operator
image: {{ .Values.operator.repository }}:{{ .Values.operator.version }}
command: ["chaosblade-operator"]
args:
{{- if .Values.blade.repository }}
- '--chaosblade-image-repository={{ .Values.blade.repository }}'
{{- end }}
{{- if .Values.blade.version }}
- '--chaosblade-version={{ .Values.blade.version }}'
{{- end }}
{{- if .Values.blade.pullPolicy }}
- '--chaosblade-image-pull-policy={{ .Values.blade.pullPolicy }}'
{{- end }}
{{- if .Values.env.zapLevel }}
- '--zap-level={{ .Values.env.zapLevel }}'
{{- end }}
{{- if .Values.env.logLevel }}
- '--log-level={{ .Values.env.logLevel }}'
{{- end }}
{{- if .Values.webhook.enable }}
- '--webhook-enable'
{{- end }}
{{- if .Values.daemonset.enable }}
- '--daemonset-enable'
{{- end }}
{{- if .Values.remove.blade.interval }}
- '--remove-blade-interval={{ .Values.remove.blade.interval }}'
{{- end }}
{{- if .Values.blade.downloadUrl }}
- '--chaosblade-download-url={{ .Values.blade.downloadUrl }}'
{{- end }}
- '--chaosblade-namespace={{ .Release.Namespace }}'
imagePullPolicy: {{ .Values.operator.pullPolicy }}
env:
- name: WATCH_NAMESPACE
value: ""
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: OPERATOR_NAME
value: "chaosblade-operator"
ports:
- containerPort: 9443
protocol: TCP
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
readOnly: true
- mountPath: /opt
name: chaosblade
volumes:
- name: cert
secret:
defaultMode: 420
secretName: chaosblade-webhook-server-cert
- name: chaosblade
emptyDir: {}
================================================
FILE: deploy/helm/chaosblade-operator-arm64/templates/rbac.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: ServiceAccount
metadata:
name: chaosblade
labels:
name: chaosblade
namespace: {{ .Release.Namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: chaosblade
labels:
name: chaosblade
rules:
- apiGroups:
- ''
resources:
- pods
- pods/exec
- configmaps
- secrets
- services
- persistentvolumeclaims
- persistentvolumes
verbs:
- "*"
- apiGroups:
- ''
resources:
- nodes
verbs:
- get
- list
- watch
- update
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- statefulsets
verbs:
- "*"
- apiGroups:
- chaosblade.io
resources:
- chaosblades
- chaosblades/status
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: chaosblade
labels:
name: chaosblade
roleRef:
kind: ClusterRole
name: chaosblade
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: chaosblade
namespace: {{ .Release.Namespace }}
================================================
FILE: deploy/helm/chaosblade-operator-arm64/templates/secret.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{{- $ca := genCA "chaosblade-webhook-server-ca" 3650 }}
{{- $cn := "chaosblade-webhook-server" }}
{{- $dns1 := printf "%s.%s" $cn .Release.Namespace }}
{{- $dns2 := printf "%s.%s.svc" $cn .Release.Namespace }}
{{- $cert := genSignedCert $cn nil (list $dns1 $dns2) 3650 $ca }}
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: chaosblade-operator
namespace: {{ .Release.Namespace }}
labels:
app: chaosblade-operator
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
webhooks:
- clientConfig:
caBundle: {{ $ca.Cert | b64enc | quote }}
service:
name: chaosblade-webhook-server
namespace: {{ .Release.Namespace }}
path: /mutating-pods
name: "{{ .Chart.Name }}.{{ .Release.Namespace }}.svc"
failurePolicy: Ignore
rules:
- apiGroups:
- ""
apiVersions:
- v1
operations:
- CREATE
- UPDATE
resources:
- pods
sideEffects: None
admissionReviewVersions: ["v1beta1"]
---
apiVersion: v1
kind: Secret
metadata:
name: chaosblade-webhook-server-cert
namespace: {{ .Release.Namespace }}
labels:
app: chaosblade-operator
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
type: kubernetes.io/tls
data:
tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }}
ca.crt: {{ $ca.Cert | b64enc | quote }}
================================================
FILE: deploy/helm/chaosblade-operator-arm64/templates/service.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Service
metadata:
name: chaosblade-webhook-server
namespace: {{ .Release.Namespace }}
spec:
ports:
- port: 443
targetPort: 9443
selector:
name: chaosblade-operator
================================================
FILE: deploy/helm/chaosblade-operator-arm64/values.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Default values for chaosblade.
# chaosblade-operator
operator:
repository: ghcr.io/chaosblade-io/chaosblade-operator-arm64
version: 1.8.0
# image.pullPolicy: must be Always|IfNotPresent|Never
pullPolicy: IfNotPresent
# qps of kubernetes client
qps: 20
reconcileCount: 20
blade:
repository: ghcr.io/chaosblade-io/chaosblade-tool-arm64
version: 1.8.0
pullPolicy: IfNotPresent
downloadUrl: ""
env:
logLevel: info
webhook:
enable: true
daemonset:
enable: true
remove:
blade:
interval: 72h
network:
host: false
dns:
policy: ClusterFirst
================================================
FILE: deploy/olm/Makefile
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
.PHONY: build clean
BLADE_VERSION=0.6.0
# Build [OLM](https://github.com/operator-framework/operator-lifecycle-manager)
build:
operator-sdk olm-catalog gen-csv \
--operator-name chaosblade-operator \
--csv-version $(BLADE_VERSION) \
--update-crds --verbose
# Change `olm` keyword to `chaosblade-operator`
sed 's/olm/chaosblade-operator/g' deploy/olm-catalog/olm/olm.package.yaml \
> deploy/olm-catalog/chaosblade-operator/chaosblade-operator.package.yaml
rm -rf deploy/olm-catalog/olm
clean:
rm -rf deploy/olm-catalog
================================================
FILE: deploy/olm/deploy/crd.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: chaosblades.chaosblade.io
spec:
group: chaosblade.io
names:
kind: ChaosBlade
listKind: ChaosBladeList
plural: chaosblades
singular: chaosblade
shortNames: [blade]
scope: Cluster
subresources:
status: {}
validation:
openAPIV3Schema:
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
experiments:
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
Important: Run "operator-sdk generate k8s" to regenerate code after
modifying this file Add custom validation using kubebuilder tags:
https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
items:
properties:
action:
description: Action is the experiment scenario of the target,
such as delay, load
type: string
desc:
description: Desc is the experiment description
type: string
matchers:
description: Matchers is the experiment rules
items:
properties:
name:
description: Name is the name of flag
type: string
value:
description: 'TODO: Temporarily defined as an array for
all flags Value is the value of flag'
items:
type: string
type: array
required:
- name
- value
type: object
type: array
scope:
description: Scope is the area of the experiments, currently support
node, pod and container
type: string
target:
description: Target is the experiment target, such as cpu, network
type: string
required:
- scope
- target
- action
type: object
type: array
required:
- experiments
type: object
status:
properties:
expStatuses:
description: 'Important: Run "operator-sdk generate k8s" to regenerate
code after modifying this file Add custom validation using kubebuilder
tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
items:
properties:
action:
type: string
error:
type: string
resStatuses:
description: ResStatuses is the details of the experiment
items:
properties:
error:
description: experiment error
type: string
id:
description: experiment uid in chaosblade
type: string
kind:
description: Kind
type: string
name:
description: resource name
type: string
nodeName:
description: NodeName
type: string
state:
description: experiment state
type: string
success:
description: success
type: boolean
uid:
description: resource uid
type: string
required:
- state
- kind
- success
type: object
type: array
scope:
description: experiment scope for cache
type: string
state:
description: State is used to describe the experiment result
type: string
success:
description: Success is used to judge the experiment result
type: boolean
target:
type: string
required:
- scope
- target
- action
- success
- state
type: object
type: array
phase:
description: Phase indicates the state of the experiment Initial ->
Running -> Updating -> Destroying -> Destroyed
type: string
required:
- expStatuses
type: object
version: v1alpha1
versions:
- name: v1alpha1
served: true
storage: true
================================================
FILE: deploy/olm/deploy/crds/chaosblade_v1alpha1_chaosblade_crd.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: chaosblades.chaosblade.io
spec:
group: chaosblade.io
names:
kind: ChaosBlade
listKind: ChaosBladeList
plural: chaosblades
singular: chaosblade
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
experiments:
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
Important: Run "operator-sdk generate k8s" to regenerate code after
modifying this file Add custom validation using kubebuilder tags:
https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
items:
properties:
action:
description: Action is the experiment scenario of the target,
such as delay, load
type: string
desc:
description: Desc is the experiment description
type: string
matchers:
description: Matchers is the experiment rules
items:
properties:
name:
description: Name is the name of flag
type: string
value:
description: 'TODO: Temporarily defined as an array for
all flags Value is the value of flag'
items:
type: string
type: array
required:
- name
- value
type: object
type: array
scope:
description: Scope is the area of the experiments, currently support
node, pod and container
type: string
target:
description: Target is the experiment target, such as cpu, network
type: string
required:
- scope
- target
- action
type: object
type: array
required:
- experiments
type: object
status:
properties:
expStatuses:
description: 'Important: Run "operator-sdk generate k8s" to regenerate
code after modifying this file Add custom validation using kubebuilder
tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
items:
properties:
action:
type: string
error:
type: string
resStatuses:
description: ResStatuses is the details of the experiment
items:
properties:
error:
description: experiment error
type: string
id:
description: experiment uid in chaosblade
type: string
kind:
description: Kind
type: string
name:
description: resource name
type: string
nodeName:
description: NodeName
type: string
state:
description: experiment state
type: string
success:
description: success
type: boolean
uid:
description: resource uid
type: string
required:
- state
- kind
- success
type: object
type: array
scope:
description: experiment scope for cache
type: string
state:
description: State is used to describe the experiment result
type: string
success:
description: Success is used to judge the experiment result
type: boolean
target:
type: string
required:
- scope
- target
- action
- success
- state
type: object
type: array
phase:
description: Phase indicates the state of the experiment Initial ->
Running -> Updating -> Destroying -> Destroyed
type: string
required:
- expStatuses
type: object
version: v1alpha1
versions:
- name: v1alpha1
served: true
storage: true
================================================
FILE: deploy/olm/deploy/olm-catalog/chaosblade-operator/0.5.1/chaosblade-operator.v0.5.1.clusterserviceversion.yaml
================================================
# Copyright 2025 The ChaosBlade Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
annotations:
capabilities: Basic Install
categories: Chaos Engineering
containerImage: chaosbladeio/chaosblade-operator:0.5.1
createdAt: 2020-02-11T15:40:00Z
certified: "false"
support: chaosblade.io
repository: https://github.com/chaosblade-io/chaosblade-operator
description: A chaos engineering operator for cloud-native on Kubernetes environments.
alm-examples: |-
[
{
"apiVersion": "chaosblade.io/v1alpha1",
"kind": "ChaosBlade",
"metadata": {
"name": "delay-pod-network-by-names"
},
"spec": {
"experiments": [
{
"scope": "pod",
"target": "network",
"action": "delay",
"desc": "delay pod network by names",
"matchers": [
{
"name": "names",
"value": [
"redis-slave-674d68586-jnf7f"
]
},
{
"name": "namespace",
"value": [
"default"
]
},
{
"name": "local-port",
"value": [
"6379"
]
},
{
"name": "interface",
"value": [
"eth0"
]
},
{
"name": "time",
"value": [
"3000"
]
},
{
"name": "offset",
"value": [
"1000"
]
}
]
}
]
}
}
]
name: chaosblade-operator.v0.5.1
namespace: kube-system
spec:
apiservicedefinitions: {}
customresourcedefinitions:
owned:
- description: Chaos engineering experiment definition
displayName: ChaosBlade
kind: ChaosBlade
name: chaosblades.chaosblade.io
version: v1alpha1
description: >
## Introduction
Chaosblade Operator is a chaos experiments injection tool for cloud-native on kubernetes platform. By defining Kubernetes CRD to manage chaos experiments, each experiment has a very clear execution status. The tool has the characteristics of simple deployment, convenient execution, standardized implementation, and rich experiments. The chaos experimental model in chaosblade is well integrated with Kubernetes, which can realize the reuse of experiments such as basic resources, application services, and containers on the Kubernetes platform, which facilitates the expansion of resource experiments under Kubernetes, and can be executed uniformly through chaosblade cli tool.
## Supported experiments (continuously adding ...)
The current experimental scenarios involve resources including Node, Pod, and Container. The specific supported experimental scenarios are as follows:
* Node:
* CPU: specify CPU usage
* Network: specify network card, port, IP, etc. packet delay, packet loss, packet blocking, packet duplication, packet re-ordering, packet corruption, etc.
* Process: specify process Hang, kill process, etc.
* Disk: specify the directory disk occupation, disk IO read and write load, etc.
* Memory: specify memory usage
* Pod:
* Network: specify network card, port, IP, etc. packet delay, packet loss, packet blocking, packet duplication, packet re-ordering, packet corruption, etc.
* Disk: specify the directory disk occupation, disk IO read and write load, etc.
* Memory: specify memory usage
* Pod: kill pod
* Container:
* CPU: specify CPU usage
* Network: specify network card, port, IP, etc. packet delay, packet loss, packet blocking, packet duplication, packet re-ordering, packet corruption, etc.
* Process: specify process Hang, kill process, etc.
* Disk: specify the directory disk occupation, disk IO read and write load, etc.
* Memory: specify memory usage
* Container: remove container
## Install and uninstall
Chaosblade operator can be installed through kubectl or helm, the installation method is as follows:
Note: For the following `VERSION`, please use the latest version number instead
### Helm v2
* Download the latest `chaosblade-operator-VERSION-v2.tgz` package at [Release](https://github.com/chaosblade-io/chaosblade-operator/releases)
* Install using `helm install --namespace kube-system --name chaosblade-operator chaosblade-operator-VERSION-v2.tgz`
* Use `kubectl get pod -l part-of=chaosblade -n kube-system` to check the installation status of the Pod. If both are running, the installation was successful
* Use the following command to uninstall, pay attention to the execution order:
```shell script
kubectl delete crd chaosblades.chaosblade.io
helm del --purge chaosblade-operator
```
### Helm v3
* Download the latest `chaosblade-operator-VERSION-v3.tgz` package at [Release](https://github.com/chaosblade-io/chaosblade-operator/releases)
* Use `helm install chaosblade-operator chaosblade-operator-VERSION-v3.tgz --namespace kube-system` command to install
* Use `kubectl get pod -l part-of=chaosblade -n kube-system` to check the installation status of the Pod. If both are running, the installation was successful
* Use the following command to uninstall, pay attention to the execution order:
```shell script
kubectl delete crd chaosblades.chaosblade.io
helm uninstall chaosblade-operator -n kube-system
```
### Kubectl
* Download the latest `chaosblade-operator-yaml-VERSION.tar.gz` package at [Release](https://github.com/chaosblade-io/chaosblade-operator/releases)
* After decompression, execute `kubectl apply -f chaosblade-operator-yaml-VERSION/` installation
* Use `kubectl get pod -l part-of=chaosblade -n kube-system` to check the installation status of the Pod. If both are running, the installation was successful
* Use the following command to uninstall, pay attention to the execution order:
```shell script
kubectl delete crd chaosblades.chaosblade.io
kubectl delete -f chaosblade-operator-yaml-VERSION/
```
## How to use
You can run chaos experiments after installing the chaosblade operator. There are three ways to execute chaos experiments:
* By configuring yaml file, use kubectl to execute
* Executed using chaosblade cli tool
* Use Kubernetes API to execute by writing code
The following uses a specific case to illustrate the use of chaosblade-operator: simulate cn-hangzhou.192.168.0.205 node local port 40690 60% network packet loss.
### By configuring the yaml file, use kubectl to execute
```
apiVersion: chaosblade.io/v1alpha1
kind: ChaosBlade
metadata:
name: loss-node-network-by-names
spec:
experiments:
- scope: node
target: network
action: loss
desc: "node network loss"
matchers:
- name: names
value: ["cn-hangzhou.192.168.0.205"]
- name: percent
value: ["60"]
- name: interface
value: ["eth0"]
- name: local-port
value: ["40690"]
```
Execute experiment:
```
kubectl apply -f loss-node-network-by-names.yaml
```
Query the experimental status, the returned information is as follows (spec and other contents are omitted):
```
~ » kubectl get blade loss-node-network-by-names -o json
{
"apiVersion": "chaosblade.io/v1alpha1",
"kind": "ChaosBlade",
"metadata": {
"creationTimestamp": "2019-11-04T09:56:36Z",
"finalizers": [
"finalizer.chaosblade.io"
],
"generation": 1,
"name": "loss-node-network-by-names",
"resourceVersion": "9262302",
"selfLink": "/apis/chaosblade.io/v1alpha1/chaosblades/loss-node-network-by-names",
"uid": "63a926dd-fee9-11e9-b3be-00163e136d88"
},
"status": {
"expStatuses": [
{
"action": "loss",
"resStatuses": [
{
"id": "057acaa47ae69363",
"kind": "node",
"name": "cn-hangzhou.192.168.0.205",
"nodeName": "cn-hangzhou.192.168.0.205",
"state": "Success",
"success": true,
"uid": "e179b30d-df77-11e9-b3be-00163e136d88"
}
],
"scope": "node",
"state": "Success",
"success": true,
"target": "network"
}
],
"phase": "Running"
}
}
```
From the above, you can clearly see the running status of the chaos experiment. Run the following command to stop the experiment:
```
kubectl delete -f loss-node-network-by-names.yaml
```
Or delete this blade resource directly:
```
kubectl delete blade loss-node-network-by-names
```
You can also edit the yaml file to update the content of the experiment and the chaosblade operator will complete the update of the experiment. See more examples: [Examples](https://github.com/chaosblade-io/chaosblade-operator/tree/master/examples)
### Execute with chaosblade cli tool
```
blade create k8s node-network loss --percent 60 --interface eth0 --local-port 40690 --names cn-hangzhou.192.168.0.205 --kubeconfig config
```
If the execution fails, a detailed error message is returned; if the execution is successful, the experiment UID is returned:
```
{"code":200,"success":true,"result":"e647064f5f20953c"}
```
You can query the status of the experiment with the following command:
```
blade query k8s create e647064f5f20953c --kubeconfig config
{
"code": 200,
"success": true,
"result": {
"uid": "e647064f5f20953c",
"success": true,
"error": "",
"statuses": [
{
"id": "fa471a6285ec45f5",
"uid": "e179b30d-df77-11e9-b3be-00163e136d88",
"name": "cn-hangzhou.192.168.0.205",
"state": "Success",
"kind": "node",
"success": true,
"nodeName": "cn-hangzhou.192.168.0.205"
}
]
}
}
```
Destroy experiment:
```
blade destroy e647064f5f20953c
```
In addition to the above two methods, you can also use the kubernetes client-go api for execution. For details, please refer to: [executor.go](https://github.com/chaosblade-io/chaosblade/blob/master/exec/kubernetes/executor.go) code implementation.
[Chinese documentation](https://chaosblade-io.gitbook.io/chaosblade-help-zh-cn/blade-create-k8s)
## Questions & Suggestions
If you encounter problems during installation and use, or suggestions and new features, all projects (including other projects) can be submitted to [Github Issues](https://github.com/chaosblade-io/chaosblade/issues)
You can also contact us via:
* Dingding group: 23177705
* Gitter room: [chaosblade community](https://gitter.im/chaosblade-io/community)
* Email: chaosblade.io.01@gmail.com
* Twitter: [chaosblade.io](https://twitter.com/ChaosbladeI)
## Contributions
We welcome every issue and PR. Even a punctuation mark, how to participate in the contribution please read the project contributing document, or contact us through the above method.
## Open source license
Chaosblade-operator is licensed under the Apache 2.0 license.
displayName: Chaosblade Operator
icon:
- base64data: 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**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
gitextract_bd7o2tq4/
├── .gitattributes
├── .github/
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── issue_template.md
│ └── workflows/
│ ├── ci.yml
│ └── release.yml
├── .gitignore
├── BUILD.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── README_CN.md
├── build/
│ ├── bin/
│ │ ├── entrypoint
│ │ └── user_setup
│ ├── image/
│ │ ├── amd/
│ │ │ └── Dockerfile
│ │ └── arm/
│ │ └── Dockerfile
│ ├── musl/
│ │ └── Dockerfile
│ └── spec.go
├── channel/
│ ├── client.go
│ └── client_test.go
├── cmd/
│ ├── hookfs/
│ │ └── main.go
│ └── manager/
│ └── main.go
├── deploy/
│ ├── crds/
│ │ └── chaosblade.io_chaosblades_crd.yaml
│ ├── helm/
│ │ ├── chaosblade-operator/
│ │ │ ├── .helmignore
│ │ │ ├── Chart.yaml
│ │ │ ├── crds/
│ │ │ │ └── crd.yaml
│ │ │ ├── templates/
│ │ │ │ ├── NOTES.txt
│ │ │ │ ├── _helpers.tpl
│ │ │ │ ├── daemonset.yaml
│ │ │ │ ├── deployment.yaml
│ │ │ │ ├── rbac.yaml
│ │ │ │ ├── secret.yaml
│ │ │ │ └── service.yaml
│ │ │ └── values.yaml
│ │ └── chaosblade-operator-arm64/
│ │ ├── .helmignore
│ │ ├── Chart.yaml
│ │ ├── crds/
│ │ │ └── crd.yaml
│ │ ├── templates/
│ │ │ ├── NOTES.txt
│ │ │ ├── _helpers.tpl
│ │ │ ├── daemonset.yaml
│ │ │ ├── deployment.yaml
│ │ │ ├── rbac.yaml
│ │ │ ├── secret.yaml
│ │ │ └── service.yaml
│ │ └── values.yaml
│ ├── olm/
│ │ ├── Makefile
│ │ └── deploy/
│ │ ├── crd.yaml
│ │ ├── crds/
│ │ │ └── chaosblade_v1alpha1_chaosblade_crd.yaml
│ │ ├── olm-catalog/
│ │ │ └── chaosblade-operator/
│ │ │ ├── 0.5.1/
│ │ │ │ ├── chaosblade-operator.v0.5.1.clusterserviceversion.yaml
│ │ │ │ └── chaosblade_v1alpha1_chaosblade_crd.yaml
│ │ │ ├── 0.6.0/
│ │ │ │ ├── chaosblade-operator.v0.6.0.clusterserviceversion.yaml
│ │ │ │ └── chaosblade_v1alpha1_chaosblade_crd.yaml
│ │ │ └── chaosblade-operator.package.yaml
│ │ ├── operator.yaml
│ │ ├── role.yaml
│ │ ├── role_binding.yaml
│ │ └── service_account.yaml
│ └── oss/
│ ├── crd.yaml
│ ├── operator.yaml
│ ├── rbac.yaml
│ ├── service.yaml
│ └── webhook-cert-job.yaml
├── examples/
│ ├── create_services_in_batch.yaml
│ ├── delay_pod_network_by_names.yaml
│ ├── delete_pod_by_labels.yaml
│ ├── delete_pod_by_names.yaml
│ ├── fail_pod_by_labels.yaml
│ ├── increase_container_cpu_load_by_id.yaml
│ ├── kill_container_process_by_id.yaml
│ ├── modify_service_traffic_policy.yaml
│ ├── node-cpu-load.yml
│ ├── node-disk-load-burn-read.yml
│ ├── node-disk-load-burn-write.yml
│ ├── node-disk-load-fill.yml
│ ├── node-mem-load.yml
│ ├── node-network-delay-by-names.yml
│ ├── node-network-loss-by-names.yml
│ ├── pod-bad-resource-size-cpu-mem.yaml
│ ├── pod-bad-resource-size-cpu.yaml
│ ├── pod-bad-resource-size-mem.yaml
│ ├── pod-configmap-delete.yaml
│ ├── pod-containercreating-by-pvc-error.yaml
│ ├── pod-containercreating-disk.yaml
│ ├── pod-cpu-load-by-names.yml
│ ├── pod-delete_by_names.yaml
│ ├── pod-failedmount-configmap.yaml
│ ├── pod-failedmount-pvc.yaml
│ ├── pod-failedmount-secret.yaml
│ ├── pod-imagepullsecretserror-by-auth-corruption.yaml
│ ├── pod-scheduling-failure.yaml
│ ├── pod-taint-node.yaml
│ ├── pod-terminating-by-finalizer.yaml
│ ├── remove_container_by_id.yaml
│ ├── tamper_container_dns_by_id.yaml
│ └── test-configmap-delete.yaml
├── exec/
│ ├── container/
│ │ ├── application.go
│ │ ├── container.go
│ │ └── controller.go
│ ├── controller.go
│ ├── model/
│ │ ├── category.go
│ │ ├── context.go
│ │ ├── controller.go
│ │ ├── controller_test.go
│ │ ├── copy.go
│ │ ├── deploy.go
│ │ ├── download.go
│ │ ├── executor.go
│ │ ├── executor_copy.go
│ │ ├── executor_nsexec.go
│ │ ├── filter.go
│ │ ├── filter_pod.go
│ │ ├── filter_pod_test.go
│ │ ├── model.go
│ │ ├── osexp.go
│ │ └── parallelizer.go
│ ├── node/
│ │ ├── cniexp.go
│ │ ├── controller.go
│ │ ├── exec_helper.go
│ │ ├── filter.go
│ │ └── node.go
│ ├── pod/
│ │ ├── badresourcesize.go
│ │ ├── configmapdeleteexp.go
│ │ ├── configmapdeleteexp_test.go
│ │ ├── containercreating.go
│ │ ├── containercreatingdisk.go
│ │ ├── containercreatingdisk_test.go
│ │ ├── controller.go
│ │ ├── delete.go
│ │ ├── failedmount.go
│ │ ├── failexp.go
│ │ ├── fsexp.go
│ │ ├── imageconfigexp.go
│ │ ├── imageconfigexp_test.go
│ │ ├── imagepullsecretserror.go
│ │ ├── imagepullsecretserror_test.go
│ │ ├── pod.go
│ │ ├── schedulingfailure.go
│ │ ├── taintnode.go
│ │ ├── taintnode_test.go
│ │ └── terminating.go
│ └── service/
│ ├── controller.go
│ ├── create.go
│ ├── modify.go
│ └── service.go
├── go.mod
├── go.sum
├── hack/
│ ├── init.sh
│ ├── update-gofmt.sh
│ ├── update-imports.sh
│ ├── verify-gofmt.sh
│ └── verify-imports.sh
├── licenserc.toml
├── pkg/
│ ├── apis/
│ │ ├── addtoscheme_chaosblade_v1alpha1.go
│ │ ├── apis.go
│ │ └── chaosblade/
│ │ ├── group.go
│ │ └── v1alpha1/
│ │ ├── doc.go
│ │ ├── register.go
│ │ ├── types.go
│ │ └── zz_generated.deepcopy.go
│ ├── controller/
│ │ ├── add_chaosblade.go
│ │ ├── chaosblade/
│ │ │ ├── controller.go
│ │ │ ├── daemonset.go
│ │ │ └── predicate.go
│ │ └── controller.go
│ ├── hookfs/
│ │ ├── client.go
│ │ ├── hook.go
│ │ ├── server.go
│ │ └── types.go
│ ├── runtime/
│ │ ├── chaosblade/
│ │ │ └── chaosblade.go
│ │ ├── product/
│ │ │ ├── aliyun/
│ │ │ │ └── aliyun.go
│ │ │ └── community/
│ │ │ └── community.go
│ │ └── runtime.go
│ └── webhook/
│ ├── pod/
│ │ ├── mutator.go
│ │ └── mutator_test.go
│ └── webhook.go
├── scripts/
│ ├── show-version.sh
│ └── version.sh
└── version/
└── version.go
SYMBOL INDEX (803 symbols across 74 files)
FILE: build/spec.go
function main (line 33) | func main() {
function getModels (line 46) | func getModels() *spec.Models {
FILE: channel/client.go
type Client (line 37) | type Client struct
method Exec (line 82) | func (c *Client) Exec(options *ExecOptions) interface{} {
function NewClientFunc (line 44) | func NewClientFunc() client.NewClientFunc {
type IOStreams (line 58) | type IOStreams struct
type StreamOptions (line 64) | type StreamOptions struct
type ExecOptions (line 72) | type ExecOptions struct
function execute (line 138) | func execute(method string, url *url.URL, config *rest.Config, options *...
FILE: channel/client_test.go
function TestClient_Exec (line 23) | func TestClient_Exec(t *testing.T) {
FILE: cmd/hookfs/main.go
function main (line 43) | func main() {
function startFuseServer (line 67) | func startFuseServer(stop context.Context) error {
FILE: cmd/manager/main.go
function printVersion (line 60) | func printVersion() {
function main (line 73) | func main() {
function addComponentsToManager (line 112) | func addComponentsToManager(mgr manager.Manager) {
function initLogger (line 132) | func initLogger() {
function addWebhook (line 141) | func addWebhook(m manager.Manager) error {
function createManager (line 154) | func createManager(cfg *rest.Config) (manager.Manager, error) {
FILE: exec/container/application.go
function getJvmModels (line 34) | func getJvmModels() []spec.ExpModelCommandSpec {
FILE: exec/container/container.go
type ResourceModelSpec (line 38) | type ResourceModelSpec struct
function NewResourceModelSpec (line 43) | func NewResourceModelSpec(client *channel.Client) model.ResourceExpModel...
function addActionExamples (line 69) | func addActionExamples(modelSpec *ResourceModelSpec) {
function getResourceFlags (line 305) | func getResourceFlags() []spec.ExpFlagSpec {
FILE: exec/container/controller.go
type ExpController (line 37) | type ExpController struct
method Name (line 50) | func (*ExpController) Name() string {
method Create (line 55) | func (e *ExpController) Create(ctx context.Context, expSpec v1alpha1.E...
method Destroy (line 103) | func (e *ExpController) Destroy(ctx context.Context, expSpec v1alpha1....
function NewExpController (line 41) | func NewExpController(client *channel.Client) model.ExperimentController {
function getMatchedContainerMetaList (line 128) | func getMatchedContainerMetaList(pods []v1.Pod, containerIdsValue, conta...
FILE: exec/controller.go
type ResourceDispatchedController (line 36) | type ResourceDispatchedController struct
method Name (line 61) | func (e *ResourceDispatchedController) Name() string {
method Create (line 65) | func (e *ResourceDispatchedController) Create(bladeName string, expSpe...
method Destroy (line 84) | func (e *ResourceDispatchedController) Destroy(bladeName string, expSp...
method register (line 145) | func (e *ResourceDispatchedController) register(cs ...model.Experiment...
function NewDispatcherExecutor (line 46) | func NewDispatcherExecutor(client *channel.Client) *ResourceDispatchedCo...
function validateAndSetNecessaryFields (line 107) | func validateAndSetNecessaryFields(status v1alpha1.ExperimentStatus, old...
function createExperimentStatusByResponse (line 131) | func createExperimentStatusByResponse(response *spec.Response) v1alpha1....
FILE: exec/model/category.go
constant CategorySystemContainer (line 19) | CategorySystemContainer = "system_container"
FILE: exec/model/context.go
constant ContainerObjectMetaListKey (line 28) | ContainerObjectMetaListKey = "ContainerObjectMetaListKey"
constant ExperimentIdKey (line 29) | ExperimentIdKey = "ExperimentIdKey"
type ContainerObjectMeta (line 32) | type ContainerObjectMeta struct
method GetIdentifier (line 75) | func (c *ContainerObjectMeta) GetIdentifier() string {
type ContainerMatchedList (line 43) | type ContainerMatchedList
function GetExperimentIdFromContext (line 46) | func GetExperimentIdFromContext(ctx context.Context) string {
function SetExperimentIdToContext (line 55) | func SetExperimentIdToContext(ctx context.Context, experimentId string) ...
function GetContainerObjectMetaListFromContext (line 60) | func GetContainerObjectMetaListFromContext(ctx context.Context) (Contain...
function SetContainerObjectMetaListToContext (line 70) | func SetContainerObjectMetaListToContext(ctx context.Context, containerM...
function ParseIdentifier (line 90) | func ParseIdentifier(identifier string) ContainerObjectMeta {
FILE: exec/model/controller.go
type ExpController (line 34) | type ExpController interface
type ExperimentController (line 43) | type ExperimentController interface
type BaseExperimentController (line 52) | type BaseExperimentController struct
method Destroy (line 57) | func (b *BaseExperimentController) Destroy(ctx context.Context, expSpe...
method Exec (line 63) | func (b *BaseExperimentController) Exec(ctx context.Context, expModel ...
function ExtractExpModelFromExperimentSpec (line 87) | func ExtractExpModelFromExperimentSpec(experimentSpec v1alpha1.Experimen...
function GetResourceCount (line 102) | func GetResourceCount(resourceCount int, flags map[string]string) (int, ...
function CreateDestroyedStatus (line 142) | func CreateDestroyedStatus(oldExpStatus v1alpha1.ExperimentStatus) v1alp...
FILE: exec/model/controller_test.go
function TestGetResourceCount (line 23) | func TestGetResourceCount(t *testing.T) {
FILE: exec/model/copy.go
type CopyOptions (line 36) | type CopyOptions struct
method execute (line 126) | func (o *CopyOptions) execute(options *channel.ExecOptions) error {
method DeployToPod (line 141) | func (o *CopyOptions) DeployToPod(experimentId, src, dest string) error {
function makeTar (line 40) | func makeTar(srcPath, destPath string, writer io.Writer) error {
function recursiveTar (line 50) | func recursiveTar(srcBase, srcFile, destBase, destFile string, tw *tar.W...
FILE: exec/model/deploy.go
type DeployMode (line 25) | type DeployMode interface
type DeployOptions (line 29) | type DeployOptions struct
method CheckFileExists (line 37) | func (o *DeployOptions) CheckFileExists(dest string) error {
method CreateDir (line 59) | func (o *DeployOptions) CreateDir(dir string) error {
FILE: exec/model/download.go
constant bin (line 41) | bin = "bin"
constant blade (line 42) | blade = "blade"
constant lib (line 43) | lib = "lib.tar.gz"
constant yaml (line 44) | yaml = "yaml.tar.gz"
type DownloadOptions (line 47) | type DownloadOptions struct
method DeployToPod (line 52) | func (d *DownloadOptions) DeployToPod(experimentId, src, dest string) ...
method uncompress (line 102) | func (d *DownloadOptions) uncompress(experimentId, file string) error {
method getUrl (line 136) | func (d *DownloadOptions) getUrl(srcFile string) string {
FILE: exec/model/executor.go
function checkExperimentStatus (line 45) | func checkExperimentStatus(ctx context.Context, expModel *spec.ExpModel,...
function execCommands (line 154) | func execCommands(isDestroy bool, rsStatus v1alpha1.ResourceStatus,
function generateDestroyCommands (line 203) | func generateDestroyCommands(experimentId string, expModel *spec.ExpModel,
function generateCreateCommands (line 227) | func generateCreateCommands(experimentId string, expModel *spec.ExpModel...
function GetChaosBladeDaemonsetPodName (line 249) | func GetChaosBladeDaemonsetPodName(nodeName string, client *channel.Clie...
function refreshChaosBladeDaemonsetPodNames (line 273) | func refreshChaosBladeDaemonsetPodNames(client *channel.Client) error {
function getNodeExperimentIdentifiers (line 290) | func getNodeExperimentIdentifiers(experimentId string, expModel *spec.Ex...
function generateDestroyNodeCommands (line 297) | func generateDestroyNodeCommands(experimentId string, expModel *spec.Exp...
function generateCreateNodeCommands (line 323) | func generateCreateNodeCommands(experimentId string, expModel *spec.ExpM...
function getTargetChaosBladePath (line 346) | func getTargetChaosBladePath(expModel *spec.ExpModel) string {
function getTargetChaosBladeBin (line 355) | func getTargetChaosBladeBin(expModel *spec.ExpModel) string {
function ExcludeKeyFunc (line 359) | func ExcludeKeyFunc() func() map[string]spec.Empty {
function TruncateContainerObjectMetaUid (line 363) | func TruncateContainerObjectMetaUid(uid string) (containerRuntime, conta...
function getDeployMode (line 371) | func getDeployMode(options DeployOptions, expModel *spec.ExpModel) (Depl...
FILE: exec/model/executor_copy.go
type ExperimentIdentifierInPod (line 39) | type ExperimentIdentifierInPod struct
type ExecCommandInPodExecutor (line 50) | type ExecCommandInPodExecutor struct
method Name (line 54) | func (e *ExecCommandInPodExecutor) Name() string {
method SetChannel (line 58) | func (e *ExecCommandInPodExecutor) SetChannel(channel spec.Channel) {
method Exec (line 62) | func (e *ExecCommandInPodExecutor) Exec(uid string, ctx context.Contex...
function getExperimentIdentifiers (line 150) | func getExperimentIdentifiers(ctx context.Context, expModel *spec.ExpMod...
function getDockerExperimentIdentifiers (line 181) | func getDockerExperimentIdentifiers(experimentId string, expModel *spec....
function getCriExperimentIdentifiers (line 194) | func getCriExperimentIdentifiers(experimentId string, expModel *spec.Exp...
function generateDestroyDockerCommands (line 207) | func generateDestroyDockerCommands(experimentId string, expModel *spec.E...
function generateCreateDockerCommands (line 245) | func generateCreateDockerCommands(experimentId string, expModel *spec.Ex...
function generateDestroyCriCommands (line 271) | func generateDestroyCriCommands(
function generateCreateCriCommands (line 304) | func generateCreateCriCommands(experimentId string, expModel *spec.ExpMo...
function deployChaosBlade (line 331) | func deployChaosBlade(experimentId string, expModel *spec.ExpModel,
function getNewContainerIdByPod (line 407) | func getNewContainerIdByPod(podName, podNamespace, containerName, experi...
FILE: exec/model/executor_nsexec.go
type CommonExecutor (line 37) | type CommonExecutor struct
method Name (line 41) | func (e *CommonExecutor) Name() string {
method SetChannel (line 45) | func (e *CommonExecutor) SetChannel(channel spec.Channel) {
method Exec (line 48) | func (e *CommonExecutor) Exec(uid string, ctx context.Context, expMode...
function getExperimentIdentifiersWithNsexec (line 136) | func getExperimentIdentifiersWithNsexec(ctx context.Context, expModel *s...
FILE: exec/model/filter.go
function GetOneAvailableContainerIdFromPod (line 30) | func GetOneAvailableContainerIdFromPod(pod v1.Pod) (containerId, contain...
function ParseLabels (line 45) | func ParseLabels(labels string) []pkglabels.Requirement {
function MapContains (line 79) | func MapContains(bigMap map[string]string, requirements []pkglabels.Requ...
function CheckFlags (line 92) | func CheckFlags(flags map[string]string) *spec.Response {
FILE: exec/model/filter_pod.go
constant DefaultNamespace (line 35) | DefaultNamespace = "default"
function CheckPodFlags (line 37) | func CheckPodFlags(flags map[string]string) *spec.Response {
method GetMatchedPodResources (line 50) | func (b *BaseExperimentController) GetMatchedPodResources(ctx context.Co...
method filterByOtherFlags (line 65) | func (b *BaseExperimentController) filterByOtherFlags(pods []v1.Pod, fla...
function randomPodSelected (line 170) | func randomPodSelected(pods []v1.Pod, count int) []v1.Pod {
FILE: exec/model/filter_pod_test.go
function Test_randomSelected (line 27) | func Test_randomSelected(t *testing.T) {
FILE: exec/model/model.go
type ActionPreProcessor (line 32) | type ActionPreProcessor interface
type ResourceExpModelSpec (line 46) | type ResourceExpModelSpec interface
function NewBaseResourceExpModelSpec (line 53) | func NewBaseResourceExpModelSpec(scopeName string, client *channel.Clien...
type BaseResourceExpModelSpec (line 61) | type BaseResourceExpModelSpec struct
method Scope (line 67) | func (b *BaseResourceExpModelSpec) Scope() string {
method ExpModels (line 71) | func (b *BaseResourceExpModelSpec) ExpModels() map[string]spec.ExpMode...
method GetExpActionModelSpec (line 75) | func (b *BaseResourceExpModelSpec) GetExpActionModelSpec(target, actio...
method RegisterExpModels (line 97) | func (b *BaseResourceExpModelSpec) RegisterExpModels(expModel ...spec....
type SubResourceExpModelSpec (line 104) | type SubResourceExpModelSpec interface
type BaseSubResourceExpModelSpec (line 110) | type BaseSubResourceExpModelSpec struct
method ExpModels (line 115) | func (b *BaseSubResourceExpModelSpec) ExpModels() []spec.ExpModelComma...
method Executor (line 119) | func (b *BaseSubResourceExpModelSpec) Executor() spec.Executor {
function GetResourceCoverageFlags (line 137) | func GetResourceCoverageFlags() []spec.ExpFlagSpec {
function GetNetworkFlags (line 225) | func GetNetworkFlags() []spec.ExpFlagSpec {
function GetContainerFlags (line 232) | func GetContainerFlags() []spec.ExpFlagSpec {
function GetResourceCommonFlags (line 240) | func GetResourceCommonFlags() []spec.ExpFlagSpec {
function GetChaosBladeFlags (line 249) | func GetChaosBladeFlags() []spec.ExpFlagSpec {
function GetResourceFlagNames (line 258) | func GetResourceFlagNames() map[string]spec.Empty {
FILE: exec/model/osexp.go
type OSSubResourceModelSpec (line 30) | type OSSubResourceModelSpec struct
function NewOSSubResourceModelSpec (line 34) | func NewOSSubResourceModelSpec() SubResourceExpModelSpec {
FILE: exec/model/parallelizer.go
constant maxWorkers (line 22) | maxWorkers = 64
type DoWorkFunc (line 25) | type DoWorkFunc
function ParallelizeExec (line 27) | func ParallelizeExec(workCount int, doWork DoWorkFunc) {
FILE: exec/node/cniexp.go
constant CniBinPathFlag (line 36) | CniBinPathFlag = "cni-bin-path"
constant CniErrorMsgFlag (line 37) | CniErrorMsgFlag = "error-msg"
function NewCniExpModelCommandSpec (line 40) | func NewCniExpModelCommandSpec(client *channel.Client) spec.ExpModelComm...
type CniExpModelCommandSpec (line 52) | type CniExpModelCommandSpec struct
method Name (line 56) | func (*CniExpModelCommandSpec) Name() string {
method ShortDesc (line 60) | func (*CniExpModelCommandSpec) ShortDesc() string {
method LongDesc (line 64) | func (*CniExpModelCommandSpec) LongDesc() string {
method Example (line 68) | func (*CniExpModelCommandSpec) Example() string {
function NewCniAddFaultActionSpec (line 77) | func NewCniAddFaultActionSpec(client *channel.Client) spec.ExpActionComm...
type CniAddFaultActionSpec (line 104) | type CniAddFaultActionSpec struct
method Name (line 108) | func (*CniAddFaultActionSpec) Name() string {
method Aliases (line 112) | func (*CniAddFaultActionSpec) Aliases() []string {
method ShortDesc (line 116) | func (*CniAddFaultActionSpec) ShortDesc() string {
method LongDesc (line 120) | func (*CniAddFaultActionSpec) LongDesc() string {
function NewCniDelFaultActionSpec (line 126) | func NewCniDelFaultActionSpec(client *channel.Client) spec.ExpActionComm...
type CniDelFaultActionSpec (line 151) | type CniDelFaultActionSpec struct
method Name (line 155) | func (*CniDelFaultActionSpec) Name() string {
method Aliases (line 159) | func (*CniDelFaultActionSpec) Aliases() []string {
method ShortDesc (line 163) | func (*CniDelFaultActionSpec) ShortDesc() string {
method LongDesc (line 167) | func (*CniDelFaultActionSpec) LongDesc() string {
type CniFaultExecutor (line 173) | type CniFaultExecutor struct
method Name (line 178) | func (e *CniFaultExecutor) Name() string {
method SetChannel (line 182) | func (e *CniFaultExecutor) SetChannel(channel spec.Channel) {
method Exec (line 185) | func (e *CniFaultExecutor) Exec(uid string, ctx context.Context, expMo...
method create (line 192) | func (e *CniFaultExecutor) create(uid string, ctx context.Context, exp...
method destroy (line 282) | func (e *CniFaultExecutor) destroy(uid string, ctx context.Context, ex...
function generateCniCreateScript (line 368) | func generateCniCreateScript(cniBinPath string, cniCommand string, error...
function generateCniDiscoverScript (line 429) | func generateCniDiscoverScript() string {
function discoverCniBinPath (line 494) | func discoverCniBinPath(client *channel.Client, daemonsetPodName string)...
function generateCniDestroyScript (line 507) | func generateCniDestroyScript(cniBinPath string) string {
FILE: exec/node/controller.go
type ExpController (line 31) | type ExpController struct
method Name (line 44) | func (*ExpController) Name() string {
method Create (line 48) | func (e *ExpController) Create(ctx context.Context, expSpec v1alpha1.E...
method Destroy (line 65) | func (e *ExpController) Destroy(ctx context.Context, expSpec v1alpha1....
function NewExpController (line 35) | func NewExpController(client *channel.Client) model.ExperimentController {
function getContainerMatchedList (line 86) | func getContainerMatchedList(nodes []v1.Node) model.ContainerMatchedList {
FILE: exec/node/exec_helper.go
function execScriptInDaemonsetPod (line 31) | func execScriptInDaemonsetPod(client *channel.Client, podName string, sc...
FILE: exec/node/filter.go
method getMatchedNodeResources (line 34) | func (e *ExpController) getMatchedNodeResources(ctx context.Context, exp...
method filterByOtherFlags (line 46) | func (e *ExpController) filterByOtherFlags(nodes []v1.Node, flags map[st...
FILE: exec/node/node.go
type ResourceModelSpec (line 38) | type ResourceModelSpec struct
function NewResourceModelSpec (line 42) | func NewResourceModelSpec(client *channel.Client) model.ResourceExpModel...
function addActionExamples (line 63) | func addActionExamples(modelSpec *ResourceModelSpec) {
function getResourceFlags (line 437) | func getResourceFlags() []spec.ExpFlagSpec {
function NewSelfExpModelCommandSpec (line 442) | func NewSelfExpModelCommandSpec() spec.ExpModelCommandSpec {
type SelfExpModelCommandSpec (line 454) | type SelfExpModelCommandSpec struct
method Name (line 458) | func (*SelfExpModelCommandSpec) Name() string {
method ShortDesc (line 462) | func (*SelfExpModelCommandSpec) ShortDesc() string {
method LongDesc (line 466) | func (*SelfExpModelCommandSpec) LongDesc() string {
method Example (line 470) | func (*SelfExpModelCommandSpec) Example() string {
FILE: exec/pod/badresourcesize.go
constant BadResourceSizeCPUFlag (line 41) | BadResourceSizeCPUFlag = "cpu"
constant BadResourceSizeMemFlag (line 42) | BadResourceSizeMemFlag = "mem"
constant ChaosBladeOriginalResourcesAnnotation (line 44) | ChaosBladeOriginalResourcesAnnotation = "chaosblade.io/original-resources"
constant ChaosBladeBadResourceSizeAction (line 45) | ChaosBladeBadResourceSizeAction = "badresourcesize"
type BadResourceSizeActionSpec (line 48) | type BadResourceSizeActionSpec struct
method Name (line 102) | func (*BadResourceSizeActionSpec) Name() string {
method Aliases (line 106) | func (*BadResourceSizeActionSpec) Aliases() []string {
method ShortDesc (line 110) | func (*BadResourceSizeActionSpec) ShortDesc() string {
method LongDesc (line 114) | func (*BadResourceSizeActionSpec) LongDesc() string {
method PreCreate (line 123) | func (a *BadResourceSizeActionSpec) PreCreate(ctx context.Context, exp...
method PreDestroy (line 159) | func (a *BadResourceSizeActionSpec) PreDestroy(ctx context.Context, ex...
function NewBadResourceSizeActionSpec (line 53) | func NewBadResourceSizeActionSpec(client *channel.Client) spec.ExpAction...
type BadResourceSizeActionExecutor (line 188) | type BadResourceSizeActionExecutor struct
method Name (line 192) | func (*BadResourceSizeActionExecutor) Name() string {
method SetChannel (line 196) | func (*BadResourceSizeActionExecutor) SetChannel(channel spec.Channel) {}
method Exec (line 198) | func (d *BadResourceSizeActionExecutor) Exec(uid string, ctx context.C...
method create (line 205) | func (d *BadResourceSizeActionExecutor) create(uid string, ctx context...
method destroy (line 315) | func (d *BadResourceSizeActionExecutor) destroy(uid string, ctx contex...
method injectDeploymentBadResourceSize (line 532) | func (d *BadResourceSizeActionExecutor) injectDeploymentBadResourceSiz...
method injectDaemonSetBadResourceSize (line 552) | func (d *BadResourceSizeActionExecutor) injectDaemonSetBadResourceSize...
method injectStatefulSetBadResourceSize (line 572) | func (d *BadResourceSizeActionExecutor) injectStatefulSetBadResourceSi...
method restoreDeploymentResources (line 592) | func (d *BadResourceSizeActionExecutor) restoreDeploymentResources(ctx...
method restoreDaemonSetResources (line 608) | func (d *BadResourceSizeActionExecutor) restoreDaemonSetResources(ctx ...
method restoreStatefulSetResources (line 624) | func (d *BadResourceSizeActionExecutor) restoreStatefulSetResources(ct...
type containerResourcesBackup (line 383) | type containerResourcesBackup struct
function buildResourceLimits (line 391) | func buildResourceLimits(cpuVal, memVal string) (v1.ResourceList, error) {
function normalizeMemoryValue (line 414) | func normalizeMemoryValue(val string) string {
function backupAndInjectResources (line 442) | func backupAndInjectResources(podSpec *v1.PodSpec, annotations map[strin...
function restoreResources (line 480) | func restoreResources(podSpec *v1.PodSpec, annotations map[string]string...
FILE: exec/pod/configmapdeleteexp.go
constant ConfigMapNameFlag (line 41) | ConfigMapNameFlag = "configmap-name"
constant ChaosBladeExperimentLabel (line 43) | ChaosBladeExperimentLabel = "chaosblade.io/experiment-id"
constant ChaosBladeBackupLabel (line 44) | ChaosBladeBackupLabel = "chaosblade.io/backup"
constant ChaosBladeOriginalNameAnn (line 45) | ChaosBladeOriginalNameAnn = "chaosblade.io/original-name"
constant ChaosBladeOriginalNamespaceAnn (line 46) | ChaosBladeOriginalNamespaceAnn = "chaosblade.io/original-namespace"
constant ChaosBladeOriginalLabelsAnn (line 47) | ChaosBladeOriginalLabelsAnn = "chaosblade.io/original-labels"
constant ChaosBladeOriginalAnnsAnn (line 48) | ChaosBladeOriginalAnnsAnn = "chaosblade.io/original-annotations"
type ConfigMapDeleteActionSpec (line 51) | type ConfigMapDeleteActionSpec struct
method Name (line 77) | func (*ConfigMapDeleteActionSpec) Name() string {
method Aliases (line 81) | func (*ConfigMapDeleteActionSpec) Aliases() []string {
method ShortDesc (line 85) | func (*ConfigMapDeleteActionSpec) ShortDesc() string {
method LongDesc (line 89) | func (*ConfigMapDeleteActionSpec) LongDesc() string {
function NewConfigMapDeleteActionSpec (line 55) | func NewConfigMapDeleteActionSpec(client *channel.Client) spec.ExpAction...
type ConfigMapDeleteActionExecutor (line 94) | type ConfigMapDeleteActionExecutor struct
method Name (line 98) | func (*ConfigMapDeleteActionExecutor) Name() string {
method SetChannel (line 102) | func (*ConfigMapDeleteActionExecutor) SetChannel(channel spec.Channel) {}
method Exec (line 104) | func (d *ConfigMapDeleteActionExecutor) Exec(uid string, ctx context.C...
method create (line 112) | func (d *ConfigMapDeleteActionExecutor) create(ctx context.Context, ex...
method destroy (line 247) | func (d *ConfigMapDeleteActionExecutor) destroy(ctx context.Context, e...
method createBackupConfigMap (line 352) | func (d *ConfigMapDeleteActionExecutor) createBackupConfigMap(ctx cont...
method restoreConfigMapFromBackup (line 404) | func (d *ConfigMapDeleteActionExecutor) restoreConfigMapFromBackup(ctx...
method deleteBackupConfigMap (line 447) | func (d *ConfigMapDeleteActionExecutor) deleteBackupConfigMap(ctx cont...
method restoreAndCleanupBackup (line 456) | func (d *ConfigMapDeleteActionExecutor) restoreAndCleanupBackup(ctx co...
type ConfigMapRef (line 469) | type ConfigMapRef struct
function collectConfigMapReferences (line 478) | func collectConfigMapReferences(pod *v1.Pod) []ConfigMapRef {
function resolveTargetConfigMap (line 524) | func resolveTargetConfigMap(pod *v1.Pod, userSpecifiedName string) (stri...
function isOptional (line 553) | func isOptional(opt *bool) bool {
function getBackupConfigMapName (line 559) | func getBackupConfigMapName(experimentId, namespace, cmName string) stri...
function copyStringMap (line 571) | func copyStringMap(src map[string]string) map[string]string {
function copyByteMap (line 582) | func copyByteMap(src map[string][]byte) map[string][]byte {
FILE: exec/pod/configmapdeleteexp_test.go
function boolPtr (line 28) | func boolPtr(b bool) *bool {
function TestCollectConfigMapReferences (line 32) | func TestCollectConfigMapReferences(t *testing.T) {
function TestResolveTargetConfigMap (line 272) | func TestResolveTargetConfigMap(t *testing.T) {
function TestGetBackupConfigMapName (line 463) | func TestGetBackupConfigMapName(t *testing.T) {
function TestIsOptional (line 548) | func TestIsOptional(t *testing.T) {
function TestCopyStringMap (line 569) | func TestCopyStringMap(t *testing.T) {
function TestCopyByteMap (line 606) | func TestCopyByteMap(t *testing.T) {
FILE: exec/pod/containercreating.go
constant ChaosBladePVAnnotation (line 42) | ChaosBladePVAnnotation = "chaosblade.io/pv"
constant ChaosBladePVCAnnotation (line 44) | ChaosBladePVCAnnotation = "chaosblade.io/pvc"
constant ChaosBladePodAnnotation (line 46) | ChaosBladePodAnnotation = "chaosblade.io/pod"
constant ChaosBladeExperimentAnnotation (line 48) | ChaosBladeExperimentAnnotation = "chaosblade.io/experiment"
constant ChaosBladeActionCreate (line 50) | ChaosBladeActionCreate = "create"
type PodContainerCreatingActionSpec (line 53) | type PodContainerCreatingActionSpec struct
method Name (line 81) | func (*PodContainerCreatingActionSpec) Name() string {
method Aliases (line 85) | func (*PodContainerCreatingActionSpec) Aliases() []string {
method ShortDesc (line 89) | func (*PodContainerCreatingActionSpec) ShortDesc() string {
method LongDesc (line 93) | func (*PodContainerCreatingActionSpec) LongDesc() string {
method PreCreate (line 508) | func (a *PodContainerCreatingActionSpec) PreCreate(ctx context.Context...
method PreDestroy (line 533) | func (a *PodContainerCreatingActionSpec) PreDestroy(ctx context.Contex...
function NewPodContainerCreatingActionSpec (line 58) | func NewPodContainerCreatingActionSpec(client *channel.Client) spec.ExpA...
type PodContainerCreatingActionExecutor (line 101) | type PodContainerCreatingActionExecutor struct
method Name (line 105) | func (*PodContainerCreatingActionExecutor) Name() string {
method SetChannel (line 109) | func (*PodContainerCreatingActionExecutor) SetChannel(channel spec.Cha...
method Exec (line 111) | func (d *PodContainerCreatingActionExecutor) Exec(uid string, ctx cont...
method create (line 118) | func (d *PodContainerCreatingActionExecutor) create(uid string, ctx co...
method destroy (line 257) | func (d *PodContainerCreatingActionExecutor) destroy(uid string, ctx c...
method createPV (line 347) | func (d *PodContainerCreatingActionExecutor) createPV(ctx context.Cont...
method createPVC (line 380) | func (d *PodContainerCreatingActionExecutor) createPVC(ctx context.Con...
method createPod (line 409) | func (d *PodContainerCreatingActionExecutor) createPod(ctx context.Con...
method deletePod (line 458) | func (d *PodContainerCreatingActionExecutor) deletePod(ctx context.Con...
method deletePVC (line 469) | func (d *PodContainerCreatingActionExecutor) deletePVC(ctx context.Con...
method waitForPVCBound (line 480) | func (d *PodContainerCreatingActionExecutor) waitForPVCBound(ctx conte...
method deletePV (line 497) | func (d *PodContainerCreatingActionExecutor) deletePV(ctx context.Cont...
FILE: exec/pod/containercreatingdisk.go
type PodContainerCreatingDiskActionSpec (line 43) | type PodContainerCreatingDiskActionSpec struct
method Name (line 82) | func (*PodContainerCreatingDiskActionSpec) Name() string {
method Aliases (line 86) | func (*PodContainerCreatingDiskActionSpec) Aliases() []string {
method ShortDesc (line 90) | func (*PodContainerCreatingDiskActionSpec) ShortDesc() string {
method LongDesc (line 94) | func (*PodContainerCreatingDiskActionSpec) LongDesc() string {
method PreCreate (line 394) | func (a *PodContainerCreatingDiskActionSpec) PreCreate(ctx context.Con...
method PreDestroy (line 433) | func (a *PodContainerCreatingDiskActionSpec) PreDestroy(ctx context.Co...
function NewPodContainerCreatingDiskActionSpec (line 48) | func NewPodContainerCreatingDiskActionSpec(client *channel.Client) spec....
type PodContainerCreatingDiskActionExecutor (line 104) | type PodContainerCreatingDiskActionExecutor struct
method Name (line 108) | func (*PodContainerCreatingDiskActionExecutor) Name() string {
method SetChannel (line 112) | func (*PodContainerCreatingDiskActionExecutor) SetChannel(channel spec...
method Exec (line 114) | func (d *PodContainerCreatingDiskActionExecutor) Exec(uid string, ctx ...
method create (line 121) | func (d *PodContainerCreatingDiskActionExecutor) create(uid string, ct...
method destroy (line 223) | func (d *PodContainerCreatingDiskActionExecutor) destroy(uid string, c...
method createPVC (line 297) | func (d *PodContainerCreatingDiskActionExecutor) createPVC(ctx context...
method createPod (line 325) | func (d *PodContainerCreatingDiskActionExecutor) createPod(ctx context...
method deletePod (line 370) | func (d *PodContainerCreatingDiskActionExecutor) deletePod(ctx context...
method deletePVC (line 381) | func (d *PodContainerCreatingDiskActionExecutor) deletePVC(ctx context...
FILE: exec/pod/containercreatingdisk_test.go
function TestPodContainerCreatingDiskActionSpec_Name (line 29) | func TestPodContainerCreatingDiskActionSpec_Name(t *testing.T) {
function TestPodContainerCreatingDiskActionSpec_ShortDesc (line 36) | func TestPodContainerCreatingDiskActionSpec_ShortDesc(t *testing.T) {
function TestPodContainerCreatingDiskActionSpec_LongDesc (line 43) | func TestPodContainerCreatingDiskActionSpec_LongDesc(t *testing.T) {
function TestPodContainerCreatingDiskActionSpec_Aliases (line 50) | func TestPodContainerCreatingDiskActionSpec_Aliases(t *testing.T) {
function TestPodContainerCreatingDiskActionSpec_ActionFlags (line 57) | func TestPodContainerCreatingDiskActionSpec_ActionFlags(t *testing.T) {
function TestPodContainerCreatingDiskActionSpec_ActionCategories (line 79) | func TestPodContainerCreatingDiskActionSpec_ActionCategories(t *testing....
function TestPodContainerCreatingDiskActionSpec_ActionExample (line 94) | func TestPodContainerCreatingDiskActionSpec_ActionExample(t *testing.T) {
function TestPodContainerCreatingDiskActionExecutor_Name (line 102) | func TestPodContainerCreatingDiskActionExecutor_Name(t *testing.T) {
function TestPreCreate_NamespaceEmpty (line 109) | func TestPreCreate_NamespaceEmpty(t *testing.T) {
function TestPreCreate_NamespaceWithComma (line 131) | func TestPreCreate_NamespaceWithComma(t *testing.T) {
function TestPreCreate_StorageClassEmpty (line 153) | func TestPreCreate_StorageClassEmpty(t *testing.T) {
function TestPreCreate_Success (line 175) | func TestPreCreate_Success(t *testing.T) {
function TestPreDestroy_Success (line 205) | func TestPreDestroy_Success(t *testing.T) {
function TestPreDestroy_NamespaceEmpty (line 235) | func TestPreDestroy_NamespaceEmpty(t *testing.T) {
function TestPreCreate_PVCapacityInvalid (line 257) | func TestPreCreate_PVCapacityInvalid(t *testing.T) {
function TestPreCreate_PVCapacityValid (line 280) | func TestPreCreate_PVCapacityValid(t *testing.T) {
FILE: exec/pod/controller.go
type ExpController (line 32) | type ExpController struct
method Name (line 45) | func (*ExpController) Name() string {
method Create (line 50) | func (e *ExpController) Create(ctx context.Context, expSpec v1alpha1.E...
method Destroy (line 86) | func (e *ExpController) Destroy(ctx context.Context, expSpec v1alpha1....
function NewExpController (line 36) | func NewExpController(client *channel.Client) model.ExperimentController {
function getContainerMatchedList (line 126) | func getContainerMatchedList(experimentId string, pods []v1.Pod) model.C...
FILE: exec/pod/delete.go
type DeletePodActionSpec (line 34) | type DeletePodActionSpec struct
method Name (line 57) | func (*DeletePodActionSpec) Name() string {
method Aliases (line 61) | func (*DeletePodActionSpec) Aliases() []string {
method ShortDesc (line 65) | func (*DeletePodActionSpec) ShortDesc() string {
method LongDesc (line 69) | func (*DeletePodActionSpec) LongDesc() string {
function NewDeletePodActionSpec (line 38) | func NewDeletePodActionSpec(client *channel.Client) spec.ExpActionComman...
type DeletePodActionExecutor (line 73) | type DeletePodActionExecutor struct
method Name (line 77) | func (*DeletePodActionExecutor) Name() string {
method SetChannel (line 81) | func (*DeletePodActionExecutor) SetChannel(channel spec.Channel) {
method Exec (line 84) | func (d *DeletePodActionExecutor) Exec(uid string, ctx context.Context...
method create (line 92) | func (d *DeletePodActionExecutor) create(uid string, ctx context.Conte...
method destroy (line 127) | func (d *DeletePodActionExecutor) destroy(uid string, ctx context.Cont...
FILE: exec/pod/failedmount.go
constant ChaosBladeFailedMountAction (line 42) | ChaosBladeFailedMountAction = "failedmount"
constant ChaosBladeOriginalVolumesAnnotation (line 43) | ChaosBladeOriginalVolumesAnnotation = "chaosblade.io/original-volumes"
constant ChaosBladeFailedMountVolumeNamePrefix (line 44) | ChaosBladeFailedMountVolumeNamePrefix = "chaosblade-fm-"
constant ChaosBladeFailedMountVolumeMountPath (line 45) | ChaosBladeFailedMountVolumeMountPath = "/chaosblade-fm-nonexistent"
constant FailedMountVolumeTypeConfigMap (line 47) | FailedMountVolumeTypeConfigMap = "configmap"
constant FailedMountVolumeTypeSecret (line 48) | FailedMountVolumeTypeSecret = "secret"
constant FailedMountVolumeTypePVC (line 49) | FailedMountVolumeTypePVC = "pvc"
type FailedMountActionSpec (line 52) | type FailedMountActionSpec struct
method Name (line 101) | func (*FailedMountActionSpec) Name() string {
method Aliases (line 105) | func (*FailedMountActionSpec) Aliases() []string {
method ShortDesc (line 109) | func (*FailedMountActionSpec) ShortDesc() string {
method LongDesc (line 113) | func (*FailedMountActionSpec) LongDesc() string {
method PreCreate (line 121) | func (a *FailedMountActionSpec) PreCreate(ctx context.Context, expMode...
method PreDestroy (line 160) | func (a *FailedMountActionSpec) PreDestroy(ctx context.Context, expMod...
function NewFailedMountActionSpec (line 57) | func NewFailedMountActionSpec(client *channel.Client) spec.ExpActionComm...
type FailedMountActionExecutor (line 189) | type FailedMountActionExecutor struct
method Name (line 193) | func (*FailedMountActionExecutor) Name() string {
method SetChannel (line 197) | func (*FailedMountActionExecutor) SetChannel(channel spec.Channel) {}
method Exec (line 199) | func (d *FailedMountActionExecutor) Exec(uid string, ctx context.Conte...
method create (line 206) | func (d *FailedMountActionExecutor) create(uid string, ctx context.Con...
method destroy (line 315) | func (d *FailedMountActionExecutor) destroy(uid string, ctx context.Co...
method injectDeploymentFailedMount (line 552) | func (d *FailedMountActionExecutor) injectDeploymentFailedMount(ctx co...
method restoreDeploymentVolumes (line 572) | func (d *FailedMountActionExecutor) restoreDeploymentVolumes(ctx conte...
method injectDaemonSetFailedMount (line 590) | func (d *FailedMountActionExecutor) injectDaemonSetFailedMount(ctx con...
method restoreDaemonSetVolumes (line 610) | func (d *FailedMountActionExecutor) restoreDaemonSetVolumes(ctx contex...
method injectStatefulSetFailedMount (line 628) | func (d *FailedMountActionExecutor) injectStatefulSetFailedMount(ctx c...
method restoreStatefulSetVolumes (line 648) | func (d *FailedMountActionExecutor) restoreStatefulSetVolumes(ctx cont...
type volumeBackup (line 382) | type volumeBackup struct
function generateRandomHash (line 389) | func generateRandomHash() string {
function buildFailedMountVolume (line 398) | func buildFailedMountVolume(volumeName, volumeType string) v1.Volume {
function injectFailedMountVolume (line 427) | func injectFailedMountVolume(podSpec *v1.PodSpec, annotations map[string...
function removeInjectedVolume (line 472) | func removeInjectedVolume(podSpec *v1.PodSpec, backup *volumeBackup) err...
function validateVolumeType (line 515) | func validateVolumeType(vol *v1.Volume, expectedType string) error {
function restoreVolumeFromAnnotation (line 536) | func restoreVolumeFromAnnotation(podSpec *v1.PodSpec, annotations map[st...
FILE: exec/pod/failexp.go
type FailPodActionSpec (line 34) | type FailPodActionSpec struct
method Name (line 54) | func (*FailPodActionSpec) Name() string {
method Aliases (line 58) | func (*FailPodActionSpec) Aliases() []string {
method ShortDesc (line 62) | func (*FailPodActionSpec) ShortDesc() string {
method LongDesc (line 66) | func (*FailPodActionSpec) LongDesc() string {
function NewFailPodActionSpec (line 38) | func NewFailPodActionSpec(client *channel.Client) spec.ExpActionCommandS...
type FailPodActionExecutor (line 70) | type FailPodActionExecutor struct
method Name (line 74) | func (*FailPodActionExecutor) Name() string {
method SetChannel (line 78) | func (*FailPodActionExecutor) SetChannel(channel spec.Channel) {
method Exec (line 81) | func (d *FailPodActionExecutor) Exec(uid string, ctx context.Context, ...
method create (line 89) | func (d *FailPodActionExecutor) create(ctx context.Context, expModel *...
method destroy (line 138) | func (d *FailPodActionExecutor) destroy(ctx context.Context, expModel ...
method failPod (line 175) | func (d *FailPodActionExecutor) failPod(ctx context.Context, pod *v1.P...
function isAnnotationExist (line 194) | func isAnnotationExist(annotation map[string]string, key string) bool {
FILE: exec/pod/fsexp.go
type PodIOActionSpec (line 38) | type PodIOActionSpec struct
method Name (line 82) | func (*PodIOActionSpec) Name() string {
method Aliases (line 86) | func (*PodIOActionSpec) Aliases() []string {
method ShortDesc (line 90) | func (*PodIOActionSpec) ShortDesc() string {
method LongDesc (line 94) | func (*PodIOActionSpec) LongDesc() string {
function NewPodIOActionSpec (line 42) | func NewPodIOActionSpec(client *channel.Client) spec.ExpActionCommandSpec {
type PodIOActionExecutor (line 98) | type PodIOActionExecutor struct
method Name (line 102) | func (*PodIOActionExecutor) Name() string {
method SetChannel (line 106) | func (*PodIOActionExecutor) SetChannel(channel spec.Channel) {
method Exec (line 109) | func (d *PodIOActionExecutor) Exec(uid string, ctx context.Context, mo...
method create (line 117) | func (d *PodIOActionExecutor) create(ctx context.Context, expModel *sp...
method destroy (line 234) | func (d *PodIOActionExecutor) destroy(ctx context.Context, expModel *s...
function isPodReady (line 282) | func isPodReady(pod *v1.Pod) bool {
function getChaosfsClient (line 295) | func getChaosfsClient(pod *v1.Pod) (*chaosfs.ChaosBladeHookClient, error) {
function getContainerPort (line 304) | func getContainerPort(portName string, pod *v1.Pod) (int32, error) {
FILE: exec/pod/imageconfigexp.go
type ImageConfigActionSpec (line 35) | type ImageConfigActionSpec struct
method Name (line 76) | func (*ImageConfigActionSpec) Name() string {
method Aliases (line 80) | func (*ImageConfigActionSpec) Aliases() []string {
method ShortDesc (line 84) | func (*ImageConfigActionSpec) ShortDesc() string {
method LongDesc (line 88) | func (*ImageConfigActionSpec) LongDesc() string {
constant ImageNameFlag (line 40) | ImageNameFlag = "image-name"
constant ImageTagFlag (line 41) | ImageTagFlag = "image-tag"
function NewImageConfigActionSpec (line 44) | func NewImageConfigActionSpec(client *channel.Client) spec.ExpActionComm...
type ImageConfigActionExecutor (line 92) | type ImageConfigActionExecutor struct
method Name (line 96) | func (*ImageConfigActionExecutor) Name() string {
method SetChannel (line 100) | func (*ImageConfigActionExecutor) SetChannel(channel spec.Channel) {}
method Exec (line 102) | func (d *ImageConfigActionExecutor) Exec(uid string, ctx context.Conte...
method create (line 109) | func (d *ImageConfigActionExecutor) create(ctx context.Context, expMod...
method destroy (line 162) | func (d *ImageConfigActionExecutor) destroy(ctx context.Context, expMo...
method modifyPodImage (line 206) | func (d *ImageConfigActionExecutor) modifyPodImage(ctx context.Context...
function buildNewImage (line 229) | func buildNewImage(originalImage, imageName, imageTag string) string {
function parseImage (line 252) | func parseImage(image string) (name, tag string) {
function isImageConfigAnnotationExist (line 265) | func isImageConfigAnnotationExist(annotation map[string]string, key stri...
function isImageConfigPodReady (line 274) | func isImageConfigPodReady(pod *v1.Pod) bool {
FILE: exec/pod/imageconfigexp_test.go
function TestParseImage (line 23) | func TestParseImage(t *testing.T) {
function TestBuildNewImage (line 53) | func TestBuildNewImage(t *testing.T) {
function TestIsImageConfigAnnotationExist (line 174) | func TestIsImageConfigAnnotationExist(t *testing.T) {
FILE: exec/pod/imagepullsecretserror.go
constant ChaosBladeIPSBackupAnnotation (line 44) | ChaosBladeIPSBackupAnnotation = "chaosblade.io/ips-backup"
constant ChaosBladeIPSOriginalNameAnnotation (line 46) | ChaosBladeIPSOriginalNameAnnotation = "chaosblade.io/ips-original-name"
constant ChaosBladeIPSOriginalNamespaceAnnotation (line 48) | ChaosBladeIPSOriginalNamespaceAnnotation = "chaosblade.io/ips-original-n...
constant ChaosBladeIPSExperimentLabel (line 50) | ChaosBladeIPSExperimentLabel = "chaosblade.io/experiment"
type ImagePullSecretsErrorActionSpec (line 53) | type ImagePullSecretsErrorActionSpec struct
method Name (line 82) | func (*ImagePullSecretsErrorActionSpec) Name() string {
method Aliases (line 86) | func (*ImagePullSecretsErrorActionSpec) Aliases() []string {
method ShortDesc (line 90) | func (*ImagePullSecretsErrorActionSpec) ShortDesc() string {
method LongDesc (line 94) | func (*ImagePullSecretsErrorActionSpec) LongDesc() string {
function NewImagePullSecretsErrorActionSpec (line 57) | func NewImagePullSecretsErrorActionSpec(client *channel.Client) spec.Exp...
type ImagePullSecretsErrorActionExecutor (line 104) | type ImagePullSecretsErrorActionExecutor struct
method Name (line 108) | func (*ImagePullSecretsErrorActionExecutor) Name() string {
method SetChannel (line 112) | func (*ImagePullSecretsErrorActionExecutor) SetChannel(channel spec.Ch...
method Exec (line 114) | func (d *ImagePullSecretsErrorActionExecutor) Exec(uid string, ctx con...
method create (line 121) | func (d *ImagePullSecretsErrorActionExecutor) create(uid string, ctx c...
method destroy (line 250) | func (d *ImagePullSecretsErrorActionExecutor) destroy(uid string, ctx ...
method corruptSecret (line 314) | func (d *ImagePullSecretsErrorActionExecutor) corruptSecret(ctx contex...
method rollbackSecret (line 420) | func (d *ImagePullSecretsErrorActionExecutor) rollbackSecret(ctx conte...
method restoreSecretsInNamespace (line 463) | func (d *ImagePullSecretsErrorActionExecutor) restoreSecretsInNamespac...
function generateBackupSecretName (line 534) | func generateBackupSecretName(experimentId, namespace, secretName string...
function corruptDockerConfigJSON (line 548) | func corruptDockerConfigJSON(data []byte) ([]byte, error) {
function corruptDockerCfg (line 583) | func corruptDockerCfg(data []byte) ([]byte, error) {
function corruptRegistryCredentials (line 606) | func corruptRegistryCredentials(registries map[string]interface{}) int {
function filterSecretRefs (line 626) | func filterSecretRefs(refs []v1.LocalObjectReference, name string) []v1....
function copySecretData (line 637) | func copySecretData(data map[string][]byte) map[string][]byte {
FILE: exec/pod/imagepullsecretserror_test.go
function TestCorruptDockerConfigJSON (line 27) | func TestCorruptDockerConfigJSON(t *testing.T) {
function TestCorruptDockerConfigJSON_EmptyAuths (line 92) | func TestCorruptDockerConfigJSON_EmptyAuths(t *testing.T) {
function TestCorruptDockerConfigJSON_NoAuthsKey (line 107) | func TestCorruptDockerConfigJSON_NoAuthsKey(t *testing.T) {
function TestCorruptDockerConfigJSON_InvalidJSON (line 122) | func TestCorruptDockerConfigJSON_InvalidJSON(t *testing.T) {
function TestCorruptDockerCfg (line 129) | func TestCorruptDockerCfg(t *testing.T) {
function TestCorruptDockerCfg_Empty (line 176) | func TestCorruptDockerCfg_Empty(t *testing.T) {
function TestGenerateBackupSecretName (line 189) | func TestGenerateBackupSecretName(t *testing.T) {
function TestGenerateBackupSecretName_Deterministic (line 245) | func TestGenerateBackupSecretName_Deterministic(t *testing.T) {
function TestImagePullSecretsErrorActionSpec_Name (line 254) | func TestImagePullSecretsErrorActionSpec_Name(t *testing.T) {
function TestImagePullSecretsErrorActionSpec_Aliases (line 261) | func TestImagePullSecretsErrorActionSpec_Aliases(t *testing.T) {
function TestImagePullSecretsErrorActionExecutor_Name (line 269) | func TestImagePullSecretsErrorActionExecutor_Name(t *testing.T) {
function TestFilterSecretRefs (line 276) | func TestFilterSecretRefs(t *testing.T) {
function TestFilterSecretRefs_EmptyInput (line 318) | func TestFilterSecretRefs_EmptyInput(t *testing.T) {
function TestFilterSecretRefs_DuplicateNames (line 330) | func TestFilterSecretRefs_DuplicateNames(t *testing.T) {
function TestCopySecretData (line 342) | func TestCopySecretData(t *testing.T) {
function TestCopySecretData_Nil (line 361) | func TestCopySecretData_Nil(t *testing.T) {
FILE: exec/pod/pod.go
type ResourceModelSpec (line 36) | type ResourceModelSpec struct
function NewResourceModelSpec (line 40) | func NewResourceModelSpec(client *channel.Client) model.ResourceExpModel...
function addActionExamples (line 56) | func addActionExamples(modelSpec *ResourceModelSpec) {
function getResourceFlags (line 333) | func getResourceFlags() []spec.ExpFlagSpec {
type SelfExpModelCommandSpec (line 340) | type SelfExpModelCommandSpec struct
method Name (line 367) | func (*SelfExpModelCommandSpec) Name() string {
method ShortDesc (line 371) | func (*SelfExpModelCommandSpec) ShortDesc() string {
method LongDesc (line 375) | func (*SelfExpModelCommandSpec) LongDesc() string {
method Example (line 379) | func (*SelfExpModelCommandSpec) Example() string {
function NewSelfExpModelCommandSpec (line 344) | func NewSelfExpModelCommandSpec(client *channel.Client) spec.ExpModelCom...
FILE: exec/pod/schedulingfailure.go
constant ChaosBladeDeploymentAnnotation (line 42) | ChaosBladeDeploymentAnnotation = "chaosblade.io/deployment"
constant ChaosBladeDaemonSetAnnotation (line 44) | ChaosBladeDaemonSetAnnotation = "chaosblade.io/daemonset"
constant ChaosBladeStatefulSetAnnotation (line 46) | ChaosBladeStatefulSetAnnotation = "chaosblade.io/statefulset"
constant ChaosBladeModifyAction (line 48) | ChaosBladeModifyAction = "modify"
constant ChaosBladeOriginalNodeAffinityAnnotation (line 50) | ChaosBladeOriginalNodeAffinityAnnotation = "chaosblade.io/original-node-...
constant ChaosBladeOriginalPodAffinityAnnotation (line 52) | ChaosBladeOriginalPodAffinityAnnotation = "chaosblade.io/original-pod-af...
constant ChaosBladeOriginalPodAntiAffinityAnnotation (line 54) | ChaosBladeOriginalPodAntiAffinityAnnotation = "chaosblade.io/original-po...
constant ChaosBladeOriginalNodeSelectorAnnotation (line 56) | ChaosBladeOriginalNodeSelectorAnnotation = "chaosblade.io/original-nodes...
constant ChaosBladeAffinityTypeAnnotation (line 58) | ChaosBladeAffinityTypeAnnotation = "chaosblade.io/affinity-type"
constant ChaosBladeSchedulingFailureAction (line 60) | ChaosBladeSchedulingFailureAction = "schedulingfailure"
constant UnreachableNodeLabelKey (line 62) | UnreachableNodeLabelKey = "chaosblade.io/unreachable"
constant UnreachableNodeLabelValue (line 63) | UnreachableNodeLabelValue = "true"
type PodSchedulingFailureActionSpec (line 66) | type PodSchedulingFailureActionSpec struct
method Name (line 107) | func (*PodSchedulingFailureActionSpec) Name() string {
method Aliases (line 111) | func (*PodSchedulingFailureActionSpec) Aliases() []string {
method ShortDesc (line 115) | func (*PodSchedulingFailureActionSpec) ShortDesc() string {
method LongDesc (line 119) | func (*PodSchedulingFailureActionSpec) LongDesc() string {
method PreCreate (line 552) | func (a *PodSchedulingFailureActionSpec) PreCreate(ctx context.Context...
method PreDestroy (line 586) | func (a *PodSchedulingFailureActionSpec) PreDestroy(ctx context.Contex...
function NewPodSchedulingFailureActionSpec (line 71) | func NewPodSchedulingFailureActionSpec(client *channel.Client) spec.ExpA...
type PodSchedulingFailureActionExecutor (line 127) | type PodSchedulingFailureActionExecutor struct
method Name (line 131) | func (*PodSchedulingFailureActionExecutor) Name() string {
method SetChannel (line 135) | func (*PodSchedulingFailureActionExecutor) SetChannel(channel spec.Cha...
method Exec (line 137) | func (d *PodSchedulingFailureActionExecutor) Exec(uid string, ctx cont...
method create (line 144) | func (d *PodSchedulingFailureActionExecutor) create(uid string, ctx co...
method destroy (line 268) | func (d *PodSchedulingFailureActionExecutor) destroy(uid string, ctx c...
method injectDeploymentSchedulingFailure (line 350) | func (d *PodSchedulingFailureActionExecutor) injectDeploymentSchedulin...
method injectDaemonSetSchedulingFailure (line 374) | func (d *PodSchedulingFailureActionExecutor) injectDaemonSetScheduling...
method injectStatefulSetSchedulingFailure (line 395) | func (d *PodSchedulingFailureActionExecutor) injectStatefulSetScheduli...
method backupAndInjectAffinity (line 417) | func (d *PodSchedulingFailureActionExecutor) backupAndInjectAffinity(p...
method restoreDeployment (line 616) | func (d *PodSchedulingFailureActionExecutor) restoreDeployment(ctx con...
method restoreDaemonSet (line 639) | func (d *PodSchedulingFailureActionExecutor) restoreDaemonSet(ctx cont...
method restoreStatefulSet (line 660) | func (d *PodSchedulingFailureActionExecutor) restoreStatefulSet(ctx co...
method restoreAffinity (line 683) | func (d *PodSchedulingFailureActionExecutor) restoreAffinity(podSpec *...
function handleGetError (line 253) | func handleGetError(err error, namespace, workloadType, workloadName str...
function ensureNoConflictingExperiment (line 342) | func ensureNoConflictingExperiment(annotations map[string]string, experi...
FILE: exec/pod/taintnode.go
constant ChaosBladeTaintAnnotation (line 40) | ChaosBladeTaintAnnotation = "chaosblade.io/taint"
constant ChaosBladeOriginalTaintsAnnotation (line 42) | ChaosBladeOriginalTaintsAnnotation = "chaosblade.io/original-taints"
constant ChaosBladeInjectedTaintAnnotation (line 44) | ChaosBladeInjectedTaintAnnotation = "chaosblade.io/injected-taint"
constant DefaultTaintKey (line 46) | DefaultTaintKey = "chaosblade.io/unreachable"
constant DefaultTaintValue (line 48) | DefaultTaintValue = "true"
constant DefaultTaintEffect (line 50) | DefaultTaintEffect = "NoSchedule"
function chaosBladeTaintAnnotations (line 54) | func chaosBladeTaintAnnotations() []string {
type PodTaintNodeActionSpec (line 62) | type PodTaintNodeActionSpec struct
method Name (line 112) | func (*PodTaintNodeActionSpec) Name() string {
method Aliases (line 116) | func (*PodTaintNodeActionSpec) Aliases() []string {
method ShortDesc (line 120) | func (*PodTaintNodeActionSpec) ShortDesc() string {
method LongDesc (line 124) | func (*PodTaintNodeActionSpec) LongDesc() string {
method PreCreate (line 415) | func (a *PodTaintNodeActionSpec) PreCreate(ctx context.Context, expMod...
method PreDestroy (line 450) | func (a *PodTaintNodeActionSpec) PreDestroy(ctx context.Context, expMo...
function NewPodTaintNodeActionSpec (line 67) | func NewPodTaintNodeActionSpec(client *channel.Client) spec.ExpActionCom...
type PodTaintNodeActionExecutor (line 132) | type PodTaintNodeActionExecutor struct
method Name (line 136) | func (*PodTaintNodeActionExecutor) Name() string {
method SetChannel (line 140) | func (*PodTaintNodeActionExecutor) SetChannel(channel spec.Channel) {}
method Exec (line 142) | func (d *PodTaintNodeActionExecutor) Exec(uid string, ctx context.Cont...
method create (line 182) | func (d *PodTaintNodeActionExecutor) create(uid string, ctx context.Co...
method destroy (line 232) | func (d *PodTaintNodeActionExecutor) destroy(uid string, ctx context.C...
method injectTaintToNode (line 284) | func (d *PodTaintNodeActionExecutor) injectTaintToNode(ctx context.Con...
method restoreNodeTaints (line 333) | func (d *PodTaintNodeActionExecutor) restoreNodeTaints(ctx context.Con...
function parseTaintNodeFlags (line 150) | func parseTaintNodeFlags(expModel *spec.ExpModel) (nodeNames []string, t...
function findTaintIndex (line 373) | func findTaintIndex(taints []v1.Taint, key string, effect v1.TaintEffect...
function removeTaintByKeyEffect (line 384) | func removeTaintByKeyEffect(taints []v1.Taint, key string, effect v1.Tai...
function parseNodeNames (line 394) | func parseNodeNames(nodesFlag string) ([]string, error) {
function validateTaintNodeFlags (line 407) | func validateTaintNodeFlags(nodes string) *spec.Response {
FILE: exec/pod/taintnode_test.go
function TestParseTaintNodeFlags (line 29) | func TestParseTaintNodeFlags(t *testing.T) {
function TestValidateTaintNodeFlags (line 153) | func TestValidateTaintNodeFlags(t *testing.T) {
function TestInjectTaintToNode_ConflictDetection (line 176) | func TestInjectTaintToNode_ConflictDetection(t *testing.T) {
function TestInjectTaintToNode_Idempotent (line 197) | func TestInjectTaintToNode_Idempotent(t *testing.T) {
function TestInjectTaintToNode_BackupAndInject (line 215) | func TestInjectTaintToNode_BackupAndInject(t *testing.T) {
function TestInjectTaintToNode_DuplicateKeyEffect (line 277) | func TestInjectTaintToNode_DuplicateKeyEffect(t *testing.T) {
function TestRestoreNodeTaints_NotModifiedByExperiment (line 309) | func TestRestoreNodeTaints_NotModifiedByExperiment(t *testing.T) {
function TestRestoreNodeTaints_SuccessfulRestore (line 356) | func TestRestoreNodeTaints_SuccessfulRestore(t *testing.T) {
function TestRestoreNodeTaints_PreservesNewTaints (line 414) | func TestRestoreNodeTaints_PreservesNewTaints(t *testing.T) {
function TestRestoreNodeTaints_NoBackup (line 470) | func TestRestoreNodeTaints_NoBackup(t *testing.T) {
function containsString (line 510) | func containsString(s, substr string) bool {
FILE: exec/pod/terminating.go
constant PodTerminatingFinalizer (line 38) | PodTerminatingFinalizer = "chaosblade.io/pod-terminating"
type PodTerminatingActionSpec (line 41) | type PodTerminatingActionSpec struct
method Name (line 62) | func (*PodTerminatingActionSpec) Name() string {
method Aliases (line 66) | func (*PodTerminatingActionSpec) Aliases() []string {
method ShortDesc (line 70) | func (*PodTerminatingActionSpec) ShortDesc() string {
method LongDesc (line 74) | func (*PodTerminatingActionSpec) LongDesc() string {
function NewPodTerminatingActionSpec (line 45) | func NewPodTerminatingActionSpec(client *channel.Client) spec.ExpActionC...
type PodTerminatingActionExecutor (line 81) | type PodTerminatingActionExecutor struct
method Name (line 85) | func (*PodTerminatingActionExecutor) Name() string {
method SetChannel (line 89) | func (*PodTerminatingActionExecutor) SetChannel(channel spec.Channel) {}
method Exec (line 91) | func (d *PodTerminatingActionExecutor) Exec(uid string, ctx context.Co...
method create (line 98) | func (d *PodTerminatingActionExecutor) create(uid string, ctx context....
method destroy (line 172) | func (d *PodTerminatingActionExecutor) destroy(uid string, ctx context...
method addFinalizer (line 235) | func (d *PodTerminatingActionExecutor) addFinalizer(ctx context.Contex...
method removeFinalizer (line 248) | func (d *PodTerminatingActionExecutor) removeFinalizer(ctx context.Con...
FILE: exec/service/controller.go
constant ServiceMetaListKey (line 32) | ServiceMetaListKey = "ServiceMetaListKey"
type ServiceMeta (line 34) | type ServiceMeta struct
type ServiceMetaList (line 40) | type ServiceMetaList
function GetServiceMetaListFromContext (line 42) | func GetServiceMetaListFromContext(ctx context.Context) (ServiceMetaList...
function SetServiceMetaListToContext (line 50) | func SetServiceMetaListToContext(ctx context.Context, list ServiceMetaLi...
type ExpController (line 54) | type ExpController struct
method Name (line 67) | func (*ExpController) Name() string {
method Create (line 71) | func (e *ExpController) Create(ctx context.Context, expSpec v1alpha1.E...
method Destroy (line 78) | func (e *ExpController) Destroy(ctx context.Context, expSpec v1alpha1....
function NewExpController (line 58) | func NewExpController(client *channel.Client) model.ExperimentController {
function parseServiceIdentifier (line 100) | func parseServiceIdentifier(identifier string) ServiceMeta {
FILE: exec/service/create.go
constant NamePrefixFlag (line 38) | NamePrefixFlag = "name-prefix"
constant ServiceCountFlag (line 39) | ServiceCountFlag = "service-count"
constant PortsPerServiceFlag (line 40) | PortsPerServiceFlag = "ports-per-service"
type CreateServiceActionSpec (line 43) | type CreateServiceActionSpec struct
method Name (line 78) | func (*CreateServiceActionSpec) Name() string {
method Aliases (line 82) | func (*CreateServiceActionSpec) Aliases() []string {
method ShortDesc (line 86) | func (*CreateServiceActionSpec) ShortDesc() string {
method LongDesc (line 90) | func (*CreateServiceActionSpec) LongDesc() string {
function NewCreateServiceActionSpec (line 47) | func NewCreateServiceActionSpec(client *channel.Client) spec.ExpActionCo...
type CreateServiceActionExecutor (line 94) | type CreateServiceActionExecutor struct
method Name (line 98) | func (*CreateServiceActionExecutor) Name() string {
method SetChannel (line 102) | func (*CreateServiceActionExecutor) SetChannel(channel spec.Channel) {
method Exec (line 105) | func (d *CreateServiceActionExecutor) Exec(uid string, ctx context.Con...
method create (line 112) | func (d *CreateServiceActionExecutor) create(uid string, ctx context.C...
method destroy (line 193) | func (d *CreateServiceActionExecutor) destroy(uid string, ctx context....
function buildService (line 251) | func buildService(name, namespace string, portsPerService int, uid strin...
FILE: exec/service/modify.go
constant ServiceNameFlag (line 36) | ServiceNameFlag = "name"
constant ExternalTrafficPolicyFlag (line 37) | ExternalTrafficPolicyFlag = "externalTrafficPolicy"
constant InternalTrafficPolicyFlag (line 38) | InternalTrafficPolicyFlag = "internalTrafficPolicy"
constant ServiceAnnotation (line 39) | ServiceAnnotation = "chaosblade.io/service"
constant ServiceModifyHistoryAnnotation (line 40) | ServiceModifyHistoryAnnotation = "chaosblade.io/service-modify-history"
type ModifyServiceActionSpec (line 43) | type ModifyServiceActionSpec struct
method Name (line 83) | func (*ModifyServiceActionSpec) Name() string {
method Aliases (line 87) | func (*ModifyServiceActionSpec) Aliases() []string {
method ShortDesc (line 91) | func (*ModifyServiceActionSpec) ShortDesc() string {
method LongDesc (line 95) | func (*ModifyServiceActionSpec) LongDesc() string {
function NewModifyServiceActionSpec (line 47) | func NewModifyServiceActionSpec(client *channel.Client) spec.ExpActionCo...
type ModifyServiceActionExecutor (line 99) | type ModifyServiceActionExecutor struct
method Name (line 103) | func (*ModifyServiceActionExecutor) Name() string {
method SetChannel (line 107) | func (*ModifyServiceActionExecutor) SetChannel(channel spec.Channel) {
method Exec (line 110) | func (d *ModifyServiceActionExecutor) Exec(uid string, ctx context.Con...
method create (line 117) | func (d *ModifyServiceActionExecutor) create(uid string, ctx context.C...
method destroy (line 240) | func (d *ModifyServiceActionExecutor) destroy(uid string, ctx context....
function isValidPolicy (line 306) | func isValidPolicy(policy string) bool {
FILE: exec/service/service.go
type ResourceModelSpec (line 26) | type ResourceModelSpec struct
function NewResourceModelSpec (line 30) | func NewResourceModelSpec(client *channel.Client) model.ResourceExpModel...
function getResourceFlags (line 42) | func getResourceFlags() []spec.ExpFlagSpec {
type SelfExpModelCommandSpec (line 53) | type SelfExpModelCommandSpec struct
method Name (line 69) | func (*SelfExpModelCommandSpec) Name() string {
method ShortDesc (line 73) | func (*SelfExpModelCommandSpec) ShortDesc() string {
method LongDesc (line 77) | func (*SelfExpModelCommandSpec) LongDesc() string {
method Example (line 81) | func (*SelfExpModelCommandSpec) Example() string {
function NewSelfExpModelCommandSpec (line 57) | func NewSelfExpModelCommandSpec(client *channel.Client) spec.ExpModelCom...
FILE: pkg/apis/addtoscheme_chaosblade_v1alpha1.go
function init (line 23) | func init() {
FILE: pkg/apis/apis.go
function AddToScheme (line 27) | func AddToScheme(s *runtime.Scheme) error {
FILE: pkg/apis/chaosblade/v1alpha1/types.go
type ClusterPhase (line 26) | type ClusterPhase
constant ClusterPhaseInitial (line 29) | ClusterPhaseInitial ClusterPhase = ""
constant ClusterPhaseInitialized (line 30) | ClusterPhaseInitialized ClusterPhase = "Initialized"
constant ClusterPhaseRunning (line 31) | ClusterPhaseRunning ClusterPhase = "Running"
constant ClusterPhaseUpdating (line 32) | ClusterPhaseUpdating ClusterPhase = "Updating"
constant ClusterPhaseDestroying (line 33) | ClusterPhaseDestroying ClusterPhase = "Destroying"
constant ClusterPhaseDestroyed (line 34) | ClusterPhaseDestroyed ClusterPhase = "Destroyed"
constant ClusterPhaseError (line 35) | ClusterPhaseError ClusterPhase = "Error"
type ChaosBladeSpec (line 40) | type ChaosBladeSpec struct
type ExperimentSpec (line 47) | type ExperimentSpec struct
type FlagSpec (line 60) | type FlagSpec struct
type ChaosBladeStatus (line 70) | type ChaosBladeStatus struct
constant PodKind (line 95) | PodKind = "pod"
constant ContainerKind (line 96) | ContainerKind = "container"
constant NodeKind (line 97) | NodeKind = "node"
constant ServiceKind (line 98) | ServiceKind = "service"
type ResourceStatus (line 101) | type ResourceStatus struct
method CreateFailResourceStatus (line 80) | func (in *ResourceStatus) CreateFailResourceStatus(err string, code in...
method CreateSuccessResourceStatus (line 88) | func (in *ResourceStatus) CreateSuccessResourceStatus() ResourceStatus {
constant SuccessState (line 122) | SuccessState = "Success"
constant ErrorState (line 123) | ErrorState = "Error"
constant DestroyedState (line 124) | DestroyedState = "Destroyed"
function CreateFailExperimentStatus (line 127) | func CreateFailExperimentStatus(err string, ResStatuses []ResourceStatus...
function CreateSuccessExperimentStatus (line 131) | func CreateSuccessExperimentStatus(ResStatuses []ResourceStatus) Experim...
function CreateDestroyedExperimentStatus (line 135) | func CreateDestroyedExperimentStatus(ResStatuses []ResourceStatus) Exper...
function CreateFailResStatuses (line 139) | func CreateFailResStatuses(code int32, err, uid string) []ResourceStatus {
type ExperimentStatus (line 150) | type ExperimentStatus struct
type ChaosBlade (line 169) | type ChaosBlade struct
type ChaosBladeList (line 180) | type ChaosBladeList struct
function init (line 186) | func init() {
FILE: pkg/apis/chaosblade/v1alpha1/zz_generated.deepcopy.go
method DeepCopyInto (line 29) | func (in *ChaosBlade) DeepCopyInto(out *ChaosBlade) {
method DeepCopy (line 39) | func (in *ChaosBlade) DeepCopy() *ChaosBlade {
method DeepCopyObject (line 49) | func (in *ChaosBlade) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 57) | func (in *ChaosBladeList) DeepCopyInto(out *ChaosBladeList) {
method DeepCopy (line 72) | func (in *ChaosBladeList) DeepCopy() *ChaosBladeList {
method DeepCopyObject (line 82) | func (in *ChaosBladeList) DeepCopyObject() runtime.Object {
method DeepCopyInto (line 90) | func (in *ChaosBladeSpec) DeepCopyInto(out *ChaosBladeSpec) {
method DeepCopy (line 103) | func (in *ChaosBladeSpec) DeepCopy() *ChaosBladeSpec {
method DeepCopyInto (line 113) | func (in *ChaosBladeStatus) DeepCopyInto(out *ChaosBladeStatus) {
method DeepCopy (line 126) | func (in *ChaosBladeStatus) DeepCopy() *ChaosBladeStatus {
method DeepCopyInto (line 136) | func (in *ExperimentSpec) DeepCopyInto(out *ExperimentSpec) {
method DeepCopy (line 149) | func (in *ExperimentSpec) DeepCopy() *ExperimentSpec {
method DeepCopyInto (line 159) | func (in *ExperimentStatus) DeepCopyInto(out *ExperimentStatus) {
method DeepCopy (line 170) | func (in *ExperimentStatus) DeepCopy() *ExperimentStatus {
method DeepCopyInto (line 180) | func (in *FlagSpec) DeepCopyInto(out *FlagSpec) {
method DeepCopy (line 191) | func (in *FlagSpec) DeepCopy() *FlagSpec {
method DeepCopyInto (line 201) | func (in *ResourceStatus) DeepCopyInto(out *ResourceStatus) {
method DeepCopy (line 207) | func (in *ResourceStatus) DeepCopy() *ResourceStatus {
FILE: pkg/controller/add_chaosblade.go
function init (line 23) | func init() {
FILE: pkg/controller/chaosblade/controller.go
constant chaosbladeFinalizer (line 46) | chaosbladeFinalizer = "finalizer.chaosblade.io"
function Add (line 55) | func Add(mgr manager.Manager) error {
function newReconciler (line 67) | func newReconciler(mgr manager.Manager) *ReconcileChaosBlade {
function add (line 77) | func add(mgr manager.Manager, rcb *ReconcileChaosBlade) error {
function startPeriodicallyCleanUpBlade (line 116) | func startPeriodicallyCleanUpBlade(ctx context.Context, mgr manager.Mana...
function periodicallyCleanUpBlade (line 140) | func periodicallyCleanUpBlade(ctx context.Context, cli client.Client, in...
type ReconcileChaosBlade (line 175) | type ReconcileChaosBlade struct
method Reconcile (line 188) | func (r *ReconcileChaosBlade) Reconcile(ctx context.Context, request r...
method finalizeChaosBlade (line 327) | func (r *ReconcileChaosBlade) finalizeChaosBlade(ctx context.Context, ...
function contains (line 360) | func contains(list []string, s string) bool {
function remove (line 369) | func remove(list []string, s string) []string {
FILE: pkg/controller/chaosblade/daemonset.go
function deployChaosBladeTool (line 37) | func deployChaosBladeTool(rcb *ReconcileChaosBlade) error {
function createOwnerReferences (line 62) | func createOwnerReferences(rcb *ReconcileChaosBlade) ([]metav1.OwnerRefe...
function createDaemonsetSpec (line 96) | func createDaemonsetSpec() appsv1.DaemonSetSpec {
function createPodTemplateSpec (line 106) | func createPodTemplateSpec() corev1.PodTemplateSpec {
function createPodSpec (line 116) | func createPodSpec() corev1.PodSpec {
function createAffinity (line 149) | func createAffinity() *corev1.Affinity {
function createContainer (line 167) | func createContainer() corev1.Container {
FILE: pkg/controller/chaosblade/predicate.go
type SpecUpdatedPredicateForRunningPhase (line 29) | type SpecUpdatedPredicateForRunningPhase struct
method Create (line 31) | func (sup *SpecUpdatedPredicateForRunningPhase) Create(e event.TypedCr...
method Delete (line 49) | func (*SpecUpdatedPredicateForRunningPhase) Delete(e event.TypedDelete...
method Update (line 59) | func (*SpecUpdatedPredicateForRunningPhase) Update(e event.TypedUpdate...
method Generic (line 111) | func (*SpecUpdatedPredicateForRunningPhase) Generic(e event.TypedGener...
FILE: pkg/controller/controller.go
function AddToManager (line 27) | func AddToManager(m manager.Manager) error {
FILE: pkg/hookfs/client.go
type ChaosBladeHookClient (line 32) | type ChaosBladeHookClient struct
method InjectFault (line 52) | func (c *ChaosBladeHookClient) InjectFault(ctx context.Context, inject...
method Revoke (line 70) | func (c *ChaosBladeHookClient) Revoke(ctx context.Context) error {
function NewChabladeHookClient (line 37) | func NewChabladeHookClient(addr string) *ChaosBladeHookClient {
FILE: pkg/hookfs/hook.go
type ChaosbladeHookContext (line 31) | type ChaosbladeHookContext struct
type ChaosbladeHook (line 33) | type ChaosbladeHook struct
method PreOpen (line 37) | func (h *ChaosbladeHook) PreOpen(path string, flags uint32) (bool, hoo...
method PostOpen (line 46) | func (h *ChaosbladeHook) PostOpen(int32, hookfs.HookContext) (bool, er...
method PreRead (line 50) | func (h *ChaosbladeHook) PreRead(path string, length int64, offset int...
method PostRead (line 59) | func (h *ChaosbladeHook) PostRead(realRetCode int32, realBuf []byte, p...
method PreWrite (line 63) | func (h *ChaosbladeHook) PreWrite(path string, buf []byte, offset int6...
method PostWrite (line 72) | func (h *ChaosbladeHook) PostWrite(realRetCode int32, prehookCtx hookf...
method PreMkdir (line 76) | func (h *ChaosbladeHook) PreMkdir(path string, mode uint32) (bool, hoo...
method PostMkdir (line 85) | func (h *ChaosbladeHook) PostMkdir(realRetCode int32, prehookCtx hookf...
method PreRmdir (line 89) | func (h *ChaosbladeHook) PreRmdir(path string) (bool, hookfs.HookConte...
method PostRmdir (line 98) | func (h *ChaosbladeHook) PostRmdir(realRetCode int32, prehookCtx hookf...
method PreOpenDir (line 102) | func (h *ChaosbladeHook) PreOpenDir(path string) (bool, hookfs.HookCon...
method PostOpenDir (line 111) | func (h *ChaosbladeHook) PostOpenDir(realRetCode int32, prehookCtx hoo...
method PreFsync (line 115) | func (h *ChaosbladeHook) PreFsync(path string, flags uint32) (bool, ho...
method PostFsync (line 124) | func (h *ChaosbladeHook) PostFsync(realRetCode int32, prehookCtx hookf...
method PreFlush (line 128) | func (h *ChaosbladeHook) PreFlush(path string) (bool, hookfs.HookConte...
method PostFlush (line 137) | func (h *ChaosbladeHook) PostFlush(realRetCode int32, prehookCtx hookf...
method PreRelease (line 141) | func (h *ChaosbladeHook) PreRelease(path string) (bool, hookfs.HookCon...
method PostRelease (line 147) | func (h *ChaosbladeHook) PostRelease(prehookCtx hookfs.HookContext) (h...
method PreTruncate (line 151) | func (h *ChaosbladeHook) PreTruncate(path string, size uint64) (bool, ...
method PostTruncate (line 160) | func (h *ChaosbladeHook) PostTruncate(realRetCode int32, prehookCtx ho...
method PreGetAttr (line 164) | func (h *ChaosbladeHook) PreGetAttr(path string) (bool, hookfs.HookCon...
method PostGetAttr (line 173) | func (h *ChaosbladeHook) PostGetAttr(realRetCode int32, prehookCtx hoo...
method PreChown (line 177) | func (h *ChaosbladeHook) PreChown(path string, uid uint32, gid uint32)...
method PostChown (line 186) | func (h *ChaosbladeHook) PostChown(realRetCode int32, prehookCtx hookf...
method PreChmod (line 190) | func (h *ChaosbladeHook) PreChmod(path string, perms uint32) (bool, ho...
method PostChmod (line 199) | func (h *ChaosbladeHook) PostChmod(realRetCode int32, prehookCtx hookf...
method PreUtimens (line 203) | func (h *ChaosbladeHook) PreUtimens(path string, atime *time.Time, mti...
method PostUtimens (line 212) | func (h *ChaosbladeHook) PostUtimens(realRetCode int32, prehookCtx hoo...
method PreAllocate (line 216) | func (h *ChaosbladeHook) PreAllocate(path string, off uint64, size uin...
method PostAllocate (line 225) | func (h *ChaosbladeHook) PostAllocate(realRetCode int32, prehookCtx ho...
method PreGetLk (line 229) | func (h *ChaosbladeHook) PreGetLk(path string, owner uint64, lk *fuse....
method PostGetLk (line 238) | func (h *ChaosbladeHook) PostGetLk(realRetCode int32, prehookCtx hookf...
method PreSetLk (line 242) | func (h *ChaosbladeHook) PreSetLk(path string, owner uint64, lk *fuse....
method PostSetLk (line 251) | func (h *ChaosbladeHook) PostSetLk(realRetCode int32, prehookCtx hookf...
method PreSetLkw (line 255) | func (h *ChaosbladeHook) PreSetLkw(path string, owner uint64, lk *fuse...
method PostSetLkw (line 264) | func (h *ChaosbladeHook) PostSetLkw(realRetCode int32, prehookCtx hook...
method PreStatFs (line 268) | func (h *ChaosbladeHook) PreStatFs(path string) (bool, hookfs.HookCont...
method PostStatFs (line 277) | func (h *ChaosbladeHook) PostStatFs(prehookCtx hookfs.HookContext) (bo...
method PreReadlink (line 281) | func (h *ChaosbladeHook) PreReadlink(name string) (bool, hookfs.HookCo...
method PostReadlink (line 290) | func (h *ChaosbladeHook) PostReadlink(realRetCode int32, prehookCtx ho...
method PreSymlink (line 294) | func (h *ChaosbladeHook) PreSymlink(value string, linkName string) (bo...
method PostSymlink (line 307) | func (h *ChaosbladeHook) PostSymlink(realRetCode int32, prehookCtx hoo...
method PreCreate (line 311) | func (h *ChaosbladeHook) PreCreate(name string, flags uint32, mode uin...
method PostCreate (line 320) | func (h *ChaosbladeHook) PostCreate(realRetCode int32, prehookCtx hook...
method PreAccess (line 324) | func (h *ChaosbladeHook) PreAccess(name string, mode uint32) (bool, ho...
method PostAccess (line 333) | func (h *ChaosbladeHook) PostAccess(realRetCode int32, prehookCtx hook...
method PreLink (line 337) | func (h *ChaosbladeHook) PreLink(oldName string, newName string) (bool...
method PostLink (line 350) | func (h *ChaosbladeHook) PostLink(realRetCode int32, prehookCtx hookfs...
method PreMknod (line 354) | func (h *ChaosbladeHook) PreMknod(name string, mode uint32, dev uint32...
method PostMknod (line 363) | func (h *ChaosbladeHook) PostMknod(realRetCode int32, prehookCtx hookf...
method PreRename (line 367) | func (h *ChaosbladeHook) PreRename(oldName string, newName string) (bo...
method PostRename (line 380) | func (h *ChaosbladeHook) PostRename(realRetCode int32, prehookCtx hook...
method PreUnlink (line 384) | func (h *ChaosbladeHook) PreUnlink(name string) (bool, hookfs.HookCont...
method PostUnlink (line 393) | func (h *ChaosbladeHook) PostUnlink(realRetCode int32, prehookCtx hook...
method PreGetXAttr (line 397) | func (h *ChaosbladeHook) PreGetXAttr(name string, attribute string) (b...
method PostGetXAttr (line 406) | func (h *ChaosbladeHook) PostGetXAttr(realRetCode int32, prehookCtx ho...
method PreListXAttr (line 410) | func (h *ChaosbladeHook) PreListXAttr(name string) (bool, hookfs.HookC...
method PostListXAttr (line 419) | func (h *ChaosbladeHook) PostListXAttr(realRetCode int32, prehookCtx h...
method PreRemoveXAttr (line 423) | func (h *ChaosbladeHook) PreRemoveXAttr(name string, attr string) (boo...
method PostRemoveXAttr (line 432) | func (h *ChaosbladeHook) PostRemoveXAttr(realRetCode int32, prehookCtx...
method PreSetXAttr (line 436) | func (h *ChaosbladeHook) PreSetXAttr(name string, attr string, data []...
method PostSetXAttr (line 445) | func (h *ChaosbladeHook) PostSetXAttr(realRetCode int32, prehookCtx ho...
method doInjectFault (line 449) | func (h *ChaosbladeHook) doInjectFault(relativePath, method string) er...
function randomErrno (line 489) | func randomErrno() error {
function probab (line 494) | func probab(percentage uint32) bool {
FILE: pkg/hookfs/server.go
function init (line 31) | func init() {
type InjectMessage (line 35) | type InjectMessage struct
type ChaosbladeHookServer (line 44) | type ChaosbladeHookServer struct
method Start (line 54) | func (s *ChaosbladeHookServer) Start(stop context.Context) error {
method InjectHandler (line 78) | func (s *ChaosbladeHookServer) InjectHandler(w http.ResponseWriter, r ...
method RecoverHandler (line 92) | func (s *ChaosbladeHookServer) RecoverHandler(w http.ResponseWriter, r...
function NewChaosbladeHookServer (line 48) | func NewChaosbladeHookServer(addr string) *ChaosbladeHookServer {
FILE: pkg/runtime/chaosblade/chaosblade.go
constant OperatorChaosBladePath (line 35) | OperatorChaosBladePath = "/opt/chaosblade"
constant OperatorChaosBladeBin (line 36) | OperatorChaosBladeBin = "/opt/chaosblade/bin"
constant OperatorChaosBladeLib (line 37) | OperatorChaosBladeLib = "/opt/chaosblade/lib"
constant OperatorChaosBladeYaml (line 38) | OperatorChaosBladeYaml = "/opt/chaosblade/yaml"
constant OperatorChaosBladeBlade (line 39) | OperatorChaosBladeBlade = "/opt/chaosblade/blade"
constant DaemonsetPodName (line 43) | DaemonsetPodName = "chaosblade-tool"
constant DefaultRemoveBladeInterval (line 44) | DefaultRemoveBladeInterval = "72h"
type ProductConstant (line 61) | type ProductConstant struct
function init (line 67) | func init() {
function FlagSet (line 79) | func FlagSet() *pflag.FlagSet {
FILE: pkg/runtime/product/aliyun/aliyun.go
constant AHAS (line 34) | AHAS = "ahas"
constant prodEnv (line 35) | prodEnv = "prod"
constant publicRegion (line 36) | publicRegion = "cn-public"
function init (line 41) | func init() {
function FlagSet (line 64) | func FlagSet() *pflag.FlagSet {
FILE: pkg/runtime/product/community/community.go
constant Community (line 23) | Community = "community"
function init (line 25) | func init() {
FILE: pkg/runtime/runtime.go
function init (line 35) | func init() {
function initRuntimeData (line 47) | func initRuntimeData() {
function FlagSet (line 51) | func FlagSet() *pflag.FlagSet {
FILE: pkg/webhook/pod/mutator.go
constant SidecarName (line 42) | SidecarName = "chaosblade-fuse"
constant FuseServerPortName (line 43) | FuseServerPortName = "fuse-port"
type Mutator (line 47) | type Mutator struct
method Handle (line 52) | func (v *Mutator) Handle(ctx context.Context, req admission.Request) a...
method mutatePodsFn (line 77) | func (v *Mutator) mutatePodsFn(pod *corev1.Pod) error {
method InjectClient (line 177) | func (v *Mutator) InjectClient(c client.Client) error {
method InjectDecoder (line 183) | func (v *Mutator) InjectDecoder(d admission.Decoder) error {
function GetSidecarImage (line 188) | func GetSidecarImage() string {
FILE: pkg/webhook/pod/mutator_test.go
function Test_mutatePodsFn (line 27) | func Test_mutatePodsFn(t *testing.T) {
FILE: pkg/webhook/webhook.go
function init (line 32) | func init() {
function FlagSet (line 41) | func FlagSet() *pflag.FlagSet {
FILE: version/version.go
constant criVersion (line 25) | criVersion = "1.5.0"
function init (line 42) | func init() {
function GetVersionInfo (line 55) | func GetVersionInfo() map[string]string {
function GetVersionString (line 68) | func GetVersionString() string {
function GetShortVersion (line 74) | func GetShortVersion() string {
function CheckVerisonHaveCriCommand (line 78) | func CheckVerisonHaveCriCommand() bool {
Condensed preview — 179 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,222K chars).
[
{
"path": ".gitattributes",
"chars": 19,
"preview": "* text=auto eol=lf\n"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 572,
"preview": "<!-- Thanks for submitting a pull request! Here are some tips for you:\n1. Please make sure you have read and understood"
},
{
"path": ".github/issue_template.md",
"chars": 425,
"preview": "<!-- \n\nPlease try to use English to describe your issue, or at least provide a snippet of English translation.\n\n-->\n\n## "
},
{
"path": ".github/workflows/ci.yml",
"chars": 5140,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": ".github/workflows/release.yml",
"chars": 9060,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": ".gitignore",
"chars": 1353,
"preview": "# Temporary Build Files\nbuild/_output\nbuild/_test\ntarget\n# Created by https://www.gitignore.io/api/go,vim,emacs,visualst"
},
{
"path": "BUILD.md",
"chars": 6837,
"preview": "# ChaosBlade Operator Build Guide\n\nThis document describes how to build the ChaosBlade Operator project. The project sup"
},
{
"path": "CHANGELOG.md",
"chars": 784,
"preview": "# ChaosBlade Operator 变更日志\n\n本文档记录了 ChaosBlade Operator 的所有重要变更。\n\n格式基于 [Keep a Changelog](https://keepachangelog.com/zh-C"
},
{
"path": "CONTRIBUTING.md",
"chars": 7826,
"preview": "# Contributing to chaosblade\n\nWelcome to ChaosBlade world, here is a list of contributing guide for you. If you find som"
},
{
"path": "LICENSE",
"chars": 11361,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "Makefile",
"chars": 13968,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "README.md",
"chars": 10751,
"preview": "# Chaosblade-operator: A Chaos Engineering Tool for Cloud-native \n\n\n##"
},
{
"path": "build/bin/entrypoint",
"chars": 392,
"preview": "#!/bin/sh -e\n\n# This is documented here:\n# https://docs.openshift.com/container-platform/3.11/creating_images/guidelines"
},
{
"path": "build/bin/user_setup",
"chars": 340,
"preview": "#!/bin/sh\nset -x\n\n# ensure $HOME exists and is accessible by group 0 (we don't know what the runtime UID will be)\nmkdir "
},
{
"path": "build/image/amd/Dockerfile",
"chars": 1321,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "build/image/arm/Dockerfile",
"chars": 1252,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "build/musl/Dockerfile",
"chars": 995,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "build/spec.go",
"chars": 2494,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "channel/client.go",
"chars": 4028,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "channel/client_test.go",
"chars": 835,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "cmd/hookfs/main.go",
"chars": 3172,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "cmd/manager/main.go",
"chars": 6388,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "deploy/crds/chaosblade.io_chaosblades_crd.yaml",
"chars": 7398,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator/.helmignore",
"chars": 333,
"preview": "# Patterns to ignore when building packages.\n# This supports shell glob matching, relative path matching, and\n# negation"
},
{
"path": "deploy/helm/chaosblade-operator/Chart.yaml",
"chars": 735,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator/crds/crd.yaml",
"chars": 7419,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator/templates/NOTES.txt",
"chars": 31,
"preview": "Thank you for using chaosblade."
},
{
"path": "deploy/helm/chaosblade-operator/templates/_helpers.tpl",
"chars": 38,
"preview": "{{/* vim: set filetype=mustache: */}}\n"
},
{
"path": "deploy/helm/chaosblade-operator/templates/daemonset.yaml",
"chars": 3782,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator/templates/deployment.yaml",
"chars": 3540,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator/templates/rbac.yaml",
"chars": 1736,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator/templates/secret.yaml",
"chars": 2152,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator/templates/service.yaml",
"chars": 794,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator/values.yaml",
"chars": 1158,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator-arm64/.helmignore",
"chars": 333,
"preview": "# Patterns to ignore when building packages.\n# This supports shell glob matching, relative path matching, and\n# negation"
},
{
"path": "deploy/helm/chaosblade-operator-arm64/Chart.yaml",
"chars": 741,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator-arm64/crds/crd.yaml",
"chars": 7419,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator-arm64/templates/NOTES.txt",
"chars": 31,
"preview": "Thank you for using chaosblade."
},
{
"path": "deploy/helm/chaosblade-operator-arm64/templates/_helpers.tpl",
"chars": 38,
"preview": "{{/* vim: set filetype=mustache: */}}\n"
},
{
"path": "deploy/helm/chaosblade-operator-arm64/templates/daemonset.yaml",
"chars": 3784,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator-arm64/templates/deployment.yaml",
"chars": 3540,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator-arm64/templates/rbac.yaml",
"chars": 1736,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator-arm64/templates/secret.yaml",
"chars": 2152,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator-arm64/templates/service.yaml",
"chars": 794,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/helm/chaosblade-operator-arm64/values.yaml",
"chars": 1170,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/Makefile",
"chars": 1128,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/crd.yaml",
"chars": 6630,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/crds/chaosblade_v1alpha1_chaosblade_crd.yaml",
"chars": 6609,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/olm-catalog/chaosblade-operator/0.5.1/chaosblade-operator.v0.5.1.clusterserviceversion.yaml",
"chars": 47443,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/olm-catalog/chaosblade-operator/0.5.1/chaosblade_v1alpha1_chaosblade_crd.yaml",
"chars": 6609,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/olm-catalog/chaosblade-operator/0.6.0/chaosblade-operator.v0.6.0.clusterserviceversion.yaml",
"chars": 47443,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/olm-catalog/chaosblade-operator/0.6.0/chaosblade_v1alpha1_chaosblade_crd.yaml",
"chars": 6609,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/olm-catalog/chaosblade-operator/chaosblade-operator.package.yaml",
"chars": 707,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/operator.yaml",
"chars": 1595,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/role.yaml",
"chars": 1347,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/role_binding.yaml",
"chars": 887,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/olm/deploy/service_account.yaml",
"chars": 708,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/oss/crd.yaml",
"chars": 6625,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/oss/operator.yaml",
"chars": 2033,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/oss/rbac.yaml",
"chars": 2228,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/oss/service.yaml",
"chars": 781,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "deploy/oss/webhook-cert-job.yaml",
"chars": 4660,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/create_services_in_batch.yaml",
"chars": 1294,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/delay_pod_network_by_names.yaml",
"chars": 1102,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/delete_pod_by_labels.yaml",
"chars": 957,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/delete_pod_by_names.yaml",
"chars": 951,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/fail_pod_by_labels.yaml",
"chars": 918,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/increase_container_cpu_load_by_id.yaml",
"chars": 1042,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/kill_container_process_by_id.yaml",
"chars": 983,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/modify_service_traffic_policy.yaml",
"chars": 1310,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/node-cpu-load.yml",
"chars": 914,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/node-disk-load-burn-read.yml",
"chars": 1048,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/node-disk-load-burn-write.yml",
"chars": 1050,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/node-disk-load-fill.yml",
"chars": 949,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/node-mem-load.yml",
"chars": 953,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/node-network-delay-by-names.yml",
"chars": 988,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/node-network-loss-by-names.yml",
"chars": 936,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-bad-resource-size-cpu-mem.yaml",
"chars": 1374,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-bad-resource-size-cpu.yaml",
"chars": 1293,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-bad-resource-size-mem.yaml",
"chars": 1303,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-configmap-delete.yaml",
"chars": 1152,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-containercreating-by-pvc-error.yaml",
"chars": 1044,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-containercreating-disk.yaml",
"chars": 1809,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-cpu-load-by-names.yml",
"chars": 903,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-delete_by_names.yaml",
"chars": 894,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-failedmount-configmap.yaml",
"chars": 1610,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-failedmount-pvc.yaml",
"chars": 1580,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-failedmount-secret.yaml",
"chars": 1773,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-imagepullsecretserror-by-auth-corruption.yaml",
"chars": 1152,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-scheduling-failure.yaml",
"chars": 1606,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-taint-node.yaml",
"chars": 1555,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/pod-terminating-by-finalizer.yaml",
"chars": 986,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/remove_container_by_id.yaml",
"chars": 994,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/tamper_container_dns_by_id.yaml",
"chars": 1072,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "examples/test-configmap-delete.yaml",
"chars": 1075,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "exec/container/application.go",
"chars": 1656,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/container/container.go",
"chars": 19414,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/container/controller.go",
"chars": 10342,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/controller.go",
"chars": 5179,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/category.go",
"chars": 673,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/context.go",
"chars": 3623,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/controller.go",
"chars": 5343,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/controller_test.go",
"chars": 2076,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/copy.go",
"chars": 4610,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/deploy.go",
"chars": 2102,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/download.go",
"chars": 3919,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/executor.go",
"chars": 14186,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/executor_copy.go",
"chars": 18252,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/executor_nsexec.go",
"chars": 7542,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/filter.go",
"chars": 3292,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/filter_pod.go",
"chars": 5912,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/filter_pod_test.go",
"chars": 1577,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/model.go",
"chars": 8130,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/osexp.go",
"chars": 1618,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/model/parallelizer.go",
"chars": 1136,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/node/cniexp.go",
"chars": 17462,
"preview": "/*\n * Copyright 1999-2020 Alibaba Group Holding Ltd.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\""
},
{
"path": "exec/node/controller.go",
"chars": 3370,
"preview": "/*\n * Copyright 1999-2020 Alibaba Group Holding Ltd.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\""
},
{
"path": "exec/node/exec_helper.go",
"chars": 2514,
"preview": "/*\n * Copyright 1999-2020 Alibaba Group Holding Ltd.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\""
},
{
"path": "exec/node/filter.go",
"chars": 4185,
"preview": "/*\n * Copyright 1999-2020 Alibaba Group Holding Ltd.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\""
},
{
"path": "exec/node/node.go",
"chars": 27075,
"preview": "/*\n * Copyright 1999-2020 Alibaba Group Holding Ltd.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\""
},
{
"path": "exec/pod/badresourcesize.go",
"chars": 26770,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/configmapdeleteexp.go",
"chars": 22281,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/configmapdeleteexp_test.go",
"chars": 17055,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/containercreating.go",
"chars": 20001,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/containercreatingdisk.go",
"chars": 16973,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/containercreatingdisk_test.go",
"chars": 9045,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/controller.go",
"chars": 5505,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/delete.go",
"chars": 5009,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/failedmount.go",
"chars": 27306,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/failexp.go",
"chars": 6596,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/fsexp.go",
"chars": 10080,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/imageconfigexp.go",
"chars": 9986,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/imageconfigexp_test.go",
"chars": 6049,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/imagepullsecretserror.go",
"chars": 25196,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/imagepullsecretserror_test.go",
"chars": 10630,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/pod.go",
"chars": 21959,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/schedulingfailure.go",
"chars": 32953,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/taintnode.go",
"chars": 16876,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/taintnode_test.go",
"chars": 16473,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/pod/terminating.go",
"chars": 9861,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/service/controller.go",
"chars": 3359,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/service/create.go",
"chars": 9718,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/service/modify.go",
"chars": 12090,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "exec/service/service.go",
"chars": 2369,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "go.mod",
"chars": 6514,
"preview": "// Copyright 2025 The ChaosBlade Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you ma"
},
{
"path": "go.sum",
"chars": 196828,
"preview": "bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=\nbou.ke/monkey v"
},
{
"path": "hack/init.sh",
"chars": 1214,
"preview": "#!/usr/bin/env bash\n# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lic"
},
{
"path": "hack/update-gofmt.sh",
"chars": 836,
"preview": "#!/usr/bin/env bash\n# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lic"
},
{
"path": "hack/update-imports.sh",
"chars": 931,
"preview": "#!/usr/bin/env bash\n# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lic"
},
{
"path": "hack/verify-gofmt.sh",
"chars": 1179,
"preview": "#!/usr/bin/env bash\n# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lic"
},
{
"path": "hack/verify-imports.sh",
"chars": 1015,
"preview": "#!/usr/bin/env bash\n# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lic"
},
{
"path": "licenserc.toml",
"chars": 3012,
"preview": "# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may no"
},
{
"path": "pkg/apis/addtoscheme_chaosblade_v1alpha1.go",
"chars": 902,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/apis/apis.go",
"chars": 922,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/apis/chaosblade/group.go",
"chars": 863,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/apis/chaosblade/v1alpha1/doc.go",
"chars": 780,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/apis/chaosblade/v1alpha1/register.go",
"chars": 1234,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/apis/chaosblade/v1alpha1/types.go",
"chars": 5985,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/apis/chaosblade/v1alpha1/zz_generated.deepcopy.go",
"chars": 6033,
"preview": "//go:build !ignore_autogenerated\n// +build !ignore_autogenerated\n\n/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Lice"
},
{
"path": "pkg/controller/add_chaosblade.go",
"chars": 886,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/controller/chaosblade/controller.go",
"chars": 13757,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/controller/chaosblade/daemonset.go",
"chars": 5556,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/controller/chaosblade/predicate.go",
"chars": 3486,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/controller/controller.go",
"chars": 1022,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/hookfs/client.go",
"chars": 2279,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/hookfs/hook.go",
"chars": 13943,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/hookfs/server.go",
"chars": 2451,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/hookfs/types.go",
"chars": 1048,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/runtime/chaosblade/chaosblade.go",
"chars": 2684,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/runtime/product/aliyun/aliyun.go",
"chars": 1772,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/runtime/product/community/community.go",
"chars": 944,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/runtime/runtime.go",
"chars": 1702,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/webhook/pod/mutator.go",
"chars": 5897,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/webhook/pod/mutator_test.go",
"chars": 3606,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "pkg/webhook/webhook.go",
"chars": 1223,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
},
{
"path": "scripts/show-version.sh",
"chars": 1572,
"preview": "#!/bin/bash\n# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "scripts/version.sh",
"chars": 1748,
"preview": "#!/bin/bash\n# Copyright 2025 The ChaosBlade Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "version/version.go",
"chars": 2212,
"preview": "/*\n * Copyright 2025 The ChaosBlade Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you"
}
]
About this extraction
This page contains the full source code of the chaosblade-io/chaosblade-operator GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 179 files (1.1 MB), approximately 376.5k tokens, and a symbol index with 803 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.