// ABOUTME: Parses Kubernetes-style resource notation for CPU and memory. // ABOUTME: CPU: "500m" = 0.5 cores, "2" = 2 cores. // ABOUTME: Memory: "1Gi" = 1 GiB, "512Mi" = 512 MiB, "1G" = 1 GB. package cgroup import ( "fmt" "strconv" "strings" ) // ParseCPU parses Kubernetes CPU notation to cores. // Examples: "500m" => 0.5, "2" => 2.0, "100m" => 0.1, "2000m" => 2.0 func ParseCPU(value string) (float64, error) { value = strings.TrimSpace(value) if value == "" { return 0, fmt.Errorf("empty CPU value") } // Handle millicores suffix if strings.HasSuffix(value, "m") { millis, err := strconv.ParseFloat(strings.TrimSuffix(value, "m"), 64) if err != nil { return 0, fmt.Errorf("parsing millicores: %w", err) } return millis / 1000.0, nil } // Plain number means cores cores, err := strconv.ParseFloat(value, 64) if err != nil { return 0, fmt.Errorf("parsing cores: %w", err) } return cores, nil } // ParseMemory parses Kubernetes memory notation to bytes. // Supports: // - Binary suffixes: Ki, Mi, Gi, Ti (powers of 1024) // - Decimal suffixes: K, M, G, T (powers of 1000) // - Plain numbers: bytes func ParseMemory(value string) (uint64, error) { value = strings.TrimSpace(value) if value == "" { return 0, fmt.Errorf("empty memory value") } // Binary suffixes (powers of 1024) binarySuffixes := map[string]uint64{ "Ki": 1024, "Mi": 1024 * 1024, "Gi": 1024 * 1024 * 1024, "Ti": 1024 * 1024 * 1024 * 1024, } // Decimal suffixes (powers of 1000) decimalSuffixes := map[string]uint64{ "K": 1000, "M": 1000 * 1000, "G": 1000 * 1000 * 1000, "T": 1000 * 1000 * 1000 * 1000, } // Try binary suffixes first (2-char) for suffix, multiplier := range binarySuffixes { if strings.HasSuffix(value, suffix) { numStr := strings.TrimSuffix(value, suffix) num, err := strconv.ParseFloat(numStr, 64) if err != nil { return 0, fmt.Errorf("parsing memory value: %w", err) } return uint64(num * float64(multiplier)), nil } } // Try decimal suffixes (1-char) for suffix, multiplier := range decimalSuffixes { if strings.HasSuffix(value, suffix) { numStr := strings.TrimSuffix(value, suffix) num, err := strconv.ParseFloat(numStr, 64) if err != nil { return 0, fmt.Errorf("parsing memory value: %w", err) } return uint64(num * float64(multiplier)), nil } } // Plain number (bytes) bytes, err := strconv.ParseUint(value, 10, 64) if err != nil { return 0, fmt.Errorf("parsing bytes: %w", err) } return bytes, nil }