2024-06-02 06:03:47 +00:00
|
|
|
package podman
|
2024-06-02 05:11:56 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"log"
|
|
|
|
"os/exec"
|
2024-06-02 06:03:47 +00:00
|
|
|
|
2024-06-03 03:49:37 +00:00
|
|
|
service_definition "spud/service_definition"
|
2024-06-02 05:11:56 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Creates a Podman volume of name `name` if it does not exist.
|
|
|
|
*
|
|
|
|
* If the volume exists, then behaviour depends on `existsOk`:
|
|
|
|
* - If `existsOk` is truthy, then the already-exists error is ignored and
|
|
|
|
* nothing is done;
|
|
|
|
* - Else, an error is returned.
|
|
|
|
*/
|
|
|
|
func CreateVolume(name string, existsOk bool) error {
|
|
|
|
args := []string{"volume", "create", name}
|
|
|
|
|
|
|
|
if existsOk {
|
|
|
|
args = append(args, "--ignore")
|
|
|
|
}
|
|
|
|
|
|
|
|
command := exec.Command("podman", args...)
|
|
|
|
|
|
|
|
if err := command.Run(); err != nil {
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("✅ Created volume \"%s\".", name)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Creates a Podman pod to keep related containers together.
|
|
|
|
*
|
|
|
|
*/
|
2024-06-03 03:49:37 +00:00
|
|
|
func CreatePod(name string, ports []service_definition.PortMapping) error {
|
|
|
|
args := []string{"pod", "create", "--replace"}
|
|
|
|
|
|
|
|
for _, portMapping := range ports {
|
|
|
|
portArgs := []string{"-p", portMapping.Host + ":" + portMapping.Container}
|
|
|
|
args = append(args, portArgs...)
|
|
|
|
}
|
|
|
|
|
|
|
|
args = append(args, name)
|
2024-06-02 05:11:56 +00:00
|
|
|
|
|
|
|
command := exec.Command("podman", args...)
|
|
|
|
|
|
|
|
if err := command.Run(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("✅ Created pod \"%s\".", name)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-06-03 03:57:55 +00:00
|
|
|
/*
|
|
|
|
* Stops a running pod.
|
|
|
|
*/
|
|
|
|
func StopPod(name string) error {
|
|
|
|
args := []string{"pod", "stop", name}
|
|
|
|
|
|
|
|
command := exec.Command("podman", args...)
|
|
|
|
|
|
|
|
if err := command.Run(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("✅ Stopped pod \"%s\" and child containers.", name)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-06-02 05:11:56 +00:00
|
|
|
/*
|
|
|
|
* Creates individual containers.
|
|
|
|
*/
|
2024-06-02 06:03:47 +00:00
|
|
|
func CreateContainer(definition service_definition.ContainerDefinition, knownVolumes map[string]string, service string) error {
|
2024-06-02 05:11:56 +00:00
|
|
|
namespacedContainerName := service + "_" + definition.Name
|
|
|
|
|
|
|
|
args := []string{
|
|
|
|
"run",
|
|
|
|
"-d",
|
|
|
|
"--name",
|
|
|
|
namespacedContainerName,
|
|
|
|
"--pod",
|
|
|
|
service,
|
|
|
|
"--replace",
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, volume := range definition.Volumes {
|
|
|
|
var host string
|
|
|
|
container := volume.Container
|
|
|
|
|
|
|
|
if volume.Name != "" {
|
|
|
|
namespacedName := service + "_" + volume.Name
|
|
|
|
host = namespacedName
|
|
|
|
} else if volume.Host != "" {
|
|
|
|
host = volume.Host
|
|
|
|
} else {
|
|
|
|
log.Fatal("Invalid volume source configuration")
|
|
|
|
}
|
|
|
|
|
|
|
|
arg := []string{"-v", host + ":" + container}
|
|
|
|
|
|
|
|
args = append(args, arg...)
|
|
|
|
}
|
|
|
|
|
|
|
|
args = append(args, definition.Image)
|
|
|
|
|
|
|
|
for _, extra := range definition.ExtraArgs {
|
|
|
|
args = append(args, extra)
|
|
|
|
}
|
|
|
|
|
|
|
|
command := exec.Command("podman", args...)
|
|
|
|
|
|
|
|
if err := command.Start(); err != nil {
|
|
|
|
log.Fatal("Failed to start")
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := command.Wait(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("✅ Started container \"%s\".", namespacedContainerName)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|