Fix generated run lifecycle profile scope

This commit is contained in:
npc0-hue
2026-08-31 01:20:36 +08:00
parent 8194671656
commit fa2ce17ce3
4 changed files with 74 additions and 3 deletions
@@ -254,6 +254,24 @@ func defaultRunDistributionProfileKey(plugin domain.GamePlugin, profileKey strin
}
return profileKey
}
return firstRuntimeLifecycleProfileKey(plugin)
}
func lifecycleDefaultProfileKey(instance domain.ServerInstance, plugin domain.GamePlugin, profileKey string) string {
profileKey = strings.TrimSpace(profileKey)
if profileKey != "" {
if profile, ok := runtimeLifecycleProfileForKey(plugin.RuntimeProfiles, profileKey); ok {
return profile.Key
}
return profileKey
}
if instance.RunEndpointID != "" && instance.RunEndpointID == generatedRunEndpointID(instance.ID) {
return firstRuntimeLifecycleProfileKey(plugin)
}
return ""
}
func firstRuntimeLifecycleProfileKey(plugin domain.GamePlugin) string {
if len(plugin.RuntimeProfiles.LifecycleProfiles) == 0 {
return ""
}
+16 -2
View File
@@ -2260,10 +2260,24 @@ func declaredPluginFileRequest(workspace domain.PluginFileWorkspace, request dom
func (svc *CoreService) runtimeProfileScope(serverInstanceID string) string {
binding, err := svc.runtimeBindingForServer(serverInstanceID)
if err != nil {
if err == nil && strings.TrimSpace(binding.ProfileKey) != "" {
return binding.ProfileKey
}
if err != nil && !errors.Is(err, repo.ErrNotFound) {
return "default"
}
return binding.ProfileKey
instance, instanceErr := svc.store.ServerInstances().Get(serverInstanceID)
if instanceErr != nil {
return "default"
}
plugin, pluginErr := svc.store.GamePlugins().Get(instance.PluginID)
if pluginErr != nil {
return "default"
}
if profileKey := lifecycleDefaultProfileKey(instance, plugin, instance.Deployment.ProfileKey); profileKey != "" {
return profileKey
}
return "default"
}
func (svc *CoreService) latestMetricsForServer(instance domain.ServerInstance) domain.ServerMetrics {
+1 -1
View File
@@ -319,7 +319,7 @@ func (svc *CoreService) dispatchLifecycleJob(instance domain.ServerInstance, act
if err == nil && strings.TrimSpace(binding.ProfileKey) != "" {
profileKey = binding.ProfileKey
} else {
profileKey = instance.Deployment.ProfileKey
profileKey = lifecycleDefaultProfileKey(instance, plugin, instance.Deployment.ProfileKey)
}
actionRef := ""
profile, hasProfile := runtimeLifecycleProfileForKey(plugin.RuntimeProfiles, profileKey)
+39
View File
@@ -1,11 +1,13 @@
package service
import (
"errors"
"strings"
"testing"
"time"
"browser.local/platform/domain"
"browser.local/platform/repo"
)
func TestCoreServiceServerLifecycleWorkflows(t *testing.T) {
@@ -104,6 +106,43 @@ func TestLifecycleProjectedStateUsesRunProcessFacts(t *testing.T) {
}
}
func TestGeneratedRunLifecycleUsesPackageDefaultProfileWithoutRuntimeBinding(t *testing.T) {
svc := newTestCoreService()
plugin := createLifecyclePlugin(t, svc)
plugin.RequiredRunCapabilities = append(plugin.RequiredRunCapabilities, domain.LifecycleCapabilityStatus)
plugin.LifecycleActions.Status = "actions/status.json"
plugin.RuntimeProfiles.LifecycleProfiles = []domain.RuntimeLifecycleProfile{{
Key: "run-local",
Mode: "local-process",
Capabilities: []string{domain.LifecycleCapabilityInstall, domain.LifecycleCapabilityStart, domain.LifecycleCapabilityStop, domain.LifecycleCapabilityStatus},
ActionRefs: domain.PluginLifecycleActions{Install: "actions/install.json", Start: "actions/start.json", Stop: "actions/stop.json", Status: "actions/status.json"},
}}
if err := svc.store.GamePlugins().Update(plugin); err != nil {
t.Fatalf("update plugin profile: %v", err)
}
ownerSession := createServiceUserAndLogin(t, svc, domain.User{ID: "generated-run-owner", DisplayName: "Generated Run Owner", Email: "generated-run-owner@example.test", Roles: []string{"server-owner"}, PasswordHash: "secret-password"})
serverID := "generated-run-server"
endpointID := generatedRunEndpointID(serverID)
if err := svc.store.RunEndpoints().Create(domain.RunEndpoint{ID: endpointID, DisplayName: "Generated Run", Version: "0.1.0", Status: domain.RunEndpointStatusOnline, Capabilities: []string{domain.LifecycleCapabilityInstall, domain.LifecycleCapabilityStart, domain.LifecycleCapabilityStop, domain.LifecycleCapabilityStatus}, Capacity: domain.RunCapacity{MaxJobs: 1}, LastHeartbeatAt: fixedTime}); err != nil {
t.Fatalf("create generated run endpoint: %v", err)
}
instance := domain.ServerInstance{ID: serverID, PluginID: plugin.ID, PluginVersion: plugin.Version, RunEndpointID: endpointID, Name: "Generated Run Server", OwnerUserID: "generated-run-owner", State: domain.ServerInstanceStateFailed, ConfigVersion: 1, Deployment: domain.ServerDeploymentDefinition{Mode: domain.ServerDeploymentModeExisting, ServerRoot: `C:\scumserver`, Revision: 1}, CreatedAt: fixedTime, UpdatedAt: fixedTime}
if err := svc.store.ServerInstances().Create(instance); err != nil {
t.Fatalf("create generated run server: %v", err)
}
if _, err := svc.runtimeBindingForServer(serverID); !errors.Is(err, repo.ErrNotFound) {
t.Fatalf("expected generated run server to have no manual runtime binding: %v", err)
}
result, err := svc.QueryServerInstanceProcessForSession(ownerSession, domain.ServerLifecycleCommand{ServerInstanceID: serverID, ExpectedConfigVersion: 1, IdempotencyKey: "generated-run-status"})
if err != nil {
t.Fatalf("query generated run status: %v", err)
}
if result.Job.ExecutionInput.WorkspaceScope != "run-local" || result.Job.TargetKey != "actions/status.json" {
t.Fatalf("expected generated run status to use packaged profile scope, job=%+v", result.Job)
}
}
func TestLifecycleJobResultsPublishProcessStateEvents(t *testing.T) {
svc, sessionToken := newLifecycleRunService(t)
createLifecyclePlugin(t, svc)