package podman import ( "log" "os/exec" service_definition "spud/service_definition" ) /* * 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. * */ 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) command := exec.Command("podman", args...) if err := command.Run(); err != nil { return err } log.Printf("✅ Created pod \"%s\".", name) return nil } /* * 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 } /* * Creates individual containers. */ func CreateContainer(definition service_definition.ContainerDefinition, knownVolumes map[string]string, service string) error { 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 }