增加隔离的 vm-dev 集成测试标签 #36
@@ -5,7 +5,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
kind:
|
kind:
|
||||||
runs-on: [self-hosted, vm]
|
runs-on: [self-hosted, vm-dev]
|
||||||
steps:
|
steps:
|
||||||
- name: Verify Docker
|
- name: Verify Docker
|
||||||
run: docker info
|
run: docker info
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ runs-on: [self-hosted, vm]
|
|||||||
只执行一个 job,并在 job 结束后连同本地状态一起销毁。完整的设计约束见
|
只执行一个 job,并在 job 结束后连同本地状态一起销毁。完整的设计约束见
|
||||||
[`docs/design-principles.md`](docs/design-principles.md)。
|
[`docs/design-principles.md`](docs/design-principles.md)。
|
||||||
|
|
||||||
|
集成期间可将 `VM_RUNNER_LABEL=vm-dev`,只接取显式使用
|
||||||
|
`runs-on: [self-hosted, vm-dev]` 的测试任务;生产 `vm` job 将保持在 Gitea pending,
|
||||||
|
不会在 backend 修复过程中继续涌入。
|
||||||
|
|
||||||
目标 Go controller 组件:
|
目标 Go controller 组件:
|
||||||
|
|
||||||
- `scheduler`:以常驻 Gitea RunnerService 身份直接领取 task,并把完整 assignment
|
- `scheduler`:以常驻 Gitea RunnerService 身份直接领取 task,并把完整 assignment
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ type controllerConfig struct {
|
|||||||
PodNamespace, PodImage, PodServiceAccount, SPIRECluster, SPIREClass string
|
PodNamespace, PodImage, PodServiceAccount, SPIRECluster, SPIREClass string
|
||||||
SPIREAgentID string
|
SPIREAgentID string
|
||||||
PodExecutorUID, PodCapacity int
|
PodExecutorUID, PodCapacity int
|
||||||
OpenSandboxURL, OpenSandboxAPIKey, OpenSandboxPool string
|
OpenSandboxURL, OpenSandboxAPIKey, OpenSandboxPool, VMRunnerLabel string
|
||||||
VMTimeout, VMCapacity int
|
VMTimeout, VMCapacity int
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ func runController(ctx context.Context) error {
|
|||||||
labels = append(labels, string(taskassignment.BackendPod))
|
labels = append(labels, string(taskassignment.BackendPod))
|
||||||
}
|
}
|
||||||
if slices.Contains(config.Components, controller.VMWorker) {
|
if slices.Contains(config.Components, controller.VMWorker) {
|
||||||
labels = append(labels, string(taskassignment.BackendVM))
|
labels = append(labels, config.VMRunnerLabel)
|
||||||
}
|
}
|
||||||
poller := taskscheduler.Poller{
|
poller := taskscheduler.Poller{
|
||||||
Client: giteaClient,
|
Client: giteaClient,
|
||||||
@@ -345,7 +345,7 @@ func loadControllerConfig() (controllerConfig, error) {
|
|||||||
FacadeListen: env("RUNNER_FACADE_LISTEN", ":8443"), FacadeURL: os.Getenv("RUNNER_FACADE_URL"), FacadeSPIFFEID: os.Getenv("RUNNER_FACADE_SPIFFE_ID"), CapabilityKey: []byte(capabilityKey),
|
FacadeListen: env("RUNNER_FACADE_LISTEN", ":8443"), FacadeURL: os.Getenv("RUNNER_FACADE_URL"), FacadeSPIFFEID: os.Getenv("RUNNER_FACADE_SPIFFE_ID"), CapabilityKey: []byte(capabilityKey),
|
||||||
PodNamespace: env("POD_NAMESPACE", "gitea-actions"), PodImage: os.Getenv("POD_EXECUTOR_IMAGE"), PodServiceAccount: env("POD_SERVICE_ACCOUNT", "gitea-task-executor"),
|
PodNamespace: env("POD_NAMESPACE", "gitea-actions"), PodImage: os.Getenv("POD_EXECUTOR_IMAGE"), PodServiceAccount: env("POD_SERVICE_ACCOUNT", "gitea-task-executor"),
|
||||||
SPIRECluster: env("SPIRE_CLUSTER", "homelab"), SPIREClass: env("SPIRE_CLASS", "spire-mgmt-spire"), SPIREAgentID: os.Getenv("SPIRE_AGENT_ID"), PodExecutorUID: envInt("POD_EXECUTOR_UID", 2000), PodCapacity: envInt("POD_CAPACITY", 4),
|
SPIRECluster: env("SPIRE_CLUSTER", "homelab"), SPIREClass: env("SPIRE_CLASS", "spire-mgmt-spire"), SPIREAgentID: os.Getenv("SPIRE_AGENT_ID"), PodExecutorUID: envInt("POD_EXECUTOR_UID", 2000), PodCapacity: envInt("POD_CAPACITY", 4),
|
||||||
OpenSandboxURL: os.Getenv("OPENSANDBOX_API"), OpenSandboxPool: env("OPENSANDBOX_POOL", "ci-vm"), VMTimeout: envInt("VM_TIMEOUT_SECONDS", 14400), VMCapacity: envInt("VM_CAPACITY", 1),
|
OpenSandboxURL: os.Getenv("OPENSANDBOX_API"), OpenSandboxPool: env("OPENSANDBOX_POOL", "ci-vm"), VMRunnerLabel: env("VM_RUNNER_LABEL", "vm"), VMTimeout: envInt("VM_TIMEOUT_SECONDS", 14400), VMCapacity: envInt("VM_CAPACITY", 1),
|
||||||
}
|
}
|
||||||
if config.WorkloadAPIAddr == "" || config.FacadeURL == "" || config.FacadeSPIFFEID == "" {
|
if config.WorkloadAPIAddr == "" || config.FacadeURL == "" || config.FacadeSPIFFEID == "" {
|
||||||
return controllerConfig{}, errors.New("SPIFFE_ENDPOINT_SOCKET, RUNNER_FACADE_URL, and RUNNER_FACADE_SPIFFE_ID are required")
|
return controllerConfig{}, errors.New("SPIFFE_ENDPOINT_SOCKET, RUNNER_FACADE_URL, and RUNNER_FACADE_SPIFFE_ID are required")
|
||||||
@@ -357,6 +357,9 @@ func loadControllerConfig() (controllerConfig, error) {
|
|||||||
return controllerConfig{}, errors.New("SPIRE_AGENT_ID is required for pod-worker")
|
return controllerConfig{}, errors.New("SPIRE_AGENT_ID is required for pod-worker")
|
||||||
}
|
}
|
||||||
if slices.Contains(selection, controller.VMWorker) {
|
if slices.Contains(selection, controller.VMWorker) {
|
||||||
|
if config.VMRunnerLabel != "vm" && config.VMRunnerLabel != "vm-dev" {
|
||||||
|
return controllerConfig{}, errors.New("VM_RUNNER_LABEL must be vm or vm-dev")
|
||||||
|
}
|
||||||
if config.OpenSandboxURL == "" {
|
if config.OpenSandboxURL == "" {
|
||||||
return controllerConfig{}, errors.New("OPENSANDBOX_API is required for vm-worker")
|
return controllerConfig{}, errors.New("OPENSANDBOX_API is required for vm-worker")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ func TestLoadControllerConfigRequiresOpenSandboxSecretOnlyForVM(t *testing.T) {
|
|||||||
t.Setenv("RUNNER_FACADE_URL", "https://facade:8443")
|
t.Setenv("RUNNER_FACADE_URL", "https://facade:8443")
|
||||||
t.Setenv("RUNNER_FACADE_SPIFFE_ID", "spiffe://ddupan.top/controller")
|
t.Setenv("RUNNER_FACADE_SPIFFE_ID", "spiffe://ddupan.top/controller")
|
||||||
t.Setenv("OPENSANDBOX_API", "http://opensandbox.internal")
|
t.Setenv("OPENSANDBOX_API", "http://opensandbox.internal")
|
||||||
|
t.Setenv("VM_RUNNER_LABEL", "vm-dev")
|
||||||
if _, err := loadControllerConfig(); err == nil {
|
if _, err := loadControllerConfig(); err == nil {
|
||||||
t.Fatal("expected missing OpenSandbox API key file error")
|
t.Fatal("expected missing OpenSandbox API key file error")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ func backendFromTask(task *runnerv1.Task) (Backend, error) {
|
|||||||
return "", fmt.Errorf("task runs-on labels must include self-hosted: %v", labels)
|
return "", fmt.Errorf("task runs-on labels must include self-hosted: %v", labels)
|
||||||
}
|
}
|
||||||
hasPod := slices.Contains(labels, string(BackendPod))
|
hasPod := slices.Contains(labels, string(BackendPod))
|
||||||
hasVM := slices.Contains(labels, string(BackendVM))
|
hasVM := slices.Contains(labels, string(BackendVM)) || slices.Contains(labels, "vm-dev")
|
||||||
if hasPod == hasVM {
|
if hasPod == hasVM {
|
||||||
return "", fmt.Errorf("task runs-on labels must select exactly one of pod or vm: %v", labels)
|
return "", fmt.Errorf("task runs-on labels must select exactly one of pod or vm: %v", labels)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ func TestNewSelectsBackendFromRunsOn(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{"[self-hosted, pod]", BackendPod},
|
{"[self-hosted, pod]", BackendPod},
|
||||||
{"[self-hosted, vm]", BackendVM},
|
{"[self-hosted, vm]", BackendVM},
|
||||||
|
{"[self-hosted, vm-dev]", BackendVM},
|
||||||
} {
|
} {
|
||||||
assignment, err := New(task(t, test.labels), "ddupan.top")
|
assignment, err := New(task(t, test.labels), "ddupan.top")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user