Fix guided lifecycle job scoping
This commit is contained in:
@@ -302,6 +302,10 @@ type JobExecutionInput struct {
|
||||
DLLExtensions []domain.RuntimeDLLExtensionPlan `json:"dllExtensions,omitempty" db:"dll_extensions"`
|
||||
// SourceRCON is secret-free connection metadata for a one-time Run command.
|
||||
SourceRCON *domain.RuntimeSourceRCONPlan `json:"sourceRcon,omitempty" db:"source_rcon"`
|
||||
// Deployment is protected lifecycle execution material delivered only to Run.
|
||||
Deployment *domain.ServerDeploymentDefinition `json:"deployment,omitempty" db:"deployment"`
|
||||
// ServerDeploymentPlan is the legacy generic deployment-plan payload.
|
||||
ServerDeploymentPlan *domain.ServerDeploymentPlan `json:"serverDeploymentPlan,omitempty" db:"server_deployment_plan"`
|
||||
}
|
||||
|
||||
type JobExecutionResult struct {
|
||||
@@ -895,11 +899,21 @@ func (job Job) ToDomain() domain.Job {
|
||||
}
|
||||
|
||||
func executionInputFromDomain(input domain.JobExecutionInput) JobExecutionInput {
|
||||
return JobExecutionInput{WorkspaceScope: input.WorkspaceScope, Content: input.Content, ExpectedVersion: input.ExpectedVersion, ExpectedChecksum: input.ExpectedChecksum, MaxReadBytes: input.MaxReadBytes, RemoteAdapterKey: input.RemoteAdapterKey, RemoteAdapterKind: input.RemoteAdapterKind, TimeoutSeconds: input.TimeoutSeconds, PluginID: input.PluginID, LifecycleOperation: input.LifecycleOperation, TargetVersion: input.TargetVersion, Inputs: domain.CopyStringMap(input.Inputs), DLLExtensions: append([]domain.RuntimeDLLExtensionPlan(nil), input.DLLExtensions...), SourceRCON: domain.CopyRuntimeSourceRCONPlan(input.SourceRCON)}
|
||||
var deployment *domain.ServerDeploymentDefinition
|
||||
if input.Deployment != nil {
|
||||
copy := domain.CopyServerDeploymentDefinition(*input.Deployment)
|
||||
deployment = ©
|
||||
}
|
||||
return JobExecutionInput{WorkspaceScope: input.WorkspaceScope, Content: input.Content, ExpectedVersion: input.ExpectedVersion, ExpectedChecksum: input.ExpectedChecksum, MaxReadBytes: input.MaxReadBytes, RemoteAdapterKey: input.RemoteAdapterKey, RemoteAdapterKind: input.RemoteAdapterKind, TimeoutSeconds: input.TimeoutSeconds, PluginID: input.PluginID, LifecycleOperation: input.LifecycleOperation, TargetVersion: input.TargetVersion, Inputs: domain.CopyStringMap(input.Inputs), DLLExtensions: append([]domain.RuntimeDLLExtensionPlan(nil), input.DLLExtensions...), SourceRCON: domain.CopyRuntimeSourceRCONPlan(input.SourceRCON), Deployment: deployment, ServerDeploymentPlan: domain.CopyServerDeploymentPlan(input.ServerDeploymentPlan)}
|
||||
}
|
||||
|
||||
func (input JobExecutionInput) ToDomain() domain.JobExecutionInput {
|
||||
return domain.JobExecutionInput{WorkspaceScope: input.WorkspaceScope, Content: input.Content, ExpectedVersion: input.ExpectedVersion, ExpectedChecksum: input.ExpectedChecksum, MaxReadBytes: input.MaxReadBytes, RemoteAdapterKey: input.RemoteAdapterKey, RemoteAdapterKind: input.RemoteAdapterKind, TimeoutSeconds: input.TimeoutSeconds, PluginID: input.PluginID, LifecycleOperation: input.LifecycleOperation, TargetVersion: input.TargetVersion, Inputs: domain.CopyStringMap(input.Inputs), DLLExtensions: append([]domain.RuntimeDLLExtensionPlan(nil), input.DLLExtensions...), SourceRCON: domain.CopyRuntimeSourceRCONPlan(input.SourceRCON)}
|
||||
var deployment *domain.ServerDeploymentDefinition
|
||||
if input.Deployment != nil {
|
||||
copy := domain.CopyServerDeploymentDefinition(*input.Deployment)
|
||||
deployment = ©
|
||||
}
|
||||
return domain.JobExecutionInput{WorkspaceScope: input.WorkspaceScope, Content: input.Content, ExpectedVersion: input.ExpectedVersion, ExpectedChecksum: input.ExpectedChecksum, MaxReadBytes: input.MaxReadBytes, RemoteAdapterKey: input.RemoteAdapterKey, RemoteAdapterKind: input.RemoteAdapterKind, TimeoutSeconds: input.TimeoutSeconds, PluginID: input.PluginID, LifecycleOperation: input.LifecycleOperation, TargetVersion: input.TargetVersion, Inputs: domain.CopyStringMap(input.Inputs), DLLExtensions: append([]domain.RuntimeDLLExtensionPlan(nil), input.DLLExtensions...), SourceRCON: domain.CopyRuntimeSourceRCONPlan(input.SourceRCON), Deployment: deployment, ServerDeploymentPlan: domain.CopyServerDeploymentPlan(input.ServerDeploymentPlan)}
|
||||
}
|
||||
|
||||
func executionResultFromDomain(result domain.JobExecutionResult) JobExecutionResult {
|
||||
|
||||
@@ -101,6 +101,24 @@ func TestJobExecutionInputModelRoundTripPreservesLifecycleMetadata(t *testing.T)
|
||||
LifecycleOperation: "upgrade",
|
||||
TargetVersion: "2.0.0",
|
||||
Inputs: map[string]string{"templateKey": "players.by-id", "playerId": "steam-123"},
|
||||
Deployment: &domain.ServerDeploymentDefinition{
|
||||
Mode: domain.ServerDeploymentModeGuided,
|
||||
ProfileKey: "run-local",
|
||||
RuntimeBindings: map[string]string{"installRoot": "D:\\scumserver"},
|
||||
CreateInputs: map[string]string{"gamePort": "27000", "maxPlayers": "128"},
|
||||
ServerRoot: "D:\\scumserver",
|
||||
WorkingDirectory: "D:\\scumserver",
|
||||
InstallCommand: "install.cmd",
|
||||
StartCommand: "start.cmd",
|
||||
Shell: domain.ServerCommandShellCmd,
|
||||
Revision: 3,
|
||||
},
|
||||
ServerDeploymentPlan: &domain.ServerDeploymentPlan{
|
||||
SchemaVersion: "1",
|
||||
Operation: "install",
|
||||
PluginID: "game.scum",
|
||||
Prerequisites: []domain.RuntimeServerPrerequisite{{Key: "steamcmd", Kind: "tool"}},
|
||||
},
|
||||
}
|
||||
|
||||
row := executionInputFromDomain(source)
|
||||
@@ -108,20 +126,31 @@ func TestJobExecutionInputModelRoundTripPreservesLifecycleMetadata(t *testing.T)
|
||||
if row.Inputs["playerId"] != "steam-123" {
|
||||
t.Fatalf("expected model execution inputs to be isolated from source mutation, row=%+v", row.Inputs)
|
||||
}
|
||||
source.Deployment.CreateInputs["maxPlayers"] = "64"
|
||||
if row.Deployment == nil || row.Deployment.CreateInputs["maxPlayers"] != "128" {
|
||||
t.Fatalf("expected model deployment inputs to be isolated from source mutation, row=%+v", row.Deployment)
|
||||
}
|
||||
source.Inputs["playerId"] = "steam-123"
|
||||
source.Deployment.CreateInputs["maxPlayers"] = "128"
|
||||
row.Inputs["playerId"] = "row-mutated"
|
||||
if source.Inputs["playerId"] != "steam-123" {
|
||||
t.Fatalf("expected source execution inputs to be isolated from model mutation, source=%+v", source.Inputs)
|
||||
}
|
||||
row.Deployment.CreateInputs["maxPlayers"] = "32"
|
||||
if source.Deployment.CreateInputs["maxPlayers"] != "128" {
|
||||
t.Fatalf("expected source deployment inputs to be isolated from model mutation, source=%+v", source.Deployment)
|
||||
}
|
||||
row.Inputs["playerId"] = "steam-123"
|
||||
row.Deployment.CreateInputs["maxPlayers"] = "128"
|
||||
|
||||
roundTrip := row.ToDomain()
|
||||
if !reflect.DeepEqual(roundTrip, source) {
|
||||
t.Fatalf("expected lifecycle execution metadata to round-trip, got %+v", roundTrip)
|
||||
}
|
||||
roundTrip.Inputs["playerId"] = "mutated"
|
||||
if source.Inputs["playerId"] != "steam-123" || row.Inputs["playerId"] != "steam-123" {
|
||||
t.Fatalf("expected execution inputs to round-trip without aliasing, source=%+v row=%+v", source.Inputs, row.Inputs)
|
||||
roundTrip.Deployment.CreateInputs["maxPlayers"] = "16"
|
||||
if source.Inputs["playerId"] != "steam-123" || row.Inputs["playerId"] != "steam-123" || source.Deployment.CreateInputs["maxPlayers"] != "128" || row.Deployment.CreateInputs["maxPlayers"] != "128" {
|
||||
t.Fatalf("expected execution inputs to round-trip without aliasing, source=%+v row=%+v", source, row)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user