
Backstage Scaffolder 任务恢复GCS Bucket 工作区存储配置迁移与实现解析【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage本文聚焦 Backstage Scaffolder 任务恢复Task Recovery功能中 GCSGoogle Cloud Storage工作区存储的配置演进以backstage/plugin-scaffolder-backend-module-gcp新增的scaffolder.taskRecovery.gcsBucket.name配置路径为核心说明其与旧实验配置EXPERIMENTAL_workspaceSerializationGcpBucketName的兼容回退关系并结合仓库源码讲解工作区序列化、恢复与错误传播的底层实现帮助你在生产环境正确配置并升级 GCS 工作区存储。背景任务恢复为什么需要工作区存储Backstage Scaffolder 的任务恢复Task Recovery功能允许崩溃或超时的任务自动恢复并从最后一个已完成的步骤继续执行。要实现这一点任务的工作区workspace即任务执行过程中生成的文件目录必须被序列化持久化才能在任务重新运行时被还原。根据仓库中的功能变更说明 .changeset/task-recovery-feature.md任务恢复由新的scaffolder.taskRecovery配置段控制它整合了此前分散的实验开关EXPERIMENTAL_recoverTasks、EXPERIMENTAL_workspaceSerialization、EXPERIMENTAL_recoverTasksTimeout这些旧开关仍作为回退继续受支持。同时工作区序列化从任务存储中拆分为独立的 Workspace Provider 模块开发环境推荐使用backstage/plugin-scaffolder-backend-module-workspace-database数据库存储约 50 MB 上限不建议生产使用生产环境推荐使用backstage/plugin-scaffolder-backend-module-gcp或类似的外部存储 ProviderScaffolder 会拒绝使用一个已配置但未安装注册的 Provider。backstage/plugin-scaffolder-backend-module-gcp正是承担GCS 桶存储序列化工作区职责的模块其入口文档见 plugins/scaffolder-backend-module-gcp/README.md。新增配置路径scaffolder.taskRecovery.gcsBucket.name本变更的核心是为 GCS 工作区 Provider 新增了一个正式、结构化的配置路径scaffolder.taskRecovery.gcsBucket.name用于指定存储序列化工作区的 GCS 桶名称。在app-config.yaml中配置如下scaffolder: taskRecovery: # 启用任务恢复 enabled: true # 选择 GCS 桶作为工作区存储 Provider workspaceProvider: gcpBucket gcsBucket: # 存储序列化工作区的 GCS 桶名称 name: my-backstage-scaffolder-workspaces配置结构的类型定义位于 plugins/scaffolder-backend-module-gcp/config.d.ts其中明确scaffolder.taskRecovery.gcsBucket.name类型为string用于存储序列化工作区的 GCS 桶名称标注为visibility backend属于后端敏感配置不会暴露给前端该配置仅在workspaceProvider设置为gcpBucket时生效旧的scaffolder.EXPERIMENTAL_workspaceSerializationGcpBucketName配置被标记为deprecated官方建议改用新的scaffolder.taskRecovery.gcsBucket.name。旧配置兼容回退与优先级为了平滑迁移旧的实验配置scaffolder.EXPERIMENTAL_workspaceSerializationGcpBucketName仍然受支持作为新配置缺失时的回退fallback。两者的优先级关系在源码中有明确实现见 GcpBucketWorkspaceProvider.tsprivate getGcpBucketName(): string { // New config path with fallback to old experimental flag const bucketName this.config?.getOptionalString( scaffolder.taskRecovery.gcsBucket.name, ) ?? this.config?.getOptionalString( scaffolder.EXPERIMENTAL_workspaceSerializationGcpBucketName, ); if (!bucketName) { throw new Error( Missing GCS bucket configuration. Set scaffolder.taskRecovery.gcsBucket.name in app-config.yaml, ); } return bucketName; }由此可以提炼出三条明确的读取规则新配置优先scaffolder.taskRecovery.gcsBucket.name存在时直接采用不会读取旧配置旧配置兜底新配置缺失时回退读取scaffolder.EXPERIMENTAL_workspaceSerializationGcpBucketName两者都缺失时抛错抛出 Missing GCS bucket configuration. Set scaffolder.taskRecovery.gcsBucket.name in app-config.yaml提示运维人员补全配置。桶名采用惰性读取lazy方式getGcpBucketName()只在真正执行桶操作上传、下载、清理时才会被调用因此 Provider 创建成功并不代表配置一定完整。让配置真正生效注册 GCS 模块仅有配置还不够——gcpBucketProvider 需要通过后端模块注册到 Scaffolder。模块实现在 plugins/scaffolder-backend-module-gcp/src/module.tsgcpBucketModule通过createBackendModule注册插件 ID 为scaffolder模块 ID 为gcp在初始化时通过scaffolderWorkspaceProviderExtensionPoint.addProviders({ gcpBucket: GcpBucketWorkspaceProvider.create(logger, config) })将gcpBucketProvider 提供给 Scaffolder 后端。因此在你的后端index.ts中需要显式安装该模块以新后端系统为例import { createBackend } from backstage/backend-defaults; import { gcpBucketModule } from backstage/plugin-scaffolder-backend-module-gcp; const backend createBackend(); // ... 其他插件与模块 backend.add(import(backstage/plugin-scaffolder-backend)); backend.add(gcpBucketModule); backend.start();如果只配置了workspaceProvider: gcpBucket却没有安装并注册该模块Scaffolder 会拒绝使用这个 Provider见 .changeset/task-recovery-feature.md 中的相关说明。源码级解析Provider 的三个核心操作GcpBucketWorkspaceProvider实现于 GcpBucketWorkspaceProvider.ts实现WorkspaceProvider接口用任务 IDtaskId作为 GCS 对象名提供三个核心方法1.serializeWorkspace序列化并上传工作区const { contents: workspace } await serializeWorkspace(options); await fileCloud.save(workspace, { contentType: application/x-tar, });将任务工作区目录序列化为 tar 归档contentType: application/x-tar然后以taskId为对象名上传到配置的 GCS 桶并记录日志Workspace for task ... has been serialized。2.rehydrateWorkspace下载并还原工作区先检查bucket.file(taskId)是否存在存在则通过file.createReadStream()读取原始内容getRawBody再调用restoreWorkspace将其还原到目标路径。3.cleanWorkspace清理工作区任务终态后删除桶中对应taskId的对象避免遗留数据持续占用存储。从实现可以推断GCS 桶中的对象命名直接复用任务 ID同一个任务的工作区在任意时刻在桶中只有一个对象生命周期由任务状态驱动。错误传播上传失败不再静默完成本次变更的另一个关键行为是工作区上传失败现在会被传播确保任务不会在缺少对应工作区的情况下记录已完成步骤。serializeWorkspace中上传失败时会抛出带上下文的ForwardedError来自backstage/errorsthrow new ForwardedError( Failed to upload workspace for task ${options.taskId} to GCS, error, );ForwardedError会保留原始错误作为cause同时补充任务 ID 与存储位置上下文便于排查根因。从结果上看一旦 GCS 上传失败任务步骤不会被标记为完成任务恢复流程也就不会在工作区实际上并未持久化的情况下继续避免了恢复后工作区缺失导致的数据不一致。对应测试位于 GcpBucketWorkspaceProvider.test.tsmockStorage.bucket().file().save抛错后断言serializeWorkspace拒绝并携带消息Failed to upload workspace for task test-task to GCS; caused by Error: GCS upload failed且cause指向原始上传错误验证了错误传播与上下文保留行为。配置读取行为测试迁移安全性验证GcpBucketWorkspaceProvider.test.ts 中针对配置读取覆盖了四类场景恰好对应迁移中需要验证的行为矩阵测试场景配置内容预期行为读取新配置路径scaffolder.taskRecovery.gcsBucket.name: my-new-bucketProvider 正常创建回退旧配置路径scaffolder.EXPERIMENTAL_workspaceSerializationGcpBucketName: my-legacy-bucketProvider 正常创建兼容旧配置新配置优先于旧配置新旧同时配置Provider 正常创建实际桶名以新配置为准在调用桶操作时体现完全缺失配置空配置{}调用桶操作时抛出 Missing GCS bucket configuration... 错误这些测试印证了迁移过程是平滑的已经使用旧实验配置的环境无需立即修改升级后依然可以工作同时鼓励运维人员尽快切换到新的正式配置路径。迁移建议与注意事项综合上述源码与配置证据迁移到新配置路径时建议按以下步骤操作检查当前配置若app-config.yaml中存在scaffolder.EXPERIMENTAL_workspaceSerializationGcpBucketName将其迁移为scaffolder.taskRecovery.gcsBucket.name两者并存时新配置生效确认 Provider 已注册确保后端安装了gcpBucketModule或等效的backstage/plugin-scaffolder-backend-module-gcp注册否则 Scaffolder 会拒绝使用该 Provider验证桶权限Provider 底层使用google-cloud/storage客户端new Storage()运行 Backstage 后端的服务账号需具备对目标桶的上传、下载与删除权限storage.objects.create/get/delete关注任务恢复的全局影响开启任务恢复作用于所有 Scaffolder 任务任务使用的 Action 应当幂等或使用 checkpoint禁用恢复默认时行为不变——任务被认领后即清除 secrets、重试会重新执行所有步骤见 .changeset/task-recovery-feature.md升级后观察日志正常工作区上传会输出Workspace for task taskId has been serialized日志若出现Failed to upload workspace for task taskId to GCS错误说明上传失败已被正确传播任务不会被错误标记为完成此时应优先排查桶名配置与 GCS 凭据。通过将工作区持久化到 GCS配合任务恢复机制Backstage 可以在进程崩溃或任务超时后从最后一个已完成步骤继续执行而新的结构化配置路径与错误传播机制则让生产环境的运维与排查变得更加可靠、可预期。【免费下载链接】backstageBackstage is an open framework for building developer portals项目地址: https://gitcode.com/GitHub_Trending/ba/backstage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考