1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package konfig
import (
"os"
"path/filepath"
"runtime"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
const (
// Symbol that must be used inside Go plugins.
PluginSymbol = "KustomizePlugin"
// Name of environment variable used to set AbsPluginHome.
// See that variable for an explanation.
KustomizePluginHomeEnv = "KUSTOMIZE_PLUGIN_HOME"
// Relative path below XDG_CONFIG_HOME/kustomize to find plugins.
// e.g. AbsPluginHome = XDG_CONFIG_HOME/kustomize/plugin
RelPluginHome = "plugin"
// Location of builtin plugins below AbsPluginHome.
BuiltinPluginPackage = "builtin"
// The value of kubernetes ApiVersion to use in configuration
// files for builtin plugins.
// The value for non-builtins can be anything.
BuiltinPluginApiVersion = BuiltinPluginPackage
// Domain from which kustomize code is imported, for locating
// plugin source code under $GOPATH when GOPATH is defined.
DomainName = "sigs.k8s.io"
// Injected into plugin paths when plugins are disabled.
// Provides a clue in flows that shouldn't happen.
NoPluginHomeSentinal = "/No/non-builtin/plugins!"
)
type NotedFunc struct {
Note string
F func() string
}
// DefaultAbsPluginHome returns the absolute path in the given file
// system to first directory that looks like a good candidate for
// the home of kustomize plugins.
func DefaultAbsPluginHome(fSys filesys.FileSystem) (string, error) {
return FirstDirThatExistsElseError(
"plugin root", fSys, []NotedFunc{
{
Note: "homed in $" + KustomizePluginHomeEnv,
F: func() string {
return os.Getenv(KustomizePluginHomeEnv)
},
},
{
Note: "homed in $" + XdgConfigHomeEnv,
F: func() string {
if root := os.Getenv(XdgConfigHomeEnv); root != "" {
return filepath.Join(root, ProgramName, RelPluginHome)
}
// do not look in "kustomize/plugin" if XdgConfigHomeEnv is unset
return ""
},
},
{
Note: "homed in default value of $" + XdgConfigHomeEnv,
F: func() string {
return filepath.Join(
HomeDir(), XdgConfigHomeEnvDefault,
ProgramName, RelPluginHome)
},
},
{
Note: "homed in home directory",
F: func() string {
return filepath.Join(
HomeDir(), ProgramName, RelPluginHome)
},
},
})
}
// FirstDirThatExistsElseError tests different path functions for
// existence, returning the first that works, else error if all fail.
func FirstDirThatExistsElseError(
what string,
fSys filesys.FileSystem,
pathFuncs []NotedFunc) (string, error) {
var nope []types.Pair
for _, dt := range pathFuncs {
if dir := dt.F(); dir != "" {
if fSys.Exists(dir) {
return dir, nil
}
nope = append(nope, types.Pair{Key: dt.Note, Value: dir})
} else {
nope = append(nope, types.Pair{Key: dt.Note, Value: "<no value>"})
}
}
return "", types.NewErrUnableToFind(what, nope)
}
func HomeDir() string {
home := os.Getenv(homeEnv())
if len(home) > 0 {
return home
}
return "~"
}
func homeEnv() string {
if runtime.GOOS == "windows" {
return "USERPROFILE"
}
return "HOME"
}
func CurrentWorkingDir() string {
// Try for full path first to be explicit.
pwd := os.Getenv(pwdEnv())
if len(pwd) > 0 {
return pwd
}
return filesys.SelfDir
}
func pwdEnv() string {
if runtime.GOOS == "windows" {
return "CD"
}
return "PWD"
}
|