// 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=` 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, options.Shell, "-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(), } }