feat(repos): 仓库接入预检 + codexsvc deploy key 配给脚本
本机 https 到 GitHub 常被出口策略挡、ssh 才通(2026-10-30 实测),而新项目填 https 私有仓会在 worker 里花几分钟超时 才失败。控制面不存仓库凭证的设计不动,缺的是建项目前的 快速预检与按仓库通用化的配 key 流程: - cloud.repos.check_repo_access:只跑 git ls-remote HEAD, 不 clone、不写盘、不改库;失败返回 (False, 原因),https 失败时追加改走 git@ 形的提示;CLI python3 -m cloud.repos check <url>,退出码 0/1,只打印结果与原因。 - deploy/provision_codexsvc_key.sh:主机上以 root 跑,为 codexsvc 生成/复用 ed25519 key(绝不覆盖已有 key),只 打印公钥(私钥绝不打印),--check 时以 codexsvc 身份跑 ls-remote,通了才算配好。 - 内层沙箱边界诚实说明:Docker 任务内层本就是 danger-full-access(见 sandbox.py 注释),外层 Docker/gVisor 才是防线;宿主级 bwrap workspace-write 的 fresh proc 在嵌套 pidns 下是内核 EPERM、/tmp 不隔离——这些是上游 codex 二进制 与内核的边界,本批不谎称在仓库代码里修掉,只把仓库接入 这一档做成可重复流程。 单测:test_project_repo 20 项全过(新增 check 5 项)。
This commit is contained in:
1 parent
b306b56517
commit
1ff8906aee
3 files changed
+173
-2
No files matched your search
@@ -21,6 +21,7 @@ try:
|
||||
from cloud.auth import AuthStore
|
||||
from cloud.repos import (
|
||||
RepoError,
|
||||
check_repo_access,
|
||||
checkout_dir,
|
||||
resolve_repo,
|
||||
validate_repo_url,
|
||||
@@ -32,6 +33,7 @@ except ImportError: # discover -s cloud/tests 时把项目根目录补进 sys.p
|
||||
from cloud.auth import AuthStore
|
||||
from cloud.repos import (
|
||||
RepoError,
|
||||
check_repo_access,
|
||||
checkout_dir,
|
||||
resolve_repo,
|
||||
validate_repo_url,
|
||||
@@ -101,6 +103,50 @@ class ValidateRepoUrlTestCase(unittest.TestCase):
|
||||
validate_repo_url(123)
|
||||
|
||||
|
||||
class CheckRepoAccessTestCase(unittest.TestCase):
|
||||
def test_ok_returns_head(self):
|
||||
def runner(cmd, timeout=None):
|
||||
self.assertEqual(cmd[:3], ["git", "ls-remote",
|
||||
"git@github.com:o/r.git"])
|
||||
return SimpleNamespace(returncode=0,
|
||||
stdout="abc123\tHEAD\n", stderr="")
|
||||
ok, detail = check_repo_access("git@github.com:o/r.git",
|
||||
runner=runner)
|
||||
self.assertTrue(ok)
|
||||
self.assertEqual(detail, "abc123")
|
||||
|
||||
def test_failure_returns_reason_not_exception(self):
|
||||
def runner(cmd, timeout=None):
|
||||
return SimpleNamespace(returncode=128, stdout="",
|
||||
stderr="fatal: Authentication failed")
|
||||
ok, detail = check_repo_access("git@github.com:o/private.git",
|
||||
runner=runner)
|
||||
self.assertFalse(ok)
|
||||
self.assertIn("Authentication failed", detail)
|
||||
|
||||
def test_https_failure_hints_ssh_form(self):
|
||||
def runner(cmd, timeout=None):
|
||||
return SimpleNamespace(returncode=128, stdout="",
|
||||
stderr="fatal: unable to access")
|
||||
ok, detail = check_repo_access("https://github.com/o/r.git",
|
||||
runner=runner)
|
||||
self.assertFalse(ok)
|
||||
self.assertIn("git@", detail)
|
||||
|
||||
def test_invalid_url_returns_false(self):
|
||||
ok, detail = check_repo_access("file:///tmp/r")
|
||||
self.assertFalse(ok)
|
||||
self.assertTrue(detail)
|
||||
|
||||
def test_timeout_returns_false(self):
|
||||
def runner(cmd, timeout=None):
|
||||
raise TimeoutError("timed out")
|
||||
ok, detail = check_repo_access("git@github.com:o/r.git",
|
||||
runner=runner)
|
||||
self.assertFalse(ok)
|
||||
self.assertIn("timed out", detail)
|
||||
|
||||
|
||||
class CheckoutDirTestCase(unittest.TestCase):
|
||||
def test_sanitizes_and_stays_inside(self):
|
||||
tmp = tempfile.TemporaryDirectory()
|
||||
|
||||
Reference in new issue
Block a user