github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/test/e2e/util/common.go (about) 1 /* 2 Copyright the Velero contributors. 3 Copyright (C) 2022-2023 ApeCloud Co., Ltd 4 5 Licensed under the Apache License, Version 2.0 (the "License"); 6 you may not use this file except in compliance with the License. 7 You may obtain a copy of the License at 8 9 http://www.apache.org/licenses/LICENSE-2.0 10 11 Unless required by applicable law or agreed to in writing, software 12 distributed under the License is distributed on an "AS IS" BASIS, 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 See the License for the specific language governing permissions and 15 limitations under the License. 16 */ 17 18 package util 19 20 import ( 21 "fmt" 22 "io/ioutil" 23 "os/exec" 24 "time" 25 26 "github.com/pkg/errors" 27 "github.com/vmware-tanzu/velero/pkg/builder" 28 veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec" 29 "github.com/vmware-tanzu/velero/test/e2e/util/common" 30 "golang.org/x/net/context" 31 corev1api "k8s.io/api/core/v1" 32 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 33 "k8s.io/apimachinery/pkg/util/wait" 34 35 "github.com/1aal/kubeblocks/pkg/constant" 36 "github.com/1aal/kubeblocks/test/testutils" 37 ) 38 39 func EnsureClusterExists(ctx context.Context) error { 40 return exec.CommandContext(ctx, "kubectl", "cluster-info").Run() 41 } 42 43 func CreateSecretFromFiles(ctx context.Context, client TestClient, namespace string, name string, files map[string]string) error { 44 data := make(map[string][]byte) 45 46 for key, filePath := range files { 47 contents, err := ioutil.ReadFile(filePath) 48 if err != nil { 49 return errors.WithMessagef(err, "Failed to read secret file %q", filePath) 50 } 51 52 data[key] = contents 53 } 54 secret := builder.ForSecret(namespace, name).Data(data).Result() 55 _, err := client.ClientGo.CoreV1().Secrets(namespace).Create(ctx, secret, metav1.CreateOptions{}) 56 return err 57 } 58 59 // WaitForPods waits till all pods arrive at PodRunning state 60 func WaitForPods(ctx context.Context, client TestClient, namespace string, pods []string) error { 61 timeout := 5 * time.Minute 62 interval := 5 * time.Second 63 err := wait.PollImmediate(interval, timeout, func() (bool, error) { 64 for _, podName := range pods { 65 checkPod, err := client.ClientGo.CoreV1().Pods(namespace).Get(context.TODO(), podName, metav1.GetOptions{}) 66 if err != nil { 67 fmt.Println(errors.Wrap(err, fmt.Sprintf("Failed to verify pod %s/%s is %s, try again...\n", namespace, podName, corev1api.PodRunning))) 68 return false, nil 69 } 70 // If any pod is still waiting, no need to check, just return and wait for next poll interval 71 if checkPod.Status.Phase != corev1api.PodRunning { 72 fmt.Printf("Pod %s is in state %s waiting for it to be %s\n", podName, checkPod.Status.Phase, corev1api.PodRunning) 73 return false, nil 74 } 75 } 76 // All pods were in PodRunning state 77 return true, nil 78 }) 79 if err != nil { 80 return errors.Wrapf(err, fmt.Sprintf("Failed to wait for pods in namespace %s to start running", namespace)) 81 } 82 return nil 83 } 84 85 func GetPvcByPodName(ctx context.Context, namespace, podName string) ([]string, error) { 86 // Example: 87 // NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE 88 // kibishii-data-kibishii-deployment-0 Bound pvc-94b9fdf2-c30f-4a7b-87bf-06eadca0d5b6 1Gi RWO kibishii-storage-class 115s 89 cmds := []*common.OsCommandLine{} 90 cmd := &common.OsCommandLine{ 91 Cmd: "kubectl", 92 Args: []string{"get", "pvc", "-n", namespace}, 93 } 94 cmds = append(cmds, cmd) 95 96 cmd = &common.OsCommandLine{ 97 Cmd: "grep", 98 Args: []string{podName}, 99 } 100 cmds = append(cmds, cmd) 101 102 cmd = &common.OsCommandLine{ 103 Cmd: "awk", 104 Args: []string{"{print $1}"}, 105 } 106 cmds = append(cmds, cmd) 107 108 return common.GetListByCmdPipes(ctx, cmds) 109 } 110 111 func GetPvByPvc(ctx context.Context, namespace, pvc string) ([]string, error) { 112 // Example: 113 // NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE 114 // pvc-3f784366-58db-40b2-8fec-77307807e74b 1Gi RWO Delete Bound bsl-deletion/kibishii-data-kibishii-deployment-0 kibishii-storage-class 6h41m 115 cmds := []*common.OsCommandLine{} 116 cmd := &common.OsCommandLine{ 117 Cmd: "kubectl", 118 Args: []string{"get", "pv"}, 119 } 120 cmds = append(cmds, cmd) 121 122 cmd = &common.OsCommandLine{ 123 Cmd: "grep", 124 Args: []string{namespace + "/" + pvc}, 125 } 126 cmds = append(cmds, cmd) 127 128 cmd = &common.OsCommandLine{ 129 Cmd: "awk", 130 Args: []string{"{print $1}"}, 131 } 132 cmds = append(cmds, cmd) 133 134 return common.GetListByCmdPipes(ctx, cmds) 135 } 136 137 func CRDShouldExist(ctx context.Context, name string) error { 138 return CRDCountShouldBe(ctx, name, 1) 139 } 140 141 func CRDShouldNotExist(ctx context.Context, name string) error { 142 return CRDCountShouldBe(ctx, name, 0) 143 } 144 145 func CRDCountShouldBe(ctx context.Context, name string, count int) error { 146 crdList, err := GetCRD(ctx, name) 147 if err != nil { 148 return errors.Wrap(err, "Fail to get CRDs") 149 } 150 len := len(crdList) 151 if len != count { 152 return errors.New(fmt.Sprintf("CRD count is expected as %d instead of %d", count, len)) 153 } 154 return nil 155 } 156 157 func GetCRD(ctx context.Context, name string) ([]string, error) { 158 cmds := []*common.OsCommandLine{} 159 cmd := &common.OsCommandLine{ 160 Cmd: "kubectl", 161 Args: []string{"get", "crd"}, 162 } 163 cmds = append(cmds, cmd) 164 165 cmd = &common.OsCommandLine{ 166 Cmd: "grep", 167 Args: []string{name}, 168 } 169 cmds = append(cmds, cmd) 170 171 cmd = &common.OsCommandLine{ 172 Cmd: "awk", 173 Args: []string{"{print $1}"}, 174 } 175 cmds = append(cmds, cmd) 176 177 return common.GetListByCmdPipes(ctx, cmds) 178 } 179 180 func AddLabelToPv(ctx context.Context, pv, label string) error { 181 return exec.CommandContext(ctx, "kubectl", "label", "pv", pv, label).Run() 182 } 183 184 func AddLabelToPvc(ctx context.Context, pvc, namespace, label string) error { 185 args := []string{"label", "pvc", pvc, "-n", namespace, label} 186 fmt.Println(args) 187 return exec.CommandContext(ctx, "kubectl", args...).Run() 188 } 189 190 func AddLabelToPod(ctx context.Context, podName, namespace, label string) error { 191 args := []string{"label", "pod", podName, "-n", namespace, label} 192 fmt.Println(args) 193 return exec.CommandContext(ctx, "kubectl", args...).Run() 194 } 195 196 func AddLabelToCRD(ctx context.Context, crd, label string) error { 197 args := []string{"label", "crd", crd, label} 198 fmt.Println(args) 199 return exec.CommandContext(ctx, "kubectl", args...).Run() 200 } 201 202 func KubectlApplyByFile(ctx context.Context, file string) error { 203 args := []string{"apply", "-f", file, "--force=true"} 204 return exec.CommandContext(ctx, "kubectl", args...).Run() 205 } 206 207 func KubectlConfigUseContext(ctx context.Context, kubectlContext string) error { 208 cmd := exec.CommandContext(ctx, "kubectl", 209 "config", "use-context", kubectlContext) 210 fmt.Printf("Kubectl config use-context cmd =%v\n", cmd) 211 stdout, stderr, err := veleroexec.RunCommand(cmd) 212 fmt.Print(stdout) 213 fmt.Print(stderr) 214 return err 215 } 216 217 func GetAPIVersions(client *TestClient, name string) ([]string, error) { 218 var version []string 219 APIGroup, err := client.ClientGo.Discovery().ServerGroups() 220 if err != nil { 221 return nil, errors.Wrap(err, "Fail to get server API groups") 222 } 223 for _, group := range APIGroup.Groups { 224 fmt.Println(group.Name) 225 if group.Name == name { 226 for _, v := range group.Versions { 227 fmt.Println(v.Version) 228 version = append(version, v.Version) 229 } 230 return version, nil 231 } 232 } 233 return nil, errors.New("Server API groups is empty") 234 } 235 236 func CreateFileToPod(ctx context.Context, namespace, podName, volume, filename, content string) error { 237 arg := []string{"exec", "-n", namespace, "-c", podName, podName, 238 "--", "/bin/sh", "-c", fmt.Sprintf("echo ns-%s pod-%s volume-%s > /%s/%s", namespace, podName, volume, volume, filename)} 239 cmd := exec.CommandContext(ctx, "kubectl", arg...) 240 fmt.Printf("Kubectl exec cmd =%v\n", cmd) 241 return cmd.Run() 242 } 243 func ReadFileFromPodVolume(ctx context.Context, namespace, podName, volume, filename string) (string, error) { 244 arg := []string{"exec", "-n", namespace, "-c", podName, podName, 245 "--", "cat", fmt.Sprintf("/%s/%s", volume, filename)} 246 cmd := exec.CommandContext(ctx, "kubectl", arg...) 247 fmt.Printf("Kubectl exec cmd =%v\n", cmd) 248 stdout, stderr, err := veleroexec.RunCommand(cmd) 249 fmt.Print(stdout) 250 fmt.Print(stderr) 251 return stdout, err 252 } 253 254 func KubectlGetInfo(cmdName string, arg []string) { 255 cmd := exec.CommandContext(context.Background(), cmdName, arg...) 256 fmt.Printf("Kubectl exec cmd =%v\n", cmd) 257 stdout, stderr, err := veleroexec.RunCommand(cmd) 258 fmt.Println(stdout) 259 if err != nil { 260 fmt.Println(stderr) 261 fmt.Println(err) 262 } 263 } 264 265 func DeleteVeleroDs(ctx context.Context) error { 266 args := []string{"delete", "ds", "-n", "velero", "--all", "--force", "--grace-period", "0"} 267 fmt.Println(args) 268 return exec.CommandContext(ctx, "kubectl", args...).Run() 269 } 270 271 func WaitForCRDEstablished(crdName string) error { 272 arg := []string{"wait", "--for", "condition=established", "--timeout=60s", "crd/" + crdName} 273 cmd := exec.CommandContext(context.Background(), "kubectl", arg...) 274 fmt.Printf("Kubectl exec cmd =%v\n", cmd) 275 stdout, stderr, err := veleroexec.RunCommand(cmd) 276 fmt.Println(stdout) 277 if err != nil { 278 fmt.Println(stderr) 279 fmt.Println(err) 280 return err 281 } 282 return nil 283 } 284 285 func BuildAddonLabelSelector() string { 286 return fmt.Sprintf("%s=%s,%s=%s", 287 constant.AppInstanceLabelKey, testutils.KubeBlocksReleaseName, 288 constant.AppNameLabelKey, testutils.KubeBlocksChartName) 289 }