Skip to content

Commit 102b08c

Browse files
authored
Merge branch 'main' into anvil-zksync
2 parents 9aaaef6 + 091d490 commit 102b08c

File tree

3 files changed

+297
-3
lines changed

3 files changed

+297
-3
lines changed

havoc/.changeset/v1.50.4.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Namespace-scoped chaos runner with main-stage tested experiments

havoc/go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ go 1.22.5
44

55
require (
66
github.com/chaos-mesh/chaos-mesh/api v0.0.0-20240821051457-da69c6d9617a
7+
github.com/google/uuid v1.6.0
78
github.com/pkg/errors v0.9.1
89
github.com/rs/zerolog v1.33.0
910
github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0
1011
k8s.io/api v0.31.2
12+
k8s.io/apimachinery v0.31.2
1113
k8s.io/client-go v0.31.2
14+
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
1215
sigs.k8s.io/controller-runtime v0.19.0
1316
)
1417

@@ -34,7 +37,6 @@ require (
3437
github.com/google/gnostic-models v0.6.8 // indirect
3538
github.com/google/go-cmp v0.6.0 // indirect
3639
github.com/google/gofuzz v1.2.0 // indirect
37-
github.com/google/uuid v1.6.0 // indirect
3840
github.com/grafana/grafana-foundation-sdk/go v0.0.0-20240326122733-6f96a993222b // indirect
3941
github.com/imdario/mergo v0.3.16 // indirect
4042
github.com/josharian/intern v1.0.0 // indirect
@@ -66,10 +68,8 @@ require (
6668
gopkg.in/yaml.v2 v2.4.0 // indirect
6769
gopkg.in/yaml.v3 v3.0.1 // indirect
6870
k8s.io/apiextensions-apiserver v0.31.0 // indirect
69-
k8s.io/apimachinery v0.31.2 // indirect
7071
k8s.io/klog/v2 v2.130.1 // indirect
7172
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
72-
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
7373
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
7474
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
7575
sigs.k8s.io/yaml v1.4.0 // indirect

havoc/template.go

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
package havoc
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
9+
"github.com/google/uuid"
10+
"github.com/rs/zerolog"
11+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/utils/ptr"
13+
"sigs.k8s.io/controller-runtime/pkg/client"
14+
)
15+
16+
func defaultListeners(l zerolog.Logger) []ChaosListener {
17+
return []ChaosListener{
18+
NewChaosLogger(l),
19+
}
20+
}
21+
22+
type ChaosRunner struct {
23+
l zerolog.Logger
24+
c client.Client
25+
}
26+
27+
// NewNamespaceRunner creates a new namespace-scoped chaos runner
28+
func NewNamespaceRunner(l zerolog.Logger, c client.Client) *ChaosRunner {
29+
return &ChaosRunner{
30+
l: l,
31+
c: c,
32+
}
33+
}
34+
35+
type PodPartitionCfg struct {
36+
Namespace string
37+
Description string
38+
LabelFromKey string
39+
LabelFromValues []string
40+
LabelToKey string
41+
LabelToValues []string
42+
InjectionDuration time.Duration
43+
ExperimentCreateDelay time.Duration
44+
}
45+
46+
func (cr *ChaosRunner) RunPodPartition(ctx context.Context, cfg PodPartitionCfg) (*Chaos, error) {
47+
experiment, err := NewChaos(ChaosOpts{
48+
Object: &v1alpha1.NetworkChaos{
49+
TypeMeta: metav1.TypeMeta{
50+
Kind: string(v1alpha1.TypeNetworkChaos),
51+
APIVersion: "chaos-mesh.org/v1alpha1",
52+
},
53+
ObjectMeta: metav1.ObjectMeta{
54+
Name: fmt.Sprintf("partition-%s", uuid.NewString()[0:5]),
55+
Namespace: cfg.Namespace,
56+
},
57+
Spec: v1alpha1.NetworkChaosSpec{
58+
Action: v1alpha1.PartitionAction,
59+
Duration: ptr.To[string]((cfg.InjectionDuration).String()),
60+
PodSelector: v1alpha1.PodSelector{
61+
Mode: v1alpha1.AllMode,
62+
Selector: v1alpha1.PodSelectorSpec{
63+
GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
64+
Namespaces: []string{cfg.Namespace},
65+
ExpressionSelectors: v1alpha1.LabelSelectorRequirements{
66+
{
67+
Operator: "In",
68+
Key: cfg.LabelFromKey,
69+
Values: cfg.LabelFromValues,
70+
},
71+
},
72+
},
73+
},
74+
},
75+
Target: &v1alpha1.PodSelector{
76+
Mode: v1alpha1.AllMode,
77+
Selector: v1alpha1.PodSelectorSpec{
78+
GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
79+
Namespaces: []string{cfg.Namespace},
80+
ExpressionSelectors: v1alpha1.LabelSelectorRequirements{
81+
{
82+
Operator: "In",
83+
Key: cfg.LabelToKey,
84+
Values: cfg.LabelToValues,
85+
},
86+
},
87+
},
88+
},
89+
},
90+
},
91+
},
92+
Listeners: defaultListeners(cr.l),
93+
Logger: &cr.l,
94+
Client: cr.c,
95+
})
96+
if err != nil {
97+
return nil, err
98+
}
99+
experiment.Create(ctx)
100+
return experiment, nil
101+
}
102+
103+
type PodDelayCfg struct {
104+
Namespace string
105+
Description string
106+
Latency time.Duration
107+
Jitter time.Duration
108+
Correlation string
109+
LabelKey string
110+
LabelValues []string
111+
InjectionDuration time.Duration
112+
ExperimentCreateDelay time.Duration
113+
}
114+
115+
func (cr *ChaosRunner) RunPodDelay(ctx context.Context, cfg PodDelayCfg) (*Chaos, error) {
116+
experiment, err := NewChaos(ChaosOpts{
117+
Object: &v1alpha1.NetworkChaos{
118+
TypeMeta: metav1.TypeMeta{
119+
Kind: string(v1alpha1.TypeNetworkChaos),
120+
APIVersion: "chaos-mesh.org/v1alpha1",
121+
},
122+
ObjectMeta: metav1.ObjectMeta{
123+
Name: fmt.Sprintf("delay-%s", uuid.NewString()[0:5]),
124+
Namespace: cfg.Namespace,
125+
},
126+
Spec: v1alpha1.NetworkChaosSpec{
127+
Action: v1alpha1.DelayAction,
128+
Duration: ptr.To[string]((cfg.InjectionDuration).String()),
129+
TcParameter: v1alpha1.TcParameter{
130+
Delay: &v1alpha1.DelaySpec{
131+
Latency: cfg.Latency.String(),
132+
Correlation: cfg.Correlation,
133+
Jitter: cfg.Jitter.String(),
134+
},
135+
},
136+
PodSelector: v1alpha1.PodSelector{
137+
Mode: v1alpha1.AllMode,
138+
Selector: v1alpha1.PodSelectorSpec{
139+
GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
140+
Namespaces: []string{cfg.Namespace},
141+
ExpressionSelectors: v1alpha1.LabelSelectorRequirements{
142+
{
143+
Operator: "In",
144+
Key: cfg.LabelKey,
145+
Values: cfg.LabelValues,
146+
},
147+
},
148+
},
149+
},
150+
},
151+
},
152+
},
153+
Listeners: defaultListeners(cr.l),
154+
Logger: &cr.l,
155+
Client: cr.c,
156+
})
157+
if err != nil {
158+
return nil, err
159+
}
160+
experiment.Create(ctx)
161+
return experiment, nil
162+
}
163+
164+
type PodFailCfg struct {
165+
Namespace string
166+
Description string
167+
LabelKey string
168+
LabelValues []string
169+
InjectionDuration time.Duration
170+
ExperimentCreateDelay time.Duration
171+
}
172+
173+
func (cr *ChaosRunner) RunPodFail(ctx context.Context, cfg PodFailCfg) (*Chaos, error) {
174+
experiment, err := NewChaos(ChaosOpts{
175+
Description: cfg.Description,
176+
DelayCreate: cfg.ExperimentCreateDelay,
177+
Object: &v1alpha1.PodChaos{
178+
TypeMeta: metav1.TypeMeta{
179+
Kind: string(v1alpha1.TypePodChaos),
180+
APIVersion: "chaos-mesh.org/v1alpha1",
181+
},
182+
ObjectMeta: metav1.ObjectMeta{
183+
Name: fmt.Sprintf("fail-%s", uuid.NewString()[0:5]),
184+
Namespace: cfg.Namespace,
185+
},
186+
Spec: v1alpha1.PodChaosSpec{
187+
Action: v1alpha1.PodFailureAction,
188+
Duration: ptr.To[string](cfg.InjectionDuration.String()),
189+
ContainerSelector: v1alpha1.ContainerSelector{
190+
PodSelector: v1alpha1.PodSelector{
191+
Mode: v1alpha1.AllMode,
192+
Selector: v1alpha1.PodSelectorSpec{
193+
GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
194+
Namespaces: []string{cfg.Namespace},
195+
ExpressionSelectors: v1alpha1.LabelSelectorRequirements{
196+
{
197+
Operator: "In",
198+
Key: cfg.LabelKey,
199+
Values: cfg.LabelValues,
200+
},
201+
},
202+
},
203+
},
204+
},
205+
},
206+
},
207+
},
208+
Listeners: defaultListeners(cr.l),
209+
Logger: &cr.l,
210+
Client: cr.c,
211+
})
212+
if err != nil {
213+
return nil, err
214+
}
215+
experiment.Create(ctx)
216+
return experiment, nil
217+
}
218+
219+
type NodeCPUStressConfig struct {
220+
Namespace string
221+
Description string
222+
Cores int
223+
CoreLoadPercentage int // 0-100
224+
LabelKey string
225+
LabelValues []string
226+
InjectionDuration time.Duration
227+
ExperimentTotalDuration time.Duration
228+
ExperimentCreateDelay time.Duration
229+
}
230+
231+
func (cr *ChaosRunner) RunPodStressCPU(ctx context.Context, cfg NodeCPUStressConfig) (*Schedule, error) {
232+
experiment, err := NewSchedule(ScheduleOpts{
233+
Description: cfg.Description,
234+
DelayCreate: cfg.ExperimentCreateDelay,
235+
Duration: cfg.ExperimentTotalDuration,
236+
Object: &v1alpha1.Schedule{
237+
TypeMeta: metav1.TypeMeta{
238+
Kind: "Schedule",
239+
APIVersion: "chaos-mesh.org/v1alpha1",
240+
},
241+
ObjectMeta: metav1.ObjectMeta{
242+
Name: "stress",
243+
Namespace: cfg.Namespace,
244+
},
245+
Spec: v1alpha1.ScheduleSpec{
246+
Schedule: "@every 1m",
247+
ConcurrencyPolicy: v1alpha1.ForbidConcurrent,
248+
Type: v1alpha1.ScheduleTypeStressChaos,
249+
HistoryLimit: 2,
250+
ScheduleItem: v1alpha1.ScheduleItem{
251+
EmbedChaos: v1alpha1.EmbedChaos{
252+
StressChaos: &v1alpha1.StressChaosSpec{
253+
ContainerSelector: v1alpha1.ContainerSelector{
254+
PodSelector: v1alpha1.PodSelector{
255+
Mode: v1alpha1.AllMode,
256+
Selector: v1alpha1.PodSelectorSpec{
257+
GenericSelectorSpec: v1alpha1.GenericSelectorSpec{
258+
Namespaces: []string{cfg.Namespace},
259+
ExpressionSelectors: v1alpha1.LabelSelectorRequirements{
260+
{
261+
Operator: "In",
262+
Key: cfg.LabelKey,
263+
Values: cfg.LabelValues,
264+
},
265+
},
266+
},
267+
},
268+
},
269+
},
270+
Stressors: &v1alpha1.Stressors{
271+
CPUStressor: &v1alpha1.CPUStressor{
272+
Stressor: v1alpha1.Stressor{
273+
Workers: cfg.Cores,
274+
},
275+
Load: ptr.To[int](cfg.CoreLoadPercentage),
276+
},
277+
},
278+
Duration: ptr.To[string](cfg.InjectionDuration.String()),
279+
},
280+
},
281+
},
282+
},
283+
},
284+
Listeners: defaultListeners(cr.l),
285+
Logger: &cr.l,
286+
Client: cr.c,
287+
})
288+
if err != nil {
289+
return nil, err
290+
}
291+
experiment.Create(ctx)
292+
return experiment, nil
293+
}

0 commit comments

Comments
 (0)