mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Merge pull request #2826 from ZhuGongpu/master
Add an option to log which function is running
This commit is contained in:
@@ -80,6 +80,15 @@ type Pipeline struct {
|
||||
// Execute executes each step in the sequence, returning immediately after encountering
|
||||
// any error as part of the Pipeline.
|
||||
func (p Pipeline) Execute() error {
|
||||
return p.ExecuteWithCallback(nil)
|
||||
}
|
||||
|
||||
// PipelineExecuteCallbackFunc defines a callback function that will be called each time a step in the pipeline succeeds.
|
||||
type PipelineExecuteCallbackFunc = func(op Filter)
|
||||
|
||||
// ExecuteWithCallback executes each step in the sequence, returning immediately after encountering
|
||||
// any error as part of the Pipeline. The callback will be called each time a step succeeds.
|
||||
func (p Pipeline) ExecuteWithCallback(callback PipelineExecuteCallbackFunc) error {
|
||||
var result []*yaml.RNode
|
||||
|
||||
// read from the inputs
|
||||
@@ -99,6 +108,9 @@ func (p Pipeline) Execute() error {
|
||||
var err error
|
||||
for i := range p.Filters {
|
||||
op := p.Filters[i]
|
||||
if callback != nil {
|
||||
callback(op)
|
||||
}
|
||||
result, err = op.Filter(result)
|
||||
if len(result) == 0 || err != nil {
|
||||
return errors.Wrap(err)
|
||||
|
||||
@@ -4,9 +4,14 @@
|
||||
package kio_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
|
||||
. "sigs.k8s.io/kustomize/kyaml/kio"
|
||||
)
|
||||
|
||||
@@ -23,6 +28,50 @@ func TestPipe(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSlice_Write(t *testing.T) {
|
||||
|
||||
type mockCallback struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (c *mockCallback) Callback(op Filter) {
|
||||
c.Called(op)
|
||||
}
|
||||
|
||||
func TestPipelineWithCallback(t *testing.T) {
|
||||
input := ResourceNodeSlice{yaml.MakeNullNode()}
|
||||
noopFilter1 := func(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
return nodes, nil
|
||||
}
|
||||
noopFilter2 := func(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
return nodes, nil
|
||||
}
|
||||
filters := []Filter{
|
||||
FilterFunc(noopFilter1),
|
||||
FilterFunc(noopFilter2),
|
||||
}
|
||||
p := Pipeline{
|
||||
Inputs: []Reader{input},
|
||||
Filters: filters,
|
||||
Outputs: []Writer{},
|
||||
}
|
||||
|
||||
callback := mockCallback{}
|
||||
// setup expectations. `Times` means the function is called no more than `times`.
|
||||
callback.On("Callback", mock.Anything).Times(len(filters))
|
||||
|
||||
err := p.ExecuteWithCallback(callback.Callback)
|
||||
|
||||
if !assert.NoError(t, err) {
|
||||
assert.FailNow(t, err.Error())
|
||||
}
|
||||
|
||||
callback.AssertNumberOfCalls(t, "Callback", len(filters))
|
||||
|
||||
// assert filters are called in the order they are defined.
|
||||
for i, filter := range filters {
|
||||
assert.Equal(
|
||||
t,
|
||||
reflect.ValueOf(callback.Calls[i].Arguments[0]).Pointer(),
|
||||
reflect.ValueOf(filter).Pointer(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,12 @@ type RunFns struct {
|
||||
// ResultsDir is where to write each functions results
|
||||
ResultsDir string
|
||||
|
||||
// LogSteps enables logging the function that is running.
|
||||
LogSteps bool
|
||||
|
||||
// LogWriter can be set to write the logs to LogWriter rather than stderr if LogSteps is enabled.
|
||||
LogWriter io.Writer
|
||||
|
||||
// resultsCount is used to generate the results filename for each container
|
||||
resultsCount uint32
|
||||
|
||||
@@ -169,8 +175,33 @@ func (r RunFns) runFunctions(
|
||||
// the output is nil (reading from Input)
|
||||
outputs = append(outputs, kio.ByteWriter{Writer: r.Output})
|
||||
}
|
||||
err := kio.Pipeline{
|
||||
Inputs: []kio.Reader{input}, Filters: fltrs, Outputs: outputs}.Execute()
|
||||
|
||||
var err error
|
||||
pipeline := kio.Pipeline{
|
||||
Inputs: []kio.Reader{input},
|
||||
Filters: fltrs,
|
||||
Outputs: outputs,
|
||||
}
|
||||
if r.LogSteps {
|
||||
err = pipeline.ExecuteWithCallback(func(op kio.Filter) {
|
||||
var identifier string
|
||||
|
||||
switch filter := op.(type) {
|
||||
case *container.Filter:
|
||||
identifier = filter.Image
|
||||
case *exec.Filter:
|
||||
identifier = filter.Path
|
||||
case *starlark.Filter:
|
||||
identifier = filter.String()
|
||||
default:
|
||||
identifier = "unknown-type function"
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(r.LogWriter, "Running %s\n", identifier)
|
||||
})
|
||||
} else {
|
||||
err = pipeline.Execute()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -333,6 +364,11 @@ func (r *RunFns) init() {
|
||||
if r.functionFilterProvider == nil {
|
||||
r.functionFilterProvider = r.ffp
|
||||
}
|
||||
|
||||
// if LogSteps is enabled and LogWriter is not specified, use stderr
|
||||
if r.LogSteps && r.LogWriter == nil {
|
||||
r.LogWriter = os.Stderr
|
||||
}
|
||||
}
|
||||
|
||||
// ffp provides function filters
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/fn/runtime/container"
|
||||
@@ -906,6 +907,36 @@ func TestCmd_Execute_setInput(t *testing.T) {
|
||||
assert.Contains(t, string(b), "kind: StatefulSet")
|
||||
}
|
||||
|
||||
// TestCmd_Execute_enableLogSteps tests the execution of a filter with LogSteps enabled.
|
||||
func TestCmd_Execute_enableLogSteps(t *testing.T) {
|
||||
dir := setupTest(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
// write a test filter to the directory of configuration
|
||||
if !assert.NoError(t, ioutil.WriteFile(
|
||||
filepath.Join(dir, "filter.yaml"), []byte(ValueReplacerYAMLData), 0600)) {
|
||||
return
|
||||
}
|
||||
|
||||
logs := &bytes.Buffer{}
|
||||
instance := RunFns{
|
||||
Path: dir,
|
||||
functionFilterProvider: getFilterProvider(t),
|
||||
LogSteps: true,
|
||||
LogWriter: logs,
|
||||
}
|
||||
if !assert.NoError(t, instance.Execute()) {
|
||||
t.FailNow()
|
||||
}
|
||||
b, err := ioutil.ReadFile(
|
||||
filepath.Join(dir, "java", "java-deployment.resource.yaml"))
|
||||
if !assert.NoError(t, err) {
|
||||
t.FailNow()
|
||||
}
|
||||
assert.Contains(t, string(b), "kind: StatefulSet")
|
||||
assert.Equal(t, "Running unknown-type function\n", logs.String())
|
||||
}
|
||||
|
||||
// setupTest initializes a temp test directory containing test data
|
||||
func setupTest(t *testing.T) string {
|
||||
dir, err := ioutil.TempDir("", "kustomize-kyaml-test")
|
||||
|
||||
Reference in New Issue
Block a user