volcano.sh/volcano@v1.9.0/pkg/cli/vsub/run.go (about) 1 /* 2 Copyright 2018 The Volcano Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package vsub 18 19 import ( 20 "context" 21 "fmt" 22 "os" 23 24 "github.com/google/shlex" 25 "github.com/spf13/cobra" 26 27 v1 "k8s.io/api/core/v1" 28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 30 vcbatch "volcano.sh/apis/pkg/apis/batch/v1alpha1" 31 "volcano.sh/apis/pkg/client/clientset/versioned" 32 "volcano.sh/volcano/pkg/cli/util" 33 ) 34 35 type runFlags struct { 36 util.CommonFlags 37 38 Name string 39 Namespace string 40 Image string 41 42 MinAvailable int 43 Replicas int 44 Requests string 45 Limits string 46 SchedulerName string 47 FileName string 48 Command string 49 } 50 51 var launchJobFlags = &runFlags{} 52 53 const ( 54 // SchedulerNameEnv is the env name of default scheduler name. 55 SchedulerNameEnv = "VOLCANO_SCHEDULER_NAME" 56 57 // DefaultImageEnv is the env name of default image. 58 DefaultImageEnv = "VOLCANO_DEFAULT_IMAGE" 59 60 // DefaultJobNamespaceEnv is the env name of default namespace of the job 61 DefaultJobNamespaceEnv = "VOLCANO_DEFAULT_JOB_NAMESPACE" 62 63 defaultImage = "busybox" 64 defaultSchedulerName = "volcano" 65 defaultJobNamespace = "default" 66 ) 67 68 // InitRunFlags init the run flags. 69 func InitRunFlags(cmd *cobra.Command) { 70 util.InitFlags(cmd, &launchJobFlags.CommonFlags) 71 72 cmd.Flags().StringVarP(&launchJobFlags.Image, "image", "i", "", 73 fmt.Sprintf("the container image of job, overwrite the value of '%s' (default \"%s\")", 74 DefaultImageEnv, defaultImage)) 75 cmd.Flags().StringVarP(&launchJobFlags.Namespace, "namespace", "N", "", 76 fmt.Sprintf("the namespace of job, overwrite the value of '%s' (default \"%s\")", DefaultJobNamespaceEnv, defaultJobNamespace)) 77 cmd.Flags().StringVarP(&launchJobFlags.Name, "name", "n", "", "the name of job") 78 cmd.Flags().IntVarP(&launchJobFlags.MinAvailable, "min", "m", 1, "the minimal available tasks of job") 79 cmd.Flags().IntVarP(&launchJobFlags.Replicas, "replicas", "r", 1, "the total tasks of job") 80 cmd.Flags().StringVarP(&launchJobFlags.Requests, "requests", "R", "cpu=1000m,memory=100Mi", "the resource request of the task") 81 cmd.Flags().StringVarP(&launchJobFlags.Limits, "limits", "L", "cpu=1000m,memory=100Mi", "the resource limit of the task") 82 cmd.Flags().StringVarP(&launchJobFlags.SchedulerName, "scheduler", "S", "", 83 fmt.Sprintf("the scheduler for this job, overwrite the value of '%s' (default \"%s\")", 84 SchedulerNameEnv, defaultSchedulerName)) 85 cmd.Flags().StringVarP(&launchJobFlags.Command, "command", "c", "", "the command of of job") 86 87 setDefaultArgs() 88 } 89 90 func setDefaultArgs() { 91 if launchJobFlags.SchedulerName == "" { 92 schedulerName := os.Getenv(SchedulerNameEnv) 93 94 if schedulerName != "" { 95 launchJobFlags.SchedulerName = schedulerName 96 } else { 97 launchJobFlags.SchedulerName = defaultSchedulerName 98 } 99 } 100 101 if launchJobFlags.Image == "" { 102 image := os.Getenv(DefaultImageEnv) 103 104 if image != "" { 105 launchJobFlags.Image = image 106 } else { 107 launchJobFlags.Image = defaultImage 108 } 109 } 110 111 if launchJobFlags.Namespace == "" { 112 namespace := os.Getenv(DefaultJobNamespaceEnv) 113 114 if namespace != "" { 115 launchJobFlags.Namespace = namespace 116 } else { 117 launchJobFlags.Namespace = defaultJobNamespace 118 } 119 } 120 } 121 122 var jobName = "job.volcano.sh" 123 124 // RunJob creates the job. 125 func RunJob() error { 126 config, err := util.BuildConfig(launchJobFlags.Master, launchJobFlags.Kubeconfig) 127 if err != nil { 128 return err 129 } 130 131 if launchJobFlags.Name == "" { 132 err = fmt.Errorf("job name cannot be left blank") 133 return err 134 } 135 136 req, err := util.PopulateResourceListV1(launchJobFlags.Requests) 137 if err != nil { 138 return err 139 } 140 141 limit, err := util.PopulateResourceListV1(launchJobFlags.Limits) 142 if err != nil { 143 return err 144 } 145 146 job, err := constructLaunchJobFlagsJob(launchJobFlags, req, limit) 147 if err != nil { 148 return err 149 } 150 151 jobClient := versioned.NewForConfigOrDie(config) 152 newJob, err := jobClient.BatchV1alpha1().Jobs(launchJobFlags.Namespace).Create(context.TODO(), job, metav1.CreateOptions{}) 153 if err != nil { 154 return err 155 } 156 157 if newJob.Spec.Queue == "" { 158 newJob.Spec.Queue = "default" 159 } 160 161 fmt.Printf("run job %v successfully\n", newJob.Name) 162 163 return nil 164 } 165 166 func constructLaunchJobFlagsJob(launchJobFlags *runFlags, req, limit v1.ResourceList) (*vcbatch.Job, error) { 167 var commands []string 168 169 if launchJobFlags.Command != "" { 170 var err error 171 if commands, err = shlex.Split(launchJobFlags.Command); err != nil { 172 return nil, err 173 } 174 } 175 176 return &vcbatch.Job{ 177 ObjectMeta: metav1.ObjectMeta{ 178 Name: launchJobFlags.Name, 179 Namespace: launchJobFlags.Namespace, 180 }, 181 Spec: vcbatch.JobSpec{ 182 MinAvailable: int32(launchJobFlags.MinAvailable), 183 SchedulerName: launchJobFlags.SchedulerName, 184 Tasks: []vcbatch.TaskSpec{ 185 { 186 Replicas: int32(launchJobFlags.Replicas), 187 188 Template: v1.PodTemplateSpec{ 189 ObjectMeta: metav1.ObjectMeta{ 190 Name: launchJobFlags.Name, 191 Labels: map[string]string{jobName: launchJobFlags.Name}, 192 }, 193 Spec: v1.PodSpec{ 194 RestartPolicy: v1.RestartPolicyNever, 195 Containers: []v1.Container{ 196 { 197 Image: launchJobFlags.Image, 198 Name: launchJobFlags.Name, 199 ImagePullPolicy: v1.PullIfNotPresent, 200 Command: commands, 201 Resources: v1.ResourceRequirements{ 202 Limits: limit, 203 Requests: req, 204 }, 205 }, 206 }, 207 }, 208 }, 209 }, 210 }, 211 }, 212 }, nil 213 }