Merge pull request #34502 from fabianofranz/cli_usability_improvements
Automatic merge from submit-queue Improvements to CLI usability and maintainability Improves `kubectl` from an usability perspective by 1. Fixing how we handle terminal width in help. Some sections like the flags use the entire available width, while others like long descriptions breaks lines but don't follow a well established max width (screenshot below). This PR adds a new responsive writer that will adjust to terminal width and set 80, 100, or 120 columns as the max width, but not more than that given POSIX best practices and recommendations for better readability.  2. Adds our own normalizers for long descriptions and cmd examples which allows us better control about how things like lists, paragraphs, line breaks, etc are printed. Features markdown support. Looks like `templates.LongDesc` and `templates.Examples` instead of `dedent.Dedend`. 3. Allows simple reordering and reuse of help and usage sections. 3. Adds `verify-cli-conventions.sh` which intends to run tests to make sure cmd developers are using what we propose as [kubectl conventions](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/kubectl-conventions.md). Just a couple simple tests for now but the framework is there and it's easy to extend. 4. Update [kubectl conventions](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/kubectl-conventions.md) to use our own normalizers instead of `dedent.Dedent`. **Release note**: <!-- Steps to write your release note: 1. Use the release-note-* labels to set the release note state (if you have access) 2. Enter your extended release note in the below block; leaving it blank means using the PR title as the release note. If no release note is required, just write `NONE`. --> ```release-note Improves how 'kubectl' uses the terminal size when printing help and usage. ``` @kubernetes/kubectl
This commit is contained in:
8
Godeps/Godeps.json
generated
8
Godeps/Godeps.json
generated
@@ -65,6 +65,10 @@
|
|||||||
"Comment": "v7.0.6-4-g2492d97",
|
"Comment": "v7.0.6-4-g2492d97",
|
||||||
"Rev": "2492d97b402e00797833c03ac5fa1c572c7bb29a"
|
"Rev": "2492d97b402e00797833c03ac5fa1c572c7bb29a"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/MakeNowJust/heredoc",
|
||||||
|
"Rev": "1d91351acdc1cb2f2c995864674b754134b86ca7"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/Microsoft/go-winio",
|
"ImportPath": "github.com/Microsoft/go-winio",
|
||||||
"Comment": "v0.1.0",
|
"Comment": "v0.1.0",
|
||||||
@@ -1537,6 +1541,10 @@
|
|||||||
"Comment": "v2.1.1-5-g1b4ae6f",
|
"Comment": "v2.1.1-5-g1b4ae6f",
|
||||||
"Rev": "1b4ae6fb4e77b095934d4430860ff202060169f8"
|
"Rev": "1b4ae6fb4e77b095934d4430860ff202060169f8"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/mitchellh/go-wordwrap",
|
||||||
|
"Rev": "ad45545899c7b13c020ea92b2072220eefad42b8"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/mitchellh/mapstructure",
|
"ImportPath": "github.com/mitchellh/mapstructure",
|
||||||
"Rev": "740c764bc6149d3f1806231418adb9f52c11bcbf"
|
"Rev": "740c764bc6149d3f1806231418adb9f52c11bcbf"
|
||||||
|
58
Godeps/LICENSES
generated
58
Godeps/LICENSES
generated
@@ -51179,6 +51179,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
= vendor/github.com/MakeNowJust/heredoc licensed under: =
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 TSUYUSATO Kitsune
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
= vendor/github.com/MakeNowJust/heredoc/LICENSE 15e1c8f1d3c204c05f71630afacbc92b -
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
= vendor/github.com/matttproud/golang_protobuf_extensions/pbutil licensed under: =
|
= vendor/github.com/matttproud/golang_protobuf_extensions/pbutil licensed under: =
|
||||||
|
|
||||||
@@ -52706,6 +52735,35 @@ Apache License
|
|||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
= vendor/github.com/mitchellh/go-wordwrap licensed under: =
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Mitchell Hashimoto
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
= vendor/github.com/mitchellh/go-wordwrap/LICENSE.md 56da355a12d4821cda57b8f23ec34bc4 -
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
= vendor/github.com/mitchellh/mapstructure licensed under: =
|
= vendor/github.com/mitchellh/mapstructure licensed under: =
|
||||||
|
|
||||||
|
48
cmd/clicheck/check_cli_conventions.go
Normal file
48
cmd/clicheck/check_cli_conventions.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
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 main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||||
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
cmdsanity "k8s.io/kubernetes/pkg/kubectl/cmd/util/sanity"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
skip = []string{}
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
errors := []error{}
|
||||||
|
|
||||||
|
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||||
|
result := cmdsanity.CheckCmdTree(kubectl, cmdsanity.AllCmdChecks, []string{})
|
||||||
|
errors = append(errors, result...)
|
||||||
|
|
||||||
|
if len(errors) > 0 {
|
||||||
|
for i, err := range errors {
|
||||||
|
fmt.Fprintf(os.Stderr, "%d. %s\n\n", i+1, err)
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(os.Stdout, "Congrats, CLI looks good!")
|
||||||
|
}
|
@@ -301,17 +301,13 @@ Sample command skeleton:
|
|||||||
// MineRecommendedName is the recommended command name for kubectl mine.
|
// MineRecommendedName is the recommended command name for kubectl mine.
|
||||||
const MineRecommendedName = "mine"
|
const MineRecommendedName = "mine"
|
||||||
|
|
||||||
// MineConfig contains all the options for running the mine cli command.
|
// Long command description and examples.
|
||||||
type MineConfig struct {
|
|
||||||
mineLatest bool
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
mineLong = dedent.Dedent(`
|
mineLong = templates.LongDesc(`
|
||||||
mine which is described here
|
mine which is described here
|
||||||
with lots of details.`)
|
with lots of details.`)
|
||||||
|
|
||||||
mineExample = dedent.Dedent(`
|
mineExample = templates.Examples(`
|
||||||
# Run my command's first action
|
# Run my command's first action
|
||||||
kubectl mine first_action
|
kubectl mine first_action
|
||||||
|
|
||||||
@@ -319,6 +315,11 @@ var (
|
|||||||
kubectl mine second_action --flag`)
|
kubectl mine second_action --flag`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MineConfig contains all the options for running the mine cli command.
|
||||||
|
type MineConfig struct {
|
||||||
|
mineLatest bool
|
||||||
|
}
|
||||||
|
|
||||||
// NewCmdMine implements the kubectl mine command.
|
// NewCmdMine implements the kubectl mine command.
|
||||||
func NewCmdMine(parent, name string, f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdMine(parent, name string, f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
opts := &MineConfig{}
|
opts := &MineConfig{}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
cluster/addons/fluentd-elasticsearch/es-image
|
cluster/addons/fluentd-elasticsearch/es-image
|
||||||
cluster/images/etcd/attachlease
|
cluster/images/etcd/attachlease
|
||||||
cluster/images/etcd/rollback
|
cluster/images/etcd/rollback
|
||||||
|
cmd/clicheck
|
||||||
cmd/gendocs
|
cmd/gendocs
|
||||||
cmd/genkubedocs
|
cmd/genkubedocs
|
||||||
cmd/genman
|
cmd/genman
|
||||||
|
40
hack/verify-cli-conventions.sh
Executable file
40
hack/verify-cli-conventions.sh
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..
|
||||||
|
source "${KUBE_ROOT}/hack/lib/init.sh"
|
||||||
|
|
||||||
|
kube::golang::setup_env
|
||||||
|
|
||||||
|
BINS=(
|
||||||
|
cmd/clicheck
|
||||||
|
)
|
||||||
|
make -C "${KUBE_ROOT}" WHAT="${BINS[*]}"
|
||||||
|
|
||||||
|
clicheck=$(kube::util::find-binary "clicheck")
|
||||||
|
|
||||||
|
if ! output=`$clicheck 2>&1`
|
||||||
|
then
|
||||||
|
echo "FAILURE: CLI is not following one or more required conventions:"
|
||||||
|
echo "$output"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "SUCCESS: CLI is following all tested conventions."
|
||||||
|
fi
|
@@ -23,11 +23,11 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -59,17 +59,17 @@ type AnnotateOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
annotate_long = dedent.Dedent(`
|
annotate_long = templates.LongDesc(`
|
||||||
Update the annotations on one or more resources.
|
Update the annotations on one or more resources.
|
||||||
|
|
||||||
An annotation is a key/value pair that can hold larger (compared to a label), and possibly not human-readable, data.
|
* An annotation is a key/value pair that can hold larger (compared to a label), and possibly not human-readable, data.
|
||||||
It is intended to store non-identifying auxiliary data, especially data manipulated by tools and system extensions.
|
* It is intended to store non-identifying auxiliary data, especially data manipulated by tools and system extensions.
|
||||||
If --overwrite is true, then existing annotations can be overwritten, otherwise attempting to overwrite an annotation will result in an error.
|
* If --overwrite is true, then existing annotations can be overwritten, otherwise attempting to overwrite an annotation will result in an error.
|
||||||
If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used.
|
* If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used.
|
||||||
|
|
||||||
`) + valid_resources
|
` + valid_resources)
|
||||||
|
|
||||||
annotate_example = dedent.Dedent(`
|
annotate_example = templates.Examples(`
|
||||||
# Update pod 'foo' with the annotation 'description' and the value 'my frontend'.
|
# Update pod 'foo' with the annotation 'description' and the value 'my frontend'.
|
||||||
# If the same annotation is set multiple times, only the last value will be applied
|
# If the same annotation is set multiple times, only the last value will be applied
|
||||||
kubectl annotate pods foo description='my frontend'
|
kubectl annotate pods foo description='my frontend'
|
||||||
|
@@ -22,7 +22,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jonboulle/clockwork"
|
"github.com/jonboulle/clockwork"
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@@ -32,6 +31,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
@@ -58,7 +58,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
apply_long = dedent.Dedent(`
|
apply_long = templates.LongDesc(`
|
||||||
Apply a configuration to a resource by filename or stdin.
|
Apply a configuration to a resource by filename or stdin.
|
||||||
This resource will be created if it doesn't exist yet.
|
This resource will be created if it doesn't exist yet.
|
||||||
To use 'apply', always create the resource initially with either 'apply' or 'create --save-config'.
|
To use 'apply', always create the resource initially with either 'apply' or 'create --save-config'.
|
||||||
@@ -67,7 +67,7 @@ var (
|
|||||||
|
|
||||||
Alpha Disclaimer: the --prune functionality is not yet complete. Do not use unless you are aware of what the current state is. See https://issues.k8s.io/34274.`)
|
Alpha Disclaimer: the --prune functionality is not yet complete. Do not use unless you are aware of what the current state is. See https://issues.k8s.io/34274.`)
|
||||||
|
|
||||||
apply_example = dedent.Dedent(`
|
apply_example = templates.Examples(`
|
||||||
# Apply the configuration in pod.json to a pod.
|
# Apply the configuration in pod.json to a pod.
|
||||||
kubectl apply -f ./pod.json
|
kubectl apply -f ./pod.json
|
||||||
|
|
||||||
|
@@ -22,13 +22,13 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/client/restclient"
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand"
|
remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand"
|
||||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||||
@@ -36,7 +36,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
attach_example = dedent.Dedent(`
|
attach_example = templates.Examples(`
|
||||||
# Get output from running pod 123456-7890, using the first container by default
|
# Get output from running pod 123456-7890, using the first container by default
|
||||||
kubectl attach 123456-7890
|
kubectl attach 123456-7890
|
||||||
|
|
||||||
|
@@ -20,9 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||||
@@ -31,13 +30,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
autoscaleLong = dedent.Dedent(`
|
autoscaleLong = templates.LongDesc(`
|
||||||
Creates an autoscaler that automatically chooses and sets the number of pods that run in a kubernetes cluster.
|
Creates an autoscaler that automatically chooses and sets the number of pods that run in a kubernetes cluster.
|
||||||
|
|
||||||
Looks up a Deployment, ReplicaSet, or ReplicationController by name and creates an autoscaler that uses the given resource as a reference.
|
Looks up a Deployment, ReplicaSet, or ReplicationController by name and creates an autoscaler that uses the given resource as a reference.
|
||||||
An autoscaler can automatically increase or decrease number of pods deployed within the system as needed.`)
|
An autoscaler can automatically increase or decrease number of pods deployed within the system as needed.`)
|
||||||
|
|
||||||
autoscaleExample = dedent.Dedent(`
|
autoscaleExample = templates.Examples(`
|
||||||
# Auto scale a deployment "foo", with the number of pods between 2 and 10, target CPU utilization specified so a default autoscaling policy will be used:
|
# Auto scale a deployment "foo", with the number of pods between 2 and 10, target CPU utilization specified so a default autoscaling policy will be used:
|
||||||
kubectl autoscale deployment foo --min=2 --max=10
|
kubectl autoscale deployment foo --min=2 --max=10
|
||||||
|
|
||||||
|
@@ -23,6 +23,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
|
|
||||||
@@ -30,8 +31,9 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var longDescr = `Display addresses of the master and services with label kubernetes.io/cluster-service=true
|
var longDescr = templates.LongDesc(`
|
||||||
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.`
|
Display addresses of the master and services with label kubernetes.io/cluster-service=true
|
||||||
|
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.`)
|
||||||
|
|
||||||
func NewCmdClusterInfo(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdClusterInfo(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
@@ -26,6 +26,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -46,28 +47,28 @@ func NewCmdClusterInfoDump(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
var (
|
||||||
dumpLong = `
|
dumpLong = templates.LongDesc(`
|
||||||
Dumps cluster info out suitable for debugging and diagnosing cluster problems. By default, dumps everything to
|
Dumps cluster info out suitable for debugging and diagnosing cluster problems. By default, dumps everything to
|
||||||
stdout. You can optionally specify a directory with --output-directory. If you specify a directory, kubernetes will
|
stdout. You can optionally specify a directory with --output-directory. If you specify a directory, kubernetes will
|
||||||
build a set of files in that directory. By default only dumps things in the 'kube-system' namespace, but you can
|
build a set of files in that directory. By default only dumps things in the 'kube-system' namespace, but you can
|
||||||
switch to a different namespace with the --namespaces flag, or specify --all-namespaces to dump all namespaces.
|
switch to a different namespace with the --namespaces flag, or specify --all-namespaces to dump all namespaces.
|
||||||
|
|
||||||
The command also dumps the logs of all of the pods in the cluster, these logs are dumped into different directories
|
The command also dumps the logs of all of the pods in the cluster, these logs are dumped into different directories
|
||||||
based on namespace and pod name.
|
based on namespace and pod name.`)
|
||||||
`
|
|
||||||
|
|
||||||
dumpExample = `# Dump current cluster state to stdout
|
dumpExample = templates.Examples(`
|
||||||
kubectl cluster-info dump
|
# Dump current cluster state to stdout
|
||||||
|
kubectl cluster-info dump
|
||||||
|
|
||||||
# Dump current cluster state to /path/to/cluster-state
|
# Dump current cluster state to /path/to/cluster-state
|
||||||
kubectl cluster-info dump --output-directory=/path/to/cluster-state
|
kubectl cluster-info dump --output-directory=/path/to/cluster-state
|
||||||
|
|
||||||
# Dump all namespaces to stdout
|
# Dump all namespaces to stdout
|
||||||
kubectl cluster-info dump --all-namespaces
|
kubectl cluster-info dump --all-namespaces
|
||||||
|
|
||||||
# Dump a set of namespaces to /path/to/cluster-state
|
# Dump a set of namespaces to /path/to/cluster-state
|
||||||
kubectl cluster-info dump --namespaces default,kube-system --output-directory=/path/to/cluster-state`
|
kubectl cluster-info dump --namespaces default,kube-system --output-directory=/path/to/cluster-state`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupOutputWriter(cmd *cobra.Command, defaultWriter io.Writer, filename string) io.Writer {
|
func setupOutputWriter(cmd *cobra.Command, defaultWriter io.Writer, filename string) io.Writer {
|
||||||
|
@@ -169,6 +169,7 @@ __custom_func() {
|
|||||||
// and add a short forms entry in expandResourceShortcut() when appropriate.
|
// and add a short forms entry in expandResourceShortcut() when appropriate.
|
||||||
// TODO: This should be populated using the discovery information from apiserver.
|
// TODO: This should be populated using the discovery information from apiserver.
|
||||||
valid_resources = `Valid resource types include:
|
valid_resources = `Valid resource types include:
|
||||||
|
|
||||||
* clusters (valid only for federation apiservers)
|
* clusters (valid only for federation apiservers)
|
||||||
* componentstatuses (aka 'cs')
|
* componentstatuses (aka 'cs')
|
||||||
* configmaps (aka 'cm')
|
* configmaps (aka 'cm')
|
||||||
@@ -193,34 +194,7 @@ __custom_func() {
|
|||||||
* secrets
|
* secrets
|
||||||
* serviceaccounts (aka 'sa')
|
* serviceaccounts (aka 'sa')
|
||||||
* services (aka 'svc')
|
* services (aka 'svc')
|
||||||
`
|
`
|
||||||
usage_template = `{{if gt .Aliases 0}}
|
|
||||||
|
|
||||||
Aliases:
|
|
||||||
{{.NameAndAliases}}{{end}}{{if .HasExample}}
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
{{ .Example }}{{end}}{{ if .HasAvailableSubCommands}}
|
|
||||||
|
|
||||||
Available Sub-commands:{{range .Commands}}{{if .IsAvailableCommand}}
|
|
||||||
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{ if .HasLocalFlags}}
|
|
||||||
|
|
||||||
Flags:
|
|
||||||
{{.LocalFlags.FlagUsages | trimRightSpace}}{{end}}{{ if .HasInheritedFlags}}
|
|
||||||
|
|
||||||
Global Flags:
|
|
||||||
{{.InheritedFlags.FlagUsages | trimRightSpace}}{{end}}{{if .HasHelpSubCommands}}
|
|
||||||
|
|
||||||
Additional help topics:{{range .Commands}}{{if .IsHelpCommand}}
|
|
||||||
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}
|
|
||||||
|
|
||||||
Usage:{{if .Runnable}}
|
|
||||||
{{if .HasFlags}}{{appendIfNotPresent .UseLine "[flags]"}}{{else}}{{.UseLine}}{{end}}{{end}}{{ if .HasSubCommands }}
|
|
||||||
{{ .CommandPath}} [command]
|
|
||||||
|
|
||||||
Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
|
|
||||||
`
|
|
||||||
help_template = `{{with or .Long .Short }}{{. | trim}}{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewKubectlCommand creates the `kubectl` command and its nested children.
|
// NewKubectlCommand creates the `kubectl` command and its nested children.
|
||||||
@@ -229,9 +203,10 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
|
|||||||
cmds := &cobra.Command{
|
cmds := &cobra.Command{
|
||||||
Use: "kubectl",
|
Use: "kubectl",
|
||||||
Short: "kubectl controls the Kubernetes cluster manager",
|
Short: "kubectl controls the Kubernetes cluster manager",
|
||||||
Long: `kubectl controls the Kubernetes cluster manager.
|
Long: templates.LongDesc(`
|
||||||
|
kubectl controls the Kubernetes cluster manager.
|
||||||
|
|
||||||
Find more information at https://github.com/kubernetes/kubernetes.`,
|
Find more information at https://github.com/kubernetes/kubernetes.`),
|
||||||
Run: runHelp,
|
Run: runHelp,
|
||||||
BashCompletionFunction: bash_completion_func,
|
BashCompletionFunction: bash_completion_func,
|
||||||
}
|
}
|
||||||
|
@@ -20,21 +20,19 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
completion_long = dedent.Dedent(`
|
completion_long = templates.LongDesc(`
|
||||||
Output shell completion code for the given shell (bash or zsh).
|
Output shell completion code for the given shell (bash or zsh).
|
||||||
|
|
||||||
This command prints shell code which must be evaluation to provide interactive
|
This command prints shell code which must be evaluation to provide interactive
|
||||||
completion of kubectl commands.
|
completion of kubectl commands.
|
||||||
`)
|
|
||||||
|
|
||||||
completion_example = dedent.Dedent(`
|
|
||||||
$ source <(kubectl completion bash)
|
$ source <(kubectl completion bash)
|
||||||
|
|
||||||
will load the kubectl completion code for bash. Note that this depends on the
|
will load the kubectl completion code for bash. Note that this depends on the
|
||||||
@@ -45,11 +43,11 @@ var (
|
|||||||
$ source $(brew --prefix)/etc/bash_completion
|
$ source $(brew --prefix)/etc/bash_completion
|
||||||
$ source <(kubectl completion bash)
|
$ source <(kubectl completion bash)
|
||||||
|
|
||||||
If you use zsh*, the following will load kubectl zsh completion:
|
If you use zsh[1], the following will load kubectl zsh completion:
|
||||||
|
|
||||||
$ source <(kubectl completion zsh)
|
$ source <(kubectl completion zsh)
|
||||||
|
|
||||||
* zsh completions are only supported in versions of zsh >= 5.2`)
|
[1] zsh completions are only supported in versions of zsh >= 5.2`)
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -69,7 +67,6 @@ func NewCmdCompletion(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
Use: "completion SHELL",
|
Use: "completion SHELL",
|
||||||
Short: "Output shell completion code for the given shell (bash or zsh)",
|
Short: "Output shell completion code for the given shell (bash or zsh)",
|
||||||
Long: completion_long,
|
Long: completion_long,
|
||||||
Example: completion_example,
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
err := RunCompletion(f, out, cmd, args)
|
err := RunCompletion(f, out, cmd, args)
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
|
@@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCmdConfig creates a command object for the "config" action, and adds all child commands to it.
|
// NewCmdConfig creates a command object for the "config" action, and adds all child commands to it.
|
||||||
@@ -35,13 +36,14 @@ func NewCmdConfig(pathOptions *clientcmd.PathOptions, out io.Writer) *cobra.Comm
|
|||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "config SUBCOMMAND",
|
Use: "config SUBCOMMAND",
|
||||||
Short: "Modify kubeconfig files",
|
Short: "Modify kubeconfig files",
|
||||||
Long: `Modify kubeconfig files using subcommands like "kubectl config set current-context my-context"
|
Long: templates.LongDesc(`
|
||||||
|
Modify kubeconfig files using subcommands like "kubectl config set current-context my-context"
|
||||||
|
|
||||||
The loading order follows these rules:
|
The loading order follows these rules:
|
||||||
1. If the --` + pathOptions.ExplicitFileFlag + ` flag is set, then only that file is loaded. The flag may only be set once and no merging takes place.
|
|
||||||
2. If $` + pathOptions.EnvVar + ` environment variable is set, then it is used a list of paths (normal path delimitting rules for your system). These paths are merged. When a value is modified, it is modified in the file that defines the stanza. When a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the last file in the list.
|
1. If the --` + pathOptions.ExplicitFileFlag + ` flag is set, then only that file is loaded. The flag may only be set once and no merging takes place.
|
||||||
3. Otherwise, ` + path.Join("${HOME}", pathOptions.GlobalFileSubpath) + ` is used and no merging takes place.
|
2. If $` + pathOptions.EnvVar + ` environment variable is set, then it is used a list of paths (normal path delimitting rules for your system). These paths are merged. When a value is modified, it is modified in the file that defines the stanza. When a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the last file in the list.
|
||||||
`,
|
3. Otherwise, ` + path.Join("${HOME}", pathOptions.GlobalFileSubpath) + ` is used and no merging takes place.`),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmd.Help()
|
cmd.Help()
|
||||||
},
|
},
|
||||||
|
@@ -24,11 +24,11 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/util/flag"
|
"k8s.io/kubernetes/pkg/util/flag"
|
||||||
)
|
)
|
||||||
@@ -55,9 +55,10 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
create_authinfo_long = fmt.Sprintf(`
|
create_authinfo_long = fmt.Sprintf(templates.LongDesc(`
|
||||||
Sets a user entry in kubeconfig
|
Sets a user entry in kubeconfig
|
||||||
Specifying a name that already exists will merge new fields on top of existing values.
|
|
||||||
|
Specifying a name that already exists will merge new fields on top of existing values.
|
||||||
|
|
||||||
Client-certificate flags:
|
Client-certificate flags:
|
||||||
--%v=certfile --%v=keyfile
|
--%v=certfile --%v=keyfile
|
||||||
@@ -68,10 +69,9 @@ Specifying a name that already exists will merge new fields on top of existing v
|
|||||||
Basic auth flags:
|
Basic auth flags:
|
||||||
--%v=basic_user --%v=basic_password
|
--%v=basic_user --%v=basic_password
|
||||||
|
|
||||||
Bearer token and basic auth are mutually exclusive.
|
Bearer token and basic auth are mutually exclusive.`), clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword)
|
||||||
`, clientcmd.FlagCertFile, clientcmd.FlagKeyFile, clientcmd.FlagBearerToken, clientcmd.FlagUsername, clientcmd.FlagPassword)
|
|
||||||
|
|
||||||
create_authinfo_example = dedent.Dedent(`
|
create_authinfo_example = templates.Examples(`
|
||||||
# Set only the "client-key" field on the "cluster-admin"
|
# Set only the "client-key" field on the "cluster-admin"
|
||||||
# entry, without touching other values:
|
# entry, without touching other values:
|
||||||
kubectl config set-credentials cluster-admin --client-key=~/.kube/admin.key
|
kubectl config set-credentials cluster-admin --client-key=~/.kube/admin.key
|
||||||
|
@@ -23,11 +23,11 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
"k8s.io/kubernetes/pkg/util/flag"
|
"k8s.io/kubernetes/pkg/util/flag"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -42,10 +42,12 @@ type createClusterOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
create_cluster_long = dedent.Dedent(`
|
create_cluster_long = templates.LongDesc(`
|
||||||
Sets a cluster entry in kubeconfig.
|
Sets a cluster entry in kubeconfig.
|
||||||
|
|
||||||
Specifying a name that already exists will merge new fields on top of existing values for those fields.`)
|
Specifying a name that already exists will merge new fields on top of existing values for those fields.`)
|
||||||
create_cluster_example = dedent.Dedent(`
|
|
||||||
|
create_cluster_example = templates.Examples(`
|
||||||
# Set only the server field on the e2e cluster entry without touching other values.
|
# Set only the server field on the e2e cluster entry without touching other values.
|
||||||
kubectl config set-cluster e2e --server=https://1.2.3.4
|
kubectl config set-cluster e2e --server=https://1.2.3.4
|
||||||
|
|
||||||
|
@@ -21,11 +21,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
"k8s.io/kubernetes/pkg/util/flag"
|
"k8s.io/kubernetes/pkg/util/flag"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -38,10 +38,12 @@ type createContextOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
create_context_long = dedent.Dedent(`
|
create_context_long = templates.LongDesc(`
|
||||||
Sets a context entry in kubeconfig
|
Sets a context entry in kubeconfig
|
||||||
|
|
||||||
Specifying a name that already exists will merge new fields on top of existing values for those fields.`)
|
Specifying a name that already exists will merge new fields on top of existing values for those fields.`)
|
||||||
create_context_example = dedent.Dedent(`
|
|
||||||
|
create_context_example = templates.Examples(`
|
||||||
# Set the user field on the gce context entry without touching other values
|
# Set the user field on the gce context entry without touching other values
|
||||||
kubectl config set-context gce --user=cluster-admin`)
|
kubectl config set-context gce --user=cluster-admin`)
|
||||||
)
|
)
|
||||||
|
@@ -20,10 +20,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -32,9 +32,10 @@ type CurrentContextOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
current_context_long = dedent.Dedent(`
|
current_context_long = templates.LongDesc(`
|
||||||
Displays the current-context`)
|
Displays the current-context`)
|
||||||
current_context_example = dedent.Dedent(`
|
|
||||||
|
current_context_example = templates.Examples(`
|
||||||
# Display the current-context
|
# Display the current-context
|
||||||
kubectl config current-context`)
|
kubectl config current-context`)
|
||||||
)
|
)
|
||||||
|
@@ -26,7 +26,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
@@ -41,14 +41,15 @@ type GetContextsOptions struct {
|
|||||||
out io.Writer
|
out io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
var (
|
||||||
getContextsLong = `Displays one or many contexts from the kubeconfig file.`
|
getContextsLong = templates.LongDesc(`Displays one or many contexts from the kubeconfig file.`)
|
||||||
|
|
||||||
getContextsExample = `# List all the contexts in your kubeconfig file
|
getContextsExample = templates.Examples(`
|
||||||
kubectl config get-contexts
|
# List all the contexts in your kubeconfig file
|
||||||
|
kubectl config get-contexts
|
||||||
|
|
||||||
# Describe one context in your kubeconfig file.
|
# Describe one context in your kubeconfig file.
|
||||||
kubectl config get-contexts my-context`
|
kubectl config get-contexts my-context`)
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCmdConfigGetContexts creates a command object for the "get-contexts" action, which
|
// NewCmdConfigGetContexts creates a command object for the "get-contexts" action, which
|
||||||
|
@@ -24,10 +24,10 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
"k8s.io/kubernetes/pkg/util/flag"
|
"k8s.io/kubernetes/pkg/util/flag"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,9 +43,11 @@ type setOptions struct {
|
|||||||
setRawBytes flag.Tristate
|
setRawBytes flag.Tristate
|
||||||
}
|
}
|
||||||
|
|
||||||
var set_long = dedent.Dedent(`
|
var set_long = templates.LongDesc(`
|
||||||
Sets an individual value in a kubeconfig file
|
Sets an individual value in a kubeconfig file
|
||||||
|
|
||||||
PROPERTY_NAME is a dot delimited name where each token represents either an attribute name or a map key. Map keys may not contain dots.
|
PROPERTY_NAME is a dot delimited name where each token represents either an attribute name or a map key. Map keys may not contain dots.
|
||||||
|
|
||||||
PROPERTY_VALUE is the new value you wish to set. Binary fields such as 'certificate-authority-data' expect a base64 encoded string unless the --set-raw-bytes flag is used.`)
|
PROPERTY_VALUE is the new value you wish to set. Binary fields such as 'certificate-authority-data' expect a base64 encoded string unless the --set-raw-bytes flag is used.`)
|
||||||
|
|
||||||
func NewCmdConfigSet(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
|
func NewCmdConfigSet(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
|
||||||
|
@@ -22,8 +22,8 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
)
|
)
|
||||||
@@ -33,8 +33,9 @@ type unsetOptions struct {
|
|||||||
propertyName string
|
propertyName string
|
||||||
}
|
}
|
||||||
|
|
||||||
var unset_long = dedent.Dedent(`
|
var unset_long = templates.LongDesc(`
|
||||||
Unsets an individual value in a kubeconfig file
|
Unsets an individual value in a kubeconfig file
|
||||||
|
|
||||||
PROPERTY_NAME is a dot delimited name where each token represents either an attribute name or a map key. Map keys may not contain dots.`)
|
PROPERTY_NAME is a dot delimited name where each token represents either an attribute name or a map key. Map keys may not contain dots.`)
|
||||||
|
|
||||||
func NewCmdConfigUnset(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
|
func NewCmdConfigUnset(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
|
||||||
|
@@ -21,13 +21,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/latest"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api/latest"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/util/flag"
|
"k8s.io/kubernetes/pkg/util/flag"
|
||||||
)
|
)
|
||||||
@@ -41,11 +41,12 @@ type ViewOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
view_long = dedent.Dedent(`
|
view_long = templates.LongDesc(`
|
||||||
Display merged kubeconfig settings or a specified kubeconfig file.
|
Display merged kubeconfig settings or a specified kubeconfig file.
|
||||||
|
|
||||||
You can use --output jsonpath={...} to extract specific values using a jsonpath expression.`)
|
You can use --output jsonpath={...} to extract specific values using a jsonpath expression.`)
|
||||||
view_example = dedent.Dedent(`
|
|
||||||
|
view_example = templates.Examples(`
|
||||||
# Show Merged kubeconfig settings.
|
# Show Merged kubeconfig settings.
|
||||||
kubectl config view
|
kubectl config view
|
||||||
|
|
||||||
|
@@ -21,12 +21,11 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -35,7 +34,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
convert_long = dedent.Dedent(`
|
convert_long = templates.LongDesc(`
|
||||||
Convert config files between different API versions. Both YAML
|
Convert config files between different API versions. Both YAML
|
||||||
and JSON formats are accepted.
|
and JSON formats are accepted.
|
||||||
|
|
||||||
@@ -44,10 +43,9 @@ var (
|
|||||||
not supported, convert to latest version.
|
not supported, convert to latest version.
|
||||||
|
|
||||||
The default output will be printed to stdout in YAML format. One can use -o option
|
The default output will be printed to stdout in YAML format. One can use -o option
|
||||||
to change to output destination.
|
to change to output destination.`)
|
||||||
`)
|
|
||||||
|
|
||||||
convert_example = dedent.Dedent(`
|
convert_example = templates.Examples(`
|
||||||
# Convert 'pod.yaml' to latest version and print to stdout.
|
# Convert 'pod.yaml' to latest version and print to stdout.
|
||||||
kubectl convert -f pod.yaml
|
kubectl convert -f pod.yaml
|
||||||
|
|
||||||
@@ -56,8 +54,7 @@ var (
|
|||||||
kubectl convert -f pod.yaml --local -o json
|
kubectl convert -f pod.yaml --local -o json
|
||||||
|
|
||||||
# Convert all files under current directory to latest version and create them all.
|
# Convert all files under current directory to latest version and create them all.
|
||||||
kubectl convert -f . | kubectl create -f -
|
kubectl convert -f . | kubectl create -f -`)
|
||||||
`)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCmdConvert creates a command object for the generic "convert" action, which
|
// NewCmdConvert creates a command object for the generic "convert" action, which
|
||||||
|
@@ -20,22 +20,23 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
create_long = dedent.Dedent(`
|
create_long = templates.LongDesc(`
|
||||||
Create a resource by filename or stdin.
|
Create a resource by filename or stdin.
|
||||||
|
|
||||||
JSON and YAML formats are accepted.`)
|
JSON and YAML formats are accepted.`)
|
||||||
create_example = dedent.Dedent(`
|
|
||||||
|
create_example = templates.Examples(`
|
||||||
# Create a pod using the data in pod.json.
|
# Create a pod using the data in pod.json.
|
||||||
kubectl create -f ./pod.json
|
kubectl create -f ./pod.json
|
||||||
|
|
||||||
|
@@ -20,15 +20,15 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
configMapLong = dedent.Dedent(`
|
configMapLong = templates.LongDesc(`
|
||||||
Create a configmap based on a file, directory, or specified literal value.
|
Create a configmap based on a file, directory, or specified literal value.
|
||||||
|
|
||||||
A single configmap may package one or more key/value pairs.
|
A single configmap may package one or more key/value pairs.
|
||||||
@@ -38,10 +38,9 @@ var (
|
|||||||
|
|
||||||
When creating a configmap based on a directory, each file whose basename is a valid key in the directory will be
|
When creating a configmap based on a directory, each file whose basename is a valid key in the directory will be
|
||||||
packaged into the configmap. Any directory entries except regular files are ignored (e.g. subdirectories,
|
packaged into the configmap. Any directory entries except regular files are ignored (e.g. subdirectories,
|
||||||
symlinks, devices, pipes, etc).
|
symlinks, devices, pipes, etc).`)
|
||||||
`)
|
|
||||||
|
|
||||||
configMapExample = dedent.Dedent(`
|
configMapExample = templates.Examples(`
|
||||||
# Create a new configmap named my-config with keys for each file in folder bar
|
# Create a new configmap named my-config with keys for each file in folder bar
|
||||||
kubectl create configmap my-config --from-file=path/to/bar
|
kubectl create configmap my-config --from-file=path/to/bar
|
||||||
|
|
||||||
|
@@ -20,18 +20,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
deploymentLong = dedent.Dedent(`
|
deploymentLong = templates.LongDesc(`
|
||||||
Create a deployment with the specified name.`)
|
Create a deployment with the specified name.`)
|
||||||
|
|
||||||
deploymentExample = dedent.Dedent(`
|
deploymentExample = templates.Examples(`
|
||||||
# Create a new deployment named my-dep that runs the busybox image.
|
# Create a new deployment named my-dep that runs the busybox image.
|
||||||
kubectl create deployment my-dep --image=busybox`)
|
kubectl create deployment my-dep --image=busybox`)
|
||||||
)
|
)
|
||||||
|
@@ -20,18 +20,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
namespaceLong = dedent.Dedent(`
|
namespaceLong = templates.LongDesc(`
|
||||||
Create a namespace with the specified name.`)
|
Create a namespace with the specified name.`)
|
||||||
|
|
||||||
namespaceExample = dedent.Dedent(`
|
namespaceExample = templates.Examples(`
|
||||||
# Create a new namespace named my-namespace
|
# Create a new namespace named my-namespace
|
||||||
kubectl create namespace my-namespace`)
|
kubectl create namespace my-namespace`)
|
||||||
)
|
)
|
||||||
|
@@ -20,22 +20,22 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
quotaLong = dedent.Dedent(`
|
quotaLong = templates.LongDesc(`
|
||||||
Create a resourcequota with the specified name, hard limits and optional scopes`)
|
Create a resourcequota with the specified name, hard limits and optional scopes`)
|
||||||
|
|
||||||
quotaExample = dedent.Dedent(`
|
quotaExample = templates.Examples(`
|
||||||
// Create a new resourcequota named my-quota
|
# Create a new resourcequota named my-quota
|
||||||
$ kubectl create quota my-quota --hard=cpu=1,memory=1G,pods=2,services=3,replicationcontrollers=2,resourcequotas=1,secrets=5,persistentvolumeclaims=10
|
$ kubectl create quota my-quota --hard=cpu=1,memory=1G,pods=2,services=3,replicationcontrollers=2,resourcequotas=1,secrets=5,persistentvolumeclaims=10
|
||||||
|
|
||||||
// Create a new resourcequota named best-effort
|
# Create a new resourcequota named best-effort
|
||||||
$ kubectl create quota best-effort --hard=pods=100 --scopes=BestEffort`)
|
$ kubectl create quota best-effort --hard=pods=100 --scopes=BestEffort`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -20,10 +20,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ func NewCmdCreateSecret(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
secretLong = dedent.Dedent(`
|
secretLong = templates.LongDesc(`
|
||||||
Create a secret based on a file, directory, or specified literal value.
|
Create a secret based on a file, directory, or specified literal value.
|
||||||
|
|
||||||
A single secret may package one or more key/value pairs.
|
A single secret may package one or more key/value pairs.
|
||||||
@@ -55,10 +55,9 @@ var (
|
|||||||
|
|
||||||
When creating a secret based on a directory, each file whose basename is a valid key in the directory will be
|
When creating a secret based on a directory, each file whose basename is a valid key in the directory will be
|
||||||
packaged into the secret. Any directory entries except regular files are ignored (e.g. subdirectories,
|
packaged into the secret. Any directory entries except regular files are ignored (e.g. subdirectories,
|
||||||
symlinks, devices, pipes, etc).
|
symlinks, devices, pipes, etc).`)
|
||||||
`)
|
|
||||||
|
|
||||||
secretExample = dedent.Dedent(`
|
secretExample = templates.Examples(`
|
||||||
# Create a new secret named my-secret with keys for each file in folder bar
|
# Create a new secret named my-secret with keys for each file in folder bar
|
||||||
kubectl create secret generic my-secret --from-file=path/to/bar
|
kubectl create secret generic my-secret --from-file=path/to/bar
|
||||||
|
|
||||||
@@ -118,13 +117,15 @@ func CreateSecretGeneric(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
secretForDockerRegistryLong = dedent.Dedent(`
|
secretForDockerRegistryLong = templates.LongDesc(`
|
||||||
Create a new secret for use with Docker registries.
|
Create a new secret for use with Docker registries.
|
||||||
|
|
||||||
Dockercfg secrets are used to authenticate against Docker registries.
|
Dockercfg secrets are used to authenticate against Docker registries.
|
||||||
|
|
||||||
When using the Docker command line to push images, you can authenticate to a given registry by running
|
When using the Docker command line to push images, you can authenticate to a given registry by running
|
||||||
'docker login DOCKER_REGISTRY_SERVER --username=DOCKER_USER --password=DOCKER_PASSWORD --email=DOCKER_EMAIL'.
|
|
||||||
|
$ docker login DOCKER_REGISTRY_SERVER --username=DOCKER_USER --password=DOCKER_PASSWORD --email=DOCKER_EMAIL'.
|
||||||
|
|
||||||
That produces a ~/.dockercfg file that is used by subsequent 'docker push' and 'docker pull' commands to
|
That produces a ~/.dockercfg file that is used by subsequent 'docker push' and 'docker pull' commands to
|
||||||
authenticate to the registry.
|
authenticate to the registry.
|
||||||
|
|
||||||
@@ -132,7 +133,7 @@ var (
|
|||||||
nodes to pull images on your behalf, they have to have the credentials. You can provide this information
|
nodes to pull images on your behalf, they have to have the credentials. You can provide this information
|
||||||
by creating a dockercfg secret and attaching it to your service account.`)
|
by creating a dockercfg secret and attaching it to your service account.`)
|
||||||
|
|
||||||
secretForDockerRegistryExample = dedent.Dedent(`
|
secretForDockerRegistryExample = templates.Examples(`
|
||||||
# If you don't already have a .dockercfg file, you can create a dockercfg secret directly by using:
|
# If you don't already have a .dockercfg file, you can create a dockercfg secret directly by using:
|
||||||
kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL`)
|
kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL`)
|
||||||
)
|
)
|
||||||
@@ -198,12 +199,12 @@ func CreateSecretDockerRegistry(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
secretForTLSLong = dedent.Dedent(`
|
secretForTLSLong = templates.LongDesc(`
|
||||||
Create a TLS secret from the given public/private key pair.
|
Create a TLS secret from the given public/private key pair.
|
||||||
|
|
||||||
The public/private key pair must exist before hand. The public key certificate must be .PEM encoded and match the given private key.`)
|
The public/private key pair must exist before hand. The public key certificate must be .PEM encoded and match the given private key.`)
|
||||||
|
|
||||||
secretForTLSExample = dedent.Dedent(`
|
secretForTLSExample = templates.Examples(`
|
||||||
# Create a new TLS secret named tls-secret with the given key pair:
|
# Create a new TLS secret named tls-secret with the given key pair:
|
||||||
kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key`)
|
kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key`)
|
||||||
)
|
)
|
||||||
|
@@ -20,11 +20,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -47,10 +47,10 @@ func NewCmdCreateService(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
serviceClusterIPLong = dedent.Dedent(`
|
serviceClusterIPLong = templates.LongDesc(`
|
||||||
Create a clusterIP service with the specified name.`)
|
Create a clusterIP service with the specified name.`)
|
||||||
|
|
||||||
serviceClusterIPExample = dedent.Dedent(`
|
serviceClusterIPExample = templates.Examples(`
|
||||||
# Create a new clusterIP service named my-cs
|
# Create a new clusterIP service named my-cs
|
||||||
kubectl create service clusterip my-cs --tcp=5678:8080
|
kubectl create service clusterip my-cs --tcp=5678:8080
|
||||||
|
|
||||||
@@ -110,10 +110,10 @@ func CreateServiceClusterIP(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Comm
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
serviceNodePortLong = dedent.Dedent(`
|
serviceNodePortLong = templates.LongDesc(`
|
||||||
Create a nodeport service with the specified name.`)
|
Create a nodeport service with the specified name.`)
|
||||||
|
|
||||||
serviceNodePortExample = dedent.Dedent(`
|
serviceNodePortExample = templates.Examples(`
|
||||||
# Create a new nodeport service named my-ns
|
# Create a new nodeport service named my-ns
|
||||||
kubectl create service nodeport my-ns --tcp=5678:8080`)
|
kubectl create service nodeport my-ns --tcp=5678:8080`)
|
||||||
)
|
)
|
||||||
@@ -167,10 +167,10 @@ func CreateServiceNodePort(f cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Comma
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
serviceLoadBalancerLong = dedent.Dedent(`
|
serviceLoadBalancerLong = templates.LongDesc(`
|
||||||
Create a LoadBalancer service with the specified name.`)
|
Create a LoadBalancer service with the specified name.`)
|
||||||
|
|
||||||
serviceLoadBalancerExample = dedent.Dedent(`
|
serviceLoadBalancerExample = templates.Examples(`
|
||||||
# Create a new nodeport service named my-lbs
|
# Create a new nodeport service named my-lbs
|
||||||
kubectl create service loadbalancer my-lbs --tcp=5678:8080`)
|
kubectl create service loadbalancer my-lbs --tcp=5678:8080`)
|
||||||
)
|
)
|
||||||
|
@@ -20,18 +20,18 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
serviceAccountLong = dedent.Dedent(`
|
serviceAccountLong = templates.LongDesc(`
|
||||||
Create a service account with the specified name.`)
|
Create a service account with the specified name.`)
|
||||||
|
|
||||||
serviceAccountExample = dedent.Dedent(`
|
serviceAccountExample = templates.Examples(`
|
||||||
# Create a new service account named my-service-account
|
# Create a new service account named my-service-account
|
||||||
$ kubectl create serviceaccount my-service-account`)
|
$ kubectl create serviceaccount my-service-account`)
|
||||||
)
|
)
|
||||||
|
@@ -21,19 +21,19 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/errors"
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
delete_long = dedent.Dedent(`
|
delete_long = templates.LongDesc(`
|
||||||
Delete resources by filenames, stdin, resources and names, or by resources and label selector.
|
Delete resources by filenames, stdin, resources and names, or by resources and label selector.
|
||||||
|
|
||||||
JSON and YAML formats are accepted.
|
JSON and YAML formats are accepted.
|
||||||
@@ -43,7 +43,8 @@ var (
|
|||||||
Note that the delete command does NOT do resource version checks, so if someone
|
Note that the delete command does NOT do resource version checks, so if someone
|
||||||
submits an update to a resource right when you submit a delete, their update
|
submits an update to a resource right when you submit a delete, their update
|
||||||
will be lost along with the rest of the resource.`)
|
will be lost along with the rest of the resource.`)
|
||||||
delete_example = dedent.Dedent(`
|
|
||||||
|
delete_example = templates.Examples(`
|
||||||
# Delete a pod using the type and name specified in pod.json.
|
# Delete a pod using the type and name specified in pod.json.
|
||||||
kubectl delete -f ./pod.json
|
kubectl delete -f ./pod.json
|
||||||
|
|
||||||
|
@@ -21,12 +21,12 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
apierrors "k8s.io/kubernetes/pkg/api/errors"
|
apierrors "k8s.io/kubernetes/pkg/api/errors"
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -34,7 +34,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
describe_long = dedent.Dedent(`
|
describe_long = templates.LongDesc(`
|
||||||
Show details of a specific resource or group of resources.
|
Show details of a specific resource or group of resources.
|
||||||
This command joins many API calls together to form a detailed description of a
|
This command joins many API calls together to form a detailed description of a
|
||||||
given resource or group of resources.
|
given resource or group of resources.
|
||||||
@@ -44,9 +44,9 @@ var (
|
|||||||
will first check for an exact match on TYPE and NAME_PREFIX. If no such resource
|
will first check for an exact match on TYPE and NAME_PREFIX. If no such resource
|
||||||
exists, it will output details for every resource that has a name prefixed with NAME_PREFIX.
|
exists, it will output details for every resource that has a name prefixed with NAME_PREFIX.
|
||||||
|
|
||||||
`) + valid_resources
|
` + valid_resources)
|
||||||
|
|
||||||
describe_example = dedent.Dedent(`
|
describe_example = templates.Examples(`
|
||||||
# Describe a node
|
# Describe a node
|
||||||
kubectl describe nodes kubernetes-node-emt8.c.myproject.internal
|
kubectl describe nodes kubernetes-node-emt8.c.myproject.internal
|
||||||
|
|
||||||
|
@@ -23,7 +23,6 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@@ -31,6 +30,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
"k8s.io/kubernetes/pkg/client/restclient"
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
"k8s.io/kubernetes/pkg/fields"
|
"k8s.io/kubernetes/pkg/fields"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/types"
|
"k8s.io/kubernetes/pkg/kubelet/types"
|
||||||
@@ -71,13 +71,12 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cordon_long = dedent.Dedent(`
|
cordon_long = templates.LongDesc(`
|
||||||
Mark node as unschedulable.
|
Mark node as unschedulable.`)
|
||||||
`)
|
|
||||||
cordon_example = dedent.Dedent(`
|
cordon_example = templates.Examples(`
|
||||||
# Mark node "foo" as unschedulable.
|
# Mark node "foo" as unschedulable.
|
||||||
kubectl cordon foo
|
kubectl cordon foo`)
|
||||||
`)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdCordon(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdCordon(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
@@ -97,13 +96,12 @@ func NewCmdCordon(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
uncordon_long = dedent.Dedent(`
|
uncordon_long = templates.LongDesc(`
|
||||||
Mark node as schedulable.
|
Mark node as schedulable.`)
|
||||||
`)
|
|
||||||
uncordon_example = dedent.Dedent(`
|
uncordon_example = templates.Examples(`
|
||||||
# Mark node "foo" as schedulable.
|
# Mark node "foo" as schedulable.
|
||||||
$ kubectl uncordon foo
|
$ kubectl uncordon foo`)
|
||||||
`)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdUncordon(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdUncordon(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
@@ -123,7 +121,7 @@ func NewCmdUncordon(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
drain_long = dedent.Dedent(`
|
drain_long = templates.LongDesc(`
|
||||||
Drain node in preparation for maintenance.
|
Drain node in preparation for maintenance.
|
||||||
|
|
||||||
The given node will be marked unschedulable to prevent new pods from arriving.
|
The given node will be marked unschedulable to prevent new pods from arriving.
|
||||||
@@ -139,16 +137,14 @@ var (
|
|||||||
When you are ready to put the node back into service, use kubectl uncordon, which
|
When you are ready to put the node back into service, use kubectl uncordon, which
|
||||||
will make the node schedulable again.
|
will make the node schedulable again.
|
||||||
|
|
||||||

|
`)
|
||||||
`)
|
|
||||||
|
|
||||||
drain_example = dedent.Dedent(`
|
drain_example = templates.Examples(`
|
||||||
# Drain node "foo", even if there are pods not managed by a ReplicationController, ReplicaSet, Job, or DaemonSet on it.
|
# Drain node "foo", even if there are pods not managed by a ReplicationController, ReplicaSet, Job, or DaemonSet on it.
|
||||||
$ kubectl drain foo --force
|
$ kubectl drain foo --force
|
||||||
|
|
||||||
# As above, but abort if there are pods not managed by a ReplicationController, ReplicaSet, Job, or DaemonSet, and use a grace period of 15 minutes.
|
# As above, but abort if there are pods not managed by a ReplicationController, ReplicaSet, Job, or DaemonSet, and use a grace period of 15 minutes.
|
||||||
$ kubectl drain foo --grace-period=900
|
$ kubectl drain foo --grace-period=900`)
|
||||||
`)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdDrain(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdDrain(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
|
@@ -27,12 +27,12 @@ import (
|
|||||||
gruntime "runtime"
|
gruntime "runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/errors"
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
@@ -47,7 +47,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
editLong = dedent.Dedent(`
|
editLong = templates.LongDesc(`
|
||||||
Edit a resource from the default editor.
|
Edit a resource from the default editor.
|
||||||
|
|
||||||
The edit command allows you to directly edit any API resource you can retrieve via the
|
The edit command allows you to directly edit any API resource you can retrieve via the
|
||||||
@@ -68,7 +68,7 @@ var (
|
|||||||
to apply your changes to the newer version of the resource, or update your temporary
|
to apply your changes to the newer version of the resource, or update your temporary
|
||||||
saved copy to include the latest resource version.`)
|
saved copy to include the latest resource version.`)
|
||||||
|
|
||||||
editExample = dedent.Dedent(`
|
editExample = templates.Examples(`
|
||||||
# Edit the service named 'docker-registry':
|
# Edit the service named 'docker-registry':
|
||||||
kubectl edit svc/docker-registry
|
kubectl edit svc/docker-registry
|
||||||
|
|
||||||
|
@@ -22,13 +22,13 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
dockerterm "github.com/docker/docker/pkg/term"
|
dockerterm "github.com/docker/docker/pkg/term"
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/client/restclient"
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand"
|
remotecommandserver "k8s.io/kubernetes/pkg/kubelet/server/remotecommand"
|
||||||
"k8s.io/kubernetes/pkg/util/interrupt"
|
"k8s.io/kubernetes/pkg/util/interrupt"
|
||||||
@@ -36,7 +36,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
exec_example = dedent.Dedent(`
|
exec_example = templates.Examples(`
|
||||||
# Get output from running 'date' from pod 123456-7890, using the first container by default
|
# Get output from running 'date' from pod 123456-7890, using the first container by default
|
||||||
kubectl exec 123456-7890 date
|
kubectl exec 123456-7890 date
|
||||||
|
|
||||||
|
@@ -20,27 +20,27 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
explainExamples = dedent.Dedent(`
|
explainLong = templates.LongDesc(`
|
||||||
|
Documentation of resources.
|
||||||
|
|
||||||
|
` + valid_resources)
|
||||||
|
|
||||||
|
explainExamples = templates.Examples(`
|
||||||
# Get the documentation of the resource and its fields
|
# Get the documentation of the resource and its fields
|
||||||
kubectl explain pods
|
kubectl explain pods
|
||||||
|
|
||||||
# Get the documentation of a specific field of a resource
|
# Get the documentation of a specific field of a resource
|
||||||
kubectl explain pods.spec.containers`)
|
kubectl explain pods.spec.containers`)
|
||||||
|
|
||||||
explainLong = dedent.Dedent(`
|
|
||||||
Documentation of resources.
|
|
||||||
|
|
||||||
`) + valid_resources
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCmdExplain returns a cobra command for swagger docs
|
// NewCmdExplain returns a cobra command for swagger docs
|
||||||
|
@@ -22,10 +22,10 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -33,12 +33,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
expose_resources = dedent.Dedent(`
|
expose_resources = `pod (po), service (svc), replicationcontroller (rc), deployment (deploy), replicaset (rs)`
|
||||||
pod (po), service (svc), replicationcontroller (rc),
|
|
||||||
deployment (deploy), replicaset (rs)
|
|
||||||
`)
|
|
||||||
|
|
||||||
expose_long = dedent.Dedent(`
|
expose_long = templates.LongDesc(`
|
||||||
Expose a resource as a new Kubernetes service.
|
Expose a resource as a new Kubernetes service.
|
||||||
|
|
||||||
Looks up a deployment, service, replica set, replication controller or pod by name and uses the selector
|
Looks up a deployment, service, replica set, replication controller or pod by name and uses the selector
|
||||||
@@ -48,9 +45,11 @@ var (
|
|||||||
--port and the exposed resource has multiple ports, all will be re-used by the new service. Also if no
|
--port and the exposed resource has multiple ports, all will be re-used by the new service. Also if no
|
||||||
labels are specified, the new service will re-use the labels from the resource it exposes.
|
labels are specified, the new service will re-use the labels from the resource it exposes.
|
||||||
|
|
||||||
Possible resources include (case insensitive): `) + expose_resources
|
Possible resources include (case insensitive):
|
||||||
|
|
||||||
expose_example = dedent.Dedent(`
|
` + expose_resources)
|
||||||
|
|
||||||
|
expose_example = templates.Examples(`
|
||||||
# Create a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000.
|
# Create a service for a replicated nginx, which serves on port 80 and connects to the containers on port 8000.
|
||||||
kubectl expose rc nginx --port=80 --target-port=8000
|
kubectl expose rc nginx --port=80 --target-port=8000
|
||||||
|
|
||||||
|
@@ -20,12 +20,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -43,17 +43,18 @@ type GetOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
get_long = dedent.Dedent(`
|
get_long = templates.LongDesc(`
|
||||||
Display one or many resources.
|
Display one or many resources.
|
||||||
|
|
||||||
`) + valid_resources + dedent.Dedent(`
|
` + valid_resources + `
|
||||||
|
|
||||||
This command will hide resources that have completed. For instance, pods that are in the Succeeded or Failed phases.
|
This command will hide resources that have completed. For instance, pods that are in the Succeeded or Failed phases.
|
||||||
You can see the full results for any resource by providing the '--show-all' flag.
|
You can see the full results for any resource by providing the '--show-all' flag.
|
||||||
|
|
||||||
By specifying the output as 'template' and providing a Go template as the value
|
By specifying the output as 'template' and providing a Go template as the value
|
||||||
of the --template flag, you can filter the attributes of the fetched resource(s).`)
|
of the --template flag, you can filter the attributes of the fetched resource(s).`)
|
||||||
get_example = dedent.Dedent(`
|
|
||||||
|
get_example = templates.Examples(`
|
||||||
# List all pods in ps output format.
|
# List all pods in ps output format.
|
||||||
kubectl get pods
|
kubectl get pods
|
||||||
|
|
||||||
|
@@ -22,11 +22,13 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const help_long = `Help provides help for any command in the application.
|
var help_long = templates.LongDesc(`
|
||||||
Simply type kubectl help [path to command] for full details.`
|
Help provides help for any command in the application.
|
||||||
|
Simply type kubectl help [path to command] for full details.`)
|
||||||
|
|
||||||
func NewCmdHelp(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdHelp(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
@@ -24,11 +24,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -61,13 +61,14 @@ type LabelOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
label_long = dedent.Dedent(`
|
label_long = templates.LongDesc(`
|
||||||
Update the labels on a resource.
|
Update the labels on a resource.
|
||||||
|
|
||||||
A label must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters.
|
* A label must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters.
|
||||||
If --overwrite is true, then existing labels can be overwritten, otherwise attempting to overwrite a label will result in an error.
|
* If --overwrite is true, then existing labels can be overwritten, otherwise attempting to overwrite a label will result in an error.
|
||||||
If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used.`)
|
* If --resource-version is specified, then updates will use this resource version, otherwise the existing resource-version will be used.`)
|
||||||
label_example = dedent.Dedent(`
|
|
||||||
|
label_example = templates.Examples(`
|
||||||
# Update pod 'foo' with the label 'unhealthy' and the value 'true'.
|
# Update pod 'foo' with the label 'unhealthy' and the value 'true'.
|
||||||
kubectl label pods foo unhealthy=true
|
kubectl label pods foo unhealthy=true
|
||||||
|
|
||||||
|
@@ -23,20 +23,20 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
"k8s.io/kubernetes/pkg/client/restclient"
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
logs_example = dedent.Dedent(`
|
logs_example = templates.Examples(`
|
||||||
# Return snapshot logs from pod nginx with only one container
|
# Return snapshot logs from pod nginx with only one container
|
||||||
kubectl logs nginx
|
kubectl logs nginx
|
||||||
|
|
||||||
|
@@ -22,11 +22,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/evanphx/json-patch"
|
"github.com/evanphx/json-patch"
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -48,14 +48,14 @@ type PatchOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
patch_long = dedent.Dedent(`
|
patch_long = templates.LongDesc(`
|
||||||
Update field(s) of a resource using strategic merge patch
|
Update field(s) of a resource using strategic merge patch
|
||||||
|
|
||||||
JSON and YAML formats are accepted.
|
JSON and YAML formats are accepted.
|
||||||
|
|
||||||
Please refer to the models in https://htmlpreview.github.io/?https://github.com/kubernetes/kubernetes/blob/HEAD/docs/api-reference/v1/definitions.html to find if a field is mutable.`)
|
Please refer to the models in https://htmlpreview.github.io/?https://github.com/kubernetes/kubernetes/blob/HEAD/docs/api-reference/v1/definitions.html to find if a field is mutable.`)
|
||||||
patch_example = dedent.Dedent(`
|
|
||||||
|
|
||||||
|
patch_example = templates.Examples(`
|
||||||
# Partially update a node using strategic merge patch
|
# Partially update a node using strategic merge patch
|
||||||
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'
|
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'
|
||||||
|
|
||||||
|
@@ -23,7 +23,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@@ -31,6 +30,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/client/restclient"
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/portforward"
|
"k8s.io/kubernetes/pkg/client/unversioned/portforward"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
"k8s.io/kubernetes/pkg/client/unversioned/remotecommand"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ type PortForwardOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
portforward_example = dedent.Dedent(`
|
portforward_example = templates.Examples(`
|
||||||
# Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod
|
# Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod
|
||||||
kubectl port-forward mypod 5000 6000
|
kubectl port-forward mypod 5000 6000
|
||||||
|
|
||||||
|
@@ -24,15 +24,32 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
default_port = 8001
|
default_port = 8001
|
||||||
proxy_example = dedent.Dedent(`
|
proxy_long = templates.LongDesc(`
|
||||||
|
To proxy all of the kubernetes api and nothing else, use:
|
||||||
|
|
||||||
|
$ kubectl proxy --api-prefix=/
|
||||||
|
|
||||||
|
To proxy only part of the kubernetes api and also some static files:
|
||||||
|
|
||||||
|
$ kubectl proxy --www=/my/files --www-prefix=/static/ --api-prefix=/api/
|
||||||
|
|
||||||
|
The above lets you 'curl localhost:8001/api/v1/pods'.
|
||||||
|
|
||||||
|
To proxy the entire kubernetes api at a different root, use:
|
||||||
|
|
||||||
|
$ kubectl proxy --api-prefix=/custom/
|
||||||
|
|
||||||
|
The above lets you 'curl localhost:8001/custom/api/v1/pods'`)
|
||||||
|
|
||||||
|
proxy_example = templates.Examples(`
|
||||||
# Run a proxy to kubernetes apiserver on port 8011, serving static content from ./local/www/
|
# Run a proxy to kubernetes apiserver on port 8011, serving static content from ./local/www/
|
||||||
kubectl proxy --port=8011 --www=./local/www/
|
kubectl proxy --port=8011 --www=./local/www/
|
||||||
|
|
||||||
@@ -49,23 +66,7 @@ func NewCmdProxy(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]",
|
Use: "proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]",
|
||||||
Short: "Run a proxy to the Kubernetes API server",
|
Short: "Run a proxy to the Kubernetes API server",
|
||||||
Long: dedent.Dedent(`
|
Long: proxy_long,
|
||||||
To proxy all of the kubernetes api and nothing else, use:
|
|
||||||
|
|
||||||
kubectl proxy --api-prefix=/
|
|
||||||
|
|
||||||
To proxy only part of the kubernetes api and also some static files:
|
|
||||||
|
|
||||||
kubectl proxy --www=/my/files --www-prefix=/static/ --api-prefix=/api/
|
|
||||||
|
|
||||||
The above lets you 'curl localhost:8001/api/v1/pods'.
|
|
||||||
|
|
||||||
To proxy the entire kubernetes api at a different root, use:
|
|
||||||
|
|
||||||
kubectl proxy --api-prefix=/custom/
|
|
||||||
|
|
||||||
The above lets you 'curl localhost:8001/custom/api/v1/pods'
|
|
||||||
`),
|
|
||||||
Example: proxy_example,
|
Example: proxy_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
err := RunProxy(f, out, cmd)
|
err := RunProxy(f, out, cmd)
|
||||||
|
@@ -23,12 +23,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"k8s.io/kubernetes/pkg/api/errors"
|
"k8s.io/kubernetes/pkg/api/errors"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -36,15 +36,17 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
replace_long = dedent.Dedent(`
|
replace_long = templates.LongDesc(`
|
||||||
Replace a resource by filename or stdin.
|
Replace a resource by filename or stdin.
|
||||||
|
|
||||||
JSON and YAML formats are accepted. If replacing an existing resource, the
|
JSON and YAML formats are accepted. If replacing an existing resource, the
|
||||||
complete resource spec must be provided. This can be obtained by
|
complete resource spec must be provided. This can be obtained by
|
||||||
|
|
||||||
$ kubectl get TYPE NAME -o yaml
|
$ kubectl get TYPE NAME -o yaml
|
||||||
|
|
||||||
Please refer to the models in https://htmlpreview.github.io/?https://github.com/kubernetes/kubernetes/blob/HEAD/docs/api-reference/v1/definitions.html to find if a field is mutable.`)
|
Please refer to the models in https://htmlpreview.github.io/?https://github.com/kubernetes/kubernetes/blob/HEAD/docs/api-reference/v1/definitions.html to find if a field is mutable.`)
|
||||||
replace_example = dedent.Dedent(`
|
|
||||||
|
replace_example = templates.Examples(`
|
||||||
# Replace a pod using the data in pod.json.
|
# Replace a pod using the data in pod.json.
|
||||||
kubectl replace -f ./pod.json
|
kubectl replace -f ./pod.json
|
||||||
|
|
||||||
|
@@ -25,7 +25,6 @@ import (
|
|||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
@@ -33,6 +32,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/api/v1"
|
"k8s.io/kubernetes/pkg/api/v1"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||||
@@ -40,16 +40,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
rollingUpdate_long = dedent.Dedent(`
|
rollingUpdate_long = templates.LongDesc(`
|
||||||
Perform a rolling update of the given ReplicationController.
|
Perform a rolling update of the given ReplicationController.
|
||||||
|
|
||||||
Replaces the specified replication controller with a new replication controller by updating one pod at a time to use the
|
Replaces the specified replication controller with a new replication controller by updating one pod at a time to use the
|
||||||
new PodTemplate. The new-controller.json must specify the same namespace as the
|
new PodTemplate. The new-controller.json must specify the same namespace as the
|
||||||
existing replication controller and overwrite at least one (common) label in its replicaSelector.
|
existing replication controller and overwrite at least one (common) label in its replicaSelector.
|
||||||
|
|
||||||

|
`)
|
||||||
`)
|
|
||||||
rollingUpdate_example = dedent.Dedent(`
|
rollingUpdate_example = templates.Examples(`
|
||||||
# Update pods of frontend-v1 using new replication controller data in frontend-v2.json.
|
# Update pods of frontend-v1 using new replication controller data in frontend-v2.json.
|
||||||
kubectl rolling-update frontend-v1 -f frontend-v2.json
|
kubectl rolling-update frontend-v1 -f frontend-v2.json
|
||||||
|
|
||||||
@@ -64,8 +64,7 @@ var (
|
|||||||
kubectl rolling-update frontend --image=image:v2
|
kubectl rolling-update frontend --image=image:v2
|
||||||
|
|
||||||
# Abort and reverse an existing rollout in progress (from frontend-v1 to frontend-v2).
|
# Abort and reverse an existing rollout in progress (from frontend-v1 to frontend-v2).
|
||||||
kubectl rolling-update frontend-v1 frontend-v2 --rollback
|
kubectl rolling-update frontend-v1 frontend-v2 --rollback`)
|
||||||
`)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@@ -21,15 +21,18 @@ import (
|
|||||||
|
|
||||||
"github.com/renstrom/dedent"
|
"github.com/renstrom/dedent"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
rollout_long = dedent.Dedent(`
|
rollout_long = templates.LongDesc(`
|
||||||
Manage a deployment using subcommands like "kubectl rollout undo deployment/abc"`)
|
Manage a deployment using subcommands like "kubectl rollout undo deployment/abc"`)
|
||||||
rollout_example = dedent.Dedent(`
|
|
||||||
|
rollout_example = templates.Examples(`
|
||||||
# Rollback to the previous deployment
|
# Rollback to the previous deployment
|
||||||
kubectl rollout undo deployment/abc`)
|
kubectl rollout undo deployment/abc`)
|
||||||
|
|
||||||
rollout_valid_resources = dedent.Dedent(`
|
rollout_valid_resources = dedent.Dedent(`
|
||||||
Valid resource types include:
|
Valid resource types include:
|
||||||
* deployments
|
* deployments
|
||||||
|
@@ -20,8 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
|
|
||||||
@@ -29,9 +29,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
history_long = dedent.Dedent(`
|
history_long = templates.LongDesc(`
|
||||||
View previous rollout revisions and configurations.`)
|
View previous rollout revisions and configurations.`)
|
||||||
history_example = dedent.Dedent(`
|
|
||||||
|
history_example = templates.Examples(`
|
||||||
# View the rollout history of a deployment
|
# View the rollout history of a deployment
|
||||||
kubectl rollout history deployment/abc
|
kubectl rollout history deployment/abc
|
||||||
|
|
||||||
|
@@ -19,11 +19,11 @@ package rollout
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -44,14 +44,14 @@ type PauseConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
pause_long = dedent.Dedent(`
|
pause_long = templates.LongDesc(`
|
||||||
Mark the provided resource as paused
|
Mark the provided resource as paused
|
||||||
|
|
||||||
Paused resources will not be reconciled by a controller.
|
Paused resources will not be reconciled by a controller.
|
||||||
Use \"kubectl rollout resume\" to resume a paused resource.
|
Use \"kubectl rollout resume\" to resume a paused resource.
|
||||||
Currently only deployments support being paused.`)
|
Currently only deployments support being paused.`)
|
||||||
|
|
||||||
pause_example = dedent.Dedent(`
|
pause_example = templates.Examples(`
|
||||||
# Mark the nginx deployment as paused. Any current state of
|
# Mark the nginx deployment as paused. Any current state of
|
||||||
# the deployment will continue its function, new updates to the deployment will not
|
# the deployment will continue its function, new updates to the deployment will not
|
||||||
# have an effect as long as the deployment is paused.
|
# have an effect as long as the deployment is paused.
|
||||||
|
@@ -19,11 +19,11 @@ package rollout
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -44,14 +44,14 @@ type ResumeConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
resume_long = dedent.Dedent(`
|
resume_long = templates.LongDesc(`
|
||||||
Resume a paused resource
|
Resume a paused resource
|
||||||
|
|
||||||
Paused resources will not be reconciled by a controller. By resuming a
|
Paused resources will not be reconciled by a controller. By resuming a
|
||||||
resource, we allow it to be reconciled again.
|
resource, we allow it to be reconciled again.
|
||||||
Currently only deployments support being resumed.`)
|
Currently only deployments support being resumed.`)
|
||||||
|
|
||||||
resume_example = dedent.Dedent(`
|
resume_example = templates.Examples(`
|
||||||
# Resume an already paused deployment
|
# Resume an already paused deployment
|
||||||
kubectl rollout resume deployment/nginx`)
|
kubectl rollout resume deployment/nginx`)
|
||||||
)
|
)
|
||||||
|
@@ -20,8 +20,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/util/interrupt"
|
"k8s.io/kubernetes/pkg/util/interrupt"
|
||||||
@@ -31,7 +31,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
status_long = dedent.Dedent(`
|
status_long = templates.LongDesc(`
|
||||||
Show the status of the rollout.
|
Show the status of the rollout.
|
||||||
|
|
||||||
By default 'rollout status' will watch the status of the latest rollout
|
By default 'rollout status' will watch the status of the latest rollout
|
||||||
@@ -40,7 +40,8 @@ var (
|
|||||||
'rollout status' will continue watching the latest revision. If you want to
|
'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,
|
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.`)
|
use --revision=N where N is the revision you need to watch for.`)
|
||||||
status_example = dedent.Dedent(`
|
|
||||||
|
status_example = templates.Examples(`
|
||||||
# Watch the rollout status of a deployment
|
# Watch the rollout status of a deployment
|
||||||
kubectl rollout status deployment/nginx`)
|
kubectl rollout status deployment/nginx`)
|
||||||
)
|
)
|
||||||
|
@@ -19,9 +19,9 @@ package rollout
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -46,9 +46,10 @@ type UndoOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
undo_long = dedent.Dedent(`
|
undo_long = templates.LongDesc(`
|
||||||
Rollback to a previous rollout.`)
|
Rollback to a previous rollout.`)
|
||||||
undo_example = dedent.Dedent(`
|
|
||||||
|
undo_example = templates.Examples(`
|
||||||
# Rollback to the previous deployment
|
# Rollback to the previous deployment
|
||||||
kubectl rollout undo deployment/abc
|
kubectl rollout undo deployment/abc
|
||||||
|
|
||||||
|
@@ -22,7 +22,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
@@ -36,6 +35,7 @@ import (
|
|||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
||||||
conditions "k8s.io/kubernetes/pkg/client/unversioned"
|
conditions "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -45,10 +45,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
run_long = dedent.Dedent(`
|
run_long = templates.LongDesc(`
|
||||||
Create and run a particular image, possibly replicated.
|
Create and run a particular image, possibly replicated.
|
||||||
|
|
||||||
Creates a deployment or job to manage the created container(s).`)
|
Creates a deployment or job to manage the created container(s).`)
|
||||||
run_example = dedent.Dedent(`
|
|
||||||
|
run_example = templates.Examples(`
|
||||||
# Start a single instance of nginx.
|
# Start a single instance of nginx.
|
||||||
kubectl run nginx --image=nginx
|
kubectl run nginx --image=nginx
|
||||||
|
|
||||||
|
@@ -21,24 +21,26 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scale_long = dedent.Dedent(`
|
scale_long = templates.LongDesc(`
|
||||||
Set a new size for a Deployment, ReplicaSet, Replication Controller, or Job.
|
Set a new size for a Deployment, ReplicaSet, Replication Controller, or Job.
|
||||||
|
|
||||||
Scale also allows users to specify one or more preconditions for the scale action.
|
Scale also allows users to specify one or more preconditions for the scale action.
|
||||||
|
|
||||||
If --current-replicas or --resource-version is specified, it is validated before the
|
If --current-replicas or --resource-version is specified, it is validated before the
|
||||||
scale is attempted, and it is guaranteed that the precondition holds true when the
|
scale is attempted, and it is guaranteed that the precondition holds true when the
|
||||||
scale is sent to the server.`)
|
scale is sent to the server.`)
|
||||||
scale_example = dedent.Dedent(`
|
|
||||||
|
scale_example = templates.Examples(`
|
||||||
# Scale a replicaset named 'foo' to 3.
|
# Scale a replicaset named 'foo' to 3.
|
||||||
kubectl scale --replicas=3 rs/foo
|
kubectl scale --replicas=3 rs/foo
|
||||||
|
|
||||||
|
@@ -19,17 +19,16 @@ package set
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
set_long = dedent.Dedent(`
|
set_long = templates.LongDesc(`
|
||||||
Configure application resources
|
Configure application resources
|
||||||
|
|
||||||
These commands help you make changes to existing application resources.`)
|
These commands help you make changes to existing application resources.`)
|
||||||
set_example = dedent.Dedent(``)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdSet(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
|
func NewCmdSet(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
|
||||||
@@ -37,7 +36,6 @@ func NewCmdSet(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
|
|||||||
Use: "set SUBCOMMAND",
|
Use: "set SUBCOMMAND",
|
||||||
Short: "Set specific features on objects",
|
Short: "Set specific features on objects",
|
||||||
Long: set_long,
|
Long: set_long,
|
||||||
Example: set_example,
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmd.Help()
|
cmd.Help()
|
||||||
},
|
},
|
||||||
|
@@ -20,10 +20,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -59,12 +59,13 @@ var (
|
|||||||
image_resources = `
|
image_resources = `
|
||||||
pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), job, replicaset (rs)`
|
pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), job, replicaset (rs)`
|
||||||
|
|
||||||
image_long = dedent.Dedent(`
|
image_long = templates.LongDesc(`
|
||||||
Update existing container image(s) of resources.
|
Update existing container image(s) of resources.
|
||||||
|
|
||||||
Possible resources include (case insensitive):`) + image_resources
|
Possible resources include (case insensitive):
|
||||||
|
` + image_resources)
|
||||||
|
|
||||||
image_example = dedent.Dedent(`
|
image_example = templates.Examples(`
|
||||||
# Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox'.
|
# Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox'.
|
||||||
kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
|
kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
|
||||||
|
|
||||||
|
@@ -25,12 +25,35 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
resources_long = templates.LongDesc(`
|
||||||
|
Specify compute resource requirements (cpu, memory) for any resource that defines a pod template. If a pod is successfully scheduled, it is guaranteed the amount of resource requested, but may burst up to its specified limits.
|
||||||
|
|
||||||
|
for each compute resource, if a limit is specified and a request is omitted, the request will default to the limit.
|
||||||
|
|
||||||
|
Possible resources include (case insensitive):`)
|
||||||
|
|
||||||
|
resources_example = templates.Examples(`
|
||||||
|
# Set a deployments nginx container cpu limits to "200m" and memory to "512Mi"
|
||||||
|
kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi
|
||||||
|
|
||||||
|
# Set the resource request and limits for all containers in nginx
|
||||||
|
kubectl set resources deployment nginx --limits=cpu=200m,memory=512Mi --requests=cpu=100m,memory=256Mi
|
||||||
|
|
||||||
|
# Remove the resource requests for resources on containers in nginx
|
||||||
|
kubectl set resources deployment nginx --limits=cpu=0,memory=0 --requests=cpu=0,memory=0
|
||||||
|
|
||||||
|
# Print the result (in yaml format) of updating nginx container limits from a local, without hitting the server
|
||||||
|
kubectl set resources -f path/to/file.yaml --limits=cpu=200m,memory=512Mi --dry-run -o yaml`)
|
||||||
|
)
|
||||||
|
|
||||||
// ResourcesOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
// ResourcesOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
||||||
// referencing the cmd.Flags
|
// referencing the cmd.Flags
|
||||||
type ResourcesOptions struct {
|
type ResourcesOptions struct {
|
||||||
@@ -59,32 +82,6 @@ type ResourcesOptions struct {
|
|||||||
Resources []string
|
Resources []string
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
|
||||||
resources_long = `Specify compute resource requirements (cpu, memory) for any resource that defines a pod template. If a pod is successfully scheduled, it is guaranteed the amount of resource requested, but may burst up to its specified limits.
|
|
||||||
|
|
||||||
for each compute resource, if a limit is specified and a request is omitted, the request will default to the limit.
|
|
||||||
|
|
||||||
Possible resources include (case insensitive):`
|
|
||||||
|
|
||||||
resources_example = `
|
|
||||||
# Set a deployments nginx container cpu limits to "200m and memory to "512Mi"
|
|
||||||
|
|
||||||
kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi
|
|
||||||
|
|
||||||
# Set the resource request and limits for all containers in nginx
|
|
||||||
|
|
||||||
kubectl set resources deployment nginx --limits=cpu=200m,memory=512Mi --requests=cpu=100m,memory=256Mi
|
|
||||||
|
|
||||||
# Remove the resource requests for resources on containers in nginx
|
|
||||||
|
|
||||||
kubectl set resources deployment nginx --limits=cpu=0,memory=0 --requests=cpu=0,memory=0
|
|
||||||
|
|
||||||
# Print the result (in yaml format) of updating nginx container limits from a local, without hitting the server
|
|
||||||
|
|
||||||
kubectl set resources -f path/to/file.yaml --limits=cpu=200m,memory=512Mi --dry-run -o yaml
|
|
||||||
`
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
|
func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
|
||||||
options := &ResourcesOptions{
|
options := &ResourcesOptions{
|
||||||
Out: out,
|
Out: out,
|
||||||
@@ -100,7 +97,7 @@ func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.
|
|||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]",
|
Use: "resources (-f FILENAME | TYPE NAME) ([--limits=LIMITS & --requests=REQUESTS]",
|
||||||
Short: "update resource requests/limits on objects with pod templates",
|
Short: "update resource requests/limits on objects with pod templates",
|
||||||
Long: resources_long + "\n" + pod_specs[2:],
|
Long: resources_long + " " + pod_specs[2:],
|
||||||
Example: resources_example,
|
Example: resources_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(options.Complete(f, cmd, args))
|
cmdutil.CheckErr(options.Complete(f, cmd, args))
|
||||||
|
@@ -20,14 +20,14 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
stop_long = dedent.Dedent(`
|
stop_long = templates.LongDesc(`
|
||||||
Deprecated: Gracefully shut down a resource by name or filename.
|
Deprecated: Gracefully shut down a resource by name or filename.
|
||||||
|
|
||||||
The stop command is deprecated, all its functionalities are covered by delete command.
|
The stop command is deprecated, all its functionalities are covered by delete command.
|
||||||
@@ -35,7 +35,8 @@ var (
|
|||||||
|
|
||||||
Attempts to shut down and delete a resource that supports graceful termination.
|
Attempts to shut down and delete a resource that supports graceful termination.
|
||||||
If the resource is scalable it will be scaled to 0 before deletion.`)
|
If the resource is scalable it will be scaled to 0 before deletion.`)
|
||||||
stop_example = dedent.Dedent(`
|
|
||||||
|
stop_example = templates.Examples(`
|
||||||
# Shut down foo.
|
# Shut down foo.
|
||||||
kubectl stop replicationcontroller foo
|
kubectl stop replicationcontroller foo
|
||||||
|
|
||||||
|
@@ -24,11 +24,11 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
"k8s.io/kubernetes/pkg/api/meta"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@@ -53,15 +53,16 @@ type TaintOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
taint_long = dedent.Dedent(`
|
taint_long = templates.LongDesc(`
|
||||||
Update the taints on one or more nodes.
|
Update the taints on one or more nodes.
|
||||||
|
|
||||||
A taint consists of a key, value, and effect. As an argument here, it is expressed as key=value:effect.
|
* A taint consists of a key, value, and effect. As an argument here, it is expressed as key=value:effect.
|
||||||
The key must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters.
|
* The key must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters.
|
||||||
The value must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters.
|
* The value must begin with a letter or number, and may contain letters, numbers, hyphens, dots, and underscores, up to %[1]d characters.
|
||||||
The effect must be NoSchedule or PreferNoSchedule.
|
* The effect must be NoSchedule or PreferNoSchedule.
|
||||||
Currently taint can only apply to node.`)
|
* Currently taint can only apply to node.`)
|
||||||
taint_example = dedent.Dedent(`
|
|
||||||
|
taint_example = templates.Examples(`
|
||||||
# Update node 'foo' with a taint with key 'dedicated' and value 'special-user' and effect 'NoSchedule'.
|
# Update node 'foo' with a taint with key 'dedicated' and value 'special-user' and effect 'NoSchedule'.
|
||||||
# If a taint with that key and effect already exists, its value is replaced as specified.
|
# If a taint with that key and effect already exists, its value is replaced as specified.
|
||||||
kubectl taint nodes foo dedicated=special-user:NoSchedule
|
kubectl taint nodes foo dedicated=special-user:NoSchedule
|
||||||
|
61
pkg/kubectl/cmd/templates/command_groups.go
Normal file
61
pkg/kubectl/cmd/templates/command_groups.go
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
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 templates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CommandGroup struct {
|
||||||
|
Message string
|
||||||
|
Commands []*cobra.Command
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommandGroups []CommandGroup
|
||||||
|
|
||||||
|
func (g CommandGroups) Add(c *cobra.Command) {
|
||||||
|
for _, group := range g {
|
||||||
|
for _, command := range group.Commands {
|
||||||
|
c.AddCommand(command)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g CommandGroups) Has(c *cobra.Command) bool {
|
||||||
|
for _, group := range g {
|
||||||
|
for _, command := range group.Commands {
|
||||||
|
if command == c {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddAdditionalCommands(g CommandGroups, message string, cmds []*cobra.Command) CommandGroups {
|
||||||
|
group := CommandGroup{Message: message}
|
||||||
|
for _, c := range cmds {
|
||||||
|
// Don't show commands that have no short description
|
||||||
|
if !g.Has(c) && len(c.Short) != 0 {
|
||||||
|
group.Commands = append(group.Commands, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(group.Commands) == 0 {
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
return append(g, group)
|
||||||
|
}
|
145
pkg/kubectl/cmd/templates/markdown.go
Normal file
145
pkg/kubectl/cmd/templates/markdown.go
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
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 templates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/russross/blackfriday"
|
||||||
|
)
|
||||||
|
|
||||||
|
const linebreak = "\n"
|
||||||
|
|
||||||
|
// ASCIIRenderer implements blackfriday.Renderer
|
||||||
|
var _ blackfriday.Renderer = &ASCIIRenderer{}
|
||||||
|
|
||||||
|
// ASCIIRenderer is a blackfriday.Renderer intended for rendering markdown
|
||||||
|
// documents as plain text, well suited for human reading on terminals.
|
||||||
|
type ASCIIRenderer struct {
|
||||||
|
Indentation string
|
||||||
|
|
||||||
|
listItemCount uint
|
||||||
|
listLevel uint
|
||||||
|
}
|
||||||
|
|
||||||
|
// NormalText gets a text chunk *after* the markdown syntax was already
|
||||||
|
// processed and does a final cleanup on things we don't expect here, like
|
||||||
|
// removing linebreaks on things that are not a paragraph break (auto unwrap).
|
||||||
|
func (r *ASCIIRenderer) NormalText(out *bytes.Buffer, text []byte) {
|
||||||
|
raw := string(text)
|
||||||
|
lines := strings.Split(raw, linebreak)
|
||||||
|
for _, line := range lines {
|
||||||
|
trimmed := strings.Trim(line, " \n\t")
|
||||||
|
out.WriteString(trimmed)
|
||||||
|
out.WriteString(" ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// List renders the start and end of a list.
|
||||||
|
func (r *ASCIIRenderer) List(out *bytes.Buffer, text func() bool, flags int) {
|
||||||
|
r.listLevel++
|
||||||
|
out.WriteString(linebreak)
|
||||||
|
text()
|
||||||
|
r.listLevel--
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListItem renders list items and supports both ordered and unordered lists.
|
||||||
|
func (r *ASCIIRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
|
||||||
|
if flags&blackfriday.LIST_ITEM_BEGINNING_OF_LIST != 0 {
|
||||||
|
r.listItemCount = 1
|
||||||
|
} else {
|
||||||
|
r.listItemCount++
|
||||||
|
}
|
||||||
|
indent := strings.Repeat(r.Indentation, int(r.listLevel))
|
||||||
|
var bullet string
|
||||||
|
if flags&blackfriday.LIST_TYPE_ORDERED != 0 {
|
||||||
|
bullet += fmt.Sprintf("%d.", r.listItemCount)
|
||||||
|
} else {
|
||||||
|
bullet += "*"
|
||||||
|
}
|
||||||
|
out.WriteString(indent + bullet + " ")
|
||||||
|
r.fw(out, text)
|
||||||
|
out.WriteString(linebreak)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paragraph renders the start and end of a paragraph.
|
||||||
|
func (r *ASCIIRenderer) Paragraph(out *bytes.Buffer, text func() bool) {
|
||||||
|
out.WriteString(linebreak)
|
||||||
|
text()
|
||||||
|
out.WriteString(linebreak)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockCode renders a chunk of text that represents source code.
|
||||||
|
func (r *ASCIIRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) {
|
||||||
|
out.WriteString(linebreak)
|
||||||
|
lines := []string{}
|
||||||
|
for _, line := range strings.Split(string(text), linebreak) {
|
||||||
|
indented := r.Indentation + line
|
||||||
|
lines = append(lines, indented)
|
||||||
|
}
|
||||||
|
out.WriteString(strings.Join(lines, linebreak))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ASCIIRenderer) GetFlags() int { return 0 }
|
||||||
|
func (r *ASCIIRenderer) HRule(out *bytes.Buffer) {
|
||||||
|
out.WriteString(linebreak + "----------" + linebreak)
|
||||||
|
}
|
||||||
|
func (r *ASCIIRenderer) LineBreak(out *bytes.Buffer) { out.WriteString(linebreak) }
|
||||||
|
func (r *ASCIIRenderer) TitleBlock(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) Header(out *bytes.Buffer, text func() bool, level int, id string) { text() }
|
||||||
|
func (r *ASCIIRenderer) BlockHtml(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) BlockQuote(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) TableRow(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) TableHeaderCell(out *bytes.Buffer, text []byte, align int) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) TableCell(out *bytes.Buffer, text []byte, align int) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) Footnotes(out *bytes.Buffer, text func() bool) { text() }
|
||||||
|
func (r *ASCIIRenderer) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) AutoLink(out *bytes.Buffer, link []byte, kind int) { r.fw(out, link) }
|
||||||
|
func (r *ASCIIRenderer) CodeSpan(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) DoubleEmphasis(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) Emphasis(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) RawHtmlTag(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) TripleEmphasis(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) StrikeThrough(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) FootnoteRef(out *bytes.Buffer, ref []byte, id int) { r.fw(out, ref) }
|
||||||
|
func (r *ASCIIRenderer) Entity(out *bytes.Buffer, entity []byte) { r.fw(out, entity) }
|
||||||
|
func (r *ASCIIRenderer) Smartypants(out *bytes.Buffer, text []byte) { r.fw(out, text) }
|
||||||
|
func (r *ASCIIRenderer) DocumentHeader(out *bytes.Buffer) {}
|
||||||
|
func (r *ASCIIRenderer) DocumentFooter(out *bytes.Buffer) {}
|
||||||
|
func (r *ASCIIRenderer) TocHeaderWithAnchor(text []byte, level int, anchor string) {}
|
||||||
|
func (r *ASCIIRenderer) TocHeader(text []byte, level int) {}
|
||||||
|
func (r *ASCIIRenderer) TocFinalize() {}
|
||||||
|
|
||||||
|
func (r *ASCIIRenderer) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {
|
||||||
|
r.fw(out, header, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ASCIIRenderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
|
||||||
|
r.fw(out, link)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ASCIIRenderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
|
||||||
|
r.fw(out, link)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ASCIIRenderer) fw(out *bytes.Buffer, text ...[]byte) {
|
||||||
|
for _, t := range text {
|
||||||
|
out.Write(t)
|
||||||
|
}
|
||||||
|
}
|
91
pkg/kubectl/cmd/templates/normalizers.go
Normal file
91
pkg/kubectl/cmd/templates/normalizers.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
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 templates
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/MakeNowJust/heredoc"
|
||||||
|
"github.com/russross/blackfriday"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Indentation = ` `
|
||||||
|
|
||||||
|
// LongDesc normalizes a command's long description to follow the conventions.
|
||||||
|
func LongDesc(s string) string {
|
||||||
|
return normalizer{s}.heredoc().markdown().trim().string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Examples normalizes a command's examples to follow the conventions.
|
||||||
|
func Examples(s string) string {
|
||||||
|
return normalizer{s}.trim().indent().string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize perform all required normalizations on a given command.
|
||||||
|
func Normalize(cmd *cobra.Command) *cobra.Command {
|
||||||
|
if len(cmd.Long) > 0 {
|
||||||
|
cmd.Long = LongDesc(cmd.Long)
|
||||||
|
}
|
||||||
|
if len(cmd.Example) > 0 {
|
||||||
|
cmd.Example = Examples(cmd.Example)
|
||||||
|
}
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
// NormalizeAll perform all required normalizations in the entire command tree.
|
||||||
|
func NormalizeAll(cmd *cobra.Command) *cobra.Command {
|
||||||
|
if cmd.HasSubCommands() {
|
||||||
|
for _, subCmd := range cmd.Commands() {
|
||||||
|
NormalizeAll(subCmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Normalize(cmd)
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
type normalizer struct {
|
||||||
|
string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s normalizer) markdown() normalizer {
|
||||||
|
bytes := []byte(s.string)
|
||||||
|
formatted := blackfriday.Markdown(bytes, &ASCIIRenderer{Indentation: Indentation}, 0)
|
||||||
|
s.string = string(formatted)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s normalizer) heredoc() normalizer {
|
||||||
|
s.string = heredoc.Doc(s.string)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s normalizer) trim() normalizer {
|
||||||
|
s.string = strings.TrimSpace(s.string)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s normalizer) indent() normalizer {
|
||||||
|
indentedLines := []string{}
|
||||||
|
for _, line := range strings.Split(s.string, "\n") {
|
||||||
|
trimmed := strings.TrimSpace(line)
|
||||||
|
indented := Indentation + trimmed
|
||||||
|
indentedLines = append(indentedLines, indented)
|
||||||
|
}
|
||||||
|
s.string = strings.Join(indentedLines, "\n")
|
||||||
|
return s
|
||||||
|
}
|
@@ -23,73 +23,12 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/util/term"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
flag "github.com/spf13/pflag"
|
flag "github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Content of this package was borrowed from openshift/origin.
|
|
||||||
|
|
||||||
type CommandGroup struct {
|
|
||||||
Message string
|
|
||||||
Commands []*cobra.Command
|
|
||||||
}
|
|
||||||
|
|
||||||
type CommandGroups []CommandGroup
|
|
||||||
|
|
||||||
func (g CommandGroups) Add(c *cobra.Command) {
|
|
||||||
for _, group := range g {
|
|
||||||
for _, command := range group.Commands {
|
|
||||||
c.AddCommand(command)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g CommandGroups) Has(c *cobra.Command) bool {
|
|
||||||
for _, group := range g {
|
|
||||||
for _, command := range group.Commands {
|
|
||||||
if command == c {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddAdditionalCommands(g CommandGroups, message string, cmds []*cobra.Command) CommandGroups {
|
|
||||||
group := CommandGroup{Message: message}
|
|
||||||
for _, c := range cmds {
|
|
||||||
// Don't show commands that has no short description
|
|
||||||
if !g.Has(c) && len(c.Short) != 0 {
|
|
||||||
group.Commands = append(group.Commands, c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(group.Commands) == 0 {
|
|
||||||
return g
|
|
||||||
}
|
|
||||||
return append(g, group)
|
|
||||||
}
|
|
||||||
|
|
||||||
func filter(cmds []*cobra.Command, names ...string) []*cobra.Command {
|
|
||||||
out := []*cobra.Command{}
|
|
||||||
for _, c := range cmds {
|
|
||||||
if c.Hidden {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
skip := false
|
|
||||||
for _, name := range names {
|
|
||||||
if name == c.Name() {
|
|
||||||
skip = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if skip {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
out = append(out, c)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
type FlagExposer interface {
|
type FlagExposer interface {
|
||||||
ExposeFlags(cmd *cobra.Command, flags ...string) FlagExposer
|
ExposeFlags(cmd *cobra.Command, flags ...string) FlagExposer
|
||||||
}
|
}
|
||||||
@@ -98,27 +37,30 @@ func ActsAsRootCommand(cmd *cobra.Command, filters []string, groups ...CommandGr
|
|||||||
if cmd == nil {
|
if cmd == nil {
|
||||||
panic("nil root command")
|
panic("nil root command")
|
||||||
}
|
}
|
||||||
cmd.SetHelpTemplate(MainHelpTemplate())
|
|
||||||
templater := &templater{
|
templater := &templater{
|
||||||
RootCmd: cmd,
|
RootCmd: cmd,
|
||||||
UsageTemplate: MainUsageTemplate(),
|
UsageTemplate: MainUsageTemplate(),
|
||||||
|
HelpTemplate: MainHelpTemplate(),
|
||||||
CommandGroups: groups,
|
CommandGroups: groups,
|
||||||
Filtered: filters,
|
Filtered: filters,
|
||||||
}
|
}
|
||||||
cmd.SetUsageFunc(templater.UsageFunc())
|
cmd.SetUsageFunc(templater.UsageFunc())
|
||||||
|
cmd.SetHelpFunc(templater.HelpFunc())
|
||||||
return templater
|
return templater
|
||||||
}
|
}
|
||||||
|
|
||||||
func UseOptionsTemplates(cmd *cobra.Command) {
|
func UseOptionsTemplates(cmd *cobra.Command) {
|
||||||
cmd.SetHelpTemplate(OptionsHelpTemplate())
|
|
||||||
templater := &templater{
|
templater := &templater{
|
||||||
UsageTemplate: OptionsUsageTemplate(),
|
UsageTemplate: OptionsUsageTemplate(),
|
||||||
|
HelpTemplate: OptionsHelpTemplate(),
|
||||||
}
|
}
|
||||||
cmd.SetUsageFunc(templater.UsageFunc())
|
cmd.SetUsageFunc(templater.UsageFunc())
|
||||||
|
cmd.SetHelpFunc(templater.HelpFunc())
|
||||||
}
|
}
|
||||||
|
|
||||||
type templater struct {
|
type templater struct {
|
||||||
UsageTemplate string
|
UsageTemplate string
|
||||||
|
HelpTemplate string
|
||||||
RootCmd *cobra.Command
|
RootCmd *cobra.Command
|
||||||
CommandGroups
|
CommandGroups
|
||||||
Filtered []string
|
Filtered []string
|
||||||
@@ -129,11 +71,31 @@ func (templater *templater) ExposeFlags(cmd *cobra.Command, flags ...string) Fla
|
|||||||
return templater
|
return templater
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (templater *templater) HelpFunc() func(*cobra.Command, []string) {
|
||||||
|
return func(c *cobra.Command, s []string) {
|
||||||
|
t := template.New("help")
|
||||||
|
t.Funcs(templater.templateFuncs())
|
||||||
|
template.Must(t.Parse(templater.HelpTemplate))
|
||||||
|
out := term.NewResponsiveWriter(c.OutOrStdout())
|
||||||
|
err := t.Execute(out, c)
|
||||||
|
if err != nil {
|
||||||
|
c.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (templater *templater) UsageFunc(exposedFlags ...string) func(*cobra.Command) error {
|
func (templater *templater) UsageFunc(exposedFlags ...string) func(*cobra.Command) error {
|
||||||
return func(c *cobra.Command) error {
|
return func(c *cobra.Command) error {
|
||||||
t := template.New("custom")
|
t := template.New("usage")
|
||||||
|
t.Funcs(templater.templateFuncs(exposedFlags...))
|
||||||
|
template.Must(t.Parse(templater.UsageTemplate))
|
||||||
|
out := term.NewResponsiveWriter(c.OutOrStderr())
|
||||||
|
return t.Execute(out, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
t.Funcs(template.FuncMap{
|
func (templater *templater) templateFuncs(exposedFlags ...string) template.FuncMap {
|
||||||
|
return template.FuncMap{
|
||||||
"trim": strings.TrimSpace,
|
"trim": strings.TrimSpace,
|
||||||
"trimRight": func(s string) string { return strings.TrimRightFunc(s, unicode.IsSpace) },
|
"trimRight": func(s string) string { return strings.TrimRightFunc(s, unicode.IsSpace) },
|
||||||
"trimLeft": func(s string) string { return strings.TrimLeftFunc(s, unicode.IsSpace) },
|
"trimLeft": func(s string) string { return strings.TrimLeftFunc(s, unicode.IsSpace) },
|
||||||
@@ -144,8 +106,8 @@ func (templater *templater) UsageFunc(exposedFlags ...string) func(*cobra.Comman
|
|||||||
"flagsNotIntersected": flagsNotIntersected,
|
"flagsNotIntersected": flagsNotIntersected,
|
||||||
"visibleFlags": visibleFlags,
|
"visibleFlags": visibleFlags,
|
||||||
"flagsUsages": flagsUsages,
|
"flagsUsages": flagsUsages,
|
||||||
"indentLines": indentLines,
|
|
||||||
"cmdGroups": templater.cmdGroups,
|
"cmdGroups": templater.cmdGroups,
|
||||||
|
"cmdGroupsString": templater.cmdGroupsString,
|
||||||
"rootCmd": templater.rootCmdName,
|
"rootCmd": templater.rootCmdName,
|
||||||
"isRootCmd": templater.isRootCmd,
|
"isRootCmd": templater.isRootCmd,
|
||||||
"optionsCmdFor": templater.optionsCmdFor,
|
"optionsCmdFor": templater.optionsCmdFor,
|
||||||
@@ -161,10 +123,6 @@ func (templater *templater) UsageFunc(exposedFlags ...string) func(*cobra.Comman
|
|||||||
}
|
}
|
||||||
return exposed
|
return exposed
|
||||||
},
|
},
|
||||||
})
|
|
||||||
|
|
||||||
template.Must(t.Parse(templater.UsageTemplate))
|
|
||||||
return t.Execute(c.OutOrStdout(), c)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,6 +140,20 @@ func (templater *templater) cmdGroups(c *cobra.Command, all []*cobra.Command) []
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *templater) cmdGroupsString(c *cobra.Command) string {
|
||||||
|
groups := []string{}
|
||||||
|
for _, cmdGroup := range t.cmdGroups(c, c.Commands()) {
|
||||||
|
cmds := []string{cmdGroup.Message}
|
||||||
|
for _, cmd := range cmdGroup.Commands {
|
||||||
|
if cmd.Runnable() {
|
||||||
|
cmds = append(cmds, " "+rpad(cmd.Name(), cmd.NamePadding())+" "+cmd.Short)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
groups = append(groups, strings.Join(cmds, "\n"))
|
||||||
|
}
|
||||||
|
return strings.Join(groups, "\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
func (t *templater) rootCmdName(c *cobra.Command) string {
|
func (t *templater) rootCmdName(c *cobra.Command) string {
|
||||||
return t.rootCmd(c).CommandPath()
|
return t.rootCmd(c).CommandPath()
|
||||||
}
|
}
|
||||||
@@ -298,3 +270,24 @@ func visibleFlags(l *flag.FlagSet) *flag.FlagSet {
|
|||||||
})
|
})
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func filter(cmds []*cobra.Command, names ...string) []*cobra.Command {
|
||||||
|
out := []*cobra.Command{}
|
||||||
|
for _, c := range cmds {
|
||||||
|
if c.Hidden {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
skip := false
|
||||||
|
for _, name := range names {
|
||||||
|
if name == c.Name() {
|
||||||
|
skip = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if skip {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out = append(out, c)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
@@ -16,84 +16,87 @@ limitations under the License.
|
|||||||
|
|
||||||
package templates
|
package templates
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"strings"
|
||||||
func MainHelpTemplate() string {
|
"unicode"
|
||||||
return decorate(mainHelpTemplate, false)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
func MainUsageTemplate() string {
|
|
||||||
return decorate(mainUsageTemplate, true) + "\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
func OptionsHelpTemplate() string {
|
|
||||||
return decorate(optionsHelpTemplate, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func OptionsUsageTemplate() string {
|
|
||||||
return decorate(optionsUsageTemplate, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func decorate(template string, trim bool) string {
|
|
||||||
if trim && len(strings.Trim(template, " ")) > 0 {
|
|
||||||
template = strings.Trim(template, "\n")
|
|
||||||
}
|
|
||||||
return template
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
vars = `{{$isRootCmd := isRootCmd .}}` +
|
// SectionVars is the help template section that declares variables to be used in the template.
|
||||||
|
SectionVars = `{{$isRootCmd := isRootCmd .}}` +
|
||||||
`{{$rootCmd := rootCmd .}}` +
|
`{{$rootCmd := rootCmd .}}` +
|
||||||
`{{$visibleFlags := visibleFlags (flagsNotIntersected .LocalFlags .PersistentFlags)}}` +
|
`{{$visibleFlags := visibleFlags (flagsNotIntersected .LocalFlags .PersistentFlags)}}` +
|
||||||
`{{$explicitlyExposedFlags := exposed .}}` +
|
`{{$explicitlyExposedFlags := exposed .}}` +
|
||||||
`{{$optionsCmdFor := optionsCmdFor .}}` +
|
`{{$optionsCmdFor := optionsCmdFor .}}` +
|
||||||
`{{$usageLine := usageLine .}}`
|
`{{$usageLine := usageLine .}}`
|
||||||
|
|
||||||
mainHelpTemplate = `{{with or .Long .Short }}{{. | trim}}{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
|
// SectionAliases is the help template section that displays command aliases.
|
||||||
|
SectionAliases = `{{if gt .Aliases 0}}Aliases:
|
||||||
|
{{.NameAndAliases}}
|
||||||
|
|
||||||
mainUsageTemplate = vars +
|
{{end}}`
|
||||||
// ALIASES
|
|
||||||
`{{if gt .Aliases 0}}
|
|
||||||
|
|
||||||
Aliases:
|
// SectionExamples is the help template section that displays command examples.
|
||||||
{{.NameAndAliases}}{{end}}` +
|
SectionExamples = `{{if .HasExample}}Examples:
|
||||||
|
{{trimRight .Example}}
|
||||||
|
|
||||||
// EXAMPLES
|
{{end}}`
|
||||||
`{{if .HasExample}}
|
|
||||||
|
|
||||||
Examples:
|
// SectionSubcommands is the help template section that displays the command's subcommands.
|
||||||
{{ indentLines (.Example | trimLeft) 2 }}{{end}}` +
|
SectionSubcommands = `{{if .HasAvailableSubCommands}}{{cmdGroupsString .}}
|
||||||
|
|
||||||
// SUBCOMMANDS
|
{{end}}`
|
||||||
`{{ if .HasAvailableSubCommands}}
|
|
||||||
{{range cmdGroups . .Commands}}
|
|
||||||
{{.Message}}
|
|
||||||
{{range .Commands}}{{if .Runnable}} {{rpad .Name .NamePadding }} {{.Short}}
|
|
||||||
{{end}}{{end}}{{end}}{{end}}` +
|
|
||||||
|
|
||||||
// VISIBLE FLAGS
|
// SectionFlags is the help template section that displays the command's flags.
|
||||||
`{{ if or $visibleFlags.HasFlags $explicitlyExposedFlags.HasFlags}}
|
SectionFlags = `{{ if or $visibleFlags.HasFlags $explicitlyExposedFlags.HasFlags}}Options:
|
||||||
|
{{ if $visibleFlags.HasFlags}}{{trimRight (flagsUsages $visibleFlags)}}{{end}}{{ if $explicitlyExposedFlags.HasFlags}}{{trimRight (flagsUsages $explicitlyExposedFlags)}}{{end}}
|
||||||
|
|
||||||
Options:
|
{{end}}`
|
||||||
{{ if $visibleFlags.HasFlags}}{{flagsUsages $visibleFlags}}{{end}}{{ if $explicitlyExposedFlags.HasFlags}}{{flagsUsages $explicitlyExposedFlags}}{{end}}{{end}}` +
|
|
||||||
|
|
||||||
// USAGE LINE
|
// SectionUsage is the help template section that displays the command's usage.
|
||||||
`{{if and .Runnable (ne .UseLine "") (ne .UseLine $rootCmd)}}
|
SectionUsage = `{{if and .Runnable (ne .UseLine "") (ne .UseLine $rootCmd)}}Usage:
|
||||||
Usage:
|
|
||||||
{{$usageLine}}
|
{{$usageLine}}
|
||||||
{{end}}` +
|
|
||||||
|
|
||||||
// TIPS: --help
|
{{end}}`
|
||||||
`{{ if .HasSubCommands }}
|
|
||||||
Use "{{$rootCmd}} <command> --help" for more information about a given command.{{end}}` +
|
|
||||||
|
|
||||||
// TIPS: global options
|
// SectionTipsHelp is the help template section that displays the '--help' hint.
|
||||||
`{{ if $optionsCmdFor}}
|
SectionTipsHelp = `{{if .HasSubCommands}}Use "{{$rootCmd}} <command> --help" for more information about a given command.
|
||||||
Use "{{$optionsCmdFor}}" for a list of global command-line options (applies to all commands).{{end}}`
|
{{end}}`
|
||||||
|
|
||||||
optionsHelpTemplate = ``
|
// SectionTipsGlobalOptions is the help template section that displays the 'options' hint for displaying global flags.
|
||||||
|
SectionTipsGlobalOptions = `{{if $optionsCmdFor}}Use "{{$optionsCmdFor}}" for a list of global command-line options (applies to all commands).
|
||||||
|
{{end}}`
|
||||||
|
)
|
||||||
|
|
||||||
optionsUsageTemplate = `{{ if .HasInheritedFlags}}The following options can be passed to any command:
|
// MainHelpTemplate if the template for 'help' used by most commands.
|
||||||
|
func MainHelpTemplate() string {
|
||||||
|
return `{{with or .Long .Short }}{{. | trim}}{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MainUsageTemplate if the template for 'usage' used by most commands.
|
||||||
|
func MainUsageTemplate() string {
|
||||||
|
sections := []string{
|
||||||
|
"\n\n",
|
||||||
|
SectionVars,
|
||||||
|
SectionAliases,
|
||||||
|
SectionExamples,
|
||||||
|
SectionSubcommands,
|
||||||
|
SectionFlags,
|
||||||
|
SectionUsage,
|
||||||
|
SectionTipsHelp,
|
||||||
|
SectionTipsGlobalOptions,
|
||||||
|
}
|
||||||
|
return strings.TrimRightFunc(strings.Join(sections, ""), unicode.IsSpace)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OptionsHelpTemplate if the template for 'help' used by the 'options' command.
|
||||||
|
func OptionsHelpTemplate() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// OptionsUsageTemplate if the template for 'usage' used by the 'options' command.
|
||||||
|
func OptionsUsageTemplate() string {
|
||||||
|
return `{{ if .HasInheritedFlags}}The following options can be passed to any command:
|
||||||
|
|
||||||
{{flagsUsages .InheritedFlags}}{{end}}`
|
{{flagsUsages .InheritedFlags}}{{end}}`
|
||||||
)
|
}
|
||||||
|
@@ -21,15 +21,15 @@ import (
|
|||||||
|
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TopOptions contains all the options for running the top cli command.
|
// TopOptions contains all the options for running the top cli command.
|
||||||
type TopOptions struct{}
|
type TopOptions struct{}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
topLong = dedent.Dedent(`
|
topLong = templates.LongDesc(`
|
||||||
Display Resource (CPU/Memory/Storage) usage.
|
Display Resource (CPU/Memory/Storage) usage.
|
||||||
|
|
||||||
The top command allows you to see the resource consumption for nodes or pods.`)
|
The top command allows you to see the resource consumption for nodes or pods.`)
|
||||||
|
@@ -20,11 +20,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
|
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
@@ -40,12 +40,12 @@ type TopNodeOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
topNodeLong = dedent.Dedent(`
|
topNodeLong = templates.LongDesc(`
|
||||||
Display Resource (CPU/Memory/Storage) usage of nodes.
|
Display Resource (CPU/Memory/Storage) usage of nodes.
|
||||||
|
|
||||||
The top-node command allows you to see the resource consumption of nodes.`)
|
The top-node command allows you to see the resource consumption of nodes.`)
|
||||||
|
|
||||||
topNodeExample = dedent.Dedent(`
|
topNodeExample = templates.Examples(`
|
||||||
# Show metrics for all nodes
|
# Show metrics for all nodes
|
||||||
kubectl top node
|
kubectl top node
|
||||||
|
|
||||||
|
@@ -24,12 +24,12 @@ import (
|
|||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/unversioned"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
|
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
|
||||||
"k8s.io/kubernetes/pkg/labels"
|
"k8s.io/kubernetes/pkg/labels"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/renstrom/dedent"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ type TopPodOptions struct {
|
|||||||
const metricsCreationDelay = 2 * time.Minute
|
const metricsCreationDelay = 2 * time.Minute
|
||||||
|
|
||||||
var (
|
var (
|
||||||
topPodLong = dedent.Dedent(`
|
topPodLong = templates.LongDesc(`
|
||||||
Display Resource (CPU/Memory/Storage) usage of pods.
|
Display Resource (CPU/Memory/Storage) usage of pods.
|
||||||
|
|
||||||
The 'top pod' command allows you to see the resource consumption of pods.
|
The 'top pod' command allows you to see the resource consumption of pods.
|
||||||
@@ -55,7 +55,7 @@ var (
|
|||||||
Due to the metrics pipeline delay, they may be unavailable for a few minutes
|
Due to the metrics pipeline delay, they may be unavailable for a few minutes
|
||||||
since pod creation.`)
|
since pod creation.`)
|
||||||
|
|
||||||
topPodExample = dedent.Dedent(`
|
topPodExample = templates.Examples(`
|
||||||
# Show metrics for all pods in the default namespace
|
# Show metrics for all pods in the default namespace
|
||||||
kubectl top pod
|
kubectl top pod
|
||||||
|
|
||||||
|
94
pkg/kubectl/cmd/util/sanity/cmd_sanity.go
Normal file
94
pkg/kubectl/cmd/util/sanity/cmd_sanity.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
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 sanity
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CmdCheck func(cmd *cobra.Command) []error
|
||||||
|
|
||||||
|
var (
|
||||||
|
AllCmdChecks = []CmdCheck{
|
||||||
|
CheckLongDesc,
|
||||||
|
CheckExamples,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func CheckCmdTree(cmd *cobra.Command, checks []CmdCheck, skip []string) []error {
|
||||||
|
cmdPath := cmd.CommandPath()
|
||||||
|
|
||||||
|
for _, skipCmdPath := range skip {
|
||||||
|
if cmdPath == skipCmdPath {
|
||||||
|
fmt.Fprintf(os.Stdout, "-----+ skipping command %s\n", cmdPath)
|
||||||
|
return []error{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errors := []error{}
|
||||||
|
|
||||||
|
if cmd.HasSubCommands() {
|
||||||
|
for _, subCmd := range cmd.Commands() {
|
||||||
|
errors = append(errors, CheckCmdTree(subCmd, checks, skip)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(os.Stdout, "-----+ checking command %s\n", cmdPath)
|
||||||
|
|
||||||
|
for _, check := range checks {
|
||||||
|
if err := check(cmd); err != nil && len(err) > 0 {
|
||||||
|
errors = append(errors, err...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckLongDesc(cmd *cobra.Command) []error {
|
||||||
|
cmdPath := cmd.CommandPath()
|
||||||
|
long := cmd.Long
|
||||||
|
if len(long) > 0 {
|
||||||
|
if strings.Trim(long, " \t\n") != long {
|
||||||
|
return []error{fmt.Errorf(`command %q: long description is not normalized
|
||||||
|
↳ make sure you are calling templates.LongDesc (from pkg/cmd/templates) before assigning cmd.Long`, cmdPath)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckExamples(cmd *cobra.Command) []error {
|
||||||
|
cmdPath := cmd.CommandPath()
|
||||||
|
examples := cmd.Example
|
||||||
|
errors := []error{}
|
||||||
|
if len(examples) > 0 {
|
||||||
|
for _, line := range strings.Split(examples, "\n") {
|
||||||
|
if !strings.HasPrefix(line, templates.Indentation) {
|
||||||
|
errors = append(errors, fmt.Errorf(`command %q: examples are not normalized
|
||||||
|
↳ make sure you are calling templates.Examples (from pkg/cmd/templates) before assigning cmd.Example`, cmdPath))
|
||||||
|
}
|
||||||
|
if trimmed := strings.TrimSpace(line); strings.HasPrefix(trimmed, "//") {
|
||||||
|
errors = append(errors, fmt.Errorf(`command %q: we use # to start comments in examples instead of //`, cmdPath))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors
|
||||||
|
}
|
124
pkg/util/term/term_writer.go
Normal file
124
pkg/util/term/term_writer.go
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
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 term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/term"
|
||||||
|
wordwrap "github.com/mitchellh/go-wordwrap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type wordWrapWriter struct {
|
||||||
|
limit uint
|
||||||
|
writer io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewResponsiveWriter creates a Writer that detects the column width of the
|
||||||
|
// terminal we are in, and adjusts every line width to fit and use recommended
|
||||||
|
// terminal sizes for better readability. Does proper word wrapping automatically.
|
||||||
|
// if terminal width >= 120 columns use 120 columns
|
||||||
|
// if terminal width >= 100 columns use 100 columns
|
||||||
|
// if terminal width >= 80 columns use 80 columns
|
||||||
|
// In case we're not in a terminal or if it's smaller than 80 columns width,
|
||||||
|
// doesn't do any wrapping.
|
||||||
|
func NewResponsiveWriter(w io.Writer) io.Writer {
|
||||||
|
file, ok := w.(*os.File)
|
||||||
|
if !ok {
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
fd := file.Fd()
|
||||||
|
if !term.IsTerminal(fd) {
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
terminalSize := GetSize(fd)
|
||||||
|
if terminalSize == nil {
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
var limit uint
|
||||||
|
switch {
|
||||||
|
case terminalSize.Width >= 120:
|
||||||
|
limit = 120
|
||||||
|
case terminalSize.Width >= 100:
|
||||||
|
limit = 100
|
||||||
|
case terminalSize.Width >= 80:
|
||||||
|
limit = 80
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewWordWrapWriter(w, limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWordWrapWriter is a Writer that supports a limit of characters on every line
|
||||||
|
// and does auto word wrapping that respects that limit.
|
||||||
|
func NewWordWrapWriter(w io.Writer, limit uint) io.Writer {
|
||||||
|
return &wordWrapWriter{
|
||||||
|
limit: limit,
|
||||||
|
writer: w,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w wordWrapWriter) Write(p []byte) (nn int, err error) {
|
||||||
|
if w.limit == 0 {
|
||||||
|
return w.writer.Write(p)
|
||||||
|
}
|
||||||
|
original := string(p)
|
||||||
|
wrapped := wordwrap.WrapString(original, w.limit)
|
||||||
|
return w.writer.Write([]byte(wrapped))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPunchCardWriter is a NewWordWrapWriter that limits the line width to 80 columns.
|
||||||
|
func NewPunchCardWriter(w io.Writer) io.Writer {
|
||||||
|
return NewWordWrapWriter(w, 80)
|
||||||
|
}
|
||||||
|
|
||||||
|
type maxWidthWriter struct {
|
||||||
|
maxWidth uint
|
||||||
|
currentWidth uint
|
||||||
|
written uint
|
||||||
|
writer io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMaxWidthWriter is a Writer that supports a limit of characters on every
|
||||||
|
// line, but doesn't do any word wrapping automatically.
|
||||||
|
func NewMaxWidthWriter(w io.Writer, maxWidth uint) io.Writer {
|
||||||
|
return &maxWidthWriter{
|
||||||
|
maxWidth: maxWidth,
|
||||||
|
writer: w,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m maxWidthWriter) Write(p []byte) (nn int, err error) {
|
||||||
|
for _, b := range p {
|
||||||
|
if m.currentWidth == m.maxWidth {
|
||||||
|
m.writer.Write([]byte{'\n'})
|
||||||
|
m.currentWidth = 0
|
||||||
|
}
|
||||||
|
if b == '\n' {
|
||||||
|
m.currentWidth = 0
|
||||||
|
}
|
||||||
|
_, err := m.writer.Write([]byte{b})
|
||||||
|
if err != nil {
|
||||||
|
return int(m.written), err
|
||||||
|
}
|
||||||
|
m.written++
|
||||||
|
m.currentWidth++
|
||||||
|
}
|
||||||
|
return len(p), nil
|
||||||
|
}
|
98
pkg/util/term/term_writer_test.go
Normal file
98
pkg/util/term/term_writer_test.go
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
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 term
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
const test = "Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube Kube"
|
||||||
|
|
||||||
|
func TestWordWrapWriter(t *testing.T) {
|
||||||
|
testcases := map[string]struct {
|
||||||
|
input string
|
||||||
|
maxWidth uint
|
||||||
|
}{
|
||||||
|
"max 10": {input: test, maxWidth: 10},
|
||||||
|
"max 80": {input: test, maxWidth: 80},
|
||||||
|
"max 120": {input: test, maxWidth: 120},
|
||||||
|
"max 5000": {input: test, maxWidth: 5000},
|
||||||
|
}
|
||||||
|
for k, tc := range testcases {
|
||||||
|
b := bytes.NewBufferString("")
|
||||||
|
w := NewWordWrapWriter(b, tc.maxWidth)
|
||||||
|
_, err := w.Write([]byte(tc.input))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: Unexpected error: %v", k, err)
|
||||||
|
}
|
||||||
|
result := b.String()
|
||||||
|
if !strings.Contains(result, "Kube") {
|
||||||
|
t.Errorf("%s: Expected to contain \"Kube\"", k)
|
||||||
|
}
|
||||||
|
if len(result) < len(tc.input) {
|
||||||
|
t.Errorf("%s: Unexpectedly short string, got %d wanted at least %d chars: %q", k, len(result), len(tc.input), result)
|
||||||
|
}
|
||||||
|
for _, line := range strings.Split(result, "\n") {
|
||||||
|
if len(line) > int(tc.maxWidth) {
|
||||||
|
t.Errorf("%s: Every line must be at most %d chars long, got %d: %q", k, tc.maxWidth, len(line), line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, word := range strings.Split(result, " ") {
|
||||||
|
if !strings.Contains(word, "Kube") {
|
||||||
|
t.Errorf("%s: Unexpected broken word: %q", k, word)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMaxWidthWriter(t *testing.T) {
|
||||||
|
testcases := map[string]struct {
|
||||||
|
input string
|
||||||
|
maxWidth uint
|
||||||
|
}{
|
||||||
|
"max 10": {input: test, maxWidth: 10},
|
||||||
|
"max 80": {input: test, maxWidth: 80},
|
||||||
|
"max 120": {input: test, maxWidth: 120},
|
||||||
|
"max 5000": {input: test, maxWidth: 5000},
|
||||||
|
}
|
||||||
|
for k, tc := range testcases {
|
||||||
|
b := bytes.NewBufferString("")
|
||||||
|
w := NewMaxWidthWriter(b, tc.maxWidth)
|
||||||
|
_, err := w.Write([]byte(tc.input))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: Unexpected error: %v", k, err)
|
||||||
|
}
|
||||||
|
result := b.String()
|
||||||
|
if !strings.Contains(result, "Kube") {
|
||||||
|
t.Errorf("%s: Expected to contain \"Kube\"", k)
|
||||||
|
}
|
||||||
|
if len(result) < len(tc.input) {
|
||||||
|
t.Errorf("%s: Unexpectedly short string, got %d wanted at least %d chars: %q", k, len(result), len(tc.input), result)
|
||||||
|
}
|
||||||
|
lines := strings.Split(result, "\n")
|
||||||
|
for i, line := range lines {
|
||||||
|
if len(line) > int(tc.maxWidth) {
|
||||||
|
t.Errorf("%s: Every line must be at most %d chars long, got %d: %q", k, tc.maxWidth, len(line), line)
|
||||||
|
}
|
||||||
|
if i < len(lines)-1 && len(line) != int(tc.maxWidth) {
|
||||||
|
t.Errorf("%s: Lines except the last one are expected to be exactly %d chars long, got %d: %q", k, tc.maxWidth, len(line), line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
vendor/github.com/MakeNowJust/heredoc/LICENSE
generated
vendored
Normal file
21
vendor/github.com/MakeNowJust/heredoc/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 TSUYUSATO Kitsune
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
53
vendor/github.com/MakeNowJust/heredoc/README.md
generated
vendored
Normal file
53
vendor/github.com/MakeNowJust/heredoc/README.md
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#heredoc [](https://drone.io/github.com/MakeNowJust/heredoc/latest) [](https://gowalker.org/github.com/MakeNowJust/heredoc)
|
||||||
|
|
||||||
|
##About
|
||||||
|
|
||||||
|
Package heredoc provides the here-document with keeping indent.
|
||||||
|
|
||||||
|
##Install
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ go get github.com/MakeNowJust/heredoc
|
||||||
|
```
|
||||||
|
|
||||||
|
##Import
|
||||||
|
|
||||||
|
```go
|
||||||
|
// usual
|
||||||
|
import "github.com/MakeNowJust/heredoc"
|
||||||
|
// shortcuts
|
||||||
|
import . "github.com/MakeNowJust/heredoc/dot"
|
||||||
|
```
|
||||||
|
|
||||||
|
##Example
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
. "github.com/MakeNowJust/heredoc/dot"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println(D(`
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipisicing elit,
|
||||||
|
sed do eiusmod tempor incididunt ut labore et dolore magna
|
||||||
|
aliqua. Ut enim ad minim veniam, ...
|
||||||
|
`))
|
||||||
|
// Output:
|
||||||
|
// Lorem ipsum dolor sit amet, consectetur adipisicing elit,
|
||||||
|
// sed do eiusmod tempor incididunt ut labore et dolore magna
|
||||||
|
// aliqua. Ut enim ad minim veniam, ...
|
||||||
|
//
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##API Document
|
||||||
|
|
||||||
|
- [Go Walker - github.com/MakeNowJust/heredoc](https://gowalker.org/github.com/MakeNowJust/heredoc)
|
||||||
|
- [Go Walker - github.com/MakeNowJust/heredoc/dot](https://gowalker.org/github.com/MakeNowJust/heredoc/dot)
|
||||||
|
|
||||||
|
##License
|
||||||
|
|
||||||
|
This software is released under the MIT License, see LICENSE.
|
89
vendor/github.com/MakeNowJust/heredoc/heredoc.go
generated
vendored
Normal file
89
vendor/github.com/MakeNowJust/heredoc/heredoc.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
// Copyright (c) 2014 TSUYUSATO Kitsune
|
||||||
|
// This software is released under the MIT License.
|
||||||
|
// http://opensource.org/licenses/mit-license.php
|
||||||
|
|
||||||
|
// Package heredoc provides the here-document with keeping indent.
|
||||||
|
//
|
||||||
|
// Golang supports raw-string syntax.
|
||||||
|
// doc := `
|
||||||
|
// Foo
|
||||||
|
// Bar
|
||||||
|
// `
|
||||||
|
// But raw-string cannot recognize indent. Thus such content is indented string, equivalent to
|
||||||
|
// "\n\tFoo\n\tBar\n"
|
||||||
|
// I dont't want this!
|
||||||
|
//
|
||||||
|
// However this problem is solved by package heredoc.
|
||||||
|
// doc := heredoc.Doc(`
|
||||||
|
// Foo
|
||||||
|
// Bar
|
||||||
|
// `)
|
||||||
|
// It is equivalent to
|
||||||
|
// "Foo\nBar\n"
|
||||||
|
package heredoc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// heredoc.Doc retutns unindented string as here-document.
|
||||||
|
//
|
||||||
|
// Process of making here-document:
|
||||||
|
// 1. Find most little indent size. (Skip empty lines)
|
||||||
|
// 2. Remove this indents of lines.
|
||||||
|
func Doc(raw string) string {
|
||||||
|
skipFirstLine := false
|
||||||
|
if raw[0] == '\n' {
|
||||||
|
raw = raw[1:]
|
||||||
|
} else {
|
||||||
|
skipFirstLine = true
|
||||||
|
}
|
||||||
|
|
||||||
|
minIndentSize := int(^uint(0) >> 1) // Max value of type int
|
||||||
|
lines := strings.Split(raw, "\n")
|
||||||
|
|
||||||
|
// 1.
|
||||||
|
for i, line := range lines {
|
||||||
|
if i == 0 && skipFirstLine {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
indentSize := 0
|
||||||
|
for _, r := range []rune(line) {
|
||||||
|
if unicode.IsSpace(r) {
|
||||||
|
indentSize += 1
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(line) == indentSize {
|
||||||
|
if i == len(lines)-1 && indentSize < minIndentSize {
|
||||||
|
lines[i] = ""
|
||||||
|
}
|
||||||
|
} else if indentSize < minIndentSize {
|
||||||
|
minIndentSize = indentSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.
|
||||||
|
for i, line := range lines {
|
||||||
|
if i == 0 && skipFirstLine {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(lines[i]) >= minIndentSize {
|
||||||
|
lines[i] = line[minIndentSize:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(lines, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// heredoc.Docf returns unindented and formatted string as here-document.
|
||||||
|
// This format is same with package fmt's format.
|
||||||
|
func Docf(raw string, args ...interface{}) string {
|
||||||
|
return fmt.Sprintf(Doc(raw), args...)
|
||||||
|
}
|
21
vendor/github.com/mitchellh/go-wordwrap/LICENSE.md
generated
vendored
Normal file
21
vendor/github.com/mitchellh/go-wordwrap/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Mitchell Hashimoto
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
39
vendor/github.com/mitchellh/go-wordwrap/README.md
generated
vendored
Normal file
39
vendor/github.com/mitchellh/go-wordwrap/README.md
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# go-wordwrap
|
||||||
|
|
||||||
|
`go-wordwrap` (Golang package: `wordwrap`) is a package for Go that
|
||||||
|
automatically wraps words into multiple lines. The primary use case for this
|
||||||
|
is in formatting CLI output, but of course word wrapping is a generally useful
|
||||||
|
thing to do.
|
||||||
|
|
||||||
|
## Installation and Usage
|
||||||
|
|
||||||
|
Install using `go get github.com/mitchellh/go-wordwrap`.
|
||||||
|
|
||||||
|
Full documentation is available at
|
||||||
|
http://godoc.org/github.com/mitchellh/go-wordwrap
|
||||||
|
|
||||||
|
Below is an example of its usage ignoring errors:
|
||||||
|
|
||||||
|
```go
|
||||||
|
wrapped := wordwrap.WrapString("foo bar baz", 3)
|
||||||
|
fmt.Println(wrapped)
|
||||||
|
```
|
||||||
|
|
||||||
|
Would output:
|
||||||
|
|
||||||
|
```
|
||||||
|
foo
|
||||||
|
bar
|
||||||
|
baz
|
||||||
|
```
|
||||||
|
|
||||||
|
## Word Wrap Algorithm
|
||||||
|
|
||||||
|
This library doesn't use any clever algorithm for word wrapping. The wrapping
|
||||||
|
is actually very naive: whenever there is whitespace or an explicit linebreak.
|
||||||
|
The goal of this library is for word wrapping CLI output, so the input is
|
||||||
|
typically pretty well controlled human language. Because of this, the naive
|
||||||
|
approach typically works just fine.
|
||||||
|
|
||||||
|
In the future, we'd like to make the algorithm more advanced. We would do
|
||||||
|
so without breaking the API.
|
73
vendor/github.com/mitchellh/go-wordwrap/wordwrap.go
generated
vendored
Normal file
73
vendor/github.com/mitchellh/go-wordwrap/wordwrap.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
package wordwrap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WrapString wraps the given string within lim width in characters.
|
||||||
|
//
|
||||||
|
// Wrapping is currently naive and only happens at white-space. A future
|
||||||
|
// version of the library will implement smarter wrapping. This means that
|
||||||
|
// pathological cases can dramatically reach past the limit, such as a very
|
||||||
|
// long word.
|
||||||
|
func WrapString(s string, lim uint) string {
|
||||||
|
// Initialize a buffer with a slightly larger size to account for breaks
|
||||||
|
init := make([]byte, 0, len(s))
|
||||||
|
buf := bytes.NewBuffer(init)
|
||||||
|
|
||||||
|
var current uint
|
||||||
|
var wordBuf, spaceBuf bytes.Buffer
|
||||||
|
|
||||||
|
for _, char := range s {
|
||||||
|
if char == '\n' {
|
||||||
|
if wordBuf.Len() == 0 {
|
||||||
|
if current+uint(spaceBuf.Len()) > lim {
|
||||||
|
current = 0
|
||||||
|
} else {
|
||||||
|
current += uint(spaceBuf.Len())
|
||||||
|
spaceBuf.WriteTo(buf)
|
||||||
|
}
|
||||||
|
spaceBuf.Reset()
|
||||||
|
} else {
|
||||||
|
current += uint(spaceBuf.Len() + wordBuf.Len())
|
||||||
|
spaceBuf.WriteTo(buf)
|
||||||
|
spaceBuf.Reset()
|
||||||
|
wordBuf.WriteTo(buf)
|
||||||
|
wordBuf.Reset()
|
||||||
|
}
|
||||||
|
buf.WriteRune(char)
|
||||||
|
current = 0
|
||||||
|
} else if unicode.IsSpace(char) {
|
||||||
|
if spaceBuf.Len() == 0 || wordBuf.Len() > 0 {
|
||||||
|
current += uint(spaceBuf.Len() + wordBuf.Len())
|
||||||
|
spaceBuf.WriteTo(buf)
|
||||||
|
spaceBuf.Reset()
|
||||||
|
wordBuf.WriteTo(buf)
|
||||||
|
wordBuf.Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
spaceBuf.WriteRune(char)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
wordBuf.WriteRune(char)
|
||||||
|
|
||||||
|
if current+uint(spaceBuf.Len()+wordBuf.Len()) > lim && uint(wordBuf.Len()) < lim {
|
||||||
|
buf.WriteRune('\n')
|
||||||
|
current = 0
|
||||||
|
spaceBuf.Reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if wordBuf.Len() == 0 {
|
||||||
|
if current+uint(spaceBuf.Len()) <= lim {
|
||||||
|
spaceBuf.WriteTo(buf)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
spaceBuf.WriteTo(buf)
|
||||||
|
wordBuf.WriteTo(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.String()
|
||||||
|
}
|
Reference in New Issue
Block a user