diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index f551e171..786f5b74 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -212,7 +212,7 @@ }, { "ImportPath": "k8s.io/apimachinery", - "Rev": "75ce4d1e60f1" + "Rev": "6171873045ff" }, { "ImportPath": "k8s.io/klog", diff --git a/go.mod b/go.mod index 948a7c05..cae62d0a 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( golang.org/x/time v0.0.0-20161028155119-f51c12702a4d google.golang.org/appengine v1.5.0 // indirect k8s.io/api v0.0.0-20190712022805-31fe033ae6f9 - k8s.io/apimachinery v0.0.0-20190712095106-75ce4d1e60f1 + k8s.io/apimachinery v0.0.0-20190715170309-6171873045ff k8s.io/klog v0.3.1 k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a sigs.k8s.io/yaml v1.1.0 @@ -41,5 +41,5 @@ replace ( golang.org/x/text => golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db golang.org/x/tools => golang.org/x/tools v0.0.0-20190313210603-aa82965741a9 k8s.io/api => k8s.io/api v0.0.0-20190712022805-31fe033ae6f9 - k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190712095106-75ce4d1e60f1 + k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190715170309-6171873045ff ) diff --git a/go.sum b/go.sum index c243f9d2..6c7ecbdb 100644 --- a/go.sum +++ b/go.sum @@ -101,7 +101,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= k8s.io/api v0.0.0-20190712022805-31fe033ae6f9/go.mod h1:quCKyJONbDKoYS6YlndaZ0BUdM1jU4J8fCiC0S2ctLI= -k8s.io/apimachinery v0.0.0-20190712095106-75ce4d1e60f1/go.mod h1:M2fZgZL9DbLfeJaPBCDqSqNsdsmLN+V29knYJnIXlMA= +k8s.io/apimachinery v0.0.0-20190715170309-6171873045ff/go.mod h1:M2fZgZL9DbLfeJaPBCDqSqNsdsmLN+V29knYJnIXlMA= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.1 h1:RVgyDHY/kFKtLqh67NvEWIgkMneNoIrdkN0CxDSQc68= k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= diff --git a/util/homedir/homedir.go b/util/homedir/homedir.go index 816db57f..3fdbeb8c 100644 --- a/util/homedir/homedir.go +++ b/util/homedir/homedir.go @@ -18,30 +18,75 @@ package homedir import ( "os" + "path/filepath" "runtime" ) -// HomeDir returns the home directory for the current user +// HomeDir returns the home directory for the current user. +// On Windows: +// 1. the first of %HOME%, %HOMEDRIVE%%HOMEPATH%, %USERPROFILE% containing a `.kube\config` file is returned. +// 2. if none of those locations contain a `.kube\config` file, the first of %HOME%, %USERPROFILE%, %HOMEDRIVE%%HOMEPATH% that exists and is writeable is returned. +// 3. if none of those locations are writeable, the first of %HOME%, %USERPROFILE%, %HOMEDRIVE%%HOMEPATH% that exists is returned. +// 4. if none of those locations exists, the first of %HOME%, %USERPROFILE%, %HOMEDRIVE%%HOMEPATH% that is set is returned. func HomeDir() string { if runtime.GOOS == "windows" { - - // First prefer the HOME environmental variable - if home := os.Getenv("HOME"); len(home) > 0 { - if _, err := os.Stat(home); err == nil { - return home - } - } + home := os.Getenv("HOME") + homeDriveHomePath := "" if homeDrive, homePath := os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"); len(homeDrive) > 0 && len(homePath) > 0 { - homeDir := homeDrive + homePath - if _, err := os.Stat(homeDir); err == nil { - return homeDir + homeDriveHomePath = homeDrive + homePath + } + userProfile := os.Getenv("USERPROFILE") + + // Return first of %HOME%, %HOMEDRIVE%/%HOMEPATH%, %USERPROFILE% that contains a `.kube\config` file. + // %HOMEDRIVE%/%HOMEPATH% is preferred over %USERPROFILE% for backwards-compatibility. + for _, p := range []string{home, homeDriveHomePath, userProfile} { + if len(p) == 0 { + continue + } + if _, err := os.Stat(filepath.Join(p, ".kube", "config")); err != nil { + continue + } + return p + } + + firstSetPath := "" + firstExistingPath := "" + + // Prefer %USERPROFILE% over %HOMEDRIVE%/%HOMEPATH% for compatibility with other auth-writing tools + for _, p := range []string{home, userProfile, homeDriveHomePath} { + if len(p) == 0 { + continue + } + if len(firstSetPath) == 0 { + // remember the first path that is set + firstSetPath = p + } + info, err := os.Stat(p) + if err != nil { + continue + } + if len(firstExistingPath) == 0 { + // remember the first path that exists + firstExistingPath = p + } + if info.IsDir() && info.Mode().Perm()&(1<<(uint(7))) != 0 { + // return first path that is writeable + return p } } - if userProfile := os.Getenv("USERPROFILE"); len(userProfile) > 0 { - if _, err := os.Stat(userProfile); err == nil { - return userProfile - } + + // If none are writeable, return first location that exists + if len(firstExistingPath) > 0 { + return firstExistingPath } + + // If none exist, return first location that is set + if len(firstSetPath) > 0 { + return firstSetPath + } + + // We've got nothing + return "" } return os.Getenv("HOME") }