fix(updater): 打通华为内网镜像回退链路 / wire up the intranet PyPI mirror fallback - #72
Open
370025263 wants to merge 1 commit into
Open
fix(updater): 打通华为内网镜像回退链路 / wire up the intranet PyPI mirror fallback#72370025263 wants to merge 1 commit into
370025263 wants to merge 1 commit into
Conversation
server wheel 回退虽然在 0.6.5 加了,但三处没打通华为纯内网场景: 1) `AutoUpdater.pypi_url` 从没被真正配置过(daemon.py 构造时不传), 公网 PyPI 不可达时永远直接跳到 server wheel,内网镜像形同虚设; 2) `_install_wheel` 装 server 下的 wheel 时完全不带 `-i`,wheel 的依赖 解析会悄悄吃 pip 默认索引(通常是不可达的公网 pypi.org),纯内网机器 上大概率装不上; 3) 手动 `xskill update` 是完全独立的一条逻辑,没有任何回退——公网 PyPI 查询失败直接报错退出,和后台自动检查的行为完全不一致。 fix(updater): the intranet PyPI mirror was configured but never actually wired into the fallback chain The server-wheel fallback landed in 0.6.5, but three gaps kept it from working for a pure-intranet (no public internet) deployment: 1) `AutoUpdater.pypi_url` was never actually set to anything but the public PyPI default — daemon.py never passed it through — so when public PyPI is unreachable the updater always jumped straight to the server-wheel path without ever trying a configured mirror. 2) `_install_wheel` installed the server wheel with no `-i` flag at all, so resolving the wheel's dependencies silently fell back to pip's default index (usually unreachable public pypi.org) instead of the mirror. 3) The manual `xskill update` CLI command was a completely separate, simpler code path with zero fallback — it just errored out if the public PyPI JSON query failed, unlike the background updater. Changes: - `ClientState` gains an optional `pypi_url` field, settable via `xskill connect --pypi-url <url>` and persisted across reconnects. - `AutoUpdater` now tries (1) public PyPI, (2) the configured mirror via `pip index versions` (works against any PEP 503 index, unlike the legacy JSON API most mirrors don't implement), (3) server wheel — in that order — before giving up. `_install_wheel` now always passes `-i self.pypi_url` so wheel dependencies resolve through a reachable index. - `cmd_update` now delegates to `AutoUpdater.run_once()` (loading the persisted server/mirror config) instead of duplicating a narrower, fallback-less version of the same logic. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景 / Background
0.6.5 加了 team server wheel 回退(#70),但排查华为内网部署场景时发现三个没打通的地方,导致对纯内网(连不上公网 PyPI)用户来说,回退实际上不work:
AutoUpdater.pypi_url从没在任何调用点被设成公网默认值以外的东西——daemon.py构造AutoUpdater时压根不传这个参数。公网 PyPI 查询失败时,代码直接跳到 server wheel 回退,配了内网镜像也用不上。_install_wheel装 server 下发的 wheel 完全不带-i——wheel 本体虽然来自 server,但它的依赖解析会悄悄吃 pip 默认索引(通常是不可达的公网 pypi.org)。纯内网机器上这一步大概率直接卡死/失败,等于回退没真正回退成。xskill update(CLI 命令)是完全独立的一条逻辑,没有任何回退——公网 PyPI JSON 查询失败就直接报错退出,和后台每小时的自动检查行为不一致。skill 安装向导的"日常维护"一节推荐用户用这条命令,但它在内网环境下必挂。改动 / Changes
ClientState新增可选字段pypi_url,通过xskill connect --pypi-url <url>设置,落盘到~/.xskill/team_client.json,重连时若不重新传参会沿用上次的值。AutoUpdater现在按 公网 PyPI → 已配置的内网镜像(用pip index versions,兼容大多数只有 PEP 503/simple/索引、没有 pypi.org legacy JSON API 的内网镜像)→ team server wheel 三级顺序回退。_install_wheel现在总是带-i self.pypi_url,wheel 的依赖解析走一个明确可达的索引,不会悄悄吃 pip 默认配置。cmd_update(xskill update)重写为复用AutoUpdater.run_once(),加载已持久化的 server/mirror 配置,不再是一条更窄、没有回退的独立逻辑。测试 / Testing
_install_wheel的-i参数、ClientState新字段的持久化与向后兼容(老 json 没有pypi_url字段时默认None)、cmd_update委托给AutoUpdater且正确复用持久化配置。make test(不含 docker_e2e / live):1144 passed。tests/test_e2e_xskill_serve_auto.py::test_canary_flip_promote_and_install_new_version——这个测试会真的 spawnclaude -p子进程,在当前沙箱环境(已经跑在一个 Claude Code 会话里,嵌套调用claudeCLI)里会一直挂起,和本次改动无关(该改动完全没碰灰度/canary 相关代码)。建议在真实 CI 里补跑一遍确认。make e2e(docker),建议合并前在有网络访问的环境里跑一遍。兼容性 / Compatibility
--pypi-url的xskill connect行为完全不变(pypi_url默认None,回退链路退化为"公网 PyPI → server wheel",和现在一样)。team_client.json(没有pypi_url字段)能正常读取,字段默认None。xskill-internal-install-guide那边的install.ps1已经改成在connect时传--pypi-url,并且做了老版本 xskill(argparse 报 unrecognized argument,退出码 2)时自动降级重试,所以这个 PR 和已部署的旧版本 server/client 之间不会因为参数不认识而报错——但只有等这个版本真正发布、部署到 server 上之后,--pypi-url才会真正生效。不要求立即合并,先看一下改动方向对不对。
🤖 Generated with Claude Code