Remove legacy client-manager workflows

This commit is contained in:
npc0-hue
2026-09-03 13:08:08 +08:00
parent bf3c382d15
commit fe09d21a56
56 changed files with 304 additions and 4121 deletions
+86 -27
View File
@@ -74,17 +74,6 @@ func (h *coreHandlers) register(mux *http.ServeMux) {
mux.HandleFunc("/api/v1/server-instances/{id}/run/download", h.serverRunDownload)
mux.HandleFunc("/api/v1/server-instances/{id}/run/key/reset", h.serverRunKeyReset)
mux.HandleFunc("/api/v1/server-instances/{id}/run/update", h.serverRunUpdate)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers/generate", h.serverClientManagerGenerate)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers/download", h.serverClientManagerDownload)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers/key/reset", h.serverClientManagerKeyReset)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers", h.serverClientManagerLifecycles)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers/{profileKey}", h.serverClientManagerLifecycleDetail)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers/deploy", h.serverClientManagerDeploy)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers/control", h.serverClientManagerControl)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers/update", h.serverClientManagerUpdateLifecycle)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers/retry", h.serverClientManagerRetry)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers/revoke-session", h.serverClientManagerRevokeSession)
mux.HandleFunc("/api/v1/server-instances/{id}/client-managers/uninstall", h.serverClientManagerUninstall)
mux.HandleFunc("/api/v1/server-instances/{id}/game-client-bridge", h.serverGameClientBridgeStatus)
mux.HandleFunc("/api/v1/server-instances/{id}/game-client-bridge/commands", h.serverGameClientBridgeCommands)
mux.HandleFunc("/api/v1/server-instances/{id}/game-client-bridge/commands/{commandId}/cancel", h.serverGameClientBridgeCommandCancel)
@@ -125,8 +114,6 @@ func (h *coreHandlers) register(mux *http.ServeMux) {
mux.HandleFunc("/api/v1/run/jobs/update-chunk", h.requireRunSignature(h.runJobUpdateChunk))
mux.HandleFunc("/api/v1/run/files/input-chunk", h.requireRunSignature(h.runFileInputChunk))
mux.HandleFunc("/api/v1/run/jobs/update-health", h.requireRunSignature(h.runJobUpdateHealth))
mux.HandleFunc("/api/v1/run/jobs/client-manager-input", h.requireRunSignature(h.runClientManagerLifecycleInput))
mux.HandleFunc("/api/v1/run/jobs/client-manager-chunk", h.requireRunSignature(h.runClientManagerLifecycleChunk))
mux.HandleFunc("/api/v1/run/jobs/cancel", h.requireRunSignature(h.runJobCancelPoll))
mux.HandleFunc("/api/v1/run/jobs/reconcile", h.requireRunSignature(h.runJobReconcile))
mux.HandleFunc("/api/v1/run/logs/batches", h.requireRunSignature(h.runLogBatchIngest))
@@ -148,14 +135,6 @@ func (h *coreHandlers) register(mux *http.ServeMux) {
mux.HandleFunc("/api/v1/log-streams", h.logStreams)
mux.HandleFunc("/api/v1/log-streams/query", h.logStreamQuery)
mux.HandleFunc("/api/v1/log-streams/{id}", h.logStreamDetail)
mux.HandleFunc("/api/v1/client-managers/register", h.clientManagerRegister)
mux.HandleFunc("/api/v1/client-managers/heartbeat", h.clientManagerHeartbeat)
mux.HandleFunc("/api/v1/game-client-bridge/companion/commands/claim", h.gameClientBridgeCompanionClaim)
mux.HandleFunc("/api/v1/game-client-bridge/companion/commands/{commandId}/ack", h.gameClientBridgeCompanionAck)
mux.HandleFunc("/api/v1/game-client-bridge/companion/commands/{commandId}/result", h.gameClientBridgeCompanionResult)
mux.HandleFunc("/api/v1/game-client-bridge/companion/logs/events", h.gameClientBridgeCompanionLogEvents)
mux.HandleFunc("/api/v1/game-client-bridge/companion/snapshots", h.gameClientBridgeCompanionSnapshot)
mux.HandleFunc("/api/v1/game-client-bridge/companion/diagnostics", h.gameClientBridgeCompanionDiagnostics)
}
// pluginLifecycles godoc
@@ -2208,9 +2187,15 @@ func (h *coreHandlers) runArtifactOpen(w http.ResponseWriter, r *http.Request) {
// @Summary Upload run artifact chunk
// @Description Accepts one bounded artifact chunk from a registered run endpoint and returns resumable acknowledgement state.
// @Tags run-artifacts
// @Accept json
// @Accept octet-stream
// @Produce json
// @Param body body dto.ArtifactChunkUploadRequest true "Artifact chunk upload request"
// @Param X-Artifact-Transfer-Id header string true "Artifact transfer ID"
// @Param X-Artifact-Id header string true "Artifact ID"
// @Param X-Artifact-Chunk-Index header int true "Chunk index"
// @Param X-Artifact-Offset header int true "Byte offset"
// @Param X-Artifact-Size header int true "Chunk size"
// @Param X-Artifact-Checksum header string true "Chunk sha256 checksum"
// @Param body body file true "Artifact chunk bytes"
// @Success 200 {object} dto.ArtifactChunkUploadResponse
// @Failure 400 {object} dto.ErrorResponse
// @Failure 404 {object} dto.ErrorResponse
@@ -2221,9 +2206,9 @@ func (h *coreHandlers) runArtifactChunkUpload(w http.ResponseWriter, r *http.Req
writeMethodNotAllowed(w, http.MethodPost)
return
}
request, err := decodeJSON[dto.ArtifactChunkUploadRequest](r)
request, err := decodeArtifactChunkUploadRequest(r)
if err != nil {
writeDecodeError(w, err)
writeServiceError(w, err)
return
}
result, err := h.core.UploadArtifactChunk(request.ToDomain())
@@ -2234,6 +2219,78 @@ func (h *coreHandlers) runArtifactChunkUpload(w http.ResponseWriter, r *http.Req
writeJSON(w, http.StatusOK, dto.ArtifactChunkUploadFromDomain(result))
}
const (
artifactTransferIDHeader = "X-Artifact-Transfer-Id"
artifactIDHeader = "X-Artifact-Id"
artifactChunkIndexHeader = "X-Artifact-Chunk-Index"
artifactChunkOffsetHeader = "X-Artifact-Offset"
artifactChunkSizeHeader = "X-Artifact-Size"
artifactChunkHashHeader = "X-Artifact-Checksum"
)
func decodeArtifactChunkUploadRequest(r *http.Request) (dto.ArtifactChunkUploadRequest, error) {
if !isOctetStream(r.Header.Get("Content-Type")) {
return dto.ArtifactChunkUploadRequest{}, validator.ValidationError{Violations: []string{"contentType must be application/octet-stream"}}
}
chunkIndex, err := parseRequiredIntHeader(r, artifactChunkIndexHeader)
if err != nil {
return dto.ArtifactChunkUploadRequest{}, err
}
offset, err := parseRequiredInt64Header(r, artifactChunkOffsetHeader)
if err != nil {
return dto.ArtifactChunkUploadRequest{}, err
}
sizeBytes, err := parseRequiredIntHeader(r, artifactChunkSizeHeader)
if err != nil {
return dto.ArtifactChunkUploadRequest{}, err
}
if sizeBytes <= 0 || sizeBytes > validator.MaxArtifactChunkBytes {
return dto.ArtifactChunkUploadRequest{}, validator.ValidationError{Violations: []string{fmt.Sprintf("%s must be between 1 and %d", artifactChunkSizeHeader, validator.MaxArtifactChunkBytes)}}
}
payload, err := io.ReadAll(io.LimitReader(r.Body, int64(validator.MaxArtifactChunkBytes)+1))
if err != nil {
return dto.ArtifactChunkUploadRequest{}, err
}
if len(payload) != sizeBytes {
return dto.ArtifactChunkUploadRequest{}, validator.ValidationError{Violations: []string{"request body size must match artifact chunk size"}}
}
return dto.ArtifactChunkUploadRequest{
RunEndpointID: strings.TrimSpace(r.Header.Get(runEndpointHeader)),
SessionToken: strings.TrimSpace(r.Header.Get(runSessionTokenHeader)),
TransferID: strings.TrimSpace(r.Header.Get(artifactTransferIDHeader)),
ArtifactID: strings.TrimSpace(r.Header.Get(artifactIDHeader)),
ChunkIndex: chunkIndex,
Offset: offset,
SizeBytes: sizeBytes,
Checksum: strings.TrimSpace(r.Header.Get(artifactChunkHashHeader)),
Payload: payload,
}, nil
}
func parseRequiredIntHeader(r *http.Request, name string) (int, error) {
value := strings.TrimSpace(r.Header.Get(name))
if value == "" {
return 0, validator.ValidationError{Violations: []string{name + " is required"}}
}
parsed, err := strconv.Atoi(value)
if err != nil {
return 0, validator.ValidationError{Violations: []string{name + " must be a number"}}
}
return parsed, nil
}
func parseRequiredInt64Header(r *http.Request, name string) (int64, error) {
value := strings.TrimSpace(r.Header.Get(name))
if value == "" {
return 0, validator.ValidationError{Violations: []string{name + " is required"}}
}
parsed, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return 0, validator.ValidationError{Violations: []string{name + " must be a number"}}
}
return parsed, nil
}
// runArtifactStatus godoc
// @Summary Query run artifact upload status
// @Description Returns resumable chunk acknowledgement state for one artifact transfer.
@@ -2597,11 +2654,13 @@ func (h *coreHandlers) artifactContent(w http.ResponseWriter, r *http.Request) {
writeServiceError(w, err)
return
}
content, err := h.core.ReadArtifactContentForSession(bearerToken(r), domain.ArtifactContentRequest{ArtifactID: r.PathValue("id"), Offset: offset, Limit: limit})
stream, err := h.core.OpenArtifactContentStreamForSession(bearerToken(r), domain.ArtifactContentRequest{ArtifactID: r.PathValue("id"), Offset: offset, Limit: limit})
if err != nil {
writeServiceError(w, err)
return
}
defer stream.Body.Close()
content := stream.Content
w.Header().Set("Content-Type", content.ContentType)
w.Header().Set("Content-Disposition", "attachment; filename=\""+strings.ReplaceAll(content.Filename, "\"", "")+"\"")
w.Header().Set("Accept-Ranges", "bytes")
@@ -2617,7 +2676,7 @@ func (h *coreHandlers) artifactContent(w http.ResponseWriter, r *http.Request) {
} else {
w.WriteHeader(http.StatusOK)
}
_, _ = w.Write(content.Payload)
_, _ = io.Copy(w, stream.Body)
}
func artifactRangeRequest(r *http.Request) (int64, int, error) {