Remove legacy steamcmd and SCUM runtime coupling

This commit is contained in:
npc0-hue
2026-09-04 12:37:39 +08:00
parent 26c07e232d
commit a695aafd0f
16 changed files with 113 additions and 91 deletions
+10 -1
View File
@@ -106,7 +106,7 @@ func ValidateRunAutonomousLifecyclePlan(plan RunAutonomousLifecyclePlan) error {
return ValidationError("autonomous install plan is invalid")
}
for _, step := range installPlan.Steps {
if !ValidLogicalFileKey(step.TargetKey) || !validAutonomousToken(step.Type, 80) || step.PackageManager != "" && !validAutonomousToken(step.PackageManager, 80) || step.PackageName != "" && !validAutonomousToken(step.PackageName, 160) || step.Version != "" && !validAutonomousToken(step.Version, 120) {
if !validAutonomousInstallStepType(step.Type) || !ValidLogicalFileKey(step.TargetKey) || step.PackageManager != "" && !validAutonomousToken(step.PackageManager, 80) || step.PackageName != "" && !validAutonomousToken(step.PackageName, 160) || step.Version != "" && !validAutonomousToken(step.Version, 120) {
return ValidationError("autonomous install step is invalid")
}
}
@@ -139,6 +139,15 @@ func ValidateRunAutonomousLifecyclePlan(plan RunAutonomousLifecyclePlan) error {
return nil
}
func validAutonomousInstallStepType(value string) bool {
switch value {
case "package", "verified-download", "manual":
return true
default:
return false
}
}
func validateAutonomousDataTarget(target RunAutonomousDataTarget) error {
if !ValidLogicalFileKey(target.Key) || !ValidLogicalFileKey(target.TransportKey) || !ValidLogicalFileKey(target.SourceRootKey) || !ValidLogicalFileKey(target.SourcePath) || !ValidLogicalFileKey(target.WorkspaceKey) {
return ValidationError("autonomous data target is invalid")
+9
View File
@@ -34,6 +34,15 @@ func TestValidateRunAutonomousLifecyclePlanRejectsUnsafeDataTargets(t *testing.T
}
}
func TestValidateRunAutonomousLifecyclePlanRejectsLegacySteamCMDAppStep(t *testing.T) {
plan := validAutonomousLifecyclePlanForTest()
plan.InstallPlans = []DependencyInstallPlan{{Key: "install-game", Title: "Install game", Steps: []DependencyInstallStep{{Type: "steamcmd-app", TargetKey: "server/install-root", PackageManager: "steamcmd", PackageName: "123456"}}}}
if err := ValidateRunAutonomousLifecyclePlan(plan); err == nil {
t.Fatal("expected legacy steamcmd-app install step to be rejected")
}
}
func validAutonomousLifecyclePlanForTest() RunAutonomousLifecyclePlan {
return RunAutonomousLifecyclePlan{SchemaVersion: "1", ServerInstanceID: "server-1", PluginID: "game.example", PluginVersion: "1.0.0", RunEndpointID: "run-1", ProfileKey: "run-local", TargetOS: "windows", TargetArch: "amd64", TargetRelease: "release-1", Bootstrap: &RunAutonomousLifecycleAction{Action: "start", Operation: "start", Capability: RunCapabilityProcessStart, TargetKey: "actions/start.json"}}
}
+11 -11
View File
@@ -229,17 +229,17 @@ type ServerDeploymentEvidence struct {
// accepted as part of a scoped process.start job; Run never fetches a mutable
// plugin declaration on its own.
type RuntimeDLLExtensionPlan struct {
Key string `json:"key"`
Version string `json:"version"`
ReleaseURL string `json:"releaseUrl"`
Checksum string `json:"checksum"`
SizeBytes int64 `json:"sizeBytes"`
TargetKey string `json:"targetKey"`
ModKey string `json:"modKey"`
DLLRef string `json:"dllRef"`
SCUMExecutableChecksum string `json:"scumExecutableChecksum"`
UE4SSABI string `json:"ue4ssAbi"`
RCONPort int `json:"rconPort"`
Key string `json:"key"`
Version string `json:"version"`
ReleaseURL string `json:"releaseUrl"`
Checksum string `json:"checksum"`
SizeBytes int64 `json:"sizeBytes"`
TargetKey string `json:"targetKey"`
ModKey string `json:"modKey"`
DLLRef string `json:"dllRef"`
TargetExecutableChecksum string `json:"targetExecutableChecksum"`
UE4SSABI string `json:"ue4ssAbi"`
RCONPort int `json:"rconPort"`
}
// RuntimeLogSourcePlan is a Platform-frozen, logical file log declaration. It
+1 -1
View File
@@ -59,7 +59,7 @@ Run distribution and runtime support jobs use the same lightweight job lifecycle
- `run.self-update`: downloads an approved same-server target-matched distribution in bounded resumable ranges, verifies the final checksum, safely extracts exactly the expected executable, preserves config, and reports a rollback-safe staged result. A helper activates only after result acceptance, then waits for health and restores the previous binary on timeout.
- `dependencies.check`: runs a plugin-declared typed dependency probe addressed by a logical `dependencies/...` key.
- `dependencies.install`: runs only an approved typed install plan addressed by `dependencies/install/...`; package, verified HTTPS download, SteamCMD, and manual steps are closed adapters, and arbitrary shell snippets, unsafe URLs/tokens, and unsupported targets are rejected.
- `dependencies.install`: runs only an approved typed install plan addressed by `dependencies/install/...`; package, verified HTTPS download, and manual steps are closed adapters, and arbitrary shell snippets, unsafe URLs/tokens, and unsupported targets are rejected.
- `logs.backfill`: advances historical log cursors for declared process, file, FTP, SQL, or plugin-specific sources and returns bounded cursor/result refs instead of log bodies.
The executor resolves lifecycle action templates under the scoped server workspace and runs direct command/argument vectors through the process supervisor. It does not run unrestricted shell strings, execute arbitrary plugin code, expose host paths, return raw credentials, open direct sockets, or embed logs/artifacts in job result payloads.
+1 -1
View File
@@ -315,7 +315,7 @@ func validateRuntimeDLLExtensionPlan(plan RuntimeDLLExtensionPlan) error {
if !ValidLogicalFileKey(plan.Key) || !ValidLogicalFileKey(plan.TargetKey) || !validExtensionVersion(plan.Version) {
return ValidationError("DLL extension identity is not allowed")
}
if !validRuntimeDLLURL(plan.ReleaseURL) || !validSHA256(plan.Checksum) || !validSHA256(plan.SCUMExecutableChecksum) || plan.SizeBytes < 1 || plan.SizeBytes > maxRunDLLExtensionBytes {
if !validRuntimeDLLURL(plan.ReleaseURL) || !validSHA256(plan.Checksum) || !validSHA256(plan.TargetExecutableChecksum) || plan.SizeBytes < 1 || plan.SizeBytes > maxRunDLLExtensionBytes {
return ValidationError("DLL extension release integrity is not allowed")
}
if !validDLLModKey(plan.ModKey) || plan.DLLRef != "ue4ss/Mods/"+plan.ModKey+"/dlls/main.dll" {
+15 -15
View File
@@ -64,14 +64,14 @@ func TestValidateRunJobAssignmentRequiresBoundedSQLiteSchemaProbe(t *testing.T)
func TestValidateRunJobAssignmentRejectsLegacyGameSpecificDeploymentPlan(t *testing.T) {
assignment := RunJobAssignment{
JobID: "job-legacy-scum-plan",
JobID: "job-legacy-game-plan",
ServerInstanceID: "server-1",
RunEndpointID: "run-local",
Capability: RunCapabilityProcessInstall,
IdempotencyKey: "idem-legacy-scum",
IdempotencyKey: "idem-legacy-game-plan",
ExecutionInput: RunJobExecutionInput{
Deployment: &ServerDeploymentExecution{SchemaVersion: "1", Mode: "guided-install", ServerRoot: "C:/scumserver", Revision: 1},
ServerDeploymentPlan: &ServerDeploymentPlan{SchemaVersion: "1", PluginID: "game.scum", TemplateKey: "scum-steamcmd-windows"},
Deployment: &ServerDeploymentExecution{SchemaVersion: "1", Mode: "guided-install", ServerRoot: "C:/game-server", Revision: 1},
ServerDeploymentPlan: &ServerDeploymentPlan{SchemaVersion: "1", PluginID: "game.example", TemplateKey: "legacy-game-template"},
},
}
@@ -361,16 +361,16 @@ func TestValidateProtectedRequestAssignmentAndOneTimeInput(t *testing.T) {
func validRuntimeDLLExtensionPlan() RuntimeDLLExtensionPlan {
return RuntimeDLLExtensionPlan{
Key: "scum-simple-rcon",
Version: "1.0.0",
ReleaseURL: "https://cdn.npc0.com/scum_simple_rcon_ue4s.dll",
Checksum: "sha256:" + strings.Repeat("a", 64),
SizeBytes: 1024,
TargetKey: "ue4ss/scum-simple-rcon",
ModKey: "scum_simple_rcon",
DLLRef: "ue4ss/Mods/scum_simple_rcon/dlls/main.dll",
SCUMExecutableChecksum: "sha256:" + strings.Repeat("b", 64),
UE4SSABI: "ue4ss-3.0",
RCONPort: 27015,
Key: "scum-simple-rcon",
Version: "1.0.0",
ReleaseURL: "https://cdn.npc0.com/scum_simple_rcon_ue4s.dll",
Checksum: "sha256:" + strings.Repeat("a", 64),
SizeBytes: 1024,
TargetKey: "ue4ss/scum-simple-rcon",
ModKey: "scum_simple_rcon",
DLLRef: "ue4ss/Mods/scum_simple_rcon/dlls/main.dll",
TargetExecutableChecksum: "sha256:" + strings.Repeat("b", 64),
UE4SSABI: "ue4ss-3.0",
RCONPort: 27015,
}
}