github.com/SamarSidharth/kpt@v0.0.0-20231122062228-c7d747ae3ace/commands/fn/render/cmdrender.go (about) 1 // Copyright 2021 The kpt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package cmdrender contains the render command 16 package render 17 18 import ( 19 "bytes" 20 "context" 21 "fmt" 22 "io" 23 "os" 24 25 docs "github.com/GoogleContainerTools/kpt/internal/docs/generated/fndocs" 26 "github.com/GoogleContainerTools/kpt/internal/fnruntime" 27 "github.com/GoogleContainerTools/kpt/internal/util/argutil" 28 "github.com/GoogleContainerTools/kpt/internal/util/cmdutil" 29 "github.com/GoogleContainerTools/kpt/internal/util/pathutil" 30 "github.com/GoogleContainerTools/kpt/internal/util/render" 31 "github.com/GoogleContainerTools/kpt/pkg/printer" 32 "github.com/spf13/cobra" 33 "sigs.k8s.io/kustomize/kyaml/filesys" 34 ) 35 36 // NewRunner returns a command runner 37 func NewRunner(ctx context.Context, parent string) *Runner { 38 r := &Runner{ctx: ctx} 39 r.InitDefaults() 40 41 c := &cobra.Command{ 42 Use: "render [PKG_PATH] [flags]", 43 Short: docs.RenderShort, 44 Long: docs.RenderShort + "\n" + docs.RenderLong, 45 Example: docs.RenderExamples, 46 RunE: r.runE, 47 PreRunE: r.preRunE, 48 } 49 c.Flags().StringVar(&r.resultsDirPath, "results-dir", "", 50 "path to a directory to save function results") 51 c.Flags().StringVarP(&r.dest, "output", "o", "", 52 fmt.Sprintf("output resources are written to provided location. Allowed values: %s|%s|<OUT_DIR_PATH>", cmdutil.Stdout, cmdutil.Unwrap)) 53 54 c.Flags().Var(&r.RunnerOptions.ImagePullPolicy, "image-pull-policy", 55 "pull image before running the container "+r.RunnerOptions.ImagePullPolicy.HelpAllowedValues()) 56 _ = c.RegisterFlagCompletionFunc("image-pull-policy", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { 57 return r.RunnerOptions.ImagePullPolicy.AllStrings(), cobra.ShellCompDirectiveDefault 58 }) 59 60 c.Flags().BoolVar(&r.RunnerOptions.AllowExec, "allow-exec", r.RunnerOptions.AllowExec, 61 "allow binary executable to be run during pipeline execution.") 62 c.Flags().BoolVar(&r.RunnerOptions.AllowNetwork, "allow-network", false, 63 "allow functions to access network during pipeline execution.") 64 c.Flags().BoolVar(&r.RunnerOptions.AllowWasm, "allow-alpha-wasm", r.RunnerOptions.AllowWasm, 65 "allow wasm to be used during pipeline execution.") 66 cmdutil.FixDocs("kpt", parent, c) 67 r.Command = c 68 return r 69 } 70 71 func NewCommand(ctx context.Context, parent string) *cobra.Command { 72 return NewRunner(ctx, parent).Command 73 } 74 75 // Runner contains the run function pipeline run command 76 type Runner struct { 77 pkgPath string 78 resultsDirPath string 79 dest string 80 Command *cobra.Command 81 ctx context.Context 82 83 RunnerOptions fnruntime.RunnerOptions 84 } 85 86 func (r *Runner) InitDefaults() { 87 r.RunnerOptions.InitDefaults() 88 } 89 90 func (r *Runner) preRunE(_ *cobra.Command, args []string) error { 91 if len(args) == 0 { 92 // no pkg path specified, default to current working dir 93 wd, err := os.Getwd() 94 if err != nil { 95 return err 96 } 97 r.pkgPath = wd 98 } else { 99 // resolve and validate the provided path 100 r.pkgPath = args[0] 101 } 102 var err error 103 r.pkgPath, err = argutil.ResolveSymlink(r.ctx, r.pkgPath) 104 if err != nil { 105 return err 106 } 107 if r.dest != "" && r.dest != cmdutil.Stdout && r.dest != cmdutil.Unwrap { 108 if err := cmdutil.CheckDirectoryNotPresent(r.dest); err != nil { 109 return err 110 } 111 } 112 if r.resultsDirPath != "" { 113 err := os.MkdirAll(r.resultsDirPath, 0755) 114 if err != nil { 115 return fmt.Errorf("cannot read or create results dir %q: %w", r.resultsDirPath, err) 116 } 117 } 118 return nil 119 } 120 121 func (r *Runner) runE(_ *cobra.Command, _ []string) error { 122 var output io.Writer 123 outContent := bytes.Buffer{} 124 if r.dest != "" { 125 // this means the output should be written to another destination 126 // capture the content to be written 127 output = &outContent 128 } 129 absPkgPath, _, err := pathutil.ResolveAbsAndRelPaths(r.pkgPath) 130 if err != nil { 131 return err 132 } 133 executor := render.Renderer{ 134 PkgPath: absPkgPath, 135 ResultsDirPath: r.resultsDirPath, 136 Output: output, 137 RunnerOptions: r.RunnerOptions, 138 FileSystem: filesys.FileSystemOrOnDisk{}, 139 } 140 if _, err := executor.Execute(r.ctx); err != nil { 141 return err 142 } 143 144 return cmdutil.WriteFnOutput(r.dest, outContent.String(), false, printer.FromContextOrDie(r.ctx).OutStream()) 145 }