123 lines
6.0 KiB
Markdown
123 lines
6.0 KiB
Markdown
# TG3 data episode sync
|
||
|
||
机器人只在 `/home/nvidia/tg3_data_collection/ready` 暴露已经收到 SIGINT、写完
|
||
`metadata.yaml`、通过 `ros2 bag info` 并生成 SHA-256 清单的 episode。本机服务用免密 SSH/rsync 复制到
|
||
`Data_Get/.incoming`,逐文件校验并 fsync 后再原子改名为 `Data_Get/<episode_id>`。本机
|
||
`VERIFIED` 收据持久化成功后,正式服务会再次完整哈希本机 payload,再让 Nvidia 侧固定根目录
|
||
helper 比对原始 manifest SHA-256,原子移入 `deleting/` 后清理。因此完整数据最终只保留在 PS 本机,Nvidia 只是临时
|
||
staging;中断、哈希错误或本机落盘失败都不会触发远端删除。
|
||
|
||
数据只走本机到 Nvidia 的 SSH 链路,与公网或 EAI 本地 OmniSocket Hub 无关。当前默认:
|
||
|
||
```text
|
||
nvidia@192.168.41.2:/home/nvidia/tg3_data_collection/ready/
|
||
-> /home/ps/Desktop/TG3_TS1P_OmniSocket_Teleop/Data_Get/
|
||
```
|
||
|
||
EAI 不运行 recorder/sync,也不保存 MCAP 或图像数据。
|
||
|
||
先确认免密与依赖:
|
||
|
||
```bash
|
||
ssh -o BatchMode=yes nvidia@192.168.41.2 true
|
||
command -v rsync
|
||
ssh nvidia@192.168.41.2 command -v rsync
|
||
```
|
||
|
||
先把固定根目录删除 helper 部署到 Nvidia。它的 CLI 只接受安全 episode ID 和 64 位
|
||
manifest SHA-256,不接受 root 参数,也不会枚举或触碰 `active/`、`failed/`。helper 在
|
||
`deleting/` 树之外的 `delete_ledger/` 先持久化独立删除授权;即使递归删除中断且 tombstone
|
||
里的 READY/manifest 已消失,仍能凭该授权安全续删,最后才删除授权文件:
|
||
|
||
```bash
|
||
scp tg3_local_teleop/delete_ready_episode.py \
|
||
nvidia@192.168.41.2:/home/nvidia/tg3_local_teleop/
|
||
ssh nvidia@192.168.41.2 \
|
||
chmod 755 /home/nvidia/tg3_local_teleop/delete_ready_episode.py
|
||
```
|
||
|
||
安装本机用户服务:
|
||
|
||
```bash
|
||
mkdir -p ~/.config/systemd/user
|
||
cp tg3_data_collection/tg3-data-get-sync.service ~/.config/systemd/user/
|
||
systemctl --user daemon-reload
|
||
systemctl --user enable --now tg3-data-get-sync.service
|
||
```
|
||
|
||
状态:
|
||
|
||
```bash
|
||
systemctl --user --no-pager status tg3-data-get-sync.service
|
||
python3 -m json.tool Data_Get/sync_status.json
|
||
```
|
||
|
||
也可以只执行一次,便于首次部署验收:
|
||
|
||
```bash
|
||
systemctl --user stop tg3-data-get-sync.service
|
||
python3 tg3_data_collection/data_get_sync.py --once --delete-remote-after-sync
|
||
systemctl --user start tg3-data-get-sync.service
|
||
```
|
||
|
||
同步器使用 `Data_Get/.data_get_sync.lock` 做 flock;正式服务运行时,另一个 `--once` 会明确
|
||
报“已有同步进程”,不会与服务同时复制或删除。不带 `--delete-remote-after-sync` 的手动命令
|
||
只复制、验真并保留远端,正式 unit 已显式启用自动回收。
|
||
|
||
日常轮询不会每 2 秒重新读取并哈希全部历史 MCAP;首次原子发布时已经完成深度校验。
|
||
如果进程在远端删除 ACK 返回前退出,`VERIFIED` 会保持 `pending`。每次真正调用 helper
|
||
之前都会重新完整哈希本机 payload;失败后从 30 秒开始指数退避,最大 15 分钟,进程重启也
|
||
遵守持久化的 `next_retry_unix_s`,避免每 2 秒重读大型 MCAP。helper 使用独立 600 秒超时,
|
||
能继续清理同摘要 tombstone/ledger,也会把已经不存在的同一目标视为成功。
|
||
需要定期审计已有本地数据时单独执行(可能耗时较长):
|
||
|
||
```bash
|
||
python3 tg3_data_collection/data_get_sync.py --once --verify-existing
|
||
```
|
||
|
||
某个旧 episode 损坏会写入 `sync_status.json`,但不会阻止同一轮继续拉取其他新 episode。
|
||
|
||
一个完成目录至少包含:
|
||
|
||
```text
|
||
<episode_id>/
|
||
READY
|
||
VERIFIED
|
||
manifest.json
|
||
bag/metadata.yaml
|
||
bag/*.mcap
|
||
ros2_bag.stdout.log
|
||
ros2_bag.stderr.log
|
||
```
|
||
|
||
同步端会再次核对 `READY`、episode ID、每个 MCAP/metadata 的长度和 SHA-256;远端
|
||
manifest 在传输中发生变化也会拒绝发布最终目录。随后 fsync 所有复制文件和目录、以
|
||
NOREPLACE 语义原子发布、fsync 父目录,最后写入并 fsync `VERIFIED`。收据绑定 episode、
|
||
远端身份、原始 manifest SHA-256、已校验文件数和字节数,并记录 `pending/deleted`。
|
||
`.incoming`、`sync_status.json` 和全部 episode 已由 `Data_Get/.gitignore` 排除。
|
||
|
||
临时目录按 `<episode>.<manifest_sha256>.partial` 隔离,rsync 同时使用删除同步;发布前还会
|
||
拒绝 manifest 未列出的任何 `*.mcap` 或 `metadata.yaml`,避免旧中断文件混入新 episode。
|
||
|
||
`sync_status.json` 的 `state=delete_pending` 表示本机数据已完整发布,但远端回收尚未收到
|
||
成功 ACK;`pending_remote_cleanup`、`last_delete_error`、`delete_count` 和
|
||
`last_deleted_episode` 可用于排查。此状态下不要手工删除本机数据,服务会在下一轮重试。
|
||
|
||
已有本机同名目录不会直接授权删除:没有可信 `VERIFIED` 时必须重新做完整哈希,并要求
|
||
本机与当前远端 manifest 原始摘要一致,之后才补收据并回收远端。同名碰撞、损坏、符号
|
||
链接、错误 root 或摘要不符都保留远端并报错。
|
||
|
||
历史 `retained/deleted` 收据可以来自旧机器人 IP,不会阻塞新地址的同步;仍为 `pending` 的
|
||
跨 IP 收据不会静默授权新机器人删除,只会逐项报错且不影响其他新 episode 继续同步。
|
||
|
||
自动回收 helper 严格只覆盖 `ready/`,录制中的 `active/` 永远不能由 PS 同步器处理,
|
||
也不能对 `failed/` 使用 READY 凭据。当前正式配置为
|
||
`retain_failed_episodes=false`:录制器只把失败原因写入状态和 journal,随后精确删除自己
|
||
刚创建的失败 payload,因此机器人不会长期保留失败 MCAP。若以后改回 `true` 以保留故障
|
||
诊断,必须另建独立验真与回收协议,不能整目录清空。
|
||
|
||
迁移后需要同步修改 service 中的本机项目路径和机器人 SSH 地址。如果 Nvidia 的
|
||
`192.168.41.2` 改变,只改 unit 的 `--remote` 并重新部署 helper;它不在机器人
|
||
`config.toml` 或 OmniSocket Peer 设置中。启用自动删除时远端路径必须保持固定的
|
||
`/home/nvidia/tg3_data_collection/ready`,同步器会拒绝对其他 root 启用删除。
|