Files
gitea-dynamic-runner/internal/taskassignment/placement.go
T
panxiao81 897d327a26
test / shell (pull_request) Successful in 28s
test / python (pull_request) Successful in 59s
test / go (pull_request) Successful in 3m35s
refactor: separate workload class from placement driver
2026-09-25 16:48:32 +00:00

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
}