From 48b6b8038e21c93465ac4d757f661ac6eda4077c Mon Sep 17 00:00:00 2001 From: panxiao81 Date: Mon, 21 Sep 2026 08:50:18 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=9A=94=E7=A6=BB=20VM=20=E9=9B=86?= =?UTF-8?q?=E6=88=90=E6=B5=8B=E8=AF=95=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/vm-kind-smoke.yml | 2 +- README.md | 4 ++++ cmd/gitea-dynamic-runner/controller.go | 9 ++++++--- cmd/gitea-dynamic-runner/controller_test.go | 1 + internal/taskassignment/assignment.go | 2 +- internal/taskassignment/assignment_test.go | 1 + 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/vm-kind-smoke.yml b/.gitea/workflows/vm-kind-smoke.yml index fdcf7ea..f2a5b20 100644 --- a/.gitea/workflows/vm-kind-smoke.yml +++ b/.gitea/workflows/vm-kind-smoke.yml @@ -5,7 +5,7 @@ on: jobs: kind: - runs-on: [self-hosted, vm] + runs-on: [self-hosted, vm-dev] steps: - name: Verify Docker run: docker info diff --git a/README.md b/README.md index b3e9ea4..2762fc0 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,10 @@ runs-on: [self-hosted, vm] 只执行一个 job,并在 job 结束后连同本地状态一起销毁。完整的设计约束见 [`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 组件: - `scheduler`:以常驻 Gitea RunnerService 身份直接领取 task,并把完整 assignment diff --git a/cmd/gitea-dynamic-runner/controller.go b/cmd/gitea-dynamic-runner/controller.go index f4cca96..c3392d1 100644 --- a/cmd/gitea-dynamic-runner/controller.go +++ b/cmd/gitea-dynamic-runner/controller.go @@ -49,7 +49,7 @@ type controllerConfig struct { PodNamespace, PodImage, PodServiceAccount, SPIRECluster, SPIREClass string SPIREAgentID string PodExecutorUID, PodCapacity int - OpenSandboxURL, OpenSandboxAPIKey, OpenSandboxPool string + OpenSandboxURL, OpenSandboxAPIKey, OpenSandboxPool, VMRunnerLabel string VMTimeout, VMCapacity int } @@ -131,7 +131,7 @@ func runController(ctx context.Context) error { labels = append(labels, string(taskassignment.BackendPod)) } if slices.Contains(config.Components, controller.VMWorker) { - labels = append(labels, string(taskassignment.BackendVM)) + labels = append(labels, config.VMRunnerLabel) } poller := taskscheduler.Poller{ 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), 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), - 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 == "" { 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") } 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 == "" { return controllerConfig{}, errors.New("OPENSANDBOX_API is required for vm-worker") } diff --git a/cmd/gitea-dynamic-runner/controller_test.go b/cmd/gitea-dynamic-runner/controller_test.go index 9c1ebd3..0566001 100644 --- a/cmd/gitea-dynamic-runner/controller_test.go +++ b/cmd/gitea-dynamic-runner/controller_test.go @@ -56,6 +56,7 @@ func TestLoadControllerConfigRequiresOpenSandboxSecretOnlyForVM(t *testing.T) { t.Setenv("RUNNER_FACADE_URL", "https://facade:8443") t.Setenv("RUNNER_FACADE_SPIFFE_ID", "spiffe://ddupan.top/controller") t.Setenv("OPENSANDBOX_API", "http://opensandbox.internal") + t.Setenv("VM_RUNNER_LABEL", "vm-dev") if _, err := loadControllerConfig(); err == nil { t.Fatal("expected missing OpenSandbox API key file error") } diff --git a/internal/taskassignment/assignment.go b/internal/taskassignment/assignment.go index c69cbea..497df49 100644 --- a/internal/taskassignment/assignment.go +++ b/internal/taskassignment/assignment.go @@ -102,7 +102,7 @@ func backendFromTask(task *runnerv1.Task) (Backend, error) { return "", fmt.Errorf("task runs-on labels must include self-hosted: %v", labels) } 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 { return "", fmt.Errorf("task runs-on labels must select exactly one of pod or vm: %v", labels) } diff --git a/internal/taskassignment/assignment_test.go b/internal/taskassignment/assignment_test.go index cce2ba0..d2413db 100644 --- a/internal/taskassignment/assignment_test.go +++ b/internal/taskassignment/assignment_test.go @@ -28,6 +28,7 @@ func TestNewSelectsBackendFromRunsOn(t *testing.T) { }{ {"[self-hosted, pod]", BackendPod}, {"[self-hosted, vm]", BackendVM}, + {"[self-hosted, vm-dev]", BackendVM}, } { assignment, err := New(task(t, test.labels), "ddupan.top") if err != nil { -- 2.54.0