ipkg/ipkg-cl 软件包生命周期状态
可以把 ipkg/ipkg-cl 理解成一个比较典型的软件包生命周期状态机。以后遇到安装、升级、降级、批量升级失败,基本都可以沿着这个生命周期排查。
1. ipkg 软件包生命周期
install / upgrade
│
▼
下载 .ipk 软件包
│
▼
解包 / unpack
│
▼
Status: install ok unpacked
│
▼
处理依赖关系 Depends
│
▼
执行 preinst / postinst
│
┌────────┴────────┐
│ │
成功 失败
│ │
▼ ▼
install ok installed install ok unpacked
│ │
▼ │
安装完成 │
│
▼
configure 重试
│
▼
解决失败原因
│
▼
install ok installed
其中最重要的是:
unpack 成功 ≠ 安装完成。
install ok unpacked 表示文件已经解包进去,但配置脚本还没有完整成功。
2. 常见状态怎么理解
重点关注 /usr/lib/ipkg/status。
install ok installed
Status: install ok installed
表示:
软件包已经正常安装并完成配置。
这是正常最终状态。
install ok unpacked
Status: install ok unpacked
表示:
.ipk已经解包,但 configure/postinst 尚未成功完成。
这是排查问题时非常重要的状态。
首先执行:
ipkg-cl -f ipkg.conf status
或者:
ipkg-cl -f ipkg.conf status | grep -B 3 -A 3 'unpacked'
3. 安装/升级过程中最容易碰见的问题
① postinst 执行失败
典型:
pkg_run_script: package "xxx" postinst script returned status 1
说明:
.ipk 解包成功
↓
postinst 执行
↓
命令返回非 0
↓
软件包停留在 unpacked
排查:
ipkg-cl -f ipkg.conf status xxx
然后找到对应脚本:
ls -l /usr/lib/ipkg/info/
通常会有:
xxx.postinst
xxx.preinst
xxx.prerm
xxx.postrm
查看:
cat /usr/lib/ipkg/info/xxx.postinst
重点不是看到 postinst failed 就重新安装,而是找到 postinst 里面到底哪条命令失败。
4. postinst 常见失败类型
① 文件/目录不存在
例如本次:
can't create /boot/extlinux/extlinux.conf:
nonexistent directory
排查:
ls -ld /boot
ls -ld /boot/extlinux
解决原则:
根据软件包设计补齐目录或修正环境,而不是盲目创建。
例如本次环境虽然缺少:
/boot/extlinux
但它本身是 NetOne 容器环境,/boot 使用的是自己的 4.19.235 内核/启动文件,所以不能简单认为“创建目录就是正确修复”。
② 内核/模块不匹配
例如:
depmod: can't change directory to
'lib/modules/7.1.13-200.fc44.x86_64'
排查:
uname -r
ls -la /lib/modules
ls -ld /lib/modules/$(uname -r)
判断:
uname -r
↓
实际运行内核
/lib/modules/$(uname -r)
↓
对应内核模块目录
如果不存在,就要考虑:
宿主机内核
≠
软件包/容器期望的内核
不要为了让 depmod 不报错,随便创建一个假的 modules 目录。
③ 依赖包没有安装/配置完成
例如:
Depends: libc*, iptables*
排查:
ipkg-cl -f ipkg.conf status
重点检查依赖包是不是:
install ok installed
而不是:
install ok unpacked
可以形成:
A
└── Depends: B
↓
B 没配置成功
↓
A 也无法正常 configure
5. configure 是非常重要的“恢复入口”
如果发现:
Status: install ok unpacked
不要马上重新 install。
优先:
ipkg-cl -f ipkg.conf configure
它的作用就是:
对已经解包、但尚未完成配置的软件包继续执行配置过程。
本次就是典型案例:
extlinux unpacked
ipset unpacked
iptables-addons unpacked
linux unpacked
linux-modules-common unpacked
│
▼
ipkg-cl configure
│
▼
全部配置成功
│
▼
install ok installed
6. upgrade、install、configure 的区别
可以简单记成:
| 命令 | 主要作用 |
|---|---|
install xxx |
安装指定软件包 |
upgrade |
根据仓库版本判断并升级软件包 |
configure |
对已经解包但尚未完成配置的软件包进行配置 |
remove xxx |
卸载软件包 |
update |
更新软件包索引 |
status |
查看软件包状态 |
info xxx |
查看软件包信息 |
list_installed |
查看已安装软件包 |
所以遇到:
install ok unpacked
第一反应应该是:
ipkg-cl -f ipkg.conf configure
而不是:
ipkg-cl -f ipkg.conf install xxx
7. upgrade 看到 Configuring xxx 不代表正在升级版本
你前面执行:
ipkg-cl -f ipkg.conf -noaction upgrade
看到:
Configuring extlinux
Configuring ipset
Configuring iptables-addons
Configuring linux
Configuring linux-modules-common
Nothing to be done
这个现象很容易误解。
它实际上说明:
没有新的版本升级操作
↓
但是存在尚未 configure 完成的软件包
↓
upgrade 流程准备处理 configure
所以:
Configuring xxx
不等于:
xxx 正在从旧版本升级到新版本
8. 如何判断一次升级/降级到底成功没有
建议固定做这几步。
第一步:看版本
ipkg-cl -f ipkg.conf status xxx
关注:
Version:
Status:
第二步:检查有没有 unpacked
ipkg-cl -f ipkg.conf status | grep -B 3 -A 3 'unpacked'
没有输出是一个非常好的信号。
第三步:确认目标包是 installed
例如:
ipkg-cl -f ipkg.conf status linux
应该看到:
Status: install ok installed
第四步:必要时检查文件
ipkg-cl -f ipkg.conf files linux
确认 .ipk 中的文件是否已经落到系统。
9. 降级测试需要特别注意
你这次采用的是:
修改 /usr/lib/ipkg/status 的 Version
↓
让 ipkg 认为当前版本较低
↓
ipkg upgrade
↓
重新安装目标版本
这是利用 版本比较机制实现的。
而 ipkg 0.99.163 本身还有:
ipkg-cl -f ipkg.conf -force-downgrade install xxx
因此测试时要区分:
普通 upgrade
↓
版本比较
↓
仓库版本 > status中的版本
↓
执行升级/重新安装
和:
-force-downgrade
↓
明确允许版本回退
↓
install 指定包
10. 最实用的一套排查口诀
以后遇到 ipkg 安装/升级异常,可以按这个顺序:
① 看状态
status
② 看是不是 unpacked
grep unpacked
③ 看依赖
Depends
④ 找 postinst
/usr/lib/ipkg/info/*.postinst
⑤ 手工定位失败命令
⑥ 修复环境/依赖/目录/权限等问题
⑦ configure
ipkg-cl -f ipkg.conf configure
⑧ 再查 status
⑨ 确认:
install ok installed
可以浓缩成一句:
先看 Status → 判断是 unpack 失败还是 configure 失败 → 查 Depends → 查 preinst/postinst → 修复具体失败原因 →
configure→ 再验证install ok installed。
这套思路基本可以覆盖你后面做 ipkg 升级、降级、批量安装、系统包升级失败时的大部分问题。

浙公网安备 33010602011771号