...

Source file src/github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/podchaos/podfailure/impl.go

Documentation: github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/podchaos/podfailure

     1  // Copyright 2021 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package podfailure
    15  
    16  import (
    17  	"context"
    18  
    19  	v1 "k8s.io/api/core/v1"
    20  	k8sError "k8s.io/apimachinery/pkg/api/errors"
    21  	"sigs.k8s.io/controller-runtime/pkg/client"
    22  
    23  	"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
    24  	"github.com/chaos-mesh/chaos-mesh/controllers/config"
    25  	"github.com/chaos-mesh/chaos-mesh/controllers/utils/controller"
    26  	"github.com/chaos-mesh/chaos-mesh/pkg/annotation"
    27  )
    28  
    29  type Impl struct {
    30  	client.Client
    31  }
    32  
    33  const (
    34  	// Always fails a container
    35  	pauseImage = "gcr.io/google-containers/pause:latest"
    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  	err := impl.Get(ctx, controller.ParseNamespacedName(records[index].Id), &origin)
    43  	if err != nil {
    44  		// TODO: handle this error
    45  		return v1alpha1.NotInjected, err
    46  	}
    47  	pod := origin.DeepCopy()
    48  	for index := range pod.Spec.Containers {
    49  		originImage := pod.Spec.Containers[index].Image
    50  		name := pod.Spec.Containers[index].Name
    51  
    52  		key := annotation.GenKeyForImage(podchaos, name, false)
    53  		if pod.Annotations == nil {
    54  			pod.Annotations = make(map[string]string)
    55  		}
    56  
    57  		// If the annotation is already existed, we could skip the reconcile for this container
    58  		if _, ok := pod.Annotations[key]; ok {
    59  			continue
    60  		}
    61  		pod.Annotations[key] = originImage
    62  		pod.Spec.Containers[index].Image = config.ControllerCfg.PodFailurePauseImage
    63  	}
    64  
    65  	for index := range pod.Spec.InitContainers {
    66  		originImage := pod.Spec.InitContainers[index].Image
    67  		name := pod.Spec.InitContainers[index].Name
    68  
    69  		key := annotation.GenKeyForImage(podchaos, name, true)
    70  		if pod.Annotations == nil {
    71  			pod.Annotations = make(map[string]string)
    72  		}
    73  
    74  		// If the annotation is already existed, we could skip the reconcile for this container
    75  		if _, ok := pod.Annotations[key]; ok {
    76  			continue
    77  		}
    78  		pod.Annotations[key] = originImage
    79  		pod.Spec.InitContainers[index].Image = config.ControllerCfg.PodFailurePauseImage
    80  	}
    81  
    82  	err = impl.Patch(ctx, pod, client.MergeFrom(&origin))
    83  	if err != nil {
    84  		// TODO: handle this error
    85  		return v1alpha1.NotInjected, err
    86  	}
    87  
    88  	return v1alpha1.Injected, nil
    89  }
    90  
    91  func (impl *Impl) Recover(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
    92  	podchaos := obj.(*v1alpha1.PodChaos)
    93  
    94  	var origin v1.Pod
    95  	err := impl.Get(ctx, controller.ParseNamespacedName(records[index].Id), &origin)
    96  	if err != nil {
    97  		// TODO: handle this error
    98  		if k8sError.IsNotFound(err) {
    99  			return v1alpha1.NotInjected, nil
   100  		}
   101  		return v1alpha1.Injected, err
   102  	}
   103  	pod := origin.DeepCopy()
   104  	for index := range pod.Spec.Containers {
   105  		name := pod.Spec.Containers[index].Name
   106  		key := annotation.GenKeyForImage(podchaos, name, false)
   107  
   108  		if pod.Annotations == nil {
   109  			pod.Annotations = make(map[string]string)
   110  		}
   111  		// check annotation
   112  		if image, ok := pod.Annotations[key]; ok {
   113  			pod.Spec.Containers[index].Image = image
   114  			delete(pod.Annotations, key)
   115  		}
   116  	}
   117  
   118  	for index := range pod.Spec.InitContainers {
   119  		name := pod.Spec.InitContainers[index].Name
   120  		key := annotation.GenKeyForImage(podchaos, name, true)
   121  
   122  		if pod.Annotations == nil {
   123  			pod.Annotations = make(map[string]string)
   124  		}
   125  		// check annotation
   126  		if image, ok := pod.Annotations[key]; ok {
   127  			pod.Spec.InitContainers[index].Image = image
   128  			delete(pod.Annotations, key)
   129  		}
   130  	}
   131  
   132  	err = impl.Patch(ctx, pod, client.MergeFrom(&origin))
   133  	if err != nil {
   134  		// TODO: handle this error
   135  		return v1alpha1.Injected, err
   136  	}
   137  
   138  	return v1alpha1.NotInjected, nil
   139  }
   140  
   141  func NewImpl(c client.Client) *Impl {
   142  	return &Impl{
   143  		Client: c,
   144  	}
   145  }
   146