feat(capabilities): Add Linux distro detection and suggested labels
All checks were successful
CI / build-and-test (push) Successful in 14s
All checks were successful
CI / build-and-test (push) Successful in 14s
- 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
This commit is contained in:
@@ -4,8 +4,10 @@
|
|||||||
package envcheck
|
package envcheck
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -23,10 +25,18 @@ type DiskInfo struct {
|
|||||||
UsedPercent float64 `json:"used_percent"`
|
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
|
// RunnerCapabilities represents the capabilities of a runner for AI consumption
|
||||||
type RunnerCapabilities struct {
|
type RunnerCapabilities struct {
|
||||||
OS string `json:"os"`
|
OS string `json:"os"`
|
||||||
Arch string `json:"arch"`
|
Arch string `json:"arch"`
|
||||||
|
Distro *DistroInfo `json:"distro,omitempty"`
|
||||||
Docker bool `json:"docker"`
|
Docker bool `json:"docker"`
|
||||||
DockerCompose bool `json:"docker_compose"`
|
DockerCompose bool `json:"docker_compose"`
|
||||||
ContainerRuntime string `json:"container_runtime,omitempty"`
|
ContainerRuntime string `json:"container_runtime,omitempty"`
|
||||||
@@ -36,6 +46,7 @@ type RunnerCapabilities struct {
|
|||||||
Limitations []string `json:"limitations,omitempty"`
|
Limitations []string `json:"limitations,omitempty"`
|
||||||
Disk *DiskInfo `json:"disk,omitempty"`
|
Disk *DiskInfo `json:"disk,omitempty"`
|
||||||
Bandwidth *BandwidthInfo `json:"bandwidth,omitempty"`
|
Bandwidth *BandwidthInfo `json:"bandwidth,omitempty"`
|
||||||
|
SuggestedLabels []string `json:"suggested_labels,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CapabilityFeatures represents feature support flags
|
// 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
|
// Detect Docker
|
||||||
cap.Docker, cap.ContainerRuntime = detectDocker(ctx, dockerHost)
|
cap.Docker, cap.ContainerRuntime = detectDocker(ctx, dockerHost)
|
||||||
if cap.Docker {
|
if cap.Docker {
|
||||||
@@ -78,9 +94,76 @@ func DetectCapabilities(ctx context.Context, dockerHost string) *RunnerCapabilit
|
|||||||
// Detect disk space
|
// Detect disk space
|
||||||
cap.Disk = detectDiskSpace()
|
cap.Disk = detectDiskSpace()
|
||||||
|
|
||||||
|
// Generate suggested labels based on detected capabilities
|
||||||
|
cap.SuggestedLabels = generateSuggestedLabels(cap)
|
||||||
|
|
||||||
return 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
|
// detectDiskSpace detects disk space on the root filesystem
|
||||||
func detectDiskSpace() *DiskInfo {
|
func detectDiskSpace() *DiskInfo {
|
||||||
var stat unix.Statfs_t
|
var stat unix.Statfs_t
|
||||||
|
|||||||
Reference in New Issue
Block a user