把依赖图解开
目标
解析假设已导入的包集合中的依赖图,找出无法在 bundle 内解决的依赖,并计算安装顺序。
为什么重要
在隔离网络中,代价最高的错误是“已经导入,却因缺少依赖而不得不再次外出获取”。如果导入审批每天只有一次,一次往返就会耗费一天。因此,在导入之前必须确认 bundle 在其内部是否闭合(closure)。如果不了解 Provides 关系,还会误以为“仓库中没有 libcuda1”,进而四处寻找一个并不存在的包。
/opt/fixtures/gpu-airgap/src/ 中包含第一批导入内容的源代码树。它们不是真正的 NVIDIA 软件,但依赖图的形状与实际情况一致。
步骤
- 创建
/root/gpu目录,把/opt/fixtures/gpu-airgap/src/下所有包的이름 버전逐行写入/root/gpu/inventory.txt。必须有 14 行。 - 将所有源代码目录构建为
.deb,集中放到/root/gpu/pool/。必须有 14 个.deb文件。 - 在
/root/gpu/pool中创建Packages索引和Packages.gz。索引中的Package:条目必须有 14 个。 - 将每个包的依赖关系按
<패키지> <의존대상>格式逐行写入/root/gpu/edges.txt。去掉版本条件,只保留名称。至少要有 15 行。 - 在
/root/gpu/missing.txt中只写出 bundle 内无法解决的依赖名称。(bundle 中不存在同名包,并且 bundle 中也没有任何包通过Provides提供该名称。) - 为安装
nvidia-driver-550,将所有必需包按依赖项优先的顺序排列,并逐行写入/root/gpu/install-order.txt。必须有 11 行。 - 将提供虚拟包
libcuda1的包名以单独一行写入/root/gpu/provides.txt。 - 按以下 5 行创建
/root/gpu/report.txt。BUNDLE=14/EDGES=<4번 파일의 줄 수>/MISSING=<5번 파일의 줄 수>/ORDER=11/LIBCUDA1_BY=<7번 값>
参考
- 构建时可采用
for d in /opt/fixtures/gpu-airgap/src/*/; do dpkg-deb --build "$d" /root/gpu/pool/ ; done形式循环执行。 - 可用
dpkg-deb -f <deb> Depends读取 control 字段,也可以直接读取源代码树中的DEBIAN/control。 - Depends 字符串的形式为
pkg-a (= 1.0), pkg-b (>= 2.0)。请按逗号分隔并删除括号内容。 - 第 6 步的 11 个包包括
nvidia-driver-550本身及其全部传递依赖,不包括 toolkit 侧的包。 - 常见错误 1:在第 5 步中加入
libc6等系统中已经安装的包。此 bundle 中的包经过设计,不依赖系统包。 - 常见错误 2:第 6 步按字母顺序排序。必须按依赖关系排序。
盘点导入 bundle
创建 /root/gpu 目录,把 /opt/fixtures/gpu-airgap/src/ 下所有包的 이름 버전 逐行写入 /root/gpu/inventory.txt。必须有 14 行。
从每个源代码目录的 DEBIAN/control 中提取 Package 和 Version 即可。
构建所有包
将所有源代码目录构建为 .deb,集中放到 /root/gpu/pool/。必须有 14 个 .deb 文件。
对每个目录重复执行 dpkg-deb --build。请使用 shell 循环一次性处理。
生成仓库索引
在 /root/gpu/pool 中创建 Packages 索引和 Packages.gz。索引中的 Package: 条目必须有 14 个。
方法与前一课程相同。Package 条目数必须与构建出的包数量一致。
列出依赖关系边
将每个包的依赖关系按 <패키지> <의존대상> 格式逐行写入 /root/gpu/edges.txt。去掉版本条件,只保留名称。至少要有 15 行。
将 Depends 字段按逗号分隔,再删除版本条件的括号,即可只留下依赖目标名称。
查找未闭合的依赖
在 /root/gpu/missing.txt 中只写出 bundle 内无法解决的依赖名称。(bundle 中不存在同名包,并且 bundle 中也没有任何包通过 Provides 提供该名称。)
在依赖边的目标中,找出 bundle 内不存在且无法通过 Provides 满足的名称。排除系统中已经安装的包。
计算安装顺序
为安装 nvidia-driver-550,将所有必需包按依赖项优先的顺序排列,并逐行写入 /root/gpu/install-order.txt。必须有 11 行。
依赖项必须排在前面。可以手工进行拓扑排序,也可以编写脚本。
追踪虚拟包
将提供虚拟包 libcuda1 的包名以单独一行写入 /root/gpu/provides.txt。
查看 control 文件的 Provides 字段,即可知道哪个包提供了该名称。
依赖分析报告
按以下 5 行创建 /root/gpu/report.txt。
BUNDLE=14 / EDGES=<4번 파일의 줄 수> / MISSING=<5번 파일의 줄 수> / ORDER=11 / LIBCUDA1_BY=<7번 값>
汇总前面各步骤得到的数量和名称即可。