github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/dataprotection/action/action_exec.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 action 21 22 import ( 23 "github.com/pkg/errors" 24 corev1 "k8s.io/api/core/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 27 dpv1alpha1 "github.com/1aal/kubeblocks/apis/dataprotection/v1alpha1" 28 "github.com/1aal/kubeblocks/pkg/constant" 29 viper "github.com/1aal/kubeblocks/pkg/viperx" 30 ) 31 32 // ExecAction is an action that executes a command on a pod. 33 // This action will create a job to execute the command. 34 type ExecAction struct { 35 JobAction 36 37 // PodName is the Name of the pod to execute the command on. 38 PodName string 39 40 // Namespace is the Namespace of the pod to execute the command on. 41 Namespace string 42 43 // Command is the command to execute. 44 Command []string 45 46 // Container is the container to execute the command on. 47 Container string 48 49 // ServiceAccountName is the service account to use to build the job object. 50 ServiceAccountName string 51 52 // Timeout is the timeout for the command. 53 Timeout metav1.Duration 54 } 55 56 func (e *ExecAction) Execute(ctx Context) (*dpv1alpha1.ActionStatus, error) { 57 if err := e.validate(); err != nil { 58 return nil, err 59 } 60 e.JobAction.PodSpec = e.buildPodSpec() 61 return e.JobAction.Execute(ctx) 62 } 63 64 func (e *ExecAction) validate() error { 65 if e.PodName == "" { 66 return errors.New("pod name is required") 67 } 68 if e.Namespace == "" { 69 return errors.New("namespace is required") 70 } 71 if len(e.Command) == 0 { 72 return errors.New("command is required") 73 } 74 return nil 75 } 76 77 func (e *ExecAction) buildPodSpec() *corev1.PodSpec { 78 return &corev1.PodSpec{ 79 RestartPolicy: corev1.RestartPolicyNever, 80 ServiceAccountName: e.ServiceAccountName, 81 Containers: []corev1.Container{ 82 { 83 Name: e.Name, 84 Image: viper.GetString(constant.KBToolsImage), 85 ImagePullPolicy: corev1.PullPolicy(viper.GetString(constant.KBImagePullPolicy)), 86 Command: []string{"kubectl"}, 87 Args: append([]string{ 88 "-n", 89 e.Namespace, 90 "exec", 91 e.PodName, 92 "-c", 93 e.Container, 94 "--", 95 }, e.Command...), 96 }, 97 }, 98 Volumes: []corev1.Volume{}, 99 // tolerate all taints 100 Tolerations: []corev1.Toleration{ 101 { 102 Operator: corev1.TolerationOpExists, 103 }, 104 }, 105 Affinity: &corev1.Affinity{}, 106 NodeSelector: map[string]string{}, 107 } 108 } 109 110 var _ Action = &ExecAction{}