mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 17:12:51 +00:00
Merge pull request #1724 from monopole/removeErrorFromConstructor
Improve error messaging around plugin loading problems.
This commit is contained in:
@@ -28,11 +28,6 @@ type Kustomizer struct {
|
|||||||
options *Options
|
options *Options
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeDefaultKustomizer returns a Kustomizer with default configuration.
|
|
||||||
func MakeDefaultKustomizer() *Kustomizer {
|
|
||||||
return MakeKustomizer(filesys.MakeFsOnDisk(), MakeDefaultOptions())
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeKustomizer returns an instance of Kustomizer.
|
// MakeKustomizer returns an instance of Kustomizer.
|
||||||
func MakeKustomizer(fSys filesys.FileSystem, o *Options) *Kustomizer {
|
func MakeKustomizer(fSys filesys.FileSystem, o *Options) *Kustomizer {
|
||||||
return &Kustomizer{fSys: fSys, options: o}
|
return &Kustomizer{fSys: fSys, options: o}
|
||||||
|
|||||||
@@ -35,6 +35,6 @@ func MakeDefaultOptions() *Options {
|
|||||||
DoLegacyResourceSort: true,
|
DoLegacyResourceSort: true,
|
||||||
LoadRestrictions: types.LoadRestrictionsRootOnly,
|
LoadRestrictions: types.LoadRestrictionsRootOnly,
|
||||||
DoPrune: false,
|
DoPrune: false,
|
||||||
PluginConfig: pgmconfig.DefaultPluginConfig(),
|
PluginConfig: pgmconfig.DisabledPluginConfig(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,19 +36,27 @@ const (
|
|||||||
DomainName = "sigs.k8s.io"
|
DomainName = "sigs.k8s.io"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ActivePluginConfig() *types.PluginConfig {
|
func EnabledPluginConfig() *types.PluginConfig {
|
||||||
pc := DefaultPluginConfig()
|
return MakePluginConfig(
|
||||||
pc.PluginRestrictions = types.PluginRestrictionsNone
|
types.PluginRestrictionsNone, DefaultAbsPluginHome())
|
||||||
return pc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultPluginConfig() *types.PluginConfig {
|
func DisabledPluginConfig() *types.PluginConfig {
|
||||||
|
return MakePluginConfig(
|
||||||
|
types.PluginRestrictionsBuiltinsOnly, NoPluginHomeSentinal)
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakePluginConfig(
|
||||||
|
pr types.PluginRestrictions, home string) *types.PluginConfig {
|
||||||
return &types.PluginConfig{
|
return &types.PluginConfig{
|
||||||
PluginRestrictions: types.PluginRestrictionsBuiltinsOnly,
|
PluginRestrictions: pr,
|
||||||
AbsPluginHome: DefaultAbsPluginHome(),
|
AbsPluginHome: home,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use an obviously erroneous path, in case it's accidentally used.
|
||||||
|
const NoPluginHomeSentinal = "/no/non-builtin/plugins!"
|
||||||
|
|
||||||
func DefaultAbsPluginHome() string {
|
func DefaultAbsPluginHome() string {
|
||||||
return filepath.Join(configRoot(), RelPluginHome)
|
return filepath.Join(configRoot(), RelPluginHome)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func DefaultSrcRoot() (string, error) {
|
|||||||
}
|
}
|
||||||
nope = append(nope, root)
|
nope = append(nope, root)
|
||||||
|
|
||||||
root = pgmconfig.DefaultPluginConfig().AbsPluginHome
|
root = pgmconfig.DefaultAbsPluginHome()
|
||||||
if FileExists(root) {
|
if FileExists(root) {
|
||||||
return root, nil
|
return root, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,15 +44,19 @@ type ExecPlugin struct {
|
|||||||
h *resmap.PluginHelpers
|
h *resmap.PluginHelpers
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewExecPlugin(p string) (*ExecPlugin, error) {
|
func NewExecPlugin(p string) *ExecPlugin {
|
||||||
f, err := os.Stat(p)
|
return &ExecPlugin{path: p}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ExecPlugin) ErrIfNotExecutable() error {
|
||||||
|
f, err := os.Stat(p.path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if f.Mode()&0111 == 0000 {
|
if f.Mode()&0111 == 0000 {
|
||||||
return nil, fmt.Errorf("unable to execute plugin on path: %s", p)
|
return fmt.Errorf("unexecutable plugin at: %s", p.path)
|
||||||
}
|
}
|
||||||
return &ExecPlugin{path: p}, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ExecPlugin) Path() string {
|
func (p *ExecPlugin) Path() string {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ package execplugin_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -44,13 +43,15 @@ s/$BAR/bar/g
|
|||||||
\ \ \
|
\ \ \
|
||||||
`))
|
`))
|
||||||
|
|
||||||
p, err := NewExecPlugin(
|
p := NewExecPlugin(
|
||||||
loader.AbsolutePluginPath(
|
loader.AbsolutePluginPath(
|
||||||
pgmconfig.DefaultPluginConfig(),
|
pgmconfig.DisabledPluginConfig(),
|
||||||
pluginConfig.OrgId()))
|
pluginConfig.OrgId()))
|
||||||
if err != nil {
|
// Not checking to see if the plugin is executable,
|
||||||
t.Fatalf("unexpected error: %v", err.Error())
|
// because this test does not run it.
|
||||||
}
|
// This tests only covers sending configuration
|
||||||
|
// to the plugin wrapper object and confirming
|
||||||
|
// that it's properly prepared for execution.
|
||||||
|
|
||||||
yaml, err := pluginConfig.AsYAML()
|
yaml, err := pluginConfig.AsYAML()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -58,7 +59,7 @@ s/$BAR/bar/g
|
|||||||
}
|
}
|
||||||
p.Config(resmap.NewPluginHelpers(ldr, v, rf), yaml)
|
p.Config(resmap.NewPluginHelpers(ldr, v, rf), yaml)
|
||||||
|
|
||||||
expected := "/kustomize/plugin/someteam.example.com/v1/sedtransformer/SedTransformer"
|
expected := "someteam.example.com/v1/sedtransformer/SedTransformer"
|
||||||
if !strings.HasSuffix(p.Path(), expected) {
|
if !strings.HasSuffix(p.Path(), expected) {
|
||||||
t.Fatalf("expected suffix '%s', got '%s'", expected, p.Path())
|
t.Fatalf("expected suffix '%s', got '%s'", expected, p.Path())
|
||||||
}
|
}
|
||||||
@@ -118,9 +119,9 @@ func strptr(s string) *string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateResourceOptions(t *testing.T) {
|
func TestUpdateResourceOptions(t *testing.T) {
|
||||||
p, err := NewExecPlugin("")
|
p := NewExecPlugin("")
|
||||||
if !os.IsNotExist(err) {
|
if err := p.ErrIfNotExecutable(); err == nil {
|
||||||
t.Fatalf("unexpected error: %v", err.Error())
|
t.Fatalf("expected unexecutable error")
|
||||||
}
|
}
|
||||||
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
|
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
|
||||||
in := resmap.New()
|
in := resmap.New()
|
||||||
@@ -166,9 +167,9 @@ func TestUpdateResourceOptions(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateResourceOptionsWithInvalidHashAnnotationValues(t *testing.T) {
|
func TestUpdateResourceOptionsWithInvalidHashAnnotationValues(t *testing.T) {
|
||||||
p, err := NewExecPlugin("")
|
p := NewExecPlugin("")
|
||||||
if !os.IsNotExist(err) {
|
if err := p.ErrIfNotExecutable(); err == nil {
|
||||||
t.Fatalf("unexpected error: %v", err.Error())
|
t.Fatalf("expected unexecutable error")
|
||||||
}
|
}
|
||||||
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
|
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
|
||||||
cases := []string{
|
cases := []string{
|
||||||
|
|||||||
@@ -146,13 +146,23 @@ func (l *Loader) makeBuiltinPlugin(r resid.Gvk) (resmap.Configurable, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *Loader) loadPlugin(resId resid.ResId) (resmap.Configurable, error) {
|
func (l *Loader) loadPlugin(resId resid.ResId) (resmap.Configurable, error) {
|
||||||
p, err := execplugin.NewExecPlugin(l.absolutePluginPath(resId))
|
// First try to load the plugin as an executable.
|
||||||
|
p := execplugin.NewExecPlugin(l.absolutePluginPath(resId))
|
||||||
|
err := p.ErrIfNotExecutable()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
if !os.IsNotExist(err) {
|
if !os.IsNotExist(err) {
|
||||||
|
// The file exists, but something else is wrong,
|
||||||
|
// likely it's not executable.
|
||||||
|
// Assume the user forgot to set the exec bit,
|
||||||
|
// and return an error, rather than adding ".so"
|
||||||
|
// to the name and attempting to load it as a Go
|
||||||
|
// plugin, which will likely fail and result
|
||||||
|
// in an obscure message.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// Failing the above, try loading it as a Go plugin.
|
||||||
c, err := l.loadGoPlugin(resId)
|
c, err := l.loadGoPlugin(resId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -186,7 +196,7 @@ func (l *Loader) loadGoPlugin(id resid.ResId) (resmap.Configurable, error) {
|
|||||||
}
|
}
|
||||||
c, ok := symbol.(resmap.Configurable)
|
c, ok := symbol.(resmap.Configurable)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("plugin %s not configurable", regId)
|
return nil, fmt.Errorf("plugin '%s' not configurable", regId)
|
||||||
}
|
}
|
||||||
registry[regId] = c
|
registry[regId] = c
|
||||||
return copyPlugin(c), nil
|
return copyPlugin(c), nil
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func TestLoader(t *testing.T) {
|
|||||||
|
|
||||||
ldr := loadertest.NewFakeLoader("/foo")
|
ldr := loadertest.NewFakeLoader("/foo")
|
||||||
|
|
||||||
pLdr := NewLoader(pgmconfig.ActivePluginConfig(), rmF)
|
pLdr := NewLoader(pgmconfig.EnabledPluginConfig(), rmF)
|
||||||
if pLdr == nil {
|
if pLdr == nil {
|
||||||
t.Fatal("expect non-nil loader")
|
t.Fatal("expect non-nil loader")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ spec:
|
|||||||
func TestSharedPatchDisAllowed(t *testing.T) {
|
func TestSharedPatchDisAllowed(t *testing.T) {
|
||||||
th := kusttest_test.NewKustTestHarnessFull(
|
th := kusttest_test.NewKustTestHarnessFull(
|
||||||
t, "/app/overlay",
|
t, "/app/overlay",
|
||||||
loader.RestrictionRootOnly, pgmconfig.DefaultPluginConfig())
|
loader.RestrictionRootOnly, pgmconfig.DisabledPluginConfig())
|
||||||
writeSmallBase(th)
|
writeSmallBase(th)
|
||||||
th.WriteK("/app/overlay", `
|
th.WriteK("/app/overlay", `
|
||||||
commonLabels:
|
commonLabels:
|
||||||
@@ -332,7 +332,7 @@ spec:
|
|||||||
func TestSharedPatchAllowed(t *testing.T) {
|
func TestSharedPatchAllowed(t *testing.T) {
|
||||||
th := kusttest_test.NewKustTestHarnessFull(
|
th := kusttest_test.NewKustTestHarnessFull(
|
||||||
t, "/app/overlay",
|
t, "/app/overlay",
|
||||||
loader.RestrictionNone, pgmconfig.DefaultPluginConfig())
|
loader.RestrictionNone, pgmconfig.DisabledPluginConfig())
|
||||||
writeSmallBase(th)
|
writeSmallBase(th)
|
||||||
th.WriteK("/app/overlay", `
|
th.WriteK("/app/overlay", `
|
||||||
commonLabels:
|
commonLabels:
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ metadata:
|
|||||||
rf := resmap.NewFactory(resource.NewFactory(
|
rf := resmap.NewFactory(resource.NewFactory(
|
||||||
kunstruct.NewKunstructuredFactoryImpl()), nil)
|
kunstruct.NewKunstructuredFactoryImpl()), nil)
|
||||||
|
|
||||||
pl := pLdr.NewLoader(pgmconfig.ActivePluginConfig(), rf)
|
pl := pLdr.NewLoader(pgmconfig.EnabledPluginConfig(), rf)
|
||||||
tg, err := target.NewKustTarget(
|
tg, err := target.NewKustTarget(
|
||||||
ldr, valtest_test.MakeFakeValidator(), rf, transformer.NewFactoryImpl(), pl)
|
ldr, valtest_test.MakeFakeValidator(), rf, transformer.NewFactoryImpl(), pl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -36,17 +36,17 @@ type KustTestHarness struct {
|
|||||||
|
|
||||||
func NewKustTestHarness(t *testing.T, path string) *KustTestHarness {
|
func NewKustTestHarness(t *testing.T, path string) *KustTestHarness {
|
||||||
return NewKustTestHarnessFull(
|
return NewKustTestHarnessFull(
|
||||||
t, path, fLdr.RestrictionRootOnly, pgmconfig.DefaultPluginConfig())
|
t, path, fLdr.RestrictionRootOnly, pgmconfig.DisabledPluginConfig())
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKustTestHarnessAllowPlugins(t *testing.T, path string) *KustTestHarness {
|
func NewKustTestHarnessAllowPlugins(t *testing.T, path string) *KustTestHarness {
|
||||||
return NewKustTestHarnessFull(
|
return NewKustTestHarnessFull(
|
||||||
t, path, fLdr.RestrictionRootOnly, pgmconfig.ActivePluginConfig())
|
t, path, fLdr.RestrictionRootOnly, pgmconfig.EnabledPluginConfig())
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKustTestHarnessNoLoadRestrictor(t *testing.T, path string) *KustTestHarness {
|
func NewKustTestHarnessNoLoadRestrictor(t *testing.T, path string) *KustTestHarness {
|
||||||
return NewKustTestHarnessFull(
|
return NewKustTestHarnessFull(
|
||||||
t, path, fLdr.RestrictionNone, pgmconfig.DefaultPluginConfig())
|
t, path, fLdr.RestrictionNone, pgmconfig.DisabledPluginConfig())
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKustTestHarnessFull(
|
func NewKustTestHarnessFull(
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import (
|
|||||||
"sigs.k8s.io/kustomize/api/pgmconfig"
|
"sigs.k8s.io/kustomize/api/pgmconfig"
|
||||||
"sigs.k8s.io/kustomize/api/resmap"
|
"sigs.k8s.io/kustomize/api/resmap"
|
||||||
"sigs.k8s.io/kustomize/api/resource"
|
"sigs.k8s.io/kustomize/api/resource"
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -103,12 +102,15 @@ func (o *Options) Validate(args []string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *Options) makeOptions() *krusty.Options {
|
func (o *Options) makeOptions() *krusty.Options {
|
||||||
opts := krusty.MakeDefaultOptions()
|
opts := &krusty.Options{
|
||||||
opts.LoadRestrictions = getFlagLoadRestrictorValue()
|
DoLegacyResourceSort: o.outOrder == legacy,
|
||||||
opts.DoLegacyResourceSort = o.outOrder == legacy
|
LoadRestrictions: getFlagLoadRestrictorValue(),
|
||||||
opts.PluginConfig.PluginRestrictions = types.PluginRestrictionsBuiltinsOnly
|
DoPrune: false,
|
||||||
|
}
|
||||||
if isFlagEnablePluginsSet() {
|
if isFlagEnablePluginsSet() {
|
||||||
opts.PluginConfig.PluginRestrictions = types.PluginRestrictionsNone
|
opts.PluginConfig = pgmconfig.EnabledPluginConfig()
|
||||||
|
} else {
|
||||||
|
opts.PluginConfig = pgmconfig.DisabledPluginConfig()
|
||||||
}
|
}
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user