diff --git a/kyaml/runfn/runfn.go b/kyaml/runfn/runfn.go index b6a5ce166..5c3b99fb7 100644 --- a/kyaml/runfn/runfn.go +++ b/kyaml/runfn/runfn.go @@ -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 diff --git a/kyaml/runfn/runfn_test.go b/kyaml/runfn/runfn_test.go index 860bae9a2..333b641be 100644 --- a/kyaml/runfn/runfn_test.go +++ b/kyaml/runfn/runfn_test.go @@ -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")