feat: 完整游戏运维功能

This commit is contained in:
npc0-hue
2026-07-18 09:04:01 +08:00
parent f3b14b7945
commit 48b8ad8d6c
187 changed files with 16607 additions and 1140 deletions
+350
View File
@@ -0,0 +1,350 @@
package domain
import "time"
type ClientManagerLifecycleStatus string
const (
ClientManagerLifecycleRequested ClientManagerLifecycleStatus = "requested"
ClientManagerLifecycleBuilding ClientManagerLifecycleStatus = "building"
ClientManagerLifecycleAvailable ClientManagerLifecycleStatus = "available"
ClientManagerLifecycleDeploying ClientManagerLifecycleStatus = "deploying"
ClientManagerLifecycleInstalled ClientManagerLifecycleStatus = "installed"
ClientManagerLifecycleRegistering ClientManagerLifecycleStatus = "registering"
ClientManagerLifecycleOnline ClientManagerLifecycleStatus = "online"
ClientManagerLifecycleDegraded ClientManagerLifecycleStatus = "degraded"
ClientManagerLifecycleOffline ClientManagerLifecycleStatus = "offline"
ClientManagerLifecycleUpdating ClientManagerLifecycleStatus = "updating"
ClientManagerLifecycleRollingBack ClientManagerLifecycleStatus = "rolling_back"
ClientManagerLifecycleStopping ClientManagerLifecycleStatus = "stopping"
ClientManagerLifecycleUninstalled ClientManagerLifecycleStatus = "uninstalled"
ClientManagerLifecycleFailed ClientManagerLifecycleStatus = "failed"
)
type ClientManagerHealthStatus string
const (
ClientManagerHealthUnknown ClientManagerHealthStatus = "unknown"
ClientManagerHealthHealthy ClientManagerHealthStatus = "healthy"
ClientManagerHealthDegraded ClientManagerHealthStatus = "degraded"
ClientManagerHealthUnhealthy ClientManagerHealthStatus = "unhealthy"
ClientManagerHealthOffline ClientManagerHealthStatus = "offline"
)
type ClientManagerLifecycleOperation string
const (
ClientManagerOperationDeploy ClientManagerLifecycleOperation = "deploy"
ClientManagerOperationStart ClientManagerLifecycleOperation = "start"
ClientManagerOperationStop ClientManagerLifecycleOperation = "stop"
ClientManagerOperationRestart ClientManagerLifecycleOperation = "restart"
ClientManagerOperationStatus ClientManagerLifecycleOperation = "status"
ClientManagerOperationUpdate ClientManagerLifecycleOperation = "update"
ClientManagerOperationRollback ClientManagerLifecycleOperation = "rollback"
ClientManagerOperationUninstall ClientManagerLifecycleOperation = "uninstall"
)
const (
JobCapabilityClientManagerDeploy = "client-manager.deploy"
JobCapabilityClientManagerControl = "client-manager.control"
JobCapabilityClientManagerUpdate = "client-manager.update"
JobCapabilityClientManagerRollback = "client-manager.rollback"
JobCapabilityClientManagerUninstall = "client-manager.uninstall"
)
type ClientManagerSessionStatus string
const (
ClientManagerSessionActive ClientManagerSessionStatus = "active"
ClientManagerSessionRevoked ClientManagerSessionStatus = "revoked"
ClientManagerSessionExpired ClientManagerSessionStatus = "expired"
)
type RuntimeClientManagerDeployment struct {
Mode string
ExecutableRef string
Arguments []string
AutoStart bool
RequiredRunCapabilities []string
}
type RuntimeClientManagerLifecycle struct {
Actions []string
StartupTimeoutSeconds int
StopTimeoutSeconds int
}
type RuntimeClientManagerHealth struct {
Mode string
IntervalSeconds int
DegradedAfterSeconds int
OfflineAfterSeconds int
RequiredCapabilities []string
}
type RuntimeClientManagerCompatibility struct {
MinimumVersion string
MaximumVersion string
AllowDowngrade bool
}
type RuntimeClientManagerUpdatePolicy struct {
Strategy string
RequireApproval bool
HealthConfirmationSeconds int
RetainPrevious bool
}
type ClientManagerInstallation struct {
ID string
ServerInstanceID string
PluginID string
ProfileKey string
RunEndpointID string
TargetOS string
TargetArch string
Status ClientManagerLifecycleStatus
Phase string
DesiredVersion string
ActiveVersion string
PreviousVersion string
DesiredRevision string
ActiveRevision string
PreviousRevision string
DesiredArtifactID string
ActiveArtifactID string
PreviousArtifactID string
Checksum string
KeyGeneration int
DeploymentGeneration int
CurrentJobID string
LastSuccessfulJobID string
LastOperation ClientManagerLifecycleOperation
Health ClientManagerHealthStatus
HealthReason string
LastSeenAt time.Time
LastHeartbeatSequence uint64
Retryable bool
RequiresRedeploy bool
CreatedAt time.Time
UpdatedAt time.Time
InstalledAt time.Time
UninstalledAt time.Time
}
type ClientManagerSession struct {
ID string
InstallationID string
ServerInstanceID string
ProfileKey string
RunEndpointID string
ArtifactID string
KeyGeneration int
DeploymentGeneration int
TokenHash string
Capabilities []string
Status ClientManagerSessionStatus
LastHeartbeatSequence uint64
LastSeenAt time.Time
ExpiresAt time.Time
CreatedAt time.Time
UpdatedAt time.Time
RevokedAt time.Time
}
type ClientManagerRegistrationNonce struct {
ID string
InstallationID string
ExpiresAt time.Time
CreatedAt time.Time
}
type ClientManagerLifecycleActionAvailability struct {
Operation ClientManagerLifecycleOperation
Available bool
Reason string
}
type ClientManagerLifecycleView struct {
Installation ClientManagerInstallation
Distribution ClientManagerDistribution
Job Job
Actions []ClientManagerLifecycleActionAvailability
}
type ClientManagerDeployRequest struct {
ServerInstanceID string
ProfileKey string
DistributionID string
ExpectedDeploymentGeneration int
IdempotencyKey string
}
type ClientManagerControlRequest struct {
ServerInstanceID string
ProfileKey string
Operation ClientManagerLifecycleOperation
ExpectedDeploymentGeneration int
IdempotencyKey string
}
type ClientManagerUpdateRequest struct {
ServerInstanceID string
ProfileKey string
DistributionID string
ExpectedDeploymentGeneration int
Approved bool
IdempotencyKey string
}
type ClientManagerUninstallRequest struct {
ServerInstanceID string
ProfileKey string
ExpectedDeploymentGeneration int
Confirmed bool
IdempotencyKey string
}
type ClientManagerRetryRequest struct {
ServerInstanceID string
ProfileKey string
ExpectedDeploymentGeneration int
IdempotencyKey string
}
type ClientManagerRevokeSessionRequest struct {
ServerInstanceID string
ProfileKey string
Reason string
}
type ClientManagerLifecycleInputRequest struct {
RunEndpointID string
SessionToken string
JobID string
LeaseToken string
Attempt int
}
type ClientManagerLifecycleInput struct {
InstallationID string
ServerInstanceID string
ProfileKey string
Operation ClientManagerLifecycleOperation
ArtifactID string
Checksum string
TargetOS string
TargetArch string
Version string
SourceRevision string
KeyGeneration int
DeploymentGeneration int
ExecutableRef string
Arguments []string
AutoStart bool
StartupTimeoutSeconds int
StopTimeoutSeconds int
HealthConfirmationSeconds int
IdempotencyKey string
}
type ClientManagerRegisterRequest struct {
InstallationID string
ServerInstanceID string
ProfileKey string
ArtifactID string
Version string
SourceRevision string
TargetOS string
TargetArch string
KeyGeneration int
DeploymentGeneration int
Capabilities []string
Timestamp time.Time
Nonce string
Signature string
}
type ClientManagerRegisterResult struct {
Accepted bool
InstallationID string
SessionToken string
ExpiresAt time.Time
HeartbeatEvery int
ServerTime time.Time
}
type ClientManagerHeartbeat struct {
InstallationID string
SessionToken string
Sequence uint64
Health ClientManagerHealthStatus
HealthReason string
Capabilities []string
SentAt time.Time
}
type ClientManagerHeartbeatResult struct {
Accepted bool
InstallationID string
Status ClientManagerLifecycleStatus
Health ClientManagerHealthStatus
NextHeartbeat int
SessionExpiresAt time.Time
ServerTime time.Time
}
type ClientManagerInstallationFilter struct {
ServerInstanceID string
ProfileKey string
RunEndpointID string
Status ClientManagerLifecycleStatus
}
type ClientManagerSessionFilter struct {
InstallationID string
ServerInstanceID string
ProfileKey string
Status ClientManagerSessionStatus
}
type ClientManagerNonceFilter struct {
InstallationID string
ExpiresBefore time.Time
}
func CopyClientManagerInstallation(value ClientManagerInstallation) ClientManagerInstallation {
return value
}
func CopyClientManagerSession(value ClientManagerSession) ClientManagerSession {
value.Capabilities = CopyStringSlice(value.Capabilities)
return value
}
func CopyClientManagerRegistrationNonce(value ClientManagerRegistrationNonce) ClientManagerRegistrationNonce {
return value
}
func CopyClientManagerLifecycleView(value ClientManagerLifecycleView) ClientManagerLifecycleView {
value.Installation = CopyClientManagerInstallation(value.Installation)
value.Distribution = CopyClientManagerDistribution(value.Distribution)
value.Job = CopyJob(value.Job)
value.Actions = append([]ClientManagerLifecycleActionAvailability(nil), value.Actions...)
return value
}
func CopyClientManagerLifecycleInput(value ClientManagerLifecycleInput) ClientManagerLifecycleInput {
value.Arguments = CopyStringSlice(value.Arguments)
return value
}
func CopyClientManagerRegisterRequest(value ClientManagerRegisterRequest) ClientManagerRegisterRequest {
value.Capabilities = CopyStringSlice(value.Capabilities)
return value
}
func CopyClientManagerHeartbeat(value ClientManagerHeartbeat) ClientManagerHeartbeat {
value.Capabilities = CopyStringSlice(value.Capabilities)
return value
}
+24 -1
View File
@@ -19,6 +19,9 @@ type RunControlHello struct {
Version string
Status RunEndpointStatus
Platform string
Architecture string
UpdateJobID string
UpdateOutcome string
CapabilityReport RunCapabilityReport
Capacity RunCapacity
}
@@ -29,6 +32,7 @@ type RunControlHelloResult struct {
SessionToken string
ServerTime time.Time
HeartbeatIntervalSeconds int
SessionExpiresAt time.Time
FeatureFlags []string
}
@@ -51,11 +55,29 @@ type RunControlHeartbeatResult struct {
type RunControlSession struct {
RunEndpointID string
SessionToken string
SessionToken string `json:"-"`
SessionTokenHash string
Status AuthSessionStatus
Generation int
CapabilityFingerprint string
HeartbeatIntervalSeconds int
CreatedAt time.Time
UpdatedAt time.Time
ExpiresAt time.Time
RevokedAt time.Time
RequireSignedRequests bool
UsedNonces []string
}
type RunRequestSignature struct {
RunEndpointID string
SessionToken string
Method string
Path string
Timestamp string
Nonce string
BodyHash string
Signature string
}
func CopyRunCapabilityReport(report RunCapabilityReport) RunCapabilityReport {
@@ -82,5 +104,6 @@ func CopyRunControlHeartbeatResult(result RunControlHeartbeatResult) RunControlH
}
func CopyRunControlSession(session RunControlSession) RunControlSession {
session.UsedNonces = CopyStringSlice(session.UsedNonces)
return session
}
+144 -31
View File
@@ -18,8 +18,14 @@ type RunJobAssignment struct {
State JobState
Progress RunJobProgressReport
ResultRef string
ExecutionInput JobExecutionInput
LeaseToken string
Attempt int
MaxAttempts int
AckDeadlineAt time.Time
LeaseExpiresAt time.Time
NextAttemptAt time.Time
ProgressSequence uint64
CreatedAt time.Time
UpdatedAt time.Time
}
@@ -72,16 +78,18 @@ type RunJobProgressResult struct {
}
type RunJobResult struct {
RunEndpointID string
SessionToken string
JobID string
LeaseToken string
Attempt int
State JobState
Progress RunJobProgressReport
ResultRef string
Message string
ErrorCode string
RunEndpointID string
SessionToken string
JobID string
LeaseToken string
Attempt int
State JobState
Progress RunJobProgressReport
ResultRef string
Message string
ErrorCode string
Retryable bool
ExecutionResult JobExecutionResult
}
type RunJobResultResult struct {
@@ -107,6 +115,7 @@ type DistributionBuildInput struct {
ProfileKey string
TargetOS string
TargetArch string
TargetRelease string
PackageFormat string
RepositoryURL string
SourceRevision string
@@ -117,6 +126,103 @@ type DistributionBuildInput struct {
AuthKey string
}
type DependencyExecutionInputRequest struct {
RunEndpointID string
SessionToken string
JobID string
LeaseToken string
Attempt int
}
type DependencyExecutionInput struct {
JobID string
ServerInstanceID string
RunEndpointID string
PluginID string
PluginVersion string
ProfileKey string
TargetOS string
TargetArch string
PlanDigest string
Probe RuntimeDependencyProbe
Plan RuntimeInstallPlan
Bindings map[string]string
}
type RunUpdateInputRequest struct {
RunEndpointID string
SessionToken string
JobID string
LeaseToken string
Attempt int
}
type RunUpdateInput struct {
JobID string
ServerInstanceID string
RunEndpointID string
ArtifactID string
Checksum string
SizeBytes int64
TargetOS string
TargetArch string
PackageFormat string
ExecutableName string
TargetRelease string
ChunkSizeBytes int
}
type RunUpdateChunkRequest struct {
RunEndpointID string
SessionToken string
JobID string
LeaseToken string
Attempt int
Offset int64
Length int
}
type RunUpdateChunk struct {
JobID string
ArtifactID string
Offset int64
TotalBytes int64
Checksum string
Payload []byte
Complete bool
}
type RunUpdateHealthReport struct {
RunEndpointID string
SessionToken string
JobID string
LeaseToken string
Attempt int
Outcome string
Version string
}
type RunUpdateHealthResult struct {
Accepted bool
JobID string
Phase RunUpdatePhase
ServerTime time.Time
}
type DependencyExecutionEvidence struct {
ProbeKey string `json:"probeKey"`
PlanKey string `json:"planKey,omitempty"`
PlanDigest string `json:"planDigest"`
State string `json:"state"`
Evidence string `json:"evidence,omitempty"`
CompletedSteps int `json:"completedSteps,omitempty"`
}
type RunUpdateExecutionEvidence struct {
TargetRelease string `json:"targetRelease"`
Phase string `json:"phase"`
}
type RunJobCancelRequest struct {
JobID string
Reason string
@@ -127,6 +233,8 @@ type RunJobCancelRequestResult struct {
JobID string
Reason string
RequestedAt time.Time
CompletedAt time.Time
State JobState
}
type RunJobCancelPoll struct {
@@ -134,6 +242,7 @@ type RunJobCancelPoll struct {
SessionToken string
JobID string
LeaseToken string
Attempt int
}
type RunJobCancelPollResult struct {
@@ -146,33 +255,26 @@ type RunJobCancelPollResult struct {
ServerTime time.Time
}
type RunJobReconcileEntry struct {
JobID string
LeaseToken string
Attempt int
}
type RunJobReconcile struct {
RunEndpointID string
SessionToken string
ActiveJobIDs []string
ActiveJobs []RunJobReconcileEntry
}
type RunJobReconcileResult struct {
Accepted bool
RunEndpointID string
ActiveJobs []RunJobAssignment
UnknownJobIDs []string
ConfirmedJobs []RunJobAssignment
DiscardJobIDs []string
ServerTime time.Time
}
type RunJobLease struct {
JobID string
RunEndpointID string
SessionToken string
LeaseToken string
Attempt int
CancelReason string
CancelRequestedAt time.Time
TerminalFingerprint string
CreatedAt time.Time
UpdatedAt time.Time
}
func CopyRunJobAssignment(assignment RunJobAssignment) RunJobAssignment {
return assignment
}
@@ -196,13 +298,15 @@ func CopyRunJobClaimResult(result RunJobClaimResult) RunJobClaimResult {
}
func CopyRunJobReconcile(reconcile RunJobReconcile) RunJobReconcile {
reconcile.ActiveJobIDs = CopyStringSlice(reconcile.ActiveJobIDs)
if reconcile.ActiveJobs != nil {
reconcile.ActiveJobs = append([]RunJobReconcileEntry(nil), reconcile.ActiveJobs...)
}
return reconcile
}
func CopyRunJobReconcileResult(result RunJobReconcileResult) RunJobReconcileResult {
result.ActiveJobs = CopyRunJobAssignments(result.ActiveJobs)
result.UnknownJobIDs = CopyStringSlice(result.UnknownJobIDs)
result.ConfirmedJobs = CopyRunJobAssignments(result.ConfirmedJobs)
result.DiscardJobIDs = CopyStringSlice(result.DiscardJobIDs)
return result
}
@@ -215,6 +319,15 @@ func CopyRunJobAssignments(assignments []RunJobAssignment) []RunJobAssignment {
return out
}
func CopyRunJobLease(lease RunJobLease) RunJobLease {
return lease
func CopyDependencyExecutionInput(input DependencyExecutionInput) DependencyExecutionInput {
input.Probe.Platforms = CopyStringSlice(input.Probe.Platforms)
input.Plan.Platforms = CopyStringSlice(input.Plan.Platforms)
input.Plan.Steps = append([]RuntimeInstallStep(nil), input.Plan.Steps...)
input.Bindings = CopyStringMap(input.Bindings)
return input
}
func CopyRunUpdateChunk(chunk RunUpdateChunk) RunUpdateChunk {
chunk.Payload = append([]byte(nil), chunk.Payload...)
return chunk
}
+185
View File
@@ -0,0 +1,185 @@
package domain
import "time"
// MetricSample is a bounded, platform-owned observation for one server instance.
type MetricSample struct {
ID string
ServerInstanceID string
RunEndpointID string
Online bool
PlayerCount *int
MaxPlayers *int
TPS *float64
LatencyMS *float64
CPUPercent *float64
MemoryPercent *float64
DiskPercent *float64
Source string
CollectedAt time.Time
}
type MetricSampleFilter struct {
ServerInstanceID string
After time.Time
Before time.Time
Limit int
}
type MetricBatchIngest struct {
RunEndpointID string
SessionToken string
Samples []MetricSample
}
type MetricBatchIngestResult struct {
Accepted bool
AcceptedCount int
LatestAt time.Time
ServerTime time.Time
}
type BackupState string
const (
BackupStatePending BackupState = "pending"
BackupStateAvailable BackupState = "available"
BackupStateFailed BackupState = "failed"
BackupStateExpired BackupState = "expired"
)
type BackupRecord struct {
ID string
ServerInstanceID string
ArtifactID string
Checksum string
SizeBytes int64
State BackupState
RecoveryStatus string
RetentionUntil time.Time
CreatedAt time.Time
UpdatedAt time.Time
}
type BackupFilter struct {
ServerInstanceID string
State BackupState
}
type RemoteAdapterKind string
const (
RemoteAdapterFTP RemoteAdapterKind = "ftp"
RemoteAdapterRsync RemoteAdapterKind = "rsync"
RemoteAdapterRunFile RemoteAdapterKind = "run-file"
RemoteAdapterRunProcess RemoteAdapterKind = "run-process"
RemoteAdapterDatabase RemoteAdapterKind = "database"
RemoteAdapterRCON RemoteAdapterKind = "rcon"
)
type RemoteAdapterDeclaration struct {
Key string
Kind RemoteAdapterKind
TargetKeys []string
Capabilities []string
TimeoutSeconds int
MaxAttempts int
}
type RemoteAdapterRequest struct {
ServerInstanceID string
DeclarationKey string
TargetKey string
Capability string
TimeoutSeconds int
MaxAttempts int
IdempotencyKey string
}
type RemoteAdapterResult struct {
RequestID string
ServerInstanceID string
DeclarationKey string
TargetKey string
Kind RemoteAdapterKind
Status string
Retryable bool
Message string
ResultRef string
AuditEventID string
CompletedAt time.Time
}
func CopyMetricSample(sample MetricSample) MetricSample {
sample.PlayerCount = copyIntPtr(sample.PlayerCount)
sample.MaxPlayers = copyIntPtr(sample.MaxPlayers)
sample.TPS = copyFloatPtr(sample.TPS)
sample.LatencyMS = copyFloatPtr(sample.LatencyMS)
sample.CPUPercent = copyFloatPtr(sample.CPUPercent)
sample.MemoryPercent = copyFloatPtr(sample.MemoryPercent)
sample.DiskPercent = copyFloatPtr(sample.DiskPercent)
return sample
}
func copyIntPtr(value *int) *int {
if value == nil {
return nil
}
copy := *value
return &copy
}
func copyFloatPtr(value *float64) *float64 {
if value == nil {
return nil
}
copy := *value
return &copy
}
func CopyMetricSamples(samples []MetricSample) []MetricSample {
if samples == nil {
return nil
}
out := make([]MetricSample, len(samples))
for i, sample := range samples {
out[i] = CopyMetricSample(sample)
}
return out
}
func CopyMetricBatchIngest(batch MetricBatchIngest) MetricBatchIngest {
batch.Samples = CopyMetricSamples(batch.Samples)
return batch
}
func CopyBackupRecord(record BackupRecord) BackupRecord { return record }
func CopyBackupRecords(records []BackupRecord) []BackupRecord {
if records == nil {
return nil
}
out := make([]BackupRecord, len(records))
copy(out, records)
return out
}
func CopyRemoteAdapterDeclaration(declaration RemoteAdapterDeclaration) RemoteAdapterDeclaration {
declaration.TargetKeys = CopyStringSlice(declaration.TargetKeys)
declaration.Capabilities = CopyStringSlice(declaration.Capabilities)
return declaration
}
func CopyRemoteAdapterDeclarations(declarations []RemoteAdapterDeclaration) []RemoteAdapterDeclaration {
if declarations == nil {
return nil
}
out := make([]RemoteAdapterDeclaration, len(declarations))
for i, declaration := range declarations {
out[i] = CopyRemoteAdapterDeclaration(declaration)
}
return out
}
func CopyRemoteAdapterRequest(request RemoteAdapterRequest) RemoteAdapterRequest { return request }
func CopyRemoteAdapterResult(result RemoteAdapterResult) RemoteAdapterResult { return result }
+390 -36
View File
@@ -81,6 +81,7 @@ const (
JobStateQueued JobState = "queued"
JobStateAccepted JobState = "accepted"
JobStateRunning JobState = "running"
JobStateRetrying JobState = "retrying"
JobStateSucceeded JobState = "succeeded"
JobStateFailed JobState = "failed"
JobStateCancelled JobState = "cancelled"
@@ -154,6 +155,19 @@ const (
DistributionJobStatusDenied DistributionJobStatus = "denied"
)
type RunUpdatePhase string
const (
RunUpdatePhaseQueued RunUpdatePhase = "queued"
RunUpdatePhaseDownloading RunUpdatePhase = "downloading"
RunUpdatePhaseStaged RunUpdatePhase = "staged"
RunUpdatePhaseRestartRequested RunUpdatePhase = "restart-requested"
RunUpdatePhaseActivating RunUpdatePhase = "activating"
RunUpdatePhaseSucceeded RunUpdatePhase = "succeeded"
RunUpdatePhaseRolledBack RunUpdatePhase = "rolled-back"
RunUpdatePhaseFailed RunUpdatePhase = "failed"
)
type LogStreamSource string
const (
@@ -227,6 +241,26 @@ type AuthSession struct {
User User
Status string
Message string
ExpiresAt time.Time
}
type AuthSessionStatus string
const (
AuthSessionStatusActive AuthSessionStatus = "active"
AuthSessionStatusRevoked AuthSessionStatus = "revoked"
)
type AuthSessionRecord struct {
ID string
UserID string
TokenHash string
Status AuthSessionStatus
Generation int
IssuedAt time.Time
ExpiresAt time.Time
LastSeenAt time.Time
RevokedAt time.Time
}
type AIProvider struct {
@@ -305,21 +339,126 @@ type GamePluginRemoteAccess struct {
LogTransfer bool
}
type GamePluginManifest struct {
ID string
Name string
Description string
Version string
type RuntimeTarget struct {
OS string
Arch string
}
type RuntimeDiscoveryProbe struct {
Key string
Kind string
TargetKey string
Required bool
Expected string
Platforms []string
}
type RuntimeLifecycleProfile struct {
Key string
Mode string
Capabilities []string
ActionRefs PluginLifecycleActions
TransportKeys []string
ClientManagerRef string
Platforms []string
}
type RuntimeDependencyProbe struct {
Key string
Kind string
TargetKey string
Required bool
MinimumVersion string
Platforms []string
}
type RuntimeInstallStep struct {
Type string
TargetKey string
PackageManager string
PackageName string
Version string
DownloadRef string
Checksum string
}
type RuntimeInstallPlan struct {
Key string
Title string
Platforms []string
Steps []RuntimeInstallStep
}
type RuntimeLogSource struct {
Key string
Kind string
TargetKey string
StreamKey string
CursorKind string
RetentionDays int
}
type RuntimeTransportProfile struct {
Key string
Kind string
Tags []string
Server GamePluginManifestServer
Bridge GamePluginBridge
TargetKey string
Capabilities []string
Permissions []string
Actions PluginLifecycleActions
Pages []GamePluginPage
AI GamePluginManifestAI
RemoteAccess GamePluginRemoteAccess
}
type RuntimeClientManagerProfile struct {
Key string
DisplayName string
Version string
RepositoryURL string
RevisionPolicy string
Branch string
Tag string
Revision string
SupportedTargets []RuntimeTarget
BuildSystem string
WorkspaceRef string
EntryRef string
ConfigTemplates []RuntimeConfigTemplate
OutputArtifacts []string
Deployment RuntimeClientManagerDeployment
Lifecycle RuntimeClientManagerLifecycle
Health RuntimeClientManagerHealth
Compatibility RuntimeClientManagerCompatibility
UpdatePolicy RuntimeClientManagerUpdatePolicy
}
type RuntimeConfigTemplate struct {
Key string
TemplateRef string
OutputRef string
}
type GamePluginRuntimeProfiles struct {
Discovery []RuntimeDiscoveryProbe
LifecycleProfiles []RuntimeLifecycleProfile
DependencyProbes []RuntimeDependencyProbe
InstallPlans []RuntimeInstallPlan
LogSources []RuntimeLogSource
TransportProfiles []RuntimeTransportProfile
ClientManagers []RuntimeClientManagerProfile
}
type GamePluginManifest struct {
ID string
Name string
Description string
Version string
Kind string
Tags []string
Server GamePluginManifestServer
Bridge GamePluginBridge
Capabilities []string
Permissions []string
Actions PluginLifecycleActions
Pages []GamePluginPage
AI GamePluginManifestAI
RemoteAccess GamePluginRemoteAccess
RuntimeProfiles GamePluginRuntimeProfiles
}
type GamePluginManifestRegistration struct {
@@ -346,6 +485,7 @@ type GamePlugin struct {
Tags []string
AIPurposes []string
RemoteAccess GamePluginRemoteAccess
RuntimeProfiles GamePluginRuntimeProfiles
ValidationViolations []string
Status GamePluginStatus
}
@@ -369,6 +509,7 @@ type PluginMarketplacePlugin struct {
Tags []string
AIPurposes []string
RemoteAccess GamePluginRemoteAccess
RuntimeProfiles GamePluginRuntimeProfiles
ValidationViolations []string
Status GamePluginStatus
Source string
@@ -437,17 +578,21 @@ type PluginBridgeExecuteResponse struct {
}
type ServerInstance struct {
ID string
PluginID string
PluginVersion string
RunEndpointID string
Name string
OwnerUserID string
AdminUserIDs []string
State ServerInstanceState
ConfigVersion int
CreatedAt time.Time
UpdatedAt time.Time
ID string
PluginID string
PluginVersion string
RunEndpointID string
Name string
OwnerUserID string
AdminUserIDs []string
State ServerInstanceState
ConfigVersion int
ConfigKey string
ConfigContent string
ConfigChecksum string
ConfigUpdatedAt time.Time
CreatedAt time.Time
UpdatedAt time.Time
}
type ServerInstanceUpdate struct {
@@ -482,6 +627,7 @@ type ServerConfig struct {
Format string
Key string
Content string
Checksum string
Source string
UpdatedAt time.Time
}
@@ -496,6 +642,7 @@ type ConfigDiffLine struct {
type ServerConfigDiffRequest struct {
ServerInstanceID string
ExpectedConfigVersion int
ExpectedChecksum string
Key string
ProposedContent string
ProposedContentInputRef string
@@ -504,6 +651,7 @@ type ServerConfigDiffRequest struct {
type ServerConfigDiffPreview struct {
ServerInstanceID string
ConfigVersion int
Checksum string
Key string
CurrentContent string
ProposedContent string
@@ -517,6 +665,7 @@ type ServerConfigDiffPreview struct {
type ServerConfigWriteApproval struct {
ServerInstanceID string
ExpectedConfigVersion int
ExpectedChecksum string
Key string
ProposedContent string
ProposedContentInputRef string
@@ -542,7 +691,9 @@ type FileOperationDispatchRequest struct {
Operation FileOperationKind
Key string
InputRef string
Content string
ExpectedConfigVersion int
ExpectedChecksum string
IdempotencyKey string
}
@@ -590,6 +741,8 @@ type RunEndpoint struct {
ID string
DisplayName string
Version string
Platform string
Architecture string
Status RunEndpointStatus
Capabilities []string
Capacity RunCapacity
@@ -601,19 +754,67 @@ type JobProgress struct {
Message string
}
type JobRetryPolicy struct {
MaxAttempts int
InitialBackoffSeconds int
MaxBackoffSeconds int
}
type JobExecutionInput struct {
WorkspaceScope string
Content string
ExpectedVersion int
ExpectedChecksum string
MaxReadBytes int
RemoteAdapterKey string
RemoteAdapterKind string
TimeoutSeconds int
}
type JobExecutionResult struct {
Kind string
ProcessState string
ExitClassification string
ExitCode int
Version int
Checksum string
SizeBytes int64
AuditSummary string
Content string
}
type Job struct {
ID string
ServerInstanceID string
RunEndpointID string
Capability string
TargetKey string
InputRef string
IdempotencyKey string
State JobState
Progress JobProgress
ResultRef string
CreatedAt time.Time
UpdatedAt time.Time
ID string
ServerInstanceID string
RunEndpointID string
Capability string
TargetKey string
InputRef string
IdempotencyKey string
State JobState
Progress JobProgress
ResultRef string
ExecutionInput JobExecutionInput
ExecutionResult JobExecutionResult
RetryPolicy JobRetryPolicy
Attempt int
QueueEligibleAt time.Time
NextAttemptAt time.Time
LeaseTokenHash string
LeaseSessionGen int
AckDeadlineAt time.Time
LeaseExpiresAt time.Time
LastProgressSeq uint64
CancelReason string
CancelRequestedAt time.Time
CancelCompletedAt time.Time
TerminalAt time.Time
TerminalFingerprint string
LastReconciledAt time.Time
ReconcileCount int
ReconcileOutcome string
CreatedAt time.Time
UpdatedAt time.Time
}
type Artifact struct {
@@ -631,6 +832,7 @@ type RuntimeBinding struct {
ID string
ServerInstanceID string
PluginID string
PluginVersion string
ProfileKey string
Mode string
Bindings map[string]string
@@ -640,6 +842,32 @@ type RuntimeBinding struct {
UpdatedAt time.Time
}
type RuntimeBindingUpdate struct {
ProfileKey string
Bindings map[string]string
}
type RuntimeBindingKeyView struct {
Key string
Required bool
Configured bool
Secret bool
}
type RuntimeBindingView struct {
ServerInstanceID string
PluginID string
ProfileKey string
Mode string
Configured bool
Keys []RuntimeBindingKeyView
MissingKeys []string
Status RuntimeBindingStatus
Reason string
CreatedAt time.Time
UpdatedAt time.Time
}
type EncryptedComponentKey struct {
ID string
ServerInstanceID string
@@ -679,6 +907,7 @@ type ClientManagerDistribution struct {
ServerInstanceID string
PluginID string
ProfileKey string
Version string
TargetOS string
TargetArch string
RepositoryURL string
@@ -703,6 +932,10 @@ type DependencyStatus struct {
State DependencyState
Required bool
InstallPlanKey string
PlanDigest string
JobID string
Evidence string
CompletedSteps int
Message string
CheckedAt time.Time
UpdatedAt time.Time
@@ -713,6 +946,7 @@ type ClientManagerBuildJob struct {
ServerInstanceID string
PluginID string
ProfileKey string
Version string
TargetOS string
TargetArch string
RepositoryURL string
@@ -732,9 +966,16 @@ type RunUpdateJob struct {
RunEndpointID string
ArtifactID string
Checksum string
TargetOS string
TargetArch string
TargetRelease string
PreviousVersion string
JobID string
IdempotencyKey string
Status DistributionJobStatus
Phase RunUpdatePhase
Message string
Rollback bool
CreatedAt time.Time
UpdatedAt time.Time
}
@@ -805,12 +1046,54 @@ type DependencyJobRequest struct {
ServerInstanceID string
ProbeKey string
InstallPlanKey string
PlanDigest string
TargetOS string
TargetArch string
IdempotencyKey string
Install bool
}
type DependencyProbeView struct {
Key string
Kind string
Required bool
MinimumVersion string
State DependencyState
Evidence string
InstallPlanKey string
}
type DependencyPlanStepView struct {
Type string
TargetKey string
PackageManager string
PackageName string
Version string
DownloadHost string
SizeBytes int64
}
type DependencyPlanView struct {
Key string
Title string
TargetOS string
TargetArch string
Digest string
Steps []DependencyPlanStepView
}
type DependencyCatalog struct {
ServerInstanceID string
PluginID string
PluginVersion string
ProfileKey string
TargetOS string
TargetArch string
Probes []DependencyProbeView
Plans []DependencyPlanView
UpdatedAt time.Time
}
type LogBackfillRequest struct {
ServerInstanceID string
SourceKey string
@@ -846,6 +1129,12 @@ type UserFilter struct {
Status UserStatus
}
type AuthSessionFilter struct {
UserID string
TokenHash string
Status AuthSessionStatus
}
type AIProviderFilter struct {
Kind AIProviderKind
Status AIProviderStatus
@@ -968,6 +1257,10 @@ func CopyUser(user User) User {
return user
}
func CopyAuthSessionRecord(session AuthSessionRecord) AuthSessionRecord {
return session
}
func CopyAIProvider(provider AIProvider) AIProvider {
provider.Models = CopyStringSlice(provider.Models)
return provider
@@ -992,6 +1285,7 @@ func CopyGamePlugin(plugin GamePlugin) GamePlugin {
plugin.Tags = CopyStringSlice(plugin.Tags)
plugin.AIPurposes = CopyStringSlice(plugin.AIPurposes)
plugin.RemoteAccess = CopyGamePluginRemoteAccess(plugin.RemoteAccess)
plugin.RuntimeProfiles = CopyGamePluginRuntimeProfiles(plugin.RuntimeProfiles)
plugin.ValidationViolations = CopyStringSlice(plugin.ValidationViolations)
return plugin
}
@@ -1005,6 +1299,7 @@ func CopyPluginMarketplacePlugin(plugin PluginMarketplacePlugin) PluginMarketpla
plugin.Tags = CopyStringSlice(plugin.Tags)
plugin.AIPurposes = CopyStringSlice(plugin.AIPurposes)
plugin.RemoteAccess = CopyGamePluginRemoteAccess(plugin.RemoteAccess)
plugin.RuntimeProfiles = CopyGamePluginRuntimeProfiles(plugin.RuntimeProfiles)
plugin.ValidationViolations = CopyStringSlice(plugin.ValidationViolations)
return plugin
}
@@ -1034,9 +1329,48 @@ func CopyGamePluginManifest(manifest GamePluginManifest) GamePluginManifest {
manifest.Pages = CopyGamePluginPageSlice(manifest.Pages)
manifest.AI.Purposes = CopyStringSlice(manifest.AI.Purposes)
manifest.RemoteAccess = CopyGamePluginRemoteAccess(manifest.RemoteAccess)
manifest.RuntimeProfiles = CopyGamePluginRuntimeProfiles(manifest.RuntimeProfiles)
return manifest
}
func CopyGamePluginRuntimeProfiles(profiles GamePluginRuntimeProfiles) GamePluginRuntimeProfiles {
profiles.Discovery = append([]RuntimeDiscoveryProbe(nil), profiles.Discovery...)
for i := range profiles.Discovery {
profiles.Discovery[i].Platforms = CopyStringSlice(profiles.Discovery[i].Platforms)
}
profiles.LifecycleProfiles = append([]RuntimeLifecycleProfile(nil), profiles.LifecycleProfiles...)
for i := range profiles.LifecycleProfiles {
profiles.LifecycleProfiles[i].Capabilities = CopyStringSlice(profiles.LifecycleProfiles[i].Capabilities)
profiles.LifecycleProfiles[i].TransportKeys = CopyStringSlice(profiles.LifecycleProfiles[i].TransportKeys)
profiles.LifecycleProfiles[i].Platforms = CopyStringSlice(profiles.LifecycleProfiles[i].Platforms)
}
profiles.DependencyProbes = append([]RuntimeDependencyProbe(nil), profiles.DependencyProbes...)
for i := range profiles.DependencyProbes {
profiles.DependencyProbes[i].Platforms = CopyStringSlice(profiles.DependencyProbes[i].Platforms)
}
profiles.InstallPlans = append([]RuntimeInstallPlan(nil), profiles.InstallPlans...)
for i := range profiles.InstallPlans {
profiles.InstallPlans[i].Platforms = CopyStringSlice(profiles.InstallPlans[i].Platforms)
profiles.InstallPlans[i].Steps = append([]RuntimeInstallStep(nil), profiles.InstallPlans[i].Steps...)
}
profiles.LogSources = append([]RuntimeLogSource(nil), profiles.LogSources...)
profiles.TransportProfiles = append([]RuntimeTransportProfile(nil), profiles.TransportProfiles...)
for i := range profiles.TransportProfiles {
profiles.TransportProfiles[i].Capabilities = CopyStringSlice(profiles.TransportProfiles[i].Capabilities)
}
profiles.ClientManagers = append([]RuntimeClientManagerProfile(nil), profiles.ClientManagers...)
for i := range profiles.ClientManagers {
profiles.ClientManagers[i].SupportedTargets = append([]RuntimeTarget(nil), profiles.ClientManagers[i].SupportedTargets...)
profiles.ClientManagers[i].ConfigTemplates = append([]RuntimeConfigTemplate(nil), profiles.ClientManagers[i].ConfigTemplates...)
profiles.ClientManagers[i].OutputArtifacts = CopyStringSlice(profiles.ClientManagers[i].OutputArtifacts)
profiles.ClientManagers[i].Deployment.Arguments = CopyStringSlice(profiles.ClientManagers[i].Deployment.Arguments)
profiles.ClientManagers[i].Deployment.RequiredRunCapabilities = CopyStringSlice(profiles.ClientManagers[i].Deployment.RequiredRunCapabilities)
profiles.ClientManagers[i].Lifecycle.Actions = CopyStringSlice(profiles.ClientManagers[i].Lifecycle.Actions)
profiles.ClientManagers[i].Health.RequiredCapabilities = CopyStringSlice(profiles.ClientManagers[i].Health.RequiredCapabilities)
}
return profiles
}
func CopyGamePluginRemoteAccess(remote GamePluginRemoteAccess) GamePluginRemoteAccess {
remote.Methods = CopyStringSlice(remote.Methods)
remote.RunCapabilities = CopyStringSlice(remote.RunCapabilities)
@@ -1148,6 +1482,17 @@ func CopyRuntimeBinding(binding RuntimeBinding) RuntimeBinding {
return binding
}
func CopyRuntimeBindingUpdate(update RuntimeBindingUpdate) RuntimeBindingUpdate {
update.Bindings = CopyStringMap(update.Bindings)
return update
}
func CopyRuntimeBindingView(view RuntimeBindingView) RuntimeBindingView {
view.Keys = append([]RuntimeBindingKeyView(nil), view.Keys...)
view.MissingKeys = CopyStringSlice(view.MissingKeys)
return view
}
func CopyEncryptedComponentKey(key EncryptedComponentKey) EncryptedComponentKey {
return key
}
@@ -1164,6 +1509,15 @@ func CopyDependencyStatus(status DependencyStatus) DependencyStatus {
return status
}
func CopyDependencyCatalog(catalog DependencyCatalog) DependencyCatalog {
catalog.Probes = append([]DependencyProbeView(nil), catalog.Probes...)
catalog.Plans = append([]DependencyPlanView(nil), catalog.Plans...)
for i := range catalog.Plans {
catalog.Plans[i].Steps = append([]DependencyPlanStepView(nil), catalog.Plans[i].Steps...)
}
return catalog
}
func CopyClientManagerBuildJob(job ClientManagerBuildJob) ClientManagerBuildJob {
return job
}
+21 -6
View File
@@ -5,7 +5,7 @@ This file defines the first platform resource contracts. Concrete Go domain stru
## Implemented Boundaries
- Domain constants centralize allowed status, state, provider kind, relay mode, artifact owner, storage backend, and audit result values.
- DTO responses expose `apiKeyRef` for AI providers but never raw key material.
- DTO responses expose AI-provider secret presence only (`apiKeyConfigured`), never the stored reference or raw key material.
- Model structs include JSON/database tags and explicit `TableName()` mappings for future persistence work.
- `platform/repo.NewFileStore` provides durable local metadata snapshots for platform startup, while `platform/repo.NewMemoryStore` provides deterministic in-memory repository behavior for unit tests and disposable local runs.
- Log stream metadata records the selected body backend. The current durable local body backend uses `local-segments`; future production adapters should target log-optimized stores such as `clickhouse`, `loki`, `opensearch`, or `elasticsearch` rather than row-per-line relational tables.
@@ -27,7 +27,8 @@ This file defines the first platform resource contracts. Concrete Go domain stru
- `name`: display name.
- `kind`: `openai-compatible`, `openai`, `claude`, `gemini`, `ollama`, or `custom`.
- `baseUrl`: provider or relay base URL.
- `apiKeyRef`: secret reference, never the raw key.
- `apiKeyRef`: platform-owned secret reference accepted on writes and never returned by response DTOs.
- `apiKeyConfigured`: response-only presence flag.
- `models`: allowed model IDs.
- `defaultModel`: optional default model.
- `relayMode`: `direct`, `relay`, or `local`.
@@ -87,18 +88,30 @@ Runtime profile and distribution permissions are declared by plugins, then gated
Run control hello can include server/component identity from a generated package config. When `serverInstanceId`, `pluginId`, `componentKind`, `componentKey`, and `keyGeneration` are present, platform authenticates the provided key against the current encrypted component key before issuing a session token. Stale generations after reset are rejected without returning raw key material.
Run sessions persist only a token hash, generation, status, expiry, capability fingerprint, signed-request policy, and bounded replay nonce history. Component-authenticated Run sessions require HMAC-SHA256 HTTP envelopes over method, path, timestamp, nonce, and request-body hash; timestamps outside five minutes and repeated nonces are rejected.
## AuthSessionRecord
- `tokenHash`: SHA-256 verifier; raw bearer tokens are never persisted.
- `userId`: owning user.
- `status`: `active` or `revoked`.
- `generation`: monotonically increasing user session generation.
- `issuedAt`, `expiresAt`, `lastSeenAt`, `revokedAt`: durable lifecycle timestamps.
## RuntimeBinding
- `id`: runtime binding ID.
- `serverInstanceId`: server instance using the binding.
- `pluginId`: installed plugin that declared the logical runtime profile.
- `pluginId` and `pluginVersion`: installed plugin contract that declared the logical runtime profile.
- `profileKey`: declared lifecycle/runtime profile key.
- `mode`: runtime mode such as `local-process`, `hosted-ftp-rcon`, `ftp-only`, or `custom-client`.
- `bindings`: logical binding keys to operator-provided settings.
- `missingKeys`: logical keys that must be completed before dependent actions are available.
- `status`: `complete`, `incomplete`, or `invalid`.
- `status`: `complete` or `incomplete`.
Bindings are used for action gating and run-side profile resolution. API responses and logs must use logical keys and safe reasons only; they must not expose raw host paths, direct sockets, FTP/RCON passwords, SQL DSNs, or component auth keys.
Installed `GamePlugin` records persist the validated manifest `runtimeProfiles` contract, including discovery, lifecycle, dependency/install, log, transport, and client-manager declarations. One server binding selects one declared lifecycle profile. Platform derives allowed and required logical keys; clients cannot assert `missingKeys` or `status`.
Bindings are used for action gating and future run-side profile resolution. File and MySQL metadata snapshots include them so a platform restart does not make a configured server appear complete or lose its selected profile. API responses expose only logical key names, configured/secret-backed flags, missing keys, and safe reasons. They never expose stored binding values, raw host paths, direct sockets, FTP/RCON passwords, SQL DSNs, component auth keys, or internal secret locations.
## Runtime Component Keys And Distributions
@@ -106,7 +119,7 @@ Bindings are used for action gating and run-side profile resolution. API respons
- `RunDistribution`: records a generated run package for one server, target OS/architecture, package format, artifact ID, checksum, key generation, secret ref, and status.
- `ClientManagerDistribution`: records a generated plugin-declared client-manager package with profile key, repository/source revision metadata, build job ID, artifact ID, checksum, key generation, secret ref, and status.
- `ClientManagerBuildJob`: records source checkout/build status, target platform, artifact ID, checksum, redacted build log ref, key generation, and status.
- `RunUpdateJob`: records platform-created run self-update orchestration with server, run endpoint, artifact ID, checksum, job ID, idempotency key, and status.
- `RunUpdateJob`: records platform-created Run self-update orchestration with server, endpoint, artifact ID/checksum, target and previous release, job/idempotency identity, `queued/downloading/staged/restart-requested/activating/succeeded/rolled-back/failed` phase, bounded message, rollback flag, and timestamps. Platform only projects success after a signed current-session post-reconciliation health report; terminal staging alone remains `restart-requested`.
Run and client-manager keys are isolated singleton credentials. Reset replaces the encrypted database value, increments generation, marks older distributions revoked, and requires regenerating and redeploying that component. API DTOs may expose key generation, fingerprint, status, artifact ID, checksum, job ID, and `secret://runtime-keys/.../current` refs, but never the raw key.
@@ -121,6 +134,8 @@ Run and client-manager keys are isolated singleton credentials. Reset replaces t
- `required`: whether the probe is required for the runtime profile.
- `installPlanKey`: optional typed install plan key.
- `message`: bounded safe status.
- `planDigest`: deterministic SHA-256 digest of the declared target-specific probe/plan and logical binding generation; install approval must match it exactly.
- `evidence`, `completedSteps`, `jobId`: bounded terminal execution projection; no command output, path, credential, or private binding is stored in the projection.
- `checkedAt`, `updatedAt`: observation times.
Dependency checks and installs are queued as run jobs with logical `dependencies/...` or `dependencies/install/...` target keys. Install jobs must use typed plugin-declared plans and must not carry arbitrary shell snippets.
+7
View File
@@ -6,12 +6,14 @@ const (
ServerLifecycleActionCreate ServerLifecycleAction = "create"
ServerLifecycleActionStart ServerLifecycleAction = "start"
ServerLifecycleActionStop ServerLifecycleAction = "stop"
ServerLifecycleActionStatus ServerLifecycleAction = "status"
)
const (
LifecycleCapabilityInstall = "process.install"
LifecycleCapabilityStart = "process.start"
LifecycleCapabilityStop = "process.stop"
LifecycleCapabilityStatus = "process.status"
)
type ServerLifecycleCreate struct {
@@ -21,6 +23,8 @@ type ServerLifecycleCreate struct {
Name string
OwnerUserID string
IdempotencyKey string
ProfileKey string
Bindings map[string]string
}
type ServerLifecycleCommand struct {
@@ -44,12 +48,15 @@ func LifecycleCapabilityForAction(action ServerLifecycleAction) string {
return LifecycleCapabilityStart
case ServerLifecycleActionStop:
return LifecycleCapabilityStop
case ServerLifecycleActionStatus:
return LifecycleCapabilityStatus
default:
return ""
}
}
func CopyServerLifecycleCreate(create ServerLifecycleCreate) ServerLifecycleCreate {
create.Bindings = CopyStringMap(create.Bindings)
return create
}