github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/fault/fault_stress.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 "fmt" 24 25 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1" 26 "github.com/spf13/cobra" 27 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 28 "k8s.io/apimachinery/pkg/runtime" 29 "k8s.io/cli-runtime/pkg/genericiooptions" 30 cmdutil "k8s.io/kubectl/pkg/cmd/util" 31 "k8s.io/kubectl/pkg/util/templates" 32 33 "github.com/1aal/kubeblocks/pkg/cli/create" 34 ) 35 36 var faultStressExample = templates.Examples(` 37 # Affects the first container in default namespace's all pods.Making CPU load up to 50%, and the memory up to 100MB. 38 kbcli fault stress --cpu-worker=2 --cpu-load=50 --memory-worker=1 --memory-size=100Mi 39 40 # Affects the first container in mycluster-mysql-0 pod. Making the CPU load up to 50%, and the memory up to 500MB. 41 kbcli fault stress mycluster-mysql-0 --cpu-worker=2 --cpu-load=50 42 43 # Affects the mysql container in mycluster-mysql-0 pod. Making the memory up to 500MB. 44 kbcli fault stress mycluster-mysql-0 --memory-worker=2 --memory-size=500Mi -c=mysql 45 `) 46 47 type CPU struct { 48 Workers int `json:"workers"` 49 Load int `json:"load"` 50 } 51 52 type Memory struct { 53 Workers int `json:"workers"` 54 Size string `json:"size"` 55 } 56 57 type Stressors struct { 58 CPU `json:"cpu"` 59 Memory `json:"memory"` 60 } 61 62 type StressChaosOptions struct { 63 Stressors `json:"stressors"` 64 ContainerNames []string `json:"containerNames,omitempty"` 65 66 FaultBaseOptions 67 } 68 69 func NewStressChaosOptions(f cmdutil.Factory, streams genericiooptions.IOStreams, action string) *StressChaosOptions { 70 o := &StressChaosOptions{ 71 FaultBaseOptions: FaultBaseOptions{ 72 CreateOptions: create.CreateOptions{ 73 Factory: f, 74 IOStreams: streams, 75 CueTemplateName: CueTemplateStressChaos, 76 GVR: GetGVR(Group, Version, ResourceStressChaos), 77 }, 78 Action: action, 79 }, 80 } 81 o.CreateOptions.PreCreate = o.PreCreate 82 o.CreateOptions.Options = o 83 return o 84 } 85 86 func NewStressChaosCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 87 o := NewStressChaosOptions(f, streams, "") 88 cmd := o.NewCobraCommand(Stress, StressShort) 89 90 o.AddCommonFlag(cmd, f) 91 return cmd 92 } 93 94 func (o *StressChaosOptions) NewCobraCommand(use, short string) *cobra.Command { 95 return &cobra.Command{ 96 Use: use, 97 Short: short, 98 Example: faultStressExample, 99 Run: func(cmd *cobra.Command, args []string) { 100 o.Args = args 101 cmdutil.CheckErr(o.CreateOptions.Complete()) 102 cmdutil.CheckErr(o.Validate()) 103 cmdutil.CheckErr(o.Complete()) 104 cmdutil.CheckErr(o.Run()) 105 }, 106 } 107 } 108 109 func (o *StressChaosOptions) AddCommonFlag(cmd *cobra.Command, f cmdutil.Factory) { 110 o.FaultBaseOptions.AddCommonFlag(cmd) 111 112 cmd.Flags().IntVar(&o.CPU.Workers, "cpu-worker", 0, `Specifies the number of threads that exert CPU pressure.`) 113 cmd.Flags().IntVar(&o.CPU.Load, "cpu-load", 0, `Specifies the percentage of CPU occupied. 0 means no extra load added, 100 means full load. The total load is workers * load.`) 114 cmd.Flags().IntVar(&o.Memory.Workers, "memory-worker", 0, `Specifies the number of threads that apply memory pressure.`) 115 cmd.Flags().StringVar(&o.Memory.Size, "memory-size", "", `Specify the size of the allocated memory or the percentage of the total memory, and the sum of the allocated memory is size. For example:256MB or 25%`) 116 cmd.Flags().StringArrayVarP(&o.ContainerNames, "container", "c", nil, "The name of the container, such as mysql, prometheus.If it's empty, the first container will be injected.") 117 118 // register flag completion func 119 registerFlagCompletionFunc(cmd, f) 120 } 121 122 func (o *StressChaosOptions) Validate() error { 123 if o.Memory.Workers == 0 && o.CPU.Workers == 0 { 124 return fmt.Errorf("the CPU or Memory workers must have at least one greater than 0, Use --cpu-workers or --memory-workers to specify") 125 } 126 127 return o.BaseValidate() 128 } 129 130 func (o *StressChaosOptions) Complete() error { 131 return o.BaseComplete() 132 } 133 134 func (o *StressChaosOptions) PreCreate(obj *unstructured.Unstructured) error { 135 c := &v1alpha1.StressChaos{} 136 if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, c); err != nil { 137 return err 138 } 139 140 data, e := runtime.DefaultUnstructuredConverter.ToUnstructured(c) 141 if e != nil { 142 return e 143 } 144 obj.SetUnstructuredContent(data) 145 return nil 146 }