github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/fault/fault_time.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 faultTimeExample = templates.Examples(` 36 # Affects the first container in default namespace's all pods.Shifts the clock back five seconds. 37 kbcli fault time --time-offset=-5s 38 39 # Affects the first container in default namespace's all pods. 40 kbcli fault time --time-offset=-5m5s 41 42 # Affects the first container in mycluster-mysql-0 pod. Shifts the clock forward five seconds. 43 kbcli fault time mycluster-mysql-0 --time-offset=+5s50ms 44 45 # Affects the mysql container in mycluster-mysql-0 pod. Shifts the clock forward five seconds. 46 kbcli fault time mycluster-mysql-0 --time-offset=+5s -c=mysql 47 48 # The clock that specifies the effect of time offset is CLOCK_REALTIME. 49 kbcli fault time mycluster-mysql-0 --time-offset=+5s --clock-id=CLOCK_REALTIME -c=mysql 50 `) 51 52 type TimeChaosOptions struct { 53 TimeOffset string `json:"timeOffset"` 54 55 ClockIds []string `json:"clockIds,omitempty"` 56 57 ContainerNames []string `json:"containerNames,omitempty"` 58 59 FaultBaseOptions 60 } 61 62 func NewTimeChaosOptions(f cmdutil.Factory, streams genericiooptions.IOStreams, action string) *TimeChaosOptions { 63 o := &TimeChaosOptions{ 64 FaultBaseOptions: FaultBaseOptions{ 65 CreateOptions: create.CreateOptions{ 66 Factory: f, 67 IOStreams: streams, 68 CueTemplateName: CueTemplateTimeChaos, 69 GVR: GetGVR(Group, Version, ResourceTimeChaos), 70 }, 71 Action: action, 72 }, 73 } 74 o.CreateOptions.PreCreate = o.PreCreate 75 o.CreateOptions.Options = o 76 return o 77 } 78 79 func NewTimeChaosCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 80 o := NewTimeChaosOptions(f, streams, "") 81 cmd := o.NewCobraCommand(Time, TimeShort) 82 83 o.AddCommonFlag(cmd, f) 84 return cmd 85 } 86 87 func (o *TimeChaosOptions) NewCobraCommand(use, short string) *cobra.Command { 88 return &cobra.Command{ 89 Use: use, 90 Short: short, 91 Example: faultTimeExample, 92 Run: func(cmd *cobra.Command, args []string) { 93 o.Args = args 94 cmdutil.CheckErr(o.CreateOptions.Complete()) 95 cmdutil.CheckErr(o.Validate()) 96 cmdutil.CheckErr(o.Complete()) 97 cmdutil.CheckErr(o.Run()) 98 }, 99 } 100 } 101 102 func (o *TimeChaosOptions) AddCommonFlag(cmd *cobra.Command, f cmdutil.Factory) { 103 o.FaultBaseOptions.AddCommonFlag(cmd) 104 105 cmd.Flags().StringVar(&o.TimeOffset, "time-offset", "", "Specifies the length of the time offset. For example: -5s, -10m100ns.") 106 cmd.Flags().StringArrayVar(&o.ClockIds, "clock-id", nil, `Specifies the clock on which the time offset acts.If it's empty, it will be set to ['CLOCK_REALTIME'].See clock_gettime [https://man7.org/linux/man-pages/man2/clock_gettime.2.html] document for details.`) 107 cmd.Flags().StringArrayVarP(&o.ContainerNames, "container", "c", nil, `Specifies the injected container name. For example: mysql. If it's empty, the first container will be injected.`) 108 109 util.CheckErr(cmd.MarkFlagRequired("time-offset")) 110 111 // register flag completion func 112 registerFlagCompletionFunc(cmd, f) 113 } 114 115 func (o *TimeChaosOptions) Validate() error { 116 return o.BaseValidate() 117 } 118 119 func (o *TimeChaosOptions) Complete() error { 120 return o.BaseComplete() 121 } 122 123 func (o *TimeChaosOptions) PreCreate(obj *unstructured.Unstructured) error { 124 c := &v1alpha1.TimeChaos{} 125 if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, c); err != nil { 126 return err 127 } 128 129 data, e := runtime.DefaultUnstructuredConverter.ToUnstructured(c) 130 if e != nil { 131 return e 132 } 133 obj.SetUnstructuredContent(data) 134 return nil 135 }