Add generated file

This PR adds generated files under pkg/client and vendor folder.
This commit is contained in:
xing-yang
2018-07-12 10:55:15 -07:00
parent 36b1de0341
commit e213d1890d
17729 changed files with 5090889 additions and 0 deletions

73
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/rollout/BUILD generated vendored Normal file
View File

@@ -0,0 +1,73 @@
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = [
"rollout.go",
"rollout_history.go",
"rollout_pause.go",
"rollout_resume.go",
"rollout_status.go",
"rollout_undo.go",
],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/rollout",
visibility = [
"//build/visible_to:pkg_kubectl_cmd_rollout_CONSUMERS",
],
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/kubectl:go_default_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/genericclioptions/printers:go_default_library",
"//pkg/kubectl/genericclioptions/resource:go_default_library",
"//pkg/kubectl/polymorphichelpers:go_default_library",
"//pkg/kubectl/scheme:go_default_library",
"//pkg/kubectl/util/i18n: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",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = [
"//build/visible_to:pkg_kubectl_cmd_rollout_CONSUMERS",
],
)
go_test(
name = "go_default_test",
srcs = ["rollout_pause_test.go"],
embed = [":go_default_library"],
deps = [
"//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",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
],
)

View File

@@ -0,0 +1,66 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rollout
import (
"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"
)
var (
rollout_long = templates.LongDesc(`
Manage the rollout of a resource.` + rollout_valid_resources)
rollout_example = templates.Examples(`
# Rollback to the previous deployment
kubectl rollout undo deployment/abc
# Check the rollout status of a daemonset
kubectl rollout status daemonset/foo`)
rollout_valid_resources = dedent.Dedent(`
Valid resource types include:
* deployments
* daemonsets
* statefulsets
`)
)
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(streams.Out),
}
// subcommands
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
}

View File

@@ -0,0 +1,118 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rollout
import (
"fmt"
"io"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
"github.com/spf13/cobra"
)
var (
history_long = templates.LongDesc(`
View previous rollout revisions and configurations.`)
history_example = templates.Examples(`
# View the rollout history of a deployment
kubectl rollout history deployment/abc
# View the details of daemonset revision 3
kubectl rollout history daemonset/abc --revision=3`)
)
func NewCmdRolloutHistory(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &resource.FilenameOptions{}
validArgs := []string{"deployment", "daemonset", "statefulset"}
cmd := &cobra.Command{
Use: "history (TYPE NAME | TYPE/NAME) [flags]",
DisableFlagsInUseLine: true,
Short: i18n.T("View rollout history"),
Long: history_long,
Example: history_example,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(RunHistory(f, cmd, out, args, options))
},
ValidArgs: validArgs,
}
cmd.Flags().Int64("revision", 0, "See the details, including podTemplate of the revision specified")
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, options, usage)
return cmd
}
func RunHistory(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.")
}
revision := cmdutil.GetFlagInt64(cmd, "revision")
if revision < 0 {
return fmt.Errorf("revision must be a positive integer: %v", revision)
}
cmdNamespace, enforceNamespace, err := f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
r := f.NewBuilder().
WithScheme(legacyscheme.Scheme).
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, options).
ResourceTypeOrNameArgs(true, args...).
ContinueOnError().
Latest().
Flatten().
Do()
err = r.Err()
if err != nil {
return err
}
return r.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
mapping := info.ResourceMapping()
historyViewer, err := polymorphichelpers.HistoryViewerFn(f, mapping)
if err != nil {
return err
}
historyInfo, err := historyViewer.ViewHistory(info.Namespace, info.Name, revision)
if err != nil {
return err
}
header := fmt.Sprintf("%s %q", mapping.Resource.Resource, info.Name)
if revision > 0 {
header = fmt.Sprintf("%s with revision #%d", header, revision)
}
fmt.Fprintf(out, "%s\n", header)
fmt.Fprintf(out, "%s\n", historyInfo)
return nil
})
}

View File

