mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-06 09:17:31 +00:00
fix(update): 补上内核升级缺失的四道安全闸(H1–H4)
四条缺陷的共同点都是「静默产出一个看起来成功的升级」,而失败的表现
是机器进崩溃循环且没人知道原因。
H1 dataDir 为空必须拒绝升级
Apply 此前只在 dataDir 非空时写 pending,空值仅跳过标记、后照常替换
二进制 ⇒ 产出「无回滚能力」的升级。现改为在动任何文件之前直接失败。
另新增导出 update.ResolveDataDir(env → <exe>/data 兜底)。
H2 备份目录不能写 /root
backup 原为 /root/homed-upgrade-backup-<ts>,服务在 ProtectSystem=strict
+ ReadWritePaths=/var/lib/hologram 下运行,非 root 对 /root 无写权限
⇒ MkdirAll 必 EACCES ⇒ 首次升级必挂。改为落在 dataDir 下。
rollback 的 homed-broken-<ts> 同样从(通常只读的)二进制目录挪到 dataDir。
H3 备份目录要有 GC
旧注释写「确认稳定后可删」,但全仓无任何删除逻辑。新增
PruneOldBackups:保留最近 3 个 homed-upgrade-backup-* 与最近 1 个
homed-broken-*,其余 RemoveAll,在 Apply 成功返回前调用。
只处理名字精确为「前缀 + NowStamp 形态」的目录,不误删 pending 标记
或前缀相近的第三方目录。
H4 结果事件吞错误 + 成功不发 result
publishResult 里 `if errMsg != "" { _ = errMsg }` 把失败原因丢弃,payload
也没有 error 字段 ⇒ 订阅方只看到 ok=false。现在 error 字段恒定存在。
Apply 成功路径此前从不发 result,现补发 ok=true。
测试:kernel_apply_test.go 新增 5 个用例(含题目要求的四个函数名)。
This commit is contained in:
@ -170,11 +170,16 @@ func RollbackIfUnconfirmed(dataDir, binPath string) (bool, string, string, error
|
||||
}
|
||||
|
||||
// 先备份"当前这个坏的"——万一回滚目标也有问题,至少能回到现场
|
||||
//
|
||||
// ★ 落在 dataDir 下,不是二进制目录:二进制目录通常是 /usr/local/bin,
|
||||
// 只读(ProtectSystem=strict)⇒ MkdirAll 静默失败(旧代码没查 err),
|
||||
// 现场丢失且日志里只有一条无关的 copy 失败。
|
||||
ts := NowStamp()
|
||||
brokenDir := filepath.Join(filepath.Dir(binPath), "homed-broken-"+ts)
|
||||
os.MkdirAll(brokenDir, 0755)
|
||||
if err := CopyFile(binPath, filepath.Join(brokenDir, "homed")); err != nil {
|
||||
brokenDir := BrokenDirPath(dataDir, ts)
|
||||
if err := os.MkdirAll(brokenDir, 0755); err != nil {
|
||||
// 备份失败不阻断回滚:回滚是主线,留现场是支线
|
||||
log.Printf("[update] create broken-binary dir %s failed: %v", brokenDir, err)
|
||||
} else if err := CopyFile(binPath, filepath.Join(brokenDir, "homed")); err != nil {
|
||||
log.Printf("[update] backup of broken binary failed: %v", err)
|
||||
} else {
|
||||
log.Printf("[update] broken binary kept at %s", brokenDir)
|
||||
|
||||
Reference in New Issue
Block a user