From 459fa3ed8fa2dc45a50c203489cf6d0335fccf70 Mon Sep 17 00:00:00 2001 From: Ciaran Johnston Date: Wed, 3 Dec 2025 14:09:51 +0000 Subject: [PATCH 01/14] Fix #1407: Make 'kpt pkg get' use current directory when '.' is specified When users explicitly pass '.' as the destination directory, kpt pkg get now places files directly in the current directory, matching the behavior of 'git clone' and 'kpt cfg set'. Changes: - Modified parse.GitParseArgs() to track if destination was explicitly provided - Updated getDest() to use current directory directly when explicitly specified - Modified get.Run() to allow using existing empty directories - Preserved default behavior: when no destination is provided, still creates a subdirectory with the package name Fixes #1407 Signed-off-by: Ciaran Johnston --- commands/pkg/get/cmdget.go | 4 +++- commands/pkg/get/cmdget_test.go | 4 ++-- internal/util/get/get.go | 29 +++++++++++++++++++++++------ pkg/lib/util/parse/parse.go | 21 ++++++++++++++------- pkg/lib/util/parse/parse_test.go | 6 +++--- 5 files changed, 45 insertions(+), 19 deletions(-) diff --git a/commands/pkg/get/cmdget.go b/commands/pkg/get/cmdget.go index 0221540775..f4022861c8 100644 --- a/commands/pkg/get/cmdget.go +++ b/commands/pkg/get/cmdget.go @@ -76,6 +76,8 @@ type Runner struct { func (r *Runner) preRunE(_ *cobra.Command, args []string) error { const op errors.Op = "cmdget.preRunE" + // Track if destination was explicitly provided + explicitDest := len(args) > 1 if len(args) == 1 { args = append(args, pkg.CurDir) } else { @@ -88,7 +90,7 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { args[1] = resolvedPath } } - t, err := parse.GitParseArgs(r.ctx, args) + t, err := parse.GitParseArgs(r.ctx, args, explicitDest) if err != nil { return errors.E(op, err) } diff --git a/commands/pkg/get/cmdget_test.go b/commands/pkg/get/cmdget_test.go index 6d01057592..c5e21f115c 100644 --- a/commands/pkg/get/cmdget_test.go +++ b/commands/pkg/get/cmdget_test.go @@ -250,7 +250,7 @@ func TestCmd_Execute_flagAndArgParsing(t *testing.T) { assert.Equal(t, filepath.Join(pathPrefix, w.WorkspaceDirectory, "java"), r.Get.Destination) }, }, - "current working dir -- should use package name": { + "current working dir -- should use current directory directly": { argsFunc: func(repo, _ string) []string { return []string{fmt.Sprintf("file://%s.git/blueprints/java", repo), "foo/../bar/../"} }, @@ -260,7 +260,7 @@ func TestCmd_Execute_flagAndArgParsing(t *testing.T) { assert.Equal(t, fmt.Sprintf("file://%s", repo), r.Get.Git.Repo) assert.Equal(t, "master", r.Get.Git.Ref) assert.Equal(t, "/blueprints/java", r.Get.Git.Directory) - assert.Equal(t, filepath.Join(pathPrefix, w.WorkspaceDirectory, "java"), r.Get.Destination) + assert.Equal(t, filepath.Join(pathPrefix, w.WorkspaceDirectory), r.Get.Destination) }, }, "clean relative path": { diff --git a/internal/util/get/get.go b/internal/util/get/get.go index ae30f59896..5fb14ad251 100644 --- a/internal/util/get/get.go +++ b/internal/util/get/get.go @@ -74,13 +74,30 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, err) } - if _, err := os.Stat(c.Destination); !goerrors.Is(err, os.ErrNotExist) { - return errors.E(op, errors.Exist, types.UniquePath(c.Destination), fmt.Errorf("destination directory already exists")) - } - - err := os.MkdirAll(c.Destination, 0700) - if err != nil { + destInfo, err := os.Stat(c.Destination) + if err == nil { + // Destination exists - check if it's an empty directory + if !destInfo.IsDir() { + return errors.E(op, errors.Exist, types.UniquePath(c.Destination), fmt.Errorf("destination exists and is not a directory")) + } + + // Check if directory is empty + entries, err := os.ReadDir(c.Destination) + if err != nil { + return errors.E(op, errors.IO, types.UniquePath(c.Destination), err) + } + if len(entries) > 0 { + return errors.E(op, errors.Exist, types.UniquePath(c.Destination), fmt.Errorf("destination directory already exists")) + } + // Directory exists but is empty, we can use it + } else if !goerrors.Is(err, os.ErrNotExist) { return errors.E(op, errors.IO, types.UniquePath(c.Destination), err) + } else { + // Directory doesn't exist, create it + err = os.MkdirAll(c.Destination, 0700) + if err != nil { + return errors.E(op, errors.IO, types.UniquePath(c.Destination), err) + } } // normalize path to a filepath diff --git a/pkg/lib/util/parse/parse.go b/pkg/lib/util/parse/parse.go index 2048fb2680..fa20f0e3f6 100644 --- a/pkg/lib/util/parse/parse.go +++ b/pkg/lib/util/parse/parse.go @@ -35,7 +35,7 @@ type Target struct { Destination string } -func GitParseArgs(ctx context.Context, args []string) (Target, error) { +func GitParseArgs(ctx context.Context, args []string, explicitDest bool) (Target, error) { g := Target{} if args[0] == "-" { return g, nil @@ -43,7 +43,7 @@ func GitParseArgs(ctx context.Context, args []string) (Target, error) { // Simple parsing if contains .git{$|/) if HasGitSuffix(args[0]) { - return targetFromPkgURL(ctx, args[0], args[1]) + return targetFromPkgURL(ctx, args[0], args[1], explicitDest) } // GitHub parsing if contains github.com @@ -52,7 +52,7 @@ func GitParseArgs(ctx context.Context, args []string) (Target, error) { if err != nil { return g, err } - return targetFromPkgURL(ctx, ghPkgURL, args[1]) + return targetFromPkgURL(ctx, ghPkgURL, args[1], explicitDest) } uri, version, err := getURIAndVersion(args[0]) @@ -75,7 +75,7 @@ func GitParseArgs(ctx context.Context, args []string) (Target, error) { version = defaultRef } - destination, err := getDest(args[1], repo, remoteDir) + destination, err := getDest(args[1], repo, remoteDir, explicitDest) if err != nil { return g, err } @@ -87,7 +87,7 @@ func GitParseArgs(ctx context.Context, args []string) (Target, error) { } // targetFromPkgURL parses a pkg url and destination into kptfile git info and local destination Target -func targetFromPkgURL(ctx context.Context, pkgURL string, dest string) (Target, error) { +func targetFromPkgURL(ctx context.Context, pkgURL string, dest string, explicitDest bool) (Target, error) { g := Target{} repo, dir, ref, err := URL(pkgURL) if err != nil { @@ -107,7 +107,7 @@ func targetFromPkgURL(ctx context.Context, pkgURL string, dest string) (Target, } ref = defaultRef } - destination, err := getDest(dest, repo, dir) + destination, err := getDest(dest, repo, dir, explicitDest) if err != nil { return g, err } @@ -255,7 +255,8 @@ func getRepoAndPkg(v string) (string, string, error) { return repoAndPkg[0], repoAndPkg[1], nil } -func getDest(v, repo, subdir string) (string, error) { +func getDest(v, repo, subdir string, explicitDest bool) (string, error) { + originalV := v v = filepath.Clean(v) f, err := os.Stat(v) @@ -274,6 +275,12 @@ func getDest(v, repo, subdir string) (string, error) { } // LOCATION EXISTS + // Check if user explicitly specified current directory (. or empty string) + // to match git clone behavior + if explicitDest && (originalV == "." || originalV == "") { + return v, nil + } + // default the location to a new subdirectory matching the pkg URI base repo = strings.TrimSuffix(repo, "/") repo = strings.TrimSuffix(repo, ".git") diff --git a/pkg/lib/util/parse/parse_test.go b/pkg/lib/util/parse/parse_test.go index 45d2393b12..222800a21a 100644 --- a/pkg/lib/util/parse/parse_test.go +++ b/pkg/lib/util/parse/parse_test.go @@ -240,7 +240,7 @@ func Test_GitParseArgs(t *testing.T) { Directory: "/", Ref: "main", }, - Destination: "kpt"}, + Destination: "."}, }, "starts with github.com": { ghURL: "https://github.com/kptdev/kpt", @@ -249,7 +249,7 @@ func Test_GitParseArgs(t *testing.T) { Directory: "/", Ref: "main", }, - Destination: "kpt"}, + Destination: "."}, }, } for name, test := range tests { @@ -258,7 +258,7 @@ func Test_GitParseArgs(t *testing.T) { t.SkipNow() } ctx := printer.WithContext(context.Background(), printer.New(nil, nil)) - actual, err := GitParseArgs(ctx, []string{test.ghURL, ""}) + actual, err := GitParseArgs(ctx, []string{test.ghURL, ""}, true) assert.NoError(t, err) assert.Equal(t, test.expected, actual) }) From 0a02d6b3ff40c4ea54e066c18fa43d7f6e6b1161 Mon Sep 17 00:00:00 2001 From: Ciaran Johnston Date: Wed, 3 Dec 2025 17:03:09 +0000 Subject: [PATCH 02/14] Fix linting error: rewrite if-else to switch statement Signed-off-by: Ciaran Johnston --- internal/util/get/get.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/internal/util/get/get.go b/internal/util/get/get.go index 5fb14ad251..1d74f85c40 100644 --- a/internal/util/get/get.go +++ b/internal/util/get/get.go @@ -75,12 +75,13 @@ func (c Command) Run(ctx context.Context) error { } destInfo, err := os.Stat(c.Destination) - if err == nil { + switch { + case err == nil: // Destination exists - check if it's an empty directory if !destInfo.IsDir() { return errors.E(op, errors.Exist, types.UniquePath(c.Destination), fmt.Errorf("destination exists and is not a directory")) } - + // Check if directory is empty entries, err := os.ReadDir(c.Destination) if err != nil { @@ -90,14 +91,14 @@ func (c Command) Run(ctx context.Context) error { return errors.E(op, errors.Exist, types.UniquePath(c.Destination), fmt.Errorf("destination directory already exists")) } // Directory exists but is empty, we can use it - } else if !goerrors.Is(err, os.ErrNotExist) { - return errors.E(op, errors.IO, types.UniquePath(c.Destination), err) - } else { + case goerrors.Is(err, os.ErrNotExist): // Directory doesn't exist, create it err = os.MkdirAll(c.Destination, 0700) if err != nil { return errors.E(op, errors.IO, types.UniquePath(c.Destination), err) } + default: + return errors.E(op, errors.IO, types.UniquePath(c.Destination), err) } // normalize path to a filepath From 49b9fb6f0c207b83d606db17348ef168b6f3ffa3 Mon Sep 17 00:00:00 2001 From: Ciaran Johnston Date: Wed, 21 Jan 2026 12:04:59 -0600 Subject: [PATCH 03/14] Fix test failures: check cleaned path for '.' and update test expectations - Changed getDest() to check cleaned path (v) instead of originalV for '.' comparison - Updated tests to expect current directory when './' or '.' is explicitly passed - Fixed TestCmdMainBranch_execute to not pass './' explicitly - Fixed TestCmd_fail to use non-existent destination directory Signed-off-by: Ciaran Johnston --- commands/pkg/get/cmdget_test.go | 10 +++++----- pkg/lib/util/parse/parse.go | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/commands/pkg/get/cmdget_test.go b/commands/pkg/get/cmdget_test.go index c5e21f115c..ee0234b0b9 100644 --- a/commands/pkg/get/cmdget_test.go +++ b/commands/pkg/get/cmdget_test.go @@ -111,7 +111,7 @@ func TestCmdMainBranch_execute(t *testing.T) { } r := get.NewRunner(fake.CtxWithDefaultPrinter(), "kpt") - r.Command.SetArgs([]string{"file://" + g.RepoDirectory + ".git/", "./"}) + r.Command.SetArgs([]string{"file://" + g.RepoDirectory + ".git/"}) err = r.Command.Execute() assert.NoError(t, err) @@ -159,9 +159,9 @@ func TestCmd_fail(t *testing.T) { r := get.NewRunner(fake.CtxWithDefaultPrinter(), "kpt") r.Command.SilenceErrors = true r.Command.SilenceUsage = true - r.Command.SetArgs([]string{"file://" + filepath.Join("not", "real", "dir") + ".git/@master", "./"}) + r.Command.SetArgs([]string{"file://" + filepath.Join("not", "real", "dir") + ".git/@master", "nonexistent"}) - defer os.RemoveAll("dir") + defer os.RemoveAll("nonexistent") err := r.Command.Execute() if !assert.Error(t, err) { @@ -234,7 +234,7 @@ func TestCmd_Execute_flagAndArgParsing(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "master", r.Get.Git.Ref) assert.Equal(t, "something://foo", r.Get.Git.Repo) - assert.Equal(t, filepath.Join(pathPrefix, w.WorkspaceDirectory, "foo"), r.Get.Destination) + assert.Equal(t, filepath.Join(pathPrefix, w.WorkspaceDirectory), r.Get.Destination) }, }, "repo arg is split up correctly into ref, directory and repo": { @@ -247,7 +247,7 @@ func TestCmd_Execute_flagAndArgParsing(t *testing.T) { assert.Equal(t, fmt.Sprintf("file://%s", repo), r.Get.Git.Repo) assert.Equal(t, "master", r.Get.Git.Ref) assert.Equal(t, "/blueprints/java", r.Get.Git.Directory) - assert.Equal(t, filepath.Join(pathPrefix, w.WorkspaceDirectory, "java"), r.Get.Destination) + assert.Equal(t, filepath.Join(pathPrefix, w.WorkspaceDirectory), r.Get.Destination) }, }, "current working dir -- should use current directory directly": { diff --git a/pkg/lib/util/parse/parse.go b/pkg/lib/util/parse/parse.go index fa20f0e3f6..5a5a6e4558 100644 --- a/pkg/lib/util/parse/parse.go +++ b/pkg/lib/util/parse/parse.go @@ -275,9 +275,9 @@ func getDest(v, repo, subdir string, explicitDest bool) (string, error) { } // LOCATION EXISTS - // Check if user explicitly specified current directory (. or empty string) + // Check if user explicitly specified current directory (. or paths that resolve to .) // to match git clone behavior - if explicitDest && (originalV == "." || originalV == "") { + if explicitDest && (v == "." || originalV == "") { return v, nil } From 656576adc97b3aa5f01daa41c374c21d60df5177 Mon Sep 17 00:00:00 2001 From: Ciaran Johnston Date: Mon, 2 Mar 2026 21:46:48 +0000 Subject: [PATCH 04/14] Fix TestCmdExecute: remove explicit './' destination argument The test was explicitly passing './' as the destination, which with the new behavior means 'use current directory directly'. Since the test runs in a non-empty workspace directory, this caused a conflict. Removing the explicit destination argument allows the default behavior to create a subdirectory with the package name, which is what the test expects. Signed-off-by: Ciaran Johnston --- commands/pkg/diff/cmddiff_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/pkg/diff/cmddiff_test.go b/commands/pkg/diff/cmddiff_test.go index c78b803659..57d2d6170f 100644 --- a/commands/pkg/diff/cmddiff_test.go +++ b/commands/pkg/diff/cmddiff_test.go @@ -61,7 +61,7 @@ func TestCmdExecute(t *testing.T) { dest := filepath.Join(w.WorkspaceDirectory, g.RepoName) getRunner := get.NewRunner(fake.CtxWithDefaultPrinter(), "") - getRunner.Command.SetArgs([]string{"file://" + g.RepoDirectory + ".git/", "./"}) + getRunner.Command.SetArgs([]string{"file://" + g.RepoDirectory + ".git/"}) err := getRunner.Command.Execute() assert.NoError(t, err) From be4c4efa599be714ac610867db84640ffe40bd40 Mon Sep 17 00:00:00 2001 From: Ciaran Johnston Date: Sun, 15 Mar 2026 23:51:27 +0000 Subject: [PATCH 05/14] Updated the test checks to be cleaner and more accurate Signed-off-by: Ciaran Johnston --- pkg/lib/util/parse/parse.go | 2 +- pkg/lib/util/parse/parse_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/lib/util/parse/parse.go b/pkg/lib/util/parse/parse.go index 5a5a6e4558..92e062b02e 100644 --- a/pkg/lib/util/parse/parse.go +++ b/pkg/lib/util/parse/parse.go @@ -277,7 +277,7 @@ func getDest(v, repo, subdir string, explicitDest bool) (string, error) { // LOCATION EXISTS // Check if user explicitly specified current directory (. or paths that resolve to .) // to match git clone behavior - if explicitDest && (v == "." || originalV == "") { + if explicitDest && v == "." { return v, nil } diff --git a/pkg/lib/util/parse/parse_test.go b/pkg/lib/util/parse/parse_test.go index 222800a21a..8496785fee 100644 --- a/pkg/lib/util/parse/parse_test.go +++ b/pkg/lib/util/parse/parse_test.go @@ -258,7 +258,7 @@ func Test_GitParseArgs(t *testing.T) { t.SkipNow() } ctx := printer.WithContext(context.Background(), printer.New(nil, nil)) - actual, err := GitParseArgs(ctx, []string{test.ghURL, ""}, true) + actual, err := GitParseArgs(ctx, []string{test.ghURL, test.expected.Destination}, true) assert.NoError(t, err) assert.Equal(t, test.expected, actual) }) From 15c07b17a93ea1a5237e1c9def2ff6b43fae156d Mon Sep 17 00:00:00 2001 From: Ciaran Johnston Date: Mon, 16 Mar 2026 19:56:13 +0000 Subject: [PATCH 06/14] Removed unused variable Signed-off-by: Ciaran Johnston --- pkg/lib/util/parse/parse.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/lib/util/parse/parse.go b/pkg/lib/util/parse/parse.go index 92e062b02e..16c85c6e38 100644 --- a/pkg/lib/util/parse/parse.go +++ b/pkg/lib/util/parse/parse.go @@ -256,7 +256,6 @@ func getRepoAndPkg(v string) (string, string, error) { } func getDest(v, repo, subdir string, explicitDest bool) (string, error) { - originalV := v v = filepath.Clean(v) f, err := os.Stat(v) From 9f98870571db88b219b1f010dc36e2fa01a71b41 Mon Sep 17 00:00:00 2001 From: Ciaran Johnston Date: Mon, 16 Mar 2026 20:45:01 +0000 Subject: [PATCH 07/14] Skip symlink resolution when directory == . Signed-off-by: Ciaran Johnston --- commands/pkg/get/cmdget.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/commands/pkg/get/cmdget.go b/commands/pkg/get/cmdget.go index f4022861c8..03821c663e 100644 --- a/commands/pkg/get/cmdget.go +++ b/commands/pkg/get/cmdget.go @@ -17,6 +17,7 @@ package get import ( "context" "os" + "path/filepath" "strings" docs "github.com/kptdev/kpt/internal/docs/generated/pkgdocs" @@ -80,7 +81,7 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { explicitDest := len(args) > 1 if len(args) == 1 { args = append(args, pkg.CurDir) - } else { + } else if filepath.Clean(args[1]) != "." { _, err := os.Lstat(args[1]) if err == nil || os.IsExist(err) { resolvedPath, err := argutil.ResolveSymlink(r.ctx, args[1]) From 077a74fcdc2e2f1e50b5a0600331dc2223e923b1 Mon Sep 17 00:00:00 2001 From: Aravindhan Ayyanathan Date: Mon, 16 Mar 2026 19:16:41 +0000 Subject: [PATCH 08/14] Replace gcr.io container image references with ghcr.io (#4428) * Replace the image registry from gcr.io to ghcr.io Signed-off-by: aravind.est * Fix the wasm build failure New WASM images published. It's a manual process now. Fix Go 1.21+ wasm compatibility by renaming the import module from go to gojs in the nodejs JS glue code. The wasmexec library used by the wasmtime runtime has the same issue but requires a separate upstream fix. Signed-off-by: aravind.est --------- Signed-off-by: aravind.est --- .github/workflows/go.yml | 1 + .../reference/cli/alpha/wasm/pull/_index.md | 5 ++- .../reference/cli/alpha/wasm/push/_index.md | 4 +- .../en/reference/cli/fn/eval/_index.md | 18 ++++---- .../en/reference/cli/fn/sink/_index.md | 2 +- .../en/reference/cli/fn/source/_index.md | 2 +- .../wasm-function/.expected/config.yaml | 3 +- .../basicpipeline-wasm/.expected/diff.patch | 8 +--- .../basicpipeline-wasm/.expected/setup.sh | 2 +- .../fn-render/basicpipeline-wasm/Kptfile | 7 +--- internal/docs/generated/fndocs/docs.go | 41 ++++++++++++++----- internal/docs/generated/wasmdocs/docs.go | 8 ++-- internal/fnruntime/jsglue.go | 4 +- .../java/java-deployment.resource.yaml | 2 +- .../mysql/mysql-statefulset.resource.yaml | 4 +- .../java/java-deployment.resource.yaml | 2 +- .../mysql/mysql-statefulset.resource.yaml | 4 +- .../java/java-deployment.resource.yaml | 2 +- .../mysql/mysql-statefulset.resource.yaml | 4 +- .../java/java-deployment.resource.yaml | 2 +- .../mysql/mysql-statefulset.resource.yaml | 4 +- .../java/java-deployment.resource.yaml | 2 +- .../mysql/mysql-statefulset.resource.yaml | 4 +- .../java/java-deployment.resource.yaml | 2 +- .../mysql/mysql-statefulset.resource.yaml | 4 +- .../java/java-deployment.resource.yaml | 2 +- .../mysql/mysql-statefulset.resource.yaml | 4 +- .../java/java-deployment.resource.yaml | 2 +- .../mysql/mysql-statefulset.resource.yaml | 4 +- .../commands/cmdsink/cmdsink_test.go | 4 +- .../commands/cmdsource/cmdsource_test.go | 16 ++++---- .../commands/cmdtree/cmdtree_test.go | 8 ++-- thirdparty/kyaml/runfn/runfn_test.go | 10 ++--- .../java/java-deployment.resource.yaml | 2 +- 34 files changed, 104 insertions(+), 89 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 754a2e7ac1..eceb472523 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -67,6 +67,7 @@ jobs: make test-docker env: KRM_FN_RUNTIME: ${{ matrix.runtime }} + KPT_FN_WASM_RUNTIME: nodejs build-macos: runs-on: macos-latest diff --git a/documentation/content/en/reference/cli/alpha/wasm/pull/_index.md b/documentation/content/en/reference/cli/alpha/wasm/pull/_index.md index 91dcf1f40a..45f54fe4e3 100644 --- a/documentation/content/en/reference/cli/alpha/wasm/pull/_index.md +++ b/documentation/content/en/reference/cli/alpha/wasm/pull/_index.md @@ -36,8 +36,9 @@ LOCAL_PATH: ```shell -# pull image gcr.io/my-org/my-fn:v1.0.0 and decompress it to ./my-fn.wasm -$ kpt alpha wasm pull gcr.io/my-org/my-fn:v1.0.0 ./my-fn.wasm +# pull image ghcr.io/my-org/my-fn:v1.0.0 and decompress it to ./my-fn.wasm +$ kpt alpha wasm pull ghcr.io/my-org/my-fn:v1.0.0 ./my-fn.wasm ``` + diff --git a/documentation/content/en/reference/cli/alpha/wasm/push/_index.md b/documentation/content/en/reference/cli/alpha/wasm/push/_index.md index c03fe6b045..0521bd99e6 100644 --- a/documentation/content/en/reference/cli/alpha/wasm/push/_index.md +++ b/documentation/content/en/reference/cli/alpha/wasm/push/_index.md @@ -36,8 +36,8 @@ IMAGE: ```shell -# compress ./my-fn.wasm and push it to gcr.io/my-org/my-fn:v1.0.0 -$ kpt alpha wasm push ./my-fn.wasm gcr.io/my-org/my-fn:v1.0.0 +# compress ./my-fn.wasm and push it to ghcr.io/my-org/my-fn:v1.0.0 +$ kpt alpha wasm push ./my-fn.wasm ghcr.io/my-org/my-fn:v1.0.0 ``` diff --git a/documentation/content/en/reference/cli/fn/eval/_index.md b/documentation/content/en/reference/cli/fn/eval/_index.md index c162f29831..606681a604 100644 --- a/documentation/content/en/reference/cli/fn/eval/_index.md +++ b/documentation/content/en/reference/cli/fn/eval/_index.md @@ -165,28 +165,28 @@ KRM_FN_RUNTIME: ```shell # execute container my-fn on the resources in DIR directory and # write output back to DIR -$ kpt fn eval DIR -i gcr.io/example.com/my-fn +$ kpt fn eval DIR -i ghcr.io/example.com/my-fn ``` ```shell # execute container my-fn on the resources in DIR directory with # `functionConfig` my-fn-config -$ kpt fn eval DIR -i gcr.io/example.com/my-fn --fn-config my-fn-config +$ kpt fn eval DIR -i ghcr.io/example.com/my-fn --fn-config my-fn-config ``` ```shell # execute container my-fn with an input ConfigMap containing `data: {foo: bar}` -$ kpt fn eval DIR -i gcr.io/example.com/my-fn:v1.0.0 -- foo=bar +$ kpt fn eval DIR -i ghcr.io/example.com/my-fn:v1.0.0 -- foo=bar ``` ```shell # execute container my-fn and save it to Kptfile `pipeline.mutators` (Default) list. -$ kpt fn eval DIR -s -i gcr.io/example.com/my-fn:v1.0.0 -- foo=bar +$ kpt fn eval DIR -s -i ghcr.io/example.com/my-fn:v1.0.0 -- foo=bar ``` ```shell # execute container my-fn and save it to Kptfile `pipeline.validators` list. -$ kpt fn eval DIR -s -t validator -i gcr.io/example.com/my-fn:v1.0.0 -- foo=bar +$ kpt fn eval DIR -s -t validator -i ghcr.io/example.com/my-fn:v1.0.0 -- foo=bar ``` ```shell @@ -204,19 +204,19 @@ $ kpt fn eval DIR --exec "./my-fn arg1 arg2" ```shell # execute container my-fn on the resources in DIR directory, # save structured results in /tmp/my-results dir and write output back to DIR -$ kpt fn eval DIR -i gcr.io/example.com/my-fn --results-dir /tmp/my-results-dir +$ kpt fn eval DIR -i ghcr.io/example.com/my-fn --results-dir /tmp/my-results-dir ``` ```shell # execute container my-fn on the resources in DIR directory with network access enabled, # and write output back to DIR -$ kpt fn eval DIR -i gcr.io/example.com/my-fn --network +$ kpt fn eval DIR -i ghcr.io/example.com/my-fn --network ``` ```shell # execute container my-fn on the resource in DIR and export KUBECONFIG # and foo environment variable -$ kpt fn eval DIR -i gcr.io/example.com/my-fn --env KUBECONFIG -e foo=bar +$ kpt fn eval DIR -i ghcr.io/example.com/my-fn --env KUBECONFIG -e foo=bar ``` ```shell @@ -265,7 +265,7 @@ kpt fn eval -i set-namespace:latest --by-kind Deployment --by-name foo -- namesp ```shell # execute container my-fn with podman on the resources in DIR directory and # write output back to DIR -$ KRM_FN_RUNTIME=podman kpt fn eval DIR -i gcr.io/example.com/my-fn +$ KRM_FN_RUNTIME=podman kpt fn eval DIR -i ghcr.io/example.com/my-fn ``` diff --git a/documentation/content/en/reference/cli/fn/sink/_index.md b/documentation/content/en/reference/cli/fn/sink/_index.md index b9ae1b16ba..c8f8b821d3 100644 --- a/documentation/content/en/reference/cli/fn/sink/_index.md +++ b/documentation/content/en/reference/cli/fn/sink/_index.md @@ -42,7 +42,7 @@ DIR: # read resources from DIR directory, execute my-fn on them and write the # output to DIR directory. $ kpt fn source DIR | - kpt fn eval - --image gcr.io/example.com/my-fn | + kpt fn eval - --image ghcr.io/example.com/my-fn | kpt fn sink NEW_DIR ``` diff --git a/documentation/content/en/reference/cli/fn/source/_index.md b/documentation/content/en/reference/cli/fn/source/_index.md index bdc22bbc25..1e94cdc9b8 100644 --- a/documentation/content/en/reference/cli/fn/source/_index.md +++ b/documentation/content/en/reference/cli/fn/source/_index.md @@ -64,7 +64,7 @@ $ kpt fn source DIR # read resources from DIR directory, execute my-fn on them and write the # output to DIR directory. $ kpt fn source DIR | - kpt fn eval - --image gcr.io/example.com/my-fn - | + kpt fn eval - --image ghcr.io/example.com/my-fn - | kpt fn sink DIR ``` diff --git a/e2e/testdata/fn-eval/wasm-function/.expected/config.yaml b/e2e/testdata/fn-eval/wasm-function/.expected/config.yaml index 85c35915f4..2473a37ea2 100644 --- a/e2e/testdata/fn-eval/wasm-function/.expected/config.yaml +++ b/e2e/testdata/fn-eval/wasm-function/.expected/config.yaml @@ -13,8 +13,7 @@ # limitations under the License. testType: eval -#image: ghcr.io/kptdev/krm-functions-catalog/wasm/set-namespace:v0.5.0 -image: gcr.io/kpt-fn-demo/set-namespace:v0.5.0 +image: ghcr.io/kptdev/krm-functions-catalog/wasm/set-namespace:v0.5.1 args: namespace: staging allowWasm: true diff --git a/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch b/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch index 373cc33df7..89e03e2827 100644 --- a/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch +++ b/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch @@ -1,8 +1,8 @@ diff --git a/resources.yaml b/resources.yaml -index eed43d6..e76b00d 100644 +index eed43d6..c1de2b0 100644 --- a/resources.yaml +++ b/resources.yaml -@@ -15,12 +15,24 @@ apiVersion: apps/v1 +@@ -15,12 +15,20 @@ apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment @@ -14,10 +14,6 @@ index eed43d6..e76b00d 100644 + selector: + matchLabels: + tier: backend -+ template: -+ metadata: -+ labels: -+ tier: backend --- apiVersion: custom.io/v1 kind: Custom diff --git a/e2e/testdata/fn-render/basicpipeline-wasm/.expected/setup.sh b/e2e/testdata/fn-render/basicpipeline-wasm/.expected/setup.sh index 115e1ca96f..bcf8bc12c1 100755 --- a/e2e/testdata/fn-render/basicpipeline-wasm/.expected/setup.sh +++ b/e2e/testdata/fn-render/basicpipeline-wasm/.expected/setup.sh @@ -13,4 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -export KPT_FN_WASM_RUNTIME=wasmtime +export KPT_FN_WASM_RUNTIME=nodejs diff --git a/e2e/testdata/fn-render/basicpipeline-wasm/Kptfile b/e2e/testdata/fn-render/basicpipeline-wasm/Kptfile index ffcf186b10..17a7822d08 100644 --- a/e2e/testdata/fn-render/basicpipeline-wasm/Kptfile +++ b/e2e/testdata/fn-render/basicpipeline-wasm/Kptfile @@ -6,12 +6,9 @@ metadata: tier: backend pipeline: mutators: - # The following 2 images are built from https://github.com/kptdev/krm-functions-catalog/pull/898. - - image: gcr.io/kpt-fn-demo/set-namespace:v0.5.0 - # ghcr.io/kptdev/krm-functions-catalog/wasm/set-namespace:v0.5.0 + - image: ghcr.io/kptdev/krm-functions-catalog/wasm/set-namespace:v0.5.1 configMap: namespace: staging - - image: gcr.io/kpt-fn-demo/set-labels:v0.2.0 - # ghcr.io/kptdev/krm-functions-catalog/wasm/set-labels:v0.2.0 + - image: ghcr.io/kptdev/krm-functions-catalog/wasm/set-labels:v0.2.4 configMap: tier: backend diff --git a/internal/docs/generated/fndocs/docs.go b/internal/docs/generated/fndocs/docs.go index 1688590bb2..4fc85f397b 100644 --- a/internal/docs/generated/fndocs/docs.go +++ b/internal/docs/generated/fndocs/docs.go @@ -161,20 +161,20 @@ Environment Variables: var EvalExamples = ` # execute container my-fn on the resources in DIR directory and # write output back to DIR - $ kpt fn eval DIR -i gcr.io/example.com/my-fn + $ kpt fn eval DIR -i ghcr.io/example.com/my-fn # execute container my-fn on the resources in DIR directory with # ` + "`" + `functionConfig` + "`" + ` my-fn-config - $ kpt fn eval DIR -i gcr.io/example.com/my-fn --fn-config my-fn-config + $ kpt fn eval DIR -i ghcr.io/example.com/my-fn --fn-config my-fn-config # execute container my-fn with an input ConfigMap containing ` + "`" + `data: {foo: bar}` + "`" + ` - $ kpt fn eval DIR -i gcr.io/example.com/my-fn:v1.0.0 -- foo=bar + $ kpt fn eval DIR -i ghcr.io/example.com/my-fn:v1.0.0 -- foo=bar # execute container my-fn and save it to Kptfile ` + "`" + `pipeline.mutators` + "`" + ` (Default) list. - $ kpt fn eval DIR -s -i gcr.io/example.com/my-fn:v1.0.0 -- foo=bar + $ kpt fn eval DIR -s -i ghcr.io/example.com/my-fn:v1.0.0 -- foo=bar # execute container my-fn and save it to Kptfile ` + "`" + `pipeline.validators` + "`" + ` list. - $ kpt fn eval DIR -s -t validator -i gcr.io/example.com/my-fn:v1.0.0 -- foo=bar + $ kpt fn eval DIR -s -t validator -i ghcr.io/example.com/my-fn:v1.0.0 -- foo=bar # execute executable my-fn on the resources in DIR directory and # write output back to DIR @@ -186,15 +186,15 @@ var EvalExamples = ` # execute container my-fn on the resources in DIR directory, # save structured results in /tmp/my-results dir and write output back to DIR - $ kpt fn eval DIR -i gcr.io/example.com/my-fn --results-dir /tmp/my-results-dir + $ kpt fn eval DIR -i ghcr.io/example.com/my-fn --results-dir /tmp/my-results-dir # execute container my-fn on the resources in DIR directory with network access enabled, # and write output back to DIR - $ kpt fn eval DIR -i gcr.io/example.com/my-fn --network + $ kpt fn eval DIR -i ghcr.io/example.com/my-fn --network # execute container my-fn on the resource in DIR and export KUBECONFIG # and foo environment variable - $ kpt fn eval DIR -i gcr.io/example.com/my-fn --env KUBECONFIG -e foo=bar + $ kpt fn eval DIR -i ghcr.io/example.com/my-fn --env KUBECONFIG -e foo=bar # execute kubeconform function by mounting schema from a local directory on wordpress package $ kpt fn eval -i ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest \ @@ -229,7 +229,7 @@ var EvalExamples = ` # execute container my-fn with podman on the resources in DIR directory and # write output back to DIR - $ KRM_FN_RUNTIME=podman kpt fn eval DIR -i gcr.io/example.com/my-fn + $ KRM_FN_RUNTIME=podman kpt fn eval DIR -i ghcr.io/example.com/my-fn ` var RenderShort = `Render a package.` @@ -272,6 +272,16 @@ Flags: to ` + "`" + `results.yaml` + "`" + ` file in the specified directory. If not specified, no result files are written to the local filesystem. +Kptfile Annotations: + + kpt.dev/save-on-render-failure: + Controls whether partially rendered resources are saved when rendering fails. + Set to "true" in the Kptfile metadata.annotations section to preserve the state + of resources at the point of failure. This is useful for debugging render failures + and understanding what changes were applied before the error occurred. + This follows the same pattern as kpt.dev/bfs-rendering annotation. + Default: false (failures will revert changes). + Environment Variables: KRM_FN_RUNTIME: @@ -305,6 +315,15 @@ var RenderExamples = ` # Render my-package-dir with network access enabled for functions $ kpt fn render --allow-network + + # Example Kptfile with save-on-render-failure annotation + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: + name: my-package + annotations: + kpt.dev/save-on-render-failure: "true" + ... ` var SinkShort = `Write resources to a local directory` @@ -318,7 +337,7 @@ var SinkExamples = ` # read resources from DIR directory, execute my-fn on them and write the # output to DIR directory. $ kpt fn source DIR | - kpt fn eval - --image gcr.io/example.com/my-fn | + kpt fn eval - --image ghcr.io/example.com/my-fn | kpt fn sink NEW_DIR ` @@ -354,6 +373,6 @@ var SourceExamples = ` # read resources from DIR directory, execute my-fn on them and write the # output to DIR directory. $ kpt fn source DIR | - kpt fn eval - --image gcr.io/example.com/my-fn - | + kpt fn eval - --image ghcr.io/example.com/my-fn - | kpt fn sink DIR ` diff --git a/internal/docs/generated/wasmdocs/docs.go b/internal/docs/generated/wasmdocs/docs.go index a4f6e1fe67..4e2e51ac34 100644 --- a/internal/docs/generated/wasmdocs/docs.go +++ b/internal/docs/generated/wasmdocs/docs.go @@ -18,8 +18,8 @@ Args: The desired path for the wasm file. e.g. /tmp/my-fn.wasm ` var PullExamples = ` - # pull image gcr.io/my-org/my-fn:v1.0.0 and decompress it to ./my-fn.wasm - $ kpt alpha wasm pull gcr.io/my-org/my-fn:v1.0.0 ./my-fn.wasm + # pull image ghcr.io/my-org/my-fn:v1.0.0 and decompress it to ./my-fn.wasm + $ kpt alpha wasm pull ghcr.io/my-org/my-fn:v1.0.0 ./my-fn.wasm ` var PushShort = `Compress a WASM module and push it as an OCI image.` @@ -34,6 +34,6 @@ Args: The desired name of an image. It must be a tag. ` var PushExamples = ` - # compress ./my-fn.wasm and push it to gcr.io/my-org/my-fn:v1.0.0 - $ kpt alpha wasm push ./my-fn.wasm gcr.io/my-org/my-fn:v1.0.0 + # compress ./my-fn.wasm and push it to ghcr.io/my-org/my-fn:v1.0.0 + $ kpt alpha wasm push ./my-fn.wasm ghcr.io/my-org/my-fn:v1.0.0 ` diff --git a/internal/fnruntime/jsglue.go b/internal/fnruntime/jsglue.go index e95b4ac5ca..ddbd7a7df3 100644 --- a/internal/fnruntime/jsglue.go +++ b/internal/fnruntime/jsglue.go @@ -234,7 +234,7 @@ const crypto = require('crypto'); } const timeOrigin = Date.now() - performance.now(); this.importObject = { - go: { + gojs: { // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters) // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function). @@ -456,6 +456,8 @@ const crypto = require('crypto'); }, } }; + // Expose imports under both "gojs" (Go 1.21+) and "go" (Go <1.21) + this.importObject.go = this.importObject.gojs; } async run(instance) { if (!(instance instanceof WebAssembly.Instance)) { diff --git a/internal/testutil/testdata/dataset1/java/java-deployment.resource.yaml b/internal/testutil/testdata/dataset1/java/java-deployment.resource.yaml index 8ea360a92a..7a18954b5f 100644 --- a/internal/testutil/testdata/dataset1/java/java-deployment.resource.yaml +++ b/internal/testutil/testdata/dataset1/java/java-deployment.resource.yaml @@ -30,7 +30,7 @@ spec: restartPolicy: Always containers: - name: app - image: gcr.io/project/app:version + image: ghcr.io/project/app:version command: - java - -jar diff --git a/internal/testutil/testdata/dataset1/mysql/mysql-statefulset.resource.yaml b/internal/testutil/testdata/dataset1/mysql/mysql-statefulset.resource.yaml index 90685c3518..8a3013f1c0 100644 --- a/internal/testutil/testdata/dataset1/mysql/mysql-statefulset.resource.yaml +++ b/internal/testutil/testdata/dataset1/mysql/mysql-statefulset.resource.yaml @@ -52,7 +52,7 @@ spec: - name: config-map mountPath: /mnt/config-map - name: clone-mysql - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c @@ -113,7 +113,7 @@ spec: periodSeconds: 2 timeoutSeconds: 1 - name: xtrabackup - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c diff --git a/internal/testutil/testdata/dataset2/java/java-deployment.resource.yaml b/internal/testutil/testdata/dataset2/java/java-deployment.resource.yaml index af6d0d7f4b..3b7e1d9d81 100644 --- a/internal/testutil/testdata/dataset2/java/java-deployment.resource.yaml +++ b/internal/testutil/testdata/dataset2/java/java-deployment.resource.yaml @@ -30,7 +30,7 @@ spec: restartPolicy: Always containers: - name: app - image: gcr.io/project/app:version + image: ghcr.io/project/app:version command: - java - -jar diff --git a/internal/testutil/testdata/dataset2/mysql/mysql-statefulset.resource.yaml b/internal/testutil/testdata/dataset2/mysql/mysql-statefulset.resource.yaml index 800cc5da11..78c63b58a1 100644 --- a/internal/testutil/testdata/dataset2/mysql/mysql-statefulset.resource.yaml +++ b/internal/testutil/testdata/dataset2/mysql/mysql-statefulset.resource.yaml @@ -52,7 +52,7 @@ spec: - name: config-map mountPath: /mnt/config-map - name: clone-mysql - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c @@ -113,7 +113,7 @@ spec: periodSeconds: 2 timeoutSeconds: 1 - name: xtrabackup - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c diff --git a/internal/testutil/testdata/dataset3/java/java-deployment.resource.yaml b/internal/testutil/testdata/dataset3/java/java-deployment.resource.yaml index cf9dbcc566..867079aa1f 100644 --- a/internal/testutil/testdata/dataset3/java/java-deployment.resource.yaml +++ b/internal/testutil/testdata/dataset3/java/java-deployment.resource.yaml @@ -30,7 +30,7 @@ spec: restartPolicy: Always containers: - name: app - image: gcr.io/project/app:version + image: ghcr.io/project/app:version command: - java - -jar diff --git a/internal/testutil/testdata/dataset3/mysql/mysql-statefulset.resource.yaml b/internal/testutil/testdata/dataset3/mysql/mysql-statefulset.resource.yaml index 800cc5da11..78c63b58a1 100644 --- a/internal/testutil/testdata/dataset3/mysql/mysql-statefulset.resource.yaml +++ b/internal/testutil/testdata/dataset3/mysql/mysql-statefulset.resource.yaml @@ -52,7 +52,7 @@ spec: - name: config-map mountPath: /mnt/config-map - name: clone-mysql - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c @@ -113,7 +113,7 @@ spec: periodSeconds: 2 timeoutSeconds: 1 - name: xtrabackup - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c diff --git a/internal/testutil/testdata/dataset4/java/java-deployment.resource.yaml b/internal/testutil/testdata/dataset4/java/java-deployment.resource.yaml index af6d0d7f4b..3b7e1d9d81 100644 --- a/internal/testutil/testdata/dataset4/java/java-deployment.resource.yaml +++ b/internal/testutil/testdata/dataset4/java/java-deployment.resource.yaml @@ -30,7 +30,7 @@ spec: restartPolicy: Always containers: - name: app - image: gcr.io/project/app:version + image: ghcr.io/project/app:version command: - java - -jar diff --git a/internal/testutil/testdata/dataset4/mysql/mysql-statefulset.resource.yaml b/internal/testutil/testdata/dataset4/mysql/mysql-statefulset.resource.yaml index 41a6a4b6ca..cda1cc1db1 100644 --- a/internal/testutil/testdata/dataset4/mysql/mysql-statefulset.resource.yaml +++ b/internal/testutil/testdata/dataset4/mysql/mysql-statefulset.resource.yaml @@ -52,7 +52,7 @@ spec: - name: config-map mountPath: /mnt/config-map - name: clone-mysql - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c @@ -113,7 +113,7 @@ spec: periodSeconds: 2 timeoutSeconds: 1 - name: xtrabackup - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c diff --git a/internal/testutil/testdata/dataset5/java/java-deployment.resource.yaml b/internal/testutil/testdata/dataset5/java/java-deployment.resource.yaml index af6d0d7f4b..3b7e1d9d81 100644 --- a/internal/testutil/testdata/dataset5/java/java-deployment.resource.yaml +++ b/internal/testutil/testdata/dataset5/java/java-deployment.resource.yaml @@ -30,7 +30,7 @@ spec: restartPolicy: Always containers: - name: app - image: gcr.io/project/app:version + image: ghcr.io/project/app:version command: - java - -jar diff --git a/internal/testutil/testdata/dataset5/mysql/mysql-statefulset.resource.yaml b/internal/testutil/testdata/dataset5/mysql/mysql-statefulset.resource.yaml index 800cc5da11..78c63b58a1 100644 --- a/internal/testutil/testdata/dataset5/mysql/mysql-statefulset.resource.yaml +++ b/internal/testutil/testdata/dataset5/mysql/mysql-statefulset.resource.yaml @@ -52,7 +52,7 @@ spec: - name: config-map mountPath: /mnt/config-map - name: clone-mysql - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c @@ -113,7 +113,7 @@ spec: periodSeconds: 2 timeoutSeconds: 1 - name: xtrabackup - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c diff --git a/internal/testutil/testdata/dataset6/java/java-deployment.resource.yaml b/internal/testutil/testdata/dataset6/java/java-deployment.resource.yaml index af6d0d7f4b..3b7e1d9d81 100644 --- a/internal/testutil/testdata/dataset6/java/java-deployment.resource.yaml +++ b/internal/testutil/testdata/dataset6/java/java-deployment.resource.yaml @@ -30,7 +30,7 @@ spec: restartPolicy: Always containers: - name: app - image: gcr.io/project/app:version + image: ghcr.io/project/app:version command: - java - -jar diff --git a/internal/testutil/testdata/dataset6/mysql/mysql-statefulset.resource.yaml b/internal/testutil/testdata/dataset6/mysql/mysql-statefulset.resource.yaml index 800cc5da11..78c63b58a1 100644 --- a/internal/testutil/testdata/dataset6/mysql/mysql-statefulset.resource.yaml +++ b/internal/testutil/testdata/dataset6/mysql/mysql-statefulset.resource.yaml @@ -52,7 +52,7 @@ spec: - name: config-map mountPath: /mnt/config-map - name: clone-mysql - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c @@ -113,7 +113,7 @@ spec: periodSeconds: 2 timeoutSeconds: 1 - name: xtrabackup - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c diff --git a/internal/testutil/testdata/datasetmerged/java/java-deployment.resource.yaml b/internal/testutil/testdata/datasetmerged/java/java-deployment.resource.yaml index 4ca0837561..67aa01f855 100644 --- a/internal/testutil/testdata/datasetmerged/java/java-deployment.resource.yaml +++ b/internal/testutil/testdata/datasetmerged/java/java-deployment.resource.yaml @@ -30,7 +30,7 @@ spec: restartPolicy: Always containers: - name: app - image: gcr.io/project/app:version + image: ghcr.io/project/app:version command: - java - -jar diff --git a/internal/testutil/testdata/datasetmerged/mysql/mysql-statefulset.resource.yaml b/internal/testutil/testdata/datasetmerged/mysql/mysql-statefulset.resource.yaml index 800cc5da11..78c63b58a1 100644 --- a/internal/testutil/testdata/datasetmerged/mysql/mysql-statefulset.resource.yaml +++ b/internal/testutil/testdata/datasetmerged/mysql/mysql-statefulset.resource.yaml @@ -52,7 +52,7 @@ spec: - name: config-map mountPath: /mnt/config-map - name: clone-mysql - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c @@ -113,7 +113,7 @@ spec: periodSeconds: 2 timeoutSeconds: 1 - name: xtrabackup - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c diff --git a/internal/testutil/testdata/updateMergeConflict/java/java-deployment.resource.yaml b/internal/testutil/testdata/updateMergeConflict/java/java-deployment.resource.yaml index af9af07c42..2f2c9928aa 100644 --- a/internal/testutil/testdata/updateMergeConflict/java/java-deployment.resource.yaml +++ b/internal/testutil/testdata/updateMergeConflict/java/java-deployment.resource.yaml @@ -30,7 +30,7 @@ spec: restartPolicy: Always containers: - name: app - image: gcr.io/project/app:version + image: ghcr.io/project/app:version command: - java - -jar diff --git a/internal/testutil/testdata/updateMergeConflict/mysql/mysql-statefulset.resource.yaml b/internal/testutil/testdata/updateMergeConflict/mysql/mysql-statefulset.resource.yaml index 0de3847248..91df32e98b 100644 --- a/internal/testutil/testdata/updateMergeConflict/mysql/mysql-statefulset.resource.yaml +++ b/internal/testutil/testdata/updateMergeConflict/mysql/mysql-statefulset.resource.yaml @@ -52,7 +52,7 @@ spec: - name: config-map mountPath: /mnt/config-map - name: clone-mysql - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c @@ -113,7 +113,7 @@ spec: periodSeconds: 2 timeoutSeconds: 1 - name: xtrabackup - image: gcr.io/google-samples/xtrabackup:1.0 + image: ghcr.io/google-samples/xtrabackup:1.0 command: - bash - -c diff --git a/thirdparty/cmdconfig/commands/cmdsink/cmdsink_test.go b/thirdparty/cmdconfig/commands/cmdsink/cmdsink_test.go index 43d8d67c1f..1d64d8df2b 100644 --- a/thirdparty/cmdconfig/commands/cmdsink/cmdsink_test.go +++ b/thirdparty/cmdconfig/commands/cmdsink/cmdsink_test.go @@ -56,7 +56,7 @@ items: annotations: config.kubernetes.io/function: | container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 config.kubernetes.io/local-config: "true" config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' @@ -119,7 +119,7 @@ metadata: annotations: config.kubernetes.io/function: | container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 config.kubernetes.io/local-config: "true" spec: replicas: 3 diff --git a/thirdparty/cmdconfig/commands/cmdsource/cmdsource_test.go b/thirdparty/cmdconfig/commands/cmdsource/cmdsource_test.go index 79384ca295..8348b9d583 100644 --- a/thirdparty/cmdconfig/commands/cmdsource/cmdsource_test.go +++ b/thirdparty/cmdconfig/commands/cmdsource/cmdsource_test.go @@ -52,7 +52,7 @@ metadata: annotations: config.kubernetes.io/function: | container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 config.kubernetes.io/local-config: "true" spec: replicas: 3 @@ -117,7 +117,7 @@ items: annotations: config.kubernetes.io/function: | container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 config.kubernetes.io/local-config: "true" config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' @@ -320,7 +320,7 @@ metadata: annotations: config.kubernetes.io/function: | container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 config.kubernetes.io/local-config: "true" spec: replicas: 3 @@ -388,7 +388,7 @@ items: annotations: config.kubernetes.io/function: | container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 config.kubernetes.io/local-config: "true" config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' @@ -451,7 +451,7 @@ func TestSourceCommandJSON(t *testing.T) { "metadata": { "name": "foo", "annotations": { - "config.kubernetes.io/function": "container:\n image: gcr.io/example/reconciler:v1\n", + "config.kubernetes.io/function": "container:\n image: ghcr.io/example/reconciler:v1\n", "config.kubernetes.io/local-config": "true" } }, @@ -478,7 +478,7 @@ func TestSourceCommandJSON(t *testing.T) { kind: ResourceList items: - {"kind": "Deployment", "metadata": {"labels": {"app": "nginx2"}, "name": "foo", "annotations": {"app": "nginx2", config.kubernetes.io/index: '0', config.kubernetes.io/path: 'f1.json', internal.config.kubernetes.io/index: '0', internal.config.kubernetes.io/path: 'f1.json', internal.config.kubernetes.io/seqindent: 'compact'}}, "spec": {"replicas": 1}} -- {"apiVersion": "v1", "kind": "Abstraction", "metadata": {"name": "foo", "annotations": {"config.kubernetes.io/function": "container:\n image: gcr.io/example/reconciler:v1\n", "config.kubernetes.io/local-config": "true", config.kubernetes.io/index: '0', config.kubernetes.io/path: 'f2.json', internal.config.kubernetes.io/index: '0', internal.config.kubernetes.io/path: 'f2.json', internal.config.kubernetes.io/seqindent: 'compact'}}, "spec": {"replicas": 3}} +- {"apiVersion": "v1", "kind": "Abstraction", "metadata": {"name": "foo", "annotations": {"config.kubernetes.io/function": "container:\n image: ghcr.io/example/reconciler:v1\n", "config.kubernetes.io/local-config": "true", config.kubernetes.io/index: '0', config.kubernetes.io/path: 'f2.json', internal.config.kubernetes.io/index: '0', internal.config.kubernetes.io/path: 'f2.json', internal.config.kubernetes.io/seqindent: 'compact'}}, "spec": {"replicas": 3}} ` if !assert.Equal(t, expected, b.String()) { @@ -531,7 +531,7 @@ metadata: annotations: config.kubernetes.io/function: | container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 config.kubernetes.io/local-config: "true" spec: replicas: 3 @@ -597,7 +597,7 @@ items: annotations: config.kubernetes.io/function: | container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 config.kubernetes.io/local-config: "true" config.kubernetes.io/index: '0' config.kubernetes.io/path: 'f2.yaml' diff --git a/thirdparty/cmdconfig/commands/cmdtree/cmdtree_test.go b/thirdparty/cmdconfig/commands/cmdtree/cmdtree_test.go index 2533590a02..d9456b41fd 100644 --- a/thirdparty/cmdconfig/commands/cmdtree/cmdtree_test.go +++ b/thirdparty/cmdconfig/commands/cmdtree/cmdtree_test.go @@ -31,7 +31,7 @@ metadata: name: foo configFn: container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 annotations: config.kubernetes.io/local-config: "true" spec: @@ -106,7 +106,7 @@ metadata: name: foo configFn: container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 annotations: config.kubernetes.io/local-config: "true" spec: @@ -232,7 +232,7 @@ metadata: name: foo configFn: container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 annotations: config.kubernetes.io/local-config: "true" spec: @@ -418,7 +418,7 @@ metadata: name: foo configFn: container: - image: gcr.io/example/reconciler:v1 + image: ghcr.io/example/reconciler:v1 annotations: config.kubernetes.io/local-config: "true" spec: diff --git a/thirdparty/kyaml/runfn/runfn_test.go b/thirdparty/kyaml/runfn/runfn_test.go index 704fad8196..fec8c00b71 100644 --- a/thirdparty/kyaml/runfn/runfn_test.go +++ b/thirdparty/kyaml/runfn/runfn_test.go @@ -131,7 +131,7 @@ func TestCmd_Execute(t *testing.T) { } fn := &runtimeutil.FunctionSpec{ Container: runtimeutil.ContainerSpec{ - Image: "gcr.io/example.com/image:version", + Image: "ghcr.io/example.com/image:version", }, } @@ -164,7 +164,7 @@ func TestCmd_Execute_includeMetaResources(t *testing.T) { } fn := &runtimeutil.FunctionSpec{ Container: runtimeutil.ContainerSpec{ - Image: "gcr.io/example.com/image:version", + Image: "ghcr.io/example.com/image:version", }, } @@ -288,7 +288,7 @@ func TestCmd_Execute_setFnConfigPath(t *testing.T) { } fn := &runtimeutil.FunctionSpec{ Container: runtimeutil.ContainerSpec{ - Image: "gcr.io/example.com/image:version", + Image: "ghcr.io/example.com/image:version", }, } @@ -328,7 +328,7 @@ func TestCmd_Execute_setOutput(t *testing.T) { } fn := &runtimeutil.FunctionSpec{ Container: runtimeutil.ContainerSpec{ - Image: "gcr.io/example.com/image:version", + Image: "ghcr.io/example.com/image:version", }, } @@ -367,7 +367,7 @@ func TestCmd_Execute_setInput(t *testing.T) { } fn := &runtimeutil.FunctionSpec{ Container: runtimeutil.ContainerSpec{ - Image: "gcr.io/example.com/image:version", + Image: "ghcr.io/example.com/image:version", }, } diff --git a/thirdparty/kyaml/runfn/test/testdata/java/java-deployment.resource.yaml b/thirdparty/kyaml/runfn/test/testdata/java/java-deployment.resource.yaml index d03d3a48d7..d95247918b 100644 --- a/thirdparty/kyaml/runfn/test/testdata/java/java-deployment.resource.yaml +++ b/thirdparty/kyaml/runfn/test/testdata/java/java-deployment.resource.yaml @@ -18,7 +18,7 @@ spec: restartPolicy: Always containers: - name: app - image: gcr.io/project/app:version + image: ghcr.io/project/app:version command: - java - -jar From 2c2d696775a848daba8a541c78515a7d5bd482c1 Mon Sep 17 00:00:00 2001 From: Aravindhan Ayyanathan Date: Mon, 16 Mar 2026 19:17:07 +0000 Subject: [PATCH 09/14] Add render status conditions to Kptfile (#4418) * Add status.conditions to show the renderstatus to Kptfile Signed-off-by: aravind.est * Address copilot and dosubot comments Signed-off-by: aravind.est --------- Signed-off-by: aravind.est --- .../content/en/book/02-concepts/_index.md | 34 ++++ .../content/en/book/03-packages/_index.md | 19 +- .../en/book/04-using-functions/_index.md | 48 ++++++ .../en/reference/cli/fn/render/_index.md | 54 ++++++ .../.expected/diff.patch | 2 +- .../.expected/diff.patch | 2 +- .../.expected/diff.patch | 11 +- .../basicpipeline-semver/.expected/diff.patch | 18 +- .../.expected/diff.patch | 11 +- .../basicpipeline-wasm/.expected/diff.patch | 22 +++ .../basicpipeline/.expected/diff.patch | 11 +- .../default-runtime/.expected/diff.patch | 11 +- .../exec-function-stderr/.expected/diff.patch | 15 ++ .../.expected/diff.patch | 11 +- .../.expected/diff.patch | 18 ++ .../.expected/diff.patch | 16 ++ .../fn-render/fn-failure/.expected/diff.patch | 33 ++++ .../.expected/diff.patch | 13 ++ .../.expected/diff.patch | 11 +- .../.expected/diff.patch | 18 ++ .../fnconfig-in-subdir/.expected/diff.patch | 10 +- .../.expected/diff.patch | 10 +- .../.expected/diff.patch | 11 +- .../fn-render/fnconfig/.expected/diff.patch | 11 +- .../fnresult-fn-failure/.expected/diff.patch | 16 ++ .../fnresult-fn-success/.expected/diff.patch | 13 ++ .../format-on-success/.expected/diff.patch | 11 +- .../.expected/diff.patch | 13 ++ .../fn-render/generator/.expected/diff.patch | 11 +- .../.expected/diff.patch | 16 ++ .../.expected/diff.patch | 11 +- .../kubeval-failure/.expected/diff.patch | 16 ++ .../missing-fn-image/.expected/diff.patch | 20 +++ .../.expected/diff.patch | 19 +- .../.expected/diff.patch | 17 ++ .../.expected/diff.patch | 13 ++ .../mutate-path-index/.expected/diff.patch | 13 ++ .../no-fnconfig/.expected/diff.patch | 16 ++ .../fn-render/no-op/.expected/diff.patch | 13 ++ .../.expected/diff.patch | 11 +- .../no-resources/.expected/diff.patch | 13 ++ .../.expected/diff.patch | 14 ++ .../non-krm-resource/.expected/diff.patch | 16 ++ .../.expected/diff.patch | 0 .../.expected/diff.patch | 0 .../.expected/diff.patch | 0 .../out-of-place-stdout/.expected/diff.patch | 0 .../out-of-place-unwrap/.expected/diff.patch | 0 .../path-index-ancestor/.expected/diff.patch | 16 ++ .../path-index-current/.expected/diff.patch | 13 ++ .../.expected/diff.patch | 13 ++ .../path-index-duplicate/.expected/diff.patch | 16 ++ .../.expected/diff.patch | 16 ++ .../preserve-comments/.expected/diff.patch | 13 ++ .../.expected/diff.patch | 11 +- .../resource-deletion/.expected/diff.patch | 11 +- .../.expected/diff.patch | 11 +- .../bfs-basicpipeline/.expected/diff.patch | 41 ++++- .../.expected/diff.patch | 23 ++- .../.expected/diff.patch | 27 ++- .../.expected/diff.patch | 27 ++- .../.expected/diff.patch | 23 ++- .../.expected/diff.patch | 23 ++- .../.expected/diff.patch | 23 ++- .../.expected/diff.patch | 25 ++- .../dfs-basicpipeline/.expected/diff.patch | 40 ++++- .../.expected/diff.patch | 28 +++ .../.expected/diff.patch | 27 +++ .../.expected/diff.patch | 27 +++ .../.expected/diff.patch | 22 ++- .../.expected/diff.patch | 22 ++- .../.expected/diff.patch | 28 +++ .../.expected/diff.patch | 30 ++++ .../.expected/diff.patch | 34 ++++ .../basicpipeline/.expected/diff.patch | 19 +- .../selectors/exclude/.expected/diff.patch | 22 +++ .../selectors/generator/.expected/diff.patch | 13 ++ .../.expected/diff.patch | 13 +- .../short-image-path/.expected/diff.patch | 11 +- .../short-image-path/.expected/results.yaml | 1 - .../.expected/diff.patch | 16 ++ .../subpkg-fn-failure/.expected/diff.patch | 16 ++ .../.expected/diff.patch | 16 ++ .../.expected/diff.patch | 13 ++ .../.expected/diff.patch | 11 +- .../.expected/diff.patch | 11 +- .../fn-render/subpkgs/.expected/diff.patch | 11 +- .../success-stdout/.expected/diff.patch | 11 +- .../.expected/diff.patch | 13 ++ .../.expected/diff.patch | 19 ++ internal/util/render/executor.go | 57 +++++- internal/util/render/executor_test.go | 162 +++++++++++++++++- pkg/api/kptfile/v1/types.go | 17 ++ pkg/kptfile/kptfileutil/util.go | 21 ++- 94 files changed, 1652 insertions(+), 103 deletions(-) create mode 100644 e2e/testdata/fn-render/exec-without-permissions/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/fn-failure-output-no-truncate/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/fn-failure/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/fn-success-with-stderr/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/fnconfig-cannot-refer-subpkgs/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/fnresult-fn-failure/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/image-pull-policy-never/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/kubeval-failure/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/missing-fn-image/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/no-fnconfig/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/no-op/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/non-krm-resource-no-pipeline/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/non-krm-resource/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/out-of-place-fnchain-stdout-results/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/out-of-place-fnchain-stdout/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/out-of-place-fnchain-unwrap/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/out-of-place-stdout/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/out-of-place-unwrap/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/path-index-ancestor/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/path-index-duplicate/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/path-index-outofpackage/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/preserve-comments/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/structured-results-from-muiltiple-fns/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/subpkg-fn-failure/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/subpkg-has-invalid-kptfile/.expected/diff.patch create mode 100644 e2e/testdata/fn-render/validate-resource-failure/.expected/diff.patch diff --git a/documentation/content/en/book/02-concepts/_index.md b/documentation/content/en/book/02-concepts/_index.md index 2629f859d8..7d5e32c03b 100644 --- a/documentation/content/en/book/02-concepts/_index.md +++ b/documentation/content/en/book/02-concepts/_index.md @@ -98,6 +98,40 @@ the default depth-first post-order. rendering fails, instead of reverting all changes. This is particularly useful for debugging render failures and is essential for programmatic package rendering scenarios where preserving partial progress is valuable. +### Status Conditions +The Kptfile includes a `status.conditions` field that provides a declarative way to track the execution status of kpt +operations. This makes package management operations observable and traceable. + +When `kpt fn render` executes, a `Rendered` status condition is automatically added to the root Kptfile to indicate +whether the rendering operation succeeded or failed. +This status is recorded only for in-place renders (the default behavior). +It is not written for out-of-place modes such as stdout (`-o stdout`), unwrap (`-o unwrap`), or +directory output (`-o `). + +**On successful render:** +```yaml +status: + conditions: + - type: Rendered + status: "True" + reason: RenderSuccess +``` + +**On failed render:** +```yaml +status: + conditions: + - type: Rendered + status: "False" + reason: RenderFailed + message: |- + pkg.render: pkg .: + pipeline.run: must run with `--allow-exec` option to allow running function binaries +``` + +The status condition is recorded only in the root Kptfile, not in subpackages. The error message in failure cases +provides details about what went wrong during the render operation. + Just as directories can be nested, a package can contain another package, called a _subpackage_. Let's take a look at the wordpress package as an example: diff --git a/documentation/content/en/book/03-packages/_index.md b/documentation/content/en/book/03-packages/_index.md index 816fdd4f90..62432b8c4e 100644 --- a/documentation/content/en/book/03-packages/_index.md +++ b/documentation/content/en/book/03-packages/_index.md @@ -63,9 +63,14 @@ pipeline: app: wordpress validators: - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest +status: + conditions: + - type: Rendered + status: "True" + reason: RenderSuccess ``` -The `Kptfile` contains two sections to keep track of the upstream package: +The `Kptfile` contains several sections to keep track of the package and its state: 1. The `upstream` section contains the user-specified Git reference to the upstream package. This contains three pieces of information: @@ -76,6 +81,10 @@ The `Kptfile` contains two sections to keep track of the upstream package: or commit SHA. 2. The `upstreamLock` section records the upstream Git reference (exact Git SHA) that was fetched by kpt. This section is managed by kpt and should not be changed manually. +3. The `status` section records the operational state of the package. This is managed by kpt and tracks the execution + status of operations like `render`. The `status.conditions` field contains a list of condition objects, similar to + how Kubernetes tracks conditions on resources. For example, after running `kpt fn render`, a `Rendered` condition + is automatically recorded to indicate whether the last render succeeded or failed. Now, let's look at the `Kptfile` for the `mysql` subpackage: @@ -239,6 +248,14 @@ perform the following steps: formatting of resources, even though a function (developed by different people using different toolchains) may have modified the formatting in some way. +4. Records the render execution status in the root `Kptfile` as a `Rendered` condition + under `status.conditions`. On success, the condition has `status: "True"` and + `reason: RenderSuccess`. On failure, it has `status: "False"`, `reason: RenderFailed`, + and includes error details in the `message` field. + +Note that status conditions are only written for in-place renders (the default behavior). +When using out-of-place output modes like `kpt fn render -o stdout` or `kpt fn render -o `, +no status condition is written since the package is not being updated on disk. [Chapter 4](../04-using-functions/) discusses different ways of running functions in detail. diff --git a/documentation/content/en/book/04-using-functions/_index.md b/documentation/content/en/book/04-using-functions/_index.md index b2ec711e7b..75ca80115f 100644 --- a/documentation/content/en/book/04-using-functions/_index.md +++ b/documentation/content/en/book/04-using-functions/_index.md @@ -124,6 +124,54 @@ The end result is that: 3. Resources in `mysql` and `wordpress` packages are validated against their OpenAPI spec. + +### Render status tracking + +After each `kpt fn render` execution, kpt records the render status in the root package's `Kptfile`. This provides +visibility into whether the most recent render succeeded or failed, which is helpful for debugging and +tracking the state of your package. + +The render status is recorded as a `Rendered` condition in the `status.conditions` section of the root `Kptfile`: + +**On success:** + +```yaml +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: wordpress +pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:latest + configMap: + app: wordpress + validators: + - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest +status: + conditions: + - type: Rendered + status: "True" + reason: RenderSuccess +``` + +**On failure:** + +```yaml +status: + conditions: + - type: Rendered + status: "False" + reason: RenderFailed + message: |- + pkg.render: pkg .: + pipeline.run: must run with `--allow-exec` option to allow running function binaries +``` + +The render status is recorded only when performing in-place rendering (the default mode). It is not recorded when using +out-of-place modes such as `--output stdout`, `--output unwrap`, or `--output `. + +You can inspect the render status by examining the root `Kptfile` to understand the result of the most recent render operation. + ### Debugging render failures When a render pipeline fails, you can configure the package to save partially rendered resources to disk. diff --git a/documentation/content/en/reference/cli/fn/render/_index.md b/documentation/content/en/reference/cli/fn/render/_index.md index 4cde120dab..e45930d290 100644 --- a/documentation/content/en/reference/cli/fn/render/_index.md +++ b/documentation/content/en/reference/cli/fn/render/_index.md @@ -95,6 +95,60 @@ KRM_FN_RUNTIME: +### Render Status Conditions + +After every `kpt fn render` execution, a `Rendered` status condition is recorded in the root Kptfile's +`status.conditions` field to track the render execution history. This helps users quickly identify whether +the last render succeeded or failed. + +#### Behavior + +- **Success**: When rendering completes successfully, the Kptfile receives a condition with `type: Rendered`, +`status: "True"`, and `reason: RenderSuccess`. +- **Failure**: When rendering fails, the Kptfile receives a condition with `type: Rendered`, `status: "False"`, +`reason: RenderFailed`, and a `message` field containing the error details. +- **In-place render only**: The status condition is written only when rendering in-place (the default behavior). +It is NOT written when using out-of-place modes: `-o stdout`, `-o unwrap`, or `-o `, since these modes +do not modify the on-disk package. +- **Always recorded**: The status is recorded regardless of the `kpt.dev/save-on-render-failure` annotation setting. +- **Root Kptfile only**: The status condition is written only to the root Kptfile, not to subpackages. + +#### Success Example + +After a successful render, the root Kptfile will contain: + +```yaml +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: my-package +status: + conditions: + - type: Rendered + status: "True" + reason: RenderSuccess +``` + +#### Failure Example + +After a failed render, the root Kptfile will contain: + +```yaml +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: my-package +status: + conditions: + - type: Rendered + status: "False" + reason: RenderFailed + message: |- + pkg.render: pkg .: + pipeline.run: must run with `--allow-exec` option to allow running function binaries +``` + + ### Examples diff --git a/e2e/testdata/fn-eval/save-fn/preserve-kptfile-comments/.expected/diff.patch b/e2e/testdata/fn-eval/save-fn/preserve-kptfile-comments/.expected/diff.patch index 1815663355..b11dad7983 100644 --- a/e2e/testdata/fn-eval/save-fn/preserve-kptfile-comments/.expected/diff.patch +++ b/e2e/testdata/fn-eval/save-fn/preserve-kptfile-comments/.expected/diff.patch @@ -30,4 +30,4 @@ index eed43d6..81473ca 100644 name: custom + namespace: staging spec: - image: nginx:1.2.3 \ No newline at end of file + image: nginx:1.2.3 diff --git a/e2e/testdata/fn-eval/simple-function-with-tag/.expected/diff.patch b/e2e/testdata/fn-eval/simple-function-with-tag/.expected/diff.patch index 5371dee2ab..f3518b8417 100644 --- a/e2e/testdata/fn-eval/simple-function-with-tag/.expected/diff.patch +++ b/e2e/testdata/fn-eval/simple-function-with-tag/.expected/diff.patch @@ -9,4 +9,4 @@ index 1f15150..5966859 100644 + namespace: staging spec: replicas: 3 - --- \ No newline at end of file + --- diff --git a/e2e/testdata/fn-render/all-resource-deletion/.expected/diff.patch b/e2e/testdata/fn-render/all-resource-deletion/.expected/diff.patch index f8121fb91e..34218ae522 100644 --- a/e2e/testdata/fn-render/all-resource-deletion/.expected/diff.patch +++ b/e2e/testdata/fn-render/all-resource-deletion/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 3c93e9e..6fa7b45 100644 +index 3c93e9e..fe0bc96 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 3c93e9e..6fa7b45 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest +@@ -12,3 +15,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/delete-all.yaml b/delete-all.yaml index 3c86d8b..6754b0a 100644 --- a/delete-all.yaml diff --git a/e2e/testdata/fn-render/basicpipeline-semver/.expected/diff.patch b/e2e/testdata/fn-render/basicpipeline-semver/.expected/diff.patch index 754306a2b7..fea4f539a1 100644 --- a/e2e/testdata/fn-render/basicpipeline-semver/.expected/diff.patch +++ b/e2e/testdata/fn-render/basicpipeline-semver/.expected/diff.patch @@ -1,8 +1,8 @@ diff --git a/Kptfile b/Kptfile -index 2336da4..85f42f5 100644 +index 2336da4..eae3be3 100644 --- a/Kptfile +++ b/Kptfile -@@ -2,6 +2,8 @@ apiVersion: kpt.dev/v1 +@@ -2,13 +2,20 @@ apiVersion: kpt.dev/v1 kind: Kptfile metadata: name: app @@ -11,6 +11,20 @@ index 2336da4..85f42f5 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace +- tag: "0.4.1 - 0.4.3" + configMap: + namespace: staging ++ tag: 0.4.1 - 0.4.3 + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels +- tag: "~0.2" + configMap: + tier: backend ++ tag: ~0.2 ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index 1f15150..936d957 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/basicpipeline-symlink/.expected/diff.patch b/e2e/testdata/fn-render/basicpipeline-symlink/.expected/diff.patch index a21c38b30e..16337308e3 100644 --- a/e2e/testdata/fn-render/basicpipeline-symlink/.expected/diff.patch +++ b/e2e/testdata/fn-render/basicpipeline-symlink/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 1307fb5..3a2c718 100644 +index 1307fb5..f645d75 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 1307fb5..3a2c718 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -10,3 +13,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index f2eec52..84cfb26 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch b/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch index 89e03e2827..33ebe1cf1c 100644 --- a/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch +++ b/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch @@ -1,3 +1,25 @@ +diff --git a/Kptfile b/Kptfile +index ffcf186..9c131fb 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,12 +6,14 @@ metadata: + tier: backend + pipeline: + mutators: +- # The following 2 images are built from https://github.com/kptdev/krm-functions-catalog/pull/898. + - image: gcr.io/kpt-fn-demo/set-namespace:v0.5.0 +- # ghcr.io/kptdev/krm-functions-catalog/wasm/set-namespace:v0.5.0 + configMap: + namespace: staging + - image: gcr.io/kpt-fn-demo/set-labels:v0.2.0 +- # ghcr.io/kptdev/krm-functions-catalog/wasm/set-labels:v0.2.0 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index eed43d6..c1de2b0 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/basicpipeline/.expected/diff.patch b/e2e/testdata/fn-render/basicpipeline/.expected/diff.patch index a21c38b30e..16337308e3 100644 --- a/e2e/testdata/fn-render/basicpipeline/.expected/diff.patch +++ b/e2e/testdata/fn-render/basicpipeline/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 1307fb5..3a2c718 100644 +index 1307fb5..f645d75 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 1307fb5..3a2c718 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -10,3 +13,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index f2eec52..84cfb26 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/default-runtime/.expected/diff.patch b/e2e/testdata/fn-render/default-runtime/.expected/diff.patch index a21c38b30e..16337308e3 100644 --- a/e2e/testdata/fn-render/default-runtime/.expected/diff.patch +++ b/e2e/testdata/fn-render/default-runtime/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 1307fb5..3a2c718 100644 +index 1307fb5..f645d75 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 1307fb5..3a2c718 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -10,3 +13,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index f2eec52..84cfb26 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/exec-function-stderr/.expected/diff.patch b/e2e/testdata/fn-render/exec-function-stderr/.expected/diff.patch index c35d542fb0..3174051755 100644 --- a/e2e/testdata/fn-render/exec-function-stderr/.expected/diff.patch +++ b/e2e/testdata/fn-render/exec-function-stderr/.expected/diff.patch @@ -1,3 +1,18 @@ +diff --git a/Kptfile b/Kptfile +index 6f2fe11..34a53c9 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -4,4 +4,9 @@ metadata: + name: app + pipeline: + mutators: +- - exec: "./testdata/fn-render/exec-function-stderr/function.sh" ++ - exec: ./testdata/fn-render/exec-function-stderr/function.sh ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index 0f69886..ff4bde7 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/exec-function-with-args/.expected/diff.patch b/e2e/testdata/fn-render/exec-function-with-args/.expected/diff.patch index c58020a874..d0bea1c78f 100644 --- a/e2e/testdata/fn-render/exec-function-with-args/.expected/diff.patch +++ b/e2e/testdata/fn-render/exec-function-with-args/.expected/diff.patch @@ -1,13 +1,18 @@ diff --git a/Kptfile b/Kptfile -index 0d98dbb..23bd061 100644 +index 0d98dbb..0dde5ad 100644 --- a/Kptfile +++ b/Kptfile -@@ -4,4 +4,4 @@ metadata: +@@ -4,4 +4,9 @@ metadata: name: app pipeline: mutators: - - exec: "sed -e 's/foo/bar/'" -+ - exec: "sed -e 's/bar/bar/'" ++ - exec: sed -e 's/bar/bar/' ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index 0f69886..ff4bde7 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/exec-without-permissions/.expected/diff.patch b/e2e/testdata/fn-render/exec-without-permissions/.expected/diff.patch new file mode 100644 index 0000000000..842b64bff6 --- /dev/null +++ b/e2e/testdata/fn-render/exec-without-permissions/.expected/diff.patch @@ -0,0 +1,18 @@ +diff --git a/Kptfile b/Kptfile +index 0d98dbb..aba9d69 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -4,4 +4,12 @@ metadata: + name: app + pipeline: + mutators: +- - exec: "sed -e 's/foo/bar/'" ++ - exec: sed -e 's/foo/bar/' ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: must run with `--allow-exec` option to allow running function binaries diff --git a/e2e/testdata/fn-render/fn-failure-output-no-truncate/.expected/diff.patch b/e2e/testdata/fn-render/fn-failure-output-no-truncate/.expected/diff.patch new file mode 100644 index 0000000000..9240aa57d5 --- /dev/null +++ b/e2e/testdata/fn-render/fn-failure-output-no-truncate/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 0586af9..30e8359 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -7,3 +7,11 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest + configMap: + strict: "true" ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/e2e/testdata/fn-render/fn-failure/.expected/diff.patch b/e2e/testdata/fn-render/fn-failure/.expected/diff.patch new file mode 100644 index 0000000000..f75cbdd706 --- /dev/null +++ b/e2e/testdata/fn-render/fn-failure/.expected/diff.patch @@ -0,0 +1,33 @@ +diff --git a/Kptfile b/Kptfile +index 3447ba3..2802b20 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -4,12 +4,19 @@ metadata: + name: app + pipeline: + mutators: +-# invalid starlark input results in failure of first fn +- - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest +- configPath: starlark-failure-fn.yaml +- - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +- configMap: +- namespace: staging +- - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 +- configMap: +- tier: backend ++ - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest ++ configPath: starlark-failure-fn.yaml ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 ++ configMap: ++ namespace: staging ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 ++ configMap: ++ tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/e2e/testdata/fn-render/fn-success-with-stderr/.expected/diff.patch b/e2e/testdata/fn-render/fn-success-with-stderr/.expected/diff.patch new file mode 100644 index 0000000000..75677018d7 --- /dev/null +++ b/e2e/testdata/fn-render/fn-success-with-stderr/.expected/diff.patch @@ -0,0 +1,13 @@ +diff --git a/Kptfile b/Kptfile +index f591880..b8c4faf 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,8 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: starlark.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/e2e/testdata/fn-render/fnconfig-ancestorfn-not-mutate-subpkg-config/.expected/diff.patch b/e2e/testdata/fn-render/fnconfig-ancestorfn-not-mutate-subpkg-config/.expected/diff.patch index 0201b51e87..bbae8e2da7 100644 --- a/e2e/testdata/fn-render/fnconfig-ancestorfn-not-mutate-subpkg-config/.expected/diff.patch +++ b/e2e/testdata/fn-render/fnconfig-ancestorfn-not-mutate-subpkg-config/.expected/diff.patch @@ -1,8 +1,8 @@ diff --git a/Kptfile b/Kptfile -index dbab15c..a37d10e 100644 +index dbab15c..18405ed 100644 --- a/Kptfile +++ b/Kptfile -@@ -2,6 +2,7 @@ apiVersion: kpt.dev/v1 +@@ -2,8 +2,14 @@ apiVersion: kpt.dev/v1 kind: Kptfile metadata: name: app-with-db @@ -10,6 +10,13 @@ index dbab15c..a37d10e 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 + configMap: + namespace: staging ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/Kptfile b/db/Kptfile index 093e789..dfe7f20 100644 --- a/db/Kptfile diff --git a/e2e/testdata/fn-render/fnconfig-cannot-refer-subpkgs/.expected/diff.patch b/e2e/testdata/fn-render/fnconfig-cannot-refer-subpkgs/.expected/diff.patch new file mode 100644 index 0000000000..e367388b3d --- /dev/null +++ b/e2e/testdata/fn-render/fnconfig-cannot-refer-subpkgs/.expected/diff.patch @@ -0,0 +1,18 @@ +diff --git a/Kptfile b/Kptfile +index 0bfdbb0..10e2d27 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,13 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configPath: db/labelconfig.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: | ++ pkg.render: pkg .: Kptfile is invalid: ++ Field: `pipeline.mutators[0].configPath` ++ Value: "db/labelconfig.yaml" ++ Reason: functionConfig must exist in the current package diff --git a/e2e/testdata/fn-render/fnconfig-in-subdir/.expected/diff.patch b/e2e/testdata/fn-render/fnconfig-in-subdir/.expected/diff.patch index e81f73f1cc..148387c37b 100644 --- a/e2e/testdata/fn-render/fnconfig-in-subdir/.expected/diff.patch +++ b/e2e/testdata/fn-render/fnconfig-in-subdir/.expected/diff.patch @@ -1,8 +1,8 @@ diff --git a/Kptfile b/Kptfile -index 0bfdbb0..69acc11 100644 +index 0bfdbb0..2ad56e8 100644 --- a/Kptfile +++ b/Kptfile -@@ -2,6 +2,8 @@ apiVersion: kpt.dev/v1 +@@ -2,7 +2,14 @@ apiVersion: kpt.dev/v1 kind: Kptfile metadata: name: app-with-db @@ -11,6 +11,12 @@ index 0bfdbb0..69acc11 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configPath: db/labelconfig.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/labelconfig.yaml b/db/labelconfig.yaml index 22d2de2..19e0746 100644 --- a/db/labelconfig.yaml diff --git a/e2e/testdata/fn-render/fnconfig-pkgfn-refers-subdir/.expected/diff.patch b/e2e/testdata/fn-render/fnconfig-pkgfn-refers-subdir/.expected/diff.patch index acfd29847a..5d24d222ce 100644 --- a/e2e/testdata/fn-render/fnconfig-pkgfn-refers-subdir/.expected/diff.patch +++ b/e2e/testdata/fn-render/fnconfig-pkgfn-refers-subdir/.expected/diff.patch @@ -1,8 +1,8 @@ diff --git a/Kptfile b/Kptfile -index c2cf3ba..81422f3 100644 +index c2cf3ba..9f17a64 100644 --- a/Kptfile +++ b/Kptfile -@@ -2,6 +2,8 @@ apiVersion: kpt.dev/v1 +@@ -2,7 +2,14 @@ apiVersion: kpt.dev/v1 kind: Kptfile metadata: name: app-with-db @@ -11,6 +11,12 @@ index c2cf3ba..81422f3 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configPath: confs/labelconfig.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/confs/labelconfig.yaml b/confs/labelconfig.yaml index 22d2de2..19e0746 100644 --- a/confs/labelconfig.yaml diff --git a/e2e/testdata/fn-render/fnconfig-updated-in-render/.expected/diff.patch b/e2e/testdata/fn-render/fnconfig-updated-in-render/.expected/diff.patch index e7c0130835..1533d4fe10 100644 --- a/e2e/testdata/fn-render/fnconfig-updated-in-render/.expected/diff.patch +++ b/e2e/testdata/fn-render/fnconfig-updated-in-render/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 950565f..7bd678e 100644 +index 950565f..77b2382 100644 --- a/Kptfile +++ b/Kptfile @@ -3,7 +3,7 @@ kind: Kptfile @@ -11,6 +11,15 @@ index 950565f..7bd678e 100644 annotations: config.kubernetes.io/local-config: "true" info: +@@ -16,3 +16,8 @@ pipeline: + configPath: update-labels.yaml + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configPath: label-input.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/app.yaml b/app.yaml index 3361e5b..33f2627 100644 --- a/app.yaml diff --git a/e2e/testdata/fn-render/fnconfig/.expected/diff.patch b/e2e/testdata/fn-render/fnconfig/.expected/diff.patch index c5cb4870a0..8e0b5d238e 100644 --- a/e2e/testdata/fn-render/fnconfig/.expected/diff.patch +++ b/e2e/testdata/fn-render/fnconfig/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 043dcac..0ee2ac8 100644 +index 043dcac..05a7f5c 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 043dcac..0ee2ac8 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -9,3 +12,8 @@ pipeline: + namespace: staging + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configPath: labelconfig.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/Kptfile b/db/Kptfile index 264dd2e..8dd7c37 100644 --- a/db/Kptfile diff --git a/e2e/testdata/fn-render/fnresult-fn-failure/.expected/diff.patch b/e2e/testdata/fn-render/fnresult-fn-failure/.expected/diff.patch new file mode 100644 index 0000000000..9240aa57d5 --- /dev/null +++ b/e2e/testdata/fn-render/fnresult-fn-failure/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 0586af9..30e8359 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -7,3 +7,11 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest + configMap: + strict: "true" ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/e2e/testdata/fn-render/fnresult-fn-success/.expected/diff.patch b/e2e/testdata/fn-render/fnresult-fn-success/.expected/diff.patch index 685cb16e8d..50314605f5 100644 --- a/e2e/testdata/fn-render/fnresult-fn-success/.expected/diff.patch +++ b/e2e/testdata/fn-render/fnresult-fn-success/.expected/diff.patch @@ -1,3 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 3c63ab9..787b279 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,8 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/search-replace:latest + configPath: search-replace-conf.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index f2eec52..114819d 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/format-on-success/.expected/diff.patch b/e2e/testdata/fn-render/format-on-success/.expected/diff.patch index aedf8745b7..d29f851dc9 100644 --- a/e2e/testdata/fn-render/format-on-success/.expected/diff.patch +++ b/e2e/testdata/fn-render/format-on-success/.expected/diff.patch @@ -1,8 +1,8 @@ diff --git a/Kptfile b/Kptfile -index dbab15c..a37d10e 100644 +index dbab15c..18405ed 100644 --- a/Kptfile +++ b/Kptfile -@@ -2,6 +2,7 @@ apiVersion: kpt.dev/v1 +@@ -2,8 +2,14 @@ apiVersion: kpt.dev/v1 kind: Kptfile metadata: name: app-with-db @@ -10,6 +10,13 @@ index dbab15c..a37d10e 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 + configMap: + namespace: staging ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/Kptfile b/db/Kptfile index 92bb0fc..31aafaa 100644 --- a/db/Kptfile diff --git a/e2e/testdata/fn-render/generator-absolute-path/.expected/diff.patch b/e2e/testdata/fn-render/generator-absolute-path/.expected/diff.patch index 1c94a808e6..c777a2aefb 100644 --- a/e2e/testdata/fn-render/generator-absolute-path/.expected/diff.patch +++ b/e2e/testdata/fn-render/generator-absolute-path/.expected/diff.patch @@ -1,3 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 714d078..7878d56 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,8 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: starlark-httpbin.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/another/file/out.yaml b/another/file/out.yaml new file mode 100644 index 0000000..f36c98e diff --git a/e2e/testdata/fn-render/generator/.expected/diff.patch b/e2e/testdata/fn-render/generator/.expected/diff.patch index 1151fe3a2d..e94718da17 100644 --- a/e2e/testdata/fn-render/generator/.expected/diff.patch +++ b/e2e/testdata/fn-render/generator/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 8050168..cb7293f 100644 +index 8050168..9fc6d67 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 8050168..cb7293f 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -10,3 +13,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: db ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/Kptfile b/db/Kptfile index 3091f75..b290407 100644 --- a/db/Kptfile diff --git a/e2e/testdata/fn-render/image-pull-policy-never/.expected/diff.patch b/e2e/testdata/fn-render/image-pull-policy-never/.expected/diff.patch new file mode 100644 index 0000000000..4399c3b1e4 --- /dev/null +++ b/e2e/testdata/fn-render/image-pull-policy-never/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 5b7fc74..e4e96f6 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -5,3 +5,11 @@ metadata: + pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/not-exist:latest ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/e2e/testdata/fn-render/krm-check-exclude-kustomize/.expected/diff.patch b/e2e/testdata/fn-render/krm-check-exclude-kustomize/.expected/diff.patch index d851cb49cd..12bd34c287 100644 --- a/e2e/testdata/fn-render/krm-check-exclude-kustomize/.expected/diff.patch +++ b/e2e/testdata/fn-render/krm-check-exclude-kustomize/.expected/diff.patch @@ -1,8 +1,8 @@ diff --git a/Kptfile b/Kptfile -index 2985a1a..3dfdcf6 100644 +index 2985a1a..7d38821 100644 --- a/Kptfile +++ b/Kptfile -@@ -2,6 +2,8 @@ apiVersion: kpt.dev/v1 +@@ -2,8 +2,15 @@ apiVersion: kpt.dev/v1 kind: Kptfile metadata: name: app @@ -11,6 +11,13 @@ index 2985a1a..3dfdcf6 100644 pipeline: mutators: - image: set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/kustomization.yaml b/kustomization.yaml index f3f0207..6c517af 100644 --- a/kustomization.yaml diff --git a/e2e/testdata/fn-render/kubeval-failure/.expected/diff.patch b/e2e/testdata/fn-render/kubeval-failure/.expected/diff.patch new file mode 100644 index 0000000000..3e2365803f --- /dev/null +++ b/e2e/testdata/fn-render/kubeval-failure/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 2c6e965..170b12f 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -7,3 +7,11 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest + configMap: + strict: "true" ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/e2e/testdata/fn-render/missing-fn-image/.expected/diff.patch b/e2e/testdata/fn-render/missing-fn-image/.expected/diff.patch new file mode 100644 index 0000000000..389f40dbd1 --- /dev/null +++ b/e2e/testdata/fn-render/missing-fn-image/.expected/diff.patch @@ -0,0 +1,20 @@ +diff --git a/Kptfile b/Kptfile +index 11012de..c9efd96 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -7,6 +7,14 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 + configMap: + namespace: staging +- - image: ghcr.io/kptdev/krm-functions-catalog/dne # non-existing image ++ - image: ghcr.io/kptdev/krm-functions-catalog/dne + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/e2e/testdata/fn-render/modify-legacy-path-annotation/.expected/diff.patch b/e2e/testdata/fn-render/modify-legacy-path-annotation/.expected/diff.patch index 6157962658..621f0f4535 100644 --- a/e2e/testdata/fn-render/modify-legacy-path-annotation/.expected/diff.patch +++ b/e2e/testdata/fn-render/modify-legacy-path-annotation/.expected/diff.patch @@ -1,4 +1,21 @@ +diff --git a/Kptfile b/Kptfile +index 5d377d4..784c77a 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -4,5 +4,10 @@ metadata: + name: app + pipeline: + mutators: +- - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest +- configPath: starlark-fn.yaml ++ - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest ++ configPath: starlark-fn.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/deployment.yaml b/newfilename.yaml similarity index 100% rename from deployment.yaml -rename to newfilename.yaml \ No newline at end of file +rename to newfilename.yaml diff --git a/e2e/testdata/fn-render/modify-path-annotation/.expected/diff.patch b/e2e/testdata/fn-render/modify-path-annotation/.expected/diff.patch index 20ce9c627f..1fe2ccb993 100644 --- a/e2e/testdata/fn-render/modify-path-annotation/.expected/diff.patch +++ b/e2e/testdata/fn-render/modify-path-annotation/.expected/diff.patch @@ -1,3 +1,20 @@ +diff --git a/Kptfile b/Kptfile +index 5d377d4..784c77a 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -4,5 +4,10 @@ metadata: + name: app + pipeline: + mutators: +- - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest +- configPath: starlark-fn.yaml ++ - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest ++ configPath: starlark-fn.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/deployment.yaml b/newfilename.yaml similarity index 100% rename from deployment.yaml diff --git a/e2e/testdata/fn-render/mutate-legacy-path-index/.expected/diff.patch b/e2e/testdata/fn-render/mutate-legacy-path-index/.expected/diff.patch index 2a7336fc06..d902763451 100644 --- a/e2e/testdata/fn-render/mutate-legacy-path-index/.expected/diff.patch +++ b/e2e/testdata/fn-render/mutate-legacy-path-index/.expected/diff.patch @@ -1,3 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 894ad57..6a36607 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,8 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: starlark-mutate-path-index.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/x.yaml b/y.yaml similarity index 100% rename from x.yaml diff --git a/e2e/testdata/fn-render/mutate-path-index/.expected/diff.patch b/e2e/testdata/fn-render/mutate-path-index/.expected/diff.patch index 2a7336fc06..d902763451 100644 --- a/e2e/testdata/fn-render/mutate-path-index/.expected/diff.patch +++ b/e2e/testdata/fn-render/mutate-path-index/.expected/diff.patch @@ -1,3 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 894ad57..6a36607 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,8 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: starlark-mutate-path-index.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/x.yaml b/y.yaml similarity index 100% rename from x.yaml diff --git a/e2e/testdata/fn-render/no-fnconfig/.expected/diff.patch b/e2e/testdata/fn-render/no-fnconfig/.expected/diff.patch new file mode 100644 index 0000000000..ff7bd2cd38 --- /dev/null +++ b/e2e/testdata/fn-render/no-fnconfig/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index f2d1249..8b6135d 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -8,3 +8,11 @@ pipeline: + configMap: + namespace: staging + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/e2e/testdata/fn-render/no-op/.expected/diff.patch b/e2e/testdata/fn-render/no-op/.expected/diff.patch new file mode 100644 index 0000000000..fe193773c3 --- /dev/null +++ b/e2e/testdata/fn-render/no-op/.expected/diff.patch @@ -0,0 +1,13 @@ +diff --git a/Kptfile b/Kptfile +index a7a2d0b..2b5abc5 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -5,3 +5,8 @@ metadata: + pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/no-op ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/e2e/testdata/fn-render/no-pipeline-in-subpackage/.expected/diff.patch b/e2e/testdata/fn-render/no-pipeline-in-subpackage/.expected/diff.patch index 21b66e32b1..00ca968e52 100644 --- a/e2e/testdata/fn-render/no-pipeline-in-subpackage/.expected/diff.patch +++ b/e2e/testdata/fn-render/no-pipeline-in-subpackage/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 1307fb5..3a2c718 100644 +index 1307fb5..f645d75 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 1307fb5..3a2c718 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -10,3 +13,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/Kptfile b/db/Kptfile index 79b7a5a..15f086b 100644 --- a/db/Kptfile diff --git a/e2e/testdata/fn-render/no-resources/.expected/diff.patch b/e2e/testdata/fn-render/no-resources/.expected/diff.patch index 1bec9c43de..9ef07fea9a 100644 --- a/e2e/testdata/fn-render/no-resources/.expected/diff.patch +++ b/e2e/testdata/fn-render/no-resources/.expected/diff.patch @@ -1,3 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 714d078..7878d56 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,8 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: starlark-httpbin.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/another/file/out.yaml b/another/file/out.yaml new file mode 100644 index 0000000..fe3c0c6 diff --git a/e2e/testdata/fn-render/non-krm-resource-no-pipeline/.expected/diff.patch b/e2e/testdata/fn-render/non-krm-resource-no-pipeline/.expected/diff.patch new file mode 100644 index 0000000000..16b239070d --- /dev/null +++ b/e2e/testdata/fn-render/non-krm-resource-no-pipeline/.expected/diff.patch @@ -0,0 +1,14 @@ +diff --git a/Kptfile b/Kptfile +index d9e2f05..775d110 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -2,3 +2,9 @@ apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: + name: app ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: 'pkg.render: pkg .: input resource list must contain only KRM resources: non-krm.yaml: resource must have `apiVersion`' diff --git a/e2e/testdata/fn-render/non-krm-resource/.expected/diff.patch b/e2e/testdata/fn-render/non-krm-resource/.expected/diff.patch new file mode 100644 index 0000000000..614f7e37a8 --- /dev/null +++ b/e2e/testdata/fn-render/non-krm-resource/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 1307fb5..630017f 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -10,3 +10,11 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: input resource list must contain only KRM resources: non-krm.yaml: resource must have `apiVersion` diff --git a/e2e/testdata/fn-render/out-of-place-fnchain-stdout-results/.expected/diff.patch b/e2e/testdata/fn-render/out-of-place-fnchain-stdout-results/.expected/diff.patch new file mode 100644 index 0000000000..e69de29bb2 diff --git a/e2e/testdata/fn-render/out-of-place-fnchain-stdout/.expected/diff.patch b/e2e/testdata/fn-render/out-of-place-fnchain-stdout/.expected/diff.patch new file mode 100644 index 0000000000..e69de29bb2 diff --git a/e2e/testdata/fn-render/out-of-place-fnchain-unwrap/.expected/diff.patch b/e2e/testdata/fn-render/out-of-place-fnchain-unwrap/.expected/diff.patch new file mode 100644 index 0000000000..e69de29bb2 diff --git a/e2e/testdata/fn-render/out-of-place-stdout/.expected/diff.patch b/e2e/testdata/fn-render/out-of-place-stdout/.expected/diff.patch new file mode 100644 index 0000000000..e69de29bb2 diff --git a/e2e/testdata/fn-render/out-of-place-unwrap/.expected/diff.patch b/e2e/testdata/fn-render/out-of-place-unwrap/.expected/diff.patch new file mode 100644 index 0000000000..e69de29bb2 diff --git a/e2e/testdata/fn-render/path-index-ancestor/.expected/diff.patch b/e2e/testdata/fn-render/path-index-ancestor/.expected/diff.patch new file mode 100644 index 0000000000..9ef7c42449 --- /dev/null +++ b/e2e/testdata/fn-render/path-index-ancestor/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index ac710dc..6762952 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -2,3 +2,11 @@ apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: + name: app-with-generator ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg ./db: ++ pipeline.run: function must not modify resources outside of package: resource has path ../deployment_httpbin.yaml diff --git a/e2e/testdata/fn-render/path-index-current/.expected/diff.patch b/e2e/testdata/fn-render/path-index-current/.expected/diff.patch index 1ae748f1e4..c06c7881cb 100644 --- a/e2e/testdata/fn-render/path-index-current/.expected/diff.patch +++ b/e2e/testdata/fn-render/path-index-current/.expected/diff.patch @@ -1,3 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 0f5d7db..4525813 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,8 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: starlark-httpbin-gen.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/deployment_httpbin.yaml b/deployment_httpbin.yaml new file mode 100644 index 0000000..f36c98e diff --git a/e2e/testdata/fn-render/path-index-descendent/.expected/diff.patch b/e2e/testdata/fn-render/path-index-descendent/.expected/diff.patch index a8e328e54e..201a8b079f 100644 --- a/e2e/testdata/fn-render/path-index-descendent/.expected/diff.patch +++ b/e2e/testdata/fn-render/path-index-descendent/.expected/diff.patch @@ -1,3 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 0f5d7db..4525813 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,8 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: starlark-httpbin-gen.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/deployment_httpbin.yaml b/db/deployment_httpbin.yaml new file mode 100644 index 0000000..f36c98e diff --git a/e2e/testdata/fn-render/path-index-duplicate/.expected/diff.patch b/e2e/testdata/fn-render/path-index-duplicate/.expected/diff.patch new file mode 100644 index 0000000000..dbe8b9918f --- /dev/null +++ b/e2e/testdata/fn-render/path-index-duplicate/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index ef99dad..44bcb32 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,11 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: starlark-gen-duplicate-path.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: resource at path "resources.yaml" and index "0" already exists diff --git a/e2e/testdata/fn-render/path-index-outofpackage/.expected/diff.patch b/e2e/testdata/fn-render/path-index-outofpackage/.expected/diff.patch new file mode 100644 index 0000000000..7017de0ffd --- /dev/null +++ b/e2e/testdata/fn-render/path-index-outofpackage/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index ac710dc..2d1632d 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -2,3 +2,11 @@ apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: + name: app-with-generator ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg ./db: ++ pipeline.run: function must not modify resources outside of package: resource has path ../notpkg/deployment_httpbin.yaml diff --git a/e2e/testdata/fn-render/preserve-comments/.expected/diff.patch b/e2e/testdata/fn-render/preserve-comments/.expected/diff.patch new file mode 100644 index 0000000000..d9752bbacb --- /dev/null +++ b/e2e/testdata/fn-render/preserve-comments/.expected/diff.patch @@ -0,0 +1,13 @@ +diff --git a/Kptfile b/Kptfile +index 828d292..2228d2c 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -5,3 +5,8 @@ metadata: + pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/drop-comments:v0.1 ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/e2e/testdata/fn-render/preserve-order-null-values/.expected/diff.patch b/e2e/testdata/fn-render/preserve-order-null-values/.expected/diff.patch index 0e758a50d7..e0b6032aa8 100644 --- a/e2e/testdata/fn-render/preserve-order-null-values/.expected/diff.patch +++ b/e2e/testdata/fn-render/preserve-order-null-values/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 1307fb5..3a2c718 100644 +index 1307fb5..f645d75 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 1307fb5..3a2c718 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -10,3 +13,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index f410b70..b58c04c 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/resource-deletion/.expected/diff.patch b/e2e/testdata/fn-render/resource-deletion/.expected/diff.patch index 61eda0ce31..d161537ad5 100644 --- a/e2e/testdata/fn-render/resource-deletion/.expected/diff.patch +++ b/e2e/testdata/fn-render/resource-deletion/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 364e274..75cfedb 100644 +index 364e274..9ad7200 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 364e274..75cfedb 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest +@@ -12,3 +15,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/deployment_httpbin.yaml b/deployment_httpbin.yaml deleted file mode 100644 index 49d4f6e..0000000 diff --git a/e2e/testdata/fn-render/resource-has-pkgname-prefix/.expected/diff.patch b/e2e/testdata/fn-render/resource-has-pkgname-prefix/.expected/diff.patch index 0149749d0f..7d3014762d 100644 --- a/e2e/testdata/fn-render/resource-has-pkgname-prefix/.expected/diff.patch +++ b/e2e/testdata/fn-render/resource-has-pkgname-prefix/.expected/diff.patch @@ -1,8 +1,8 @@ diff --git a/Kptfile b/Kptfile -index 21d9773..66b7fc9 100644 +index 21d9773..94b2528 100644 --- a/Kptfile +++ b/Kptfile -@@ -2,6 +2,8 @@ apiVersion: kpt.dev/v1 +@@ -2,8 +2,15 @@ apiVersion: kpt.dev/v1 kind: Kptfile metadata: name: wordpress @@ -11,6 +11,13 @@ index 21d9773..66b7fc9 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-annotations:latest + configMap: + abc: def ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/mysql/Kptfile b/mysql/Kptfile index 3d51a77..965bc63 100644 --- a/mysql/Kptfile diff --git a/e2e/testdata/fn-render/save-on-render-failure/bfs-basicpipeline/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/bfs-basicpipeline/.expected/diff.patch index b0b6b3e100..e9382ce252 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/bfs-basicpipeline/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/bfs-basicpipeline/.expected/diff.patch @@ -1,17 +1,46 @@ diff --git a/Kptfile b/Kptfile -index ec2c042..d795f4f 100644 +index ec2c042..50c2a18 100644 --- a/Kptfile +++ b/Kptfile -@@ -4,7 +4,9 @@ metadata: +@@ -1,18 +1,28 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: save-on-render-failure ++ namespace: staging annotations: ++ app: myapp kpt.dev/bfs-rendering: "true" kpt.dev/save-on-render-failure: "true" -+ app: myapp - name: save-on-render-failure -+ namespace: staging +- name: save-on-render-failure pipeline: mutators: - - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +- - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +- configMap: +- namespace: staging +- - image: ghcr.io/kptdev/krm-functions-catalog/set-annotations:v0.1.4 +- configMap: +- app: myapp +- - image: invalid-image:v0.0.0 +- configMap: +- tier: backend ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 ++ configMap: ++ namespace: staging ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-annotations:v0.1.4 ++ configMap: ++ app: myapp ++ - image: invalid-image:v0.0.0 ++ configMap: ++ tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/resources.yaml b/resources.yaml index 0848ba0..7eece9b 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/bfs-deep-nested-middle-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/bfs-deep-nested-middle-fails/.expected/diff.patch index 3efb8adbb5..0544ac3be1 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/bfs-deep-nested-middle-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/bfs-deep-nested-middle-fails/.expected/diff.patch @@ -1,13 +1,18 @@ diff --git a/Kptfile b/Kptfile -index dbd6541..bc4fd2d 100644 +index dbd6541..915dd4b 100644 --- a/Kptfile +++ b/Kptfile -@@ -5,10 +5,12 @@ metadata: - kpt.dev/bfs-rendering: "true" - kpt.dev/save-on-render-failure: "true" - name: bfs-deep-nested-middle-fails +@@ -1,14 +1,24 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: bfs-deep-nested-middle-fails + labels: + level: root + annotations: + kpt.dev/bfs-rendering: "true" + kpt.dev/save-on-render-failure: "true" +- name: bfs-deep-nested-middle-fails info: description: BFS - Deep nested, middle level fails pipeline: @@ -16,6 +21,14 @@ index dbd6541..bc4fd2d 100644 configMap: - level: "root" + level: root ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: pkg ./level1: already handled error diff --git a/configmap.yaml b/configmap.yaml index 59bb817..19a7ead 100644 --- a/configmap.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/bfs-multiple-subpkgs-one-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/bfs-multiple-subpkgs-one-fails/.expected/diff.patch index 8a582dcd77..8ddd89fefa 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/bfs-multiple-subpkgs-one-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/bfs-multiple-subpkgs-one-fails/.expected/diff.patch @@ -1,16 +1,33 @@ diff --git a/Kptfile b/Kptfile -index e9fad85..1b08a62 100644 +index e9fad85..48186b1 100644 --- a/Kptfile +++ b/Kptfile -@@ -5,6 +5,8 @@ metadata: - kpt.dev/bfs-rendering: "true" - kpt.dev/save-on-render-failure: "true" - name: bfs-multiple-subpkgs-one-fails +@@ -1,10 +1,12 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: bfs-multiple-subpkgs-one-fails + labels: + pkg: root + annotations: + kpt.dev/bfs-rendering: "true" + kpt.dev/save-on-render-failure: "true" +- name: bfs-multiple-subpkgs-one-fails info: description: BFS - Multiple subpackages, sub2 fails pipeline: +@@ -12,3 +14,11 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + pkg: root ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: pkg ./sub2: already handled error diff --git a/service.yaml b/service.yaml index 9148b9b..2e551c8 100644 --- a/service.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-and-subpkg-both-fail/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-and-subpkg-both-fail/.expected/diff.patch index 6154172d4a..e5e2e83e81 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-and-subpkg-both-fail/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-and-subpkg-both-fail/.expected/diff.patch @@ -1,16 +1,33 @@ diff --git a/Kptfile b/Kptfile -index cbe756f..a5fa6c0 100644 +index cbe756f..8ce300c 100644 --- a/Kptfile +++ b/Kptfile -@@ -5,6 +5,8 @@ metadata: - kpt.dev/bfs-rendering: "true" - kpt.dev/save-on-render-failure: "true" - name: bfs-parent-and-subpkg-both-fail +@@ -1,10 +1,12 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: bfs-parent-and-subpkg-both-fail + labels: + pkg: root + annotations: + kpt.dev/bfs-rendering: "true" + kpt.dev/save-on-render-failure: "true" +- name: bfs-parent-and-subpkg-both-fail info: description: BFS - Both parent and subpackage fail pipeline: +@@ -14,3 +16,11 @@ pipeline: + pkg: root + validators: + - image: ghcr.io/kptdev/krm-functions-catalog/invalid-image:v0.0.0 ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/configmap.yaml b/configmap.yaml index 8594873..a591ceb 100644 --- a/configmap.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-mutator-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-mutator-fails/.expected/diff.patch index d7619bd383..f7cc0a511a 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-mutator-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-mutator-fails/.expected/diff.patch @@ -1,13 +1,18 @@ diff --git a/Kptfile b/Kptfile -index c80b904..6954e67 100644 +index c80b904..d0bc053 100644 --- a/Kptfile +++ b/Kptfile -@@ -5,11 +5,13 @@ metadata: - kpt.dev/bfs-rendering: "true" - kpt.dev/save-on-render-failure: "true" - name: bfs-parent-mutator-fails +@@ -1,15 +1,25 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: bfs-parent-mutator-fails + labels: + test: parent-mutator-fail + annotations: + kpt.dev/bfs-rendering: "true" + kpt.dev/save-on-render-failure: "true" +- name: bfs-parent-mutator-fails info: description: BFS - Parent mutator fails pipeline: @@ -17,6 +22,14 @@ index c80b904..6954e67 100644 - test: "parent-mutator-fail" + test: parent-mutator-fail - image: ghcr.io/kptdev/krm-functions-catalog/invalid-image:v0.0.0 ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/configmap.yaml b/configmap.yaml index 20a54f6..a46a12b 100644 --- a/configmap.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-validator-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-validator-fails/.expected/diff.patch index 1d8bba0c89..77a376f85e 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-validator-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/bfs-parent-validator-fails/.expected/diff.patch @@ -1,13 +1,18 @@ diff --git a/Kptfile b/Kptfile -index 491b12e..8c66fe7 100644 +index 491b12e..28e400c 100644 --- a/Kptfile +++ b/Kptfile -@@ -5,12 +5,14 @@ metadata: - kpt.dev/bfs-rendering: "true" - kpt.dev/save-on-render-failure: "true" - name: bfs-parent-validator-fails +@@ -1,16 +1,26 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: bfs-parent-validator-fails + labels: + test: parent-fail + annotations: + kpt.dev/bfs-rendering: "true" + kpt.dev/save-on-render-failure: "true" +- name: bfs-parent-validator-fails info: description: BFS - Parent validator fails pipeline: @@ -18,6 +23,14 @@ index 491b12e..8c66fe7 100644 + test: parent-fail validators: - image: ghcr.io/kptdev/krm-functions-catalog/invalid-image:v0.0.0 ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/configmap.yaml b/configmap.yaml index 20a54f6..ad595de 100644 --- a/configmap.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/bfs-subpkg-mutator-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/bfs-subpkg-mutator-fails/.expected/diff.patch index 5c771fd77f..b4d487a414 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/bfs-subpkg-mutator-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/bfs-subpkg-mutator-fails/.expected/diff.patch @@ -1,13 +1,18 @@ diff --git a/Kptfile b/Kptfile -index 84b93a6..877725d 100644 +index 84b93a6..4ae9f17 100644 --- a/Kptfile +++ b/Kptfile -@@ -5,10 +5,12 @@ metadata: - kpt.dev/bfs-rendering: "true" - kpt.dev/save-on-render-failure: "true" - name: bfs-subpkg-mutator-fails +@@ -1,14 +1,24 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: bfs-subpkg-mutator-fails + labels: + test: mutator-fail + annotations: + kpt.dev/bfs-rendering: "true" + kpt.dev/save-on-render-failure: "true" +- name: bfs-subpkg-mutator-fails info: description: BFS - Subpackage mutator fails pipeline: @@ -16,6 +21,14 @@ index 84b93a6..877725d 100644 configMap: - test: "mutator-fail" + test: mutator-fail ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: pkg ./subpkg: already handled error diff --git a/deployment.yaml b/deployment.yaml index cc866f6..6ed4201 100644 --- a/deployment.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/bfs-subpkg-validator-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/bfs-subpkg-validator-fails/.expected/diff.patch index c18f86ccf4..18a748ab0c 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/bfs-subpkg-validator-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/bfs-subpkg-validator-fails/.expected/diff.patch @@ -1,14 +1,19 @@ diff --git a/Kptfile b/Kptfile -index 86dbe13..c5c38b8 100644 +index 86dbe13..f0c67c4 100644 --- a/Kptfile +++ b/Kptfile -@@ -5,11 +5,14 @@ metadata: - kpt.dev/bfs-rendering: "true" - kpt.dev/save-on-render-failure: "true" - name: bfs-subpkg-validator-fails +@@ -1,15 +1,26 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: bfs-subpkg-validator-fails + labels: + level: root + test: subpkg-fail + annotations: + kpt.dev/bfs-rendering: "true" + kpt.dev/save-on-render-failure: "true" +- name: bfs-subpkg-validator-fails info: description: BFS - Subpackage validator fails pipeline: @@ -17,8 +22,16 @@ index 86dbe13..c5c38b8 100644 configMap: - test: "subpkg-fail" - level: "root" -+ test: subpkg-fail + level: root ++ test: subpkg-fail ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: pkg ./subpkg: already handled error diff --git a/deployment.yaml b/deployment.yaml index 7123634..4db6211 100644 --- a/deployment.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/dfs-basicpipeline/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/dfs-basicpipeline/.expected/diff.patch index 92754c2fd1..3234bb19c8 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/dfs-basicpipeline/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/dfs-basicpipeline/.expected/diff.patch @@ -1,17 +1,45 @@ diff --git a/Kptfile b/Kptfile -index c6fc0c5..1631bfb 100644 +index c6fc0c5..620b80e 100644 --- a/Kptfile +++ b/Kptfile -@@ -3,7 +3,9 @@ kind: Kptfile +@@ -1,17 +1,27 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile metadata: ++ name: save-on-render-failure ++ namespace: staging annotations: - kpt.dev/save-on-render-failure: "true" + app: myapp - name: save-on-render-failure -+ namespace: staging + kpt.dev/save-on-render-failure: "true" +- name: save-on-render-failure pipeline: mutators: - - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +- - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +- configMap: +- namespace: staging +- - image: ghcr.io/kptdev/krm-functions-catalog/set-annotations:v0.1.4 +- configMap: +- app: myapp +- - image: invalid-image:v0.0.0 +- configMap: +- tier: backend ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 ++ configMap: ++ namespace: staging ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-annotations:v0.1.4 ++ configMap: ++ app: myapp ++ - image: invalid-image:v0.0.0 ++ configMap: ++ tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/resources.yaml b/resources.yaml index 0848ba0..7eece9b 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/dfs-deep-nested-middle-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/dfs-deep-nested-middle-fails/.expected/diff.patch index a4012da01e..14f98d3f02 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/dfs-deep-nested-middle-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/dfs-deep-nested-middle-fails/.expected/diff.patch @@ -1,3 +1,31 @@ +diff --git a/Kptfile b/Kptfile +index 4047d27..e7ca740 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -1,13 +1,21 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: dfs-deep-nested-middle-fails + annotations: + kpt.dev/save-on-render-failure: "true" +- name: dfs-deep-nested-middle-fails + info: + description: DFS - Deep nested, middle level fails + pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: +- level: "root" ++ level: root ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg ./level1: ++ pipeline.run: already handled error diff --git a/level1/Kptfile b/level1/Kptfile index b5960dd..b42f153 100644 --- a/level1/Kptfile diff --git a/e2e/testdata/fn-render/save-on-render-failure/dfs-multiple-subpkgs-one-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/dfs-multiple-subpkgs-one-fails/.expected/diff.patch index 70def2baa5..582f70fc72 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/dfs-multiple-subpkgs-one-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/dfs-multiple-subpkgs-one-fails/.expected/diff.patch @@ -1,3 +1,30 @@ +diff --git a/Kptfile b/Kptfile +index c47c90d..1b7e920 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -1,9 +1,9 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: dfs-multiple-subpkgs-one-fails + annotations: + kpt.dev/save-on-render-failure: "true" +- name: dfs-multiple-subpkgs-one-fails + info: + description: DFS - Multiple subpackages, sub2 fails + pipeline: +@@ -11,3 +11,11 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + pkg: root ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg ./sub2: ++ pipeline.run: already handled error diff --git a/sub1/Kptfile b/sub1/Kptfile index 2d62077..0f03268 100644 --- a/sub1/Kptfile diff --git a/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-and-subpkg-both-fail/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-and-subpkg-both-fail/.expected/diff.patch index e2923d8d42..f0105bbf0f 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-and-subpkg-both-fail/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-and-subpkg-both-fail/.expected/diff.patch @@ -1,3 +1,30 @@ +diff --git a/Kptfile b/Kptfile +index e4d630d..c8d5efb 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -1,9 +1,9 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: dfs-parent-and-subpkg-both-fail + annotations: + kpt.dev/save-on-render-failure: "true" +- name: dfs-parent-and-subpkg-both-fail + info: + description: DFS - Both parent and subpackage fail + pipeline: +@@ -13,3 +13,11 @@ pipeline: + pkg: root + validators: + - image: ghcr.io/kptdev/krm-functions-catalog/invalid-image:v0.0.0 ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg ./subpkg: ++ pipeline.run: already handled error diff --git a/subpkg/Kptfile b/subpkg/Kptfile index a332cf5..cb45834 100644 --- a/subpkg/Kptfile diff --git a/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-mutator-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-mutator-fails/.expected/diff.patch index 0c15742529..eecfacca1c 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-mutator-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-mutator-fails/.expected/diff.patch @@ -1,13 +1,17 @@ diff --git a/Kptfile b/Kptfile -index c134b37..32d759a 100644 +index c134b37..a48d9bb 100644 --- a/Kptfile +++ b/Kptfile -@@ -4,11 +4,13 @@ metadata: - annotations: - kpt.dev/save-on-render-failure: "true" - name: dfs-parent-mutator-fails +@@ -1,14 +1,24 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: dfs-parent-mutator-fails + labels: + test: parent-mutator-fail + annotations: + kpt.dev/save-on-render-failure: "true" +- name: dfs-parent-mutator-fails info: description: DFS - Parent mutator fails pipeline: @@ -17,6 +21,14 @@ index c134b37..32d759a 100644 - test: "parent-mutator-fail" + test: parent-mutator-fail - image: ghcr.io/kptdev/krm-functions-catalog/invalid-image:v0.0.0 ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/configmap.yaml b/configmap.yaml index 20a54f6..a46a12b 100644 --- a/configmap.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-validator-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-validator-fails/.expected/diff.patch index cfdb9a036b..0d65d79302 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-validator-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/dfs-parent-validator-fails/.expected/diff.patch @@ -1,13 +1,17 @@ diff --git a/Kptfile b/Kptfile -index 94a7a73..8581173 100644 +index 94a7a73..8965faa 100644 --- a/Kptfile +++ b/Kptfile -@@ -4,12 +4,14 @@ metadata: - annotations: - kpt.dev/save-on-render-failure: "true" - name: dfs-parent-validator-fails +@@ -1,15 +1,25 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: dfs-parent-validator-fails + labels: + test: parent-fail + annotations: + kpt.dev/save-on-render-failure: "true" +- name: dfs-parent-validator-fails info: description: DFS - Parent validator fails pipeline: @@ -18,6 +22,14 @@ index 94a7a73..8581173 100644 + test: parent-fail validators: - image: ghcr.io/kptdev/krm-functions-catalog/invalid-image:v0.0.0 ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/configmap.yaml b/configmap.yaml index 20a54f6..ad595de 100644 --- a/configmap.yaml diff --git a/e2e/testdata/fn-render/save-on-render-failure/dfs-subpkg-mutator-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/dfs-subpkg-mutator-fails/.expected/diff.patch index 24433c71d9..514a0dde24 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/dfs-subpkg-mutator-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/dfs-subpkg-mutator-fails/.expected/diff.patch @@ -1,3 +1,31 @@ +diff --git a/Kptfile b/Kptfile +index 80aa788..0fca116 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -1,13 +1,21 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: dfs-subpkg-mutator-fails + annotations: + kpt.dev/save-on-render-failure: "true" +- name: dfs-subpkg-mutator-fails + info: + description: DFS - Subpackage mutator fails + pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: +- test: "mutator-fail" ++ test: mutator-fail ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg ./subpkg: ++ pipeline.run: already handled error diff --git a/subpkg/Kptfile b/subpkg/Kptfile index ec4ce38..d7ac408 100644 --- a/subpkg/Kptfile diff --git a/e2e/testdata/fn-render/save-on-render-failure/dfs-subpkg-validator-fails/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/dfs-subpkg-validator-fails/.expected/diff.patch index 0fdd10dee3..4dbe465e7d 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/dfs-subpkg-validator-fails/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/dfs-subpkg-validator-fails/.expected/diff.patch @@ -1,3 +1,33 @@ +diff --git a/Kptfile b/Kptfile +index 7c3b09a..6bc279b 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -1,14 +1,22 @@ + apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: ++ name: dfs-subpkg-validator-fails + annotations: + kpt.dev/save-on-render-failure: "true" +- name: dfs-subpkg-validator-fails + info: + description: DFS - Subpackage validator fails + pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: +- test: "subpkg-fail" +- level: "root" ++ level: root ++ test: subpkg-fail ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg ./subpkg: ++ pipeline.run: already handled error diff --git a/subpkg/Kptfile b/subpkg/Kptfile index f147d84..b3c532e 100644 --- a/subpkg/Kptfile diff --git a/e2e/testdata/fn-render/save-on-render-failure/no-save-on-render-failure/.expected/diff.patch b/e2e/testdata/fn-render/save-on-render-failure/no-save-on-render-failure/.expected/diff.patch index e69de29bb2..187669d407 100644 --- a/e2e/testdata/fn-render/save-on-render-failure/no-save-on-render-failure/.expected/diff.patch +++ b/e2e/testdata/fn-render/save-on-render-failure/no-save-on-render-failure/.expected/diff.patch @@ -0,0 +1,34 @@ +diff --git a/Kptfile b/Kptfile +index 6e26cd3..fb2aa71 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -4,12 +4,20 @@ metadata: + name: no-save-on-render-failure + pipeline: + mutators: +- - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +- configMap: +- namespace: staging +- - image: ghcr.io/kptdev/krm-functions-catalog/set-annotations:v0.1.4 +- configMap: +- app: myapp +- - image: invalid-image:v0.0.0 +- configMap: +- tier: backend ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 ++ configMap: ++ namespace: staging ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-annotations:v0.1.4 ++ configMap: ++ app: myapp ++ - image: invalid-image:v0.0.0 ++ configMap: ++ tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/e2e/testdata/fn-render/selectors/basicpipeline/.expected/diff.patch b/e2e/testdata/fn-render/selectors/basicpipeline/.expected/diff.patch index b29c072d71..8187cff1d0 100644 --- a/e2e/testdata/fn-render/selectors/basicpipeline/.expected/diff.patch +++ b/e2e/testdata/fn-render/selectors/basicpipeline/.expected/diff.patch @@ -1,8 +1,8 @@ diff --git a/Kptfile b/Kptfile -index abc7b97..1120263 100644 +index abc7b97..0b78750 100644 --- a/Kptfile +++ b/Kptfile -@@ -2,6 +2,8 @@ apiVersion: kpt.dev/v1 +@@ -2,14 +2,21 @@ apiVersion: kpt.dev/v1 kind: Kptfile metadata: name: app @@ -11,6 +11,21 @@ index abc7b97..1120263 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 + configMap: + namespace: staging + selectors: +- - name: nginx-deployment +- kind: Deployment ++ - kind: Deployment ++ name: nginx-deployment + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index f2eec52..6b5d443 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/selectors/exclude/.expected/diff.patch b/e2e/testdata/fn-render/selectors/exclude/.expected/diff.patch index 207f384e99..c092089266 100644 --- a/e2e/testdata/fn-render/selectors/exclude/.expected/diff.patch +++ b/e2e/testdata/fn-render/selectors/exclude/.expected/diff.patch @@ -1,3 +1,25 @@ +diff --git a/Kptfile b/Kptfile +index 266b33a..92e4a02 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -8,10 +8,15 @@ pipeline: + configMap: + namespace: staging + selectors: +- - name: nginx-deployment +- kind: Deployment ++ - kind: Deployment ++ name: nginx-deployment + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend + exclude: + - kind: Kptfile ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index f2eec52..6b5d443 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/selectors/generator/.expected/diff.patch b/e2e/testdata/fn-render/selectors/generator/.expected/diff.patch index dd1d2c47f0..9722438cf4 100644 --- a/e2e/testdata/fn-render/selectors/generator/.expected/diff.patch +++ b/e2e/testdata/fn-render/selectors/generator/.expected/diff.patch @@ -1,3 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index eb2f084..cb608a0 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -14,3 +14,8 @@ pipeline: + tier: db + selectors: + - name: httpbin ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/deployment_httpbin.yaml b/db/deployment_httpbin.yaml new file mode 100644 index 0000000..ffdf484 diff --git a/e2e/testdata/fn-render/selectors/selectors-with-exclude/.expected/diff.patch b/e2e/testdata/fn-render/selectors/selectors-with-exclude/.expected/diff.patch index 45e8d1aff3..ea9cd478bc 100644 --- a/e2e/testdata/fn-render/selectors/selectors-with-exclude/.expected/diff.patch +++ b/e2e/testdata/fn-render/selectors/selectors-with-exclude/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index c16cdca..ef430cd 100644 +index c16cdca..8941f26 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,8 @@ apiVersion: kpt.dev/v1 @@ -11,6 +11,15 @@ index c16cdca..ef430cd 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -15,3 +17,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index d3ed04c..f66e542 100644 --- a/resources.yaml @@ -39,4 +48,4 @@ index d3ed04c..f66e542 100644 foo: bar + tier: backend spec: - image: nginx:1.2.3 \ No newline at end of file + image: nginx:1.2.3 diff --git a/e2e/testdata/fn-render/short-image-path/.expected/diff.patch b/e2e/testdata/fn-render/short-image-path/.expected/diff.patch index af84880849..2312d6f22c 100644 --- a/e2e/testdata/fn-render/short-image-path/.expected/diff.patch +++ b/e2e/testdata/fn-render/short-image-path/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index d4e5935..06cb2ef 100644 +index d4e5935..95f5ba8 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index d4e5935..06cb2ef 100644 pipeline: mutators: - image: set-namespace:v0.2.0 +@@ -10,3 +13,8 @@ pipeline: + - image: set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index f2eec52..84cfb26 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/short-image-path/.expected/results.yaml b/e2e/testdata/fn-render/short-image-path/.expected/results.yaml index bc3a869a98..1ea8a8f00b 100755 --- a/e2e/testdata/fn-render/short-image-path/.expected/results.yaml +++ b/e2e/testdata/fn-render/short-image-path/.expected/results.yaml @@ -8,4 +8,3 @@ items: exitCode: 0 - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 exitCode: 0 - diff --git a/e2e/testdata/fn-render/structured-results-from-muiltiple-fns/.expected/diff.patch b/e2e/testdata/fn-render/structured-results-from-muiltiple-fns/.expected/diff.patch new file mode 100644 index 0000000000..06c08a0a2c --- /dev/null +++ b/e2e/testdata/fn-render/structured-results-from-muiltiple-fns/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 91828a8..aea2cb9 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -9,3 +9,11 @@ pipeline: + configMap: + ignore_missing_schemas: "true" + strict: "true" ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/e2e/testdata/fn-render/subpkg-fn-failure/.expected/diff.patch b/e2e/testdata/fn-render/subpkg-fn-failure/.expected/diff.patch new file mode 100644 index 0000000000..bd7106dd95 --- /dev/null +++ b/e2e/testdata/fn-render/subpkg-fn-failure/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 364e274..4316cf6 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -12,3 +12,11 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg ./db: ++ pipeline.run: already handled error diff --git a/e2e/testdata/fn-render/subpkg-has-invalid-kptfile/.expected/diff.patch b/e2e/testdata/fn-render/subpkg-has-invalid-kptfile/.expected/diff.patch new file mode 100644 index 0000000000..c66b445d9e --- /dev/null +++ b/e2e/testdata/fn-render/subpkg-has-invalid-kptfile/.expected/diff.patch @@ -0,0 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 1307fb5..15413d2 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -10,3 +10,11 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pkg.Subpackages: pkg ./db: error reading Kptfile at "./db": yaml: line 10: mapping values are not allowed in this context diff --git a/e2e/testdata/fn-render/subpkg-has-samename-subdir/.expected/diff.patch b/e2e/testdata/fn-render/subpkg-has-samename-subdir/.expected/diff.patch index 3ed1b478ec..cb038df6d8 100644 --- a/e2e/testdata/fn-render/subpkg-has-samename-subdir/.expected/diff.patch +++ b/e2e/testdata/fn-render/subpkg-has-samename-subdir/.expected/diff.patch @@ -1,3 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index 701e0a1..3107d07 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -4,3 +4,8 @@ metadata: + name: root-pkg + info: + description: sample description ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/pkg-a/Kptfile b/pkg-a/Kptfile index 088bc03..c42f368 100644 --- a/pkg-a/Kptfile diff --git a/e2e/testdata/fn-render/subpkg-resource-deletion/.expected/diff.patch b/e2e/testdata/fn-render/subpkg-resource-deletion/.expected/diff.patch index a92d37160d..ace86b1bd8 100644 --- a/e2e/testdata/fn-render/subpkg-resource-deletion/.expected/diff.patch +++ b/e2e/testdata/fn-render/subpkg-resource-deletion/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 364e274..75cfedb 100644 +index 364e274..9ad7200 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 364e274..75cfedb 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest +@@ -12,3 +15,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/Kptfile b/db/Kptfile index 6c7674c..11fe9cc 100644 --- a/db/Kptfile diff --git a/e2e/testdata/fn-render/subpkgs-with-krmignore/.expected/diff.patch b/e2e/testdata/fn-render/subpkgs-with-krmignore/.expected/diff.patch index efb950203b..63ae894e45 100644 --- a/e2e/testdata/fn-render/subpkgs-with-krmignore/.expected/diff.patch +++ b/e2e/testdata/fn-render/subpkgs-with-krmignore/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 82686a8..c24d77e 100644 +index 82686a8..a4b2da6 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 82686a8..c24d77e 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -10,3 +13,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: db ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/Kptfile b/db/Kptfile index 264dd2e..8dd7c37 100644 --- a/db/Kptfile diff --git a/e2e/testdata/fn-render/subpkgs/.expected/diff.patch b/e2e/testdata/fn-render/subpkgs/.expected/diff.patch index efb950203b..63ae894e45 100644 --- a/e2e/testdata/fn-render/subpkgs/.expected/diff.patch +++ b/e2e/testdata/fn-render/subpkgs/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 82686a8..c24d77e 100644 +index 82686a8..a4b2da6 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 82686a8..c24d77e 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -10,3 +13,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: db ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/db/Kptfile b/db/Kptfile index 264dd2e..8dd7c37 100644 --- a/db/Kptfile diff --git a/e2e/testdata/fn-render/success-stdout/.expected/diff.patch b/e2e/testdata/fn-render/success-stdout/.expected/diff.patch index a21c38b30e..16337308e3 100644 --- a/e2e/testdata/fn-render/success-stdout/.expected/diff.patch +++ b/e2e/testdata/fn-render/success-stdout/.expected/diff.patch @@ -1,5 +1,5 @@ diff --git a/Kptfile b/Kptfile -index 1307fb5..3a2c718 100644 +index 1307fb5..f645d75 100644 --- a/Kptfile +++ b/Kptfile @@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 @@ -12,6 +12,15 @@ index 1307fb5..3a2c718 100644 pipeline: mutators: - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.2.0 +@@ -10,3 +13,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5 + configMap: + tier: backend ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/resources.yaml b/resources.yaml index f2eec52..84cfb26 100644 --- a/resources.yaml diff --git a/e2e/testdata/fn-render/validate-generated-resource/.expected/diff.patch b/e2e/testdata/fn-render/validate-generated-resource/.expected/diff.patch index 1ae748f1e4..5499661a18 100644 --- a/e2e/testdata/fn-render/validate-generated-resource/.expected/diff.patch +++ b/e2e/testdata/fn-render/validate-generated-resource/.expected/diff.patch @@ -1,3 +1,16 @@ +diff --git a/Kptfile b/Kptfile +index b2432a4..0362808 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -9,3 +9,8 @@ pipeline: + validators: + - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: starlark-httpbin-val.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess diff --git a/deployment_httpbin.yaml b/deployment_httpbin.yaml new file mode 100644 index 0000000..f36c98e diff --git a/e2e/testdata/fn-render/validate-resource-failure/.expected/diff.patch b/e2e/testdata/fn-render/validate-resource-failure/.expected/diff.patch new file mode 100644 index 0000000000..b063c5efd4 --- /dev/null +++ b/e2e/testdata/fn-render/validate-resource-failure/.expected/diff.patch @@ -0,0 +1,19 @@ +diff --git a/Kptfile b/Kptfile +index 8c3173a..c241762 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -4,5 +4,13 @@ metadata: + name: db + pipeline: + validators: +- - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest # validates httpbin deployment exists ++ - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: starlark-httpbin-val.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "False" ++ reason: RenderFailed ++ message: |- ++ pkg.render: pkg .: ++ pipeline.run: already handled error diff --git a/internal/util/render/executor.go b/internal/util/render/executor.go index d74ccf4957..eb83469e25 100644 --- a/internal/util/render/executor.go +++ b/internal/util/render/executor.go @@ -20,6 +20,7 @@ import ( "io" "os" "path/filepath" + "slices" "strings" "github.com/kptdev/kpt/internal/fnruntime" @@ -34,6 +35,7 @@ import ( "github.com/kptdev/kpt/pkg/lib/errors" "github.com/kptdev/kpt/pkg/lib/runneroptions" "github.com/kptdev/kpt/pkg/printer" + "k8s.io/klog/v2" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio/kioutil" @@ -109,6 +111,9 @@ func (e *Renderer) Execute(ctx context.Context) (*fnresult.ResultList, error) { _, hydErr := hydrateFn(ctx, root, hctx) if hydErr != nil && !hctx.saveOnRenderFailure { + if e.Output == nil { + updateRenderStatus(hctx, hydErr) + } _ = e.saveFnResults(ctx, hctx.fnResults) return hctx.fnResults, errors.E(op, root.pkg.UniquePath, hydErr) } @@ -173,11 +178,20 @@ func (e *Renderer) Execute(ctx context.Context) (*fnresult.ResultList, error) { } if hydErr != nil { + if e.Output == nil { + updateRenderStatus(hctx, hydErr) + } _ = e.saveFnResults(ctx, hctx.fnResults) // Ignore save error to avoid masking hydration error return hctx.fnResults, errors.E(op, root.pkg.UniquePath, hydErr) } - return hctx.fnResults, e.saveFnResults(ctx, hctx.fnResults) + saveErr := e.saveFnResults(ctx, hctx.fnResults) + + if e.Output == nil { + updateRenderStatus(hctx, saveErr) + } + + return hctx.fnResults, saveErr } func (e *Renderer) printPipelineExecutionSummary(pr printer.Printer, hctx hydrationContext, hydErr error) { @@ -192,6 +206,47 @@ func (e *Renderer) printPipelineExecutionSummary(pr printer.Printer, hctx hydrat } } +// updateRenderStatus writes a Rendered status condition to the root Kptfile. +// On success, the root package gets a True condition. +// On failure, the root package gets a False condition with the error message. +func updateRenderStatus(hctx *hydrationContext, hydErr error) { + if hctx.fileSystem == nil { + return + } + + rootPath := hctx.root.pkg.UniquePath.String() + conditionStatus := kptfilev1.ConditionTrue + reason := kptfilev1.ReasonRenderSuccess + message := "" + if hydErr != nil { + conditionStatus = kptfilev1.ConditionFalse + reason = kptfilev1.ReasonRenderFailed + message = strings.ReplaceAll(hydErr.Error(), rootPath, ".") + } + setRenderCondition(hctx.fileSystem, rootPath, kptfilev1.NewRenderedCondition(conditionStatus, reason, message)) +} + +// setRenderCondition reads the Kptfile at pkgPath, sets the Rendered condition, and writes it back. +func setRenderCondition(fs filesys.FileSystem, pkgPath string, condition kptfilev1.Condition) { + fsOrDisk := filesys.FileSystemOrOnDisk{FileSystem: fs} + kf, err := kptfileutil.ReadKptfile(fsOrDisk, pkgPath) + if err != nil { + klog.V(3).Infof("failed to read Kptfile for render status update at %s: %v", pkgPath, err) + return + } + if kf.Status == nil { + kf.Status = &kptfilev1.Status{} + } + // Replace any existing Rendered condition + kf.Status.Conditions = slices.DeleteFunc(kf.Status.Conditions, func(c kptfilev1.Condition) bool { + return c.Type == kptfilev1.ConditionTypeRendered + }) + kf.Status.Conditions = append(kf.Status.Conditions, condition) + if err := kptfileutil.WriteKptfileToFS(fs, pkgPath, kf); err != nil { + klog.V(3).Infof("failed to write render status condition to Kptfile at %s: %v", pkgPath, err) + } +} + func (e *Renderer) saveFnResults(ctx context.Context, fnResults *fnresult.ResultList) error { e.fnResultsList = fnResults resultsFile, err := fnruntime.SaveResults(e.FileSystem, e.ResultsDirPath, fnResults) diff --git a/internal/util/render/executor_test.go b/internal/util/render/executor_test.go index 2c8e253f54..e09b33bc50 100644 --- a/internal/util/render/executor_test.go +++ b/internal/util/render/executor_test.go @@ -25,6 +25,8 @@ import ( "github.com/kptdev/kpt/internal/fnruntime" "github.com/kptdev/kpt/internal/pkg" "github.com/kptdev/kpt/internal/types" + kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" + "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/printer" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/filesys" @@ -32,6 +34,7 @@ import ( ) const rootString = "/root" +const subPkgString = "/root/subpkg" func TestPathRelToRoot(t *testing.T) { tests := []struct { @@ -249,7 +252,7 @@ func setupRendererTest(t *testing.T, renderBfs bool) (*Renderer, *bytes.Buffer, err := mockFileSystem.Mkdir(rootPkgPath) assert.NoError(t, err) - subPkgPath := "/root/subpkg" + subPkgPath := subPkgString err = mockFileSystem.Mkdir(subPkgPath) assert.NoError(t, err) @@ -410,7 +413,7 @@ func TestHydrateBfsOrder_ErrorCases(t *testing.T) { err := mockFileSystem.Mkdir(rootPkgPath) assert.NoError(t, err) - subPkgPath := "/root/subpkg" + subPkgPath := subPkgString err = mockFileSystem.Mkdir(subPkgPath) assert.NoError(t, err) @@ -572,6 +575,161 @@ func TestRenderer_PrintPipelineExecutionSummary(t *testing.T) { } } +func TestUpdateRenderStatus_Success(t *testing.T) { + mockFS := filesys.MakeFsInMemory() + rootPath := rootString + assert.NoError(t, mockFS.Mkdir(rootPath)) + + assert.NoError(t, mockFS.WriteFile(filepath.Join(rootPath, "Kptfile"), []byte(` +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: root-package +`))) + + rootPkg, err := pkg.New(mockFS, rootPath) + assert.NoError(t, err) + + hctx := &hydrationContext{ + root: &pkgNode{pkg: rootPkg}, + pkgs: map[types.UniquePath]*pkgNode{}, + fileSystem: mockFS, + } + hctx.pkgs[rootPkg.UniquePath] = &pkgNode{pkg: rootPkg} + + updateRenderStatus(hctx, nil) + + rootKf, err := kptfileutil.ReadKptfile(mockFS, rootPath) + assert.NoError(t, err) + assert.NotNil(t, rootKf.Status) + assert.Len(t, rootKf.Status.Conditions, 1) + assert.Equal(t, kptfilev1.ConditionTypeRendered, rootKf.Status.Conditions[0].Type) + assert.Equal(t, kptfilev1.ConditionTrue, rootKf.Status.Conditions[0].Status) + assert.Equal(t, kptfilev1.ReasonRenderSuccess, rootKf.Status.Conditions[0].Reason) +} + +func TestUpdateRenderStatus_Failure(t *testing.T) { + mockFS := filesys.MakeFsInMemory() + rootPath := rootString + assert.NoError(t, mockFS.Mkdir(rootPath)) + + assert.NoError(t, mockFS.WriteFile(filepath.Join(rootPath, "Kptfile"), []byte(` +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: root-package +`))) + + rootPkg, err := pkg.New(mockFS, rootPath) + assert.NoError(t, err) + + hctx := &hydrationContext{ + root: &pkgNode{pkg: rootPkg}, + pkgs: map[types.UniquePath]*pkgNode{}, + fileSystem: mockFS, + } + hctx.pkgs[rootPkg.UniquePath] = &pkgNode{pkg: rootPkg} + + updateRenderStatus(hctx, fmt.Errorf("set-annotations failed: some error")) + + rootKf, err := kptfileutil.ReadKptfile(mockFS, rootPath) + assert.NoError(t, err) + assert.NotNil(t, rootKf.Status) + assert.Len(t, rootKf.Status.Conditions, 1) + assert.Equal(t, kptfilev1.ConditionFalse, rootKf.Status.Conditions[0].Status) + assert.Equal(t, kptfilev1.ReasonRenderFailed, rootKf.Status.Conditions[0].Reason) + assert.Contains(t, rootKf.Status.Conditions[0].Message, "set-annotations failed") +} + +func TestUpdateRenderStatus_ReplacesExistingCondition(t *testing.T) { + mockFS := filesys.MakeFsInMemory() + rootPath := rootString + assert.NoError(t, mockFS.Mkdir(rootPath)) + + // Kptfile with an existing Rendered condition from a previous run + assert.NoError(t, mockFS.WriteFile(filepath.Join(rootPath, "Kptfile"), []byte(` +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: root-package +status: + conditions: + - type: Rendered + status: "False" + reason: RenderFailed + message: "old error" +`))) + + rootPkg, err := pkg.New(mockFS, rootPath) + assert.NoError(t, err) + + hctx := &hydrationContext{ + root: &pkgNode{pkg: rootPkg}, + pkgs: map[types.UniquePath]*pkgNode{}, + fileSystem: mockFS, + } + hctx.pkgs[rootPkg.UniquePath] = &pkgNode{pkg: rootPkg} + + updateRenderStatus(hctx, nil) + + rootKf, err := kptfileutil.ReadKptfile(mockFS, rootPath) + assert.NoError(t, err) + assert.NotNil(t, rootKf.Status) + assert.Len(t, rootKf.Status.Conditions, 1) + assert.Equal(t, kptfilev1.ConditionTrue, rootKf.Status.Conditions[0].Status) + assert.Equal(t, kptfilev1.ReasonRenderSuccess, rootKf.Status.Conditions[0].Reason) + assert.Empty(t, rootKf.Status.Conditions[0].Message) +} + +func TestUpdateRenderStatus_OnlyUpdatesRootKptfile(t *testing.T) { + mockFS := filesys.MakeFsInMemory() + rootPath := rootString + assert.NoError(t, mockFS.Mkdir(rootPath)) + + subPkgPath := subPkgString + assert.NoError(t, mockFS.Mkdir(subPkgPath)) + + assert.NoError(t, mockFS.WriteFile(filepath.Join(rootPath, "Kptfile"), []byte(` +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: root-package +`))) + assert.NoError(t, mockFS.WriteFile(filepath.Join(subPkgPath, "Kptfile"), []byte(` +apiVersion: kpt.dev/v1 +kind: Kptfile +metadata: + name: sub-package +`))) + + rootPkg, err := pkg.New(mockFS, rootPath) + assert.NoError(t, err) + subPkg, err := pkg.New(mockFS, subPkgPath) + assert.NoError(t, err) + + hctx := &hydrationContext{ + root: &pkgNode{pkg: rootPkg}, + pkgs: map[types.UniquePath]*pkgNode{}, + fileSystem: mockFS, + } + hctx.pkgs[rootPkg.UniquePath] = &pkgNode{pkg: rootPkg} + hctx.pkgs[subPkg.UniquePath] = &pkgNode{pkg: subPkg} + + updateRenderStatus(hctx, nil) + + // Root should have the condition + rootKf, err := kptfileutil.ReadKptfile(mockFS, rootPath) + assert.NoError(t, err) + assert.NotNil(t, rootKf.Status) + assert.Len(t, rootKf.Status.Conditions, 1) + assert.Equal(t, kptfilev1.ConditionTrue, rootKf.Status.Conditions[0].Status) + + // Subpackage should NOT have any condition + subKf, err := kptfileutil.ReadKptfile(mockFS, subPkgPath) + assert.NoError(t, err) + assert.True(t, subKf.Status == nil || len(subKf.Status.Conditions) == 0) +} + func TestPkgNode_ClearAnnotationsOnMutFailure(t *testing.T) { tests := []struct { name string diff --git a/pkg/api/kptfile/v1/types.go b/pkg/api/kptfile/v1/types.go index 1baab8c203..7d160ed61e 100644 --- a/pkg/api/kptfile/v1/types.go +++ b/pkg/api/kptfile/v1/types.go @@ -431,6 +431,23 @@ const ( ConditionUnknown ConditionStatus = "Unknown" ) +// Rendered condition type and reasons +const ( + ConditionTypeRendered = "Rendered" + ReasonRenderSuccess = "RenderSuccess" + ReasonRenderFailed = "RenderFailed" +) + +// NewRenderedCondition creates a Rendered status condition. +func NewRenderedCondition(status ConditionStatus, reason, message string) Condition { + return Condition{ + Type: ConditionTypeRendered, + Status: status, + Reason: reason, + Message: message, + } +} + // BFSRenderAnnotation is an annotation that can be used to indicate that a package // should be hydrated from the root package to the subpackages in a Breadth-First Level Order manner. // SaveOnRenderFailureAnnotation is an annotation that controls whether partially rendered diff --git a/pkg/kptfile/kptfileutil/util.go b/pkg/kptfile/kptfileutil/util.go index 01018a3ff4..2070142470 100644 --- a/pkg/kptfile/kptfileutil/util.go +++ b/pkg/kptfile/kptfileutil/util.go @@ -78,7 +78,7 @@ func (e *UnknownKptfileResourceError) Error() string { func WriteFile(dir string, k any) error { const op errors.Op = "kptfileutil.WriteFile" - b, err := yaml.MarshalWithOptions(k, &yaml.EncoderOptions{SeqIndent: yaml.WideSequenceStyle}) + b, err := marshalKptfile(k) if err != nil { return err } @@ -94,6 +94,25 @@ func WriteFile(dir string, k any) error { return nil } +// WriteKptfileToFS writes a Kptfile to the given filesystem at the specified directory. +func WriteKptfileToFS(fs filesys.FileSystem, dir string, k any) error { + const op errors.Op = "kptfileutil.WriteKptfileToFS" + b, err := marshalKptfile(k) + if err != nil { + return err + } + err = fs.WriteFile(filepath.Join(dir, kptfilev1.KptFileName), b) + if err != nil { + return errors.E(op, errors.IO, types.UniquePath(dir), err) + } + return nil +} + +// marshalKptfile marshals a Kptfile struct to YAML bytes. +func marshalKptfile(k any) ([]byte, error) { + return yaml.MarshalWithOptions(k, &yaml.EncoderOptions{SeqIndent: yaml.WideSequenceStyle}) +} + // ValidateInventory returns true and a nil error if the passed inventory // is valid; otherwiste, false and the reason the inventory is not valid // is returned. A valid inventory must have a non-empty namespace, name, From ac7d118640e87d74d722e394c05e37f13aefa322 Mon Sep 17 00:00:00 2001 From: Michael Greaves Date: Thu, 26 Feb 2026 10:44:22 +0100 Subject: [PATCH 10/14] Proofreading of chapter 1. Signed-off-by: Michael Greaves --- .../en/book/01-getting-started/_index.md | 121 +++++++++--------- 1 file changed, 57 insertions(+), 64 deletions(-) diff --git a/documentation/content/en/book/01-getting-started/_index.md b/documentation/content/en/book/01-getting-started/_index.md index d35f179577..0b5c411e20 100644 --- a/documentation/content/en/book/01-getting-started/_index.md +++ b/documentation/content/en/book/01-getting-started/_index.md @@ -1,8 +1,7 @@ --- title: "Chapter 1: Getting started" linkTitle: "Chapter 1: Getting started" -description: This chapter is a quick introduction to kpt using an example to demonstrate important concepts and - features. The following chapters will cover these concepts in detail. +description: This chapter provides a quick introduction to kpt, using examples to demonstrate the important concepts and features. The following chapters cover these concepts in detail. toc: true menu: main: @@ -10,11 +9,11 @@ menu: weight: 10 --- -## System Requirements +## System requirements ### kpt -Install the [kpt CLI](installation/kpt-cli): +Install the [kpt CLI](installation/kpt-cli), using the following command: ```shell kpt version @@ -22,43 +21,43 @@ kpt version ### Git -kpt requires that you have [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) installed and +`kpt` requires that you have [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) installed and configured. -### Container Runtime +### Container runtime -`kpt` requires you to have at least one of the following runtimes installed and configured. +`kpt` requires that you have at least one of the following runtimes installed and configured. #### Docker -Please follow the [instructions](https://docs.docker.com/get-docker) to install and configure Docker. +Follow the [instructions](https://docs.docker.com/get-docker) to install and configure Docker. #### Podman -Please follow the [instructions](https://podman.io/getting-started/installation) to install and configure Podman. +Follow the [instructions](https://podman.io/getting-started/installation) to install and configure Podman. -If you want to set up rootless container runtime, [this](https://rootlesscontaine.rs/) may be a useful resource for you. +If you want to set up a rootless container runtime, then [this](https://rootlesscontaine.rs/) may be a useful resource for you. Environment variables can be used to control which container runtime to use. More details can be found in the reference documents for [`kpt fn render`](../../reference/cli/fn/render/) and [`kpt fn eval`](../../reference/cli/fn/eval/). ### Kubernetes cluster -In order to deploy the examples, you need a Kubernetes cluster and a configured kubeconfig context. +To deploy the examples, you need a Kubernetes cluster and a configured kubeconfig context. -For testing purposes, [kind](https://kind.sigs.k8s.io/docs/user/quick-start/) tool is useful for running ephemeral -Kubernetes cluster on your local host. +For testing purposes, the [kind](https://kind.sigs.k8s.io/docs/user/quick-start/) tool is useful for running an ephemeral Kubernetes +cluster on your local host. ## Quickstart In this example, you are going to configure and deploy Nginx to a Kubernetes cluster. -### Fetch the package +### Fetching the package -kpt is fully integrated with Git and enables forking, rebasing and versioning a package of configuration using the +`kpt` is fully integrated with Git and enables the forking, rebasing, and versioning of a configuration package using the underlying Git version control system. -First, let's fetch the _kpt package_ from Git to your local filesystem: +First, using the following command, fetch the kpt package from Git to your local filesystem: ```shell kpt pkg get https://github.com/kptdev/kpt/package-examples/nginx@v1.0.0-beta.61 @@ -70,9 +69,9 @@ Subsequent commands are run from the `nginx` directory: cd nginx ``` -`kpt pkg` commands provide the functionality for working with packages on Git and on your local filesystem. +The `kpt pkg` commands provide the functionality for working with packages on Git and on your local filesystem. -Next, let's quickly view the content of the package: +Next, use the following command to view the content of the package: ```shell kpt pkg tree @@ -82,36 +81,34 @@ Package "nginx" └── [svc.yaml] Service my-nginx-svc ``` -As you can see, this package contains 3 resources in 3 files. There is a special file named `Kptfile` which is used by +As can be seen, this package contains three resources in three files. There is a special file named `Kptfile`. This file is used by the kpt tool itself and is not deployed to the cluster. Later chapters will explain the `Kptfile` in detail. -Initialize a local Git repo and commit the forked copy of the package: +Initialize a local Git repo and commit the forked copy of the package, using the following commands: ```shell git init; git add .; git commit -m "Pristine nginx package" ``` -### Customize the package +### Customizing the package -At this point, you typically want to customize the package. With kpt, you can use different approaches depending on your -use case. +At this point, it is a good idea to customize the package. With kpt, you can use different approaches, depending on your use case. -#### Manual Editing +#### Manual editing -You may want to manually edit the files. For example, modify the value of `spec.replicas` in `deployment.yaml` using -your favorite editor: +You may want to edit the files manually. For example, modify the value of `spec.replicas` in the `deployment.yaml` using your favorite +editor: ```shell vim deployment.yaml ``` -#### Automating One-time Edits with Functions +#### Automating one-time edits with functions -The [`kpt fn`](../../reference/cli/fn/) set of commands enable you to execute programs called _kpt functions_. These -programs are packaged as containers and take in YAML files, mutate or validate them, and then output YAML. +The [`kpt fn`](../../reference/cli/fn/) set of commands enables you to execute programs called _kpt functions_. These programs are +packaged as containers and take in YAML files, mutate or validate them, and then output YAML. -For instance, you can use a function (`ghcr.io/kptdev/krm-functions-catalog/search-replace:latest`) to search and replace all the occurrences of -the `app` key in the `spec` section of the YAML document (`spec.**.app`) and set the value to `my-nginx`. +For example, you can use a function (`ghcr.io/kptdev/krm-functions-catalog/search-replace:latest`) to search for and replace all the occurrences of the `app` key, in the `spec` section of the YAML document (`spec.**.app`), and set the value to `my-nginx`. You can use the `kpt fn eval` command to run this mutation on your local files a single time: @@ -119,17 +116,17 @@ You can use the `kpt fn eval` command to run this mutation on your local files a kpt fn eval --image ghcr.io/kptdev/krm-functions-catalog/search-replace:latest -- by-path='spec.**.app' put-value=my-nginx ``` -To see what changes were made to the local package: +To see what changes were made to the local package, use the following command: ```shell git diff ``` -#### Declaratively Defining Edits +#### Declaratively defining edits -For operations that need to be performed repeatedly, there is a _declarative_ way to define a pipeline of functions as -part of the package (in the `Kptfile`). In this `nginx` package, the author has already declared a function (`kubeconform`) -that validates the resources using their OpenAPI schema. +For operations that need to be performed repeatedly, there is a _declarative_ way to define a pipeline of functions as part of the +package (in the `Kptfile`). In this `nginx` package, the author has already declared a function (`kubeconform`) that validates the +resources using their OpenAPI schema. ```yaml pipeline: @@ -137,8 +134,8 @@ pipeline: - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ``` -You might want to label all resources in the package. To achieve that, you can declare `set-labels` function in the -`pipeline` section of `Kptfile`. Add this by running the following command: +It might be a good idea to label all the resources in the package. To achieve this, you can declare the `set-labels` function, in the +`pipeline` section of the `Kptfile`. Add this by running the following command: ```shell cat >> Kptfile <> Kptfile < Date: Thu, 12 Mar 2026 11:07:21 +0100 Subject: [PATCH 11/14] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Michael Greaves --- documentation/content/en/book/01-getting-started/_index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/content/en/book/01-getting-started/_index.md b/documentation/content/en/book/01-getting-started/_index.md index 0b5c411e20..a1f4af7d90 100644 --- a/documentation/content/en/book/01-getting-started/_index.md +++ b/documentation/content/en/book/01-getting-started/_index.md @@ -43,7 +43,7 @@ documents for [`kpt fn render`](../../reference/cli/fn/render/) and [`kpt fn eva ### Kubernetes cluster -To deploy the examples, you need a Kubernetes cluster and a configured kubeconfig context. +To deploy the examples, you need a Kubernetes cluster and a configured kubectl context. For testing purposes, the [kind](https://kind.sigs.k8s.io/docs/user/quick-start/) tool is useful for running an ephemeral Kubernetes cluster on your local host. @@ -106,7 +106,7 @@ vim deployment.yaml #### Automating one-time edits with functions The [`kpt fn`](../../reference/cli/fn/) set of commands enables you to execute programs called _kpt functions_. These programs are -packaged as containers and take in YAML files, mutate or validate them, and then output YAML. +packaged as containers and take YAML files as input, mutate or validate them, and then output YAML. For example, you can use a function (`ghcr.io/kptdev/krm-functions-catalog/search-replace:latest`) to search for and replace all the occurrences of the `app` key, in the `spec` section of the YAML document (`spec.**.app`), and set the value to `my-nginx`. From b08fa65a8e02728c6f917bba1d781c525a67484d Mon Sep 17 00:00:00 2001 From: Michael Greaves Date: Thu, 12 Mar 2026 11:16:15 +0100 Subject: [PATCH 12/14] Made a minor amendment to the sentence structure. Signed-off-by: Michael Greaves --- documentation/content/en/book/01-getting-started/_index.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/documentation/content/en/book/01-getting-started/_index.md b/documentation/content/en/book/01-getting-started/_index.md index a1f4af7d90..f86aee96c4 100644 --- a/documentation/content/en/book/01-getting-started/_index.md +++ b/documentation/content/en/book/01-getting-started/_index.md @@ -154,9 +154,7 @@ The pipeline is executed using the `render` command, as follows: kpt fn render ``` -Regardless of how you choose to customize the package — whether by manually editing it or running one-time functions using `kpt fn eval` - — you need to _render_ the package before applying it to the cluster. This ensures that all the functions declared in the package -have been executed, and the package is ready to be applied to the cluster. +Regardless of how you choose to customize the package, whether by manually editing it or running one-time functions using `kpt fn eval`, you need to _render_ the package before applying it to the cluster. This ensures that all the functions declared in the package have been executed, and the package is ready to be applied to the cluster. ### Applying the package From bef9794abb451c72ab92b2800944943c03223801 Mon Sep 17 00:00:00 2001 From: Aravindhan Ayyanathan Date: Wed, 18 Mar 2026 14:52:20 +0000 Subject: [PATCH 13/14] Fix ci failure (#4435) CI failure due to renderstatus merge fixed. Env variable to use nodejs as wasm env moved to Makefile from Github workflow Signed-off-by: aravind.est --- .github/workflows/go.yml | 1 - Makefile | 2 ++ .../basicpipeline-wasm/.expected/diff.patch | 15 +++------------ 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index eceb472523..754a2e7ac1 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -67,7 +67,6 @@ jobs: make test-docker env: KRM_FN_RUNTIME: ${{ matrix.runtime }} - KPT_FN_WASM_RUNTIME: nodejs build-macos: runs-on: macos-latest diff --git a/Makefile b/Makefile index 4072ef7d57..7b64949f8d 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,8 @@ YEAR_GEN := $(shell date '+%Y') GOBIN := $(shell go env GOPATH)/bin GIT_COMMIT := $(shell git rev-parse --short HEAD) +export KPT_FN_WASM_RUNTIME ?= nodejs + LDFLAGS := -ldflags "-X github.com/kptdev/kpt/run.version=${GIT_COMMIT} ifeq ($(OS),Windows_NT) # Do nothing diff --git a/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch b/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch index 33ebe1cf1c..9c2bb0566e 100644 --- a/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch +++ b/e2e/testdata/fn-render/basicpipeline-wasm/.expected/diff.patch @@ -1,18 +1,9 @@ diff --git a/Kptfile b/Kptfile -index ffcf186..9c131fb 100644 +index 17a7822..94b6f80 100644 --- a/Kptfile +++ b/Kptfile -@@ -6,12 +6,14 @@ metadata: - tier: backend - pipeline: - mutators: -- # The following 2 images are built from https://github.com/kptdev/krm-functions-catalog/pull/898. - - image: gcr.io/kpt-fn-demo/set-namespace:v0.5.0 -- # ghcr.io/kptdev/krm-functions-catalog/wasm/set-namespace:v0.5.0 - configMap: - namespace: staging - - image: gcr.io/kpt-fn-demo/set-labels:v0.2.0 -- # ghcr.io/kptdev/krm-functions-catalog/wasm/set-labels:v0.2.0 +@@ -12,3 +12,8 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/wasm/set-labels:v0.2.4 configMap: tier: backend +status: From cd92f0f3b9197bfbb581154b702ba16d8f339ebc Mon Sep 17 00:00:00 2001 From: Aravindhan Ayyanathan Date: Tue, 24 Mar 2026 15:29:53 +0000 Subject: [PATCH 14/14] Fix podman version check conditional expression Signed-off-by: Aravindhan Ayyanathan --- .github/workflows/go.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 754a2e7ac1..353e866689 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -1,4 +1,4 @@ -# Copyright 2019 The kpt Authors +# Copyright 2019-2026 The kpt Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -45,7 +45,7 @@ jobs: steps: # The CI complains about the podman not installed, adding some debugging info here. - name: check podman - if: ${{ matrix.runtime }} == 'podman' + if: ${{ matrix.runtime == 'podman' }} run: | which podman podman version