diff --git a/cmd/declarative.go b/cmd/declarative.go index 5807e903..f14a4356 100644 --- a/cmd/declarative.go +++ b/cmd/declarative.go @@ -79,6 +79,9 @@ func runTestSteps(test declarative.Test) error { // spawn an alpine container runner = &declarative.Containerrunner{Image: "golang"} ctx = context.Background() + ctx = context.WithValue(ctx, declarative.ContextKey("ruleName"), test.Rule) + ctx = context.WithValue(ctx, declarative.ContextKey("beforeScript"), test.Before) + ctx = context.WithValue(ctx, declarative.ContextKey("afterScript"), test.After) default: return fmt.Errorf("unsupported runner: %v", test.Runner) } @@ -89,11 +92,9 @@ func runTestSteps(test declarative.Test) error { } // Execute each step in the test. - for _, step := range test.Steps { - err := runner.ExecuteStep(ctx, step) - if err != nil { - return fmt.Errorf("error executing steps for the rule %v : %v", test.Rule, err) - } + err := runner.ExecuteStep(ctx, test.Steps) + if err != nil { + return fmt.Errorf("error executing steps for the rule %v : %v", test.Rule, err) } // Execute the "After" script. diff --git a/pkg/declarative/container.go b/pkg/declarative/container.go index 5df868fe..d5aa91a7 100644 --- a/pkg/declarative/container.go +++ b/pkg/declarative/container.go @@ -20,6 +20,7 @@ import ( "io" "log" "os" + "path/filepath" "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/image" @@ -86,50 +87,10 @@ func (r *Containerrunner) Setup(ctx context.Context, beforeScript string) error if err != nil { return fmt.Errorf("error starting Docker container: %v", err) } - - // Run beforescript - cmd := []string{"sh", "-c", beforeScript} - - execConfig := container.ExecOptions{ - Cmd: cmd, - } - - execID, err := cli.ContainerExecCreate(ctx, r.ContainerId, execConfig) - if err != nil { - return fmt.Errorf("error creating Docker exec: %v", err) - } - - err = cli.ContainerExecStart(ctx, execID.ID, container.ExecStartOptions{}) - if err != nil { - return fmt.Errorf("error starting Docker exec: %v", err) - } - - // Use this channel to wait for the exec instance to complete i.e, beforescript - done := make(chan error, 1) - go func() { - for { - inspectResp, err := cli.ContainerExecInspect(ctx, execID.ID) - if err != nil { - done <- fmt.Errorf("error inspecting Docker exec: %v", err) - return - } - - if !inspectResp.Running { - if inspectResp.ExitCode != 0 { - done <- fmt.Errorf("before execution failed with exit code %v", inspectResp.ExitCode) - } else { - done <- nil - } - return - } - } - }() - - err = <-done - return err + return nil } -func (r *Containerrunner) ExecuteStep(ctx context.Context, step SyscallStep) error { +func (r *Containerrunner) ExecuteStep(ctx context.Context, steps []SyscallStep) error { cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { return fmt.Errorf("error creating Docker Client: %v", err) @@ -139,11 +100,11 @@ func (r *Containerrunner) ExecuteStep(ctx context.Context, step SyscallStep) err testFile := Tests{ Tests: []Test{ { - Rule: "any-name", + Rule: ctx.Value(ContextKey("ruleName")).(string), Runner: "HostRunner", - Before: "", - Steps: []SyscallStep{step}, - After: "", + Before: ctx.Value(ContextKey("beforeScript")).(string), + Steps: steps, + After: ctx.Value(ContextKey("afterScript")).(string), }, }, } @@ -173,13 +134,14 @@ func (r *Containerrunner) ExecuteStep(ctx context.Context, step SyscallStep) err return fmt.Errorf("error creating tar reader: %v", err) } - err = cli.CopyToContainer(ctx, r.ContainerId, "/syscall.yaml", tarReader, container.CopyToContainerOptions{}) + err = cli.CopyToContainer(ctx, r.ContainerId, "/", tarReader, container.CopyToContainerOptions{}) if err != nil { return fmt.Errorf("error copying yaml file to container: %v", err) } - // Prepare the command to run the event-generator with the write syscall - cmd := []string{"./event-generator", "run", "declarative", "/syscall.yaml"} + // Prepare the command to run the event-generator inside container + yamlFileName := filepath.Base(tempFile.Name()) + cmd := []string{"/event-generator", "run", "declarative", "/" + yamlFileName} execConfig := container.ExecOptions{ Cmd: cmd, @@ -228,24 +190,6 @@ func (r *Containerrunner) Cleanup(ctx context.Context, afterScript string) error return fmt.Errorf("error creating Docker Client: %v", err) } - // If there is any afterScript execute it before removing the container - if afterScript != "" { - cmd := []string{"sh", "-c", afterScript} - execConfig := container.ExecOptions{ - Cmd: cmd, - } - - execID, err := cli.ContainerExecCreate(ctx, r.ContainerId, execConfig) - if err != nil { - return fmt.Errorf("error creating Docker exec: %v", err) - } - - err = cli.ContainerExecStart(ctx, execID.ID, container.ExecStartOptions{}) - if err != nil { - return fmt.Errorf("error starting Docker exec: %v", err) - } - } - err = cli.ContainerRemove(ctx, r.ContainerId, container.RemoveOptions{Force: true}) if err != nil { return fmt.Errorf("error removing Docker container: %v", err) diff --git a/pkg/declarative/host.go b/pkg/declarative/host.go index ed5f0ad0..6ad1e71f 100644 --- a/pkg/declarative/host.go +++ b/pkg/declarative/host.go @@ -31,14 +31,16 @@ func (r *Hostrunner) Setup(ctx context.Context, beforeScript string) error { return nil } -func (r *Hostrunner) ExecuteStep(ctx context.Context, step SyscallStep) error { - switch step.Syscall { - case "write": - if err := WriteSyscall(step.Args["filepath"], step.Args["content"]); err != nil { - return fmt.Errorf("write syscall failed with error: %v", err) +func (r *Hostrunner) ExecuteStep(ctx context.Context, steps []SyscallStep) error { + for _, step := range steps { + switch step.Syscall { + case "write": + if err := WriteSyscall(step.Args["filepath"], step.Args["content"]); err != nil { + return fmt.Errorf("write syscall failed with error: %v", err) + } + default: + return fmt.Errorf("unsupported syscall: %s", step.Syscall) } - default: - return fmt.Errorf("unsupported syscall: %s", step.Syscall) } return nil } diff --git a/pkg/declarative/interface.go b/pkg/declarative/interface.go index 9f415c4e..242f7eda 100644 --- a/pkg/declarative/interface.go +++ b/pkg/declarative/interface.go @@ -19,6 +19,9 @@ import "context" // Common runner interface for runners like hostrunner, container-runner etc.. type Runner interface { Setup(ctx context.Context, beforeScript string) error - ExecuteStep(ctx context.Context, step SyscallStep) error + ExecuteStep(ctx context.Context, steps []SyscallStep) error Cleanup(ctx context.Context, afterScript string) error } + +// A type which helps to store and retrive key-value pairs in context +type ContextKey string