@@ -0,0 +1,181 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rollout
import (
"fmt"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"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/genericclioptions/printers"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
// 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 *genericclioptions.PrintFlags
ToPrinter func(string) (printers.ResourcePrinter, error)
Pauser polymorphichelpers.ObjectPauserFunc
Infos []*resource.Info
genericclioptions.IOStreams
}
var (
pause_long = templates.LongDesc(`
Mark the provided resource as paused
Paused resources will not be reconciled by a controller.
Use "kubectl rollout resume" to resume a paused resource.
Currently only deployments support being paused.`)
pause_example = templates.Examples(`
# Mark the nginx deployment as paused. Any current state of
# the deployment will continue its function, new updates to the deployment will not
# have an effect as long as the deployment is paused.
kubectl rollout pause deployment/nginx`)
)
func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := &PauseConfig{
PrintFlags: genericclioptions.NewPrintFlags("paused").WithTypeSetter(scheme.Scheme),
IOStreams: streams,
}
validArgs := []string{"deployment"}
cmd := &cobra.Command{
Use: "pause RESOURCE",
DisableFlagsInUseLine: true,
Short: i18n.T("Mark the provided resource as paused"),
Long: pause_long,
Example: pause_example,
Run: func(cmd *cobra.Command, args []string) {
allErrs := []error{}
err := o.CompletePause(f, cmd, args)
if err != nil {
allErrs = append(allErrs, err)
}
err = o.RunPause()
if err != nil {
allErrs = append(allErrs, err)
}
cmdutil.CheckErr(utilerrors.Flatten(utilerrors.NewAggregate(allErrs)))
},
ValidArgs: validArgs,
}
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
return cmd
}
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)
}
o.Pauser = polymorphichelpers.ObjectPauserFn
cmdNamespace, enforceNamespace, err := f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
r := f.NewBuilder().
WithScheme(legacyscheme.Scheme).
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
ResourceTypeOrNameArgs(true, args...).
ContinueOnError().
Latest().
Flatten().
Do()
err = r.Err()
if err != nil {
return err
}
o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) {
o.PrintFlags.NamePrintFlags.Operation = operation
return o.PrintFlags.ToPrinter()
}
o.Infos, err = r.Infos()
if err != nil {
return err
}
return nil
}
func (o PauseConfig) RunPause() error {
allErrs := []error{}
for _, patch := range set.CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), set.PatchFn(o.Pauser)) {
info := patch.Info
if patch.Err != nil {
resourceString := info.Mapping.Resource.Resource
if len(info.Mapping.Resource.Group) > 0 {
resourceString = resourceString + "." + info.Mapping.Resource.Group
}
allErrs = append(allErrs, fmt.Errorf("error: %s %q %v", resourceString, info.Name, patch.Err))
continue
}
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
printer, err := o.ToPrinter("already paused")
if err != nil {
allErrs = append(allErrs, err)
continue
}
if err = printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
allErrs = append(allErrs, err)
}
continue
}
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch: %v", err))
continue
}
info.Refresh(obj, true)
printer, err := o.ToPrinter("paused")
if err != nil {
allErrs = append(allErrs, err)
continue
}
if err = printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
allErrs = append(allErrs, err)
}
}
return utilerrors.NewAggregate(allErrs)
}

View File

