feat(storage): 统一二进制对象存储与公开错误
新增 Aliyun OSS 与 S3 协议、通道内重试和按优先级跨通道切换,保留 server-main 兼容与环境 OSS 内存通道。 将请求及结果中的 Base64、Data URI、Buffer、multipart 和内联二进制统一对象化,生产路径不再写入本机静态目录,历史本地资源仅保留只读兼容。 引入 PublicErrorV1 并统一 API、异步查询、兼容协议和失败回调的安全错误输出,同时补充迁移、管理端、指标、OpenAPI 与本地模拟验收。 验证:go test ./... -count=1;go vet ./...;pnpm lint;pnpm test;pnpm build;pnpm openapi;tests/ci/migrations-test.sh。
This commit is contained in:
+182
-16
@@ -3157,7 +3157,7 @@
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "创建文件存储通道,当前主要用于配置 server-main OpenAPI 上传通道。",
|
||||
"description": "创建 server-main OpenAPI、阿里云 OSS 或 S3 兼容文件存储通道。",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
@@ -3354,6 +3354,70 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/admin/system/file-storage/channels/{channelID}/test": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "对指定 OSS 或 S3 通道执行隔离的 Put、Head、Delete 探针,不返回凭据或对象键。",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"system"
|
||||
],
|
||||
"summary": "测试对象存储通道",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "文件存储通道 ID",
|
||||
"name": "channelID",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.FileStorageChannelTestResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "Forbidden",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
},
|
||||
"503": {
|
||||
"description": "Service Unavailable",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/httpapi.ErrorEnvelope"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/admin/system/file-storage/settings": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -6712,7 +6776,7 @@
|
||||
"BearerAuth": []
|
||||
}
|
||||
],
|
||||
"description": "上传文件到配置的文件存储通道;没有启用通道时回退到本地静态上传目录。单文件最大 256MiB。",
|
||||
"description": "上传文件到配置的对象存储通道;所有通道失败时返回标准化存储错误,不写入本机静态目录。单文件最大 256MiB。",
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
],
|
||||
@@ -11207,22 +11271,52 @@
|
||||
"httpapi.ErrorPayload": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"example": "retry_after"
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"example": "rate_limit"
|
||||
},
|
||||
"code": {
|
||||
"type": "string",
|
||||
"example": "rate_limit"
|
||||
},
|
||||
"httpStatus": {
|
||||
"type": "integer",
|
||||
"example": 429
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "invalid json body"
|
||||
},
|
||||
"param": {},
|
||||
"requestId": {
|
||||
"type": "string"
|
||||
},
|
||||
"retryAfterSeconds": {
|
||||
"type": "integer",
|
||||
"example": 2
|
||||
},
|
||||
"retryable": {
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
},
|
||||
"status": {
|
||||
"type": "integer",
|
||||
"example": 400
|
||||
},
|
||||
"taskId": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"example": "invalid_request_error"
|
||||
},
|
||||
"version": {
|
||||
"type": "string",
|
||||
"example": "v1"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -11237,6 +11331,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"httpapi.FileStorageChannelTestResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"deleteSucceeded": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"durationMs": {
|
||||
"type": "integer"
|
||||
},
|
||||
"headSucceeded": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"provider": {
|
||||
"type": "string"
|
||||
},
|
||||
"putSucceeded": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"httpapi.FileUploadData": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -11443,6 +11557,9 @@
|
||||
"example": 0
|
||||
},
|
||||
"data": {},
|
||||
"error": {
|
||||
"$ref": "#/definitions/publicerror.Error"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "SUCCEED"
|
||||
@@ -11620,6 +11737,9 @@
|
||||
"type": "string",
|
||||
"example": "invalid parameter"
|
||||
},
|
||||
"public_error": {
|
||||
"$ref": "#/definitions/publicerror.Error"
|
||||
},
|
||||
"request_id": {
|
||||
"type": "string"
|
||||
}
|
||||
@@ -12809,20 +12929,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"error": {
|
||||
"$ref": "#/definitions/httpapi.VolcesErrorPayload"
|
||||
}
|
||||
}
|
||||
},
|
||||
"httpapi.VolcesErrorPayload": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"example": "invalid_parameter"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "model is required"
|
||||
"$ref": "#/definitions/publicerror.Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -13323,6 +13430,41 @@
|
||||
"RevisionFailed"
|
||||
]
|
||||
},
|
||||
"publicerror.Error": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string"
|
||||
},
|
||||
"category": {
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
"httpStatus": {
|
||||
"type": "integer"
|
||||
},
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"requestId": {
|
||||
"type": "string"
|
||||
},
|
||||
"retryAfterSeconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"retryable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"taskId": {
|
||||
"type": "string"
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"runner.PortraitAssetCapability": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -13835,6 +13977,9 @@
|
||||
"type": "object",
|
||||
"additionalProperties": {}
|
||||
},
|
||||
"publicError": {
|
||||
"$ref": "#/definitions/publicerror.Error"
|
||||
},
|
||||
"remoteTaskId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -14771,6 +14916,15 @@
|
||||
"store.FileStorageChannelInput": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"accessKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"accessKeyId": {
|
||||
"type": "string"
|
||||
},
|
||||
"accessKeySecret": {
|
||||
"type": "string"
|
||||
},
|
||||
"apiKey": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -14800,6 +14954,12 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"secretKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"sessionToken": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -14971,6 +15131,9 @@
|
||||
"type": "object",
|
||||
"additionalProperties": {}
|
||||
},
|
||||
"publicError": {
|
||||
"$ref": "#/definitions/publicerror.Error"
|
||||
},
|
||||
"remoteTaskId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -16540,6 +16703,9 @@
|
||||
"providerModelName": {
|
||||
"type": "string"
|
||||
},
|
||||
"publicError": {
|
||||
"$ref": "#/definitions/publicerror.Error"
|
||||
},
|
||||
"queueKey": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user