Skip to content

Commit

Permalink
Refactor: Run before and after script of container runner inside the …
Browse files Browse the repository at this point in the history
…container using host runner

Signed-off-by: GLVS Kiriti <[email protected]>
  • Loading branch information
GLVSKiriti committed Aug 1, 2024
1 parent 0c38982 commit d8baeb5
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 80 deletions.
11 changes: 6 additions & 5 deletions cmd/declarative.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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.
Expand Down
78 changes: 11 additions & 67 deletions pkg/declarative/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"io"
"log"
"os"
"path/filepath"

"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/image"
Expand Down Expand Up @@ -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)
Expand All @@ -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),
},
},
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
16 changes: 9 additions & 7 deletions pkg/declarative/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/declarative/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit d8baeb5

Please sign in to comment.