mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-30 09:51:23 +00:00
One plugin per dir.
This commit is contained in:
@@ -21,6 +21,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"sigs.k8s.io/kustomize/k8sdeps/kv/plugin"
|
||||
@@ -95,7 +96,8 @@ func goBin() string {
|
||||
// Compile reads ${srcRoot}/${g}/${v}/${k}.go
|
||||
// and writes ${objRoot}/${g}/${v}/${k}.so
|
||||
func (b *Compiler) Compile(g, v, k string) error {
|
||||
objDir := filepath.Join(b.objRoot, g, v)
|
||||
lowK := strings.ToLower(k)
|
||||
objDir := filepath.Join(b.objRoot, g, v, lowK)
|
||||
objFile := filepath.Join(objDir, k) + ".so"
|
||||
if RecentFileExists(objFile) {
|
||||
// Skip rebuilding it.
|
||||
@@ -105,7 +107,7 @@ func (b *Compiler) Compile(g, v, k string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
srcFile := filepath.Join(b.srcRoot, g, v, k) + ".go"
|
||||
srcFile := filepath.Join(b.srcRoot, g, v, lowK, k) + ".go"
|
||||
if !FileExists(srcFile) {
|
||||
return fmt.Errorf(
|
||||
"cannot find source %s", srcFile)
|
||||
@@ -114,7 +116,6 @@ func (b *Compiler) Compile(g, v, k string) error {
|
||||
"build",
|
||||
"-buildmode",
|
||||
"plugin",
|
||||
"-tags=plugin",
|
||||
"-o", objFile, srcFile,
|
||||
}
|
||||
goBin := goBin()
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestCompiler(t *testing.T) {
|
||||
|
||||
expectObj := filepath.Join(
|
||||
c.ObjRoot(),
|
||||
"someteam.example.com", "v1", "DatePrefixer.so")
|
||||
"someteam.example.com", "v1", "dateprefixer", "DatePrefixer.so")
|
||||
if FileExists(expectObj) {
|
||||
t.Errorf("obj file should not exist yet: %s", expectObj)
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func TestCompiler(t *testing.T) {
|
||||
|
||||
expectObj = filepath.Join(
|
||||
c.ObjRoot(),
|
||||
"builtin", "", "SecretGenerator.so")
|
||||
"builtin", "", "secretgenerator", "SecretGenerator.so")
|
||||
if FileExists(expectObj) {
|
||||
t.Errorf("obj file should not exist yet: %s", expectObj)
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
@@ -39,8 +38,8 @@ const (
|
||||
// ExecPlugin record the name and args of an executable
|
||||
// It triggers the executable generator and transformer
|
||||
type ExecPlugin struct {
|
||||
// name of the executable
|
||||
name string
|
||||
// absolute path of the executable
|
||||
path string
|
||||
|
||||
// Optional command line arguments to the executable
|
||||
// pulled from specially named fields in cfg.
|
||||
@@ -57,15 +56,13 @@ type ExecPlugin struct {
|
||||
ldr ifc.Loader
|
||||
}
|
||||
|
||||
func NewExecPlugin(root string, id resid.ResId) *ExecPlugin {
|
||||
return &ExecPlugin{
|
||||
name: filepath.Join(root, pluginPath(id)),
|
||||
}
|
||||
func NewExecPlugin(p string) *ExecPlugin {
|
||||
return &ExecPlugin{path: p}
|
||||
}
|
||||
|
||||
// isAvailable checks to see if the plugin is available
|
||||
func (p *ExecPlugin) isAvailable() bool {
|
||||
f, err := os.Stat(p.name)
|
||||
f, err := os.Stat(p.path)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
@@ -164,7 +161,7 @@ func (p *ExecPlugin) invokePlugin(input []byte) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd := exec.Command(p.name, args...)
|
||||
cmd := exec.Command(p.path, args...)
|
||||
cmd.Env = p.getEnv()
|
||||
cmd.Stdin = bytes.NewReader(input)
|
||||
cmd.Stderr = os.Stderr
|
||||
@@ -226,7 +223,7 @@ func (p *ExecPlugin) updateResMapValues(output []byte, rm resmap.ResMap) error {
|
||||
idString, ok := annotations[idAnnotation]
|
||||
if !ok {
|
||||
return fmt.Errorf("the transformer %s should not remove annotation %s",
|
||||
p.name, idAnnotation)
|
||||
p.path, idAnnotation)
|
||||
}
|
||||
id := resid.ResId{}
|
||||
err := yaml.Unmarshal([]byte(idString), &id)
|
||||
|
||||
@@ -51,8 +51,9 @@ s/$BAR/bar/g
|
||||
`))
|
||||
|
||||
p := NewExecPlugin(
|
||||
plugin.DefaultPluginConfig().DirectoryPath,
|
||||
pluginConfig.Id())
|
||||
AbsolutePluginPath(
|
||||
plugin.DefaultPluginConfig(),
|
||||
pluginConfig.Id()))
|
||||
|
||||
yaml, err := pluginConfig.AsYAML()
|
||||
if err != nil {
|
||||
@@ -60,9 +61,9 @@ s/$BAR/bar/g
|
||||
}
|
||||
p.Config(ldr, rf, yaml)
|
||||
|
||||
expected := "/kustomize/plugin/someteam.example.com/v1/SedTransformer"
|
||||
if !strings.HasSuffix(p.name, expected) {
|
||||
t.Fatalf("expected suffix '%s', got '%s'", expected, p.name)
|
||||
expected := "/kustomize/plugin/someteam.example.com/v1/sedtransformer/SedTransformer"
|
||||
if !strings.HasSuffix(p.path, expected) {
|
||||
t.Fatalf("expected suffix '%s', got '%s'", expected, p.path)
|
||||
}
|
||||
|
||||
expected = `apiVersion: someteam.example.com/v1
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"plugin"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/kustomize/pkg/ifc"
|
||||
@@ -96,8 +97,20 @@ func (l *Loader) LoadTransformer(
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func pluginPath(id resid.ResId) string {
|
||||
return filepath.Join(id.Gvk().Group, id.Gvk().Version, id.Gvk().Kind)
|
||||
func relativePluginPath(id resid.ResId) string {
|
||||
return filepath.Join(
|
||||
id.Gvk().Group,
|
||||
id.Gvk().Version,
|
||||
strings.ToLower(id.Gvk().Kind))
|
||||
}
|
||||
|
||||
func AbsolutePluginPath(pc *types.PluginConfig, id resid.ResId) string {
|
||||
return filepath.Join(
|
||||
pc.DirectoryPath, relativePluginPath(id), id.Gvk().Kind)
|
||||
}
|
||||
|
||||
func (l *Loader) absolutePluginPath(id resid.ResId) string {
|
||||
return AbsolutePluginPath(l.pc, id)
|
||||
}
|
||||
|
||||
func (l *Loader) loadAndConfigurePlugin(
|
||||
@@ -106,7 +119,8 @@ func (l *Loader) loadAndConfigurePlugin(
|
||||
return nil, errors.Errorf(
|
||||
"plugins not enabled, but trying to load %s", res.Id())
|
||||
}
|
||||
if p := NewExecPlugin(l.pc.DirectoryPath, res.Id()); p.isAvailable() {
|
||||
if p := NewExecPlugin(
|
||||
l.absolutePluginPath(res.Id())); p.isAvailable() {
|
||||
c = p
|
||||
} else {
|
||||
c, err = l.loadGoPlugin(res.Id())
|
||||
@@ -135,26 +149,26 @@ func (l *Loader) loadAndConfigurePlugin(
|
||||
var registry = make(map[string]Configurable)
|
||||
|
||||
func (l *Loader) loadGoPlugin(id resid.ResId) (c Configurable, err error) {
|
||||
regId := relativePluginPath(id)
|
||||
var ok bool
|
||||
path := pluginPath(id)
|
||||
if c, ok = registry[path]; ok {
|
||||
if c, ok = registry[regId]; ok {
|
||||
return c, nil
|
||||
}
|
||||
name := filepath.Join(l.pc.DirectoryPath, path)
|
||||
p, err := plugin.Open(name + ".so")
|
||||
absPath := l.absolutePluginPath(id)
|
||||
p, err := plugin.Open(absPath + ".so")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "plugin %s fails to load", name)
|
||||
return nil, errors.Wrapf(err, "plugin %s fails to load", absPath)
|
||||
}
|
||||
symbol, err := p.Lookup(PluginSymbol)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(
|
||||
err, "plugin %s doesn't have symbol %s",
|
||||
name, PluginSymbol)
|
||||
regId, PluginSymbol)
|
||||
}
|
||||
c, ok = symbol.(Configurable)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("plugin %s not configurable", name)
|
||||
return nil, fmt.Errorf("plugin %s not configurable", regId)
|
||||
}
|
||||
registry[path] = c
|
||||
registry[regId] = c
|
||||
return
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ port: "12345"
|
||||
)
|
||||
|
||||
func TestLoader(t *testing.T) {
|
||||
tc := plugin.NewPluginTestEnv(t).Set()
|
||||
tc := plugin.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
tc.BuildGoPlugin(
|
||||
|
||||
Reference in New Issue
Block a user