Skip to content

Commit

Permalink
Implementation of the Starlark run_local() function
Browse files Browse the repository at this point in the history
This patch implements the Go code for starlark builtin function run_local(). This
function allows Crashd script to run arbitrary command  from on the local machine.

This patch does the followings:
- Adds Go function to support starlark builtin func for run_local
- Adds and updates tests for run_local

Signed-off-by: Vladimir Vivien <vivienv@vmware.com>
  • Loading branch information
vladimirvivien committed Jul 1, 2020
1 parent 7ea48e8 commit a46c358
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 0 deletions.
32 changes: 32 additions & 0 deletions starlark/run_local.go
@@ -0,0 +1,32 @@
// Copyright (c) 2020 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package starlark

import (
"fmt"

"github.com/vladimirvivien/echo"
"go.starlark.net/starlark"
)

// runLocalFunc is a built-in starlark function that runs a provided command on the local machine.
// It returns the result of the command as struct containing information about the executed command.
// Starlark format: run_local(<command string>)
func runLocalFunc(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var cmdStr string
if args != nil && args.Len() == 1 {
cmd, ok := args.Index(0).(starlark.String)
if !ok {
return starlark.None, fmt.Errorf("%s: command must be a string", identifiers.runLocal)
}
cmdStr = string(cmd)
}

p := echo.New().RunProc(cmdStr)
if p.Err() != nil {
return starlark.None, fmt.Errorf("%s: %s", identifiers.runLocal, p.Err())
}

return starlark.String(p.Result()), nil
}
84 changes: 84 additions & 0 deletions starlark/run_local_test.go
@@ -0,0 +1,84 @@
// Copyright (c) 2020 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package starlark

import (
"strings"
"testing"

"go.starlark.net/starlark"
)

func TestRunLocalFunc(t *testing.T) {
tests := []struct {
name string
args func(t *testing.T) starlark.Tuple
eval func(t *testing.T, args starlark.Tuple)
}{
{
name: "simple command",
args: func(t *testing.T) starlark.Tuple { return starlark.Tuple{starlark.String("echo 'Hello World!'")} },
eval: func(t *testing.T, args starlark.Tuple) {
val, err := runLocalFunc(newTestThreadLocal(t), nil, args, nil)
if err != nil {
t.Fatal(err)
}
result := ""
if r, ok := val.(starlark.String); ok {
result = string(r)
}
if result != "Hello World!" {
t.Errorf("unexpected result: %s", result)
}
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
test.eval(t, test.args(t))
})
}
}

func TestRunLocalScript(t *testing.T) {
tests := []struct {
name string
script string
eval func(t *testing.T, script string)
}{
{
name: "run local",
script: `
result = run_local("""echo 'Hello World!'""")
`,
eval: func(t *testing.T, script string) {
exe := New()
if err := exe.Exec("test.star", strings.NewReader(script)); err != nil {
t.Fatal(err)
}

resultVal := exe.result["result"]
if resultVal == nil {
t.Fatal("run_local() should be assigned to a variable for test")
}
result, ok := resultVal.(starlark.String)
if !ok {
t.Fatal("run_local() should return a string")
}

if string(result) != "Hello World!" {
t.Fatalf("uneexpected result %s", result)
}

},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
test.eval(t, test.script)
})
}
}
1 change: 1 addition & 0 deletions starlark/starlark_exec.go
Expand Up @@ -75,6 +75,7 @@ func newPredeclareds() starlark.StringDict {
identifiers.hostListProvider: starlark.NewBuiltin(identifiers.hostListProvider, hostListProvider),
identifiers.resources: starlark.NewBuiltin(identifiers.resources, resourcesFunc),
identifiers.run: starlark.NewBuiltin(identifiers.run, runFunc),
identifiers.runLocal: starlark.NewBuiltin(identifiers.runLocal, runLocalFunc),
identifiers.capture: starlark.NewBuiltin(identifiers.capture, captureFunc),
identifiers.copyFrom: starlark.NewBuiltin(identifiers.copyFrom, copyFromFunc),
identifiers.kubeCfg: starlark.NewBuiltin(identifiers.kubeCfg, kubeConfigFn),
Expand Down
2 changes: 2 additions & 0 deletions starlark/support.go
Expand Up @@ -34,6 +34,7 @@ var (
hostResource string
resources string
run string
runLocal string
capture string
copyFrom string

Expand All @@ -55,6 +56,7 @@ var (
hostResource: "host_resource",
resources: "resources",
run: "run",
runLocal: "run_local",
capture: "capture",
copyFrom: "copy_from",

Expand Down

0 comments on commit a46c358

Please sign in to comment.