mirror of https://github.com/k3s-io/k3s
Merge pull request #14087 from brendandburns/kubectl
Move the default schema cache to the home directorypull/6/head
commit
44a16834d8
|
@ -29,8 +29,8 @@ JSON and YAML formats are accepted.
|
|||
Output mode. Use "\-o name" for shorter output (resource/name).
|
||||
|
||||
.PP
|
||||
\fB\-\-schema\-cache\-dir\fP="/tmp/kubectl.schema"
|
||||
If non\-empty, load/store cached API schemas in this directory, default is '/tmp/kubectl.schema'
|
||||
\fB\-\-schema\-cache\-dir\fP="\~/.kube/schema"
|
||||
If non\-empty, load/store cached API schemas in this directory, default is '$HOME/.kube/schema'
|
||||
|
||||
.PP
|
||||
\fB\-\-validate\fP=true
|
||||
|
|
|
@ -47,8 +47,8 @@ Please refer to the models in
|
|||
Output mode. Use "\-o name" for shorter output (resource/name).
|
||||
|
||||
.PP
|
||||
\fB\-\-schema\-cache\-dir\fP="/tmp/kubectl.schema"
|
||||
If non\-empty, load/store cached API schemas in this directory, default is '/tmp/kubectl.schema'
|
||||
\fB\-\-schema\-cache\-dir\fP="\~/.kube/schema"
|
||||
If non\-empty, load/store cached API schemas in this directory, default is '$HOME/.kube/schema'
|
||||
|
||||
.PP
|
||||
\fB\-\-timeout\fP=0
|
||||
|
|
|
@ -61,8 +61,8 @@ existing replication controller and overwrite at least one (common) label in its
|
|||
If true, this is a request to abort an existing rollout that is partially rolled out. It effectively reverses current and next and runs a rollout
|
||||
|
||||
.PP
|
||||
\fB\-\-schema\-cache\-dir\fP="/tmp/kubectl.schema"
|
||||
If non\-empty, load/store cached API schemas in this directory, default is '/tmp/kubectl.schema'
|
||||
\fB\-\-schema\-cache\-dir\fP="\~/.kube/schema"
|
||||
If non\-empty, load/store cached API schemas in this directory, default is '$HOME/.kube/schema'
|
||||
|
||||
.PP
|
||||
\fB\-a\fP, \fB\-\-show\-all\fP=false
|
||||
|
|
|
@ -61,7 +61,7 @@ $ cat pod.json | kubectl create -f -
|
|||
```
|
||||
-f, --filename=[]: Filename, directory, or URL to file to use to create the resource
|
||||
-o, --output="": Output mode. Use "-o name" for shorter output (resource/name).
|
||||
--schema-cache-dir="/tmp/kubectl.schema": If non-empty, load/store cached API schemas in this directory, default is '/tmp/kubectl.schema'
|
||||
--schema-cache-dir="~/.kube/schema": If non-empty, load/store cached API schemas in this directory, default is '$HOME/.kube/schema'
|
||||
--validate[=true]: If true, use a schema to validate the input before sending it
|
||||
```
|
||||
|
||||
|
@ -97,7 +97,7 @@ $ cat pod.json | kubectl create -f -
|
|||
|
||||
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
||||
|
||||
###### Auto generated by spf13/cobra at 2015-09-11 20:48:33.289761103 +0000 UTC
|
||||
###### Auto generated by spf13/cobra at 2015-09-17 21:39:48.399116592 +0000 UTC
|
||||
|
||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_create.md?pixel)]()
|
||||
|
|
|
@ -74,7 +74,7 @@ kubectl replace --force -f ./pod.json
|
|||
--force[=false]: Delete and re-create the specified resource
|
||||
--grace-period=-1: Only relevant during a force replace. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative.
|
||||
-o, --output="": Output mode. Use "-o name" for shorter output (resource/name).
|
||||
--schema-cache-dir="/tmp/kubectl.schema": If non-empty, load/store cached API schemas in this directory, default is '/tmp/kubectl.schema'
|
||||
--schema-cache-dir="~/.kube/schema": If non-empty, load/store cached API schemas in this directory, default is '$HOME/.kube/schema'
|
||||
--timeout=0: Only relevant during a force replace. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object
|
||||
--validate[=true]: If true, use a schema to validate the input before sending it
|
||||
```
|
||||
|
@ -111,7 +111,7 @@ kubectl replace --force -f ./pod.json
|
|||
|
||||
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
||||
|
||||
###### Auto generated by spf13/cobra at 2015-09-11 20:48:33.290279625 +0000 UTC
|
||||
###### Auto generated by spf13/cobra at 2015-09-17 21:39:48.399461456 +0000 UTC
|
||||
|
||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_replace.md?pixel)]()
|
||||
|
|
|
@ -78,7 +78,7 @@ $ kubectl rolling-update frontend --image=image:v2
|
|||
--output-version="": Output the formatted object with the given version (default api-version).
|
||||
--poll-interval=3s: Time delay between polling for replication controller status after the update. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
--rollback[=false]: If true, this is a request to abort an existing rollout that is partially rolled out. It effectively reverses current and next and runs a rollout
|
||||
--schema-cache-dir="/tmp/kubectl.schema": If non-empty, load/store cached API schemas in this directory, default is '/tmp/kubectl.schema'
|
||||
--schema-cache-dir="~/.kube/schema": If non-empty, load/store cached API schemas in this directory, default is '$HOME/.kube/schema'
|
||||
-a, --show-all[=false]: When printing, show all resources (default hide terminated pods.)
|
||||
--sort-by="": If non-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. 'ObjectMeta.Name'). The field in the API resource specified by this JSONPath expression must be an integer or a string.
|
||||
--template="": Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
|
||||
|
@ -119,7 +119,7 @@ $ kubectl rolling-update frontend --image=image:v2
|
|||
|
||||
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
||||
|
||||
###### Auto generated by spf13/cobra at 2015-09-11 20:48:33.293748592 +0000 UTC
|
||||
###### Auto generated by spf13/cobra at 2015-09-17 21:39:48.40113721 +0000 UTC
|
||||
|
||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_rolling-update.md?pixel)]()
|
||||
|
|
|
@ -36,11 +36,14 @@ import (
|
|||
const (
|
||||
RecommendedConfigPathFlag = "kubeconfig"
|
||||
RecommendedConfigPathEnvVar = "KUBECONFIG"
|
||||
RecommendedHomeFileName = "/.kube/config"
|
||||
RecommendedHomeDir = ".kube"
|
||||
RecommendedFileName = "config"
|
||||
RecommendedSchemaName = "schema"
|
||||
)
|
||||
|
||||
var OldRecommendedHomeFile = path.Join(os.Getenv("HOME"), "/.kube/.kubeconfig")
|
||||
var RecommendedHomeFile = path.Join(os.Getenv("HOME"), RecommendedHomeFileName)
|
||||
var RecommendedHomeFile = path.Join(os.Getenv("HOME"), RecommendedHomeDir, RecommendedFileName)
|
||||
var RecommendedSchemaFile = path.Join(os.Getenv("HOME"), RecommendedHomeDir, RecommendedSchemaName)
|
||||
|
||||
// ClientConfigLoadingRules is an ExplicitPath and string slice of specific locations that are used for merging together a Config
|
||||
// Callers can put the chain together however they want, but we'd recommend:
|
||||
|
|
|
@ -100,7 +100,7 @@ func NewDefaultPathOptions() *PathOptions {
|
|||
EnvVar: clientcmd.RecommendedConfigPathEnvVar,
|
||||
ExplicitFileFlag: clientcmd.RecommendedConfigPathFlag,
|
||||
|
||||
GlobalFileSubpath: clientcmd.RecommendedHomeFileName,
|
||||
GlobalFileSubpath: path.Join(clientcmd.RecommendedHomeDir, clientcmd.RecommendedFileName),
|
||||
|
||||
LoadingRules: clientcmd.NewDefaultClientConfigLoadingRules(),
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
|
@ -308,9 +309,63 @@ type schemaClient interface {
|
|||
Get() *client.Request
|
||||
}
|
||||
|
||||
func recursiveSplit(dir string) []string {
|
||||
parent, file := path.Split(dir)
|
||||
if len(parent) == 0 {
|
||||
return []string{file}
|
||||
}
|
||||
return append(recursiveSplit(parent[:len(parent)-1]), file)
|
||||
}
|
||||
|
||||
func substituteUserHome(dir string) (string, error) {
|
||||
if len(dir) == 0 || dir[0] != '~' {
|
||||
return dir, nil
|
||||
}
|
||||
parts := recursiveSplit(dir)
|
||||
if len(parts[0]) == 1 {
|
||||
parts[0] = os.Getenv("HOME")
|
||||
} else {
|
||||
usr, err := user.Lookup(parts[0][1:])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
parts[0] = usr.HomeDir
|
||||
}
|
||||
return path.Join(parts...), nil
|
||||
}
|
||||
|
||||
func writeSchemaFile(schemaData []byte, cacheDir, cacheFile, prefix, groupVersion string) error {
|
||||
if err := os.MkdirAll(path.Join(cacheDir, prefix, groupVersion), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
tmpFile, err := ioutil.TempFile(cacheDir, "schema")
|
||||
if err != nil {
|
||||
// If we can't write, keep going.
|
||||
if os.IsPermission(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(tmpFile, bytes.NewBuffer(schemaData)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Link(tmpFile.Name(), cacheFile); err != nil {
|
||||
// If we can't write due to file existing, or permission problems, keep going.
|
||||
if os.IsExist(err) || os.IsPermission(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cacheDir string) (err error) {
|
||||
var schemaData []byte
|
||||
cacheFile := path.Join(cacheDir, prefix, groupVersion, schemaFileName)
|
||||
fullDir, err := substituteUserHome(cacheDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cacheFile := path.Join(fullDir, prefix, groupVersion, schemaFileName)
|
||||
|
||||
if len(cacheDir) != 0 {
|
||||
if schemaData, err = ioutil.ReadFile(cacheFile); err != nil && !os.IsNotExist(err) {
|
||||
|
@ -326,17 +381,7 @@ func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cac
|
|||
return err
|
||||
}
|
||||
if len(cacheDir) != 0 {
|
||||
if err = os.MkdirAll(path.Join(cacheDir, prefix, groupVersion), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
tmpFile, err := ioutil.TempFile(cacheDir, "schema")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(tmpFile, bytes.NewBuffer(schemaData)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Link(tmpFile.Name(), cacheFile); err != nil && !os.IsExist(err) {
|
||||
if err := writeSchemaFile(schemaData, fullDir, cacheFile, prefix, groupVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
@ -302,3 +303,32 @@ func TestValidateCachesSchema(t *testing.T) {
|
|||
t.Errorf("unexpected cache file error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubstitueUser(t *testing.T) {
|
||||
usr, _ := user.Current()
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
expectErr bool
|
||||
}{
|
||||
{input: "~/foo", expected: path.Join(os.Getenv("HOME"), "foo")},
|
||||
{input: "~" + usr.Username + "/bar", expected: usr.HomeDir + "/bar"},
|
||||
{input: "/foo/bar", expected: "/foo/bar"},
|
||||
{input: "~doesntexit/bar", expectErr: true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
output, err := substituteUserHome(test.input)
|
||||
if test.expectErr {
|
||||
if err == nil {
|
||||
t.Error("unexpected non-error")
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if output != test.expected {
|
||||
t.Errorf("expected: %s, saw: %s", test.expected, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -279,7 +279,7 @@ func GetFlagDuration(cmd *cobra.Command, flag string) time.Duration {
|
|||
|
||||
func AddValidateFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("validate", true, "If true, use a schema to validate the input before sending it")
|
||||
cmd.Flags().String("schema-cache-dir", "/tmp/kubectl.schema", "If non-empty, load/store cached API schemas in this directory, default is '/tmp/kubectl.schema'")
|
||||
cmd.Flags().String("schema-cache-dir", fmt.Sprintf("~/%s/%s", clientcmd.RecommendedHomeDir, clientcmd.RecommendedSchemaName), fmt.Sprintf("If non-empty, load/store cached API schemas in this directory, default is '$HOME/%s/%s'", clientcmd.RecommendedHomeDir, clientcmd.RecommendedSchemaName))
|
||||
}
|
||||
|
||||
func ReadConfigDataFromReader(reader io.Reader, source string) ([]byte, error) {
|
||||
|
|
Loading…
Reference in New Issue