1
2
3
4
5
6
7
8
9
10
11
12
13
14 package jvmchaos
15
16 import (
17 "context"
18 "fmt"
19
20 "github.com/go-logr/logr"
21 "go.uber.org/fx"
22 v1 "k8s.io/api/core/v1"
23 "sigs.k8s.io/controller-runtime/pkg/client"
24
25 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
26 "github.com/chaos-mesh/chaos-mesh/controllers/common"
27 "github.com/chaos-mesh/chaos-mesh/controllers/utils/controller"
28 "github.com/chaos-mesh/chaos-mesh/pkg/jvm"
29 )
30
31 const sandboxPort = 10086
32
33 type Impl struct {
34 client.Client
35 Log logr.Logger
36 }
37
38
39 func (impl *Impl) Apply(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
40 jvmchaos := obj.(*v1alpha1.JVMChaos)
41
42 var pod v1.Pod
43 err := impl.Client.Get(ctx, controller.ParseNamespacedName(records[index].Id), &pod)
44 if err != nil {
45
46 return v1alpha1.NotInjected, err
47 }
48
49 impl.Log.Info("Try to apply jvm chaos", "namespace",
50 pod.Namespace, "name", pod.Name)
51
52
53 err = jvm.ActiveSandbox(pod.Status.PodIP, sandboxPort)
54 if err != nil {
55 return v1alpha1.NotInjected, err
56 }
57
58 impl.Log.Info("active sandbox", "pod", pod.Name)
59
60 suid := genSUID(&pod, jvmchaos)
61 jsonBytes, err := jvm.ToSandboxAction(suid, jvmchaos)
62
63 if err != nil {
64 return v1alpha1.NotInjected, err
65 }
66
67 err = jvm.InjectChaos(pod.Status.PodIP, sandboxPort, jsonBytes)
68 if err != nil {
69 return v1alpha1.NotInjected, err
70 }
71 impl.Log.Info("Inject JVM Chaos", "pod", pod.Name, "action", jvmchaos.Spec.Action)
72
73 return v1alpha1.Injected, nil
74 }
75
76 func genSUID(pod *v1.Pod, chaos *v1alpha1.JVMChaos) string {
77 return fmt.Sprintf("%s:%s:%s:%s:%s",
78 pod.Name,
79 chaos.Spec.Action,
80 chaos.Spec.Target,
81 chaos.Name,
82 chaos.Namespace)
83 }
84
85
86 func (impl *Impl) Recover(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
87 jvmchaos := obj.(*v1alpha1.JVMChaos)
88
89 var pod v1.Pod
90 err := impl.Client.Get(ctx, controller.ParseNamespacedName(records[index].Id), &pod)
91 if err != nil {
92 if client.IgnoreNotFound(err) != nil {
93 return v1alpha1.Injected, err
94 }
95
96 impl.Log.Info("Target pod has been deleted", "namespace", pod.Namespace, "name", pod.Name)
97 return v1alpha1.NotInjected, nil
98
99 }
100
101 impl.Log.Info("Try to recover pod", "namespace", pod.Namespace, "name", pod.Name)
102
103 suid := genSUID(&pod, jvmchaos)
104 jsonBytes, err := jvm.ToSandboxAction(suid, jvmchaos)
105 if err != nil {
106 return v1alpha1.Injected, err
107 }
108
109
110 err = jvm.RecoverChaos(pod.Status.PodIP, sandboxPort, jsonBytes)
111
112 if err != nil {
113 return v1alpha1.Injected, err
114 }
115
116 return v1alpha1.NotInjected, nil
117 }
118
119
120
121 func NewImpl(c client.Client, log logr.Logger) *common.ChaosImplPair {
122 return &common.ChaosImplPair{
123 Name: "jvmchaos",
124 Object: &v1alpha1.JVMChaos{},
125 Impl: &Impl{
126 Client: c,
127 Log: log.WithName("jvmchaos"),
128 },
129 }
130 }
131
132 var Module = fx.Provide(
133 fx.Annotated{
134 Group: "impl",
135 Target: NewImpl,
136 },
137 )
138