volcano.sh/volcano@v1.9.0/pkg/cli/job/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 job
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"os"
    23  	"strings"
    24  
    25  	"github.com/spf13/cobra"
    26  
    27  	v1 "k8s.io/api/core/v1"
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	"sigs.k8s.io/yaml"
    30  
    31  	vcbatch "volcano.sh/apis/pkg/apis/batch/v1alpha1"
    32  	"volcano.sh/apis/pkg/client/clientset/versioned"
    33  	"volcano.sh/volcano/pkg/cli/util"
    34  )
    35  
    36  type runFlags struct {
    37  	commonFlags
    38  
    39  	Name      string
    40  	Namespace string
    41  	Image     string
    42  
    43  	MinAvailable  int
    44  	Replicas      int
    45  	Requests      string
    46  	Limits        string
    47  	SchedulerName string
    48  	FileName      string
    49  }
    50  
    51  var launchJobFlags = &runFlags{}
    52  
    53  // InitRunFlags init the run flags.
    54  func InitRunFlags(cmd *cobra.Command) {
    55  	initFlags(cmd, &launchJobFlags.commonFlags)
    56  
    57  	cmd.Flags().StringVarP(&launchJobFlags.Image, "image", "i", "busybox", "the container image of job")
    58  	cmd.Flags().StringVarP(&launchJobFlags.Namespace, "namespace", "n", "default", "the namespace of job")
    59  	cmd.Flags().StringVarP(&launchJobFlags.Name, "name", "N", "", "the name of job")
    60  	cmd.Flags().IntVarP(&launchJobFlags.MinAvailable, "min", "m", 1, "the minimal available tasks of job")
    61  	cmd.Flags().IntVarP(&launchJobFlags.Replicas, "replicas", "r", 1, "the total tasks of job")
    62  	cmd.Flags().StringVarP(&launchJobFlags.Requests, "requests", "R", "cpu=1000m,memory=100Mi", "the resource request of the task")
    63  	cmd.Flags().StringVarP(&launchJobFlags.Limits, "limits", "L", "cpu=1000m,memory=100Mi", "the resource limit of the task")
    64  	cmd.Flags().StringVarP(&launchJobFlags.SchedulerName, "scheduler", "S", "volcano", "the scheduler for this job")
    65  	cmd.Flags().StringVarP(&launchJobFlags.FileName, "filename", "f", "", "the yaml file of job")
    66  }
    67  
    68  var jobName = "job.volcano.sh"
    69  
    70  // RunJob creates the job.
    71  func RunJob() error {
    72  	config, err := util.BuildConfig(launchJobFlags.Master, launchJobFlags.Kubeconfig)
    73  	if err != nil {
    74  		return err
    75  	}
    76  
    77  	if launchJobFlags.Name == "" && launchJobFlags.FileName == "" {
    78  		err = fmt.Errorf("job name cannot be left blank")
    79  		return err
    80  	}
    81  
    82  	req, err := populateResourceListV1(launchJobFlags.Requests)
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	limit, err := populateResourceListV1(launchJobFlags.Limits)
    88  	if err != nil {
    89  		return err
    90  	}
    91  
    92  	job, err := readFile(launchJobFlags.FileName)
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	if job == nil {
    98  		job = constructLaunchJobFlagsJob(launchJobFlags, req, limit)
    99  	}
   100  
   101  	jobClient := versioned.NewForConfigOrDie(config)
   102  	newJob, err := jobClient.BatchV1alpha1().Jobs(launchJobFlags.Namespace).Create(context.TODO(), job, metav1.CreateOptions{})
   103  	if err != nil {
   104  		return err
   105  	}
   106  
   107  	if newJob.Spec.Queue == "" {
   108  		newJob.Spec.Queue = "default"
   109  	}
   110  
   111  	fmt.Printf("run job %v successfully\n", newJob.Name)
   112  
   113  	return nil
   114  }
   115  
   116  func readFile(filename string) (*vcbatch.Job, error) {
   117  	if filename == "" {
   118  		return nil, nil
   119  	}
   120  
   121  	if !strings.Contains(filename, ".yaml") && !strings.Contains(filename, ".yml") {
   122  		return nil, fmt.Errorf("only support yaml file")
   123  	}
   124  
   125  	file, err := os.ReadFile(filename)
   126  	if err != nil {
   127  		return nil, fmt.Errorf("failed to read file, err: %v", err)
   128  	}
   129  
   130  	var job vcbatch.Job
   131  	if err := yaml.Unmarshal(file, &job); err != nil {
   132  		return nil, fmt.Errorf("failed to unmarshal file, err:  %v", err)
   133  	}
   134  
   135  	return &job, nil
   136  }
   137  
   138  func constructLaunchJobFlagsJob(launchJobFlags *runFlags, req, limit v1.ResourceList) *vcbatch.Job {
   139  	return &vcbatch.Job{
   140  		ObjectMeta: metav1.ObjectMeta{
   141  			Name:      launchJobFlags.Name,
   142  			Namespace: launchJobFlags.Namespace,
   143  		},
   144  		Spec: vcbatch.JobSpec{
   145  			MinAvailable:  int32(launchJobFlags.MinAvailable),
   146  			SchedulerName: launchJobFlags.SchedulerName,
   147  			Tasks: []vcbatch.TaskSpec{
   148  				{
   149  					Replicas: int32(launchJobFlags.Replicas),
   150  
   151  					Template: v1.PodTemplateSpec{
   152  						ObjectMeta: metav1.ObjectMeta{
   153  							Name:   launchJobFlags.Name,
   154  							Labels: map[string]string{jobName: launchJobFlags.Name},
   155  						},
   156  						Spec: v1.PodSpec{
   157  							RestartPolicy: v1.RestartPolicyNever,
   158  							Containers: []v1.Container{
   159  								{
   160  									Image:           launchJobFlags.Image,
   161  									Name:            launchJobFlags.Name,
   162  									ImagePullPolicy: v1.PullIfNotPresent,
   163  									Resources: v1.ResourceRequirements{
   164  										Limits:   limit,
   165  										Requests: req,
   166  									},
   167  								},
   168  							},
   169  						},
   170  					},
   171  				},
   172  			},
   173  		},
   174  	}
   175  }