mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-13 18:10:59 +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(
|
||||
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
// TODO: Download and inflate the chart, and check that
|
||||
// in for the test.
|
||||
func TestChartInflatorPlugin(t *testing.T) {
|
||||
tc := plugin.NewPluginTestEnv(t).Set()
|
||||
tc := plugin.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
tc.BuildExecPlugin(
|
||||
|
||||
@@ -1,18 +1,5 @@
|
||||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package target
|
||||
|
||||
@@ -23,7 +10,7 @@ import (
|
||||
"sigs.k8s.io/kustomize/pkg/transformers"
|
||||
"sigs.k8s.io/kustomize/pkg/transformers/config"
|
||||
"sigs.k8s.io/kustomize/pkg/types"
|
||||
"sigs.k8s.io/kustomize/plugin/builtingen"
|
||||
"sigs.k8s.io/kustomize/plugin/builtin"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
@@ -104,7 +91,7 @@ func (kt *KustTarget) configureBuiltinSecretGenerator() (
|
||||
}
|
||||
for _, args := range kt.kustomization.SecretGenerator {
|
||||
c.SecretArgs = args
|
||||
p := builtingen.NewSecretGeneratorPlugin()
|
||||
p := builtin.NewSecretGeneratorPlugin()
|
||||
err = kt.configureBuiltinPlugin(p, c, "secret")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -125,7 +112,7 @@ func (kt *KustTarget) configureBuiltinConfigMapGenerator() (
|
||||
}
|
||||
for _, args := range kt.kustomization.ConfigMapGenerator {
|
||||
c.ConfigMapArgs = args
|
||||
p := builtingen.NewConfigMapGeneratorPlugin()
|
||||
p := builtin.NewConfigMapGeneratorPlugin()
|
||||
err = kt.configureBuiltinPlugin(p, c, "configmap")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -146,7 +133,7 @@ func (kt *KustTarget) configureBuiltinNameTransformer(
|
||||
c.Prefix = kt.kustomization.NamePrefix
|
||||
c.Suffix = kt.kustomization.NameSuffix
|
||||
c.FieldSpecs = tConfig.NamePrefix
|
||||
p := builtingen.NewNameTransformerPlugin()
|
||||
p := builtin.NewNameTransformerPlugin()
|
||||
err = kt.configureBuiltinPlugin(p, c, "name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -165,7 +152,7 @@ func (kt *KustTarget) configureBuiltinImageTagTransformer(
|
||||
for _, args := range kt.kustomization.Images {
|
||||
c.ImageTag = args
|
||||
c.FieldSpecs = tConfig.Images
|
||||
p := builtingen.NewImageTagTransformerPlugin()
|
||||
p := builtin.NewImageTagTransformerPlugin()
|
||||
err = kt.configureBuiltinPlugin(p, c, "imageTag")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
)
|
||||
|
||||
func TestPluginDir(t *testing.T) {
|
||||
tc := plugin.NewPluginTestEnv(t).Set()
|
||||
tc := plugin.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
tc.BuildExecPlugin(
|
||||
|
||||
@@ -47,7 +47,7 @@ metadata:
|
||||
}
|
||||
|
||||
func TestOrderedTransformers(t *testing.T) {
|
||||
tc := plugin.NewPluginTestEnv(t).Set()
|
||||
tc := plugin.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
tc.BuildGoPlugin(
|
||||
@@ -92,7 +92,7 @@ spec:
|
||||
}
|
||||
|
||||
func TestSedTransformer(t *testing.T) {
|
||||
tc := plugin.NewPluginTestEnv(t).Set()
|
||||
tc := plugin.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
tc.BuildExecPlugin(
|
||||
@@ -161,7 +161,7 @@ metadata:
|
||||
}
|
||||
|
||||
func TestTransformedTransformers(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