mirror of https://github.com/knative/client.git
Adds service get command (#90)
* Adds service get command replaces service list command * Updates go.mod and vendors/* * Adds message if no services found in requested namespace * Adds tests for service get
This commit is contained in:
parent
6582e8239a
commit
bd7d57fa09
2
go.mod
2
go.mod
|
|
@ -16,7 +16,7 @@ require (
|
|||
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.6 // indirect
|
||||
github.com/knative/build v0.5.0 // indirect
|
||||
github.com/knative/pkg v0.0.0-20190329155329-916205998db9 // indirect
|
||||
github.com/knative/pkg v0.0.0-20190329155329-916205998db9
|
||||
github.com/knative/serving v0.5.2
|
||||
github.com/knative/test-infra v0.0.0-20190509163238-a721698dbe49
|
||||
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a // indirect
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright © 2019 The Knative Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
hprinters "github.com/knative/client/pkg/printers"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// HumanPrintFlags provides default flags necessary for printing.
|
||||
// Given the following flag values, a printer can be requested that knows
|
||||
// how to handle printing based on these values.
|
||||
type HumanPrintFlags struct {
|
||||
//TODO: Add more flags as required
|
||||
}
|
||||
|
||||
// AllowedFormats returns more customized formating options
|
||||
func (f *HumanPrintFlags) AllowedFormats() []string {
|
||||
// TODO: Add more formats eg: wide
|
||||
return []string{""}
|
||||
}
|
||||
|
||||
// ToPrinter receives returns a printer capable of
|
||||
// handling human-readable output.
|
||||
func (f *HumanPrintFlags) ToPrinter() (hprinters.ResourcePrinter, error) {
|
||||
p := hprinters.NewTablePrinter(hprinters.PrintOptions{})
|
||||
// Add the column definitions and respective functions
|
||||
ServiceGetHandlers(p)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// AddFlags receives a *cobra.Command reference and binds
|
||||
// flags related to human-readable printing to it
|
||||
func (f *HumanPrintFlags) AddFlags(c *cobra.Command) {
|
||||
//TODO: Add more flags as required
|
||||
}
|
||||
|
||||
// NewHumanPrintFlags returns flags associated with
|
||||
// human-readable printing, with default values set.
|
||||
func NewHumanPrintFlags() *HumanPrintFlags {
|
||||
return &HumanPrintFlags{}
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ func NewServiceCommand(p *KnParams) *cobra.Command {
|
|||
Use: "service",
|
||||
Short: "Service command group",
|
||||
}
|
||||
serviceCmd.AddCommand(NewServiceListCommand(p))
|
||||
serviceCmd.AddCommand(NewServiceGetCommand(p))
|
||||
serviceCmd.AddCommand(NewServiceDescribeCommand(p))
|
||||
serviceCmd.AddCommand(NewServiceCreateCommand(p))
|
||||
serviceCmd.AddCommand(NewServiceDeleteCommand(p))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright © 2018 The Knative Authors
|
||||
// Copyright © 2019 The Knative Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
|
@ -15,21 +15,20 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
)
|
||||
|
||||
var serviceListPrintFlags *genericclioptions.PrintFlags
|
||||
// NewServiceGetCommand represents 'kn service get' command
|
||||
func NewServiceGetCommand(p *KnParams) *cobra.Command {
|
||||
serviceGetFlags := NewServiceGetFlags()
|
||||
|
||||
// listCmd represents the list command
|
||||
func NewServiceListCommand(p *KnParams) *cobra.Command {
|
||||
serviceListPrintFlags := genericclioptions.NewPrintFlags("").WithDefaultOutput(
|
||||
"jsonpath={range .items[*]}{.metadata.name}{\"\\n\"}{end}")
|
||||
serviceListCommand := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List available services.",
|
||||
serviceGetCommand := &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Get available services.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
client, err := p.ServingFactory()
|
||||
if err != nil {
|
||||
|
|
@ -43,15 +42,20 @@ func NewServiceListCommand(p *KnParams) *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printer, err := serviceListPrintFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return err
|
||||
if len(service.Items) == 0 {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "No resources found.\n")
|
||||
return nil
|
||||
}
|
||||
service.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{
|
||||
Group: "knative.dev",
|
||||
Version: "v1alpha1",
|
||||
Kind: "Service"})
|
||||
|
||||
printer, err := serviceGetFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = printer.PrintObj(service, cmd.OutOrStdout())
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -59,7 +63,7 @@ func NewServiceListCommand(p *KnParams) *cobra.Command {
|
|||
return nil
|
||||
},
|
||||
}
|
||||
AddNamespaceFlags(serviceListCommand.Flags(), true)
|
||||
serviceListPrintFlags.AddFlags(serviceListCommand)
|
||||
return serviceListCommand
|
||||
AddNamespaceFlags(serviceGetCommand.Flags(), true)
|
||||
serviceGetFlags.AddFlags(serviceGetCommand)
|
||||
return serviceGetCommand
|
||||
}
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
// Copyright © 2019 The Knative Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or im
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
hprinters "github.com/knative/client/pkg/printers"
|
||||
duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1"
|
||||
servingv1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1"
|
||||
"github.com/spf13/cobra"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/duration"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ServiceGetFlags composes common printer flag structs
|
||||
// used in the Get command.
|
||||
type ServiceGetFlags struct {
|
||||
GenericPrintFlags *genericclioptions.PrintFlags
|
||||
HumanReadableFlags *HumanPrintFlags
|
||||
}
|
||||
|
||||
// AllowedFormats is the list of formats in which data can be displayed
|
||||
func (f *ServiceGetFlags) AllowedFormats() []string {
|
||||
formats := f.GenericPrintFlags.AllowedFormats()
|
||||
formats = append(formats, f.HumanReadableFlags.AllowedFormats()...)
|
||||
return formats
|
||||
}
|
||||
|
||||
// ToPrinter attempts to find a composed set of ServiceGetFlags suitable for
|
||||
// returning a printer based on current flag values.
|
||||
func (f *ServiceGetFlags) ToPrinter() (hprinters.ResourcePrinter, error) {
|
||||
// if there are flags specified for generic printing
|
||||
if f.GenericPrintFlags.OutputFlagSpecified() {
|
||||
p, err := f.GenericPrintFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
// if no flags specified, use the table printing
|
||||
p, err := f.HumanReadableFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// AddFlags receives a *cobra.Command reference and binds
|
||||
// flags related to humanreadable and template printing.
|
||||
func (f *ServiceGetFlags) AddFlags(cmd *cobra.Command) {
|
||||
f.GenericPrintFlags.AddFlags(cmd)
|
||||
f.HumanReadableFlags.AddFlags(cmd)
|
||||
}
|
||||
|
||||
// NewGetPrintFlags returns flags associated with humanreadable,
|
||||
// template, and "name" printing, with default values set.
|
||||
func NewServiceGetFlags() *ServiceGetFlags {
|
||||
return &ServiceGetFlags{
|
||||
GenericPrintFlags: genericclioptions.NewPrintFlags(""),
|
||||
HumanReadableFlags: NewHumanPrintFlags(),
|
||||
}
|
||||
}
|
||||
|
||||
// ServiceGetHandlers adds print handlers for service get command
|
||||
func ServiceGetHandlers(h hprinters.PrintHandler) {
|
||||
kServiceColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Description: "Name of the knative service."},
|
||||
{Name: "Domain", Type: "string", Description: "Domain name of the knative service."},
|
||||
//{Name: "LastCreatedRevision", Type: "string", Description: "Name of last revision created."},
|
||||
//{Name: "LastReadyRevision", Type: "string", Description: "Name of last ready revision."},
|
||||
{Name: "Generation", Type: "integer", Description: "Sequence number of 'Generation' of the service that was last processed by the controller."},
|
||||
{Name: "Age", Type: "string", Description: "Age of the service."},
|
||||
{Name: "Conditions", Type: "string", Description: "Conditions describing statuses of service components."},
|
||||
{Name: "Ready", Type: "string", Description: "Ready condition status of the service."},
|
||||
{Name: "Reason", Type: "string", Description: "Reason for non-ready condition of the service."},
|
||||
}
|
||||
h.TableHandler(kServiceColumnDefinitions, printKService)
|
||||
h.TableHandler(kServiceColumnDefinitions, printKServiceList)
|
||||
}
|
||||
|
||||
// conditionsValue returns the True conditions count among total conditions
|
||||
func conditionsValue(conditions duckv1alpha1.Conditions) string {
|
||||
var ok int
|
||||
for _, condition := range conditions {
|
||||
if condition.Status == "True" {
|
||||
ok++
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%d OK / %d", ok, len(conditions))
|
||||
}
|
||||
|
||||
// readyCondition returns status of resource's Ready type condition
|
||||
func readyCondition(conditions duckv1alpha1.Conditions) string {
|
||||
for _, condition := range conditions {
|
||||
if condition.Type == duckv1alpha1.ConditionReady {
|
||||
return string(condition.Status)
|
||||
}
|
||||
}
|
||||
return "<unknown>"
|
||||
}
|
||||
|
||||
func nonReadyConditionReason(conditions duckv1alpha1.Conditions) string {
|
||||
for _, condition := range conditions {
|
||||
if condition.Type == duckv1alpha1.ConditionReady {
|
||||
if string(condition.Status) == "True" {
|
||||
return ""
|
||||
}
|
||||
if condition.Message != "" {
|
||||
return fmt.Sprintf("%s : %s", condition.Reason, condition.Message)
|
||||
}
|
||||
return string(condition.Reason)
|
||||
}
|
||||
}
|
||||
return "<unknown>"
|
||||
}
|
||||
|
||||
// translateTimestampSince returns the elapsed time since timestamp in
|
||||
// human-readable approximation.
|
||||
func translateTimestampSince(timestamp metav1.Time) string {
|
||||
if timestamp.IsZero() {
|
||||
return "<unknown>"
|
||||
}
|
||||
return duration.HumanDuration(time.Since(timestamp.Time))
|
||||
}
|
||||
|
||||
// printKServiceList populates the knative service list table rows
|
||||
func printKServiceList(kServiceList *servingv1alpha1.ServiceList, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
rows := make([]metav1beta1.TableRow, 0, len(kServiceList.Items))
|
||||
for _, ksvc := range kServiceList.Items {
|
||||
r, err := printKService(&ksvc, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows = append(rows, r...)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// printKService populates the knative service table rows
|
||||
func printKService(kService *servingv1alpha1.Service, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
name := kService.Name
|
||||
domain := kService.Status.Domain
|
||||
//lastCreatedRevision := kService.Status.LatestCreatedRevisionName
|
||||
//lastReadyRevision := kService.Status.LatestReadyRevisionName
|
||||
generation := kService.Status.ObservedGeneration
|
||||
age := translateTimestampSince(kService.CreationTimestamp)
|
||||
conditions := conditionsValue(kService.Status.Conditions)
|
||||
ready := readyCondition(kService.Status.Conditions)
|
||||
reason := nonReadyConditionReason(kService.Status.Conditions)
|
||||
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: kService},
|
||||
}
|
||||
row.Cells = append(row.Cells,
|
||||
name,
|
||||
domain,
|
||||
//lastCreatedRevision,
|
||||
//lastReadyRevision,
|
||||
generation,
|
||||
age,
|
||||
conditions,
|
||||
ready,
|
||||
reason)
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
|
@ -19,6 +19,8 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
//servinglib "github.com/knative/client/pkg/serving"
|
||||
duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1"
|
||||
"github.com/knative/serving/pkg/apis/serving/v1alpha1"
|
||||
serving "github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1"
|
||||
"github.com/knative/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake"
|
||||
|
|
@ -27,7 +29,7 @@ import (
|
|||
client_testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func fakeList(args []string, response *v1alpha1.ServiceList) (action client_testing.Action, output []string, err error) {
|
||||
func fakeGet(args []string, response *v1alpha1.ServiceList) (action client_testing.Action, output []string, err error) {
|
||||
buf := new(bytes.Buffer)
|
||||
fakeServing := &fake.FakeServingV1alpha1{&client_testing.Fake{}}
|
||||
cmd := NewKnCommand(KnParams{
|
||||
|
|
@ -48,58 +50,67 @@ func fakeList(args []string, response *v1alpha1.ServiceList) (action client_test
|
|||
return
|
||||
}
|
||||
|
||||
func TestListEmpty(t *testing.T) {
|
||||
action, output, err := fakeList([]string{"service", "list"}, &v1alpha1.ServiceList{})
|
||||
func TestGetEmpty(t *testing.T) {
|
||||
action, output, err := fakeGet([]string{"service", "get"}, &v1alpha1.ServiceList{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
for _, s := range output {
|
||||
if s != "" {
|
||||
t.Errorf("Bad output line %v", s)
|
||||
}
|
||||
}
|
||||
if action == nil {
|
||||
t.Errorf("No action")
|
||||
} else if !action.Matches("list", "services") {
|
||||
t.Errorf("Bad action %v", action)
|
||||
} else if output[0] != "No resources found." {
|
||||
t.Errorf("Bad output %s", output[0])
|
||||
}
|
||||
}
|
||||
|
||||
var serviceType = metav1.TypeMeta{
|
||||
Kind: "service",
|
||||
APIVersion: "serving.knative.dev/v1alpha1",
|
||||
}
|
||||
|
||||
func TestListDefaultOutput(t *testing.T) {
|
||||
action, output, err := fakeList([]string{"service", "list"}, &v1alpha1.ServiceList{
|
||||
Items: []v1alpha1.Service{
|
||||
v1alpha1.Service{
|
||||
TypeMeta: serviceType,
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
},
|
||||
v1alpha1.Service{
|
||||
TypeMeta: serviceType,
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
service1 := createMockServiceWithParams(t, "foo", "foo.default.example.com", 1)
|
||||
service2 := createMockServiceWithParams(t, "bar", "bar.default.example.com", 2)
|
||||
serviceList := &v1alpha1.ServiceList{Items: []v1alpha1.Service{*service1, *service2}}
|
||||
action, output, err := fakeGet([]string{"service", "get"}, serviceList)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected := []string{"foo", "bar", ""}
|
||||
for i, s := range output {
|
||||
if s != expected[i] {
|
||||
t.Errorf("Bad output line %v expected %v", s, expected[i])
|
||||
}
|
||||
}
|
||||
if action == nil {
|
||||
t.Errorf("No action")
|
||||
} else if !action.Matches("list", "services") {
|
||||
t.Errorf("Bad action %v", action)
|
||||
}
|
||||
testContains(t, output[0], []string{"NAME", "DOMAIN", "GENERATION", "AGE", "CONDITIONS", "READY", "REASON"}, "column header")
|
||||
testContains(t, output[1], []string{"foo", "foo.default.example.com", "1"}, "value")
|
||||
testContains(t, output[2], []string{"bar", "bar.default.example.com", "2"}, "value")
|
||||
}
|
||||
|
||||
func testContains(t *testing.T, output string, sub []string, element string) {
|
||||
for _, each := range sub {
|
||||
if !strings.Contains(output, each) {
|
||||
t.Errorf("Missing %s: %s", element, each)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createMockServiceWithParams(t *testing.T, name, domain string, generation int64) *v1alpha1.Service {
|
||||
service := &v1alpha1.Service{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Service",
|
||||
APIVersion: "knative.dev/v1alpha1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: v1alpha1.ServiceSpec{
|
||||
RunLatest: &v1alpha1.RunLatestType{},
|
||||
},
|
||||
Status: v1alpha1.ServiceStatus{
|
||||
Status: duckv1alpha1.Status{
|
||||
ObservedGeneration: generation},
|
||||
RouteStatusFields: v1alpha1.RouteStatusFields{
|
||||
Domain: domain,
|
||||
},
|
||||
},
|
||||
}
|
||||
return service
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package duration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ShortHumanDuration returns a succint representation of the provided duration
|
||||
// with limited precision for consumption by humans.
|
||||
func ShortHumanDuration(d time.Duration) string {
|
||||
// Allow deviation no more than 2 seconds(excluded) to tolerate machine time
|
||||
// inconsistence, it can be considered as almost now.
|
||||
if seconds := int(d.Seconds()); seconds < -1 {
|
||||
return fmt.Sprintf("<invalid>")
|
||||
} else if seconds < 0 {
|
||||
return fmt.Sprintf("0s")
|
||||
} else if seconds < 60 {
|
||||
return fmt.Sprintf("%ds", seconds)
|
||||
} else if minutes := int(d.Minutes()); minutes < 60 {
|
||||
return fmt.Sprintf("%dm", minutes)
|
||||
} else if hours := int(d.Hours()); hours < 24 {
|
||||
return fmt.Sprintf("%dh", hours)
|
||||
} else if hours < 24*365 {
|
||||
return fmt.Sprintf("%dd", hours/24)
|
||||
}
|
||||
return fmt.Sprintf("%dy", int(d.Hours()/24/365))
|
||||
}
|
||||
|
||||
// HumanDuration returns a succint representation of the provided duration
|
||||
// with limited precision for consumption by humans. It provides ~2-3 significant
|
||||
// figures of duration.
|
||||
func HumanDuration(d time.Duration) string {
|
||||
// Allow deviation no more than 2 seconds(excluded) to tolerate machine time
|
||||
// inconsistence, it can be considered as almost now.
|
||||
if seconds := int(d.Seconds()); seconds < -1 {
|
||||
return fmt.Sprintf("<invalid>")
|
||||
} else if seconds < 0 {
|
||||
return fmt.Sprintf("0s")
|
||||
} else if seconds < 60*2 {
|
||||
return fmt.Sprintf("%ds", seconds)
|
||||
}
|
||||
minutes := int(d / time.Minute)
|
||||
if minutes < 10 {
|
||||
s := int(d/time.Second) % 60
|
||||
if s == 0 {
|
||||
return fmt.Sprintf("%dm", minutes)
|
||||
}
|
||||
return fmt.Sprintf("%dm%ds", minutes, s)
|
||||
} else if minutes < 60*3 {
|
||||
return fmt.Sprintf("%dm", minutes)
|
||||
}
|
||||
hours := int(d / time.Hour)
|
||||
if hours < 8 {
|
||||
m := int(d/time.Minute) % 60
|
||||
if m == 0 {
|
||||
return fmt.Sprintf("%dh", hours)
|
||||
}
|
||||
return fmt.Sprintf("%dh%dm", hours, m)
|
||||
} else if hours < 48 {
|
||||
return fmt.Sprintf("%dh", hours)
|
||||
} else if hours < 24*8 {
|
||||
h := hours % 24
|
||||
if h == 0 {
|
||||
return fmt.Sprintf("%dd", hours/24)
|
||||
}
|
||||
return fmt.Sprintf("%dd%dh", hours/24, h)
|
||||
} else if hours < 24*365*2 {
|
||||
return fmt.Sprintf("%dd", hours/24)
|
||||
} else if hours < 24*365*8 {
|
||||
return fmt.Sprintf("%dy%dd", hours/24/365, (hours/24)%365)
|
||||
}
|
||||
return fmt.Sprintf("%dy", int(hours/24/365))
|
||||
}
|
||||
|
|
@ -63,11 +63,11 @@ github.com/json-iterator/go
|
|||
github.com/knative/build/pkg/apis/build/v1alpha1
|
||||
github.com/knative/build/pkg/apis/build
|
||||
# github.com/knative/pkg v0.0.0-20190329155329-916205998db9
|
||||
github.com/knative/pkg/apis
|
||||
github.com/knative/pkg/apis/duck/v1alpha1
|
||||
github.com/knative/pkg/apis
|
||||
github.com/knative/pkg/apis/duck
|
||||
github.com/knative/pkg/kmeta
|
||||
github.com/knative/pkg/kmp
|
||||
github.com/knative/pkg/apis/duck
|
||||
github.com/knative/pkg/configmap
|
||||
# github.com/knative/serving v0.5.2
|
||||
github.com/knative/serving/pkg/apis/serving/v1alpha1
|
||||
|
|
@ -195,10 +195,11 @@ k8s.io/api/storage/v1beta1
|
|||
# k8s.io/apimachinery v0.0.0-20190221084156-01f179d85dbc
|
||||
k8s.io/apimachinery/pkg/api/resource
|
||||
k8s.io/apimachinery/pkg/apis/meta/v1
|
||||
k8s.io/apimachinery/pkg/runtime/schema
|
||||
k8s.io/apimachinery/pkg/api/meta
|
||||
k8s.io/apimachinery/pkg/apis/meta/v1beta1
|
||||
k8s.io/apimachinery/pkg/runtime
|
||||
k8s.io/apimachinery/pkg/runtime/schema
|
||||
k8s.io/apimachinery/pkg/util/duration
|
||||
k8s.io/apimachinery/pkg/api/meta
|
||||
k8s.io/apimachinery/pkg/util/runtime
|
||||
k8s.io/apimachinery/pkg/api/equality
|
||||
k8s.io/apimachinery/pkg/api/validation
|
||||
|
|
@ -213,12 +214,12 @@ k8s.io/apimachinery/pkg/conversion
|
|||
k8s.io/apimachinery/pkg/fields
|
||||
k8s.io/apimachinery/pkg/labels
|
||||
k8s.io/apimachinery/pkg/selection
|
||||
k8s.io/apimachinery/pkg/conversion/queryparams
|
||||
k8s.io/apimachinery/pkg/util/errors
|
||||
k8s.io/apimachinery/pkg/util/json
|
||||
k8s.io/apimachinery/pkg/util/naming
|
||||
k8s.io/apimachinery/pkg/util/net
|
||||
k8s.io/apimachinery/pkg/util/yaml
|
||||
k8s.io/apimachinery/pkg/util/errors
|
||||
k8s.io/apimachinery/pkg/conversion/queryparams
|
||||
k8s.io/apimachinery/pkg/util/naming
|
||||
k8s.io/apimachinery/pkg/apis/meta/v1/validation
|
||||
k8s.io/apimachinery/pkg/util/validation/field
|
||||
k8s.io/apimachinery/pkg/runtime/serializer/json
|
||||
|
|
@ -256,6 +257,7 @@ k8s.io/client-go/util/jsonpath
|
|||
k8s.io/client-go/tools/auth
|
||||
k8s.io/client-go/tools/clientcmd/api/latest
|
||||
k8s.io/client-go/testing
|
||||
k8s.io/client-go/dynamic
|
||||
k8s.io/client-go/tools/cache
|
||||
k8s.io/client-go/pkg/version
|
||||
k8s.io/client-go/plugin/pkg/client/auth/exec
|
||||
|
|
@ -267,7 +269,6 @@ k8s.io/client-go/util/flowcontrol
|
|||
k8s.io/client-go/kubernetes/scheme
|
||||
k8s.io/client-go/third_party/forked/golang/template
|
||||
k8s.io/client-go/tools/clientcmd/api/v1
|
||||
k8s.io/client-go/dynamic
|
||||
k8s.io/client-go/tools/pager
|
||||
k8s.io/client-go/util/buffer
|
||||
k8s.io/client-go/util/retry
|
||||
|
|
|
|||
Loading…
Reference in New Issue