- config: add Prefix/Suffix fields to Config struct - systemd: ServiceName/Generate/UnitPath/Install/Uninstall/Enable/Disable/Status all accept prefix+suffix - runtime: fall back to short container ID (12 chars) when container has no name - cmd: active, status, install all thread prefix/suffix from config - systemd/generator_test.go: updated all calls + added TestGenerate_WithPrefixSuffix - docs/generated-units.md: full examples of every unit type + ordering + naming - README: updated config docs, prefix/suffix section, link to docs/
83 lines
1.7 KiB
Go
83 lines
1.7 KiB
Go
package runtime
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
type Podman struct{}
|
|
|
|
func (p *Podman) Name() string { return "podman" }
|
|
|
|
type podmanContainer struct {
|
|
ID string `json:"Id"`
|
|
Names []string `json:"Names"`
|
|
Image string `json:"Image"`
|
|
Command string `json:"Command"`
|
|
State string `json:"State"`
|
|
}
|
|
|
|
func (p *Podman) ListRunning() ([]Container, error) {
|
|
bin, err := exec.LookPath("podman")
|
|
if err != nil {
|
|
return nil, nil // podman not installed — not an error
|
|
}
|
|
|
|
out, err := exec.Command(bin, "ps", "--format", "json").Output()
|
|
if err != nil {
|
|
// Podman installed but not usable — treat as no containers
|
|
return nil, nil
|
|
}
|
|
|
|
var raw []podmanContainer
|
|
if err := json.Unmarshal(out, &raw); err != nil {
|
|
return nil, fmt.Errorf("parsing podman output: %w", err)
|
|
}
|
|
|
|
var containers []Container
|
|
for _, c := range raw {
|
|
name := ""
|
|
if len(c.Names) > 0 {
|
|
name = c.Names[0]
|
|
}
|
|
// Fall back to short container ID if no name assigned
|
|
if name == "" {
|
|
if len(c.ID) >= 12 {
|
|
name = c.ID[:12]
|
|
} else if c.ID != "" {
|
|
name = c.ID
|
|
} else {
|
|
continue
|
|
}
|
|
}
|
|
containers = append(containers, Container{
|
|
Name: name,
|
|
Image: c.Image,
|
|
Command: c.Command,
|
|
Runtime: "podman",
|
|
})
|
|
}
|
|
return containers, nil
|
|
}
|
|
|
|
func (p *Podman) Exists(name string) (bool, error) {
|
|
bin, err := exec.LookPath("podman")
|
|
if err != nil {
|
|
return false, nil
|
|
}
|
|
|
|
out, err := exec.Command(bin, "ps", "-a", "--format", "{{.Names}}").Output()
|
|
if err != nil {
|
|
return false, fmt.Errorf("podman ps -a: %w", err)
|
|
}
|
|
|
|
for _, line := range strings.Split(string(out), "\n") {
|
|
if strings.TrimSpace(line) == name {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|