...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package podfailure
17
18 import (
19 "context"
20
21 v1 "k8s.io/api/core/v1"
22 k8sError "k8s.io/apimachinery/pkg/api/errors"
23 "sigs.k8s.io/controller-runtime/pkg/client"
24
25 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
26 impltypes "github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/types"
27 "github.com/chaos-mesh/chaos-mesh/controllers/config"
28 "github.com/chaos-mesh/chaos-mesh/controllers/utils/controller"
29 "github.com/chaos-mesh/chaos-mesh/pkg/annotation"
30 )
31
32 var _ impltypes.ChaosImpl = (*Impl)(nil)
33
34 type Impl struct {
35 client.Client
36 }
37
38 func (impl *Impl) Apply(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
39 podchaos := obj.(*v1alpha1.PodChaos)
40
41 var origin v1.Pod
42 namespacedName, err := controller.ParseNamespacedName(records[index].Id)
43 if err != nil {
44 return v1alpha1.NotInjected, err
45 }
46 err = impl.Get(ctx, namespacedName, &origin)
47 if err != nil {
48
49 return v1alpha1.NotInjected, err
50 }
51 pod := origin.DeepCopy()
52 for index := range pod.Spec.Containers {
53 originImage := pod.Spec.Containers[index].Image
54 name := pod.Spec.Containers[index].Name
55
56 key := annotation.GenKeyForImage(podchaos, name, false)
57 if pod.Annotations == nil {
58 pod.Annotations = make(map[string]string)
59 }
60
61
62 if _, ok := pod.Annotations[key]; ok {
63 continue
64 }
65 pod.Annotations[key] = originImage
66 pod.Spec.Containers[index].Image = config.ControllerCfg.PodFailurePauseImage
67 }
68
69 for index := range pod.Spec.InitContainers {
70 originImage := pod.Spec.InitContainers[index].Image
71 name := pod.Spec.InitContainers[index].Name
72
73 key := annotation.GenKeyForImage(podchaos, name, true)
74 if pod.Annotations == nil {
75 pod.Annotations = make(map[string]string)
76 }
77
78
79 if _, ok := pod.Annotations[key]; ok {
80 continue
81 }
82 pod.Annotations[key] = originImage
83 pod.Spec.InitContainers[index].Image = config.ControllerCfg.PodFailurePauseImage
84 }
85
86 err = impl.Patch(ctx, pod, client.MergeFrom(&origin))
87 if err != nil {
88
89 return v1alpha1.NotInjected, err
90 }
91
92 return v1alpha1.Injected, nil
93 }
94
95 func (impl *Impl) Recover(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
96 podchaos := obj.(*v1alpha1.PodChaos)
97
98 var origin v1.Pod
99 namespacedName, err := controller.ParseNamespacedName(records[index].Id)
100 if err != nil {
101
102 return v1alpha1.NotInjected, err
103 }
104 err = impl.Get(ctx, namespacedName, &origin)
105 if err != nil {
106
107 if k8sError.IsNotFound(err) {
108 return v1alpha1.NotInjected, nil
109 }
110 return v1alpha1.Injected, err
111 }
112 pod := origin.DeepCopy()
113 for index := range pod.Spec.Containers {
114 name := pod.Spec.Containers[index].Name
115 key := annotation.GenKeyForImage(podchaos, name, false)
116
117 if pod.Annotations == nil {
118 pod.Annotations = make(map[string]string)
119 }
120
121 if image, ok := pod.Annotations[key]; ok {
122 pod.Spec.Containers[index].Image = image
123 delete(pod.Annotations, key)
124 }
125 }
126
127 for index := range pod.Spec.InitContainers {
128 name := pod.Spec.InitContainers[index].Name
129 key := annotation.GenKeyForImage(podchaos, name, true)
130
131 if pod.Annotations == nil {
132 pod.Annotations = make(map[string]string)
133 }
134
135 if image, ok := pod.Annotations[key]; ok {
136 pod.Spec.InitContainers[index].Image = image
137 delete(pod.Annotations, key)
138 }
139 }
140
141 err = impl.Patch(ctx, pod, client.MergeFrom(&origin))
142 if err != nil {
143
144 return v1alpha1.Injected, err
145 }
146
147 return v1alpha1.NotInjected, nil
148 }
149
150 func NewImpl(c client.Client) *Impl {
151 return &Impl{
152 Client: c,
153 }
154 }
155