Update godeps

This commit is contained in:
Manuel de Brito Fontes 2016-07-11 23:42:47 -04:00
parent 8b25cc67a5
commit a736fba0e1
769 changed files with 15495 additions and 7996 deletions

View file

@ -1,5 +1,4 @@
assignees:
- bgrant0607
- brendandburns
- deads2k
- janetkuo

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Copyright 2015 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Copyright 2015 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -48,6 +48,7 @@ import (
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/autoscaling"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/certificates"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/apis/rbac"
@ -253,14 +254,14 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
// have been dynamically added to the apiserver
Object: func(discoverDynamicAPIs bool) (meta.RESTMapper, runtime.ObjectTyper) {
cfg, err := clientConfig.ClientConfig()
CheckErr(err)
checkErrWithPrefix("failed to get client config: ", err)
cmdApiVersion := unversioned.GroupVersion{}
if cfg.GroupVersion != nil {
cmdApiVersion = *cfg.GroupVersion
}
if discoverDynamicAPIs {
client, err := clients.ClientForVersion(&unversioned.GroupVersion{Version: "v1"})
CheckErr(err)
checkErrWithPrefix("failed to find client for version v1: ", err)
var versions []unversioned.GroupVersion
var gvks []unversioned.GroupVersionKind
@ -274,7 +275,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
break
}
}
CheckErr(err)
checkErrWithPrefix("failed to get third-party group versions: ", err)
if len(versions) > 0 {
priorityMapper, ok := mapper.RESTMapper.(meta.PriorityRESTMapper)
if !ok {
@ -294,7 +295,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
preferredExternalVersion := versionList[0]
thirdPartyMapper, err := kubectl.NewThirdPartyResourceMapper(versionList, getGroupVersionKinds(gvks, group))
CheckErr(err)
checkErrWithPrefix("failed to create third party resource mapper: ", err)
accessor := meta.NewAccessor()
groupMeta := apimachinery.GroupMeta{
GroupVersion: preferredExternalVersion,
@ -304,7 +305,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
InterfacesFor: makeInterfacesFor(versionList),
}
CheckErr(registered.RegisterGroup(groupMeta))
checkErrWithPrefix("failed to register group: ", registered.RegisterGroup(groupMeta))
registered.AddThirdPartyAPIGroupVersions(versionList...)
multiMapper = append(meta.MultiRESTMapper{thirdPartyMapper}, multiMapper...)
}
@ -366,6 +367,8 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
return clients.FederationClientForVersion(&mappingVersion)
case rbac.GroupName:
return c.RbacClient.RESTClient, nil
case certificates.GroupName:
return c.CertificatesClient.RESTClient, nil
default:
if !registered.IsThirdPartyAPIGroupVersion(gvk.GroupVersion()) {
return nil, fmt.Errorf("unknown api group/version: %s", gvk.String())
@ -377,7 +380,6 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
gv := gvk.GroupVersion()
cfg.GroupVersion = &gv
cfg.APIPath = "/apis"
cfg.Codec = thirdpartyresourcedata.NewCodec(c.ExtensionsClient.RESTClient.Codec(), gvk)
cfg.NegotiatedSerializer = thirdpartyresourcedata.NewNegotiatedSerializer(api.Codecs, gvk.Kind, gv, gv)
return restclient.RESTClientFor(cfg)
}
@ -520,7 +522,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
return nil, errors.New("provided options object is not a PodLogOptions")
}
selector := labels.SelectorFromSet(t.Spec.Selector)
sortBy := func(pods []*api.Pod) sort.Interface { return controller.ActivePods(pods) }
sortBy := func(pods []*api.Pod) sort.Interface { return controller.ByLogging(pods) }
pod, numPods, err := GetFirstPod(c, t.Namespace, selector, 20*time.Second, sortBy)
if err != nil {
return nil, err
@ -540,7 +542,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
if err != nil {
return nil, fmt.Errorf("invalid label selector: %v", err)
}
sortBy := func(pods []*api.Pod) sort.Interface { return controller.ActivePods(pods) }
sortBy := func(pods []*api.Pod) sort.Interface { return controller.ByLogging(pods) }
pod, numPods, err := GetFirstPod(c, t.Namespace, selector, 20*time.Second, sortBy)
if err != nil {
return nil, err
@ -800,7 +802,7 @@ See http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md for more d
// GetFirstPod returns a pod matching the namespace and label selector
// and the number of all pods that match the label selector.
func GetFirstPod(client client.Interface, namespace string, selector labels.Selector, timeout time.Duration, sortBy func([]*api.Pod) sort.Interface) (*api.Pod, int, error) {
func GetFirstPod(client client.PodsNamespacer, namespace string, selector labels.Selector, timeout time.Duration, sortBy func([]*api.Pod) sort.Interface) (*api.Pod, int, error) {
options := api.ListOptions{LabelSelector: selector}
podList, err := client.Pods(namespace).List(options)
@ -1104,6 +1106,12 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
}
return getSchemaAndValidate(c.fedc, data, "apis/", gvk.GroupVersion().String(), c.cacheDir, c)
}
if gvk.Group == certificates.GroupName {
if c.c.CertificatesClient == nil {
return errors.New("unable to validate: no certificates client")
}
return getSchemaAndValidate(c.c.CertificatesClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir, c)
}
return getSchemaAndValidate(c.c.RESTClient, data, "api", gvk.GroupVersion().String(), c.cacheDir, c)
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -105,17 +105,22 @@ func fatal(msg string) {
// This method is generic to the command in use and may be used by non-Kubectl
// commands.
func CheckErr(err error) {
checkErr(err, fatalErrHandler)
checkErr("", err, fatalErrHandler)
}
func checkErr(err error, handleErr func(string)) {
// checkErrWithPrefix works like CheckErr, but adds a caller-defined prefix to non-nil errors
func checkErrWithPrefix(prefix string, err error) {
checkErr(prefix, err, fatalErrHandler)
}
func checkErr(pref string, err error, handleErr func(string)) {
if err == nil {
return
}
if errors.IsInvalid(err) {
details := err.(*errors.StatusError).Status().Details
prefix := fmt.Sprintf("The %s %q is invalid.\n", details.Kind, details.Name)
prefix := fmt.Sprintf("%sThe %s %q is invalid.\n", pref, details.Kind, details.Name)
errs := statusCausesToAggrError(details.Causes)
handleErr(MultilineError(prefix, errs))
}
@ -125,23 +130,23 @@ func checkErr(err error, handleErr func(string)) {
switch {
case len(noMatch.PartialResource.Group) > 0 && len(noMatch.PartialResource.Version) > 0:
handleErr(fmt.Sprintf("the server doesn't have a resource type %q in group %q and version %q", noMatch.PartialResource.Resource, noMatch.PartialResource.Group, noMatch.PartialResource.Version))
handleErr(fmt.Sprintf("%sthe server doesn't have a resource type %q in group %q and version %q", pref, noMatch.PartialResource.Resource, noMatch.PartialResource.Group, noMatch.PartialResource.Version))
case len(noMatch.PartialResource.Group) > 0:
handleErr(fmt.Sprintf("the server doesn't have a resource type %q in group %q", noMatch.PartialResource.Resource, noMatch.PartialResource.Group))
handleErr(fmt.Sprintf("%sthe server doesn't have a resource type %q in group %q", pref, noMatch.PartialResource.Resource, noMatch.PartialResource.Group))
case len(noMatch.PartialResource.Version) > 0:
handleErr(fmt.Sprintf("the server doesn't have a resource type %q in version %q", noMatch.PartialResource.Resource, noMatch.PartialResource.Version))
handleErr(fmt.Sprintf("%sthe server doesn't have a resource type %q in version %q", pref, noMatch.PartialResource.Resource, noMatch.PartialResource.Version))
default:
handleErr(fmt.Sprintf("the server doesn't have a resource type %q", noMatch.PartialResource.Resource))
handleErr(fmt.Sprintf("%sthe server doesn't have a resource type %q", pref, noMatch.PartialResource.Resource))
}
return
}
// handle multiline errors
if clientcmd.IsConfigurationInvalid(err) {
handleErr(MultilineError("Error in configuration: ", err))
handleErr(MultilineError(fmt.Sprintf("%sError in configuration: ", pref), err))
}
if agg, ok := err.(utilerrors.Aggregate); ok && len(agg.Errors()) > 0 {
handleErr(MultipleErrors("", agg.Errors()))
handleErr(MultipleErrors(pref, agg.Errors()))
}
msg, ok := StandardErrorMessage(err)
@ -151,7 +156,7 @@ func checkErr(err error, handleErr func(string)) {
msg = fmt.Sprintf("error: %s", msg)
}
}
handleErr(msg)
handleErr(fmt.Sprintf("%s%s", pref, msg))
}
func statusCausesToAggrError(scs []unversioned.StatusCause) utilerrors.Aggregate {

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -30,9 +30,9 @@ import (
// AddPrinterFlags adds printing related flags to a command (e.g. output format, no headers, template path)
func AddPrinterFlags(cmd *cobra.Command) {
cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml|wide|name|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=... See golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [http://releases.k8s.io/HEAD/docs/user-guide/jsonpath.md].")
AddOutputFlags(cmd)
cmd.Flags().String("output-version", "", "Output the formatted object with the given group version (for ex: 'extensions/v1beta1').")
cmd.Flags().Bool("no-headers", false, "When using the default output, don't print headers.")
AddNoHeadersFlags(cmd)
cmd.Flags().Bool("show-labels", false, "When printing, show all labels as the last column (default hide labels column)")
cmd.Flags().String("template", "", "Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].")
cmd.MarkFlagFilename("template")
@ -45,6 +45,16 @@ func AddOutputFlagsForMutation(cmd *cobra.Command) {
cmd.Flags().StringP("output", "o", "", "Output mode. Use \"-o name\" for shorter output (resource/name).")
}
// AddOutputFlags adds output related flags to a command.
func AddOutputFlags(cmd *cobra.Command) {
cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml|wide|name|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=... See golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [http://kubernetes.io/docs/user-guide/jsonpath].")
}
// AddNoHeadersFlags adds no-headers flags to a command.
func AddNoHeadersFlags(cmd *cobra.Command) {
cmd.Flags().Bool("no-headers", false, "When using the default or custom-column output format, don't print headers.")
}
// PrintSuccess prints message after finishing mutating operations
func PrintSuccess(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource string, name string, operation string) {
resource, _ = mapper.ResourceSingularizer(resource)
@ -111,7 +121,7 @@ func PrinterForCommand(cmd *cobra.Command) (kubectl.ResourcePrinter, bool, error
}
}
printer, generic, err := kubectl.GetPrinter(outputFormat, templateFile)
printer, generic, err := kubectl.GetPrinter(outputFormat, templateFile, GetFlagBool(cmd, "no-headers"))
if err != nil {
return nil, generic, err
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Copyright 2016 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.
@ -24,8 +24,8 @@ import (
"strings"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/validation"
)
// ConfigMapGeneratorV1 supports stable generation of a configMap.
@ -199,10 +199,9 @@ func addKeyFromFileToConfigMap(configMap *api.ConfigMap, keyName, filePath strin
// addKeyFromLiteralToConfigMap adds the given key and data to the given config map,
// returning an error if the key is not valid or if the key already exists.
func addKeyFromLiteralToConfigMap(configMap *api.ConfigMap, keyName, data string) error {
// Note, the rules for ConfigMap keys are the exact same as the ones for SecretKeys
// to be consistent; validation.IsSecretKey is used here intentionally.
if !validation.IsSecretKey(keyName) {
return fmt.Errorf("%v is not a valid key name for a configMap", keyName)
// Note, the rules for ConfigMap keys are the exact same as the ones for SecretKeys.
if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 {
return fmt.Errorf("%q is not a valid key name for a ConfigMap: %s", keyName, strings.Join(errs, ";"))
}
if _, entryExists := configMap.Data[keyName]; entryExists {
return fmt.Errorf("cannot add key %s, another key by that name already exists: %v.", keyName, configMap.Data)

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -73,7 +73,7 @@ func massageJSONPath(pathExpression string) (string, error) {
//
// NAME API_VERSION
// foo bar
func NewCustomColumnsPrinterFromSpec(spec string, decoder runtime.Decoder) (*CustomColumnsPrinter, error) {
func NewCustomColumnsPrinterFromSpec(spec string, decoder runtime.Decoder, noHeaders bool) (*CustomColumnsPrinter, error) {
if len(spec) == 0 {
return nil, fmt.Errorf("custom-columns format specified but no custom columns given")
}
@ -90,7 +90,7 @@ func NewCustomColumnsPrinterFromSpec(spec string, decoder runtime.Decoder) (*Cus
}
columns[ix] = Column{Header: colSpec[0], FieldSpec: spec}
}
return &CustomColumnsPrinter{Columns: columns, Decoder: decoder}, nil
return &CustomColumnsPrinter{Columns: columns, Decoder: decoder, NoHeaders: noHeaders}, nil
}
func splitOnWhitespace(line string) []string {
@ -135,7 +135,7 @@ func NewCustomColumnsPrinterFromTemplate(templateReader io.Reader, decoder runti
FieldSpec: spec,
}
}
return &CustomColumnsPrinter{Columns: columns, Decoder: decoder}, nil
return &CustomColumnsPrinter{Columns: columns, Decoder: decoder, NoHeaders: false}, nil
}
// Column represents a user specified column
@ -150,17 +150,21 @@ type Column struct {
// CustomColumnPrinter is a printer that knows how to print arbitrary columns
// of data from templates specified in the `Columns` array
type CustomColumnsPrinter struct {
Columns []Column
Decoder runtime.Decoder
Columns []Column
Decoder runtime.Decoder
NoHeaders bool
}
func (s *CustomColumnsPrinter) PrintObj(obj runtime.Object, out io.Writer) error {
w := tabwriter.NewWriter(out, columnwidth, tabwidth, padding, padding_character, flags)
headers := make([]string, len(s.Columns))
for ix := range s.Columns {
headers[ix] = s.Columns[ix].Header
if !s.NoHeaders {
headers := make([]string, len(s.Columns))
for ix := range s.Columns {
headers[ix] = s.Columns[ix].Header
}
fmt.Fprintln(w, strings.Join(headers, "\t"))
}
fmt.Fprintln(w, strings.Join(headers, "\t"))
parsers := make([]*jsonpath.JSONPath, len(s.Columns))
for ix := range s.Columns {
parsers[ix] = jsonpath.New(fmt.Sprintf("column%d", ix))

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -42,12 +42,12 @@ import (
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
client "k8s.io/kubernetes/pkg/client/unversioned"
adapter "k8s.io/kubernetes/pkg/client/unversioned/adapters/internalclientset"
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
"k8s.io/kubernetes/pkg/fieldpath"
"k8s.io/kubernetes/pkg/fields"
qosutil "k8s.io/kubernetes/pkg/kubelet/qos/util"
"k8s.io/kubernetes/pkg/kubelet/qos"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/types"
deploymentutil "k8s.io/kubernetes/pkg/util/deployment"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/sets"
)
@ -540,7 +540,7 @@ func describePod(pod *api.Pod, events *api.EventList) (string, error) {
}
}
describeVolumes(pod.Spec.Volumes, out, "")
fmt.Fprintf(out, "QoS Tier:\t%s\n", qosutil.GetPodQos(pod))
fmt.Fprintf(out, "QoS Class:\t%s\n", qos.GetPodQOS(pod))
if events != nil {
DescribeEvents(events, out)
}
@ -549,7 +549,7 @@ func describePod(pod *api.Pod, events *api.EventList) (string, error) {
}
func printControllers(annotation map[string]string) string {
value, ok := annotation["kubernetes.io/created-by"]
value, ok := annotation[api.CreatedByAnnotation]
if ok {
var r api.SerializedReference
err := json.Unmarshal([]byte(value), &r)
@ -887,7 +887,28 @@ func describeContainers(label string, containers []api.Container, containerStatu
probe := DescribeProbe(container.ReadinessProbe)
fmt.Fprintf(out, " Readiness:\t%s\n", probe)
}
none := ""
if len(container.VolumeMounts) == 0 {
none = "\t<none>"
}
fmt.Fprintf(out, " Volume Mounts:%s\n", none)
sort.Sort(SortableVolumeMounts(container.VolumeMounts))
for _, mount := range container.VolumeMounts {
flags := []string{}
switch {
case mount.ReadOnly:
flags = append(flags, "ro")
case !mount.ReadOnly:
flags = append(flags, "rw")
case len(mount.SubPath) > 0:
flags = append(flags, fmt.Sprintf("path=%q", mount.SubPath))
}
fmt.Fprintf(out, " %s from %s (%s)\n", mount.MountPath, mount.Name, strings.Join(flags, ","))
}
none = ""
if len(container.Env) == 0 {
none = "\t<none>"
}
@ -1846,7 +1867,7 @@ func describeNodeResource(nodeNonTerminatedPodsList *api.PodList, node *api.Node
memoryReq.String(), int64(fractionMemoryReq), memoryLimit.String(), int64(fractionMemoryLimit))
}
fmt.Fprint(out, "Allocated resources:\n (Total limits may be over 100 percent, i.e., overcommitted. More info: http://releases.k8s.io/HEAD/docs/user-guide/compute-resources.md)\n CPU Requests\tCPU Limits\tMemory Requests\tMemory Limits\n")
fmt.Fprint(out, "Allocated resources:\n (Total limits may be over 100 percent, i.e., overcommitted.\n CPU Requests\tCPU Limits\tMemory Requests\tMemory Limits\n")
fmt.Fprint(out, " ------------\t----------\t---------------\t-------------\n")
reqs, limits, err := getPodsTotalRequestsAndLimits(nodeNonTerminatedPodsList)
if err != nil {
@ -2116,22 +2137,6 @@ func describeCluster(cluster *federation.Cluster) (string, error) {
c.Message)
}
}
fmt.Fprintf(out, "Version:\t%s\n", cluster.Status.Version)
if len(cluster.Status.Capacity) > 0 {
fmt.Fprintf(out, "Capacity:\n")
for resource, value := range cluster.Status.Capacity {
fmt.Fprintf(out, " %s:\t%s\n", resource, value.String())
}
}
if len(cluster.Status.Allocatable) > 0 {
fmt.Fprintf(out, "Allocatable:\n")
for resource, value := range cluster.Status.Allocatable {
fmt.Fprintf(out, " %s:\t%s\n", resource, value.String())
}
}
return nil
})
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Copyright 2016 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.
@ -25,8 +25,8 @@ import (
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
"k8s.io/kubernetes/pkg/runtime"
deploymentutil "k8s.io/kubernetes/pkg/util/deployment"
sliceutil "k8s.io/kubernetes/pkg/util/slice"
)

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -31,11 +31,11 @@ import (
const (
kubectlAnnotationPrefix = "kubectl.kubernetes.io/"
// TODO: auto-generate this
PossibleResourceTypes = `Possible resource types include (case insensitive): pods (po), services (svc), deployments,
replicasets (rs), replicationcontrollers (rc), nodes (no), events (ev), limitranges (limits),
persistentvolumes (pv), persistentvolumeclaims (pvc), resourcequotas (quota), namespaces (ns),
serviceaccounts (sa), ingresses (ing), horizontalpodautoscalers (hpa), daemonsets (ds), configmaps,
componentstatuses (cs), endpoints (ep), and secrets.`
PossibleResourceTypes = `Possible resource types include (case insensitive): pods (aka 'po'), services (aka 'svc'), deployments,
replicasets (aka 'rs'), replicationcontrollers (aka 'rc'), nodes (aka 'no'), events (aka 'ev'), limitranges (aka 'limits'),
persistentvolumes (aka 'pv'), persistentvolumeclaims (aka 'pvc'), resourcequotas (aka 'quota'), namespaces (aka 'ns'),
serviceaccounts (aka 'sa'), ingresses (aka 'ing'), horizontalpodautoscalers (aka 'hpa'), daemonsets (aka 'ds'), configmaps,
componentstatuses (aka 'cs), endpoints (aka 'ep'), petsets (alpha feature, may be unstable) and secrets.`
)
type NamespaceInfo struct {
@ -164,6 +164,19 @@ var shortForms = map[string]string{
"svc": "services",
}
// Look-up for resource short forms by value
func ResourceShortFormFor(resource string) (string, bool) {
var alias string
exists := false
for k, val := range shortForms {
if val == resource {
alias = k
exists = true
}
}
return alias, exists
}
// expandResourceShortcut will return the expanded version of resource
// (something that a pkg/api/meta.RESTMapper can understand), if it is
// indeed a shortcut. Otherwise, will return resource unmodified.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Copyright 2015 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -688,6 +688,9 @@ func (b *Builder) visitorResult() *Result {
return &Result{singular: singular, visitor: visitors, sources: b.paths}
}
if len(b.resources) != 0 {
return &Result{err: fmt.Errorf("resource(s) were provided, but no name, label selector, or --all flag specified")}
}
return &Result{err: fmt.Errorf("you must provide one or more resources by argument or filename (%s)", strings.Join(InputExtensions, "|"))}
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -50,6 +50,15 @@ func (r *Selector) Visit(fn VisitorFunc) error {
list, err := NewHelper(r.Client, r.Mapping).List(r.Namespace, r.ResourceMapping().GroupVersionKind.GroupVersion().String(), r.Selector, r.Export)
if err != nil {
if errors.IsBadRequest(err) || errors.IsNotFound(err) {
if se, ok := err.(*errors.StatusError); ok {
// modify the message without hiding this is an API error
if r.Selector.Empty() {
se.ErrStatus.Message = fmt.Sprintf("Unable to list %q: %v", r.Mapping.Resource, se.ErrStatus.Message)
} else {
se.ErrStatus.Message = fmt.Sprintf("Unable to find %q that match the selector %q: %v", r.Mapping.Resource, r.Selector, se.ErrStatus.Message)
}
return se
}
if r.Selector.Empty() {
return fmt.Errorf("Unable to list %q: %v", r.Mapping.Resource, err)
} else {

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -62,7 +62,7 @@ const (
// is agnostic to schema versions, so you must send arguments to PrintObj in the
// version you wish them to be shown using a VersionedPrinter (typically when
// generic is true).
func GetPrinter(format, formatArgument string) (ResourcePrinter, bool, error) {
func GetPrinter(format, formatArgument string, noHeaders bool) (ResourcePrinter, bool, error) {
var printer ResourcePrinter
switch format {
case "json":
@ -119,7 +119,7 @@ func GetPrinter(format, formatArgument string) (ResourcePrinter, bool, error) {
}
case "custom-columns":
var err error
if printer, err = NewCustomColumnsPrinterFromSpec(formatArgument, api.Codecs.UniversalDecoder()); err != nil {
if printer, err = NewCustomColumnsPrinterFromSpec(formatArgument, api.Codecs.UniversalDecoder(), noHeaders); err != nil {
return nil, false, err
}
case "custom-columns-file":
@ -322,10 +322,12 @@ type handlerEntry struct {
type PrintOptions struct {
NoHeaders bool
WithNamespace bool
WithKind bool
Wide bool
ShowAll bool
ShowLabels bool
AbsoluteTimestamps bool
KindName string
ColumnLabels []string
}
@ -335,7 +337,7 @@ type PrintOptions struct {
// received from watches.
type HumanReadablePrinter struct {
handlerMap map[reflect.Type]*handlerEntry
options PrintOptions
Options PrintOptions
lastType reflect.Type
}
@ -343,9 +345,11 @@ type HumanReadablePrinter struct {
func NewHumanReadablePrinter(noHeaders, withNamespace bool, wide bool, showAll bool, showLabels bool, absoluteTimestamps bool, columnLabels []string) *HumanReadablePrinter {
printer := &HumanReadablePrinter{
handlerMap: make(map[reflect.Type]*handlerEntry),
options: PrintOptions{
Options: PrintOptions{
NoHeaders: noHeaders,
WithNamespace: withNamespace,
WithKind: false,
KindName: "",
Wide: wide,
ShowAll: showAll,
ShowLabels: showLabels,
@ -599,6 +603,11 @@ func printPod(pod *api.Pod, w io.Writer, options PrintOptions) error {
func printPodBase(pod *api.Pod, w io.Writer, options PrintOptions) error {
name := pod.Name
namespace := pod.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
restarts := 0
totalContainers := len(pod.Spec.Containers)
@ -616,6 +625,7 @@ func printPodBase(pod *api.Pod, w io.Writer, options PrintOptions) error {
initializing := false
for i := range pod.Status.InitContainerStatuses {
container := pod.Status.InitContainerStatuses[i]
restarts += int(container.RestartCount)
switch {
case container.State.Terminated != nil && container.State.Terminated.ExitCode == 0:
continue
@ -641,6 +651,7 @@ func printPodBase(pod *api.Pod, w io.Writer, options PrintOptions) error {
break
}
if !initializing {
restarts = 0
for i := len(pod.Status.ContainerStatuses) - 1; i >= 0; i-- {
container := pod.Status.ContainerStatuses[i]
@ -716,6 +727,11 @@ func printPodList(podList *api.PodList, w io.Writer, options PrintOptions) error
func printPodTemplate(pod *api.PodTemplate, w io.Writer, options PrintOptions) error {
name := pod.Name
namespace := pod.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
containers := pod.Template.Spec.Containers
@ -757,6 +773,11 @@ func printReplicationController(controller *api.ReplicationController, w io.Writ
name := controller.Name
namespace := controller.Namespace
containers := controller.Spec.Template.Spec.Containers
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -806,6 +827,11 @@ func printReplicaSet(rs *extensions.ReplicaSet, w io.Writer, options PrintOption
name := rs.Name
namespace := rs.Namespace
containers := rs.Spec.Template.Spec.Containers
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -851,6 +877,11 @@ func printReplicaSetList(list *extensions.ReplicaSetList, w io.Writer, options P
}
func printCluster(c *federation.Cluster, w io.Writer, options PrintOptions) error {
name := c.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
var statuses []string
for _, condition := range c.Status.Conditions {
if condition.Status == api.ConditionTrue {
@ -863,10 +894,9 @@ func printCluster(c *federation.Cluster, w io.Writer, options PrintOptions) erro
statuses = append(statuses, "Unknown")
}
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\n",
c.Name,
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n",
name,
strings.Join(statuses, ","),
c.Status.Version,
translateTimestamp(c.CreationTimestamp),
); err != nil {
return err
@ -886,6 +916,11 @@ func printJob(job *batch.Job, w io.Writer, options PrintOptions) error {
name := job.Name
namespace := job.Namespace
containers := job.Spec.Template.Spec.Containers
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -1004,6 +1039,11 @@ func printService(svc *api.Service, w io.Writer, options PrintOptions) error {
internalIP := svc.Spec.ClusterIP
externalIP := getServiceExternalIP(svc, options.Wide)
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -1080,6 +1120,11 @@ func formatPorts(tls []extensions.IngressTLS) string {
func printIngress(ingress *extensions.Ingress, w io.Writer, options PrintOptions) error {
name := ingress.Name
namespace := ingress.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -1119,6 +1164,11 @@ func printPetSet(ps *apps.PetSet, w io.Writer, options PrintOptions) error {
name := ps.Name
namespace := ps.Namespace
containers := ps.Spec.Template.Spec.Containers
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -1165,6 +1215,11 @@ func printPetSetList(petSetList *apps.PetSetList, w io.Writer, options PrintOpti
func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, options PrintOptions) error {
name := ds.Name
namespace := ds.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
containers := ds.Spec.Template.Spec.Containers
@ -1220,6 +1275,11 @@ func printDaemonSetList(list *extensions.DaemonSetList, w io.Writer, options Pri
func printEndpoints(endpoints *api.Endpoints, w io.Writer, options PrintOptions) error {
name := endpoints.Name
namespace := endpoints.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -1246,11 +1306,17 @@ func printEndpointsList(list *api.EndpointsList, w io.Writer, options PrintOptio
}
func printNamespace(item *api.Namespace, w io.Writer, options PrintOptions) error {
name := item.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
return fmt.Errorf("namespace is not namespaced")
}
if _, err := fmt.Fprintf(w, "%s\t%s\t%s", item.Name, item.Status.Phase, translateTimestamp(item.CreationTimestamp)); err != nil {
if _, err := fmt.Fprintf(w, "%s\t%s\t%s", name, item.Status.Phase, translateTimestamp(item.CreationTimestamp)); err != nil {
return err
}
if _, err := fmt.Fprint(w, AppendLabels(item.Labels, options.ColumnLabels)); err != nil {
@ -1272,6 +1338,11 @@ func printNamespaceList(list *api.NamespaceList, w io.Writer, options PrintOptio
func printSecret(item *api.Secret, w io.Writer, options PrintOptions) error {
name := item.Name
namespace := item.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -1301,6 +1372,11 @@ func printSecretList(list *api.SecretList, w io.Writer, options PrintOptions) er
func printServiceAccount(item *api.ServiceAccount, w io.Writer, options PrintOptions) error {
name := item.Name
namespace := item.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -1328,6 +1404,12 @@ func printServiceAccountList(list *api.ServiceAccountList, w io.Writer, options
}
func printNode(node *api.Node, w io.Writer, options PrintOptions) error {
name := node.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
return fmt.Errorf("node is not namespaced")
}
@ -1354,7 +1436,7 @@ func printNode(node *api.Node, w io.Writer, options PrintOptions) error {
status = append(status, "SchedulingDisabled")
}
if _, err := fmt.Fprintf(w, "%s\t%s\t%s", node.Name, strings.Join(status, ","), translateTimestamp(node.CreationTimestamp)); err != nil {
if _, err := fmt.Fprintf(w, "%s\t%s\t%s", name, strings.Join(status, ","), translateTimestamp(node.CreationTimestamp)); err != nil {
return err
}
// Display caller specify column labels first.
@ -1375,10 +1457,15 @@ func printNodeList(list *api.NodeList, w io.Writer, options PrintOptions) error
}
func printPersistentVolume(pv *api.PersistentVolume, w io.Writer, options PrintOptions) error {
name := pv.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
return fmt.Errorf("persistentVolume is not namespaced")
}
name := pv.Name
claimRefUID := ""
if pv.Spec.ClaimRef != nil {
@ -1421,6 +1508,11 @@ func printPersistentVolumeList(list *api.PersistentVolumeList, w io.Writer, opti
func printPersistentVolumeClaim(pvc *api.PersistentVolumeClaim, w io.Writer, options PrintOptions) error {
name := pvc.Name
namespace := pvc.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -1458,7 +1550,13 @@ func printPersistentVolumeClaimList(list *api.PersistentVolumeClaimList, w io.Wr
}
func printEvent(event *api.Event, w io.Writer, options PrintOptions) error {
name := event.InvolvedObject.Name
namespace := event.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
return err
@ -1480,7 +1578,7 @@ func printEvent(event *api.Event, w io.Writer, options PrintOptions) error {
LastTimestamp,
FirstTimestamp,
event.Count,
event.InvolvedObject.Name,
name,
event.InvolvedObject.Kind,
event.InvolvedObject.FieldPath,
event.Type,
@ -1524,6 +1622,12 @@ func printLimitRangeList(list *api.LimitRangeList, w io.Writer, options PrintOpt
// printObjectMeta prints the object metadata of a given resource.
func printObjectMeta(meta api.ObjectMeta, w io.Writer, options PrintOptions, namespaced bool) error {
name := meta.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if namespaced && options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", meta.Namespace); err != nil {
return err
@ -1532,7 +1636,7 @@ func printObjectMeta(meta api.ObjectMeta, w io.Writer, options PrintOptions, nam
if _, err := fmt.Fprintf(
w, "%s\t%s",
meta.Name,
name,
translateTimestamp(meta.CreationTimestamp),
); err != nil {
return err
@ -1615,6 +1719,12 @@ func printClusterRoleBindingList(list *rbac.ClusterRoleBindingList, w io.Writer,
}
func printComponentStatus(item *api.ComponentStatus, w io.Writer, options PrintOptions) error {
name := item.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
return fmt.Errorf("componentStatus is not namespaced")
}
@ -1634,7 +1744,7 @@ func printComponentStatus(item *api.ComponentStatus, w io.Writer, options PrintO
}
}
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s", item.Name, status, message, error); err != nil {
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s", name, status, message, error); err != nil {
return err
}
if _, err := fmt.Fprint(w, AppendLabels(item.Labels, options.ColumnLabels)); err != nil {
@ -1655,13 +1765,20 @@ func printComponentStatusList(list *api.ComponentStatusList, w io.Writer, option
}
func printThirdPartyResource(rsrc *extensions.ThirdPartyResource, w io.Writer, options PrintOptions) error {
name := rsrc.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
versions := make([]string, len(rsrc.Versions))
for ix := range rsrc.Versions {
version := &rsrc.Versions[ix]
versions[ix] = fmt.Sprintf("%s", version.Name)
}
versionsString := strings.Join(versions, ",")
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", rsrc.Name, rsrc.Description, versionsString); err != nil {
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", name, rsrc.Description, versionsString); err != nil {
return err
}
return nil
@ -1685,12 +1802,19 @@ func truncate(str string, maxLen int) string {
}
func printThirdPartyResourceData(rsrc *extensions.ThirdPartyResourceData, w io.Writer, options PrintOptions) error {
name := rsrc.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
l := labels.FormatLabels(rsrc.Labels)
truncateCols := 50
if options.Wide {
truncateCols = 100
}
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", rsrc.Name, l, truncate(string(rsrc.Data), truncateCols)); err != nil {
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", name, l, truncate(string(rsrc.Data), truncateCols)); err != nil {
return err
}
return nil
@ -1707,6 +1831,12 @@ func printThirdPartyResourceDataList(list *extensions.ThirdPartyResourceDataList
}
func printDeployment(deployment *extensions.Deployment, w io.Writer, options PrintOptions) error {
name := deployment.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", deployment.Namespace); err != nil {
return err
@ -1718,7 +1848,7 @@ func printDeployment(deployment *extensions.Deployment, w io.Writer, options Pri
updatedReplicas := deployment.Status.UpdatedReplicas
availableReplicas := deployment.Status.AvailableReplicas
age := translateTimestamp(deployment.CreationTimestamp)
if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\t%s", deployment.Name, desiredReplicas, currentReplicas, updatedReplicas, availableReplicas, age); err != nil {
if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\t%s", name, desiredReplicas, currentReplicas, updatedReplicas, availableReplicas, age); err != nil {
return err
}
if _, err := fmt.Fprint(w, AppendLabels(deployment.Labels, options.ColumnLabels)); err != nil {
@ -1740,6 +1870,11 @@ func printDeploymentList(list *extensions.DeploymentList, w io.Writer, options P
func printHorizontalPodAutoscaler(hpa *autoscaling.HorizontalPodAutoscaler, w io.Writer, options PrintOptions) error {
namespace := hpa.Namespace
name := hpa.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
reference := fmt.Sprintf("%s/%s",
hpa.Spec.ScaleTargetRef.Kind,
hpa.Spec.ScaleTargetRef.Name)
@ -1756,6 +1891,7 @@ func printHorizontalPodAutoscaler(hpa *autoscaling.HorizontalPodAutoscaler, w io
minPods = fmt.Sprintf("%d", *hpa.Spec.MinReplicas)
}
maxPods := hpa.Spec.MaxReplicas
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
return err
@ -1792,6 +1928,11 @@ func printHorizontalPodAutoscalerList(list *autoscaling.HorizontalPodAutoscalerL
func printConfigMap(configMap *api.ConfigMap, w io.Writer, options PrintOptions) error {
name := configMap.Name
namespace := configMap.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -1818,7 +1959,13 @@ func printConfigMapList(list *api.ConfigMapList, w io.Writer, options PrintOptio
}
func printPodSecurityPolicy(item *extensions.PodSecurityPolicy, w io.Writer, options PrintOptions) error {
_, err := fmt.Fprintf(w, "%s\t%t\t%v\t%s\t%s\t%s\t%s\t%t\t%v\n", item.Name, item.Spec.Privileged,
name := item.Name
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
_, err := fmt.Fprintf(w, "%s\t%t\t%v\t%s\t%s\t%s\t%s\t%t\t%v\n", name, item.Spec.Privileged,
item.Spec.AllowedCapabilities, item.Spec.SELinux.Rule,
item.Spec.RunAsUser.Rule, item.Spec.FSGroup.Rule, item.Spec.SupplementalGroups.Rule, item.Spec.ReadOnlyRootFilesystem, item.Spec.Volumes)
return err
@ -1837,6 +1984,11 @@ func printPodSecurityPolicyList(list *extensions.PodSecurityPolicyList, w io.Wri
func printNetworkPolicy(networkPolicy *extensions.NetworkPolicy, w io.Writer, options PrintOptions) error {
name := networkPolicy.Name
namespace := networkPolicy.Namespace
kind := options.KindName
if options.WithKind {
name = kind + "/" + name
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
@ -1983,18 +2135,18 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
}
t := reflect.TypeOf(obj)
if handler := h.handlerMap[t]; handler != nil {
if !h.options.NoHeaders && t != h.lastType {
headers := append(handler.columns, formatWideHeaders(h.options.Wide, t)...)
headers = append(headers, formatLabelHeaders(h.options.ColumnLabels)...)
if !h.Options.NoHeaders && t != h.lastType {
headers := append(handler.columns, formatWideHeaders(h.Options.Wide, t)...)
headers = append(headers, formatLabelHeaders(h.Options.ColumnLabels)...)
// LABELS is always the last column.
headers = append(headers, formatShowLabelsHeader(h.options.ShowLabels, t)...)
if h.options.WithNamespace {
headers = append(headers, formatShowLabelsHeader(h.Options.ShowLabels, t)...)
if h.Options.WithNamespace {
headers = append(withNamespacePrefixColumns, headers...)
}
h.printHeader(headers, w)
h.lastType = t
}
args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(w), reflect.ValueOf(h.options)}
args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(w), reflect.ValueOf(h.Options)}
resultValue := handler.printFunc.Call(args)[0]
if resultValue.IsNil() {
return nil

View file

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Copyright 2016 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.
@ -26,14 +26,14 @@ import (
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
client "k8s.io/kubernetes/pkg/client/unversioned"
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
"k8s.io/kubernetes/pkg/runtime"
deploymentutil "k8s.io/kubernetes/pkg/util/deployment"
"k8s.io/kubernetes/pkg/watch"
)
// Rollbacker provides an interface for resources that can be rolled back.
type Rollbacker interface {
Rollback(namespace, name string, updatedAnnotations map[string]string, toRevision int64, obj runtime.Object) (string, error)
Rollback(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64) (string, error)
}
func RollbackerFor(kind unversioned.GroupKind, c client.Interface) (Rollbacker, error) {
@ -48,13 +48,16 @@ type DeploymentRollbacker struct {
c client.Interface
}
func (r *DeploymentRollbacker) Rollback(namespace, name string, updatedAnnotations map[string]string, toRevision int64, obj runtime.Object) (string, error) {
d := obj.(*extensions.Deployment)
func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64) (string, error) {
d, ok := obj.(*extensions.Deployment)
if !ok {
return "", fmt.Errorf("passed object is not a Deployment: %#v", obj)
}
if d.Spec.Paused {
return "", fmt.Errorf("you cannot rollback a paused deployment; resume it first with 'kubectl rollout resume' and try again")
return "", fmt.Errorf("you cannot rollback a paused deployment; resume it first with 'kubectl rollout resume deployment/%s' and try again", d.Name)
}
deploymentRollback := &extensions.DeploymentRollback{
Name: name,
Name: d.Name,
UpdatedAnnotations: updatedAnnotations,
RollbackTo: extensions.RollbackConfig{
Revision: toRevision,
@ -63,16 +66,16 @@ func (r *DeploymentRollbacker) Rollback(namespace, name string, updatedAnnotatio
result := ""
// Get current events
events, err := r.c.Events(namespace).List(api.ListOptions{})
events, err := r.c.Events(d.Namespace).List(api.ListOptions{})
if err != nil {
return result, err
}
// Do the rollback
if err := r.c.Extensions().Deployments(namespace).Rollback(deploymentRollback); err != nil {
if err := r.c.Extensions().Deployments(d.Namespace).Rollback(deploymentRollback); err != nil {
return result, err
}
// Watch for the changes of events
watch, err := r.c.Events(namespace).Watch(api.ListOptions{Watch: true, ResourceVersion: events.ResourceVersion})
watch, err := r.c.Events(d.Namespace).Watch(api.ListOptions{Watch: true, ResourceVersion: events.ResourceVersion})
if err != nil {
return result, err
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -26,10 +26,11 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned"
client "k8s.io/kubernetes/pkg/client/unversioned"
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/deployment"
"k8s.io/kubernetes/pkg/util/integer"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/wait"
@ -58,6 +59,8 @@ type RollingUpdaterConfig struct {
Interval time.Duration
// Timeout is the time to wait for controller updates before giving up.
Timeout time.Duration
// MinReadySeconds is the number of seconds to wait after the pods are ready
MinReadySeconds int32
// CleanupPolicy defines the cleanup action to take after the deployment is
// complete.
CleanupPolicy RollingUpdaterCleanupPolicy
@ -118,7 +121,9 @@ type RollingUpdater struct {
// cleanup performs post deployment cleanup tasks for newRc and oldRc.
cleanup func(oldRc, newRc *api.ReplicationController, config *RollingUpdaterConfig) error
// getReadyPods returns the amount of old and new ready pods.
getReadyPods func(oldRc, newRc *api.ReplicationController) (int32, int32, error)
getReadyPods func(oldRc, newRc *api.ReplicationController, minReadySeconds int32) (int32, int32, error)
// nowFn returns the current time used to calculate the minReadySeconds
nowFn func() unversioned.Time
}
// NewRollingUpdater creates a RollingUpdater from a client.
@ -132,6 +137,7 @@ func NewRollingUpdater(namespace string, client client.Interface) *RollingUpdate
updater.getOrCreateTargetController = updater.getOrCreateTargetControllerWithClient
updater.getReadyPods = updater.readyPods
updater.cleanup = updater.cleanupWithClients
updater.nowFn = func() unversioned.Time { return unversioned.Now() }
return updater
}
@ -187,19 +193,20 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error {
if err != nil {
return err
}
if existing.Annotations == nil {
existing.Annotations = map[string]string{}
originReplicas := strconv.Itoa(int(existing.Spec.Replicas))
applyUpdate := func(rc *api.ReplicationController) {
if rc.Annotations == nil {
rc.Annotations = map[string]string{}
}
rc.Annotations[originalReplicasAnnotation] = originReplicas
}
existing.Annotations[originalReplicasAnnotation] = strconv.Itoa(int(existing.Spec.Replicas))
updated, err := r.c.ReplicationControllers(existing.Namespace).Update(existing)
if err != nil {
if oldRc, err = updateRcWithRetries(r.c, existing.Namespace, existing, applyUpdate); err != nil {
return err
}
oldRc = updated
}
// maxSurge is the maximum scaling increment and maxUnavailable are the maximum pods
// that can be unavailable during a rollout.
maxSurge, maxUnavailable, err := deployment.ResolveFenceposts(&config.MaxSurge, &config.MaxUnavailable, desired)
maxSurge, maxUnavailable, err := deploymentutil.ResolveFenceposts(&config.MaxSurge, &config.MaxUnavailable, desired)
if err != nil {
return err
}
@ -339,7 +346,7 @@ func (r *RollingUpdater) scaleDown(newRc, oldRc *api.ReplicationController, desi
// Get ready pods. We shouldn't block, otherwise in case both old and new
// pods are unavailable then the rolling update process blocks.
// Timeout-wise we are already covered by the progress check.
_, newAvailable, err := r.getReadyPods(oldRc, newRc)
_, newAvailable, err := r.getReadyPods(oldRc, newRc, config.MinReadySeconds)
if err != nil {
return nil, err
}
@ -396,10 +403,13 @@ func (r *RollingUpdater) scaleAndWaitWithScaler(rc *api.ReplicationController, r
// readyPods returns the old and new ready counts for their pods.
// If a pod is observed as being ready, it's considered ready even
// if it later becomes notReady.
func (r *RollingUpdater) readyPods(oldRc, newRc *api.ReplicationController) (int32, int32, error) {
func (r *RollingUpdater) readyPods(oldRc, newRc *api.ReplicationController, minReadySeconds int32) (int32, int32, error) {
controllers := []*api.ReplicationController{oldRc, newRc}
oldReady := int32(0)
newReady := int32(0)
if r.nowFn == nil {
r.nowFn = func() unversioned.Time { return unversioned.Now() }
}
for i := range controllers {
controller := controllers[i]
@ -410,13 +420,14 @@ func (r *RollingUpdater) readyPods(oldRc, newRc *api.ReplicationController) (int
return 0, 0, err
}
for _, pod := range pods.Items {
if api.IsPodReady(&pod) {
switch controller.Name {
case oldRc.Name:
oldReady++
case newRc.Name:
newReady++
}
if !deploymentutil.IsPodAvailable(&pod, minReadySeconds, r.nowFn().Time) {
continue
}
switch controller.Name {
case oldRc.Name:
oldReady++
case newRc.Name:
newReady++
}
}
}
@ -482,13 +493,14 @@ func (r *RollingUpdater) cleanupWithClients(oldRc, newRc *api.ReplicationControl
if err != nil {
return err
}
delete(newRc.Annotations, sourceIdAnnotation)
delete(newRc.Annotations, desiredReplicasAnnotation)
newRc, err = r.c.ReplicationControllers(r.ns).Update(newRc)
if err != nil {
applyUpdate := func(rc *api.ReplicationController) {
delete(rc.Annotations, sourceIdAnnotation)
delete(rc.Annotations, desiredReplicasAnnotation)
}
if newRc, err = updateRcWithRetries(r.c, r.ns, newRc, applyUpdate); err != nil {
return err
}
if err = wait.Poll(config.Interval, config.Timeout, client.ControllerHasDesiredReplicas(r.c, newRc)); err != nil {
return err
}
@ -643,27 +655,29 @@ func SetNextControllerAnnotation(rc *api.ReplicationController, name string) {
}
func UpdateExistingReplicationController(c client.Interface, oldRc *api.ReplicationController, namespace, newName, deploymentKey, deploymentValue string, out io.Writer) (*api.ReplicationController, error) {
SetNextControllerAnnotation(oldRc, newName)
if _, found := oldRc.Spec.Selector[deploymentKey]; !found {
SetNextControllerAnnotation(oldRc, newName)
return AddDeploymentKeyToReplicationController(oldRc, c, deploymentKey, deploymentValue, namespace, out)
} else {
// If we didn't need to update the controller for the deployment key, we still need to write
// the "next" controller.
return c.ReplicationControllers(namespace).Update(oldRc)
applyUpdate := func(rc *api.ReplicationController) {
SetNextControllerAnnotation(rc, newName)
}
return updateRcWithRetries(c, namespace, oldRc, applyUpdate)
}
}
const MaxRetries = 3
func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, client client.Interface, deploymentKey, deploymentValue, namespace string, out io.Writer) (*api.ReplicationController, error) {
var err error
// First, update the template label. This ensures that any newly created pods will have the new label
if oldRc, err = updateWithRetries(client.ReplicationControllers(namespace), oldRc, func(rc *api.ReplicationController) {
applyUpdate := func(rc *api.ReplicationController) {
if rc.Spec.Template.Labels == nil {
rc.Spec.Template.Labels = map[string]string{}
}
rc.Spec.Template.Labels[deploymentKey] = deploymentValue
}); err != nil {
}
if oldRc, err = updateRcWithRetries(client, namespace, oldRc, applyUpdate); err != nil {
return nil, err
}
@ -677,26 +691,16 @@ func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, c
}
for ix := range podList.Items {
pod := &podList.Items[ix]
if pod.Labels == nil {
pod.Labels = map[string]string{
deploymentKey: deploymentValue,
}
} else {
pod.Labels[deploymentKey] = deploymentValue
}
err = nil
delay := 3
for i := 0; i < MaxRetries; i++ {
_, err = client.Pods(namespace).Update(pod)
if err != nil {
fmt.Fprintf(out, "Error updating pod (%v), retrying after %d seconds", err, delay)
time.Sleep(time.Second * time.Duration(delay))
delay *= delay
applyUpdate := func(p *api.Pod) {
if p.Labels == nil {
p.Labels = map[string]string{
deploymentKey: deploymentValue,
}
} else {
break
p.Labels[deploymentKey] = deploymentValue
}
}
if err != nil {
if pod, err = updatePodWithRetries(client, namespace, pod, applyUpdate); err != nil {
return nil, err
}
}
@ -709,12 +713,11 @@ func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, c
for k, v := range oldRc.Spec.Selector {
selectorCopy[k] = v
}
oldRc.Spec.Selector[deploymentKey] = deploymentValue
// Update the selector of the rc so it manages all the pods we updated above
if oldRc, err = updateWithRetries(client.ReplicationControllers(namespace), oldRc, func(rc *api.ReplicationController) {
applyUpdate = func(rc *api.ReplicationController) {
rc.Spec.Selector[deploymentKey] = deploymentValue
}); err != nil {
}
// Update the selector of the rc so it manages all the pods we updated above
if oldRc, err = updateRcWithRetries(client, namespace, oldRc, applyUpdate); err != nil {
return nil, err
}
@ -736,33 +739,72 @@ func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, c
return oldRc, nil
}
type updateFunc func(controller *api.ReplicationController)
type updateRcFunc func(controller *api.ReplicationController)
// updateWithRetries updates applies the given rc as an update.
func updateWithRetries(rcClient client.ReplicationControllerInterface, rc *api.ReplicationController, applyUpdate updateFunc) (*api.ReplicationController, error) {
var err error
oldRc := rc
err = wait.Poll(10*time.Millisecond, 1*time.Minute, func() (bool, error) {
// updateRcWithRetries retries updating the given rc on conflict with the following steps:
// 1. Get latest resource
// 2. applyUpdate
// 3. Update the resource
func updateRcWithRetries(c client.Interface, namespace string, rc *api.ReplicationController, applyUpdate updateRcFunc) (*api.ReplicationController, error) {
// Deep copy the rc in case we failed on Get during retry loop
obj, err := api.Scheme.Copy(rc)
if err != nil {
return nil, fmt.Errorf("failed to deep copy rc before updating it: %v", err)
}
oldRc := obj.(*api.ReplicationController)
err = client.RetryOnConflict(client.DefaultBackoff, func() (e error) {
// Apply the update, then attempt to push it to the apiserver.
applyUpdate(rc)
if rc, err = rcClient.Update(rc); err == nil {
if rc, e = c.ReplicationControllers(namespace).Update(rc); e == nil {
// rc contains the latest controller post update
return true, nil
return
}
updateErr := e
// Update the controller with the latest resource version, if the update failed we
// can't trust rc so use oldRc.Name.
if rc, err = rcClient.Get(oldRc.Name); err != nil {
if rc, e = c.ReplicationControllers(namespace).Get(oldRc.Name); e != nil {
// The Get failed: Value in rc cannot be trusted.
rc = oldRc
}
// The Get passed: rc contains the latest controller, expect a poll for the update.
return false, nil
// Only return the error from update
return updateErr
})
// If the error is non-nil the returned controller cannot be trusted, if it is nil, the returned
// controller contains the applied update.
return rc, err
}
type updatePodFunc func(controller *api.Pod)
// updatePodWithRetries retries updating the given pod on conflict with the following steps:
// 1. Get latest resource
// 2. applyUpdate
// 3. Update the resource
func updatePodWithRetries(c client.Interface, namespace string, pod *api.Pod, applyUpdate updatePodFunc) (*api.Pod, error) {
// Deep copy the pod in case we failed on Get during retry loop
obj, err := api.Scheme.Copy(pod)
if err != nil {
return nil, fmt.Errorf("failed to deep copy pod before updating it: %v", err)
}
oldPod := obj.(*api.Pod)
err = client.RetryOnConflict(client.DefaultBackoff, func() (e error) {
// Apply the update, then attempt to push it to the apiserver.
applyUpdate(pod)
if pod, e = c.Pods(namespace).Update(pod); e == nil {
return
}
updateErr := e
if pod, e = c.Pods(namespace).Get(oldPod.Name); e != nil {
pod = oldPod
}
// Only return the error from update
return updateErr
})
// If the error is non-nil the returned pod cannot be trusted, if it is nil, the returned
// controller contains the applied update.
return pod, err
}
func FindSourceController(r client.ReplicationControllersNamespacer, namespace, name string) (*api.ReplicationController, error) {
list, err := r.ReplicationControllers(namespace).List(api.ListOptions{})
if err != nil {

View file

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Copyright 2016 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -835,7 +835,10 @@ func parseEnvs(envArray []string) ([]api.EnvVar, error) {
}
name := env[:pos]
value := env[pos+1:]
if len(name) == 0 || !validation.IsCIdentifier(name) || len(value) == 0 {
if len(name) == 0 || len(value) == 0 {
return nil, fmt.Errorf("invalid env: %v", env)
}
if len(validation.IsCIdentifier(name)) != 0 {
return nil, fmt.Errorf("invalid env: %v", env)
}
envVar := api.EnvVar{Name: name, Value: value}
@ -853,7 +856,7 @@ func parseV1Envs(envArray []string) ([]v1.EnvVar, error) {
}
name := env[:pos]
value := env[pos+1:]
if len(name) == 0 || !validation.IsCIdentifier(name) || len(value) == 0 {
if len(name) == 0 || len(validation.IsCIdentifier(name)) != 0 || len(value) == 0 {
return nil, fmt.Errorf("invalid env: %v", env)
}
envVar := v1.EnvVar{Name: name, Value: value}

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -81,7 +81,7 @@ type ScaleErrorType int
const (
ScaleGetFailure ScaleErrorType = iota
ScaleUpdateFailure
ScaleUpdateInvalidFailure
ScaleUpdateConflictFailure
)
// A ScaleError is returned when a scale request passes
@ -115,11 +115,8 @@ func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name s
case nil:
return true, nil
case ScaleError:
// if it's invalid we shouldn't keep waiting
if e.FailureType == ScaleUpdateInvalidFailure {
return false, err
}
if e.FailureType == ScaleUpdateFailure {
// Retry only on update conflicts.
if e.FailureType == ScaleUpdateConflictFailure {
return false, nil
}
}
@ -153,10 +150,9 @@ func (scaler *ReplicationControllerScaler) ScaleSimple(namespace, name string, p
}
}
controller.Spec.Replicas = int32(newSize)
// TODO: do retry on 409 errors here?
if _, err := scaler.c.ReplicationControllers(namespace).Update(controller); err != nil {
if errors.IsInvalid(err) {
return ScaleError{ScaleUpdateInvalidFailure, controller.ResourceVersion, err}
if errors.IsConflict(err) {
return ScaleError{ScaleUpdateConflictFailure, controller.ResourceVersion, err}
}
return ScaleError{ScaleUpdateFailure, controller.ResourceVersion, err}
}
@ -183,8 +179,11 @@ func (scaler *ReplicationControllerScaler) Scale(namespace, name string, newSize
if err != nil {
return err
}
return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
client.ControllerHasDesiredReplicas(scaler.c, rc))
err = wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, client.ControllerHasDesiredReplicas(scaler.c, rc))
if err == wait.ErrWaitTimeout {
return fmt.Errorf("timed out waiting for %q to be synced", name)
}
return err
}
return nil
}
@ -215,10 +214,9 @@ func (scaler *ReplicaSetScaler) ScaleSimple(namespace, name string, precondition
}
}
rs.Spec.Replicas = int32(newSize)
// TODO: do retry on 409 errors here?
if _, err := scaler.c.ReplicaSets(namespace).Update(rs); err != nil {
if errors.IsInvalid(err) {
return ScaleError{ScaleUpdateInvalidFailure, rs.ResourceVersion, err}
if errors.IsConflict(err) {
return ScaleError{ScaleUpdateConflictFailure, rs.ResourceVersion, err}
}
return ScaleError{ScaleUpdateFailure, rs.ResourceVersion, err}
}
@ -245,8 +243,11 @@ func (scaler *ReplicaSetScaler) Scale(namespace, name string, newSize uint, prec
if err != nil {
return err
}
return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
client.ReplicaSetHasDesiredReplicas(scaler.c, rs))
err = wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, client.ReplicaSetHasDesiredReplicas(scaler.c, rs))
if err == wait.ErrWaitTimeout {
return fmt.Errorf("timed out waiting for %q to be synced", name)
}
return err
}
return nil
}
@ -283,8 +284,8 @@ func (scaler *JobScaler) ScaleSimple(namespace, name string, preconditions *Scal
parallelism := int32(newSize)
job.Spec.Parallelism = &parallelism
if _, err := scaler.c.Jobs(namespace).Update(job); err != nil {
if errors.IsInvalid(err) {
return ScaleError{ScaleUpdateInvalidFailure, job.ResourceVersion, err}
if errors.IsConflict(err) {
return ScaleError{ScaleUpdateConflictFailure, job.ResourceVersion, err}
}
return ScaleError{ScaleUpdateFailure, job.ResourceVersion, err}
}
@ -311,8 +312,11 @@ func (scaler *JobScaler) Scale(namespace, name string, newSize uint, preconditio
if err != nil {
return err
}
return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
client.JobHasDesiredParallelism(scaler.c, job))
err = wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, client.JobHasDesiredParallelism(scaler.c, job))
if err == wait.ErrWaitTimeout {
return fmt.Errorf("timed out waiting for %q to be synced", name)
}
return err
}
return nil
}
@ -348,8 +352,8 @@ func (scaler *DeploymentScaler) ScaleSimple(namespace, name string, precondition
// For now I'm falling back to regular Deployment update operation.
deployment.Spec.Replicas = int32(newSize)
if _, err := scaler.c.Deployments(namespace).Update(deployment); err != nil {
if errors.IsInvalid(err) {
return ScaleError{ScaleUpdateInvalidFailure, deployment.ResourceVersion, err}
if errors.IsConflict(err) {
return ScaleError{ScaleUpdateConflictFailure, deployment.ResourceVersion, err}
}
return ScaleError{ScaleUpdateFailure, deployment.ResourceVersion, err}
}
@ -375,8 +379,11 @@ func (scaler *DeploymentScaler) Scale(namespace, name string, newSize uint, prec
if err != nil {
return err
}
return wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout,
client.DeploymentHasDesiredReplicas(scaler.c, deployment))
err = wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, client.DeploymentHasDesiredReplicas(scaler.c, deployment))
if err == wait.ErrWaitTimeout {
return fmt.Errorf("timed out waiting for %q to be synced", name)
}
return err
}
return nil
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Copyright 2015 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.
@ -24,8 +24,8 @@ import (
"strings"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/validation"
)
// SecretGeneratorV1 supports stable generation of an opaque secret
@ -196,9 +196,10 @@ func addKeyFromFileToSecret(secret *api.Secret, keyName, filePath string) error
}
func addKeyFromLiteralToSecret(secret *api.Secret, keyName string, data []byte) error {
if !validation.IsSecretKey(keyName) {
return fmt.Errorf("%v is not a valid key name for a secret", keyName)
if errs := validation.IsConfigMapKey(keyName); len(errs) != 0 {
return fmt.Errorf("%q is not a valid key name for a Secret: %s", keyName, strings.Join(errs, ";"))
}
if _, entryExists := secret.Data[keyName]; entryExists {
return fmt.Errorf("cannot add key %s, another key by that name already exists: %v.", keyName, secret.Data)
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Copyright 2015 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Copyright 2015 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Copyright 2016 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -20,7 +20,7 @@ import (
"sort"
"k8s.io/kubernetes/pkg/api"
qosutil "k8s.io/kubernetes/pkg/kubelet/qos/util"
"k8s.io/kubernetes/pkg/kubelet/qos"
)
type SortableResourceNames []api.ResourceName
@ -61,8 +61,22 @@ func (list SortableResourceQuotas) Less(i, j int) bool {
return list[i].Name < list[j].Name
}
type SortableVolumeMounts []api.VolumeMount
func (list SortableVolumeMounts) Len() int {
return len(list)
}
func (list SortableVolumeMounts) Swap(i, j int) {
list[i], list[j] = list[j], list[i]
}
func (list SortableVolumeMounts) Less(i, j int) bool {
return list[i].MountPath < list[j].MountPath
}
// SortedQoSResourceNames returns the sorted resource names of a QoS list.
func SortedQoSResourceNames(list qosutil.QoSList) []api.ResourceName {
func SortedQoSResourceNames(list qos.QOSList) []api.ResourceName {
resources := make([]api.ResourceName, 0, len(list))
for res := range list {
resources = append(resources, res)

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.
@ -28,9 +28,9 @@ import (
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/extensions"
client "k8s.io/kubernetes/pkg/client/unversioned"
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/util"
deploymentutil "k8s.io/kubernetes/pkg/util/deployment"
utilerrors "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/wait"
)

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.

View file

@ -1,5 +1,5 @@
/*
Copyright 2014 The Kubernetes Authors All rights reserved.
Copyright 2014 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.