@@ -0,0 +1,121 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rollout
import (
"bytes"
"io/ioutil"
"net/http"
"net/url"
"testing"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
"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"}
var rolloutPauseGroupVersionDecoder = schema.GroupVersion{Group: "extensions", Version: runtime.APIVersionInternal}
func TestRolloutPause(t *testing.T) {
deploymentName := "deployment/nginx-deployment"
ns := legacyscheme.Codecs
tf := cmdtesting.NewTestFactory().WithNamespace("test")
info, _ := runtime.SerializerInfoForMediaType(ns.SupportedMediaTypes(), runtime.ContentTypeJSON)
encoder := ns.EncoderForVersion(info.Serializer, rolloutPauseGroupVersionEncoder)
tf.Client = &RolloutPauseRESTClient{
RESTClient: &fake.RESTClient{
NegotiatedSerializer: ns,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/deployments/nginx-deployment" && (m == "GET" || m == "PATCH"):
responseDeployment := &extensions.Deployment{}
responseDeployment.Name = deploymentName
body := ioutil.NopCloser(bytes.NewReader([]byte(runtime.EncodeOrDie(encoder, responseDeployment))))
return &http.Response{StatusCode: http.StatusOK, Header: defaultHeader(), Body: body}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
},
}
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdRolloutPause(tf, streams)
cmd.Run(cmd, []string{deploymentName})
expectedOutput := "deployment.extensions/" + deploymentName + " paused\n"
if buf.String() != expectedOutput {
t.Errorf("expected output: %s, but got: %s", expectedOutput, buf.String())
}
}
type RolloutPauseRESTClient struct {
*fake.RESTClient
}
func (c *RolloutPauseRESTClient) Get() *restclient.Request {
config := restclient.ContentConfig{
ContentType: runtime.ContentTypeJSON,
GroupVersion: &rolloutPauseGroupVersionEncoder,
NegotiatedSerializer: c.NegotiatedSerializer,
}
info, _ := runtime.SerializerInfoForMediaType(c.NegotiatedSerializer.SupportedMediaTypes(), runtime.ContentTypeJSON)
serializers := restclient.Serializers{
Encoder: c.NegotiatedSerializer.EncoderForVersion(info.Serializer, rolloutPauseGroupVersionEncoder),
Decoder: c.NegotiatedSerializer.DecoderToVersion(info.Serializer, rolloutPauseGroupVersionDecoder),
}
if info.StreamSerializer != nil {
serializers.StreamingSerializer = info.StreamSerializer.Serializer
serializers.Framer = info.StreamSerializer.Framer
}
return restclient.NewRequest(c, "GET", &url.URL{Host: "localhost"}, c.VersionedAPIPath, config, serializers, nil, nil, 0)
}
func (c *RolloutPauseRESTClient) Patch(pt types.PatchType) *restclient.Request {
config := restclient.ContentConfig{
ContentType: runtime.ContentTypeJSON,
GroupVersion: &rolloutPauseGroupVersionEncoder,
NegotiatedSerializer: c.NegotiatedSerializer,
}
info, _ := runtime.SerializerInfoForMediaType(c.NegotiatedSerializer.SupportedMediaTypes(), runtime.ContentTypeJSON)
serializers := restclient.Serializers{
Encoder: c.NegotiatedSerializer.EncoderForVersion(info.Serializer, rolloutPauseGroupVersionEncoder),
Decoder: c.NegotiatedSerializer.DecoderToVersion(info.Serializer, rolloutPauseGroupVersionDecoder),
}
if info.StreamSerializer != nil {
serializers.StreamingSerializer = info.StreamSerializer.Serializer
serializers.Framer = info.StreamSerializer.Framer
}
return restclient.NewRequest(c, "PATCH", &url.URL{Host: "localhost"}, c.VersionedAPIPath, config, serializers, nil, nil, 0)
}
func defaultHeader() http.Header {
header := http.Header{}
header.Set("Content-Type", runtime.ContentTypeJSON)
return header
}

View File

