77 lines
2.1 KiB
Go
77 lines
2.1 KiB
Go
package taskassignment
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"slices"
|
|
)
|
|
|
|
type WorkloadClass string
|
|
|
|
const (
|
|
WorkloadContainer WorkloadClass = "container"
|
|
WorkloadVM WorkloadClass = "vm"
|
|
)
|
|
|
|
type Driver string
|
|
|
|
const (
|
|
DriverKubernetes Driver = "kubernetes"
|
|
DriverOpenSandbox Driver = "opensandbox"
|
|
)
|
|
|
|
type Placement struct {
|
|
Class WorkloadClass `json:"workload_class"`
|
|
Driver Driver `json:"driver"`
|
|
}
|
|
|
|
var (
|
|
KubernetesContainer = Placement{Class: WorkloadContainer, Driver: DriverKubernetes}
|
|
OpenSandboxVM = Placement{Class: WorkloadVM, Driver: DriverOpenSandbox}
|
|
)
|
|
|
|
func (p Placement) Validate() error {
|
|
switch p {
|
|
case KubernetesContainer, OpenSandboxVM:
|
|
return nil
|
|
default:
|
|
return fmt.Errorf("unsupported workload placement %s/%s", p.Class, p.Driver)
|
|
}
|
|
}
|
|
|
|
func (p Placement) Key() string { return string(p.Class) + "." + string(p.Driver) }
|
|
|
|
func PlacementFromLabels(labels []string) (Placement, error) {
|
|
if !slices.Contains(labels, "self-hosted") {
|
|
return Placement{}, fmt.Errorf("task runs-on labels must include self-hosted: %v", labels)
|
|
}
|
|
legacyPod := slices.Contains(labels, "pod")
|
|
container := slices.Contains(labels, string(WorkloadContainer))
|
|
vm := slices.Contains(labels, string(WorkloadVM)) || slices.Contains(labels, "vm-dev")
|
|
kubernetes := slices.Contains(labels, string(DriverKubernetes))
|
|
opensandbox := slices.Contains(labels, string(DriverOpenSandbox))
|
|
|
|
if legacyPod {
|
|
if container || vm || kubernetes || opensandbox {
|
|
return Placement{}, errors.New("legacy pod label cannot be combined with workload or VM driver labels")
|
|
}
|
|
return KubernetesContainer, nil
|
|
}
|
|
if container == vm {
|
|
return Placement{}, fmt.Errorf("task runs-on labels must select exactly one workload class: %v", labels)
|
|
}
|
|
if kubernetes && opensandbox {
|
|
return Placement{}, fmt.Errorf("task runs-on labels select multiple drivers: %v", labels)
|
|
}
|
|
if container {
|
|
if opensandbox {
|
|
return Placement{}, fmt.Errorf("opensandbox does not support container workloads")
|
|
}
|
|
return KubernetesContainer, nil
|
|
}
|
|
if kubernetes {
|
|
return Placement{}, fmt.Errorf("kubernetes does not support VM workloads")
|
|
}
|
|
return OpenSandboxVM, nil
|
|
}
|