Skip to content

Commit

Permalink
Merge pull request #111 from vladimirvivien/impl-archive-func
Browse files Browse the repository at this point in the history
Implementation of the archive script function
  • Loading branch information
vladimirvivien committed Jul 10, 2020
2 parents c1b2755 + 4afbef5 commit 2bece74
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 1 deletion.
52 changes: 52 additions & 0 deletions starlark/archive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2020 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package starlark

import (
"fmt"

"go.starlark.net/starlark"

"github.com/vmware-tanzu/crash-diagnostics/archiver"
)

// archiveFunc is a built-in starlark function that bundles specified directories into
// an arhive format (i.e. tar.gz)
// Starlark format: archive(file_name=<file name> ,source_paths=list)
func archiveFunc(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
var outputFile string
var paths *starlark.List

if err := starlark.UnpackArgs(
identifiers.archive, args, kwargs,
"output_file?", &outputFile,
"source_paths", &paths,
); err != nil {
return starlark.None, fmt.Errorf("%s: %s", identifiers.archive, err)
}

if len(outputFile) == 0 {
outputFile = "archive.tar.gz"
}

if paths != nil && paths.Len() == 0 {
return starlark.None, fmt.Errorf("%s: one or more paths required", identifiers.archive)
}

if err := archiver.Tar(outputFile, getPathElements(paths)...); err != nil {
return starlark.None, fmt.Errorf("%s failed: %s", identifiers.archive, err)
}

return starlark.String(outputFile), nil
}

func getPathElements(paths *starlark.List) []string {
pathElems := []string{}
for i := 0; i < paths.Len(); i++ {
if val, ok := paths.Index(i).(starlark.String); ok {
pathElems = append(pathElems, string(val))
}
}
return pathElems
}
101 changes: 101 additions & 0 deletions starlark/archive_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright (c) 2020 VMware, Inc. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package starlark

import (
"os"
"strings"
"testing"

"go.starlark.net/starlark"
)

func TestArchiveFunc(t *testing.T) {
tests := []struct {
name string
args func(t *testing.T) []starlark.Tuple
eval func(t *testing.T, kwargs []starlark.Tuple)
}{
{
name: "arhive single file",
args: func(t *testing.T) []starlark.Tuple {
return []starlark.Tuple{
{starlark.String("output_file"), starlark.String("/tmp/out.tar.gz")},
{starlark.String("source_paths"), starlark.NewList([]starlark.Value{starlark.String(defaults.workdir)})},
}
},
eval: func(t *testing.T, kwargs []starlark.Tuple) {
val, err := archiveFunc(newTestThreadLocal(t), nil, nil, kwargs)
if err != nil {
t.Fatal(err)
}
expected := "/tmp/out.tar.gz"
defer func() {
os.RemoveAll(expected)
os.RemoveAll(defaults.workdir)
}()

result := ""
if r, ok := val.(starlark.String); ok {
result = string(r)
}
if result != expected {
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 TestArchiveScript(t *testing.T) {
tests := []struct {
name string
script string
eval func(t *testing.T, script string)
}{
{
name: "archive defaults",
script: `
result = archive(output_file="/tmp/archive.tar.gz", source_paths=["/tmp/crashd"])
`,
eval: func(t *testing.T, script string) {
exe := New()
if err := exe.Exec("test.star", strings.NewReader(script)); err != nil {
t.Fatal(err)
}

expected := "/tmp/archive.tar.gz"
var result string
resultVal := exe.result["result"]
if resultVal == nil {
t.Fatal("archive() should be assigned to a variable for test")
}
res, ok := resultVal.(starlark.String)
if !ok {
t.Fatal("archive() should return a string")
}
result = string(res)
defer func() {
os.RemoveAll(result)
os.RemoveAll(defaults.workdir)
}()

if result != expected {
t.Errorf("unexpected 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/crashd_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func testCrashdConfigFunc(t *testing.T) {
name: "crash_config saved in thread",
script: `crashd_config(workdir="fooval", default_shell="barval")`,
eval: func(t *testing.T, script string) {
defer os.RemoveAll("fooval")
exe := New()
if err := exe.Exec("test.star", strings.NewReader(script)); err != nil {
t.Fatal(err)
Expand Down
1 change: 1 addition & 0 deletions starlark/starlark_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ func newPredeclareds() starlark.StringDict {
identifiers.sshCfg: starlark.NewBuiltin(identifiers.sshCfg, sshConfigFn),
identifiers.hostListProvider: starlark.NewBuiltin(identifiers.hostListProvider, hostListProvider),
identifiers.resources: starlark.NewBuiltin(identifiers.resources, resourcesFunc),
identifiers.archive: starlark.NewBuiltin(identifiers.archive, archiveFunc),
identifiers.run: starlark.NewBuiltin(identifiers.run, runFunc),
identifiers.runLocal: starlark.NewBuiltin(identifiers.runLocal, runLocalFunc),
identifiers.capture: starlark.NewBuiltin(identifiers.capture, captureFunc),
Expand Down
3 changes: 2 additions & 1 deletion starlark/support.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ var (
capture string
captureLocal string
copyFrom string
archive string

kubeCapture string
kubeGet string
Expand All @@ -62,6 +63,7 @@ var (
capture: "capture",
captureLocal: "capture_local",
copyFrom: "copy_from",
archive: "archive",

kubeCapture: "kube_capture",
kubeGet: "kube_get",
Expand Down Expand Up @@ -91,7 +93,6 @@ var (
pkPath: func() string {
return filepath.Join(os.Getenv("HOME"), ".ssh", "id_rsa")
}(),
outPath: "./crashd.tar.gz",
connRetries: 30,
connTimeout: 30,
}
Expand Down

0 comments on commit 2bece74

Please sign in to comment.