mirror of https://github.com/k3s-io/k3s
finish wiring PrintFlags
parent
284e8182a4
commit
f432ebe262
|
@ -273,9 +273,9 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
|
||||||
{
|
{
|
||||||
Message: "Deploy Commands:",
|
Message: "Deploy Commands:",
|
||||||
Commands: []*cobra.Command{
|
Commands: []*cobra.Command{
|
||||||
rollout.NewCmdRollout(f, out, err),
|
rollout.NewCmdRollout(f, ioStreams),
|
||||||
NewCmdRollingUpdate(f, out),
|
NewCmdRollingUpdate(f, ioStreams),
|
||||||
NewCmdScale(f, out, err),
|
NewCmdScale(f, ioStreams),
|
||||||
NewCmdAutoscale(f, ioStreams),
|
NewCmdAutoscale(f, ioStreams),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -288,7 +288,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
|
||||||
NewCmdCordon(f, ioStreams),
|
NewCmdCordon(f, ioStreams),
|
||||||
NewCmdUncordon(f, ioStreams),
|
NewCmdUncordon(f, ioStreams),
|
||||||
NewCmdDrain(f, ioStreams),
|
NewCmdDrain(f, ioStreams),
|
||||||
NewCmdTaint(f, out),
|
NewCmdTaint(f, ioStreams),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,11 +19,9 @@ package cmd
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
|
@ -31,14 +29,19 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
|
scaleclient "k8s.io/client-go/scale"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util"
|
"k8s.io/kubernetes/pkg/kubectl/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/validation"
|
||||||
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -75,8 +78,55 @@ var (
|
||||||
pollInterval, _ = time.ParseDuration("3s")
|
pollInterval, _ = time.ParseDuration("3s")
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdRollingUpdate(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
type RollingUpdateOptions struct {
|
||||||
options := &resource.FilenameOptions{}
|
FilenameOptions *resource.FilenameOptions
|
||||||
|
|
||||||
|
OldName string
|
||||||
|
KeepOldName bool
|
||||||
|
|
||||||
|
DeploymentKey string
|
||||||
|
Image string
|
||||||
|
Container string
|
||||||
|
PullPolicy string
|
||||||
|
Rollback bool
|
||||||
|
Period time.Duration
|
||||||
|
Timeout time.Duration
|
||||||
|
Interval time.Duration
|
||||||
|
DryRun bool
|
||||||
|
OutputFormat string
|
||||||
|
Namespace string
|
||||||
|
EnforceNamespace bool
|
||||||
|
|
||||||
|
ScaleClient scaleclient.ScalesGetter
|
||||||
|
ClientSet internalclientset.Interface
|
||||||
|
Builder *resource.Builder
|
||||||
|
|
||||||
|
ShouldValidate bool
|
||||||
|
Validator func(bool) (validation.Schema, error)
|
||||||
|
|
||||||
|
FindNewName func(*api.ReplicationController) string
|
||||||
|
|
||||||
|
PrintFlags *printers.PrintFlags
|
||||||
|
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
|
||||||
|
|
||||||
|
genericclioptions.IOStreams
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRollingUpdateOptions(streams genericclioptions.IOStreams) *RollingUpdateOptions {
|
||||||
|
return &RollingUpdateOptions{
|
||||||
|
PrintFlags: printers.NewPrintFlags("rolling updated"),
|
||||||
|
FilenameOptions: &resource.FilenameOptions{},
|
||||||
|
DeploymentKey: "deployment",
|
||||||
|
Timeout: timeout,
|
||||||
|
Interval: pollInterval,
|
||||||
|
Period: updatePeriod,
|
||||||
|
|
||||||
|
IOStreams: streams,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCmdRollingUpdate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
|
||||||
|
o := NewRollingUpdateOptions(ioStreams)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "rolling-update OLD_CONTROLLER_NAME ([NEW_CONTROLLER_NAME] --image=NEW_CONTAINER_IMAGE | -f NEW_CONTROLLER_SPEC)",
|
Use: "rolling-update OLD_CONTROLLER_NAME ([NEW_CONTROLLER_NAME] --image=NEW_CONTAINER_IMAGE | -f NEW_CONTROLLER_SPEC)",
|
||||||
|
@ -87,23 +137,26 @@ func NewCmdRollingUpdate(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
Deprecated: `use "rollout" instead`,
|
Deprecated: `use "rollout" instead`,
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
err := RunRollingUpdate(f, out, cmd, args, options)
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(o.Validate(cmd, args))
|
||||||
|
cmdutil.CheckErr(o.Run())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmd.Flags().Duration("update-period", updatePeriod, `Time to wait between updating pods. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`)
|
|
||||||
cmd.Flags().Duration("poll-interval", pollInterval, `Time delay between polling for replication controller status after the update. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`)
|
o.PrintFlags.AddFlags(cmd)
|
||||||
cmd.Flags().Duration("timeout", timeout, `Max time to wait for a replication controller to update before giving up. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`)
|
|
||||||
|
cmd.Flags().DurationVar(&o.Period, "update-period", o.Period, `Time to wait between updating pods. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`)
|
||||||
|
cmd.Flags().DurationVar(&o.Interval, "poll-interval", o.Interval, `Time delay between polling for replication controller status after the update. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`)
|
||||||
|
cmd.Flags().DurationVar(&o.Timeout, "timeout", o.Timeout, `Max time to wait for a replication controller to update before giving up. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".`)
|
||||||
usage := "Filename or URL to file to use to create the new replication controller."
|
usage := "Filename or URL to file to use to create the new replication controller."
|
||||||
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
|
kubectl.AddJsonFilenameFlag(cmd, &o.FilenameOptions.Filenames, usage)
|
||||||
cmd.Flags().String("image", "", i18n.T("Image to use for upgrading the replication controller. Must be distinct from the existing image (either new image or new image tag). Can not be used with --filename/-f"))
|
cmd.Flags().StringVar(&o.Image, "image", o.Image, i18n.T("Image to use for upgrading the replication controller. Must be distinct from the existing image (either new image or new image tag). Can not be used with --filename/-f"))
|
||||||
cmd.Flags().String("deployment-label-key", "deployment", i18n.T("The key to use to differentiate between two different controllers, default 'deployment'. Only relevant when --image is specified, ignored otherwise"))
|
cmd.Flags().StringVar(&o.DeploymentKey, "deployment-label-key", o.DeploymentKey, i18n.T("The key to use to differentiate between two different controllers, default 'deployment'. Only relevant when --image is specified, ignored otherwise"))
|
||||||
cmd.Flags().String("container", "", i18n.T("Container name which will have its image upgraded. Only relevant when --image is specified, ignored otherwise. Required when using --image on a multi-container pod"))
|
cmd.Flags().StringVar(&o.Container, "container", o.Container, i18n.T("Container name which will have its image upgraded. Only relevant when --image is specified, ignored otherwise. Required when using --image on a multi-container pod"))
|
||||||
cmd.Flags().String("image-pull-policy", "", i18n.T("Explicit policy for when to pull container images. Required when --image is same as existing image, ignored otherwise."))
|
cmd.Flags().StringVar(&o.PullPolicy, "image-pull-policy", o.PullPolicy, i18n.T("Explicit policy for when to pull container images. Required when --image is same as existing image, ignored otherwise."))
|
||||||
cmd.Flags().Bool("rollback", false, "If true, this is a request to abort an existing rollout that is partially rolled out. It effectively reverses current and next and runs a rollout")
|
cmd.Flags().BoolVar(&o.Rollback, "rollback", o.Rollback, "If true, this is a request to abort an existing rollout that is partially rolled out. It effectively reverses current and next and runs a rollout")
|
||||||
cmdutil.AddDryRunFlag(cmd)
|
cmdutil.AddDryRunFlag(cmd)
|
||||||
cmdutil.AddValidateFlags(cmd)
|
cmdutil.AddValidateFlags(cmd)
|
||||||
cmdutil.AddPrinterFlags(cmd)
|
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -140,69 +193,93 @@ func validateArguments(cmd *cobra.Command, filenames, args []string) error {
|
||||||
return utilerrors.NewAggregate(errors)
|
return utilerrors.NewAggregate(errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *resource.FilenameOptions) error {
|
func (o *RollingUpdateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||||
err := validateArguments(cmd, options.Filenames, args)
|
o.OldName = args[0]
|
||||||
|
o.DryRun = cmdutil.GetDryRunFlag(cmd)
|
||||||
|
o.OutputFormat = cmdutil.GetFlagString(cmd, "output")
|
||||||
|
o.KeepOldName = len(args) == 1
|
||||||
|
o.ShouldValidate = cmdutil.GetFlagBool(cmd, "validate")
|
||||||
|
|
||||||
|
o.Validator = f.Validator
|
||||||
|
o.FindNewName = func(obj *api.ReplicationController) string {
|
||||||
|
return findNewName(args, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
deploymentKey := cmdutil.GetFlagString(cmd, "deployment-label-key")
|
o.ScaleClient, err = f.ScaleClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
o.ClientSet, err = f.ClientSet()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
o.Builder = f.NewBuilder()
|
||||||
|
|
||||||
|
o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) {
|
||||||
|
o.PrintFlags.NamePrintFlags.Operation = operation
|
||||||
|
if o.DryRun {
|
||||||
|
o.PrintFlags.Complete("%s (dry run)")
|
||||||
|
}
|
||||||
|
|
||||||
|
printer, err := o.PrintFlags.ToPrinter()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return printer.PrintObj, nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *RollingUpdateOptions) Validate(cmd *cobra.Command, args []string) error {
|
||||||
|
return validateArguments(cmd, o.FilenameOptions.Filenames, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *RollingUpdateOptions) Run() error {
|
||||||
|
|
||||||
filename := ""
|
filename := ""
|
||||||
image := cmdutil.GetFlagString(cmd, "image")
|
if len(o.FilenameOptions.Filenames) > 0 {
|
||||||
pullPolicy := cmdutil.GetFlagString(cmd, "image-pull-policy")
|
filename = o.FilenameOptions.Filenames[0]
|
||||||
oldName := args[0]
|
|
||||||
rollback := cmdutil.GetFlagBool(cmd, "rollback")
|
|
||||||
period := cmdutil.GetFlagDuration(cmd, "update-period")
|
|
||||||
interval := cmdutil.GetFlagDuration(cmd, "poll-interval")
|
|
||||||
timeout := cmdutil.GetFlagDuration(cmd, "timeout")
|
|
||||||
dryrun := cmdutil.GetDryRunFlag(cmd)
|
|
||||||
outputFormat := cmdutil.GetFlagString(cmd, "output")
|
|
||||||
container := cmdutil.GetFlagString(cmd, "container")
|
|
||||||
|
|
||||||
if len(options.Filenames) > 0 {
|
|
||||||
filename = options.Filenames[0]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
coreClient := o.ClientSet.Core()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
clientset, err := f.ClientSet()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
coreClient := clientset.Core()
|
|
||||||
|
|
||||||
var newRc *api.ReplicationController
|
var newRc *api.ReplicationController
|
||||||
// fetch rc
|
// fetch rc
|
||||||
oldRc, err := coreClient.ReplicationControllers(cmdNamespace).Get(oldName, metav1.GetOptions{})
|
oldRc, err := coreClient.ReplicationControllers(o.Namespace).Get(o.OldName, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.IsNotFound(err) || len(image) == 0 || len(args) > 1 {
|
if !errors.IsNotFound(err) || len(o.Image) == 0 || !o.KeepOldName {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// We're in the middle of a rename, look for an RC with a source annotation of oldName
|
// We're in the middle of a rename, look for an RC with a source annotation of oldName
|
||||||
newRc, err := kubectl.FindSourceController(coreClient, cmdNamespace, oldName)
|
newRc, err := kubectl.FindSourceController(coreClient, o.Namespace, o.OldName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return kubectl.Rename(coreClient, newRc, oldName)
|
return kubectl.Rename(coreClient, newRc, o.OldName)
|
||||||
}
|
}
|
||||||
|
|
||||||
var keepOldName bool
|
|
||||||
var replicasDefaulted bool
|
var replicasDefaulted bool
|
||||||
|
|
||||||
if len(filename) != 0 {
|
if len(filename) != 0 {
|
||||||
schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"))
|
schema, err := o.Validator(o.ShouldValidate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
request := f.NewBuilder().
|
request := o.Builder.
|
||||||
Unstructured().
|
Unstructured().
|
||||||
Schema(schema).
|
Schema(schema).
|
||||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
NamespaceParam(o.Namespace).DefaultNamespace().
|
||||||
FilenameParam(enforceNamespace, &resource.FilenameOptions{Recursive: false, Filenames: []string{filename}}).
|
FilenameParam(o.EnforceNamespace, &resource.FilenameOptions{Recursive: false, Filenames: []string{filename}}).
|
||||||
Flatten().
|
Flatten().
|
||||||
Do()
|
Do()
|
||||||
infos, err := request.Infos()
|
infos, err := request.Infos()
|
||||||
|
@ -211,10 +288,10 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
|
||||||
}
|
}
|
||||||
// Handle filename input from stdin.
|
// Handle filename input from stdin.
|
||||||
if len(infos) > 1 {
|
if len(infos) > 1 {
|
||||||
return cmdutil.UsageErrorf(cmd, "%s specifies multiple items", filename)
|
return fmt.Errorf("%s specifies multiple items", filename)
|
||||||
}
|
}
|
||||||
if len(infos) == 0 {
|
if len(infos) == 0 {
|
||||||
return cmdutil.UsageErrorf(cmd, "please make sure %s exists and is not empty", filename)
|
return fmt.Errorf("please make sure %s exists and is not empty", filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
uncastVersionedObj, err := legacyscheme.Scheme.ConvertToVersion(infos[0].Object, v1.SchemeGroupVersion)
|
uncastVersionedObj, err := legacyscheme.Scheme.ConvertToVersion(infos[0].Object, v1.SchemeGroupVersion)
|
||||||
|
@ -233,39 +310,38 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
|
||||||
}
|
}
|
||||||
if newRc == nil {
|
if newRc == nil {
|
||||||
glog.V(4).Infof("Object %T is not a ReplicationController", infos[0].Object)
|
glog.V(4).Infof("Object %T is not a ReplicationController", infos[0].Object)
|
||||||
return cmdutil.UsageErrorf(cmd, "%s contains a %v not a ReplicationController", filename, infos[0].Object.GetObjectKind().GroupVersionKind())
|
return fmt.Errorf("%s contains a %v not a ReplicationController", filename, infos[0].Object.GetObjectKind().GroupVersionKind())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the --image option is specified, we need to create a new rc with at least one different selector
|
// If the --image option is specified, we need to create a new rc with at least one different selector
|
||||||
// than the old rc. This selector is the hash of the rc, with a suffix to provide uniqueness for
|
// than the old rc. This selector is the hash of the rc, with a suffix to provide uniqueness for
|
||||||
// same-image updates.
|
// same-image updates.
|
||||||
if len(image) != 0 {
|
if len(o.Image) != 0 {
|
||||||
codec := legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion)
|
codec := legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion)
|
||||||
keepOldName = len(args) == 1
|
newName := o.FindNewName(oldRc)
|
||||||
newName := findNewName(args, oldRc)
|
if newRc, err = kubectl.LoadExistingNextReplicationController(coreClient, o.Namespace, newName); err != nil {
|
||||||
if newRc, err = kubectl.LoadExistingNextReplicationController(coreClient, cmdNamespace, newName); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if newRc != nil {
|
if newRc != nil {
|
||||||
if inProgressImage := newRc.Spec.Template.Spec.Containers[0].Image; inProgressImage != image {
|
if inProgressImage := newRc.Spec.Template.Spec.Containers[0].Image; inProgressImage != o.Image {
|
||||||
return cmdutil.UsageErrorf(cmd, "Found existing in-progress update to image (%s).\nEither continue in-progress update with --image=%s or rollback with --rollback", inProgressImage, inProgressImage)
|
return fmt.Errorf("Found existing in-progress update to image (%s).\nEither continue in-progress update with --image=%s or rollback with --rollback", inProgressImage, inProgressImage)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "Found existing update in progress (%s), resuming.\n", newRc.Name)
|
fmt.Fprintf(o.Out, "Found existing update in progress (%s), resuming.\n", newRc.Name)
|
||||||
} else {
|
} else {
|
||||||
config := &kubectl.NewControllerConfig{
|
config := &kubectl.NewControllerConfig{
|
||||||
Namespace: cmdNamespace,
|
Namespace: o.Namespace,
|
||||||
OldName: oldName,
|
OldName: o.OldName,
|
||||||
NewName: newName,
|
NewName: newName,
|
||||||
Image: image,
|
Image: o.Image,
|
||||||
Container: container,
|
Container: o.Container,
|
||||||
DeploymentKey: deploymentKey,
|
DeploymentKey: o.DeploymentKey,
|
||||||
}
|
}
|
||||||
if oldRc.Spec.Template.Spec.Containers[0].Image == image {
|
if oldRc.Spec.Template.Spec.Containers[0].Image == o.Image {
|
||||||
if len(pullPolicy) == 0 {
|
if len(o.PullPolicy) == 0 {
|
||||||
return cmdutil.UsageErrorf(cmd, "--image-pull-policy (Always|Never|IfNotPresent) must be provided when --image is the same as existing container image")
|
return fmt.Errorf("--image-pull-policy (Always|Never|IfNotPresent) must be provided when --image is the same as existing container image")
|
||||||
}
|
}
|
||||||
config.PullPolicy = api.PullPolicy(pullPolicy)
|
config.PullPolicy = api.PullPolicy(o.PullPolicy)
|
||||||
}
|
}
|
||||||
newRc, err = kubectl.CreateNewControllerFromCurrentController(coreClient, codec, config)
|
newRc, err = kubectl.CreateNewControllerFromCurrentController(coreClient, codec, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -280,35 +356,29 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
|
||||||
}
|
}
|
||||||
// If new image is same as old, the hash may not be distinct, so add a suffix.
|
// If new image is same as old, the hash may not be distinct, so add a suffix.
|
||||||
oldHash += "-orig"
|
oldHash += "-orig"
|
||||||
oldRc, err = kubectl.UpdateExistingReplicationController(coreClient, coreClient, oldRc, cmdNamespace, newRc.Name, deploymentKey, oldHash, out)
|
oldRc, err = kubectl.UpdateExistingReplicationController(coreClient, coreClient, oldRc, o.Namespace, newRc.Name, o.DeploymentKey, oldHash, o.Out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if rollback {
|
if o.Rollback {
|
||||||
keepOldName = len(args) == 1
|
newName := o.FindNewName(oldRc)
|
||||||
newName := findNewName(args, oldRc)
|
if newRc, err = kubectl.LoadExistingNextReplicationController(coreClient, o.Namespace, newName); err != nil {
|
||||||
if newRc, err = kubectl.LoadExistingNextReplicationController(coreClient, cmdNamespace, newName); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if newRc == nil {
|
if newRc == nil {
|
||||||
return cmdutil.UsageErrorf(cmd, "Could not find %s to rollback.\n", newName)
|
return fmt.Errorf("Could not find %s to rollback.\n", newName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if oldName == newRc.Name {
|
if o.OldName == newRc.Name {
|
||||||
return cmdutil.UsageErrorf(cmd, "%s cannot have the same name as the existing ReplicationController %s",
|
return fmt.Errorf("%s cannot have the same name as the existing ReplicationController %s",
|
||||||
filename, oldName)
|
filename, o.OldName)
|
||||||
}
|
}
|
||||||
|
|
||||||
scalesGetter, err := f.ScaleClient()
|
updater := kubectl.NewRollingUpdater(newRc.Namespace, coreClient, coreClient, o.ScaleClient)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
updater := kubectl.NewRollingUpdater(newRc.Namespace, coreClient, coreClient, scalesGetter)
|
|
||||||
|
|
||||||
// To successfully pull off a rolling update the new and old rc have to differ
|
// To successfully pull off a rolling update the new and old rc have to differ
|
||||||
// by at least one selector. Every new pod should have the selector and every
|
// by at least one selector. Every new pod should have the selector and every
|
||||||
|
@ -321,46 +391,50 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !hasLabel {
|
if !hasLabel {
|
||||||
return cmdutil.UsageErrorf(cmd, "%s must specify a matching key with non-equal value in Selector for %s",
|
return fmt.Errorf("%s must specify a matching key with non-equal value in Selector for %s",
|
||||||
filename, oldName)
|
filename, o.OldName)
|
||||||
}
|
}
|
||||||
// TODO: handle scales during rolling update
|
// TODO: handle scales during rolling update
|
||||||
if replicasDefaulted {
|
if replicasDefaulted {
|
||||||
newRc.Spec.Replicas = oldRc.Spec.Replicas
|
newRc.Spec.Replicas = oldRc.Spec.Replicas
|
||||||
}
|
}
|
||||||
if dryrun {
|
if o.DryRun {
|
||||||
oldRcData := &bytes.Buffer{}
|
oldRcData := &bytes.Buffer{}
|
||||||
newRcData := &bytes.Buffer{}
|
newRcData := &bytes.Buffer{}
|
||||||
if outputFormat == "" {
|
if o.OutputFormat == "" {
|
||||||
oldRcData.WriteString(oldRc.Name)
|
oldRcData.WriteString(oldRc.Name)
|
||||||
newRcData.WriteString(newRc.Name)
|
newRcData.WriteString(newRc.Name)
|
||||||
} else {
|
} else {
|
||||||
if err := cmdutil.PrintObject(cmd, oldRc, oldRcData); err != nil {
|
printer, err := o.ToPrinter("rolling updated")
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := cmdutil.PrintObject(cmd, newRc, newRcData); err != nil {
|
if err := printer.PrintObj(oldRc, oldRcData); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := printer.PrintObj(newRc, newRcData); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "Rolling from:\n%s\nTo:\n%s\n", string(oldRcData.Bytes()), string(newRcData.Bytes()))
|
fmt.Fprintf(o.Out, "Rolling from:\n%s\nTo:\n%s\n", string(oldRcData.Bytes()), string(newRcData.Bytes()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
updateCleanupPolicy := kubectl.DeleteRollingUpdateCleanupPolicy
|
updateCleanupPolicy := kubectl.DeleteRollingUpdateCleanupPolicy
|
||||||
if keepOldName {
|
if o.KeepOldName {
|
||||||
updateCleanupPolicy = kubectl.RenameRollingUpdateCleanupPolicy
|
updateCleanupPolicy = kubectl.RenameRollingUpdateCleanupPolicy
|
||||||
}
|
}
|
||||||
config := &kubectl.RollingUpdaterConfig{
|
config := &kubectl.RollingUpdaterConfig{
|
||||||
Out: out,
|
Out: o.Out,
|
||||||
OldRc: oldRc,
|
OldRc: oldRc,
|
||||||
NewRc: newRc,
|
NewRc: newRc,
|
||||||
UpdatePeriod: period,
|
UpdatePeriod: o.Period,
|
||||||
Interval: interval,
|
Interval: o.Interval,
|
||||||
Timeout: timeout,
|
Timeout: timeout,
|
||||||
CleanupPolicy: updateCleanupPolicy,
|
CleanupPolicy: updateCleanupPolicy,
|
||||||
MaxUnavailable: intstr.FromInt(0),
|
MaxUnavailable: intstr.FromInt(0),
|
||||||
MaxSurge: intstr.FromInt(1),
|
MaxSurge: intstr.FromInt(1),
|
||||||
}
|
}
|
||||||
if rollback {
|
if o.Rollback {
|
||||||
err = kubectl.AbortRollingUpdate(config)
|
err = kubectl.AbortRollingUpdate(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -373,20 +447,21 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
|
||||||
}
|
}
|
||||||
|
|
||||||
message := "rolling updated"
|
message := "rolling updated"
|
||||||
if keepOldName {
|
if o.KeepOldName {
|
||||||
newRc.Name = oldName
|
newRc.Name = o.OldName
|
||||||
} else {
|
} else {
|
||||||
message = fmt.Sprintf("rolling updated to %q", newRc.Name)
|
message = fmt.Sprintf("rolling updated to %q", newRc.Name)
|
||||||
}
|
}
|
||||||
newRc, err = coreClient.ReplicationControllers(cmdNamespace).Get(newRc.Name, metav1.GetOptions{})
|
newRc, err = coreClient.ReplicationControllers(o.Namespace).Get(newRc.Name, metav1.GetOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if outputFormat != "" {
|
|
||||||
return cmdutil.PrintObject(cmd, newRc, out)
|
printer, err := o.ToPrinter(message)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
cmdutil.PrintSuccess(false, out, newRc, dryrun, message)
|
return printer.PrintObj(newRc, o.Out)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func findNewName(args []string, oldRc *api.ReplicationController) string {
|
func findNewName(args []string, oldRc *api.ReplicationController) string {
|
||||||
|
|
|
@ -17,10 +17,10 @@ limitations under the License.
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestValidateArgs(t *testing.T) {
|
func TestValidateArgs(t *testing.T) {
|
||||||
|
@ -74,8 +74,7 @@ func TestValidateArgs(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
out := &bytes.Buffer{}
|
cmd := NewCmdRollingUpdate(f, genericclioptions.NewTestIOStreamsDiscard())
|
||||||
cmd := NewCmdRollingUpdate(f, out)
|
|
||||||
|
|
||||||
if test.flags != nil {
|
if test.flags != nil {
|
||||||
for key, val := range test.flags {
|
for key, val := range test.flags {
|
||||||
|
|
|
@ -24,8 +24,10 @@ go_library(
|
||||||
"//pkg/kubectl/cmd/set:go_default_library",
|
"//pkg/kubectl/cmd/set:go_default_library",
|
||||||
"//pkg/kubectl/cmd/templates:go_default_library",
|
"//pkg/kubectl/cmd/templates:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
"//pkg/kubectl/resource:go_default_library",
|
"//pkg/kubectl/resource:go_default_library",
|
||||||
"//pkg/kubectl/util/i18n:go_default_library",
|
"//pkg/kubectl/util/i18n:go_default_library",
|
||||||
|
"//pkg/printers:go_default_library",
|
||||||
"//pkg/util/interrupt:go_default_library",
|
"//pkg/util/interrupt:go_default_library",
|
||||||
"//vendor/github.com/renstrom/dedent:go_default_library",
|
"//vendor/github.com/renstrom/dedent:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
|
@ -59,6 +61,7 @@ go_test(
|
||||||
"//pkg/api/legacyscheme:go_default_library",
|
"//pkg/api/legacyscheme:go_default_library",
|
||||||
"//pkg/apis/extensions:go_default_library",
|
"//pkg/apis/extensions:go_default_library",
|
||||||
"//pkg/kubectl/cmd/testing:go_default_library",
|
"//pkg/kubectl/cmd/testing:go_default_library",
|
||||||
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
|
|
|
@ -17,12 +17,12 @@ limitations under the License.
|
||||||
package rollout
|
package rollout
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
"github.com/renstrom/dedent"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -46,22 +46,21 @@ var (
|
||||||
`)
|
`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdRollout(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
func NewCmdRollout(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "rollout SUBCOMMAND",
|
Use: "rollout SUBCOMMAND",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
Short: i18n.T("Manage the rollout of a resource"),
|
Short: i18n.T("Manage the rollout of a resource"),
|
||||||
Long: rollout_long,
|
Long: rollout_long,
|
||||||
Example: rollout_example,
|
Example: rollout_example,
|
||||||
Run: cmdutil.DefaultSubCommandRun(errOut),
|
Run: cmdutil.DefaultSubCommandRun(streams.Out),
|
||||||
}
|
}
|
||||||
// subcommands
|
// subcommands
|
||||||
cmd.AddCommand(NewCmdRolloutHistory(f, out))
|
cmd.AddCommand(NewCmdRolloutHistory(f, streams.Out))
|
||||||
cmd.AddCommand(NewCmdRolloutPause(f, out))
|
cmd.AddCommand(NewCmdRolloutPause(f, streams))
|
||||||
cmd.AddCommand(NewCmdRolloutResume(f, out))
|
cmd.AddCommand(NewCmdRolloutResume(f, streams))
|
||||||
cmd.AddCommand(NewCmdRolloutUndo(f, out))
|
cmd.AddCommand(NewCmdRolloutUndo(f, streams.Out))
|
||||||
cmd.AddCommand(NewCmdRolloutStatus(f, out))
|
cmd.AddCommand(NewCmdRolloutStatus(f, streams))
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ package rollout
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
@ -30,20 +29,24 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PauseConfig is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
// PauseConfig is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
||||||
// referencing the cmd.Flags()
|
// referencing the cmd.Flags()
|
||||||
type PauseConfig struct {
|
type PauseConfig struct {
|
||||||
resource.FilenameOptions
|
resource.FilenameOptions
|
||||||
|
PrintFlags *printers.PrintFlags
|
||||||
|
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
|
||||||
|
|
||||||
Pauser func(info *resource.Info) ([]byte, error)
|
Pauser func(info *resource.Info) ([]byte, error)
|
||||||
Mapper meta.RESTMapper
|
Mapper meta.RESTMapper
|
||||||
Infos []*resource.Info
|
Infos []*resource.Info
|
||||||
|
|
||||||
Out io.Writer
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -61,8 +64,11 @@ var (
|
||||||
kubectl rollout pause deployment/nginx`)
|
kubectl rollout pause deployment/nginx`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdRolloutPause(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
options := &PauseConfig{}
|
o := &PauseConfig{
|
||||||
|
PrintFlags: printers.NewPrintFlags("paused"),
|
||||||
|
IOStreams: streams,
|
||||||
|
}
|
||||||
|
|
||||||
validArgs := []string{"deployment"}
|
validArgs := []string{"deployment"}
|
||||||
argAliases := kubectl.ResourceAliases(validArgs)
|
argAliases := kubectl.ResourceAliases(validArgs)
|
||||||
|
@ -75,11 +81,11 @@ func NewCmdRolloutPause(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
Example: pause_example,
|
Example: pause_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
allErrs := []error{}
|
allErrs := []error{}
|
||||||
err := options.CompletePause(f, cmd, out, args)
|
err := o.CompletePause(f, cmd, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, err)
|
allErrs = append(allErrs, err)
|
||||||
}
|
}
|
||||||
err = options.RunPause()
|
err = o.RunPause()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, err)
|
allErrs = append(allErrs, err)
|
||||||
}
|
}
|
||||||
|
@ -90,11 +96,11 @@ func NewCmdRolloutPause(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
usage := "identifying the resource to get from a server."
|
usage := "identifying the resource to get from a server."
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []string) error {
|
func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||||
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
||||||
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
|
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
|
||||||
}
|
}
|
||||||
|
@ -102,7 +108,6 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i
|
||||||
o.Mapper = f.RESTMapper()
|
o.Mapper = f.RESTMapper()
|
||||||
|
|
||||||
o.Pauser = f.Pauser
|
o.Pauser = f.Pauser
|
||||||
o.Out = out
|
|
||||||
|
|
||||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -123,6 +128,16 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) {
|
||||||
|
o.PrintFlags.NamePrintFlags.Operation = operation
|
||||||
|
printer, err := o.PrintFlags.ToPrinter()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return printer.PrintObj, nil
|
||||||
|
}
|
||||||
|
|
||||||
o.Infos, err = r.Infos()
|
o.Infos, err = r.Infos()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -140,7 +155,12 @@ func (o PauseConfig) RunPause() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
|
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
|
||||||
cmdutil.PrintSuccess(false, o.Out, info.Object, false, "already paused")
|
printer, err := o.ToPrinter("already paused")
|
||||||
|
if err != nil {
|
||||||
|
allErrs = append(allErrs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +171,12 @@ func (o PauseConfig) RunPause() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
info.Refresh(obj, true)
|
info.Refresh(obj, true)
|
||||||
cmdutil.PrintSuccess(false, o.Out, info.Object, false, "paused")
|
printer, err := o.ToPrinter("paused")
|
||||||
|
if err != nil {
|
||||||
|
allErrs = append(allErrs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
|
||||||
}
|
}
|
||||||
|
|
||||||
return utilerrors.NewAggregate(allErrs)
|
return utilerrors.NewAggregate(allErrs)
|
||||||
|
|
|
@ -31,6 +31,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
var rolloutPauseGroupVersionEncoder = schema.GroupVersion{Group: "extensions", Version: "v1beta1"}
|
var rolloutPauseGroupVersionEncoder = schema.GroupVersion{Group: "extensions", Version: "v1beta1"}
|
||||||
|
@ -62,11 +63,11 @@ func TestRolloutPause(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
cmd := NewCmdRolloutPause(tf, buf)
|
cmd := NewCmdRolloutPause(tf, streams)
|
||||||
|
|
||||||
cmd.Run(cmd, []string{deploymentName})
|
cmd.Run(cmd, []string{deploymentName})
|
||||||
expectedOutput := "deployment.apps \"" + deploymentName + "\" paused\n"
|
expectedOutput := "deployment.extensions/" + deploymentName + " paused\n"
|
||||||
if buf.String() != expectedOutput {
|
if buf.String() != expectedOutput {
|
||||||
t.Errorf("expected output: %s, but got: %s", expectedOutput, buf.String())
|
t.Errorf("expected output: %s, but got: %s", expectedOutput, buf.String())
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ package rollout
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
@ -30,20 +29,24 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResumeConfig is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
// ResumeConfig is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
||||||
// referencing the cmd.Flags()
|
// referencing the cmd.Flags()
|
||||||
type ResumeConfig struct {
|
type ResumeConfig struct {
|
||||||
resource.FilenameOptions
|
resource.FilenameOptions
|
||||||
|
PrintFlags *printers.PrintFlags
|
||||||
|
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
|
||||||
|
|
||||||
Resumer func(object *resource.Info) ([]byte, error)
|
Resumer func(object *resource.Info) ([]byte, error)
|
||||||
Mapper meta.RESTMapper
|
Mapper meta.RESTMapper
|
||||||
Infos []*resource.Info
|
Infos []*resource.Info
|
||||||
|
|
||||||
Out io.Writer
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -59,8 +62,11 @@ var (
|
||||||
kubectl rollout resume deployment/nginx`)
|
kubectl rollout resume deployment/nginx`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdRolloutResume(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
options := &ResumeConfig{}
|
o := &ResumeConfig{
|
||||||
|
PrintFlags: printers.NewPrintFlags("resumed"),
|
||||||
|
IOStreams: streams,
|
||||||
|
}
|
||||||
|
|
||||||
validArgs := []string{"deployment"}
|
validArgs := []string{"deployment"}
|
||||||
argAliases := kubectl.ResourceAliases(validArgs)
|
argAliases := kubectl.ResourceAliases(validArgs)
|
||||||
|
@ -73,11 +79,11 @@ func NewCmdRolloutResume(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
Example: resume_example,
|
Example: resume_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
allErrs := []error{}
|
allErrs := []error{}
|
||||||
err := options.CompleteResume(f, cmd, out, args)
|
err := o.CompleteResume(f, cmd, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, err)
|
allErrs = append(allErrs, err)
|
||||||
}
|
}
|
||||||
err = options.RunResume()
|
err = o.RunResume()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, err)
|
allErrs = append(allErrs, err)
|
||||||
}
|
}
|
||||||
|
@ -88,11 +94,11 @@ func NewCmdRolloutResume(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
usage := "identifying the resource to get from a server."
|
usage := "identifying the resource to get from a server."
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []string) error {
|
func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||||
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
||||||
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
|
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
|
||||||
}
|
}
|
||||||
|
@ -100,13 +106,22 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, out
|
||||||
o.Mapper = f.RESTMapper()
|
o.Mapper = f.RESTMapper()
|
||||||
|
|
||||||
o.Resumer = f.Resumer
|
o.Resumer = f.Resumer
|
||||||
o.Out = out
|
|
||||||
|
|
||||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) {
|
||||||
|
o.PrintFlags.NamePrintFlags.Operation = operation
|
||||||
|
printer, err := o.PrintFlags.ToPrinter()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return printer.PrintObj, nil
|
||||||
|
}
|
||||||
|
|
||||||
r := f.NewBuilder().
|
r := f.NewBuilder().
|
||||||
Internal(legacyscheme.Scheme).
|
Internal(legacyscheme.Scheme).
|
||||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||||
|
@ -145,8 +160,12 @@ func (o ResumeConfig) RunResume() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
|
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
|
||||||
cmdutil.PrintSuccess(false, o.Out, info.Object, false, "already resumed")
|
printer, err := o.ToPrinter("already resumed")
|
||||||
continue
|
if err != nil {
|
||||||
|
allErrs = append(allErrs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
|
||||||
|
@ -156,7 +175,12 @@ func (o ResumeConfig) RunResume() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
info.Refresh(obj, true)
|
info.Refresh(obj, true)
|
||||||
cmdutil.PrintSuccess(false, o.Out, info.Object, false, "resumed")
|
printer, err := o.ToPrinter("resumed")
|
||||||
|
if err != nil {
|
||||||
|
allErrs = append(allErrs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
|
||||||
}
|
}
|
||||||
|
|
||||||
return utilerrors.NewAggregate(allErrs)
|
return utilerrors.NewAggregate(allErrs)
|
||||||
|
|
|
@ -18,7 +18,6 @@ package rollout
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
@ -26,6 +25,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
"k8s.io/kubernetes/pkg/util/interrupt"
|
"k8s.io/kubernetes/pkg/util/interrupt"
|
||||||
|
@ -49,8 +49,32 @@ var (
|
||||||
kubectl rollout status deployment/nginx`)
|
kubectl rollout status deployment/nginx`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdRolloutStatus(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
type RolloutStatusOptions struct {
|
||||||
options := &resource.FilenameOptions{}
|
FilenameOptions *resource.FilenameOptions
|
||||||
|
genericclioptions.IOStreams
|
||||||
|
|
||||||
|
Namespace string
|
||||||
|
EnforceNamespace bool
|
||||||
|
BuilderArgs []string
|
||||||
|
|
||||||
|
Watch bool
|
||||||
|
Revision int64
|
||||||
|
|
||||||
|
StatusViewer func(*meta.RESTMapping) (kubectl.StatusViewer, error)
|
||||||
|
|
||||||
|
Builder *resource.Builder
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRolloutStatusOptions(streams genericclioptions.IOStreams) *RolloutStatusOptions {
|
||||||
|
return &RolloutStatusOptions{
|
||||||
|
FilenameOptions: &resource.FilenameOptions{},
|
||||||
|
IOStreams: streams,
|
||||||
|
Watch: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCmdRolloutStatus(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
|
o := NewRolloutStatusOptions(streams)
|
||||||
|
|
||||||
validArgs := []string{"deployment", "daemonset", "statefulset"}
|
validArgs := []string{"deployment", "daemonset", "statefulset"}
|
||||||
argAliases := kubectl.ResourceAliases(validArgs)
|
argAliases := kubectl.ResourceAliases(validArgs)
|
||||||
|
@ -62,38 +86,52 @@ func NewCmdRolloutStatus(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
Long: status_long,
|
Long: status_long,
|
||||||
Example: status_example,
|
Example: status_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(RunStatus(f, cmd, out, args, options))
|
cmdutil.CheckErr(o.Complete(f, args))
|
||||||
|
cmdutil.CheckErr(o.Validate(cmd, args))
|
||||||
|
cmdutil.CheckErr(o.Run())
|
||||||
},
|
},
|
||||||
ValidArgs: validArgs,
|
ValidArgs: validArgs,
|
||||||
ArgAliases: argAliases,
|
ArgAliases: argAliases,
|
||||||
}
|
}
|
||||||
|
|
||||||
usage := "identifying the resource to get from a server."
|
usage := "identifying the resource to get from a server."
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, options, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, o.FilenameOptions, usage)
|
||||||
cmd.Flags().BoolP("watch", "w", true, "Watch the status of the rollout until it's done.")
|
cmd.Flags().BoolVarP(&o.Watch, "watch", "w", o.Watch, "Watch the status of the rollout until it's done.")
|
||||||
cmd.Flags().Int64("revision", 0, "Pin to a specific revision for showing its status. Defaults to 0 (last revision).")
|
cmd.Flags().Int64Var(&o.Revision, "revision", o.Revision, "Pin to a specific revision for showing its status. Defaults to 0 (last revision).")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []string, options *resource.FilenameOptions) error {
|
func (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error {
|
||||||
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(options.Filenames) {
|
o.Builder = f.NewBuilder()
|
||||||
return cmdutil.UsageErrorf(cmd, "Required resource not specified.")
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
var err error
|
||||||
|
o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
r := f.NewBuilder().
|
o.BuilderArgs = args
|
||||||
|
o.StatusViewer = f.StatusViewer
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *RolloutStatusOptions) Validate(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
|
||||||
|
return cmdutil.UsageErrorf(cmd, "Required resource not specified.")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *RolloutStatusOptions) Run() error {
|
||||||
|
r := o.Builder.
|
||||||
Internal(legacyscheme.Scheme).
|
Internal(legacyscheme.Scheme).
|
||||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
NamespaceParam(o.Namespace).DefaultNamespace().
|
||||||
FilenameParam(enforceNamespace, options).
|
FilenameParam(o.EnforceNamespace, o.FilenameOptions).
|
||||||
ResourceTypeOrNameArgs(true, args...).
|
ResourceTypeOrNameArgs(true, o.BuilderArgs...).
|
||||||
SingleResourceType().
|
SingleResourceType().
|
||||||
Latest().
|
Latest().
|
||||||
Do()
|
Do()
|
||||||
err = r.Err()
|
err := r.Err()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -117,12 +155,12 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
statusViewer, err := f.StatusViewer(mapping)
|
statusViewer, err := o.StatusViewer(mapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
revision := cmdutil.GetFlagInt64(cmd, "revision")
|
revision := o.Revision
|
||||||
if revision < 0 {
|
if revision < 0 {
|
||||||
return fmt.Errorf("revision must be a positive integer: %v", revision)
|
return fmt.Errorf("revision must be a positive integer: %v", revision)
|
||||||
}
|
}
|
||||||
|
@ -132,12 +170,12 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "%s", status)
|
fmt.Fprintf(o.Out, "%s", status)
|
||||||
if done {
|
if done {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldWatch := cmdutil.GetFlagBool(cmd, "watch")
|
shouldWatch := o.Watch
|
||||||
if !shouldWatch {
|
if !shouldWatch {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -157,7 +195,7 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
fmt.Fprintf(out, "%s", status)
|
fmt.Fprintf(o.Out, "%s", status)
|
||||||
// Quit waiting if the rollout is done
|
// Quit waiting if the rollout is done
|
||||||
if done {
|
if done {
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
|
@ -27,6 +27,7 @@ import (
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -36,6 +37,9 @@ import (
|
||||||
type UndoOptions struct {
|
type UndoOptions struct {
|
||||||
resource.FilenameOptions
|
resource.FilenameOptions
|
||||||
|
|
||||||
|
PrintFlags *printers.PrintFlags
|
||||||
|
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
|
||||||
|
|
||||||
Rollbackers []kubectl.Rollbacker
|
Rollbackers []kubectl.Rollbacker
|
||||||
Mapper meta.RESTMapper
|
Mapper meta.RESTMapper
|
||||||
Infos []*resource.Info
|
Infos []*resource.Info
|
||||||
|
@ -61,7 +65,9 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
options := &UndoOptions{}
|
o := &UndoOptions{
|
||||||
|
PrintFlags: printers.NewPrintFlags(""),
|
||||||
|
}
|
||||||
|
|
||||||
validArgs := []string{"deployment", "daemonset", "statefulset"}
|
validArgs := []string{"deployment", "daemonset", "statefulset"}
|
||||||
argAliases := kubectl.ResourceAliases(validArgs)
|
argAliases := kubectl.ResourceAliases(validArgs)
|
||||||
|
@ -74,11 +80,11 @@ func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
Example: undo_example,
|
Example: undo_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
allErrs := []error{}
|
allErrs := []error{}
|
||||||
err := options.CompleteUndo(f, cmd, out, args)
|
err := o.CompleteUndo(f, cmd, out, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, err)
|
allErrs = append(allErrs, err)
|
||||||
}
|
}
|
||||||
err = options.RunUndo()
|
err = o.RunUndo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
allErrs = append(allErrs, err)
|
allErrs = append(allErrs, err)
|
||||||
}
|
}
|
||||||
|
@ -90,7 +96,7 @@ func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
|
|
||||||
cmd.Flags().Int64("to-revision", 0, "The revision to rollback to. Default to 0 (last revision).")
|
cmd.Flags().Int64("to-revision", 0, "The revision to rollback to. Default to 0 (last revision).")
|
||||||
usage := "identifying the resource to get from a server."
|
usage := "identifying the resource to get from a server."
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||||
cmdutil.AddDryRunFlag(cmd)
|
cmdutil.AddDryRunFlag(cmd)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -110,6 +116,19 @@ func (o *UndoOptions) CompleteUndo(f cmdutil.Factory, cmd *cobra.Command, out io
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) {
|
||||||
|
o.PrintFlags.NamePrintFlags.Operation = operation
|
||||||
|
if o.DryRun {
|
||||||
|
o.PrintFlags.Complete("%s (dry run)")
|
||||||
|
}
|
||||||
|
printer, err := o.PrintFlags.ToPrinter()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return printer.PrintObj, nil
|
||||||
|
}
|
||||||
|
|
||||||
r := f.NewBuilder().
|
r := f.NewBuilder().
|
||||||
Internal(legacyscheme.Scheme).
|
Internal(legacyscheme.Scheme).
|
||||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||||
|
@ -147,7 +166,12 @@ func (o *UndoOptions) RunUndo() error {
|
||||||
allErrs = append(allErrs, cmdutil.AddSourceToErr("undoing", info.Source, err))
|
allErrs = append(allErrs, cmdutil.AddSourceToErr("undoing", info.Source, err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cmdutil.PrintSuccess(false, o.Out, info.Object, false, result)
|
printer, err := o.ToPrinter(result)
|
||||||
|
if err != nil {
|
||||||
|
allErrs = append(allErrs, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
|
||||||
}
|
}
|
||||||
return utilerrors.NewAggregate(allErrs)
|
return utilerrors.NewAggregate(allErrs)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,14 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
batchclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/internalversion"
|
batchclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/scalejob"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/scalejob"
|
||||||
|
@ -32,6 +34,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -64,21 +67,49 @@ var (
|
||||||
type ScaleOptions struct {
|
type ScaleOptions struct {
|
||||||
FilenameOptions resource.FilenameOptions
|
FilenameOptions resource.FilenameOptions
|
||||||
RecordFlags *genericclioptions.RecordFlags
|
RecordFlags *genericclioptions.RecordFlags
|
||||||
|
PrintFlags *printers.PrintFlags
|
||||||
|
PrintObj printers.ResourcePrinterFunc
|
||||||
|
|
||||||
|
BuilderArgs []string
|
||||||
|
Namespace string
|
||||||
|
EnforceNamespace bool
|
||||||
|
|
||||||
|
Builder *resource.Builder
|
||||||
|
ClientSet internalclientset.Interface
|
||||||
|
Scaler kubectl.Scaler
|
||||||
|
|
||||||
|
All bool
|
||||||
|
Selector string
|
||||||
|
|
||||||
|
CmdParent string
|
||||||
|
|
||||||
|
ResourceVersion string
|
||||||
|
CurrentReplicas int
|
||||||
|
Replicas int
|
||||||
|
Duration time.Duration
|
||||||
|
|
||||||
|
ClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
|
||||||
|
|
||||||
Recorder genericclioptions.Recorder
|
Recorder genericclioptions.Recorder
|
||||||
|
|
||||||
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewScaleOptions() *ScaleOptions {
|
func NewScaleOptions(ioStreams genericclioptions.IOStreams) *ScaleOptions {
|
||||||
return &ScaleOptions{
|
return &ScaleOptions{
|
||||||
RecordFlags: genericclioptions.NewRecordFlags(),
|
RecordFlags: genericclioptions.NewRecordFlags(),
|
||||||
|
PrintFlags: printers.NewPrintFlags("scaled"),
|
||||||
|
|
||||||
Recorder: genericclioptions.NoopRecorder{},
|
CurrentReplicas: -1,
|
||||||
|
|
||||||
|
Recorder: genericclioptions.NoopRecorder{},
|
||||||
|
IOStreams: ioStreams,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmdScale returns a cobra command with the appropriate configuration and flags to run scale
|
// NewCmdScale returns a cobra command with the appropriate configuration and flags to run scale
|
||||||
func NewCmdScale(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
func NewCmdScale(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
o := NewScaleOptions()
|
o := NewScaleOptions(streams)
|
||||||
|
|
||||||
validArgs := []string{"deployment", "replicaset", "replicationcontroller", "statefulset"}
|
validArgs := []string{"deployment", "replicaset", "replicationcontroller", "statefulset"}
|
||||||
argAliases := kubectl.ResourceAliases(validArgs)
|
argAliases := kubectl.ResourceAliases(validArgs)
|
||||||
|
@ -90,33 +121,58 @@ func NewCmdScale(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
||||||
Long: scaleLong,
|
Long: scaleLong,
|
||||||
Example: scaleExample,
|
Example: scaleExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
|
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
|
||||||
shortOutput := cmdutil.GetFlagString(cmd, "output") == "name"
|
cmdutil.CheckErr(o.RunScale())
|
||||||
cmdutil.CheckErr(o.RunScale(f, out, errOut, cmd, args, shortOutput))
|
|
||||||
},
|
},
|
||||||
ValidArgs: validArgs,
|
ValidArgs: validArgs,
|
||||||
ArgAliases: argAliases,
|
ArgAliases: argAliases,
|
||||||
}
|
}
|
||||||
|
|
||||||
o.RecordFlags.AddFlags(cmd)
|
o.RecordFlags.AddFlags(cmd)
|
||||||
|
o.PrintFlags.AddFlags(cmd)
|
||||||
|
|
||||||
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||||
cmd.Flags().Bool("all", false, "Select all resources in the namespace of the specified resource types")
|
cmd.Flags().BoolVar(&o.All, "all", o.All, "Select all resources in the namespace of the specified resource types")
|
||||||
cmd.Flags().String("resource-version", "", i18n.T("Precondition for resource version. Requires that the current resource version match this value in order to scale."))
|
cmd.Flags().StringVar(&o.ResourceVersion, "resource-version", o.ResourceVersion, i18n.T("Precondition for resource version. Requires that the current resource version match this value in order to scale."))
|
||||||
cmd.Flags().Int("current-replicas", -1, "Precondition for current size. Requires that the current size of the resource match this value in order to scale.")
|
cmd.Flags().IntVar(&o.CurrentReplicas, "current-replicas", o.CurrentReplicas, "Precondition for current size. Requires that the current size of the resource match this value in order to scale.")
|
||||||
cmd.Flags().Int("replicas", -1, "The new desired number of replicas. Required.")
|
cmd.Flags().IntVar(&o.Replicas, "replicas", o.Replicas, "The new desired number of replicas. Required.")
|
||||||
cmd.MarkFlagRequired("replicas")
|
cmd.MarkFlagRequired("replicas")
|
||||||
cmd.Flags().Duration("timeout", 0, "The length of time to wait before giving up on a scale operation, zero means don't wait. Any other values should contain a corresponding time unit (e.g. 1s, 2m, 3h).")
|
cmd.Flags().DurationVar(&o.Duration, "timeout", o.Duration, "The length of time to wait before giving up on a scale operation, zero means don't wait. Any other values should contain a corresponding time unit (e.g. 1s, 2m, 3h).")
|
||||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
|
||||||
|
|
||||||
usage := "identifying the resource to set a new size"
|
usage := "identifying the resource to set a new size"
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *ScaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
func (o *ScaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
|
o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
o.CmdParent = cmd.Parent().Name()
|
||||||
|
o.Builder = f.NewBuilder()
|
||||||
|
|
||||||
|
o.ClientSet, err = f.ClientSet()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
o.Scaler, err = f.Scaler()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
o.BuilderArgs = args
|
||||||
|
o.ClientForMapping = f.UnstructuredClientForMapping
|
||||||
|
|
||||||
|
printer, err := o.PrintFlags.ToPrinter()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.PrintObj = printer.PrintObj
|
||||||
|
|
||||||
o.RecordFlags.Complete(f.Command(cmd, false))
|
o.RecordFlags.Complete(f.Command(cmd, false))
|
||||||
o.Recorder, err = o.RecordFlags.ToRecorder()
|
o.Recorder, err = o.RecordFlags.ToRecorder()
|
||||||
|
@ -124,36 +180,28 @@ func (o *ScaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunScale executes the scaling
|
// RunScale executes the scaling
|
||||||
func (o *ScaleOptions) RunScale(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args []string, shortOutput bool) error {
|
func (o *ScaleOptions) RunScale() error {
|
||||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
|
||||||
if err != nil {
|
if o.Replicas < 0 {
|
||||||
return err
|
return fmt.Errorf("The --replicas=COUNT flag is required, and COUNT must be greater than or equal to 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
count := cmdutil.GetFlagInt(cmd, "replicas")
|
r := o.Builder.
|
||||||
if count < 0 {
|
|
||||||
return cmdutil.UsageErrorf(cmd, "The --replicas=COUNT flag is required, and COUNT must be greater than or equal to 0")
|
|
||||||
}
|
|
||||||
|
|
||||||
selector := cmdutil.GetFlagString(cmd, "selector")
|
|
||||||
all := cmdutil.GetFlagBool(cmd, "all")
|
|
||||||
|
|
||||||
r := f.NewBuilder().
|
|
||||||
Unstructured().
|
Unstructured().
|
||||||
ContinueOnError().
|
ContinueOnError().
|
||||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
NamespaceParam(o.Namespace).DefaultNamespace().
|
||||||
FilenameParam(enforceNamespace, &o.FilenameOptions).
|
FilenameParam(o.EnforceNamespace, &o.FilenameOptions).
|
||||||
ResourceTypeOrNameArgs(all, args...).
|
ResourceTypeOrNameArgs(o.All, o.BuilderArgs...).
|
||||||
Flatten().
|
Flatten().
|
||||||
LabelSelectorParam(selector).
|
LabelSelectorParam(o.Selector).
|
||||||
Do()
|
Do()
|
||||||
err = r.Err()
|
err := r.Err()
|
||||||
if resource.IsUsageError(err) {
|
if resource.IsUsageError(err) {
|
||||||
return cmdutil.UsageErrorf(cmd, "%v", err)
|
return fmt.Errorf("%v", err)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -167,17 +215,16 @@ func (o *ScaleOptions) RunScale(f cmdutil.Factory, out, errOut io.Writer, cmd *c
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
resourceVersion := cmdutil.GetFlagString(cmd, "resource-version")
|
if len(o.ResourceVersion) != 0 && len(infos) > 1 {
|
||||||
if len(resourceVersion) != 0 && len(infos) > 1 {
|
|
||||||
return fmt.Errorf("cannot use --resource-version with multiple resources")
|
return fmt.Errorf("cannot use --resource-version with multiple resources")
|
||||||
}
|
}
|
||||||
|
|
||||||
currentSize := cmdutil.GetFlagInt(cmd, "current-replicas")
|
currentSize := o.CurrentReplicas
|
||||||
precondition := &kubectl.ScalePrecondition{Size: currentSize, ResourceVersion: resourceVersion}
|
precondition := &kubectl.ScalePrecondition{Size: currentSize, ResourceVersion: o.ResourceVersion}
|
||||||
retry := kubectl.NewRetryParams(kubectl.Interval, kubectl.Timeout)
|
retry := kubectl.NewRetryParams(kubectl.Interval, kubectl.Timeout)
|
||||||
|
|
||||||
var waitForReplicas *kubectl.RetryParams
|
var waitForReplicas *kubectl.RetryParams
|
||||||
if timeout := cmdutil.GetFlagDuration(cmd, "timeout"); timeout != 0 {
|
if timeout := o.Duration; timeout != 0 {
|
||||||
waitForReplicas = kubectl.NewRetryParams(kubectl.Interval, timeout)
|
waitForReplicas = kubectl.NewRetryParams(kubectl.Interval, timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,24 +237,15 @@ func (o *ScaleOptions) RunScale(f cmdutil.Factory, out, errOut io.Writer, cmd *c
|
||||||
mapping := info.ResourceMapping()
|
mapping := info.ResourceMapping()
|
||||||
if mapping.Resource == "jobs" {
|
if mapping.Resource == "jobs" {
|
||||||
// go down the legacy jobs path. This can be removed in 3.14 For now, contain it.
|
// go down the legacy jobs path. This can be removed in 3.14 For now, contain it.
|
||||||
fmt.Fprintf(errOut, "%s scale job is DEPRECATED and will be removed in a future version.\n", cmd.Parent().Name())
|
fmt.Fprintf(o.ErrOut, "%s scale job is DEPRECATED and will be removed in a future version.\n", o.CmdParent)
|
||||||
|
|
||||||
clientset, err := f.ClientSet()
|
if err := ScaleJob(info, o.ClientSet.Batch(), uint(o.Replicas), precondition, retry, waitForReplicas); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := ScaleJob(info, clientset.Batch(), uint(count), precondition, retry, waitForReplicas); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
scaler, err := f.Scaler()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
gvk := mapping.GroupVersionKind.GroupVersion().WithResource(mapping.Resource)
|
gvk := mapping.GroupVersionKind.GroupVersion().WithResource(mapping.Resource)
|
||||||
if err := scaler.Scale(info.Namespace, info.Name, uint(count), precondition, retry, waitForReplicas, gvk.GroupResource()); err != nil {
|
if err := o.Scaler.Scale(info.Namespace, info.Name, uint(o.Replicas), precondition, retry, waitForReplicas, gvk.GroupResource()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +254,7 @@ func (o *ScaleOptions) RunScale(f cmdutil.Factory, out, errOut io.Writer, cmd *c
|
||||||
if mergePatch, err := o.Recorder.MakeRecordMergePatch(info.Object); err != nil {
|
if mergePatch, err := o.Recorder.MakeRecordMergePatch(info.Object); err != nil {
|
||||||
glog.V(4).Infof("error recording current command: %v", err)
|
glog.V(4).Infof("error recording current command: %v", err)
|
||||||
} else if len(mergePatch) > 0 {
|
} else if len(mergePatch) > 0 {
|
||||||
client, err := f.UnstructuredClientForMapping(mapping)
|
client, err := o.ClientForMapping(mapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -227,8 +265,7 @@ func (o *ScaleOptions) RunScale(f cmdutil.Factory, out, errOut io.Writer, cmd *c
|
||||||
}
|
}
|
||||||
|
|
||||||
counter++
|
counter++
|
||||||
cmdutil.PrintSuccess(shortOutput, out, info.Object, false, "scaled")
|
return o.PrintObj(info.Object, o.Out)
|
||||||
return nil
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -18,7 +18,6 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -26,6 +25,7 @@ import (
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||||
|
@ -34,13 +34,18 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
taintutils "k8s.io/kubernetes/pkg/util/taints"
|
taintutils "k8s.io/kubernetes/pkg/util/taints"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TaintOptions have the data required to perform the taint operation
|
// TaintOptions have the data required to perform the taint operation
|
||||||
type TaintOptions struct {
|
type TaintOptions struct {
|
||||||
|
PrintFlags *printers.PrintFlags
|
||||||
|
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
|
||||||
|
|
||||||
resources []string
|
resources []string
|
||||||
taintsToAdd []v1.Taint
|
taintsToAdd []v1.Taint
|
||||||
taintsToRemove []v1.Taint
|
taintsToRemove []v1.Taint
|
||||||
|
@ -48,9 +53,10 @@ type TaintOptions struct {
|
||||||
selector string
|
selector string
|
||||||
overwrite bool
|
overwrite bool
|
||||||
all bool
|
all bool
|
||||||
f cmdutil.Factory
|
|
||||||
out io.Writer
|
ClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
|
||||||
cmd *cobra.Command
|
|
||||||
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -79,8 +85,11 @@ var (
|
||||||
kubectl taint node -l myLabel=X dedicated=foo:PreferNoSchedule`))
|
kubectl taint node -l myLabel=X dedicated=foo:PreferNoSchedule`))
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdTaint(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
options := &TaintOptions{}
|
options := &TaintOptions{
|
||||||
|
PrintFlags: printers.NewPrintFlags("tainted"),
|
||||||
|
IOStreams: streams,
|
||||||
|
}
|
||||||
|
|
||||||
validArgs := []string{"node"}
|
validArgs := []string{"node"}
|
||||||
argAliases := kubectl.ResourceAliases(validArgs)
|
argAliases := kubectl.ResourceAliases(validArgs)
|
||||||
|
@ -92,7 +101,7 @@ func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
Long: fmt.Sprintf(taintLong, validation.DNS1123SubdomainMaxLength, validation.LabelValueMaxLength),
|
Long: fmt.Sprintf(taintLong, validation.DNS1123SubdomainMaxLength, validation.LabelValueMaxLength),
|
||||||
Example: taintExample,
|
Example: taintExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
if err := options.Complete(f, out, cmd, args); err != nil {
|
if err := options.Complete(f, cmd, args); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
if err := options.Validate(); err != nil {
|
if err := options.Validate(); err != nil {
|
||||||
|
@ -105,9 +114,10 @@ func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
ValidArgs: validArgs,
|
ValidArgs: validArgs,
|
||||||
ArgAliases: argAliases,
|
ArgAliases: argAliases,
|
||||||
}
|
}
|
||||||
cmdutil.AddValidateFlags(cmd)
|
|
||||||
|
|
||||||
cmdutil.AddPrinterFlags(cmd)
|
options.PrintFlags.AddFlags(cmd)
|
||||||
|
|
||||||
|
cmdutil.AddValidateFlags(cmd)
|
||||||
cmd.Flags().StringVarP(&options.selector, "selector", "l", options.selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
cmd.Flags().StringVarP(&options.selector, "selector", "l", options.selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||||
cmd.Flags().BoolVar(&options.overwrite, "overwrite", options.overwrite, "If true, allow taints to be overwritten, otherwise reject taint updates that overwrite existing taints.")
|
cmd.Flags().BoolVar(&options.overwrite, "overwrite", options.overwrite, "If true, allow taints to be overwritten, otherwise reject taint updates that overwrite existing taints.")
|
||||||
cmd.Flags().BoolVar(&options.all, "all", options.all, "Select all nodes in the cluster")
|
cmd.Flags().BoolVar(&options.all, "all", options.all, "Select all nodes in the cluster")
|
||||||
|
@ -115,7 +125,7 @@ func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete adapts from the command line args and factory to the data required.
|
// Complete adapts from the command line args and factory to the data required.
|
||||||
func (o *TaintOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) (err error) {
|
func (o *TaintOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) (err error) {
|
||||||
namespace, _, err := f.DefaultNamespace()
|
namespace, _, err := f.DefaultNamespace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -140,6 +150,16 @@ func (o *TaintOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Com
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) {
|
||||||
|
o.PrintFlags.NamePrintFlags.Operation = operation
|
||||||
|
printer, err := o.PrintFlags.ToPrinter()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return printer.PrintObj, nil
|
||||||
|
}
|
||||||
|
|
||||||
if len(o.resources) < 1 {
|
if len(o.resources) < 1 {
|
||||||
return fmt.Errorf("one or more resources must be specified as <resource> <name>")
|
return fmt.Errorf("one or more resources must be specified as <resource> <name>")
|
||||||
}
|
}
|
||||||
|
@ -166,9 +186,8 @@ func (o *TaintOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Com
|
||||||
o.builder = o.builder.LabelSelectorParam(o.selector).
|
o.builder = o.builder.LabelSelectorParam(o.selector).
|
||||||
Flatten().
|
Flatten().
|
||||||
Latest()
|
Latest()
|
||||||
o.f = f
|
|
||||||
o.out = out
|
o.ClientForMapping = f.ClientForMapping
|
||||||
o.cmd = cmd
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +277,7 @@ func (o TaintOptions) RunTaint() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping := info.ResourceMapping()
|
mapping := info.ResourceMapping()
|
||||||
client, err := o.f.ClientForMapping(mapping)
|
client, err := o.ClientForMapping(mapping)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -274,13 +293,11 @@ func (o TaintOptions) RunTaint() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
outputFormat := cmdutil.GetFlagString(o.cmd, "output")
|
printer, err := o.ToPrinter(operation)
|
||||||
if outputFormat != "" {
|
if err != nil {
|
||||||
return cmdutil.PrintObject(o.cmd, outputObj, o.out)
|
return err
|
||||||
}
|
}
|
||||||
|
return printer.PrintObj(outputObj, o.Out)
|
||||||
cmdutil.PrintSuccess(false, o.out, info.Object, false, operation)
|
|
||||||
return nil
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -32,6 +31,7 @@ import (
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -302,8 +302,7 @@ func TestTaint(t *testing.T) {
|
||||||
}
|
}
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
|
|
||||||
buf := bytes.NewBuffer([]byte{})
|
cmd := NewCmdTaint(tf, genericclioptions.NewTestIOStreamsDiscard())
|
||||||
cmd := NewCmdTaint(tf, buf)
|
|
||||||
|
|
||||||
saw_fatal := false
|
saw_fatal := false
|
||||||
func() {
|
func() {
|
||||||
|
|
Loading…
Reference in New Issue