镜像可以导入了:docker save 的 tar、OCI 镜像布局(tar 或目录)都能读,每个 blob 和每一层都校验摘要,层解到 files 分区的 ext4 上,不同镜像共用相同的层;从镜像叠出根文件系统后,真实的 debian:trixie 镜像里 bash、apt-get update、apt-get install 都能用。镜像工具是一个用户态程序,内核和模块接口都没改。
| 步骤 | 内容 | 验收 |
|---|---|---|
| M6.1 | userland/:随系统提供的用户态程序的工作区(Rust 标准库、静态 musl);images 程序:load、ls、inspect、tag、rm、rootfs;存储在 /var/lib/rustros/images(层按 diff_id 存、镜像、标签;先写临时名字再改名) | 单元测试:tar 解析(PAX、GNU 长名字、校验和)、路径安全、删除标记和不透明目录、硬链接 |
| M6.2 | 解包(自己写的 tar 读取)和叠根文件系统:普通文件、目录、符号链接、硬链接、设备、FIFO;属主、权限(含 setuid)、时间;删除标记 .wh.、不透明目录 | 合成镜像(三层,覆盖上述各种情况)以三种格式导入:同一个镜像、层只存一份;叠出的根目录逐项核对类型、权限、属主、内容、硬链接、设备号,删掉的确实不在;层内容和摘要不符被拒绝;层里经符号链接往外写被拒绝 |
| M6.3 | 真实镜像:测试机用自己写的 Python 从 Docker Hub 取 debian:trixie(linux/amd64,存在工作目录里) | 导入、叠出根文件系统,在里面跑 bash、apt-get update、apt-get install hello、hello;删除镜像连同层;导入进行中把进程杀掉,存储里没有半个镜像,再导入成功 |
| 测试中发现 | VFS:一边读目录一边删其中的项(Rust 的 remove_dir_all、rm -r 都这样做)时,后面的项会被跳过,删目录失败(Directory not empty)。现在删除时把正在读这个目录的句柄的位置往回调 | VFS 单元测试(40 个文件,边读边删);images rm |
为什么做成用户态程序:解包是对不可信输入(tar、gzip、JSON)的大量处理,放在 ring 3 出错只影响它自己;只用已有的文件系统调用,不用改内核和模块接口,这个里程碑不用重启;顺便检验了兼容层(Rust 标准库的程序第一次在 RustROS 上跑)。
| 缺口 | 打算 |
|---|---|
| 用户态程序怎么随发布分发(现在测试时直接放进 files 分区) | M7b:和 docker 命令一起,作为发布里的一种新条目,pkg 装到 /usr/lib/rustros/ |
容器的根文件系统现在是整份复制(rootfs) | M7a 决定:VFS 里做叠加视图(各层只读、容器一层可写),复制作为后备 |
从仓库拉取(registry pull)、docker save 导出 | 按计划在后;测试里的 Python 拉取可以作为参考流程 |
| zstd 压缩的层;扩展属性(文件能力,如 ping 的 cap_net_raw) | 按需 |
M6 是否发布:这次不用重启(内核沿用,只更新 vfs 模块;镜像工具先不随发布分发,见遗留)。之后按顺序是 M7a(通用容器核心:隔离的根目录和 PID 空间、根文件系统、网络接入、资源限制、生命周期、状态交接)。M7a 开始前我会先发设计请你确认里面的几个决定(根文件系统用叠加视图还是复制、PID 空间的做法)。