@@ -0,0 +1,185 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rollout
import (
"fmt"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"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/genericclioptions/printers"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
// 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 *genericclioptions.PrintFlags
ToPrinter func(string) (printers.ResourcePrinter, error)
Resumer polymorphichelpers.ObjectResumerFunc
Infos []*resource.Info
genericclioptions.IOStreams
}
var (
resume_long = templates.LongDesc(`
Resume a paused resource
Paused resources will not be reconciled by a controller. By resuming a
resource, we allow it to be reconciled again.
Currently only deployments support being resumed.`)
resume_example = templates.Examples(`
# Resume an already paused deployment
kubectl rollout resume deployment/nginx`)
)
func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := &ResumeConfig{
PrintFlags: genericclioptions.NewPrintFlags("resumed").WithTypeSetter(scheme.Scheme),
IOStreams: streams,
}
validArgs := []string{"deployment"}
cmd := &cobra.Command{
Use: "resume RESOURCE",
DisableFlagsInUseLine: true,
Short: i18n.T("Resume a paused resource"),
Long: resume_long,
Example: resume_example,
Run: func(cmd *cobra.Command, args []string) {
allErrs := []error{}
err := o.CompleteResume(f, cmd, args)
if err != nil {
allErrs = append(allErrs, err)
}
err = o.RunResume()
if err != nil {
allErrs = append(allErrs, err)
}
cmdutil.CheckErr(utilerrors.Flatten(utilerrors.NewAggregate(allErrs)))
},
ValidArgs: validArgs,
}
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
return cmd
}
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)
}
o.Resumer = polymorphichelpers.ObjectResumerFn
cmdNamespace, enforceNamespace, err := f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) {
o.PrintFlags.NamePrintFlags.Operation = operation
return o.PrintFlags.ToPrinter()
}
r := f.NewBuilder().
WithScheme(legacyscheme.Scheme).
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
ResourceTypeOrNameArgs(true, args...).
ContinueOnError().
Latest().
Flatten().
Do()
err = r.Err()
if err != nil {
return err
}
err = r.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
o.Infos = append(o.Infos, info)
return nil
})
if err != nil {
return err
}
return nil
}
func (o ResumeConfig) RunResume() error {
allErrs := []error{}
for _, patch := range set.CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), set.PatchFn(o.Resumer)) {
info := patch.Info
if patch.Err != nil {
resourceString := info.Mapping.Resource.Resource
if len(info.Mapping.Resource.Group) > 0 {
resourceString = resourceString + "." + info.Mapping.Resource.Group
}
allErrs = append(allErrs, fmt.Errorf("error: %s %q %v", resourceString, info.Name, patch.Err))
continue
}
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
printer, err := o.ToPrinter("already resumed")
if err != nil {
allErrs = append(allErrs, err)
continue
}
if err = printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
allErrs = append(allErrs, err)
}
}
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
if err != nil {
allErrs = append(allErrs, fmt.Errorf("failed to patch: %v", err))
continue
}
info.Refresh(obj, true)
printer, err := o.ToPrinter("resumed")
if err != nil {
allErrs = append(allErrs, err)
continue
}
if err = printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
allErrs = append(allErrs, err)
}
}
return utilerrors.NewAggregate(allErrs)
}

View File

