enhance: add macOS VM executor backend

Replace the Tart-based prototype with a runner-oriented macOS VM
executor backed by runner-executor-macos and Apple Virtualization.

Assisted-by: Codet:MODEL_VERSION
This commit is contained in:
Lunny Xiao
2026-09-05 13:20:03 -07:00
parent 1745c7c841
commit 2db24c7401
18 changed files with 1167 additions and 15 deletions
@@ -12,6 +12,7 @@ import (
"time"
"gitea.com/gitea/runner/internal/pkg/config"
"gitea.com/gitea/runner/internal/pkg/labels"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -331,3 +332,37 @@ func TestRunnerOnIdleRemovesOrphanNetworks(t *testing.T) {
hostOnly.OnIdle(context.Background())
assert.Equal(t, []string{"runner-1"}, swept)
}
func TestRunnerOnIdleRemovesOrphanMacOSVMs(t *testing.T) {
now := time.Date(2026, time.April, 29, 20, 0, 0, 0, time.UTC)
cfg := &config.Config{
Runner: config.Runner{
WorkdirCleanupAge: 24 * time.Hour,
IdleCleanupInterval: time.Minute,
},
}
macOSVMLabel, err := labels.Parse("macos-latest:macos-vm://ghcr.io/cirruslabs/macos-sonoma-base:latest")
require.NoError(t, err)
var swept []string
var sweptCutoff time.Time
origRemoveOrphanMacOSVMs := removeOrphanMacOSVMs
removeOrphanMacOSVMs = func(_ context.Context, _, runnerUUID string, accessedBefore time.Time) error {
swept = append(swept, runnerUUID)
sweptCutoff = accessedBefore
return nil
}
t.Cleanup(func() { removeOrphanMacOSVMs = origRemoveOrphanMacOSVMs })
r := &Runner{uuid: "runner-1", cfg: cfg, labels: labels.Labels{macOSVMLabel}, now: func() time.Time { return now }}
r.OnIdle(context.Background())
assert.Equal(t, []string{"runner-1"}, swept)
assert.Equal(t, now.Add(-24*time.Hour), sweptCutoff)
// a docker-only runner has no macOS VMs to sweep
dockerLabel, err := labels.Parse("ubuntu:docker://node:18")
require.NoError(t, err)
dockerOnly := &Runner{uuid: "runner-2", cfg: &config.Config{Runner: cfg.Runner}, labels: labels.Labels{dockerLabel}, now: func() time.Time { return now }}
dockerOnly.OnIdle(context.Background())
assert.Equal(t, []string{"runner-1"}, swept)
}