courgette/internal/driver/podman_driver.go

113 lines
2.5 KiB
Go
Raw Normal View History

// Podman driver
//
// Abstracts interactions with Podman commands via the ContainerDriver interface.
package driver
import (
logger "courgette/internal/logging"
"fmt"
"os"
"os/exec"
)
type PodmanDriver struct{}
func (d PodmanDriver) Pull(uri string) error {
cmd := exec.Command("podman", "pull", uri)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
return nil
}
// Sets up a new container with an attached workspace volume.
//
// The volume created is labeled with `owner=<containerName>` so it
// can be easily collected and cleaned up on stop.
func (d PodmanDriver) Start(uri string, containerName string) error {
volumeName := fmt.Sprintf("%s-workspace", containerName)
cmd := exec.Command("podman", "volume", "create", volumeName, "--label", fmt.Sprintf("owner=%s", containerName))
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
cmd = exec.Command("podman", "run", "-td", "--name", containerName, "-v", fmt.Sprintf("%s:/workspace", volumeName), uri)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
return nil
}
// Stops a container and removes any volumes labelled with its name
// as owner.
func (d PodmanDriver) Stop(containerName string) error {
cmd := exec.Command("podman", "rm", "-f", "-t", "2", containerName)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
cmd = exec.Command("podman", "wait", containerName, "--ignore")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
logger.Error("%+v", err)
}
cmd = exec.Command("podman", "volume", "prune", "--filter", fmt.Sprintf("label=owner=%s", containerName), "-f")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
return nil
}
func (d PodmanDriver) Exec(containerId string, command string, options CommandOptions) CommandResult {
envArgs := []string{}
for key, value := range options.Env {
envArgs = append(envArgs, fmt.Sprintf("-e=%s=%s", key, value))
}
commandArgs := []string{
"exec",
"--workdir",
options.Cwd,
}
commandArgs = append(commandArgs, envArgs...)
commandArgs = append(commandArgs, containerId,
"bash",
"-c",
command,
)
cmd := exec.Command("podman", commandArgs...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
return CommandResult{
Error: err,
ExitCode: cmd.ProcessState.ExitCode(),
}
}