From 49a0b6f16771d5ddfd7c35ea99056c203279624b Mon Sep 17 00:00:00 2001 From: GitCaddy Date: Sun, 11 Jan 2026 17:25:45 +0000 Subject: [PATCH] feat(capabilities): Add Linux distro detection and suggested labels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add DistroInfo struct to detect Linux distribution from /etc/os-release - Add detectLinuxDistro() function to parse distro ID, version, pretty name - Add generateSuggestedLabels() to create industry-standard labels - Suggested labels include: linux/windows/macos, distro name, with -latest suffix 🤖 Generated with Claude Code --- internal/pkg/envcheck/capabilities.go | 83 +++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/internal/pkg/envcheck/capabilities.go b/internal/pkg/envcheck/capabilities.go index 014ebdf..d5b7da7 100644 --- a/internal/pkg/envcheck/capabilities.go +++ b/internal/pkg/envcheck/capabilities.go @@ -4,8 +4,10 @@ package envcheck import ( + "bufio" "context" "encoding/json" + "os" "os/exec" "runtime" "strings" @@ -23,10 +25,18 @@ type DiskInfo struct { UsedPercent float64 `json:"used_percent"` } +// DistroInfo holds Linux distribution information +type DistroInfo struct { + ID string `json:"id,omitempty"` // e.g., "ubuntu", "debian", "fedora" + VersionID string `json:"version_id,omitempty"` // e.g., "24.04", "12" + PrettyName string `json:"pretty_name,omitempty"` // e.g., "Ubuntu 24.04 LTS" +} + // RunnerCapabilities represents the capabilities of a runner for AI consumption type RunnerCapabilities struct { OS string `json:"os"` Arch string `json:"arch"` + Distro *DistroInfo `json:"distro,omitempty"` Docker bool `json:"docker"` DockerCompose bool `json:"docker_compose"` ContainerRuntime string `json:"container_runtime,omitempty"` @@ -36,6 +46,7 @@ type RunnerCapabilities struct { Limitations []string `json:"limitations,omitempty"` Disk *DiskInfo `json:"disk,omitempty"` Bandwidth *BandwidthInfo `json:"bandwidth,omitempty"` + SuggestedLabels []string `json:"suggested_labels,omitempty"` } // CapabilityFeatures represents feature support flags @@ -65,6 +76,11 @@ func DetectCapabilities(ctx context.Context, dockerHost string) *RunnerCapabilit }, } + // Detect Linux distribution + if runtime.GOOS == "linux" { + cap.Distro = detectLinuxDistro() + } + // Detect Docker cap.Docker, cap.ContainerRuntime = detectDocker(ctx, dockerHost) if cap.Docker { @@ -78,9 +94,76 @@ func DetectCapabilities(ctx context.Context, dockerHost string) *RunnerCapabilit // Detect disk space cap.Disk = detectDiskSpace() + // Generate suggested labels based on detected capabilities + cap.SuggestedLabels = generateSuggestedLabels(cap) + return cap } +// detectLinuxDistro reads /etc/os-release to get distribution info +func detectLinuxDistro() *DistroInfo { + file, err := os.Open("/etc/os-release") + if err != nil { + return nil + } + defer file.Close() + + distro := &DistroInfo{} + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "ID=") { + distro.ID = strings.Trim(strings.TrimPrefix(line, "ID="), "\"") + } else if strings.HasPrefix(line, "VERSION_ID=") { + distro.VersionID = strings.Trim(strings.TrimPrefix(line, "VERSION_ID="), "\"") + } else if strings.HasPrefix(line, "PRETTY_NAME=") { + distro.PrettyName = strings.Trim(strings.TrimPrefix(line, "PRETTY_NAME="), "\"") + } + } + + if distro.ID == "" { + return nil + } + + return distro +} + +// generateSuggestedLabels creates industry-standard labels based on capabilities +func generateSuggestedLabels(cap *RunnerCapabilities) []string { + labels := []string{} + seen := make(map[string]bool) + + addLabel := func(label string) { + if label != "" && !seen[label] { + seen[label] = true + labels = append(labels, label) + } + } + + // OS labels + switch cap.OS { + case "linux": + addLabel("linux") + addLabel("linux-latest") + case "windows": + addLabel("windows") + addLabel("windows-latest") + case "darwin": + addLabel("macos") + addLabel("macos-latest") + } + + // Distro labels (Linux only) + if cap.Distro != nil && cap.Distro.ID != "" { + distro := strings.ToLower(cap.Distro.ID) + addLabel(distro) + addLabel(distro + "-latest") + } + + return labels +} + // detectDiskSpace detects disk space on the root filesystem func detectDiskSpace() *DiskInfo { var stat unix.Statfs_t