Skip to content

Commit 255569b

Browse files
Align eval output with render (#1907)
* refactor fn runner * update eval output format * omit output when the result is printed to stdout * fix test * improve comment * always use FunctionRunner
1 parent d36d049 commit 255569b

File tree

11 files changed

+84
-138
lines changed

11 files changed

+84
-138
lines changed

commands/fncmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func GetFnCommand(ctx context.Context, name string) *cobra.Command {
4646
},
4747
}
4848

49-
eval := cmdeval.EvalCommand(name)
49+
eval := cmdeval.EvalCommand(ctx, name)
5050
eval.Short = fndocs.RunShort
5151
eval.Long = fndocs.RunShort + "\n" + fndocs.RunLong
5252
eval.Example = fndocs.RunExamples

e2e/testdata/fn-eval/missing-fn-config/.expected/config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ testType: eval
1616
exitCode: 1
1717
image: gcr.io/kpt-fn/set-namespace:v0.1
1818
stdErr: "failed to configure function: input namespace cannot be empty"
19+
stdOut: |
20+
[RUNNING] "gcr.io/kpt-fn/set-namespace:v0.1"
21+
[FAIL] "gcr.io/kpt-fn/set-namespace:v0.1"

e2e/testdata/fn-eval/missing-fn-image/.expected/config.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ image: gcr.io/kpt-fn/dne # non-existing image
1818
args:
1919
namespace: staging
2020
stdErr: 'failed to check function image existence: function image "gcr.io/kpt-fn/dne" doesn''t exist'
21+
stdOut: |
22+
[RUNNING] "gcr.io/kpt-fn/dne"
23+
[FAIL] "gcr.io/kpt-fn/dne"

internal/cmdrender/executor.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"strings"
2424

