Skip to content

CI 和部署文档适配 Ubuntu 26.04 自带的 bwrap AppArmor profile (#135) - #140

Merged
joesmart merged 2 commits into
mainfrom
joesmart/fix-ci-userns
Nov 11, 2026
Merged

joesmart merged 2 commits into
mainfrom
joesmart/fix-ci-userns

Conversation

@joesmart

@joesmart joesmart commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

根因

Ubuntu 26.04 的 apparmor 5.0.2 自带 /etc/apparmor.d/bwrap-userns-restrict:profile bwrap 挂在 /usr/bin/bwrap 上放行 user namespace,子进程叠到 bwrap//&unpriv_bwrap。CI 原来又给同一路径挂了一份 baize-bwrap,两份冲突(dmesg:info="conflicting profile attachments"),exec 时一份都不用,bwrap 落回 unconfined,建 user namespace 时被转进 unprivileged_userns,capable net_admin / setpcap 被 DENIED。带 --unshare-net 报 loopback: Failed RTM_NEWADDR,不带报 setting up uid map: Permission denied。不是内核 sysctl 本身,也不是 bwrap 版本。

实验(临时探针 workflow,已删)

探针 run 42007221495,26.04 runner:Ubuntu 26.04.1、内核 7.0.0-1019-azure、apparmor 5.0.2、bubblewrap 0.11.1、apparmor_restrict_unprivileged_userns=1。四种参数(--unshare-net、--unshare-all、BWRAP_PROBE_ARGS、--unshare-user --unshare-net)结果一致:

宿主机状态 26.04 24.04(apparmor 4.0.1,bwrap 0.9.0,无自带 profile)
什么都不做 通,bwrap//&unpriv_bwrap (enforce) 不通
加我们的 profile 不通(冲突) 通,baize-bwrap (unconfined)
我们的 profile 加 capability,network / allow all 不通 —
卸掉自带的,只留我们的 通 —
sysctl 设 0 通(不采用,整机放开) —

容器(bookworm + bubblewrap 0.8.0,seccomp-bwrap.json、apparmor=unconfined,root 和 uid 1000)跟宿主机走:宿主机 profile 按路径也挂得上容器里的 /usr/bin/bwrap。

第二轮探针 run 42007586554:新 CI 步骤在两个 runner 上都过。26.04 上 bwrap「不加 profile 就能建」,Chrome(/usr/local/share/chromium/chrome-linux/chrome)不加 profile 以 134 中止,补 baize-chrome 后通;系统自带的 chrome/chromium profile 挂别的路径,不冲突。24.04 上两个都补了 profile。

改了什么

  • .github/workflows/ci.yml:每个程序先照原样起一次,起不来才补 profile,补完再起,还不通停在这一步。bwrap 用运行器的 BWRAP_PROBE_ARGS,探不通时 Linux 上沙箱用例会全跳过,所以这里要和它一致。只放开 bwrap 和 Chrome,不动 sysctl。注释改准。
  • deploy/README.md「AppArmor 与 bwrap 探测」:探测参数对齐 BWRAP_PROBE_ARGS;写实测表;以有没有 /etc/apparmor.d/bwrap-userns-restrict 判断(不看版本号):有就什么都不加,没有(24.04)才加 baize-bwrap;升级到带它的版本先 apparmor_parser -R 并删掉自己那份;改完 docker compose restart remote-computer 重探。
  • deploy/remote/README.md:探测命令补全参数,宿主机要求指向上面那节。

产品代码没改。探测失败时 sandboxKind() 是 none:每条 bash 都弹审批、批了不进沙箱直接跑;只读例行里 bash 被拒(NO_SANDBOX_REASON);云电脑网页终端不开;relaxIfContained 不放宽。启动日志有 bubblewrap 起不来(原因)…。这是收紧方向,不需要改。

验证

本地:

pnpm format:check   # All matched files use Prettier code style!
pnpm typecheck      # 全部 Done
pnpm lint           # 退出码 0,只有既有 warning

CI(同一套改动,临时加 push 触发和 pnpm -r --no-bail test 看全量):run 42008343335,userns 步骤通过,测试全部真跑:

包 结果
shared 284 通过
pi-embed 5 通过
web vitest 366 通过,Playwright 553 通过
bot-runner 1694 通过,1 失败,31 跳过
control-plane 1643 通过,1 跳过
computer-agent 202 通过,8 跳过
desktop 132 通过
e2e 55 通过

bwrap 沙箱用例在 26.04 上真跑并通过。唯一的失败是 runner.test.ts > 助理浏览器(真 Chrome)> 截图进模型是图片…,Page.captureScreenshot 30 秒不回,属 #89,和本线无关;#134 已在 main 上(本分支已 rebase 到它之后)。

最终 CI run(本 PR,head 8ed6858,pnpm format:check && pnpm check):https://github.com/SmartStudio/baize-bot/actions/runs/42012461349 ,结论 failure。

  • userns 步骤通过:/usr/bin/bwrap 不加 profile 就能建 user namespace,/usr/local/share/chromium/chrome-linux/chrome 补了 profile baize-chrome。
  • shared 13 个文件、web vitest 51 个文件、pi-embed、control-plane 全过。
  • bot-runner:1696 通过,1 失败,31 跳过。失败的还是上面那条截图用例(助理 Chrome 等了 30s 没回 Page.captureScreenshot,src/cdp.ts:132)。pnpm -r 在这里停了,后面的包没跑,全量结果看 run 42008343335。

这条截图用例在 26.04 上三次都红(42007586647、42008343335、42012461349),#134 合进来之后也红。它不像 #89 说的偶发,更像 26.04 上稳定复现。它和 bwrap、userns 无关,不在本 PR 修,建议另开 issue 跟。

Closes #135

🤖 Generated with Claude Code

https://claude.ai/code/session_01Be3SZps2JjqvyrJ1vbLmni

@joesmart
joesmart merged commit 8bbcda9 into main Nov 11, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

main 的 CI 从 10-25 起红在 user namespace 那一步,runner 换成 Ubuntu 26.04 后 bwrap 配不了回环口

1 participant