diff --git a/CHANGELOG.md b/CHANGELOG.md index d231c2d..7bcdb71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,11 +26,12 @@ ### Fixed -- **同步过去的资源行指向来源实例的存储后端 id**:`storage:///minio:///` +- **同步过去的资源行指向来源实例的存储后端 id(定位符与独立列两处)**:`storage:///minio:///` 里的 `` 是来源 `storage_backends` 的主键,目标实例没有这条行。只换桶不改 id 时, 原版应用落回默认存储服务并拒绝整条路径(真实下载 500 `code 1007 invalid MinIO file path`)。现在写入前按"租户 + 目标桶名"在目标库解析后端 id, 写入与校验共用同一份行变换;解析不到就拒绝写入,不产出目标读不出来的定位符。 + `resources.storage_backend_id` 这一列同样要换(应用先按它找文件服务)。 - 指纹对空白敏感会让"同一份内容"两边算不出同一个值(PostgreSQL `to_jsonb::text` 带空格、Go `json.Marshal` 不带);指纹改为先 `json.Compact` 再摘要。 diff --git a/internal/releaseadapter/v071/library_production_target.go b/internal/releaseadapter/v071/library_production_target.go index 781221c..79a63fb 100644 --- a/internal/releaseadapter/v071/library_production_target.go +++ b/internal/releaseadapter/v071/library_production_target.go @@ -439,6 +439,21 @@ func (t *ProductionLibraryTarget) applyResourceBucket(row map[string]json.RawMes return err } row["physical_path"] = encoded + // 原版应用先按 resources.storage_backend_id 找存储后端,再回落到 KB,再落默认服务。 + // 这一列留着来源 id,目标仍然 500(真跑:storage backend not found → invalid path)。 + if t.storageBackend == "" { + return nil + } + if raw, ok := row["storage_backend_id"]; ok { + var current string + if json.Unmarshal(raw, ¤t) == nil && current != "" && current != t.storageBackend { + encodedBackend, err := json.Marshal(t.storageBackend) + if err != nil { + return err + } + row["storage_backend_id"] = encodedBackend + } + } return nil } diff --git a/internal/releaseadapter/v071/resource_locator_test.go b/internal/releaseadapter/v071/resource_locator_test.go index 7c3c2bc..a504e97 100644 --- a/internal/releaseadapter/v071/resource_locator_test.go +++ b/internal/releaseadapter/v071/resource_locator_test.go @@ -73,3 +73,24 @@ func TestResourceRowTransformRewritesBackendAndBucket(t *testing.T) { t.Fatalf("transform=%q", got) } } + +// 存储后端 id 在 resources 表里还有独立一列:原版应用按它找文件服务。 +// 只改定位符不改这一列,目标仍是 storage backend not found(真跑 500)。 +func TestResourceRowTransformRewritesBackendColumn(t *testing.T) { + target := &ProductionLibraryTarget{config: ProductionLibraryConfig{ObjectsBucket: "kgseal-1029a"}, + storageBackend: "target-backend"} + row := map[string]json.RawMessage{ + "physical_path": json.RawMessage(`"storage://source-backend/minio://kgmaint-1028a/1/k/ab.md"`), + "storage_backend_id": json.RawMessage(`"source-backend"`), + } + if err := target.rowTransform("resources")(row); err != nil { + t.Fatalf("row transform failed: %v", err) + } + var backend string + if err := json.Unmarshal(row["storage_backend_id"], &backend); err != nil { + t.Fatal(err) + } + if backend != "target-backend" { + t.Fatalf("storage_backend_id=%q", backend) + } +}