Fix guided lifecycle job scoping

This commit is contained in:
npc0-hue
2026-08-01 17:11:25 +08:00
parent e37f00c48a
commit 9f82e310b2
6 changed files with 92 additions and 20 deletions
+6 -6
View File
@@ -322,8 +322,8 @@ func TestCoreServiceDedicatedRunRegistrationAutomaticallyDeploysGuidedDraftOnly(
t.Fatalf("generated Run registration should queue install without deployment target, server=%+v err=%v", storedGenerated, err)
}
jobs, err = svc.store.Jobs().List(domain.JobFilter{ServerInstanceID: generatedRunDraft.ID})
if err != nil || len(jobs) != 1 || jobs[0].Capability != domain.LifecycleCapabilityInstall {
t.Fatalf("expected one automatic generated Run install job, jobs=%+v err=%v", jobs, err)
if err != nil || len(jobs) != 1 || jobs[0].Capability != domain.LifecycleCapabilityInstall || jobs[0].ExecutionInput.WorkspaceScope != "local" {
t.Fatalf("expected one scoped automatic generated Run install job, jobs=%+v err=%v", jobs, err)
}
existing, err := svc.CreateServerInstanceWorkflowForSession(owner, domain.ServerLifecycleCreate{ID: "managed-existing", PluginID: plugin.ID, DeploymentTargetID: "run-local", Name: "Managed Existing", IdempotencyKey: "managed-existing-create", ProfileKey: "local", Deployment: domain.ServerDeploymentDefinition{Mode: domain.ServerDeploymentModeExisting, ServerRoot: "C:\\existing-scum"}})
@@ -431,15 +431,15 @@ func TestCoreServiceGeneratedSCUMRunRegistrationQueuesGuidedInstall(t *testing.T
t.Fatalf("expected one SCUM install job, jobs=%+v err=%v", jobs, err)
}
job := jobs[0]
if job.Capability != domain.LifecycleCapabilityInstall || job.TargetKey != "actions/install.json" || job.ExecutionInput.Deployment == nil || job.ExecutionInput.ServerDeploymentPlan != nil {
t.Fatalf("expected SCUM install job with plugin action and generic deployment inputs, job=%+v", job)
if job.Capability != domain.LifecycleCapabilityInstall || job.TargetKey != "actions/install.json" || job.ExecutionInput.WorkspaceScope != "run-local" || job.ExecutionInput.Deployment == nil || job.ExecutionInput.ServerDeploymentPlan != nil {
t.Fatalf("expected SCUM install job with scoped plugin action and generic deployment inputs, job=%+v", job)
}
if job.ExecutionInput.Deployment.CreateInputs["gamePort"] != "27000" || job.ExecutionInput.Deployment.CreateInputs["maxPlayers"] != "128" {
t.Fatalf("SCUM install job lost create inputs: %+v", job.ExecutionInput.Deployment.CreateInputs)
}
claim, err := svc.ClaimRunJob(domain.RunJobClaim{RunEndpointID: instance.RunEndpointID, SessionToken: registered.SessionToken, Capabilities: hello.CapabilityReport.Capabilities, Capacity: domain.RunCapacity{MaxJobs: 1}})
if err != nil || !claim.HasJob || claim.Job.TargetKey != "actions/install.json" || claim.Job.ExecutionInput.ServerDeploymentPlan != nil {
t.Fatalf("generated SCUM Run should claim plugin-owned install action, claim=%+v err=%v", claim, err)
if err != nil || !claim.HasJob || claim.Job.TargetKey != "actions/install.json" || claim.Job.ExecutionInput.WorkspaceScope != "run-local" || claim.Job.ExecutionInput.ServerDeploymentPlan != nil {
t.Fatalf("generated SCUM Run should claim scoped plugin-owned install action, claim=%+v err=%v", claim, err)
}
}
+1 -1
View File
@@ -95,7 +95,7 @@ func TestRuntimeBindingValidationAndLifecycleGating(t *testing.T) {
t.Fatalf("unexpected complete binding: view=%+v err=%v", view, err)
}
result, err := svc.StartServerInstanceForSession(ownerSession, domain.ServerLifecycleCommand{ServerInstanceID: instance.ID, ExpectedConfigVersion: instance.ConfigVersion, IdempotencyKey: "start-complete-binding"})
if err != nil || result.Job.TargetKey != "local" {
if err != nil || result.Job.TargetKey != "actions/start.json" || result.Job.ExecutionInput.WorkspaceScope != "local" {
t.Fatalf("expected complete binding to permit start, result=%+v err=%v", result, err)
}
}
+5 -4
View File
@@ -291,19 +291,20 @@ func (svc *CoreService) dispatchLifecycleJob(instance domain.ServerInstance, act
return domain.Job{}, err
}
profileKey := ""
if err == nil {
if err == nil && strings.TrimSpace(binding.ProfileKey) != "" {
profileKey = binding.ProfileKey
} else {
profileKey = instance.Deployment.ProfileKey
}
actionRef := profileKey
actionRef := ""
profile, hasProfile := runtimeLifecycleProfileForKey(plugin.RuntimeProfiles, profileKey)
if hasProfile {
if ref := runtimeProfileActionRef(profile.ActionRefs, action); ref != "" {
actionRef = ref
}
} else if ref := lifecycleActionRef(plugin, action); ref != "" {
actionRef = ref
}
if strings.TrimSpace(actionRef) == "" {
actionRef = lifecycleActionRef(plugin, action)
}
if strings.TrimSpace(actionRef) == "" {
return domain.Job{}, validationError(fmt.Sprintf("plugin %s lifecycle action is required", action))