github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/commands/fn/render/cmdrender.go (about) 1 // Copyright 2021 Google LLC 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/printer" 28 "github.com/GoogleContainerTools/kpt/internal/util/argutil" 29 "github.com/GoogleContainerTools/kpt/internal/util/cmdutil" 30 "github.com/GoogleContainerTools/kpt/internal/util/pathutil" 31 "github.com/GoogleContainerTools/kpt/internal/util/render" 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.AllowWasm, "allow-alpha-wasm", r.RunnerOptions.AllowWasm, 63 "allow wasm to be used during pipeline execution.") 64 cmdutil.FixDocs("kpt", parent, c) 65 r.Command = c 66 return r 67 } 68 69 func NewCommand(ctx context.Context, parent string) *cobra.Command { 70 return NewRunner(ctx, parent).Command 71 } 72 73 // Runner contains the run function pipeline run command 74 type Runner struct { 75 pkgPath string 76 resultsDirPath string 77 dest string 78 Command *cobra.Command 79 ctx context.Context 80 81 RunnerOptions fnruntime.RunnerOptions 82 } 83 84 func (r *Runner) InitDefaults() { 85 r.RunnerOptions.InitDefaults() 86 } 87 88 func (r *Runner) preRunE(c *cobra.Command, args []string) error { 89 if len(args) == 0 { 90 // no pkg path specified, default to current working dir 91 wd, err := os.Getwd() 92 if err != nil { 93 return err 94 } 95 r.pkgPath = wd 96 } else { 97 // resolve and validate the provided path 98 r.pkgPath = args[0] 99 } 100 var err error 101 r.pkgPath, err = argutil.ResolveSymlink(r.ctx, r.pkgPath) 102 if err != nil { 103 return err 104 } 105 if r.dest != "" && r.dest != cmdutil.Stdout && r.dest != cmdutil.Unwrap { 106 if err := cmdutil.CheckDirectoryNotPresent(r.dest); err != nil { 107 return err 108 } 109 } 110 if r.resultsDirPath != "" { 111 err := os.MkdirAll(r.resultsDirPath, 0755) 112 if err != nil { 113 return fmt.Errorf("cannot read or create results dir %q: %w", r.resultsDirPath, err) 114 } 115 } 116 return nil 117 } 118 119 func (r *Runner) runE(c *cobra.Command, _ []string) error { 120 var output io.Writer 121 outContent := bytes.Buffer{} 122 if r.dest != "" { 123 // this means the output should be written to another destination 124 // capture the content to be written 125 output = &outContent 126 } 127 absPkgPath, _, err := pathutil.ResolveAbsAndRelPaths(r.pkgPath) 128 if err != nil { 129 return err 130 } 131 executor := render.Renderer{ 132 PkgPath: absPkgPath, 133 ResultsDirPath: r.resultsDirPath, 134 Output: output, 135 RunnerOptions: r.RunnerOptions, 136 FileSystem: filesys.FileSystemOrOnDisk{}, 137 } 138 if err := executor.Execute(r.ctx); err != nil { 139 return err 140 } 141 142 return cmdutil.WriteFnOutput(r.dest, outContent.String(), false, printer.FromContextOrDie(r.ctx).OutStream()) 143 }