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:",
|
||||
Commands: []*cobra.Command{
|
||||
rollout.NewCmdRollout(f, out, err),
|
||||
NewCmdRollingUpdate(f, out),
|
||||
NewCmdScale(f, out, err),
|
||||
rollout.NewCmdRollout(f, ioStreams),
|
||||
NewCmdRollingUpdate(f, ioStreams),
|
||||
NewCmdScale(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),
|
||||
NewCmdUncordon(f, ioStreams),
|
||||
NewCmdDrain(f, ioStreams),
|
||||
NewCmdTaint(f, out),
|
||||
NewCmdTaint(f, ioStreams),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -19,11 +19,9 @@ package cmd
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
|
@ -31,14 +29,19 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
scaleclient "k8s.io/client-go/scale"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
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/cmd/templates"
|
||||
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/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
"k8s.io/kubernetes/pkg/kubectl/validation"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -75,8 +78,55 @@ var (
|
|||
pollInterval, _ = time.ParseDuration("3s")
|
||||
)
|
||||
|
||||
func NewCmdRollingUpdate(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
options := &resource.FilenameOptions{}
|
||||
type RollingUpdateOptions struct {
|
||||
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{
|
||||
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`,
|
||||
Hidden: true,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := RunRollingUpdate(f, out, cmd, args, options)
|
||||
cmdutil.CheckErr(err)
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
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".`)
|
||||
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".`)
|
||||
|
||||
o.PrintFlags.AddFlags(cmd)
|
||||
|
||||
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."
|
||||
kubectl.AddJsonFilenameFlag(cmd, &options.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().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().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().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().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")
|
||||
kubectl.AddJsonFilenameFlag(cmd, &o.FilenameOptions.Filenames, usage)
|
||||
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().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().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().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().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.AddValidateFlags(cmd)
|
||||
cmdutil.AddPrinterFlags(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -140,69 +193,93 @@ func validateArguments(cmd *cobra.Command, filenames, args []string) error {
|
|||
return utilerrors.NewAggregate(errors)
|
||||
}
|
||||
|
||||
func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, options *resource.FilenameOptions) error {
|
||||
err := validateArguments(cmd, options.Filenames, args)
|
||||
func (o *RollingUpdateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
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 {
|
||||
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 := ""
|
||||
image := cmdutil.GetFlagString(cmd, "image")
|
||||
pullPolicy := cmdutil.GetFlagString(cmd, "image-pull-policy")
|
||||
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]
|
||||
if len(o.FilenameOptions.Filenames) > 0 {
|
||||
filename = o.FilenameOptions.Filenames[0]
|
||||
}
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clientset, err := f.ClientSet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
coreClient := clientset.Core()
|
||||
coreClient := o.ClientSet.Core()
|
||||
|
||||
var newRc *api.ReplicationController
|
||||
// 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 !errors.IsNotFound(err) || len(image) == 0 || len(args) > 1 {
|
||||
if !errors.IsNotFound(err) || len(o.Image) == 0 || !o.KeepOldName {
|
||||
return err
|
||||
}
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
return kubectl.Rename(coreClient, newRc, oldName)
|
||||
return kubectl.Rename(coreClient, newRc, o.OldName)
|
||||
}
|
||||
|
||||
var keepOldName bool
|
||||
var replicasDefaulted bool
|
||||
|
||||
if len(filename) != 0 {
|
||||
schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"))
|
||||
schema, err := o.Validator(o.ShouldValidate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
request := f.NewBuilder().
|
||||
request := o.Builder.
|
||||
Unstructured().
|
||||
Schema(schema).
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
FilenameParam(enforceNamespace, &resource.FilenameOptions{Recursive: false, Filenames: []string{filename}}).
|
||||
NamespaceParam(o.Namespace).DefaultNamespace().
|
||||
FilenameParam(o.EnforceNamespace, &resource.FilenameOptions{Recursive: false, Filenames: []string{filename}}).
|
||||
Flatten().
|
||||
Do()
|
||||
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.
|
||||
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 {
|
||||
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)
|
||||
|
@ -233,39 +310,38 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
|
|||
}
|
||||
if newRc == nil {
|
||||
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
|
||||
// than the old rc. This selector is the hash of the rc, with a suffix to provide uniqueness for
|
||||
// same-image updates.
|
||||
if len(image) != 0 {
|
||||
if len(o.Image) != 0 {
|
||||
codec := legacyscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion)
|
||||
keepOldName = len(args) == 1
|
||||
newName := findNewName(args, oldRc)
|
||||
if newRc, err = kubectl.LoadExistingNextReplicationController(coreClient, cmdNamespace, newName); err != nil {
|
||||
newName := o.FindNewName(oldRc)
|
||||
if newRc, err = kubectl.LoadExistingNextReplicationController(coreClient, o.Namespace, newName); err != nil {
|
||||
return err
|
||||
}
|
||||
if newRc != nil {
|
||||
if inProgressImage := newRc.Spec.Template.Spec.Containers[0].Image; inProgressImage != 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)
|
||||
if inProgressImage := newRc.Spec.Template.Spec.Containers[0].Image; inProgressImage != o.Image {
|
||||
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 {
|
||||
config := &kubectl.NewControllerConfig{
|
||||
Namespace: cmdNamespace,
|
||||
OldName: oldName,
|
||||
Namespace: o.Namespace,
|
||||
OldName: o.OldName,
|
||||
NewName: newName,
|
||||
Image: image,
|
||||
Container: container,
|
||||
DeploymentKey: deploymentKey,
|
||||
Image: o.Image,
|
||||
Container: o.Container,
|
||||
DeploymentKey: o.DeploymentKey,
|
||||
}
|
||||
if oldRc.Spec.Template.Spec.Containers[0].Image == image {
|
||||
if len(pullPolicy) == 0 {
|
||||
return cmdutil.UsageErrorf(cmd, "--image-pull-policy (Always|Never|IfNotPresent) must be provided when --image is the same as existing container image")
|
||||
if oldRc.Spec.Template.Spec.Containers[0].Image == o.Image {
|
||||
if len(o.PullPolicy) == 0 {
|
||||
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)
|
||||
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.
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if rollback {
|
||||
keepOldName = len(args) == 1
|
||||
newName := findNewName(args, oldRc)
|
||||
if newRc, err = kubectl.LoadExistingNextReplicationController(coreClient, cmdNamespace, newName); err != nil {
|
||||
if o.Rollback {
|
||||
newName := o.FindNewName(oldRc)
|
||||
if newRc, err = kubectl.LoadExistingNextReplicationController(coreClient, o.Namespace, newName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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 {
|
||||
return cmdutil.UsageErrorf(cmd, "%s cannot have the same name as the existing ReplicationController %s",
|
||||
filename, oldName)
|
||||
if o.OldName == newRc.Name {
|
||||
return fmt.Errorf("%s cannot have the same name as the existing ReplicationController %s",
|
||||
filename, o.OldName)
|
||||
}
|
||||
|
||||
scalesGetter, err := f.ScaleClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updater := kubectl.NewRollingUpdater(newRc.Namespace, coreClient, coreClient, scalesGetter)
|
||||
updater := kubectl.NewRollingUpdater(newRc.Namespace, coreClient, coreClient, o.ScaleClient)
|
||||
|
||||
// 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
|
||||
|
@ -321,46 +391,50 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
|
|||
}
|
||||
}
|
||||
if !hasLabel {
|
||||
return cmdutil.UsageErrorf(cmd, "%s must specify a matching key with non-equal value in Selector for %s",
|
||||
filename, oldName)
|
||||
return fmt.Errorf("%s must specify a matching key with non-equal value in Selector for %s",
|
||||
filename, o.OldName)
|
||||
}
|
||||
// TODO: handle scales during rolling update
|
||||
if replicasDefaulted {
|
||||
newRc.Spec.Replicas = oldRc.Spec.Replicas
|
||||
}
|
||||
if dryrun {
|
||||
if o.DryRun {
|
||||
oldRcData := &bytes.Buffer{}
|
||||
newRcData := &bytes.Buffer{}
|
||||
if outputFormat == "" {
|
||||
if o.OutputFormat == "" {
|
||||
oldRcData.WriteString(oldRc.Name)
|
||||
newRcData.WriteString(newRc.Name)
|
||||
} else {
|
||||
if err := cmdutil.PrintObject(cmd, oldRc, oldRcData); err != nil {
|
||||
printer, err := o.ToPrinter("rolling updated")
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
updateCleanupPolicy := kubectl.DeleteRollingUpdateCleanupPolicy
|
||||
if keepOldName {
|
||||
if o.KeepOldName {
|
||||
updateCleanupPolicy = kubectl.RenameRollingUpdateCleanupPolicy
|
||||
}
|
||||
config := &kubectl.RollingUpdaterConfig{
|
||||
Out: out,
|
||||
Out: o.Out,
|
||||
OldRc: oldRc,
|
||||
NewRc: newRc,
|
||||
UpdatePeriod: period,
|
||||
Interval: interval,
|
||||
UpdatePeriod: o.Period,
|
||||
Interval: o.Interval,
|
||||
Timeout: timeout,
|
||||
CleanupPolicy: updateCleanupPolicy,
|
||||
MaxUnavailable: intstr.FromInt(0),
|
||||
MaxSurge: intstr.FromInt(1),
|
||||
}
|
||||
if rollback {
|
||||
if o.Rollback {
|
||||
err = kubectl.AbortRollingUpdate(config)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -373,20 +447,21 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
|
|||
}
|
||||
|
||||
message := "rolling updated"
|
||||
if keepOldName {
|
||||
newRc.Name = oldName
|
||||
if o.KeepOldName {
|
||||
newRc.Name = o.OldName
|
||||
} else {
|
||||
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 {
|
||||
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 nil
|
||||
return printer.PrintObj(newRc, o.Out)
|
||||
}
|
||||
|
||||
func findNewName(args []string, oldRc *api.ReplicationController) string {
|
||||
|
|
|
@ -17,10 +17,10 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
)
|
||||
|
||||
func TestValidateArgs(t *testing.T) {
|
||||
|
@ -74,8 +74,7 @@ func TestValidateArgs(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
out := &bytes.Buffer{}
|
||||
cmd := NewCmdRollingUpdate(f, out)
|
||||
cmd := NewCmdRollingUpdate(f, genericclioptions.NewTestIOStreamsDiscard())
|
||||
|
||||
if test.flags != nil {
|
||||
for key, val := range test.flags {
|
||||
|
|
|
@ -24,8 +24,10 @@ go_library(
|
|||
"//pkg/kubectl/cmd/set:go_default_library",
|
||||
"//pkg/kubectl/cmd/templates:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||
"//pkg/kubectl/resource:go_default_library",
|
||||
"//pkg/kubectl/util/i18n:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//pkg/util/interrupt:go_default_library",
|
||||
"//vendor/github.com/renstrom/dedent:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
|
@ -59,6 +61,7 @@ go_test(
|
|||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/extensions: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/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
|
|
|
@ -17,12 +17,12 @@ limitations under the License.
|
|||
package rollout
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/renstrom/dedent"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"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{
|
||||
Use: "rollout SUBCOMMAND",
|
||||
DisableFlagsInUseLine: true,
|
||||
Short: i18n.T("Manage the rollout of a resource"),
|
||||
Long: rollout_long,
|
||||
Example: rollout_example,
|
||||
Run: cmdutil.DefaultSubCommandRun(errOut),
|
||||
Run: cmdutil.DefaultSubCommandRun(streams.Out),
|
||||
}
|
||||
// subcommands
|
||||
cmd.AddCommand(NewCmdRolloutHistory(f, out))
|
||||
cmd.AddCommand(NewCmdRolloutPause(f, out))
|
||||
cmd.AddCommand(NewCmdRolloutResume(f, out))
|
||||
cmd.AddCommand(NewCmdRolloutUndo(f, out))
|
||||
cmd.AddCommand(NewCmdRolloutStatus(f, out))
|
||||
cmd.AddCommand(NewCmdRolloutHistory(f, streams.Out))
|
||||
cmd.AddCommand(NewCmdRolloutPause(f, streams))
|
||||
cmd.AddCommand(NewCmdRolloutResume(f, streams))
|
||||
cmd.AddCommand(NewCmdRolloutUndo(f, streams.Out))
|
||||
cmd.AddCommand(NewCmdRolloutStatus(f, streams))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package rollout
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
|
@ -30,20 +29,24 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
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/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
|
||||
// referencing the cmd.Flags()
|
||||
type PauseConfig struct {
|
||||
resource.FilenameOptions
|
||||
PrintFlags *printers.PrintFlags
|
||||
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
|
||||
|
||||
Pauser func(info *resource.Info) ([]byte, error)
|
||||
Mapper meta.RESTMapper
|
||||
Infos []*resource.Info
|
||||
|
||||
Out io.Writer
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -61,8 +64,11 @@ var (
|
|||
kubectl rollout pause deployment/nginx`)
|
||||
)
|
||||
|
||||
func NewCmdRolloutPause(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
options := &PauseConfig{}
|
||||
func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
o := &PauseConfig{
|
||||
PrintFlags: printers.NewPrintFlags("paused"),
|
||||
IOStreams: streams,
|
||||
}
|
||||
|
||||
validArgs := []string{"deployment"}
|
||||
argAliases := kubectl.ResourceAliases(validArgs)
|
||||
|
@ -75,11 +81,11 @@ func NewCmdRolloutPause(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||
Example: pause_example,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
allErrs := []error{}
|
||||
err := options.CompletePause(f, cmd, out, args)
|
||||
err := o.CompletePause(f, cmd, args)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
err = options.RunPause()
|
||||
err = o.RunPause()
|
||||
if err != nil {
|
||||
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."
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||
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) {
|
||||
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.Pauser = f.Pauser
|
||||
o.Out = out
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
if err != nil {
|
||||
|
@ -123,6 +128,16 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i
|
|||
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()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -140,7 +155,12 @@ func (o PauseConfig) RunPause() error {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -151,7 +171,12 @@ func (o PauseConfig) RunPause() error {
|
|||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -31,6 +31,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
extensions "k8s.io/kubernetes/pkg/apis/extensions"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
)
|
||||
|
||||
var rolloutPauseGroupVersionEncoder = schema.GroupVersion{Group: "extensions", Version: "v1beta1"}
|
||||
|
@ -62,11 +63,11 @@ func TestRolloutPause(t *testing.T) {
|
|||
}
|
||||
|
||||
tf.Namespace = "test"
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
cmd := NewCmdRolloutPause(tf, buf)
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
cmd := NewCmdRolloutPause(tf, streams)
|
||||
|
||||
cmd.Run(cmd, []string{deploymentName})
|
||||
expectedOutput := "deployment.apps \"" + deploymentName + "\" paused\n"
|
||||
expectedOutput := "deployment.extensions/" + deploymentName + " paused\n"
|
||||
if buf.String() != expectedOutput {
|
||||
t.Errorf("expected output: %s, but got: %s", expectedOutput, buf.String())
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package rollout
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
|
@ -30,20 +29,24 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
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/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
|
||||
// referencing the cmd.Flags()
|
||||
type ResumeConfig struct {
|
||||
resource.FilenameOptions
|
||||
PrintFlags *printers.PrintFlags
|
||||
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
|
||||
|
||||
Resumer func(object *resource.Info) ([]byte, error)
|
||||
Mapper meta.RESTMapper
|
||||
Infos []*resource.Info
|
||||
|
||||
Out io.Writer
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -59,8 +62,11 @@ var (
|
|||
kubectl rollout resume deployment/nginx`)
|
||||
)
|
||||
|
||||
func NewCmdRolloutResume(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
options := &ResumeConfig{}
|
||||
func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
o := &ResumeConfig{
|
||||
PrintFlags: printers.NewPrintFlags("resumed"),
|
||||
IOStreams: streams,
|
||||
}
|
||||
|
||||
validArgs := []string{"deployment"}
|
||||
argAliases := kubectl.ResourceAliases(validArgs)
|
||||
|
@ -73,11 +79,11 @@ func NewCmdRolloutResume(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||
Example: resume_example,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
allErrs := []error{}
|
||||
err := options.CompleteResume(f, cmd, out, args)
|
||||
err := o.CompleteResume(f, cmd, args)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
err = options.RunResume()
|
||||
err = o.RunResume()
|
||||
if err != nil {
|
||||
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."
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||
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) {
|
||||
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.Resumer = f.Resumer
|
||||
o.Out = out
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
if err != nil {
|
||||
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().
|
||||
Internal(legacyscheme.Scheme).
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
|
@ -145,8 +160,12 @@ func (o ResumeConfig) RunResume() error {
|
|||
}
|
||||
|
||||
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
|
||||
cmdutil.PrintSuccess(false, o.Out, info.Object, false, "already resumed")
|
||||
continue
|
||||
printer, err := o.ToPrinter("already resumed")
|
||||
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)
|
||||
|
@ -156,7 +175,12 @@ func (o ResumeConfig) RunResume() error {
|
|||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -18,7 +18,6 @@ package rollout
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
|
@ -26,6 +25,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
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/util/i18n"
|
||||
"k8s.io/kubernetes/pkg/util/interrupt"
|
||||
|
@ -49,8 +49,32 @@ var (
|
|||
kubectl rollout status deployment/nginx`)
|
||||
)
|
||||
|
||||
func NewCmdRolloutStatus(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
options := &resource.FilenameOptions{}
|
||||
type RolloutStatusOptions struct {
|
||||
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"}
|
||||
argAliases := kubectl.ResourceAliases(validArgs)
|
||||
|
@ -62,38 +86,52 @@ func NewCmdRolloutStatus(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||
Long: status_long,
|
||||
Example: status_example,
|
||||
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,
|
||||
ArgAliases: argAliases,
|
||||
}
|
||||
|
||||
usage := "identifying the resource to get from a server."
|
||||
cmdutil.AddFilenameOptionFlags(cmd, options, usage)
|
||||
cmd.Flags().BoolP("watch", "w", true, "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).")
|
||||
cmdutil.AddFilenameOptionFlags(cmd, o.FilenameOptions, usage)
|
||||
cmd.Flags().BoolVarP(&o.Watch, "watch", "w", o.Watch, "Watch the status of the rollout until it's done.")
|
||||
cmd.Flags().Int64Var(&o.Revision, "revision", o.Revision, "Pin to a specific revision for showing its status. Defaults to 0 (last revision).")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []string, options *resource.FilenameOptions) error {
|
||||
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(options.Filenames) {
|
||||
return cmdutil.UsageErrorf(cmd, "Required resource not specified.")
|
||||
}
|
||||
func (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error {
|
||||
o.Builder = f.NewBuilder()
|
||||
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
var err error
|
||||
o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace()
|
||||
if err != nil {
|
||||
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).
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
FilenameParam(enforceNamespace, options).
|
||||
ResourceTypeOrNameArgs(true, args...).
|
||||
NamespaceParam(o.Namespace).DefaultNamespace().
|
||||
FilenameParam(o.EnforceNamespace, o.FilenameOptions).
|
||||
ResourceTypeOrNameArgs(true, o.BuilderArgs...).
|
||||
SingleResourceType().
|
||||
Latest().
|
||||
Do()
|
||||
err = r.Err()
|
||||
err := r.Err()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -117,12 +155,12 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri
|
|||
return err
|
||||
}
|
||||
|
||||
statusViewer, err := f.StatusViewer(mapping)
|
||||
statusViewer, err := o.StatusViewer(mapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
revision := cmdutil.GetFlagInt64(cmd, "revision")
|
||||
revision := o.Revision
|
||||
if revision < 0 {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(out, "%s", status)
|
||||
fmt.Fprintf(o.Out, "%s", status)
|
||||
if done {
|
||||
return nil
|
||||
}
|
||||
|
||||
shouldWatch := cmdutil.GetFlagBool(cmd, "watch")
|
||||
shouldWatch := o.Watch
|
||||
if !shouldWatch {
|
||||
return nil
|
||||
}
|
||||
|
@ -157,7 +195,7 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri
|
|||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
fmt.Fprintf(out, "%s", status)
|
||||
fmt.Fprintf(o.Out, "%s", status)
|
||||
// Quit waiting if the rollout is done
|
||||
if done {
|
||||
return true, nil
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -36,6 +37,9 @@ import (
|
|||
type UndoOptions struct {
|
||||
resource.FilenameOptions
|
||||
|
||||
PrintFlags *printers.PrintFlags
|
||||
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
|
||||
|
||||
Rollbackers []kubectl.Rollbacker
|
||||
Mapper meta.RESTMapper
|
||||
Infos []*resource.Info
|
||||
|
@ -61,7 +65,9 @@ var (
|
|||
)
|
||||
|
||||
func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
options := &UndoOptions{}
|
||||
o := &UndoOptions{
|
||||
PrintFlags: printers.NewPrintFlags(""),
|
||||
}
|
||||
|
||||
validArgs := []string{"deployment", "daemonset", "statefulset"}
|
||||
argAliases := kubectl.ResourceAliases(validArgs)
|
||||
|
@ -74,11 +80,11 @@ func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||
Example: undo_example,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
allErrs := []error{}
|
||||
err := options.CompleteUndo(f, cmd, out, args)
|
||||
err := o.CompleteUndo(f, cmd, out, args)
|
||||
if err != nil {
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
err = options.RunUndo()
|
||||
err = o.RunUndo()
|
||||
if err != nil {
|
||||
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).")
|
||||
usage := "identifying the resource to get from a server."
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||
cmdutil.AddDryRunFlag(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
@ -110,6 +116,19 @@ func (o *UndoOptions) CompleteUndo(f cmdutil.Factory, cmd *cobra.Command, out io
|
|||
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().
|
||||
Internal(legacyscheme.Scheme).
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
|
@ -147,7 +166,12 @@ func (o *UndoOptions) RunUndo() error {
|
|||
allErrs = append(allErrs, cmdutil.AddSourceToErr("undoing", info.Source, err))
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -18,12 +18,14 @@ package cmd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"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"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/scalejob"
|
||||
|
@ -32,6 +34,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -64,21 +67,49 @@ var (
|
|||
type ScaleOptions struct {
|
||||
FilenameOptions resource.FilenameOptions
|
||||
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
|
||||
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
func NewScaleOptions() *ScaleOptions {
|
||||
func NewScaleOptions(ioStreams genericclioptions.IOStreams) *ScaleOptions {
|
||||
return &ScaleOptions{
|
||||
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
|
||||
func NewCmdScale(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
||||
o := NewScaleOptions()
|
||||
func NewCmdScale(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
o := NewScaleOptions(streams)
|
||||
|
||||
validArgs := []string{"deployment", "replicaset", "replicationcontroller", "statefulset"}
|
||||
argAliases := kubectl.ResourceAliases(validArgs)
|
||||
|
@ -90,33 +121,58 @@ func NewCmdScale(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||
Long: scaleLong,
|
||||
Example: scaleExample,
|
||||
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))
|
||||
shortOutput := cmdutil.GetFlagString(cmd, "output") == "name"
|
||||
cmdutil.CheckErr(o.RunScale(f, out, errOut, cmd, args, shortOutput))
|
||||
cmdutil.CheckErr(o.RunScale())
|
||||
},
|
||||
ValidArgs: validArgs,
|
||||
ArgAliases: argAliases,
|
||||
}
|
||||
|
||||
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().Bool("all", false, "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().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().Int("replicas", -1, "The new desired number of replicas. Required.")
|
||||
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().BoolVar(&o.All, "all", o.All, "Select all resources in the namespace of the specified resource types")
|
||||
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().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().IntVar(&o.Replicas, "replicas", o.Replicas, "The new desired number of replicas. Required.")
|
||||
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).")
|
||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
||||
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).")
|
||||
|
||||
usage := "identifying the resource to set a new size"
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
|
||||
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
|
||||
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.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 nil
|
||||
}
|
||||
|
||||
// RunScale executes the scaling
|
||||
func (o *ScaleOptions) RunScale(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args []string, shortOutput bool) error {
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
if err != nil {
|
||||
return err
|
||||
func (o *ScaleOptions) RunScale() error {
|
||||
|
||||
if o.Replicas < 0 {
|
||||
return fmt.Errorf("The --replicas=COUNT flag is required, and COUNT must be greater than or equal to 0")
|
||||
}
|
||||
|
||||
count := cmdutil.GetFlagInt(cmd, "replicas")
|
||||
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().
|
||||
r := o.Builder.
|
||||
Unstructured().
|
||||
ContinueOnError().
|
||||
NamespaceParam(cmdNamespace).DefaultNamespace().
|
||||
FilenameParam(enforceNamespace, &o.FilenameOptions).
|
||||
ResourceTypeOrNameArgs(all, args...).
|
||||
NamespaceParam(o.Namespace).DefaultNamespace().
|
||||
FilenameParam(o.EnforceNamespace, &o.FilenameOptions).
|
||||
ResourceTypeOrNameArgs(o.All, o.BuilderArgs...).
|
||||
Flatten().
|
||||
LabelSelectorParam(selector).
|
||||
LabelSelectorParam(o.Selector).
|
||||
Do()
|
||||
err = r.Err()
|
||||
err := r.Err()
|
||||
if resource.IsUsageError(err) {
|
||||
return cmdutil.UsageErrorf(cmd, "%v", err)
|
||||
return fmt.Errorf("%v", err)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -167,17 +215,16 @@ func (o *ScaleOptions) RunScale(f cmdutil.Factory, out, errOut io.Writer, cmd *c
|
|||
return nil
|
||||
})
|
||||
|
||||
resourceVersion := cmdutil.GetFlagString(cmd, "resource-version")
|
||||
if len(resourceVersion) != 0 && len(infos) > 1 {
|
||||
if len(o.ResourceVersion) != 0 && len(infos) > 1 {
|
||||
return fmt.Errorf("cannot use --resource-version with multiple resources")
|
||||
}
|
||||
|
||||
currentSize := cmdutil.GetFlagInt(cmd, "current-replicas")
|
||||
precondition := &kubectl.ScalePrecondition{Size: currentSize, ResourceVersion: resourceVersion}
|
||||
currentSize := o.CurrentReplicas
|
||||
precondition := &kubectl.ScalePrecondition{Size: currentSize, ResourceVersion: o.ResourceVersion}
|
||||
retry := kubectl.NewRetryParams(kubectl.Interval, kubectl.Timeout)
|
||||
|
||||
var waitForReplicas *kubectl.RetryParams
|
||||
if timeout := cmdutil.GetFlagDuration(cmd, "timeout"); timeout != 0 {
|
||||
if timeout := o.Duration; timeout != 0 {
|
||||
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()
|
||||
if mapping.Resource == "jobs" {
|
||||
// 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 != nil {
|
||||
return err
|
||||
}
|
||||
if err := ScaleJob(info, clientset.Batch(), uint(count), precondition, retry, waitForReplicas); err != nil {
|
||||
if err := ScaleJob(info, o.ClientSet.Batch(), uint(o.Replicas), precondition, retry, waitForReplicas); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
scaler, err := f.Scaler()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
glog.V(4).Infof("error recording current command: %v", err)
|
||||
} else if len(mergePatch) > 0 {
|
||||
client, err := f.UnstructuredClientForMapping(mapping)
|
||||
client, err := o.ClientForMapping(mapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -227,8 +265,7 @@ func (o *ScaleOptions) RunScale(f cmdutil.Factory, out, errOut io.Writer, cmd *c
|
|||
}
|
||||
|
||||
counter++
|
||||
cmdutil.PrintSuccess(shortOutput, out, info.Object, false, "scaled")
|
||||
return nil
|
||||
return o.PrintObj(info.Object, o.Out)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -18,7 +18,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"encoding/json"
|
||||
|
@ -26,6 +25,7 @@ import (
|
|||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
|
@ -34,13 +34,18 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
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/util/i18n"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
taintutils "k8s.io/kubernetes/pkg/util/taints"
|
||||
)
|
||||
|
||||
// TaintOptions have the data required to perform the taint operation
|
||||
type TaintOptions struct {
|
||||
PrintFlags *printers.PrintFlags
|
||||
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
|
||||
|
||||
resources []string
|
||||
taintsToAdd []v1.Taint
|
||||
taintsToRemove []v1.Taint
|
||||
|
@ -48,9 +53,10 @@ type TaintOptions struct {
|
|||
selector string
|
||||
overwrite bool
|
||||
all bool
|
||||
f cmdutil.Factory
|
||||
out io.Writer
|
||||
cmd *cobra.Command
|
||||
|
||||
ClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
|
||||
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -79,8 +85,11 @@ var (
|
|||
kubectl taint node -l myLabel=X dedicated=foo:PreferNoSchedule`))
|
||||
)
|
||||
|
||||
func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
options := &TaintOptions{}
|
||||
func NewCmdTaint(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
options := &TaintOptions{
|
||||
PrintFlags: printers.NewPrintFlags("tainted"),
|
||||
IOStreams: streams,
|
||||
}
|
||||
|
||||
validArgs := []string{"node"}
|
||||
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),
|
||||
Example: taintExample,
|
||||
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)
|
||||
}
|
||||
if err := options.Validate(); err != nil {
|
||||
|
@ -105,9 +114,10 @@ func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||
ValidArgs: validArgs,
|
||||
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().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")
|
||||
|
@ -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.
|
||||
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()
|
||||
if err != nil {
|
||||
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 {
|
||||
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).
|
||||
Flatten().
|
||||
Latest()
|
||||
o.f = f
|
||||
o.out = out
|
||||
o.cmd = cmd
|
||||
|
||||
o.ClientForMapping = f.ClientForMapping
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -258,7 +277,7 @@ func (o TaintOptions) RunTaint() error {
|
|||
}
|
||||
|
||||
mapping := info.ResourceMapping()
|
||||
client, err := o.f.ClientForMapping(mapping)
|
||||
client, err := o.ClientForMapping(mapping)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -274,13 +293,11 @@ func (o TaintOptions) RunTaint() error {
|
|||
return err
|
||||
}
|
||||
|
||||
outputFormat := cmdutil.GetFlagString(o.cmd, "output")
|
||||
if outputFormat != "" {
|
||||
return cmdutil.PrintObject(o.cmd, outputObj, o.out)
|
||||
printer, err := o.ToPrinter(operation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmdutil.PrintSuccess(false, o.out, info.Object, false, operation)
|
||||
return nil
|
||||
return printer.PrintObj(outputObj, o.Out)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
@ -32,6 +31,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
)
|
||||
|
||||
|
@ -302,8 +302,7 @@ func TestTaint(t *testing.T) {
|
|||
}
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
cmd := NewCmdTaint(tf, buf)
|
||||
cmd := NewCmdTaint(tf, genericclioptions.NewTestIOStreamsDiscard())
|
||||
|
||||
saw_fatal := false
|
||||
func() {
|
||||
|
|
Loading…
Reference in New Issue