diff --git a/pkg/projectconfig/config.go b/pkg/projectconfig/config.go index bd51d5d..33ec170 100644 --- a/pkg/projectconfig/config.go +++ b/pkg/projectconfig/config.go @@ -28,7 +28,9 @@ type DeploymentConfig struct { type HardwareConfig struct { CPU *float64 `mapstructure:"cpu" toml:"cpu,omitempty"` Memory *float64 `mapstructure:"memory" toml:"memory,omitempty"` - Compute *string `mapstructure:"compute" toml:"compute,omitempty"` + ComputeRaw interface{} `mapstructure:"compute" toml:"compute,omitempty"` + Compute *string `mapstructure:"-" toml:"-"` + ComputeFallbacks []string `mapstructure:"-" toml:"-"` GPUCount *int `mapstructure:"gpu_count" toml:"gpu_count,omitempty"` Provider *string `mapstructure:"provider" toml:"provider,omitempty"` Region *string `mapstructure:"region" toml:"region,omitempty"` @@ -114,7 +116,12 @@ func (pc *ProjectConfig) ToPayload() map[string]any { payload["memory"] = *pc.Hardware.Memory } if pc.Hardware.Compute != nil { - payload["compute"] = *pc.Hardware.Compute + if len(pc.Hardware.ComputeFallbacks) > 0 { + all := append([]string{*pc.Hardware.Compute}, pc.Hardware.ComputeFallbacks...) + payload["compute"] = all + } else { + payload["compute"] = *pc.Hardware.Compute + } } if pc.Hardware.GPUCount != nil && pc.Hardware.Compute != nil && *pc.Hardware.Compute != "CPU" { payload["gpuCount"] = *pc.Hardware.GPUCount @@ -160,6 +167,9 @@ func (pc *ProjectConfig) ToPayload() map[string]any { if pc.Scaling.LoadBalancingAlgorithm != nil { payload["loadBalancingAlgorithm"] = *pc.Scaling.LoadBalancingAlgorithm } + if pc.Scaling.ComputeTier != nil { + payload["computeTier"] = *pc.Scaling.ComputeTier + } // Runtime configuration if pc.CustomRuntime != nil && pc.PartnerService != nil { diff --git a/pkg/projectconfig/loader.go b/pkg/projectconfig/loader.go index 4c18a21..31c915e 100644 --- a/pkg/projectconfig/loader.go +++ b/pkg/projectconfig/loader.go @@ -113,6 +113,11 @@ func Load(configPath string) (*ProjectConfig, error) { } } + // Normalize compute: accepts string or array + if err := normalizeCompute(&config.Hardware); err != nil { + return nil, err + } + // Validate compute_tier before applying defaults if config.Scaling.ComputeTier != nil { tier := *config.Scaling.ComputeTier @@ -127,6 +132,35 @@ func Load(configPath string) (*ProjectConfig, error) { return &config, nil } +func normalizeCompute(hw *HardwareConfig) error { + if hw.ComputeRaw == nil { + return nil + } + switch v := hw.ComputeRaw.(type) { + case string: + hw.Compute = &v + case []interface{}: + if len(v) == 0 { + return fmt.Errorf("compute array must not be empty") + } + first, ok := v[0].(string) + if !ok { + return fmt.Errorf("compute values must be strings") + } + hw.Compute = &first + for _, item := range v[1:] { + s, ok := item.(string) + if !ok { + return fmt.Errorf("compute values must be strings") + } + hw.ComputeFallbacks = append(hw.ComputeFallbacks, s) + } + default: + return fmt.Errorf("compute must be a string or array of strings") + } + return nil +} + // applyDefaults sets default values for fields that weren't specified in the config func applyDefaults(config *ProjectConfig) { // Apply deployment defaults