Skip to content

Commit

Permalink
Refactor: Setup and executestep methods are refactored
Browse files Browse the repository at this point in the history
Signed-off-by: GLVS Kiriti <[email protected]>
  • Loading branch information
GLVSKiriti committed Jul 31, 2024
1 parent eda7d83 commit 601a1f0
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 41 deletions.
11 changes: 0 additions & 11 deletions events/exampleyamlfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,3 @@ tests:
before: "wget"
steps:
after: ""

- rule: ContainerDriftDetectedOpenCreate
runner: ContainerRunner
before: ""
steps:
- syscall: "write"
args:
filepath: "/root/created-by-event-generator"
content: ""
after: "rm -f /root/created-by-event-generator"

108 changes: 78 additions & 30 deletions pkg/declarative/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/client"
"gopkg.in/yaml.v2"
)

type Containerrunner struct {
Expand All @@ -44,6 +45,7 @@ func (r *Containerrunner) Setup(beforeScript string) error {
return fmt.Errorf("error pulling Docker Image: %v", err)
}

// Read the response of body inorder to download the image
defer pullRes.Close()
_, err = io.Copy(io.Discard, pullRes)
if err != nil {
Expand All @@ -54,7 +56,7 @@ func (r *Containerrunner) Setup(beforeScript string) error {
resp, err := cli.ContainerCreate(context.Background(),
&container.Config{
Image: r.Image,
Cmd: []string{"sh", "-c", beforeScript},
Cmd: []string{"sleep", "1h"},
}, nil, nil, nil, "alpine-container-by-event-generator")

if err != nil {
Expand All @@ -71,8 +73,7 @@ func (r *Containerrunner) Setup(beforeScript string) error {
}

// Copy the event-generator executable into the container
cmd := exec.Command("docker", "cp", path_eg, fmt.Sprintf("%s:%s", r.ContainerId, "/"))
err = cmd.Run()
err = exec.Command("docker", "cp", path_eg, fmt.Sprintf("%s:%s", r.ContainerId, "/")).Run()
if err != nil {
return fmt.Errorf("error copying file to container: %v", err)
}
Expand All @@ -83,20 +84,46 @@ func (r *Containerrunner) Setup(beforeScript string) error {
return fmt.Errorf("error starting Docker container: %v", err)
}

// Wait for the container to finish executing the beforescript
// ContainerWait returns 2 channels
// statusCh - receives the container exit status once it stops running
// errCh - receives any error occurs while waiting for the container to stop
statusCh, errCh := cli.ContainerWait(context.Background(), r.ContainerId, container.WaitConditionNotRunning)
select {
case err := <-errCh:
if err != nil {
return fmt.Errorf("error waiting for the docker container: %v", err)
}
case <-statusCh:
// Run beforescript
cmd := []string{"sh", "-c", beforeScript}

execConfig := container.ExecOptions{
Cmd: cmd,
}

return nil
execID, err := cli.ContainerExecCreate(context.Background(), r.ContainerId, execConfig)
if err != nil {
return fmt.Errorf("error creating Docker exec: %v", err)
}

err = cli.ContainerExecStart(context.Background(), 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(context.Background(), 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
}

func (r *Containerrunner) ExecuteStep(step SyscallStep) error {
Expand All @@ -105,28 +132,49 @@ func (r *Containerrunner) ExecuteStep(step SyscallStep) error {
return fmt.Errorf("error creating Docker Client: %v", err)
}

// Check the container's current status
inspect, err := cli.ContainerInspect(context.Background(), r.ContainerId)
// Create a yaml structure for given step
testFile := Tests{
Tests: []Test{
{
Rule: "any-name",
Runner: "HostRunner",
Before: "",
Steps: []SyscallStep{step},
After: "",
},
},
}

// Marshall struct to yaml data
yamldata, err := yaml.Marshal(testFile)
if err != nil {
return fmt.Errorf("error inspecting docker container: %v", err)
return fmt.Errorf("error marshalling syscallstep input to yaml: %v", err)
}

// Start the container if it is not running
if !inspect.State.Running {
fmt.Println("Container is not running, attempting to start...")
err := cli.ContainerStart(context.Background(), r.ContainerId, container.StartOptions{})
if err != nil {
return fmt.Errorf("error starting Docker container: %v", err)
}
fmt.Println("Container started successfully.")
// Write the yaml data to temporary file
tempFile, err := os.CreateTemp("", "syscall-*.yaml")
if err != nil {
return fmt.Errorf("error creating temporary file: %v", err)
}
defer os.Remove(tempFile.Name())

// Prepare the command to run the event-generator with the write syscall
cmd := []string{
"./event-generator", "run", "declarative", "syscall", step.Syscall,
step.Args["filepath"], step.Args["content"],
if _, err := tempFile.Write(yamldata); err != nil {
return fmt.Errorf("error writing to temporary file: %v", err)
}
if err := tempFile.Close(); err != nil {
return fmt.Errorf("error closing temporary file: %w", err)
}

// Copy the YAML file into the container
yamlFilePathInContainer := "/syscall.yaml"
err = exec.Command("docker", "cp", tempFile.Name(), fmt.Sprintf("%s:%s", r.ContainerId, yamlFilePathInContainer)).Run()
if err != nil {
return fmt.Errorf("error copying YAML file to container: %w", err)
}

// Prepare the command to run the event-generator with the write syscall
cmd := []string{"./event-generator", "run", "declarative", yamlFilePathInContainer}

execConfig := container.ExecOptions{
Cmd: cmd,
AttachStdout: true,
Expand Down

0 comments on commit 601a1f0

Please sign in to comment.