Files
spinifex/cmd/ecs-agent/gpu_discovery.go
T
Josh Siviour 98fc01764b feat(ecs): GPU passthrough to task containers (Epic C) (#512)
* feat(ecs): thread resourceRequirements GPU count through conv, ContainerDef, AssignContainer and RunSpec

* feat(ecs): add GPU placement dimension — InstanceRecord capacity, fits/reserve/release, STRINGSET resource reporting

* feat(ecs): agent GPU discovery via nvidia-smi, pinning ledger, device-UUID report-back and DescribeTasks gpuIds

* feat(ecs): inject assigned GPU devices into containerd OCI spec via CDI (oci.WithCDIDevices)

* test(ecs): add GPU task e2e (nvidia-smi container, gpuIds assertion) to gpu e2e suite

* test(gpu): decouple base-AMI requirement from GPU fixture so ECS e2e runs without the ubuntu EC2 image

* test(gpu): pick smallest advertised GPU instance type to fit a single host

* fix(ecs): preserve pinned GPU UUIDs across STOPPED state change so DescribeTasks reports gpuIds for one-shot tasks
2026-07-13 10:54:55 +10:00

43 lines
1.3 KiB
Go

package main
import (
"os/exec"
"strings"
)
// commandRunner abstracts exec.Command so discovery is unit-testable without
// shelling out. Production uses execCommandRunner; tests inject a fake.
type commandRunner func(name string, args ...string) ([]byte, error)
// execCommandRunner runs a real host command and returns its stdout.
func execCommandRunner(name string, args ...string) ([]byte, error) {
return exec.Command(name, args...).Output()
}
// discoverNvidiaGPUs enumerates local NVIDIA GPU device UUIDs via nvidia-smi.
// A missing binary or any run failure (no GPU host) yields an empty list, not
// an error — the agent still registers with zero GPU capacity.
func discoverNvidiaGPUs(run commandRunner) []string {
out, err := run("nvidia-smi", "--query-gpu=uuid", "--format=csv,noheader")
if err != nil {
return nil
}
return parseNvidiaSMIUUIDs(string(out))
}
// parseNvidiaSMIUUIDs splits nvidia-smi's newline-delimited UUID output,
// dropping blank lines. Exported as a pure function so fixture strings can be
// tested without exec.
func parseNvidiaSMIUUIDs(out string) []string {
lines := strings.Split(strings.TrimSpace(out), "\n")
uuids := make([]string, 0, len(lines))
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
continue
}
uuids = append(uuids, line)
}
return uuids
}