github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/fault/fault_pod.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package fault 21 22 import ( 23 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1" 24 "github.com/spf13/cobra" 25 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 26 "k8s.io/apimachinery/pkg/runtime" 27 "k8s.io/cli-runtime/pkg/genericiooptions" 28 cmdutil "k8s.io/kubectl/pkg/cmd/util" 29 "k8s.io/kubectl/pkg/util/templates" 30 31 "github.com/1aal/kubeblocks/pkg/cli/create" 32 "github.com/1aal/kubeblocks/pkg/cli/util" 33 ) 34 35 var faultPodExample = templates.Examples(` 36 # kill all pods in default namespace 37 kbcli fault pod kill 38 39 # kill any pod in default namespace 40 kbcli fault pod kill --mode=one 41 42 # kill two pods in default namespace 43 kbcli fault pod kill --mode=fixed --value=2 44 45 # kill 50% pods in default namespace 46 kbcli fault pod kill --mode=percentage --value=50 47 48 # kill mysql-cluster-mysql-0 pod in default namespace 49 kbcli fault pod kill mysql-cluster-mysql-0 50 51 # kill all pods in default namespace 52 kbcli fault pod kill --ns-fault="default" 53 54 # --label is required to specify the pods that need to be killed. 55 kbcli fault pod kill --label statefulset.kubernetes.io/pod-name=mysql-cluster-mysql-2 56 57 # kill pod under the specified node. 58 kbcli fault pod kill --node=minikube-m02 59 60 # kill pod under the specified node-label. 61 kbcli fault pod kill --node-label=kubernetes.io/arch=arm64 62 63 # Allow the experiment to last for one minute. 64 kbcli fault pod failure --duration=1m 65 66 # kill container in pod 67 kbcli fault pod kill-container mysql-cluster-mysql-0 --container=mysql 68 `) 69 70 type PodChaosOptions struct { 71 // GracePeriod waiting time, after which fault injection is performed 72 GracePeriod int64 `json:"gracePeriod"` 73 ContainerNames []string `json:"containerNames,omitempty"` 74 75 FaultBaseOptions 76 } 77 78 func NewPodChaosOptions(f cmdutil.Factory, streams genericiooptions.IOStreams, action string) *PodChaosOptions { 79 o := &PodChaosOptions{ 80 FaultBaseOptions: FaultBaseOptions{ 81 CreateOptions: create.CreateOptions{ 82 Factory: f, 83 IOStreams: streams, 84 CueTemplateName: CueTemplatePodChaos, 85 GVR: GetGVR(Group, Version, ResourcePodChaos), 86 }, 87 Action: action, 88 }, 89 } 90 o.CreateOptions.PreCreate = o.PreCreate 91 o.CreateOptions.Options = o 92 return o 93 } 94 95 func NewPodChaosCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 96 cmd := &cobra.Command{ 97 Use: "pod", 98 Short: "Pod chaos.", 99 } 100 cmd.AddCommand( 101 NewPodKillCmd(f, streams), 102 NewPodFailureCmd(f, streams), 103 NewContainerKillCmd(f, streams), 104 ) 105 return cmd 106 } 107 108 func NewPodKillCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 109 o := NewPodChaosOptions(f, streams, string(v1alpha1.PodKillAction)) 110 cmd := o.NewCobraCommand(Kill, KillShort) 111 112 o.AddCommonFlag(cmd) 113 cmd.Flags().Int64VarP(&o.GracePeriod, "grace-period", "g", 0, "Grace period represents the duration in seconds before the pod should be killed") 114 115 // register flag completion func 116 registerFlagCompletionFunc(cmd, f) 117 118 return cmd 119 } 120 121 func NewPodFailureCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 122 o := NewPodChaosOptions(f, streams, string(v1alpha1.PodFailureAction)) 123 cmd := o.NewCobraCommand(Failure, FailureShort) 124 125 o.AddCommonFlag(cmd) 126 // register flag completion func 127 registerFlagCompletionFunc(cmd, f) 128 129 return cmd 130 } 131 132 func NewContainerKillCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 133 o := NewPodChaosOptions(f, streams, string(v1alpha1.ContainerKillAction)) 134 cmd := o.NewCobraCommand(KillContainer, KillContainerShort) 135 136 o.AddCommonFlag(cmd) 137 cmd.Flags().StringArrayVarP(&o.ContainerNames, "container", "c", nil, "the name of the container you want to kill, such as mysql, prometheus.") 138 139 util.CheckErr(cmd.MarkFlagRequired("container")) 140 141 // register flag completion func 142 registerFlagCompletionFunc(cmd, f) 143 144 return cmd 145 } 146 147 func (o *PodChaosOptions) NewCobraCommand(use, short string) *cobra.Command { 148 return &cobra.Command{ 149 Use: use, 150 Short: short, 151 Example: faultPodExample, 152 Run: func(cmd *cobra.Command, args []string) { 153 o.Args = args 154 cmdutil.CheckErr(o.CreateOptions.Complete()) 155 cmdutil.CheckErr(o.Validate()) 156 cmdutil.CheckErr(o.Complete()) 157 cmdutil.CheckErr(o.Run()) 158 }, 159 } 160 } 161 162 func (o *PodChaosOptions) AddCommonFlag(cmd *cobra.Command) { 163 o.FaultBaseOptions.AddCommonFlag(cmd) 164 } 165 166 func (o *PodChaosOptions) Validate() error { 167 return o.BaseValidate() 168 } 169 170 func (o *PodChaosOptions) Complete() error { 171 return o.BaseComplete() 172 } 173 174 func (o *PodChaosOptions) PreCreate(obj *unstructured.Unstructured) error { 175 c := &v1alpha1.PodChaos{} 176 if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, c); err != nil { 177 return err 178 } 179 180 data, e := runtime.DefaultUnstructuredConverter.ToUnstructured(c) 181 if e != nil { 182 return e 183 } 184 obj.SetUnstructuredContent(data) 185 return nil 186 }