Move the default schema cache to the home directory

This commit is contained in:
Brendan Burns
2015-09-16 16:31:45 -07:00
parent 6a04145362
commit afea127a3e
11 changed files with 106 additions and 28 deletions

View File

@@ -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
}
}

View File

@@ -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)
}
}
}

View File

@@ -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) {