2525
"github.com/GoogleContainerTools/kpt/internal/errors"
26+
"github.com/GoogleContainerTools/kpt/internal/fnruntime"
2627
"github.com/GoogleContainerTools/kpt/internal/pkg"
2728
"github.com/GoogleContainerTools/kpt/internal/printer"
2829
"github.com/GoogleContainerTools/kpt/internal/types"
@@ -356,7 +357,7 @@ func (pn *pkgNode) runValidators(ctx context.Context, hctx *hydrationContext, in
356357

357358
for i := range pl.Validators {
358359
fn := pl.Validators[i]
359-
validator, err := newFnRunner(ctx, &fn, pn.pkg.UniquePath)
360+
validator, err := fnruntime.NewContainerRunner(ctx, &fn, pn.pkg.UniquePath)
360361
if err != nil {
361362
return err
362363
}
@@ -410,7 +411,7 @@ func fnChain(ctx context.Context, pkgPath types.UniquePath, fns []kptfilev1alpha
410411
var runners []kio.Filter
411412
for i := range fns {
412413
fn := fns[i]
413-
r, err := newFnRunner(ctx, &fn, pkgPath)
414+
r, err := fnruntime.NewContainerRunner(ctx, &fn, pkgPath)
414415
if err != nil {
415416
return nil, err
416417
}

internal/fnruntime/container.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,6 @@ type ContainerFnPermission struct {
4747
AllowMount bool
4848
}
4949

50-
// ContainerFnWrapper wraps the real function filter, prints
51-
// the function running progress and failures.
52-
type ContainerFnWrapper struct {
53-
Fn *ContainerFn
54-
}
55-
56-
func (fw *ContainerFnWrapper) Run(r io.Reader, w io.Writer) error {
57-
pr := printer.FromContextOrDie(fw.Fn.Ctx)
58-
printOpt := printer.NewOpt()
59-
pr.OptPrintf(printOpt, "[RUNNING] %q\n", fw.Fn.Image)
60-
err := fw.Fn.Run(r, w)
61-
if err != nil {
62-
pr.OptPrintf(printOpt, "[FAIL] %q\n", fw.Fn.Image)
63-
return err
64-
}
65-
pr.OptPrintf(printOpt, "[PASS] %q\n", fw.Fn.Image)
66-
return nil
67-
}
68-
6950
// ContainerFn implements a KRMFn which run a containerized
7051
// KRM function
7152
type ContainerFn struct {

internal/cmdrender/pipeline_function.go renamed to internal/fnruntime/runner.go

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
// Package pipeline provides struct definitions for Pipeline and utility
16-
// methods to read and write a pipeline resource.
17-
package cmdrender
15+
package fnruntime
1816

1917
import (
2018
"context"
@@ -24,38 +22,73 @@ import (
2422
"path/filepath"
2523

2624
"github.com/GoogleContainerTools/kpt/internal/errors"
27-
"github.com/GoogleContainerTools/kpt/internal/fnruntime"
25+
"github.com/GoogleContainerTools/kpt/internal/printer"
2826
"github.com/GoogleContainerTools/kpt/internal/types"
2927
kptfilev1alpha2 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1alpha2"
3028
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
3129
"sigs.k8s.io/kustomize/kyaml/kio"
3230
"sigs.k8s.io/kustomize/kyaml/yaml"
3331
)
3432

35-
// newFnRunner returns a fnRunner from the image and configs of
36-
// this function.
37-
func newFnRunner(ctx context.Context, f *kptfilev1alpha2.Function, pkgPath types.UniquePath) (kio.Filter, error) {
33+
// NewContainerRunner returns a kio.Filter given a specification of a container function
34+
// and it's config.
35+
func NewContainerRunner(ctx context.Context, f *kptfilev1alpha2.Function, pkgPath types.UniquePath) (kio.Filter, error) {
3836
config, err := newFnConfig(f, pkgPath)
3937
if err != nil {
4038
return nil, err
4139
}
42-
43-
cfn := &fnruntime.ContainerFn{
40+
cfn := &ContainerFn{
4441
Path: pkgPath,
4542
Image: f.Image,
4643
Ctx: ctx,
4744
}
48-
49-
cfnw := &fnruntime.ContainerFnWrapper{
50-
Fn: cfn,
45+
fltr := &runtimeutil.FunctionFilter{
46+
Run: cfn.Run,
47+
FunctionConfig: config,
5148
}
49+
return NewFunctionRunner(ctx, fltr, f.Image, false)
50+
}
5251

53-
return &runtimeutil.FunctionFilter{
54-
Run: cfnw.Run,
55-
FunctionConfig: config,
52+
// NewFunctionRunner returns a kio.Filter given a specification of a function
53+
// and it's config.
54+
func NewFunctionRunner(ctx context.Context, fltr *runtimeutil.FunctionFilter, name string, disableOutput bool) (kio.Filter, error) {
55+
return &FunctionRunner{
56+
ctx: ctx,
57+
name: name,
58+
filter: fltr,
59+
disableOutput: disableOutput,
5660
}, nil
5761
}
5862

63+
// FunctionRunner wraps FunctionFilter and implements kio.Filter interface.
64+
type FunctionRunner struct {
65+
ctx context.Context
66+
name string
67+
disableOutput bool
68+
filter *runtimeutil.FunctionFilter
69+
}
70+
71+
func (fr *FunctionRunner) Filter(input []*yaml.RNode) (output []*yaml.RNode, err error) {
72+
if fr.disableOutput {
73+
output, err = fr.filter.Filter(input)
74+
} else {
75+
pr := printer.FromContextOrDie(fr.ctx)
76+
printOpt := printer.NewOpt()
77+
pr.OptPrintf(printOpt, "[RUNNING] %q\n", fr.name)
78+
output, err = fr.filter.Filter(input)
79+
if err != nil {
80+
pr.OptPrintf(printOpt, "[FAIL] %q\n", fr.name)
81+
return nil, err
82+
}
83+
// capture the result from running the function
84+
pr.OptPrintf(printOpt, "[PASS] %q\n", fr.name)
85+
}
86+
87+
// TODO(droot): print functionResults
88+
89+
return
90+
}
91+
5992
func newFnConfig(f *kptfilev1alpha2.Function, pkgPath types.UniquePath) (*yaml.RNode, error) {
6093
const op errors.Op = "fn.readConfig"
6194
var fn errors.Fn = errors.Fn(f.Image)

internal/cmdrender/pipeline_function_test.go renamed to internal/fnruntime/runner_test.go

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,9 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
// Licensed under the Apache License, Version 2.0 (the "License");
16-
// you may not use this file except in compliance with the License.
17-
// You may obtain a copy of the License at
18-
//
19-
// http://www.apache.org/licenses/LICENSE-2.0
20-
//
21-
// Unless required by applicable law or agreed to in writing, software
22-
// distributed under the License is distributed on an "AS IS" BASIS,
23-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24-
// See the License for the specific language governing permissions and
25-
// limitations under the License.
26-
2715
// Package pipeline provides struct definitions for Pipeline and utility
2816
// methods to read and write a pipeline resource.
29-
package cmdrender
17+
package fnruntime
3018

3119
import (
3220
"io/ioutil"

thirdparty/cmdconfig/commands/cmdeval/cmdeval.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package cmdeval
55

66
import (
7+
"context"
78
"fmt"
89
"io"
910
"os"
@@ -18,8 +19,8 @@ import (
1819
)
1920

2021
// GetEvalFnRunner returns a EvalFnRunner.
21-
func GetEvalFnRunner(name string) *EvalFnRunner {
22-
r := &EvalFnRunner{}
22+
func GetEvalFnRunner(ctx context.Context, name string) *EvalFnRunner {
23+
r := &EvalFnRunner{Ctx: ctx}
2324
c := &cobra.Command{
2425
Use: "eval [DIR | -]",
2526
RunE: r.runE,
@@ -61,8 +62,8 @@ func GetEvalFnRunner(name string) *EvalFnRunner {
6162
return r
6263
}
6364

64-
func EvalCommand(name string) *cobra.Command {
65-
return GetEvalFnRunner(name).Command
65+
func EvalCommand(ctx context.Context, name string) *cobra.Command {
66+
return GetEvalFnRunner(ctx, name).Command
6667
}
6768

6869
// EvalFnRunner contains the run function
@@ -81,6 +82,7 @@ type EvalFnRunner struct {
8182
Env []string
8283
AsCurrentUser bool
8384
IncludeMetaResources bool
85+
Ctx context.Context
8486
}
8587

8688
func (r *EvalFnRunner) runE(c *cobra.Command, _ []string) error {
@@ -275,6 +277,7 @@ func (r *EvalFnRunner) preRunE(c *cobra.Command, args []string) error {
275277
}
276278

277279
r.RunFns = runfn.RunFns{
280+
Ctx: r.Ctx,
278281
Functions: fns,
279282
Output: output,
280283
Input: input,

thirdparty/cmdconfig/commands/cmdeval/cmdeval_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package cmdeval
55

66
import (
7+
"context"
78
"io"
89
"os"
910
"strings"
@@ -183,6 +184,7 @@ apiVersion: v1
183184
ResultsDir: "foo/",
184185
Env: []string{},
185186
ContinueOnEmptyResult: true,
187+
Ctx: context.TODO(),
186188
},
187189
expected: `
188190
metadata:
@@ -219,6 +221,7 @@ apiVersion: v1
219221
LogSteps: true,
220222
Env: []string{},
221223
ContinueOnEmptyResult: true,
224+
Ctx: context.TODO(),
222225
},
223226
expected: `
224227
metadata:
@@ -239,6 +242,7 @@ apiVersion: v1
239242
Path: "dir",
240243
Env: []string{"FOO=BAR", "BAR"},
241244
ContinueOnEmptyResult: true,
245+
Ctx: context.TODO(),
242246
},
243247
expected: `
244248
metadata:
@@ -260,6 +264,7 @@ apiVersion: v1
260264
AsCurrentUser: true,
261265
Env: []string{},
262266
ContinueOnEmptyResult: true,
267+
Ctx: context.TODO(),
263268
},
264269
expected: `
265270
metadata:
@@ -287,7 +292,7 @@ apiVersion: v1
287292
for i := range tests {
288293
tt := tests[i]
289294
t.Run(tt.name, func(t *testing.T) {
290-
r := GetEvalFnRunner("kpt")
295+
r := GetEvalFnRunner(context.TODO(), "kpt")
291296
// Don't run the actual command
292297
r.Command.Run = nil
293298
r.Command.RunE = func(cmd *cobra.Command, args []string) error { return nil }

thirdparty/kyaml/runfn/runfn.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package runfn
55

66
import (
7+
"context"
78
"fmt"
89
"io"
910
"os"
@@ -30,6 +31,8 @@ import (
3031
// RunFns runs the set of configuration functions in a local directory against
3132
// the Resources in that directory
3233
type RunFns struct {
34+
Ctx context.Context
35+
3336
StorageMounts []runtimeutil.StorageMount
3437

3538
// Path is the path to the directory containing functions
@@ -419,6 +422,8 @@ func (r *RunFns) defaultFnFilterProvider(spec runtimeutil.FunctionSpec, fnConfig
419422
return nil, err
420423
}
421424
}
425+
var fltr *runtimeutil.FunctionFilter
426+
var name string
422427
if spec.Container.Image != "" {
423428
// TODO: Add a test for this behavior
424429
uidgid, err := getUIDGID(r.AsCurrentUser, currentUser)
@@ -438,27 +443,29 @@ func (r *RunFns) defaultFnFilterProvider(spec runtimeutil.FunctionSpec, fnConfig
438443
AllowMount: true,
439444
},
440445
}
441-
cf := &runtimeutil.FunctionFilter{
446+
fltr = &runtimeutil.FunctionFilter{
442447
Run: c.Run,
443448
FunctionConfig: fnConfig,
444449
DeferFailure: spec.DeferFailure,
445450
ResultsFile: resultsFile,
446451
}
447-
return cf, nil
452+
name = spec.Container.Image
448453
}
449454

450455
if spec.Exec.Path != "" {
451456
e := &fnruntime.ExecFn{
452457
Path: spec.Exec.Path,
453458
}
454-
ef := &runtimeutil.FunctionFilter{
459+
fltr = &runtimeutil.FunctionFilter{
455460
Run: e.Run,
456461
FunctionConfig: fnConfig,
457462
DeferFailure: spec.DeferFailure,
458463
ResultsFile: resultsFile,
459464
}
460-
return ef, nil
465+
name = spec.Exec.Path
461466
}
467+
// if output is not nil we will write the resources to stdout
468+
disableOutput := (r.Output != nil)
469+
return fnruntime.NewFunctionRunner(r.Ctx, fltr, name, disableOutput)
462470

463-
return nil, nil
464471
}

0 commit comments

Comments
 (0)