Files
unitdore/runtime/docker.go
sgcommand a8c12c8c21 Add prefix/suffix support, short ID fallback, unit docs
- 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/
2026-04-03 15:47:56 +02:00

83 lines
1.8 KiB
Go

package runtime
import (
"encoding/json"
"fmt"
"os/exec"
"strings"
)
type Docker struct{}
func (d *Docker) Name() string { return "docker" }
type dockerContainer struct {
ID string `json:"ID"`
Names string `json:"Names"`
Image string `json:"Image"`
Command string `json:"Command"`
State string `json:"State"`
}
func (d *Docker) ListRunning() ([]Container, error) {
bin, err := exec.LookPath("docker")
if err != nil {
return nil, nil // docker not installed — not an error
}
out, err := exec.Command(bin, "ps", "--format", "json").Output()
if err != nil {
// Docker installed but daemon not running — treat as no containers
return nil, nil
}
// Docker outputs one JSON object per line (not a JSON array)
var containers []Container
for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
if line == "" {
continue
}
var c dockerContainer
if err := json.Unmarshal([]byte(line), &c); err != nil {
continue
}
name := strings.TrimPrefix(c.Names, "/")
// 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: "docker",
})
}
return containers, nil
}
func (d *Docker) Exists(name string) (bool, error) {
bin, err := exec.LookPath("docker")
if err != nil {
return false, nil
}
out, err := exec.Command(bin, "ps", "-a", "--format", "{{.Names}}").Output()
if err != nil {
return false, fmt.Errorf("docker ps -a: %w", err)
}
for _, line := range strings.Split(string(out), "\n") {
if strings.TrimSpace(line) == name {
return true, nil
}
}
return false, nil
}