@@ -0,0 +1,208 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rollout
import (
"fmt"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"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/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
"k8s.io/kubernetes/pkg/util/interrupt"
)
var (
status_long = templates.LongDesc(`
Show the status of the rollout.
By default 'rollout status' will watch the status of the latest rollout
until it's done. If you don't want to wait for the rollout to finish then
you can use --watch=false. Note that if a new rollout starts in-between, then
'rollout status' will continue watching the latest revision. If you want to
pin to a specific revision and abort if it is rolled over by another revision,
use --revision=N where N is the revision you need to watch for.`)
status_example = templates.Examples(`
# Watch the rollout status of a deployment
kubectl rollout status deployment/nginx`)
)
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"}
cmd := &cobra.Command{
Use: "status (TYPE NAME | TYPE/NAME) [flags]",
DisableFlagsInUseLine: true,
Short: i18n.T("Show the status of the rollout"),
Long: status_long,
Example: status_example,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, args))
cmdutil.CheckErr(o.Validate(cmd, args))
cmdutil.CheckErr(o.Run())
},
ValidArgs: validArgs,
}
usage := "identifying the resource to get from a server."
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 (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error {
o.Builder = f.NewBuilder()
var err error
o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
o.BuilderArgs = args
o.StatusViewer = func(mapping *meta.RESTMapping) (kubectl.StatusViewer, error) {
return polymorphichelpers.StatusViewerFn(f, mapping)
}
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.
WithScheme(legacyscheme.Scheme).
NamespaceParam(o.Namespace).DefaultNamespace().
FilenameParam(o.EnforceNamespace, o.FilenameOptions).
ResourceTypeOrNameArgs(true, o.BuilderArgs...).
SingleResourceType().
Latest().
Do()
err := r.Err()
if err != nil {
return err
}
infos, err := r.Infos()
if err != nil {
return err
}
if len(infos) != 1 {
return fmt.Errorf("rollout status is only supported on individual resources and resource collections - %d resources were found", len(infos))
}
info := infos[0]
mapping := info.ResourceMapping()
obj, err := r.Object()
if err != nil {
return err
}
rv, err := meta.NewAccessor().ResourceVersion(obj)
if err != nil {
return err
}
statusViewer, err := o.StatusViewer(mapping)
if err != nil {
return err
}
revision := o.Revision
if revision < 0 {
return fmt.Errorf("revision must be a positive integer: %v", revision)
}
// check if deployment's has finished the rollout
status, done, err := statusViewer.Status(info.Namespace, info.Name, revision)
if err != nil {
return err
}
fmt.Fprintf(o.Out, "%s", status)
if done {
return nil
}
shouldWatch := o.Watch
if !shouldWatch {
return nil
}
// watch for changes to the deployment
w, err := r.Watch(rv)
if err != nil {
return err
}
// if the rollout isn't done yet, keep watching deployment status
intr := interrupt.New(nil, w.Stop)
return intr.Run(func() error {
_, err := watch.Until(0, w, func(e watch.Event) (bool, error) {
// print deployment's status
status, done, err := statusViewer.Status(info.Namespace, info.Name, revision)
if err != nil {
return false, err
}
fmt.Fprintf(o.Out, "%s", status)
// Quit waiting if the rollout is done
if done {
return true, nil
}
return false, nil
})
return err
})
}

View File

@@ -0,0 +1,170 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rollout
import (
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"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/genericclioptions/printers"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
// UndoOptions 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 UndoOptions struct {
resource.FilenameOptions
PrintFlags *genericclioptions.PrintFlags
ToPrinter func(string) (printers.ResourcePrinter, error)
Rollbackers []kubectl.Rollbacker
Infos []*resource.Info
ToRevision int64
DryRun bool
Out io.Writer
}
var (
undo_long = templates.LongDesc(`
Rollback to a previous rollout.`)
undo_example = templates.Examples(`
# Rollback to the previous deployment
kubectl rollout undo deployment/abc
# Rollback to daemonset revision 3
kubectl rollout undo daemonset/abc --to-revision=3
# Rollback to the previous deployment with dry-run
kubectl rollout undo --dry-run=true deployment/abc`)
)
func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
o := &UndoOptions{
PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme),
ToRevision: int64(0),
}
validArgs := []string{"deployment", "daemonset", "statefulset"}
cmd := &cobra.Command{
Use: "undo (TYPE NAME | TYPE/NAME) [flags]",
DisableFlagsInUseLine: true,
Short: i18n.T("Undo a previous rollout"),
Long: undo_long,
Example: undo_example,
Run: func(cmd *cobra.Command, args []string) {
allErrs := []error{}
err := o.CompleteUndo(f, cmd, out, args)
if err != nil {
allErrs = append(allErrs, err)
}
err = o.RunUndo()
if err != nil {
allErrs = append(allErrs, err)
}
cmdutil.CheckErr(utilerrors.Flatten(utilerrors.NewAggregate(allErrs)))
},
ValidArgs: validArgs,
}
cmd.Flags().Int64Var(&o.ToRevision, "to-revision", o.ToRevision, "The revision to rollback to. Default to 0 (last revision).")
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
cmdutil.AddDryRunFlag(cmd)
return cmd
}
func (o *UndoOptions) CompleteUndo(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []string) error {
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
return cmdutil.UsageErrorf(cmd, "Required resource not specified.")
}
o.Out = out
o.DryRun = cmdutil.GetDryRunFlag(cmd)
cmdNamespace, enforceNamespace, err := f.ToRawKubeConfigLoader().Namespace()
if err != nil {
return err
}
o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) {
o.PrintFlags.NamePrintFlags.Operation = operation
if o.DryRun {
o.PrintFlags.Complete("%s (dry run)")
}
return o.PrintFlags.ToPrinter()
}
r := f.NewBuilder().
WithScheme(legacyscheme.Scheme).
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
ResourceTypeOrNameArgs(true, args...).
ContinueOnError().
Latest().
Flatten().
Do()
err = r.Err()
if err != nil {
return err
}
err = r.Visit(func(info *resource.Info, err error) error {
if err != nil {
return err
}
rollbacker, err := polymorphichelpers.RollbackerFn(f, info.ResourceMapping())
if err != nil {
return err
}
o.Infos = append(o.Infos, info)
o.Rollbackers = append(o.Rollbackers, rollbacker)
return nil
})
return err
}
func (o *UndoOptions) RunUndo() error {
allErrs := []error{}
for ix, info := range o.Infos {
result, err := o.Rollbackers[ix].Rollback(info.Object, nil, o.ToRevision, o.DryRun)
if err != nil {
allErrs = append(allErrs, cmdutil.AddSourceToErr("undoing", info.Source, err))
continue
}
printer, err := o.ToPrinter(result)
if err != nil {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out)
}
return utilerrors.NewAggregate(allErrs)
}