chore: sync production runtime and docs
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
# 当前状态快照
|
||||
|
||||
更新时间:2026-04-25
|
||||
|
||||
## 1. 项目形态
|
||||
|
||||
当前项目已经形成以下稳定形态:
|
||||
|
||||
- 主界面仍然是地图工作区。
|
||||
- 顶级生产入口已经统一为“生产管理”。
|
||||
- “生产管理”同时包含:
|
||||
- D-InSAR 运行
|
||||
- 时序 InSAR 运行
|
||||
- D-InSAR 产物
|
||||
- 时序 InSAR 产物
|
||||
- 时序入口的前端显示名已经统一为“时序 InSAR”。
|
||||
- 当前时序链路默认接入的是 SBAS 实现,而不是传统 PS-InSAR 单一路径。
|
||||
|
||||
## 2. 当前生产引擎
|
||||
|
||||
### D-InSAR
|
||||
|
||||
- `sarscape`
|
||||
当前可用,已有 19 个发布产品进入 catalog。
|
||||
|
||||
- `isce2`
|
||||
已完成托管式接入,运行在 WSL 共享运行时中。
|
||||
|
||||
- `gamma / pyint`
|
||||
运行时接口与目录已经预留,后续可继续落生产设计。
|
||||
|
||||
### 时序 InSAR
|
||||
|
||||
- 当前产品名称统一为“时序 InSAR”。
|
||||
- 当前默认执行路径是 SBAS。
|
||||
- 后续可在该顶级入口下继续扩展 `psinsar`、`sbas-insar` 等类型。
|
||||
|
||||
## 3. 结果目录现状
|
||||
|
||||
当前结果目录已经统一收口到 `D:\production_results`:
|
||||
|
||||
```text
|
||||
D:\production_results
|
||||
├─ dinsar
|
||||
├─ timeseries
|
||||
└─ _quarantine
|
||||
```
|
||||
|
||||
当前健康检查中的目录状态:
|
||||
|
||||
- `D:\production_results\dinsar`
|
||||
存在,catalog 正常。
|
||||
|
||||
- `D:\production_results\timeseries`
|
||||
存在,catalog 正常。
|
||||
|
||||
- `D:\production_results\_quarantine`
|
||||
已作为统一隔离根目录纳入配置模型。
|
||||
|
||||
说明:
|
||||
|
||||
- `backend\result_products` 旧目录已经不是当前文件系统事实来源。
|
||||
- 数据库 `result_products` 表仍然保留,是发布产品登记表,不要与旧目录混淆。
|
||||
|
||||
## 4. 当前启动自维护链路
|
||||
|
||||
后端启动时会依次执行:
|
||||
|
||||
1. 数据库自维护
|
||||
2. SQLAlchemy 会话初始化
|
||||
3. 根目录登记同步
|
||||
4. manifest inventory 同步
|
||||
5. D-InSAR catalog 自举
|
||||
6. 时序 InSAR catalog 自举
|
||||
7. pairing cache 状态自举
|
||||
8. 启动健康检查
|
||||
|
||||
这说明当前系统已经不是“纯手工维护目录 + 手工修库”的模式,而是有稳定的启动自维护链路。
|
||||
|
||||
## 5. 2026-04-25 现场健康摘要
|
||||
|
||||
本次审计现场读取到的核心状态如下:
|
||||
|
||||
- 数据库:
|
||||
- `ok = true`
|
||||
- `schema_ok = true`
|
||||
- `postgis_ok = true`
|
||||
- `required_table_count = 42`
|
||||
|
||||
- D-InSAR catalog:
|
||||
- `storage_root = D:\production_results\dinsar`
|
||||
- `manifest_count = 19`
|
||||
- `db_count = 19`
|
||||
- `needs_rebuild = false`
|
||||
|
||||
- 时序 InSAR catalog:
|
||||
- `storage_root = D:\production_results\timeseries`
|
||||
- `manifest_count = 0`
|
||||
- `db_count = 0`
|
||||
- `needs_rebuild = false`
|
||||
|
||||
- 产品包:
|
||||
- `total_count = 19`
|
||||
- `canonical_schema = insar.product-package/v1`
|
||||
- 缺失 manifest / publish dir / processor / runtime / native output 均为 0
|
||||
|
||||
- WSL 共享运行时:
|
||||
- `shared_distro = Ubuntu-24.04`
|
||||
- `shared_conda_env_name = insar_wsl_v1`
|
||||
- `shared_python_path = /home/administrator/miniconda3/envs/insar_wsl_v1/bin/python`
|
||||
- `required_runtime_count = 2`
|
||||
- `healthy_runtime_count = 2`
|
||||
|
||||
- 配对系统:
|
||||
- `status = READY`
|
||||
- `scene_count = 1500`
|
||||
- `pair_count = 91737`
|
||||
- `dirty_scene_count = 0`
|
||||
|
||||
## 6. 现场源目录状态
|
||||
|
||||
当前健康检查确认以下源目录可访问:
|
||||
|
||||
- `D:\LuTan1_Image_Pool`
|
||||
- `D:\LT1_data_lsarorbit`
|
||||
- `D:\DInSARResult`
|
||||
|
||||
即当前 `source_roots` 为全绿状态,没有不可访问目录。
|
||||
|
||||
## 7. 当前数据库设计是否匹配
|
||||
|
||||
结论:
|
||||
|
||||
- 当前 ORM 与现场数据库匹配。
|
||||
- 当前 catalog、结果包、WSL 运行时和 pairing 状态与现有架构一致。
|
||||
- 当前数据库自维护机制适合现在这批“新增字段、统一结果目录、增加运行时登记”的改动。
|
||||
|
||||
边界:
|
||||
|
||||
- 它仍然只是“增量补齐型”自维护,不是全功能 migration 框架。
|
||||
- 如果后续要做字段改名、类型调整、约束重构,仍然需要显式迁移方案。
|
||||
|
||||
## 8. 当前最需要保持一致的事实
|
||||
|
||||
以下几件事已经是当前系统事实,后续文档和代码都应围绕它们展开:
|
||||
|
||||
- 顶级生产入口是“生产管理”,不是“生产规划”里的临时子入口。
|
||||
- 时序 InSAR 是顶级产品族,当前默认接入 SBAS。
|
||||
- 结果发布根目录是 `RESULT_PUBLISH_ROOT`,不是历史散落目录。
|
||||
- WSL 运行时是共享模型,当前共享环境为 `insar_wsl_v1`。
|
||||
- 数据库自维护默认保守,不自动做破坏性重建。
|
||||
@@ -0,0 +1,203 @@
|
||||
# 数据库自维护审计
|
||||
|
||||
审计日期:2026-04-25
|
||||
|
||||
## 1. 审计目标
|
||||
|
||||
本次审计关注两件事:
|
||||
|
||||
1. 当前数据库自维护机制,是否仍然符合现在的系统设计。
|
||||
2. 当前现场数据库,是否已经与现有 ORM / catalog / 运行时设计对齐。
|
||||
|
||||
## 2. 当前自维护机制实际做什么
|
||||
|
||||
代码入口位于 `backend/app/db_maintenance.py`,系统启动时由 `backend/app/main.py` 调用。
|
||||
|
||||
当前自维护能力包括:
|
||||
|
||||
- 自动创建 `postgis` 扩展
|
||||
- 自动创建缺失表
|
||||
- 自动补齐缺失列
|
||||
- 自动执行 `backend/migrations/001` 到 `006`
|
||||
- 自动引导管理员账号
|
||||
- 自动灌入灾害点数据
|
||||
|
||||
当前启动链路中的相关步骤:
|
||||
|
||||
1. `ensure_database_ready(...)`
|
||||
2. `database.init_db()`
|
||||
3. 根目录登记同步
|
||||
4. manifest inventory 同步
|
||||
5. D-InSAR / 时序 catalog 自举
|
||||
6. pairing state 自举
|
||||
7. 健康检查
|
||||
|
||||
## 3. 当前机制不做什么
|
||||
|
||||
当前实现不是完整迁移框架,它不会自动处理:
|
||||
|
||||
- 字段改名
|
||||
- 字段类型变更
|
||||
- 可空性从宽到严
|
||||
- 索引 / 约束漂移修补
|
||||
- 旧字段 / 旧表删除
|
||||
|
||||
破坏性重建只有在以下两个开关同时为 `true` 时才允许:
|
||||
|
||||
```env
|
||||
DB_SCHEMA_RESET_ON_MISMATCH=true
|
||||
DB_SCHEMA_RESET_CONFIRM=true
|
||||
```
|
||||
|
||||
默认情况下这是关闭的,符合当前内网生产环境“保守自维护”的要求。
|
||||
|
||||
## 4. 本次现场检查方法
|
||||
|
||||
本次检查直接用当前项目代码读取现场数据库并执行:
|
||||
|
||||
- `inspect_database_structure(...)`
|
||||
- `ensure_database_ready(settings.DATABASE_URL, bootstrap_admin=False, seed_hazard=False)`
|
||||
- `get_health_status(include_external=False, include_details=True, refresh=True)`
|
||||
|
||||
使用的是项目当前 `.env` 中配置的 Python 解释器和数据库连接。
|
||||
|
||||
## 5. 现场检查结果
|
||||
|
||||
### 5.1 schema 结构检查
|
||||
|
||||
结果:
|
||||
|
||||
- `mismatch = false`
|
||||
- `reason_count = 0`
|
||||
- `required_table_count = 42`
|
||||
- `missing_tables = []`
|
||||
- `extra_tables = []`
|
||||
- `missing_columns = {}`
|
||||
- `type_mismatches = []`
|
||||
- `nullable_mismatches = []`
|
||||
|
||||
结论:
|
||||
|
||||
- 现场数据库结构与当前 ORM 一致。
|
||||
- 当前新增的结果包、运行时、catalog 相关字段已经在数据库中落稳。
|
||||
|
||||
### 5.2 自维护执行结果
|
||||
|
||||
结果:
|
||||
|
||||
- `schema_reset = false`
|
||||
- `mismatch_detected = false`
|
||||
- `added_columns = []`
|
||||
- `bootstrap_initialized = false`
|
||||
|
||||
启动时仍会执行以下 SQL 文件:
|
||||
|
||||
- `001_st_intersection_agg.sql`
|
||||
- `002_spatial_functions.sql`
|
||||
- `003_pairing_enhancement.sql`
|
||||
- `004_pairing_refactor.sql`
|
||||
- `005_pairing_task_trace.sql`
|
||||
- `006_result_pairing_trace.sql`
|
||||
|
||||
结论:
|
||||
|
||||
- 当前数据库已处于“无需修补”的稳定状态。
|
||||
- 启动自维护仍会重复执行迁移 SQL,因此这些 SQL 文件必须继续保持幂等。
|
||||
|
||||
### 5.3 健康检查结果
|
||||
|
||||
结果摘要:
|
||||
|
||||
- `health.ok = true`
|
||||
- `database.ok = true`
|
||||
- `database.schema_ok = true`
|
||||
- `database.postgis_ok = true`
|
||||
- `dinsar_result_catalog.ok = true`
|
||||
- `timeseries_result_catalog.ok = true`
|
||||
- `dinsar_bridge.ok = true`
|
||||
- `source_roots.ok = true`
|
||||
- `product_packages.ok = true`
|
||||
- `wsl_runtime.ok = true`
|
||||
- `pairing_system.ok = true`
|
||||
|
||||
关键现场值:
|
||||
|
||||
- D-InSAR catalog:
|
||||
- `storage_root = D:\production_results\dinsar`
|
||||
- `manifest_count = 19`
|
||||
- `db_count = 19`
|
||||
|
||||
- 时序 InSAR catalog:
|
||||
- `storage_root = D:\production_results\timeseries`
|
||||
- `manifest_count = 0`
|
||||
- `db_count = 0`
|
||||
|
||||
- 产品包:
|
||||
- `total_count = 19`
|
||||
- `canonical_schema = insar.product-package/v1`
|
||||
- 所有缺失项计数均为 0
|
||||
|
||||
- WSL 共享运行时:
|
||||
- `shared_distro = Ubuntu-24.04`
|
||||
- `shared_conda_env_name = insar_wsl_v1`
|
||||
- `shared_python_path = /home/administrator/miniconda3/envs/insar_wsl_v1/bin/python`
|
||||
- `required_runtime_count = 2`
|
||||
- `healthy_runtime_count = 2`
|
||||
|
||||
## 6. 结论
|
||||
|
||||
结论很明确:
|
||||
|
||||
- 当前数据库自维护机制与当前系统状态相符。
|
||||
- 对于当前这轮改造引入的新增字段、catalog、结果包、WSL runtime 信息,它是足够的。
|
||||
- 当前现场数据库已经对齐当前 ORM 和结果目录设计。
|
||||
|
||||
这意味着:
|
||||
|
||||
- 现在可以继续在当前 schema 基础上推进 D-InSAR / 时序 InSAR 生产。
|
||||
- 不需要为了“数据库跟不上代码”而先清空库或强制重建。
|
||||
|
||||
## 7. 残余风险
|
||||
|
||||
虽然当前是对齐的,但仍有三个明确边界:
|
||||
|
||||
### 7.1 它不是 migration framework
|
||||
|
||||
后续如果要做以下改动,不能只靠当前自维护:
|
||||
|
||||
- 重命名字段
|
||||
- 修改字段类型
|
||||
- 增加更严格的非空约束
|
||||
- 重建索引或唯一约束
|
||||
- 删除旧结构
|
||||
|
||||
### 7.2 SQL 文件必须幂等
|
||||
|
||||
因为启动时会重复执行 `001` 到 `006`,任何新增 SQL 文件也必须遵守同样原则。
|
||||
|
||||
### 7.3 健康面板已成为设计约束的一部分
|
||||
|
||||
当前运维自检不只是“看数据库能不能连”,而是在验证:
|
||||
|
||||
- catalog 是否正常
|
||||
- product package 是否完整
|
||||
- WSL 运行时是否齐全
|
||||
- pairing trace 是否一致
|
||||
|
||||
因此后续只要改目录模型、结果包模型、运行时模型,就必须同步维护健康检查逻辑。
|
||||
|
||||
## 8. 建议
|
||||
|
||||
当前建议如下:
|
||||
|
||||
1. 保持 `DB_SCHEMA_RESET_ON_MISMATCH=false` 和 `DB_SCHEMA_RESET_CONFIRM=false`。
|
||||
2. 后续涉及 schema 破坏性调整时,单独编写受控迁移,不要指望启动自维护自动兜底。
|
||||
3. 新增数据库字段时,优先采用“可空 + 向后兼容 + 健康面板补校验”的方式推进。
|
||||
4. 每次结果目录、运行时 registry、catalog 设计变动后,都重新跑一次:
|
||||
- schema 检查
|
||||
- `ensure_database_ready(...)`
|
||||
- `GET /api/health`
|
||||
|
||||
## 9. 审计结语
|
||||
|
||||
截至 2026-04-25,数据库自维护机制与当前系统状态是匹配的,且现场数据库处于健康状态。当前更大的风险已经不在“数据库结构漂移”,而在后续若继续做结果模型或运行时模型重构时,是否同步维护 catalog、健康检查和文档。
|
||||
+252
-913
File diff suppressed because it is too large
Load Diff
+63
-92
@@ -1,117 +1,88 @@
|
||||
# 当前文档总览
|
||||
# 文档索引
|
||||
|
||||
这是 `docs/` 目录的统一入口文档。
|
||||
本索引用来区分“当前有效文档”和“历史参考文档”。
|
||||
|
||||
从现在开始,`docs/` 根目录只保留“当前仍在使用”的文档;历史过程材料、已完成实施记录、被新文档覆盖的旧方案,统一放入 `docs/archive/`。
|
||||
原则:
|
||||
|
||||
## 1. 当前有效文档
|
||||
- 以本页列为“当前有效”的文档,才作为现网架构、部署和运维的事实依据。
|
||||
- 没有列入“当前有效”区域的文档,默认只作为设计过程记录或历史参考。
|
||||
- 旧文档即使仍保留在 `docs/` 根目录,也不代表它仍然描述当前系统。
|
||||
|
||||
### 核心使用
|
||||
## 1. 当前有效
|
||||
|
||||
- **[README.md](../README.md)**
|
||||
系统主文档。优先阅读,包含整体功能、架构、快速开始和主要配置说明。
|
||||
- **[DEPLOYMENT.md](DEPLOYMENT.md)**
|
||||
部署与运维细节文档。适合正式部署、数据库初始化、服务启动和环境核对时使用。
|
||||
- **[PROJ_CONFIGURATION.md](PROJ_CONFIGURATION.md)**
|
||||
PROJ/GDAL 相关专项配置说明。只有在坐标转换或 PROJ 冲突时才需要单独查看。
|
||||
- [../README.md](../README.md)
|
||||
项目总览、当前架构和启动入口。
|
||||
|
||||
### 当前安全状态
|
||||
- [CURRENT_STATUS_20260425.md](CURRENT_STATUS_20260425.md)
|
||||
2026-04-25 的项目状态快照,包含结果目录、运行时、健康检查摘要。
|
||||
|
||||
- **[SECURITY_AUDIT_2026-03-12.md](SECURITY_AUDIT_2026-03-12.md)**
|
||||
当前有效的安全审计结论。已经把“开发机阶段可接受暴露”和“上线前必须修复的问题”分开说明,后续安全判断以这份为准。
|
||||
- [DEPLOYMENT.md](DEPLOYMENT.md)
|
||||
当前 Windows + PostgreSQL + WSL2 部署模型、环境变量和启动链路。
|
||||
|
||||
### 仍在推进的设计与任务
|
||||
- [DATABASE_SELF_MAINTENANCE_AUDIT_20260425.md](DATABASE_SELF_MAINTENANCE_AUDIT_20260425.md)
|
||||
当前数据库自维护机制与现场数据库一致性审计结果。
|
||||
|
||||
- **[DINSAR_ENHANCEMENT_TASKS.md](DINSAR_ENHANCEMENT_TASKS.md)**
|
||||
D-InSAR 多引擎生产增强与结果管理增强的总 Task 文档。覆盖前端架构、ENVI 六步链路、ISCE2 的 WSL 校验、运维自检与结果治理。
|
||||
- **[PAIRING_ENHANCEMENT_DESIGN.md](PAIRING_ENHANCEMENT_DESIGN.md)**
|
||||
配对能力增强设计。属于未完全落地的专项设计文档。
|
||||
- **[GAMMA_WSL2_INTEGRATION_PLAN.md](GAMMA_WSL2_INTEGRATION_PLAN.md)**
|
||||
GAMMA + WSL2 双引擎方案。属于后续扩展规划,不是当前默认运行链路。
|
||||
- **[PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md](PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md)**
|
||||
PyINT 生产引擎与 Gamma 精配对总体设计。明确现有多引擎架构下的接入边界、配置管理、数据库策略、运维自检扩展与前端入口分布。
|
||||
- **[PYINT_GAMMA_IMPLEMENTATION_TODO_20260418.md](PYINT_GAMMA_IMPLEMENTATION_TODO_20260418.md)**
|
||||
PyINT 生产引擎与 Gamma 精配对实施清单。按阶段拆分后端、前端、接口、运维与可选数据库任务,作为后续落地执行顺序。
|
||||
- **[PYINT_INPUT_ASSET_ADAPTATION_DESIGN_20260419.md](PYINT_INPUT_ASSET_ADAPTATION_DESIGN_20260419.md)**
|
||||
PyINT 输入资产适配设计。聚焦 `Task_*` 路径如何映射到 PyINT 工作区,以及 DEM、LT-1 精密轨道、运维自检和前端入口应如何纳入系统托管治理。
|
||||
- **[PYINT_LT1_COREG_ORBIT_HYPOTHESIS_EXPERIMENT_20260420.md](PYINT_LT1_COREG_ORBIT_HYPOTHESIS_EXPERIMENT_20260420.md)**
|
||||
LT-1 在 PyINT/Gamma 中 `coreg` 失败的轨道假设验证实验设计。固定输入和 DEM,只改变 `.slc.par` 的 state vector 处理方式,对照验证问题是否集中在导入后的轨道几何链条。
|
||||
- **[PYINT_LT1_DEM_GEOMETRY_CHAIN_EXPERIMENT_20260420.md](PYINT_LT1_DEM_GEOMETRY_CHAIN_EXPERIMENT_20260420.md)**
|
||||
LT-1 在 PyINT/Gamma 中 `init_offsetm` 失败的 DEM 几何链定位实验。聚焦 `HGTSIM / lt0 / mli0 / Samp` 的中间产物,区分 DEM 本体问题、DEM 几何映射链问题和中心 patch 选取问题。
|
||||
- **[WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md](WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md)**
|
||||
基于本机 `Ubuntu-24.04` WSL2、`isce2` / `mintpy` / `isce2_mintpy_v1` 实际环境核对后的 SBAS 集成落地方案,明确推荐运行时、workflow 补全顺序和正式产品边界。
|
||||
- **[ISCE2_SBAS_TIMESERIES_DESIGN.md](ISCE2_SBAS_TIMESERIES_DESIGN.md)**
|
||||
ISCE2 框架下 SBAS / 时序生产设计稿,说明如何从现有 `PS stack batch` 扩展到 `workflow + psinsar catalog` 的正式生产链路。
|
||||
- **[SBAS_PROGRESS_STATUS_20260406.md](SBAS_PROGRESS_STATUS_20260406.md)**
|
||||
SBAS 系统改造当前落地状态。优先查看这份文档以了解“已经做到哪一步、验证做到哪一步、下一步该补什么”。
|
||||
- **[SBAS_SYSTEM_INTEGRATION_AUDIT_20260406.md](SBAS_SYSTEM_INTEGRATION_AUDIT_20260406.md)**
|
||||
对现有系统接入 SBAS 的审计结果,聚焦现状缺口与最小可行接入点。
|
||||
- **[SBAS_SYSTEM_EMBEDDING_DESIGN_20260406.md](SBAS_SYSTEM_EMBEDDING_DESIGN_20260406.md)**
|
||||
SBAS 嵌入现有系统的详细设计稿,覆盖运行记录、作业编排、结果注册与前端页面边界。
|
||||
- **[SBAS_TASK_PATH_MODE_EVALUATION_20260406.md](SBAS_TASK_PATH_MODE_EVALUATION_20260406.md)**
|
||||
评估是否沿用现有 D-InSAR `task 路径 -> 生产` 模式,以及 SBAS 为什么必须增加 `prepare` 阶段。
|
||||
- **[SBAS_SYSTEM_CHANGE_RISK_ASSESSMENT_20260406.md](SBAS_SYSTEM_CHANGE_RISK_ASSESSMENT_20260406.md)**
|
||||
SBAS 系统改造风险评估,重点约束“新增不伤旧链”。
|
||||
- **[SBAS_RESULT_MANAGEMENT_AND_DISPLAY_SPEC_20260406.md](SBAS_RESULT_MANAGEMENT_AND_DISPLAY_SPEC_20260406.md)**
|
||||
SBAS 结果管理、编目和展示约定,明确发布级 bundle 与系统结果目录的关系。
|
||||
- **[SBAS_FRONTEND_UX_SPEC_20260406.md](SBAS_FRONTEND_UX_SPEC_20260406.md)**
|
||||
SBAS 生产页、结果页与分析页的前端交互设计。
|
||||
- **[SBAS_IMPLEMENTATION_TODO_20260406.md](SBAS_IMPLEMENTATION_TODO_20260406.md)**
|
||||
SBAS 系统改造任务清单,适合作为后续 Phase 2 / Phase 3 推进的执行列表。
|
||||
- [PROJ_CONFIGURATION.md](PROJ_CONFIGURATION.md)
|
||||
PROJ / GDAL 相关专项配置说明。
|
||||
|
||||
## 2. 已归档文档
|
||||
## 2. 当前执行中的核心设计
|
||||
|
||||
以下文档已移入 `docs/archive/`,原因通常是“历史记录”“已完成实施”或“被后续结论覆盖”。
|
||||
- [PRODUCTION_RESULTS_MULTI_ENGINE_DESIGN_20260423.md](PRODUCTION_RESULTS_MULTI_ENGINE_DESIGN_20260423.md)
|
||||
多引擎结果目录、发布结构和 catalog 治理设计。
|
||||
|
||||
### 本轮归档
|
||||
- [WSL_RUNTIME_REFACTOR_DESIGN_20260422.md](WSL_RUNTIME_REFACTOR_DESIGN_20260422.md)
|
||||
WSL 共享运行时和 Broker 设计。
|
||||
|
||||
- `SECURITY_AUDIT_2026-03-04.md`
|
||||
- `SECURITY_AUDIT_ANALYSIS_2026-03-04.md`
|
||||
- `SECURITY_FIX_PLAN.md`
|
||||
- `SECURITY_FIX_PROGRESS.md`
|
||||
- `SECURITY_FIX_CHECKLIST.md`
|
||||
- `SECURITY_FIX_STAGE1_SUMMARY.md`
|
||||
- `SECURITY_OVERVIEW.md`
|
||||
- `HARDCODE_AUDIT_2026-03-05.md`
|
||||
- `LOG_MANAGEMENT_IMPLEMENTATION_2026-03-05.md`
|
||||
- [ISCE2_MANAGED_DINSAR_IMPLEMENTATION_20260424.md](ISCE2_MANAGED_DINSAR_IMPLEMENTATION_20260424.md)
|
||||
ISCE2 托管式 D-InSAR 落地说明。
|
||||
|
||||
### 既有归档
|
||||
- [ISCE2_PRODUCTION_RELIABILITY_HARDENING_DESIGN_20260424.md](ISCE2_PRODUCTION_RELIABILITY_HARDENING_DESIGN_20260424.md)
|
||||
ISCE2 生产链路稳定性修补与约束。
|
||||
|
||||
`docs/archive/` 中原有的旧设计、旧 TODO、阶段性分析和历史修复记录继续保留,仅作历史参考,不再视为当前执行依据。
|
||||
- [DINSAR_ENHANCEMENT_TASKS.md](DINSAR_ENHANCEMENT_TASKS.md)
|
||||
D-InSAR 生产相关任务清单。
|
||||
|
||||
## 3. 建议阅读顺序
|
||||
## 3. 时序 InSAR / SBAS
|
||||
|
||||
### 新接手项目
|
||||
- [ISCE2_SBAS_TIMESERIES_DESIGN.md](ISCE2_SBAS_TIMESERIES_DESIGN.md)
|
||||
- [ISCE2_SBAS_PRODUCT_SPEC.md](ISCE2_SBAS_PRODUCT_SPEC.md)
|
||||
|
||||
1. 先读 [README.md](../README.md)
|
||||
2. 再读 [DEPLOYMENT.md](DEPLOYMENT.md)
|
||||
3. 若涉及上线前风险,再读 [SECURITY_AUDIT_2026-03-12.md](SECURITY_AUDIT_2026-03-12.md)
|
||||
说明:
|
||||
|
||||
### 正式部署
|
||||
- 当前前端顶级显示名已经统一为“时序 InSAR”。
|
||||
- 当前默认接入仍然是 SBAS 路径,因此这两份文档仍然有效。
|
||||
- `SBAS_*` 命名的一批旧文档大多是阶段性设计材料,不再作为总事实来源。
|
||||
|
||||
1. [README.md](../README.md)
|
||||
2. [DEPLOYMENT.md](DEPLOYMENT.md)
|
||||
3. [PROJ_CONFIGURATION.md](PROJ_CONFIGURATION.md)(仅在需要时)
|
||||
## 4. 配对与前端导航
|
||||
|
||||
### 后续功能规划
|
||||
- [PAIRING_ENHANCEMENT_DESIGN.md](PAIRING_ENHANCEMENT_DESIGN.md)
|
||||
- [PAIRING_SYSTEM_REFACTOR_PLAN_20260413.md](PAIRING_SYSTEM_REFACTOR_PLAN_20260413.md)
|
||||
- [FRONTEND_NAVIGATION_ARCHITECTURE.md](FRONTEND_NAVIGATION_ARCHITECTURE.md)
|
||||
|
||||
1. [DINSAR_ENHANCEMENT_TASKS.md](DINSAR_ENHANCEMENT_TASKS.md)
|
||||
2. [PAIRING_ENHANCEMENT_DESIGN.md](PAIRING_ENHANCEMENT_DESIGN.md)
|
||||
3. [PAIRING_SYSTEM_REFACTOR_PLAN_20260413.md](PAIRING_SYSTEM_REFACTOR_PLAN_20260413.md)
|
||||
4. [ISCE2_SBAS_TIMESERIES_DESIGN.md](ISCE2_SBAS_TIMESERIES_DESIGN.md)
|
||||
5. [WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md](WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md)
|
||||
6. [GAMMA_WSL2_INTEGRATION_PLAN.md](GAMMA_WSL2_INTEGRATION_PLAN.md)
|
||||
7. [PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md](PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md)
|
||||
8. [PYINT_GAMMA_IMPLEMENTATION_TODO_20260418.md](PYINT_GAMMA_IMPLEMENTATION_TODO_20260418.md)
|
||||
9. [PYINT_INPUT_ASSET_ADAPTATION_DESIGN_20260419.md](PYINT_INPUT_ASSET_ADAPTATION_DESIGN_20260419.md)
|
||||
10. [PYINT_LT1_COREG_ORBIT_HYPOTHESIS_EXPERIMENT_20260420.md](PYINT_LT1_COREG_ORBIT_HYPOTHESIS_EXPERIMENT_20260420.md)
|
||||
11. [PYINT_LT1_DEM_GEOMETRY_CHAIN_EXPERIMENT_20260420.md](PYINT_LT1_DEM_GEOMETRY_CHAIN_EXPERIMENT_20260420.md)
|
||||
## 5. Gamma / PyINT / WSL 预留
|
||||
|
||||
## 4. 后续维护规则
|
||||
- [GAMMA_WSL2_INTEGRATION_PLAN.md](GAMMA_WSL2_INTEGRATION_PLAN.md)
|
||||
- [PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md](PYINT_GAMMA_INTEGRATION_DESIGN_20260418.md)
|
||||
- [PYINT_INPUT_ASSET_ADAPTATION_DESIGN_20260419.md](PYINT_INPUT_ASSET_ADAPTATION_DESIGN_20260419.md)
|
||||
- [PYINT_GAMMA_AB_FINDINGS_20260420.md](PYINT_GAMMA_AB_FINDINGS_20260420.md)
|
||||
|
||||
- `docs/` 根目录只放当前有效文档。
|
||||
- 已完成实施总结、阶段性修复过程、旧审计分析、被覆盖方案,统一放入 `docs/archive/`。
|
||||
- 新增文档前,优先判断是否可以并入现有文档,避免再次堆出多份并行说明。
|
||||
- 如果某份文档只记录一次任务过程,而不是长期参考资料,不应继续留在根目录。
|
||||
说明:
|
||||
|
||||
**最后整理**:2026-03-13
|
||||
- 这部分主要作为 Gamma / PyINT 接入的预留设计和实验记录。
|
||||
- 真正的当前运行时事实,以 `WSL_RUNTIME_REFACTOR_DESIGN_20260422.md`、`.env` 和健康面板为准。
|
||||
|
||||
## 6. 安全与审计
|
||||
|
||||
- [SECURITY_AUDIT_2026-03-12.md](SECURITY_AUDIT_2026-03-12.md)
|
||||
|
||||
## 7. 历史参考
|
||||
|
||||
以下材料默认视为历史设计记录或过程文档:
|
||||
|
||||
- `docs/archive/`
|
||||
- `SBAS_*`
|
||||
- `WSL2_ISCE2_MINTPY_SBAS_INTEGRATION_PLAN_20260412.md`
|
||||
- `项目汇报.md`
|
||||
- 各类 `*_EXPERIMENT_*` / `*_PROGRESS_*` / `*_TODO_*`
|
||||
|
||||
最后更新:2026-04-25
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
# ISCE2 Managed D-InSAR Implementation 2026-04-24
|
||||
|
||||
## Scope
|
||||
|
||||
This document records the backend implementation that moves ISCE2 D-InSAR onto the same managed production lifecycle already used by ENVI.
|
||||
|
||||
The goal of this round is not to redesign the scientific core of ISCE2. The goal is to make ISCE2 production operationally healthy:
|
||||
|
||||
- submitted from the same production-management entry
|
||||
- tracked by the same run / item / execution tables
|
||||
- published into the same managed result tree
|
||||
- scanned by the same catalog rebuild path
|
||||
- compatible with database self-maintenance and health checks
|
||||
|
||||
## Implemented changes
|
||||
|
||||
### 1. Submission path
|
||||
|
||||
`/dinsar-production/run` now sends both `sarscape` and `isce2` through `dinsar_production_service.create_run(...)`.
|
||||
|
||||
This means ISCE2 no longer bypasses production management when it is launched from the normal UI entry.
|
||||
|
||||
### 2. Production run lifecycle
|
||||
|
||||
`dinsar_production_service.create_run(...)` now supports:
|
||||
|
||||
- `sarscape`
|
||||
- `isce2`
|
||||
|
||||
For ISCE2 it creates:
|
||||
|
||||
- `dinsar_production_runs`
|
||||
- `dinsar_production_run_items`
|
||||
- `dinsar_production_executions`
|
||||
- workflow steps with job type `ISCE2_RUN`
|
||||
|
||||
No schema migration was required for this round.
|
||||
|
||||
### 3. Managed ISCE2 controller
|
||||
|
||||
`JOB_TYPE_ISCE2_RUN` now has two modes:
|
||||
|
||||
- legacy queued mode: no `production_run_id`, keep the old shared queued handler
|
||||
- managed production mode: `production_run_id` present, use the new WSL production controller
|
||||
|
||||
The managed controller is responsible for:
|
||||
|
||||
- creating one execution row per selected task
|
||||
- forcing a managed run directory for each task
|
||||
- writing `execution_manifest.json`
|
||||
- writing `current/isce2__<profile>.json`
|
||||
- publishing successful run directories
|
||||
- rebuilding the result catalog after publish
|
||||
|
||||
### 4. Managed result layout
|
||||
|
||||
Each successful ISCE2 task now lands in the same managed D-InSAR tree as ENVI:
|
||||
|
||||
```text
|
||||
D:\production_results\dinsar\<pair_key>\
|
||||
current\
|
||||
isce2__lt1_stripmap.json
|
||||
runs\
|
||||
<run_key>\
|
||||
.dinsar_run.json
|
||||
execution_manifest.json
|
||||
manifest.json
|
||||
native\
|
||||
workflow\
|
||||
...
|
||||
export\
|
||||
<task>_disp.tif
|
||||
<task>_coh.tif
|
||||
assets\
|
||||
disp\
|
||||
disp.tif
|
||||
coh\
|
||||
coh.tif
|
||||
preview\
|
||||
thumb.webp
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- `native/` keeps the raw ISCE2 work and export outputs
|
||||
- `assets/` holds the standardized files consumed by the system
|
||||
- `manifest.json` is still written by `publish_from_sources(...)`
|
||||
- `result_products` rows are still created by `rebuild_catalog(...)`
|
||||
|
||||
### 5. ISCE2 layout normalization
|
||||
|
||||
`backend/app/services/dinsar_result_layout_service.py` now includes `normalize_isce2_run_layout(...)`.
|
||||
|
||||
Behavior:
|
||||
|
||||
- copy raw ISCE2 `*_disp.tif` into `assets/disp/disp.tif`
|
||||
- copy raw ISCE2 `*_coh.tif` into `assets/coh/coh.tif`
|
||||
- keep the raw files under `native/export`
|
||||
- rewrite run metadata / execution manifest / current pointer / package manifest when those files already exist
|
||||
|
||||
## Completion semantics
|
||||
|
||||
`rerun_mode=unfinished_only` for ISCE2 now checks the managed pointer:
|
||||
|
||||
```text
|
||||
<DINSAR_PRODUCT_DIR>\<pair_key>\current\isce2__<profile>.json
|
||||
```
|
||||
|
||||
This is intentional.
|
||||
|
||||
Legacy raw ISCE2 folders without a managed current pointer are no longer treated as a completed production result. That keeps skip logic aligned with production management rather than with stray historical outputs.
|
||||
|
||||
## Database and self-check compatibility
|
||||
|
||||
This implementation keeps the existing operational contract:
|
||||
|
||||
- no new tables
|
||||
- no destructive migration
|
||||
- no change to `result_products` / `result_assets` / `result_issues` schema
|
||||
- no change to `dinsar_production_runs` schema
|
||||
|
||||
Operational compatibility points:
|
||||
|
||||
- catalog state is still rooted at `settings.DINSAR_PRODUCT_DIR`
|
||||
- health checks still use the same catalog-state and manifest-tree logic
|
||||
- database self-maintenance still works because manifests remain canonical and catalog rebuild remains the only registration path
|
||||
|
||||
## Validation completed in this round
|
||||
|
||||
- syntax compilation in memory for the edited Python modules
|
||||
- direct module import validation for:
|
||||
- `backend.app.dinsar_engines.isce2_engine`
|
||||
- `backend.app.services.dinsar_result_layout_service`
|
||||
- `backend.app.services.dinsar_production_service`
|
||||
- `backend.app.routers.dinsar_production`
|
||||
- `backend.app.services.job_handlers`
|
||||
|
||||
## Remaining work
|
||||
|
||||
- add hard cancellation for an in-flight WSL subprocess
|
||||
- add Gamma D-InSAR on top of the same managed controller contract
|
||||
- decide whether `lt1_stripmap` should stay as the public profile code or be renamed in a later migration round
|
||||
@@ -0,0 +1,445 @@
|
||||
# ISCE2 生产可靠性加固设计 2026-04-24
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前 ISCE2 生产链路已经具备:
|
||||
|
||||
- 统一的 WSL runtime 入口
|
||||
- 共享 conda 环境 `insar_wsl_v1`
|
||||
- 结果发布到 `D:\production_results`
|
||||
- 统一 catalog / 自检 / 运维面板
|
||||
|
||||
但这条链路仍存在一个核心问题:
|
||||
|
||||
系统现在更像是“子进程执行器”,还不是“结果可靠性交付器”。
|
||||
|
||||
也就是说,当前成功判定主要依赖:
|
||||
|
||||
- WSL runner 返回码是否为 `0`
|
||||
- 输出目录是否存在
|
||||
- 自动发布阶段是否“尝试过”
|
||||
|
||||
这会导致几类假成功:
|
||||
|
||||
1. ISCE2 子进程返回 `0`,但没有形成可发布的主产物,任务仍显示完成。
|
||||
2. 历史运行只留下目录和 `.dinsar_run.json`,但主产物已损坏或缺失,“只跑未完成” 仍会跳过。
|
||||
3. 运维自检用的是一套路径规则,真实运行用的是另一套路径规则,面板和实际行为可能不一致。
|
||||
|
||||
本设计的目标不是重写 ISCE2 算法链,而是把 ISCE2 生产从“命令执行成功”收紧到“结果可验收、可发布、可重跑、可运维”。
|
||||
|
||||
## 2. 本轮范围
|
||||
|
||||
本轮只做可靠性加固,不做算法重写。
|
||||
|
||||
### 纳入本轮
|
||||
|
||||
- ISCE2 原生产结果的验收契约
|
||||
- “只跑未完成” 判定收紧
|
||||
- 自动发布阶段收紧
|
||||
- 健康检查与真实运行入口对齐
|
||||
- 文档、自检、日志字段同步
|
||||
|
||||
### 暂不纳入本轮
|
||||
|
||||
- stripmap/SNAPHU/PICKLE 恢复链的算法级改写
|
||||
- 与 ENVI/IDL 流水线逐步逐项数值对比
|
||||
- Gamma 生产实现细节
|
||||
- MintPy / 时序生产链的算法可靠性评估
|
||||
|
||||
## 3. 当前问题拆解
|
||||
|
||||
### 3.1 成功判定过宽
|
||||
|
||||
当前 `backend/app/dinsar_engines/isce2_engine.py` 中,单对任务成功主要由 `rc == 0` 决定。
|
||||
|
||||
现状后果:
|
||||
|
||||
- 只要 runner 没报错,就写入 `.dinsar_run.json`
|
||||
- 只要 `output_dir` 被加入 `output_dirs`,后续任务层就进入自动发布
|
||||
- 自动发布即使 `processed == 0`,任务最终仍可标记为 `COMPLETED`
|
||||
|
||||
这不符合“生产完成”的系统定义。
|
||||
|
||||
### 3.2 未完成重跑判定过宽
|
||||
|
||||
当前 `_has_completed_task_result()` 只看:
|
||||
|
||||
- 历史 `run_dir`
|
||||
- `.dinsar_run.json`
|
||||
- `output_dir` 目录存在
|
||||
|
||||
它不看:
|
||||
|
||||
- 主产物是否存在
|
||||
- 主产物是否可读
|
||||
- 该结果是否满足发布器识别规则
|
||||
|
||||
因此历史半成品会被误判为“已完成”。
|
||||
|
||||
### 3.3 健康检查与真实运行入口不一致
|
||||
|
||||
当前存在两套 stripmapApp 路径逻辑:
|
||||
|
||||
- 健康检查依赖 `ISCE2_STRIPMAP_APP`
|
||||
- 真正运行时在 WSL 内通过 `import isce` 动态定位
|
||||
|
||||
这会导致:
|
||||
|
||||
- 面板报错但实际能跑
|
||||
- 面板通过但实际解释器/包位置已经漂移
|
||||
|
||||
### 3.4 手工恢复链缺少显式边界
|
||||
|
||||
当前 `run_lt1_dinsar_pipeline.py` 通过复制 `PICKLE` 中文件并改写 XML 来衔接:
|
||||
|
||||
- `filter -> filter_high_band`
|
||||
- `unwrap -> ionosphere`
|
||||
|
||||
这条链路短期可用,但它对 ISCE2 内部文件结构有隐含依赖。
|
||||
|
||||
本轮不重写它,但必须把它从“隐式成功”改成“显式验收”。
|
||||
|
||||
## 4. 目标状态
|
||||
|
||||
ISCE2 生产链路调整后,系统对“完成”的定义变为:
|
||||
|
||||
1. WSL runner 执行完成。
|
||||
2. 原生产物通过本地验收。
|
||||
3. 验收通过的产物可被统一发布器识别。
|
||||
4. 自动发布成功写入标准包。
|
||||
5. 自检面板能看到 runtime、native output、publish package 三层状态一致。
|
||||
|
||||
换句话说:
|
||||
|
||||
- `rc == 0` 只表示“执行成功”
|
||||
- “任务完成” 必须是“执行成功 + 产物验收成功 + 发布链成功”
|
||||
|
||||
## 5. 具体改造方案
|
||||
|
||||
### 5.1 新增 ISCE2 原生产物验收层
|
||||
|
||||
新增一个独立验收模块,建议位置:
|
||||
|
||||
- `backend/app/services/isce2_result_validator.py`
|
||||
|
||||
职责:
|
||||
|
||||
- 不参与计算
|
||||
- 不参与数据库写入
|
||||
- 只负责判断一个 `output_dir` 是否是“可发布、可交付”的 ISCE2 原生结果
|
||||
|
||||
#### 输入
|
||||
|
||||
- `output_dir`
|
||||
- `task_alias`
|
||||
- `engine_code`
|
||||
- `profile_code`
|
||||
- `run_key`
|
||||
|
||||
#### 核心检查项
|
||||
|
||||
必选检查:
|
||||
|
||||
- `output_dir` 目录存在
|
||||
- 至少存在一个符合发布规则的主位移产物
|
||||
- 主产物文件大小大于 0
|
||||
- 主产物能被 GDAL 打开
|
||||
- 若存在配对的相干产品,则记录为辅助资产
|
||||
|
||||
建议主产物识别规则直接复用发布器当前的规则,避免两套规则分叉:
|
||||
|
||||
- `*_disp.tif`
|
||||
- 可选 `*_coh.tif`
|
||||
|
||||
#### 输出结构
|
||||
|
||||
返回统一 `acceptance_result`:
|
||||
|
||||
```json
|
||||
{
|
||||
"accepted": true,
|
||||
"primary_file": "D:/.../Task_xxx_disp.tif",
|
||||
"asset_files": [
|
||||
"D:/.../Task_xxx_disp.tif",
|
||||
"D:/.../Task_xxx_coh.tif"
|
||||
],
|
||||
"issues": [],
|
||||
"metrics": {
|
||||
"primary_exists": true,
|
||||
"primary_readable": true,
|
||||
"asset_count": 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 运行时行为
|
||||
|
||||
`isce2_engine.run()` 中:
|
||||
|
||||
- `rc != 0` 直接失败
|
||||
- `rc == 0` 后必须执行验收
|
||||
- 只有 `accepted == true` 才计入 `pairs_processed`
|
||||
- 只有验收通过的 `output_dir` 才进入 `output_dirs`
|
||||
|
||||
这样“runner 成功但没产物”的情况会被收口为失败。
|
||||
|
||||
### 5.2 收紧 `.dinsar_run.json` 语义
|
||||
|
||||
当前 `.dinsar_run.json` 只是运行元数据,需要补成“运行 + 验收”的统一侧写。
|
||||
|
||||
本轮不改数据库表结构,先改 sidecar 内容。
|
||||
|
||||
新增字段建议:
|
||||
|
||||
```json
|
||||
{
|
||||
"run_key": "run_xxx",
|
||||
"engine_code": "isce2",
|
||||
"profile_code": "lt1_stripmap",
|
||||
"runtime_id": "isce2_runtime_v1",
|
||||
"output_dir": "D:/.../native",
|
||||
"acceptance": {
|
||||
"accepted": true,
|
||||
"accepted_at": "2026-04-24T15:00:00Z",
|
||||
"primary_file": "D:/.../Task_xxx_disp.tif",
|
||||
"asset_files": [
|
||||
"D:/.../Task_xxx_disp.tif",
|
||||
"D:/.../Task_xxx_coh.tif"
|
||||
],
|
||||
"issues": [],
|
||||
"metrics": {
|
||||
"primary_exists": true,
|
||||
"primary_readable": true,
|
||||
"asset_count": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
原则:
|
||||
|
||||
- `.dinsar_run.json` 不再只表示“跑过”
|
||||
- 它要能表达“验收通过 / 未通过”
|
||||
|
||||
### 5.3 重写“只跑未完成”判定
|
||||
|
||||
将 `_has_completed_task_result()` 调整为 `_has_accepted_task_result()`。
|
||||
|
||||
新的跳过条件:
|
||||
|
||||
1. 历史 run 的 `.dinsar_run.json` 存在
|
||||
2. `engine_code / profile_code` 匹配当前请求
|
||||
3. `acceptance.accepted == true`
|
||||
4. `acceptance.primary_file` 存在且可读
|
||||
|
||||
只有满足以上条件,才视为“已完成”。
|
||||
|
||||
#### 不再采用的旧判断
|
||||
|
||||
- 仅凭 `output_dir` 存在
|
||||
- 仅凭 `.dinsar_run.json` 存在
|
||||
|
||||
#### 这样做的效果
|
||||
|
||||
- 目录空壳不会再被跳过
|
||||
- 历史损坏结果会重新进入生产
|
||||
- “只跑未完成” 的含义变成“只跳过已验收成功的对”
|
||||
|
||||
### 5.4 自动发布阶段从“尽力而为”改为“交付闭环”
|
||||
|
||||
当前自动发布逻辑即使 `processed == 0` 也只记日志。
|
||||
|
||||
本轮改为:
|
||||
|
||||
- 引擎层只把“已验收通过”的 `output_dir` 交给发布器
|
||||
- 任务层以“验收通过数量”作为发布期望值
|
||||
- 发布结果必须满足:
|
||||
- `processed == accepted_output_count`
|
||||
- `failed == 0`
|
||||
|
||||
若不满足,则任务整体失败。
|
||||
|
||||
#### 原则
|
||||
|
||||
- 自动发布不再是可有可无的附属步骤
|
||||
- 对托管生产来说,发布成功是交付定义的一部分
|
||||
|
||||
#### 失败语义
|
||||
|
||||
若 native output 已验收通过,但标准包发布失败:
|
||||
|
||||
- 任务状态标记为 `FAILED`
|
||||
- 保留 native output 目录
|
||||
- 日志明确写出:
|
||||
- accepted count
|
||||
- processed count
|
||||
- failed count
|
||||
|
||||
这样后续可以修发布器或手动重建 catalog,但不会再出现“任务完成却没有结果”的误导状态。
|
||||
|
||||
### 5.5 健康检查与真实运行入口统一
|
||||
|
||||
目标:只保留一套 runtime 事实来源。
|
||||
|
||||
#### 调整方向
|
||||
|
||||
`ISCE2_STRIPMAP_APP` 不再作为运行事实来源,只保留为兼容字段。
|
||||
|
||||
健康检查改成:
|
||||
|
||||
1. 从 `wsl_runtime_registry` 读取共享 Python
|
||||
2. 在对应 Python 中执行:
|
||||
|
||||
```python
|
||||
import isce
|
||||
from pathlib import Path
|
||||
print(Path(isce.__file__).resolve().parent / "applications" / "stripmapApp.py")
|
||||
```
|
||||
|
||||
3. 检查该路径是否存在
|
||||
4. 将解析出的真实路径回显到自检面板
|
||||
|
||||
#### 自检项调整
|
||||
|
||||
保留:
|
||||
|
||||
- WSL 可用
|
||||
- 共享 Python 可执行
|
||||
- `import isce` 成功
|
||||
- stripmapApp 动态解析成功
|
||||
- runner 脚本存在
|
||||
|
||||
弱化:
|
||||
|
||||
- 直接检查 `.env` 中的 `ISCE2_STRIPMAP_APP`
|
||||
|
||||
#### 自检返回建议新增字段
|
||||
|
||||
- `resolved_stripmap_app`
|
||||
- `resolved_isce_package_path`
|
||||
- `python_matches_shared`
|
||||
- `runtime_id`
|
||||
|
||||
### 5.6 数据库与自维护策略
|
||||
|
||||
本轮尽量不动数据库 schema。
|
||||
|
||||
原因:
|
||||
|
||||
- 当前问题核心在文件系统验收语义,不在表结构
|
||||
- 用户已经明确要求兼容数据库自维护与自检
|
||||
- 现阶段没有必要为了可靠性问题引入一轮 schema 变更风险
|
||||
|
||||
#### 本轮原则
|
||||
|
||||
- 不新增非必要列
|
||||
- 先把验收信息写入 `.dinsar_run.json`
|
||||
- 数据库继续通过现有 `result_products / result_assets / result_issues` 表表达发布结果
|
||||
|
||||
#### 若后续必须加列
|
||||
|
||||
只允许:
|
||||
|
||||
- nullable
|
||||
- 可由 `_add_missing_columns()` 自动补齐
|
||||
- 不要求清库
|
||||
|
||||
但这不属于本轮必须项。
|
||||
|
||||
### 5.7 运维自检扩展
|
||||
|
||||
为避免“native 有结果但 publish 不一致”的灰区,本轮建议在健康面板新增两个聚合视角。
|
||||
|
||||
#### 1. runtime 视角
|
||||
|
||||
- 共享 distro / Python / stripmapApp 动态解析是否一致
|
||||
|
||||
#### 2. product 视角
|
||||
|
||||
- 已入库产品是否存在 `native_output_dir`
|
||||
- `native_output_dir` 是否仍存在
|
||||
- `manifest_path` 是否存在
|
||||
|
||||
#### 3. 新增建议计数项
|
||||
|
||||
- `missing_native_output_count`
|
||||
- `missing_manifest_count`
|
||||
- `missing_runtime_count`
|
||||
|
||||
其中前两项已有基础,重点是让 ISCE2 runtime 检查结果和产品检查结果在面板里串起来。
|
||||
|
||||
## 6. 文件落点
|
||||
|
||||
### 核心代码
|
||||
|
||||
- `backend/app/dinsar_engines/isce2_engine.py`
|
||||
- `backend/app/services/job_handlers.py`
|
||||
- `backend/app/services/result_catalog_service.py`
|
||||
- `backend/app/services/health_service.py`
|
||||
- `backend/app/services/wsl_service.py`
|
||||
|
||||
### 新增模块
|
||||
|
||||
- `backend/app/services/isce2_result_validator.py`
|
||||
|
||||
### 文档与运维
|
||||
|
||||
- `docs/ISCE2_PRODUCTION_RELIABILITY_HARDENING_DESIGN_20260424.md`
|
||||
|
||||
## 7. 分阶段实施
|
||||
|
||||
### Phase 1: 成功判定收口
|
||||
|
||||
- 新增 `isce2_result_validator`
|
||||
- `rc == 0` 后执行验收
|
||||
- 未验收通过不写成功结果
|
||||
- `.dinsar_run.json` 补 `acceptance`
|
||||
|
||||
### Phase 2: 重跑语义收口
|
||||
|
||||
- `_has_completed_task_result()` 改为验收驱动
|
||||
- “只跑未完成” 只跳过已验收成功的结果
|
||||
|
||||
### Phase 3: 发布闭环收口
|
||||
|
||||
- 自动发布必须与验收通过数量对齐
|
||||
- `processed == 0` 不再仅告警,改为任务失败
|
||||
|
||||
### Phase 4: 自检对齐
|
||||
|
||||
- stripmapApp 改为动态解析检查
|
||||
- 面板展示 runtime 实际解析结果
|
||||
|
||||
### Phase 5: 后续科学性加固
|
||||
|
||||
不在本轮立即落地,但建议保留后续专题:
|
||||
|
||||
- PIKCLE 恢复链版本敏感性评估
|
||||
- bbox / geoPosting 的科学性收紧
|
||||
- 与 ENVI/IDL 基线链的阶段性对比
|
||||
|
||||
## 8. 验收标准
|
||||
|
||||
改造完成后,至少满足以下场景:
|
||||
|
||||
1. WSL runner 返回 `0`,但没有 `*_disp.tif`。
|
||||
- 结果:任务失败,不得显示完成。
|
||||
|
||||
2. 历史 run 目录仍在,但 `*_disp.tif` 已被删掉。
|
||||
- 结果:`只跑未完成` 不应跳过,应重新生产。
|
||||
|
||||
3. 健康面板显示 stripmapApp 路径。
|
||||
- 结果:必须来自共享 Python 动态解析,不再依赖旧硬编码。
|
||||
|
||||
4. native output 验收通过,但发布器没识别到包。
|
||||
- 结果:任务失败,日志明确指出 publish mismatch。
|
||||
|
||||
5. 自检面板与实际 runtime 使用的 Python / runner / runtime_id 一致。
|
||||
|
||||
## 9. 本轮结论
|
||||
|
||||
本轮实现不应该再把 ISCE2 生产理解为“跑完脚本”,而应理解为:
|
||||
|
||||
“执行成功 -> 原生结果验收通过 -> 标准包发布成功 -> 系统完成交付”。
|
||||
|
||||
先把这个闭环收紧,再谈后续算法科学性优化,顺序才是健康的。
|
||||
@@ -0,0 +1,388 @@
|
||||
# 多引擎生产结果管理与路径设计
|
||||
|
||||
更新日期:2026-04-24
|
||||
|
||||
## 1. 目标
|
||||
|
||||
本设计解决三个长期问题:
|
||||
|
||||
- 让 `ENVI / SARscape`、`ISCE2`、后续 `Gamma` 的原生输出可以共存,但系统只消费统一结果包。
|
||||
- 让生产、发布、catalog、数据库自维护、运维自检都围绕同一套受管理目录工作。
|
||||
- 让同一对影像可以保留多引擎、多 profile、多次重跑结果,而不会互相覆盖。
|
||||
|
||||
本设计不是要求所有引擎输出长得一样,而是要求系统托管的结果目录、指针、manifest 和数据库语义一致。
|
||||
|
||||
## 2. 核心原则
|
||||
|
||||
- 结果管理以“标准包”为中心,不以某个引擎的原生目录命名为中心。
|
||||
- 原生输出和系统发布资产必须分层,不能混在一起。
|
||||
- `pair_key` 或 `stack_key` 是业务稳定主键,`run_key` 或 `run_id` 是一次具体生产实例。
|
||||
- catalog 只扫描受管理发布根中的 `manifest.json`,不再把“历史扫描目录”和“正式生产目录”混用。
|
||||
- `current` 指针只在“验收通过并成功发布”后更新。
|
||||
- “只跑未完成”只看当前引擎和当前 profile 对应的 `current` 指针,不看裸目录是否存在。
|
||||
|
||||
## 3. 根路径设计
|
||||
|
||||
系统只保留一套正式受管理结果根:
|
||||
|
||||
```text
|
||||
D:\production_results\
|
||||
dinsar\
|
||||
timeseries\
|
||||
_quarantine\
|
||||
```
|
||||
|
||||
环境变量语义固定为:
|
||||
|
||||
- `RESULT_PUBLISH_ROOT`
|
||||
结果发布总根,默认 `D:\production_results`
|
||||
- `DINSAR_PRODUCT_DIR`
|
||||
D-InSAR 正式发布根,默认 `D:\production_results\dinsar`
|
||||
- `TIMESERIES_PRODUCT_DIR`
|
||||
时序 InSAR 正式发布根,默认 `D:\production_results\timeseries`
|
||||
- `RESULT_QUARANTINE_ROOT`
|
||||
结果隔离区,默认 `D:\production_results\_quarantine`
|
||||
|
||||
以下路径不再视为正式结果根:
|
||||
|
||||
- `MONITOR_DINSAR_DIRS`
|
||||
只保留为历史导入或兼容扫描入口,不再作为新生产的默认落盘位置
|
||||
- `Task_xxx\dinsar_results`
|
||||
只保留迁移期兼容语义,最终退出正式生产链
|
||||
|
||||
## 4. 目录分层
|
||||
|
||||
### 4.1 D-InSAR
|
||||
|
||||
```text
|
||||
D:\production_results\dinsar\<pair_key>\
|
||||
current\
|
||||
current.json
|
||||
sarscape__custom6.json
|
||||
isce2__lt1_dinsar_production_v1.json
|
||||
gamma__lt1_gamma_dinsar_v1.json
|
||||
runs\
|
||||
<run_key>\
|
||||
execution_manifest.json
|
||||
manifest.json
|
||||
native\
|
||||
...
|
||||
assets\
|
||||
disp\
|
||||
disp.tif
|
||||
coh\
|
||||
coh.tif
|
||||
preview\
|
||||
thumb.webp
|
||||
```
|
||||
|
||||
目录语义:
|
||||
|
||||
- `<pair_key>`
|
||||
同一对影像的稳定业务目录
|
||||
- `runs/<run_key>`
|
||||
一次具体生产
|
||||
- `native/`
|
||||
引擎原生输出,用于追溯、审计、复核,不直接作为系统消费入口
|
||||
- `assets/`
|
||||
系统统一消费的标准资产层
|
||||
- `manifest.json`
|
||||
正式 catalog 入库契约
|
||||
- `execution_manifest.json`
|
||||
生产执行记录
|
||||
- `current/*.json`
|
||||
当前可用结果指针
|
||||
|
||||
### 4.2 时序 InSAR
|
||||
|
||||
```text
|
||||
D:\production_results\timeseries\<stack_key>\
|
||||
current\
|
||||
current.json
|
||||
sbas__v1.json
|
||||
psinsar__v1.json
|
||||
runs\
|
||||
<run_id>\
|
||||
manifest.json
|
||||
native\
|
||||
...
|
||||
assets\
|
||||
...
|
||||
preview\
|
||||
thumb.webp
|
||||
```
|
||||
|
||||
这里沿用同一哲学,只是主键从 `pair_key` 换成 `stack_key`。
|
||||
|
||||
## 5. 指针设计
|
||||
|
||||
### 5.1 引擎级 current 指针
|
||||
|
||||
每个结果根都允许多个指针同时存在:
|
||||
|
||||
- `sarscape__custom6.json`
|
||||
- `isce2__lt1_dinsar_production_v1.json`
|
||||
- `gamma__lt1_gamma_dinsar_v1.json`
|
||||
|
||||
用途:
|
||||
|
||||
- 支持同一对影像保留多引擎结果
|
||||
- 支持前端按引擎切换结果
|
||||
- 支持“只跑未完成”按引擎和 profile 做跳过判断
|
||||
|
||||
### 5.2 默认 current 指针
|
||||
|
||||
`current.json` 不是必须立即启用。
|
||||
|
||||
建议语义:
|
||||
|
||||
- 只有在系统明确需要“默认展示结果”时才写入
|
||||
- 默认值由人工或策略层决定,而不是由最近一次运行自动覆盖
|
||||
|
||||
## 6. 原生输出与发布资产分层
|
||||
|
||||
这是本轮设计的关键约束。
|
||||
|
||||
### 6.1 原生输出层
|
||||
|
||||
原生输出层由引擎控制,但必须落到受管理 run 目录的 `native/` 下:
|
||||
|
||||
- ENVI / SARscape
|
||||
保留其成熟原生流程,但原生落盘最终收敛到 `native/`
|
||||
- ISCE2
|
||||
`stripmapApp` 原生输出、日志、中间文件全部进入 `native/`
|
||||
- Gamma
|
||||
后续接入时也遵循相同约束
|
||||
|
||||
### 6.2 标准资产层
|
||||
|
||||
系统统一暴露资产层:
|
||||
|
||||
- `assets/disp/disp.tif`
|
||||
- `assets/coh/coh.tif`
|
||||
- `preview/thumb.webp`
|
||||
|
||||
未来允许增加:
|
||||
|
||||
- `assets/conncomp/conncomp.tif`
|
||||
- `assets/debug/...`
|
||||
|
||||
但 catalog 识别仍以标准 `manifest.json` 为准,不直接猜原生文件结构。
|
||||
|
||||
## 7. D-InSAR 生产路径设计
|
||||
|
||||
### 7.1 生产服务拥有 run 根目录
|
||||
|
||||
对任意一个 `pair_key`,生产服务先创建稳定结果根:
|
||||
|
||||
```text
|
||||
<DINSAR_PRODUCT_DIR>\<pair_key>\runs\<run_key>\
|
||||
```
|
||||
|
||||
然后再把引擎执行和打包都约束到这个 run 目录下。
|
||||
|
||||
这意味着:
|
||||
|
||||
- `results_root_dir` 指向 `<DINSAR_PRODUCT_DIR>\<pair_key>`
|
||||
- `execution.output_dir` 指向 `<DINSAR_PRODUCT_DIR>\<pair_key>\runs\<run_key>`
|
||||
- 原生输出默认进入 `<run_dir>\native`
|
||||
|
||||
### 7.2 ISCE2 的路径设计
|
||||
|
||||
对正式生产链,`ISCE2_OUTPUT_ROOT` 不再承担“正式发布根”的职责。
|
||||
|
||||
建议语义调整为:
|
||||
|
||||
- `ISCE2_WORK_ROOT`
|
||||
仅用于调试、缓存、临时工作空间,或 standalone 调试运行
|
||||
- 正式生产时,由编排层直接下发 `<run_dir>\native` 作为原生输出目录
|
||||
- `ISCE2_OUTPUT_ROOT`
|
||||
只保留 fallback 含义,不再默认等于 `DINSAR_PRODUCT_DIR`
|
||||
|
||||
### 7.3 ENVI 的路径设计
|
||||
|
||||
ENVI 当前仍可能写入 `Task_xxx\dinsar_results`。迁移完成后应统一为:
|
||||
|
||||
- 原生结果写入 `<run_dir>\native`
|
||||
- 标准资产与 manifest 写入 `<run_dir>`
|
||||
|
||||
迁移期允许 packager 从历史目录导入,但这只是兼容,不再作为正式目标结构。
|
||||
|
||||
## 8. ISCE2 D-InSAR 生产设计约束
|
||||
|
||||
### 8.1 生产 profile
|
||||
|
||||
建议正式生产 profile 收敛为:
|
||||
|
||||
- `lt1_dinsar_production_v1`
|
||||
|
||||
不再为 ISCE2 复制 ENVI 的 `metatask/custom6` 形态。ISCE2 自己已经是成熟 orchestrator,项目层不应再人为拆成外部 6 步工作流。
|
||||
|
||||
### 8.2 流程边界
|
||||
|
||||
正式流程分四层:
|
||||
|
||||
1. `preflight`
|
||||
2. `native_isce2`
|
||||
3. `postprocess`
|
||||
4. `acceptance_publish`
|
||||
|
||||
其中:
|
||||
|
||||
- `preflight`
|
||||
负责解析主从影像、DEM、精轨、bbox、多视参数
|
||||
- `native_isce2`
|
||||
必须是一趟原生 `stripmapApp` 跑通到 geocode
|
||||
- `postprocess`
|
||||
负责位移导出、质量掩膜、稳定点精化、标准资产生成
|
||||
- `acceptance_publish`
|
||||
负责写 manifest、更新 current 指针、交给 catalog
|
||||
|
||||
### 8.3 参数设计
|
||||
|
||||
ISCE2 应继承 ENVI 已经验证过的工程经验,而不是机械复制 ENVI 步骤。
|
||||
|
||||
保留或新增的正式生产参数:
|
||||
|
||||
- `force`
|
||||
- `target_grid_size_m`
|
||||
- `bbox`
|
||||
- `bbox_margin`
|
||||
- `orbit_margin_sec`
|
||||
- `coh_threshold`
|
||||
- `unwrap_coh_threshold`
|
||||
- `stable_point_coh_threshold`
|
||||
- `stable_point_count`
|
||||
- `refinement_mode`
|
||||
|
||||
不建议前端暴露的参数:
|
||||
|
||||
- `wavelength`
|
||||
LT1 固定值,只读
|
||||
- `filter_method`
|
||||
v1 固定为工程默认值,不向前端开放高级切换
|
||||
|
||||
### 8.4 ENVI 经验映射
|
||||
|
||||
ENVI 现有工程经验中,值得保留的是:
|
||||
|
||||
- `target_resolution -> looks` 换算逻辑
|
||||
- 基于高相干稳定点的精化思想
|
||||
- 导出后再做稳定性等待与验收
|
||||
|
||||
不应该照搬的是:
|
||||
|
||||
- 把 ISCE2 拆成 ENVI 式的外部 6 步调度
|
||||
- 依赖扫目录“捞”中间文件来续跑
|
||||
|
||||
## 9. Catalog、数据库与自检
|
||||
|
||||
### 9.1 Catalog
|
||||
|
||||
catalog 只扫描:
|
||||
|
||||
- `DINSAR_PRODUCT_DIR`
|
||||
- `TIMESERIES_PRODUCT_DIR`
|
||||
|
||||
并且只认 `manifest.json`。
|
||||
|
||||
`MONITOR_DINSAR_DIRS` 不再参与正式 catalog rebuild,只保留外部导入用途。
|
||||
|
||||
### 9.2 数据库
|
||||
|
||||
现有数据库设计可以继续使用,不需要推倒重建:
|
||||
|
||||
- `result_products`
|
||||
- `result_assets`
|
||||
- `result_issues`
|
||||
- `result_catalog_states`
|
||||
- `dinsar_production_runs`
|
||||
- `dinsar_production_run_items`
|
||||
- `dinsar_production_executions`
|
||||
|
||||
约束:
|
||||
|
||||
- `results_root_dir` 继续指向 `<pair_key>` 根目录
|
||||
- `publish_root_dir` 继续指向 `DINSAR_PRODUCT_DIR`
|
||||
- `native_output_dir` 由 manifest 持久化
|
||||
- 启动自维护仍采用“增量补列,不破坏现有数据”的方式
|
||||
|
||||
### 9.3 运维自检
|
||||
|
||||
运维自检继续围绕 `storage_root` 工作,不围绕任务目录工作。
|
||||
|
||||
重点检查三层:
|
||||
|
||||
- 结果发布根是否存在
|
||||
- catalog 状态是否健康
|
||||
- manifest 数、数据库记录数、needs_rebuild 是否一致
|
||||
|
||||
后续再加两项专项检查:
|
||||
|
||||
- `product_packages`
|
||||
检查 manifest 契约和资产完整性
|
||||
- `wsl_runtime`
|
||||
检查 WSL shared runtime、Python、ISCE2/Gamma 入口一致性
|
||||
|
||||
## 10. 迁移顺序
|
||||
|
||||
### Phase 1
|
||||
|
||||
- 固化本设计
|
||||
- 不打断当前正在运行的 ENVI 生产
|
||||
- 仅允许文档、审计、只读检查
|
||||
|
||||
### Phase 2
|
||||
|
||||
- D-InSAR run 目录强制收敛到 `<pair_key>\runs\<run_key>`
|
||||
- 把引擎原生输出收敛到 `native/`
|
||||
- packager 只在 run 目录内生成标准资产和 manifest
|
||||
- current 指针更新改为“验收通过后再写”
|
||||
|
||||
### Phase 3
|
||||
|
||||
- ISCE2 正式 profile 切换到 `lt1_dinsar_production_v1`
|
||||
- 停止 synthetic resume 方案
|
||||
- 增加 preflight、稳定点精化、结果验收
|
||||
|
||||
### Phase 4
|
||||
|
||||
- ENVI 生产链迁移到同一结果结构
|
||||
- legacy `Task_xxx\dinsar_results` 退出正式生产路径
|
||||
|
||||
### Phase 5
|
||||
|
||||
- catalog rebuild
|
||||
- compat 视图同步
|
||||
- 运维自检补齐结果包专项检查
|
||||
|
||||
## 11. 当前执行约束
|
||||
|
||||
当前如果 ENVI 仍在生产中,以下修改必须等待生产结束后再做:
|
||||
|
||||
- 修改 `ISCE2_OUTPUT_ROOT` 默认语义
|
||||
- 修改 D-InSAR 生产 run 目录结构
|
||||
- 修改 current 指针判定逻辑
|
||||
- 修改 packager 输入路径和 in-place 规则
|
||||
- 修改 catalog rebuild 入口和默认扫描路径
|
||||
- 修改 ENVI 正式落盘位置
|
||||
|
||||
当前可以立即做的事情:
|
||||
|
||||
- 文档固化
|
||||
- 代码审计
|
||||
- 只读自检
|
||||
- 改造计划维护
|
||||
|
||||
原因很简单:本轮改造会动到结果路径、发布契约、跳过判定和指针语义。生产进行中切这些逻辑,风险不是“某个功能出错”,而是直接污染正在生成的结果根。
|
||||
|
||||
## 12. 结论
|
||||
|
||||
健康的方案不是让所有引擎“输出一样”,而是让系统消费的“受管理结果结构”一样。
|
||||
|
||||
这样之后:
|
||||
|
||||
- ENVI 可以继续保留自己的成熟原生算法链
|
||||
- ISCE2 可以按自己的原生工作流稳定生产
|
||||
- Gamma 接入时不需要再改目录哲学
|
||||
- 数据库自维护、catalog、自检、前端结果工作台都只围绕一套标准结果结构工作
|
||||
@@ -0,0 +1,274 @@
|
||||
# WSL Runtime 改造设计 2026-04-22
|
||||
|
||||
## 1. 背景
|
||||
|
||||
当前 `ISCE2` 与 `Gamma/PyINT` 的 WSL 执行存在三个根问题:
|
||||
|
||||
1. 执行边界仍是 shell 字符串,后端直接把命令交给 `wsl.exe ... bash -lc`。
|
||||
2. `.env` 直接持有 WSL Python、pipeline、Gamma 环境脚本等执行型配置,配置权和执行权耦合。
|
||||
3. WSL 内的 conda 环境没有被定义成正式运行时资产,实际运行依赖“当前机器上碰巧可用的环境”。
|
||||
|
||||
这会带来四类风险:
|
||||
|
||||
- 参数或路径一旦逃逸 quote,直接进入 shell 解释边界。
|
||||
- 引擎服务自己拼命令,执行治理无法集中落地。
|
||||
- `ISCE2` 和 `Gamma/PyINT` 虽然物理上可以共用一套 WSL/conda,但逻辑上没有独立运行时标识,审计和迁移困难。
|
||||
- WSL 环境漂移无法被健康检查和运维流程正式识别。
|
||||
|
||||
## 2. 目标
|
||||
|
||||
本次改造采用:
|
||||
|
||||
- 单 WSL distro
|
||||
- 单共享 conda env
|
||||
- 双逻辑 runtime
|
||||
- 单一 WSL broker 出口
|
||||
|
||||
目标形态:
|
||||
|
||||
```text
|
||||
业务服务
|
||||
-> Engine Adapter
|
||||
-> WslBroker
|
||||
-> RuntimeRegistry
|
||||
-> JobManifest
|
||||
-> WSL Runner
|
||||
-> shared conda env: insar_wsl_v1
|
||||
```
|
||||
|
||||
其中:
|
||||
|
||||
- `ISCE2` 使用 `isce2_runtime_v1`
|
||||
- `Gamma/PyINT` 使用 `gamma_pyint_runtime_v1`
|
||||
|
||||
二者可以共用:
|
||||
|
||||
- `WSL_DISTRO=Ubuntu-24.04`
|
||||
- `WSL_SHARED_CONDA_ENV=insar_wsl_v1`
|
||||
|
||||
但不能共用“逻辑运行时定义”。
|
||||
|
||||
## 3. 运行时模型
|
||||
|
||||
### 3.1 共享运行时
|
||||
|
||||
共享运行时负责:
|
||||
|
||||
- distro 选择
|
||||
- 共享 conda env 名称
|
||||
- 共享 Python 路径
|
||||
- broker 作业落盘目录
|
||||
|
||||
建议配置:
|
||||
|
||||
```env
|
||||
WSL_DISTRO=Ubuntu-24.04
|
||||
WSL_SHARED_CONDA_ENV=insar_wsl_v1
|
||||
WSL_SHARED_PYTHON=/home/administrator/miniconda3/envs/insar_wsl_v1/bin/python
|
||||
WSL_BROKER_JOB_ROOT=<backend/runtime/wsl_jobs>
|
||||
```
|
||||
|
||||
### 3.2 逻辑 runtime
|
||||
|
||||
每个逻辑 runtime 固定:
|
||||
|
||||
- `runtime_id`
|
||||
- `engine_code`
|
||||
- `runner`
|
||||
- `allowed_operations`
|
||||
- 固定 profile 路径
|
||||
- 固定审计标识
|
||||
|
||||
当前规划:
|
||||
|
||||
| runtime_id | engine | runner | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| `isce2_runtime_v1` | `isce2` | `deploy/wsl/runners/isce2_runner.py` | LT-1 条带 D-InSAR |
|
||||
| `gamma_pyint_runtime_v1` | `pyint` | `deploy/wsl/runners/gamma_pyint_runner.py` | Gamma / PyINT |
|
||||
|
||||
Gamma 固定 profile:
|
||||
|
||||
- `deploy/wsl/profiles/gamma_env.sh`
|
||||
|
||||
注意:Gamma profile 属于部署资产,不再建议继续由 `.env` 动态指定脚本路径。
|
||||
|
||||
## 4. 执行模型
|
||||
|
||||
### 4.1 Broker
|
||||
|
||||
Broker 负责:
|
||||
|
||||
- 解析 `runtime_id`
|
||||
- 写入结构化 `job manifest`
|
||||
- 生成固定 `argv`
|
||||
- 通过 `wsl.exe --exec` 执行 runner
|
||||
|
||||
禁止的旧模式:
|
||||
|
||||
- 服务层直接拼 `bash -lc "..."`
|
||||
- 服务层直接决定 `source` 哪个环境脚本
|
||||
- 服务层直接把 `.env` 中的 Python 绝对路径当成执行入口
|
||||
|
||||
### 4.2 Manifest
|
||||
|
||||
建议 manifest 固定包含:
|
||||
|
||||
- `job_id`
|
||||
- `runtime_id`
|
||||
- `engine_code`
|
||||
- `operation`
|
||||
- `created_at`
|
||||
- `payload`
|
||||
|
||||
payload 中再放:
|
||||
|
||||
- 输入路径
|
||||
- 工作路径
|
||||
- 输出路径
|
||||
- 参数
|
||||
- 操作人
|
||||
- 引擎内部业务上下文
|
||||
|
||||
### 4.3 Runner
|
||||
|
||||
Runner 是 WSL 内的固定可信入口。
|
||||
|
||||
阶段划分:
|
||||
|
||||
1. V1:只承担 manifest 读取、参数校验和 dry-run 输出
|
||||
2. V2:接入实际 pipeline / PyINT / Gamma
|
||||
3. V3:补齐固定 profile、版本指纹、错误分类与审计摘要
|
||||
|
||||
## 5. Conda 环境治理
|
||||
|
||||
### 5.1 基本原则
|
||||
|
||||
- 不原地继续污染旧环境
|
||||
- 先冻结现有环境
|
||||
- 再建立共享正式环境 `insar_wsl_v1`
|
||||
- 旧环境只保留回滚用途
|
||||
|
||||
### 5.2 版本资产
|
||||
|
||||
`deploy/wsl/conda/` 下至少维护:
|
||||
|
||||
- `insar_wsl_v1.environment.yml`
|
||||
- `insar_wsl_v1.explicit.lock`
|
||||
- `insar_wsl_v1.fingerprint.json`
|
||||
|
||||
说明:
|
||||
|
||||
- `environment.yml` 用于人工维护和审阅
|
||||
- `explicit.lock` 用于精确重建
|
||||
- `fingerprint.json` 用于健康检查、审计和漂移检测
|
||||
|
||||
### 5.3 Gamma
|
||||
|
||||
Gamma 通常不作为 conda 包管理。
|
||||
|
||||
因此建议:
|
||||
|
||||
- Gamma 以固定安装路径存在于 WSL
|
||||
- 由 `deploy/wsl/profiles/gamma_env.sh` 统一注入环境变量
|
||||
- 不再由 `.env` 直接提供动态 profile 路径
|
||||
|
||||
## 6. 配置迁移策略
|
||||
|
||||
### 6.1 新增配置
|
||||
|
||||
新增统一配置:
|
||||
|
||||
```env
|
||||
WSL_DISTRO=Ubuntu-24.04
|
||||
WSL_SHARED_CONDA_ENV=insar_wsl_v1
|
||||
WSL_SHARED_PYTHON=/home/administrator/miniconda3/envs/insar_wsl_v1/bin/python
|
||||
WSL_BROKER_JOB_ROOT=...
|
||||
ISCE2_RUNTIME_ID=isce2_runtime_v1
|
||||
PYINT_RUNTIME_ID=gamma_pyint_runtime_v1
|
||||
```
|
||||
|
||||
### 6.2 旧配置处理
|
||||
|
||||
旧配置短期保留,用于兼容现有业务链路:
|
||||
|
||||
- `ISCE2_PYTHON`
|
||||
- `PYINT_WSL_PYTHON`
|
||||
- `PYINT_GAMMA_ENV_SCRIPT`
|
||||
- `ISCE2_WSL_DISTRO`
|
||||
- `PYINT_WSL_DISTRO`
|
||||
|
||||
但应逐步降级为:
|
||||
|
||||
- 历史兼容字段
|
||||
- 启动检查告警来源
|
||||
- 回滚开关
|
||||
|
||||
而不再是长期正式执行入口。
|
||||
|
||||
## 7. 目录规划
|
||||
|
||||
新增目录:
|
||||
|
||||
```text
|
||||
deploy/wsl/
|
||||
conda/
|
||||
profiles/
|
||||
runners/
|
||||
backend/app/services/
|
||||
wsl_runtime_registry.py
|
||||
wsl_broker.py
|
||||
```
|
||||
|
||||
运行时作业目录:
|
||||
|
||||
```text
|
||||
backend/runtime/wsl_jobs/<runtime_id>/<operation>/<job_id>.json
|
||||
```
|
||||
|
||||
## 8. 实施阶段
|
||||
|
||||
### Phase 1
|
||||
|
||||
- 新增 `WSL shared runtime` 配置
|
||||
- 新增 `RuntimeRegistry`
|
||||
- 新增 `WslBroker`
|
||||
- 新增 runner/profile/conda 目录落点
|
||||
|
||||
### Phase 2
|
||||
|
||||
- 迁移 `ISCE2` 到 `runtime_id + manifest + broker`
|
||||
- 去掉服务层 shell 字符串拼接
|
||||
|
||||
### Phase 3
|
||||
|
||||
- 迁移 `Gamma/PyINT`
|
||||
- 把 `PYINT_GAMMA_ENV_SCRIPT` 收敛到固定 profile
|
||||
|
||||
### Phase 4
|
||||
|
||||
- 增加环境指纹校验
|
||||
- 健康检查显示 runtime 漂移
|
||||
- 审计日志记录 runtime_id / fingerprint / runner / manifest
|
||||
|
||||
## 9. 本轮代码落点
|
||||
|
||||
本轮先完成 V1 骨架:
|
||||
|
||||
- `backend/app/services/wsl_service.py`
|
||||
- 新增 `run_wsl_exec()`,支持 `wsl.exe --exec`
|
||||
- `backend/app/services/wsl_runtime_registry.py`
|
||||
- 新增共享 runtime 与双逻辑 runtime 定义
|
||||
- `backend/app/services/wsl_broker.py`
|
||||
- 新增 manifest staging 与 broker 执行骨架
|
||||
- `deploy/wsl/runners/*`
|
||||
- 新增 runner scaffold
|
||||
- `deploy/wsl/profiles/gamma_env.sh`
|
||||
- 固定 profile 落点
|
||||
- `deploy/wsl/conda/README.md`
|
||||
- 约束 conda 环境治理落点
|
||||
|
||||
下一步迁移优先级建议:
|
||||
|
||||
1. `ISCE2`
|
||||
2. `Gamma/PyINT`
|
||||
3. 健康检查与审计
|
||||
Reference in New Issue
Block a user