Enable exec functions (Alpha)

This commit is contained in:
Phillip Wittrock
2020-05-05 07:47:08 -07:00
parent 174b2ed62e
commit 95f0a44fc0
4 changed files with 80 additions and 25 deletions

View File

@@ -19,7 +19,7 @@ linters:
# - gochecknoinits
# - goconst
# - gocritic
- gocyclo
# - gocyclo
- gofmt
- goimports
# - golint

View File

@@ -42,14 +42,17 @@ func GetRunFnRunner(name string) *RunFnRunner {
&r.Image, "image", "",
"run this image as a function instead of discovering them.")
r.Command.Flags().BoolVar(
&r.EnableStar, "enable-star", false, "enable support for starlark functions.")
r.Command.Flags().MarkHidden("enable-star")
&r.EnableExec, "enable-exec", false, "enable support for exec functions. (Alpha)")
r.Command.Flags().StringVar(
&r.StarPath, "star-path", "", "run a starlark script as a function.")
r.Command.Flags().MarkHidden("star-path")
&r.ExecPath, "exec-path", "", "run an executable as a function. (Alpha)")
r.Command.Flags().StringArrayVar(
&r.ExecArgs, "exec-arg", nil, "arg for executable function. (Alpha)")
r.Command.Flags().BoolVar(
&r.EnableStar, "enable-star", false, "enable support for starlark functions. (Alpha)")
r.Command.Flags().StringVar(
&r.StarName, "star-name", "", "name of starlark program.")
r.Command.Flags().MarkHidden("star-name")
&r.StarPath, "star-path", "", "run a starlark script as a function. (Alpha)")
r.Command.Flags().StringVar(
&r.StarName, "star-name", "", "name of starlark program. (Alpha)")
r.Command.Flags().StringVar(
&r.ResultsDir, "results-dir", "", "write function results to this dir")
@@ -79,6 +82,9 @@ type RunFnRunner struct {
EnableStar bool
StarPath string
StarName string
EnableExec bool
ExecPath string
ExecArgs []string
RunFns runfn.RunFns
ResultsDir string
Network bool
@@ -94,14 +100,13 @@ func (r *RunFnRunner) runE(c *cobra.Command, args []string) error {
// Functions to run.
func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, args, dataItems []string) (
[]*yaml.RNode, error) {
if r.Image == "" && r.StarPath == "" {
if r.Image == "" && r.StarPath == "" && r.ExecPath == "" {
return nil, nil
}
var fn *yaml.RNode
var err error
// if image isn't specified, then Functions is empty
if r.Image != "" {
// create the function spec to set as an annotation
fn, err = yaml.Parse(`container: {}`)
@@ -143,8 +148,29 @@ func (r *RunFnRunner) getContainerFunctions(c *cobra.Command, args, dataItems []
if err != nil {
return nil, err
}
} else {
return nil, nil
} else if r.EnableExec && r.ExecPath != "" {
// create the function spec to set as an annotation
fn, err = yaml.Parse(`exec: {}`)
if err != nil {
return nil, err
}
err = fn.PipeE(
yaml.Lookup("exec"),
yaml.SetField("path", yaml.NewScalarRNode(r.ExecPath)))
if err != nil {
return nil, err
}
// add the arguments
for _, a := range r.ExecArgs {
err = fn.PipeE(
yaml.LookupCreate(yaml.SequenceNode, "exec", "args"),
yaml.Append(yaml.NewScalarRNode(a).YNode()))
if err != nil {
return nil, err
}
}
}
// create the function config
@@ -221,8 +247,12 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
return errors.Errorf("must specify --enable-star with --star-path")
}
if !r.EnableExec && r.ExecPath != "" {
return errors.Errorf("must specify --enable-exec with --exec-path")
}
if c.ArgsLenAtDash() >= 0 && r.Image == "" &&
!(r.EnableStar && r.StarPath != "") {
!(r.EnableStar && r.StarPath != "") && !(r.EnableExec && r.ExecPath != "") {
return errors.Errorf("must specify --image")
}
@@ -270,6 +300,7 @@ func (r *RunFnRunner) preRunE(c *cobra.Command, args []string) error {
Network: r.Network,
NetworkName: r.NetworkName,
EnableStarlark: r.EnableStar,
EnableExec: r.EnableExec,
StorageMounts: storageMounts,
ResultsDir: r.ResultsDir,
}

View File

@@ -30,10 +30,19 @@ type FunctionSpec struct {
// Starlark is the spec for running a function as a starlark script
Starlark StarlarkSpec `json:"starlark,omitempty" yaml:"starlark,omitempty"`
// ExecSpec is the spec for running a function as an executable
Exec ExecSpec `json:"exec,omitempty" yaml:"exec,omitempty"`
// Mounts are the storage or directories to mount into the container
StorageMounts []StorageMount `json:"mounts,omitempty" yaml:"mounts,omitempty"`
}
type ExecSpec struct {
Path string `json:"path,omitempty" yaml:"path,omitempty"`
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
}
// ContainerSpec defines a spec for running a function as a container
type ContainerSpec struct {
// Image is the container image to run

View File

@@ -15,6 +15,7 @@ import (
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/container"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/exec"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/starlark"
"sigs.k8s.io/kustomize/kyaml/kio"
@@ -64,6 +65,9 @@ type RunFns struct {
// EnableStarlark will enable functions run as starlark scripts
EnableStarlark bool
// EnableExec will enable exec functions
EnableExec bool
// DisableContainers will disable functions run as containers
DisableContainers bool
@@ -333,16 +337,14 @@ func (r *RunFns) init() {
// ffp provides function filters
func (r *RunFns) ffp(spec runtimeutil.FunctionSpec, api *yaml.RNode) (kio.Filter, error) {
var resultsFile string
if r.ResultsDir != "" {
resultsFile = filepath.Join(r.ResultsDir, fmt.Sprintf(
"results-%v.yaml", r.resultsCount))
atomic.AddUint32(&r.resultsCount, 1)
}
if !r.DisableContainers && spec.Container.Image != "" {
var resultsFile string
// TODO: Add a test for this behavior
if r.ResultsDir != "" {
resultsFile = filepath.Join(r.ResultsDir, fmt.Sprintf(
"results-%v.yaml", r.resultsCount))
atomic.AddUint32(&r.resultsCount, 1)
}
cf := &container.Filter{
Image: spec.Container.Image,
Network: spec.Network,
@@ -372,11 +374,24 @@ func (r *RunFns) ffp(spec runtimeutil.FunctionSpec, api *yaml.RNode) (kio.Filter
}
p = path.Join(r.Path, path.Dir(p), spec.Starlark.Path)
return &starlark.Filter{
Name: spec.Starlark.Name,
Path: p,
FunctionFilter: runtimeutil.FunctionFilter{FunctionConfig: api},
}, nil
sf := &starlark.Filter{Name: spec.Starlark.Name, Path: p}
sf.FunctionConfig = api
sf.GlobalScope = r.GlobalScope
sf.ResultsFile = resultsFile
sf.DeferFailure = spec.DeferFailure
return sf, nil
}
if r.EnableExec && spec.Exec.Path != "" {
ef := &exec.Filter{Path: spec.Exec.Path, Args: spec.Exec.Args}
ef.FunctionConfig = api
ef.GlobalScope = r.GlobalScope
ef.ResultsFile = resultsFile
ef.DeferFailure = spec.DeferFailure
return ef, nil
}
return nil, nil
}