volcano.sh/volcano@v1.9.0/pkg/cli/job/util.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  	"time"
    25  
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  
    28  	v1 "k8s.io/api/core/v1"
    29  	"k8s.io/apimachinery/pkg/api/resource"
    30  	"k8s.io/client-go/rest"
    31  
    32  	vcbus "volcano.sh/apis/pkg/apis/bus/v1alpha1"
    33  	"volcano.sh/apis/pkg/apis/helpers"
    34  	"volcano.sh/apis/pkg/client/clientset/versioned"
    35  )
    36  
    37  func homeDir() string {
    38  	if h := os.Getenv("HOME"); h != "" {
    39  		return h
    40  	}
    41  	return os.Getenv("USERPROFILE") // windows
    42  }
    43  
    44  // populateResourceListV1 takes strings of form <resourceName1>=<value1>,<resourceName2>=<value2>
    45  // and returns ResourceList.
    46  func populateResourceListV1(spec string) (v1.ResourceList, error) {
    47  	// empty input gets a nil response to preserve generator test expected behaviors
    48  	if spec == "" {
    49  		return nil, nil
    50  	}
    51  
    52  	result := v1.ResourceList{}
    53  	resourceStatements := strings.Split(spec, ",")
    54  	for _, resourceStatement := range resourceStatements {
    55  		parts := strings.Split(resourceStatement, "=")
    56  		if len(parts) != 2 {
    57  			return nil, fmt.Errorf("invalid argument syntax %v, expected <resource>=<value>", resourceStatement)
    58  		}
    59  		resourceName := v1.ResourceName(parts[0])
    60  		resourceQuantity, err := resource.ParseQuantity(parts[1])
    61  		if err != nil {
    62  			return nil, err
    63  		}
    64  		result[resourceName] = resourceQuantity
    65  	}
    66  	return result, nil
    67  }
    68  
    69  func createJobCommand(config *rest.Config, ns, name string, action vcbus.Action) error {
    70  	jobClient := versioned.NewForConfigOrDie(config)
    71  	job, err := jobClient.BatchV1alpha1().Jobs(ns).Get(context.TODO(), name, metav1.GetOptions{})
    72  	if err != nil {
    73  		return err
    74  	}
    75  
    76  	ctrlRef := metav1.NewControllerRef(job, helpers.JobKind)
    77  	cmd := &vcbus.Command{
    78  		ObjectMeta: metav1.ObjectMeta{
    79  			GenerateName: fmt.Sprintf("%s-%s-",
    80  				job.Name, strings.ToLower(string(action))),
    81  			Namespace: job.Namespace,
    82  			OwnerReferences: []metav1.OwnerReference{
    83  				*ctrlRef,
    84  			},
    85  		},
    86  		TargetObject: ctrlRef,
    87  		Action:       string(action),
    88  	}
    89  
    90  	if _, err := jobClient.BusV1alpha1().Commands(ns).Create(context.TODO(), cmd, metav1.CreateOptions{}); err != nil {
    91  		return err
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  func translateTimestampSince(timestamp metav1.Time) string {
    98  	if timestamp.IsZero() {
    99  		return "<unknown>"
   100  	}
   101  	return HumanDuration(time.Since(timestamp.Time))
   102  }
   103  
   104  // HumanDuration translate time.Duration to human readable time string.
   105  func HumanDuration(d time.Duration) string {
   106  	// Allow deviation no more than 2 seconds(excluded) to tolerate machine time
   107  	// inconsistence, it can be considered as almost now.
   108  	if seconds := int(d.Seconds()); seconds < -1 {
   109  		return "<invalid>"
   110  	} else if seconds < 0 {
   111  		return "0s"
   112  	} else if seconds < 60*2 {
   113  		return fmt.Sprintf("%ds", seconds)
   114  	}
   115  	minutes := int(d / time.Minute)
   116  	if minutes < 10 {
   117  		s := int(d/time.Second) % 60
   118  		if s == 0 {
   119  			return fmt.Sprintf("%dm", minutes)
   120  		}
   121  		return fmt.Sprintf("%dm%ds", minutes, s)
   122  	} else if minutes < 60*3 {
   123  		return fmt.Sprintf("%dm", minutes)
   124  	}
   125  	hours := int(d / time.Hour)
   126  	if hours < 8 {
   127  		m := int(d/time.Minute) % 60
   128  		if m == 0 {
   129  			return fmt.Sprintf("%dh", hours)
   130  		}
   131  		return fmt.Sprintf("%dh%dm", hours, m)
   132  	} else if hours < 48 {
   133  		return fmt.Sprintf("%dh", hours)
   134  	} else if hours < 24*8 {
   135  		h := hours % 24
   136  		if h == 0 {
   137  			return fmt.Sprintf("%dd", hours/24)
   138  		}
   139  		return fmt.Sprintf("%dd%dh", hours/24, h)
   140  	} else if hours < 24*365*2 {
   141  		return fmt.Sprintf("%dd", hours/24)
   142  	} else if hours < 24*365*8 {
   143  		return fmt.Sprintf("%dy%dd", hours/24/365, (hours/24)%365)
   144  	}
   145  	return fmt.Sprintf("%dy", hours/24/365)
   146  }