140 lines
5.5 KiB
Markdown
140 lines
5.5 KiB
Markdown
# simplegit
|
||
|
||
一个自包含(self-contained)的 git 宿主服务。提供 git smart-HTTP、SSH、Connect-RPC 三种访问入口,以及一套对仓库做读写的 RPC。
|
||
|
||
---
|
||
|
||
## 设计哲学
|
||
|
||
simplegit 的核心原则只有一条:
|
||
|
||
> **simplegit 拥有自己的数据库,这个数据库只跟自己通,不与任何外部服务共享或同步。**
|
||
|
||
由此推出三点:
|
||
|
||
1. **不依赖外部元数据服务。** simplegit 不连别人的库、不读别人的表。平台(console 等)不再同步持有 simplegit 的元数据,也不在请求路径上替 simplegit 做鉴权。
|
||
2. **外部不能直接写 simplegit 的库。** 元数据的唯一入口是 simplegit 自己的 API,或直接操作数据库本身。
|
||
3. **可以独立运行。** 没有平台、没有 console、没有消息队列,simplegit 依然是一个完整可用的 git 服务器。
|
||
|
||
设计目的:把 simplegit 和平台彻底解耦。simplegit 对自己的数据是唯一权威(single source of truth),既能作为平台的一员协同运作,也能单机裸跑。
|
||
|
||
---
|
||
|
||
## 三大部件
|
||
|
||
### 1. 私有数据库(Private DB)
|
||
|
||
simplegit 自带的元数据库,存放仓库注册表、用户、凭证(PAT)、权限等。
|
||
|
||
- 只对 simplegit 自身可见,不对外暴露连接。
|
||
- 不接受来自外部服务的写入。
|
||
- 变更途径只有两条:
|
||
1. **走 simplegit 自己的 API**(受其鉴权保护);
|
||
2. **直接操作数据库本身**(运维 / 紧急手段)。
|
||
|
||
### 2. 更新器(Updater)
|
||
|
||
simplegit 与外部世界保持同步的**唯一通道**。它是一个事件订阅者。
|
||
|
||
启动时可以指定(二选一,或都不选):
|
||
|
||
- **一个 URL**:Updater 连接该端点订阅事件(webhook / 长轮询 / SSE 等)。
|
||
- **一个消息队列**:Updater 连接该队列消费事件。
|
||
|
||
收到事件后,Updater 据此对 simplegit 自身做出更改(写私有库、触发仓库生命周期等)。
|
||
|
||
**如果不订阅**(既不指定 URL 也不指定队列):
|
||
|
||
- Updater 不运行 / 空转;
|
||
- simplegit 完全自行管理数据库,相当于一个孤立的 git 服务器;
|
||
- 数据库是"死的"——没有事件流去驱动它,只能通过 API 或直接改库来变更。
|
||
|
||
一句话:**Updater 是 simplegit 从"孤立"走向"协同"的可插拔开关。** 订阅了,它就跟着外部事件自我更新;不订阅,它就独立运转。
|
||
|
||
### 3. HTTP 鉴权:PAT + Basic Auth
|
||
|
||
HTTP 传输**只保留这一种**鉴权方式:
|
||
|
||
- 用户持 **Personal Access Token(PAT)**;
|
||
- 走 **HTTP Basic Auth**:`git clone http://...` 时用户名随意、密码填 PAT;
|
||
- simplegit 用本地私有库校验 PAT,**不再依赖外部 RBAC 中心、不再校验 console 的 JWT**。
|
||
|
||
HTTP 鉴权完全闭环在 simplegit 内部,符合"数据库只跟自己通"的原则。
|
||
|
||
> SSH 传输仍走公钥,公钥→用户的解析同样查本地私有库,保持自包含。
|
||
|
||
---
|
||
|
||
## 运行形态
|
||
|
||
| 形态 | Updater | 数据库 | 说明 |
|
||
|------|---------|--------|------|
|
||
| 孤立模式 | 不订阅 | 自管 | 单机裸跑;变更只来自 API 或直改库 |
|
||
| 协同模式 | 订阅 URL 或 MQ | 由事件驱动更新 | 作为平台一员,跟随事件自我变更 |
|
||
|
||
两种形态是同一个二进制的不同启动参数,没有代码分支。
|
||
|
||
---
|
||
|
||
## Git hooks
|
||
|
||
所有 Git hook 统一执行一个策略脚本:
|
||
|
||
```text
|
||
hook.sh <hook-type> <owner/name> [Git hook 原始参数...]
|
||
```
|
||
|
||
脚本继承 hook 的 stdin 和 `GIT_*` 环境。daemon 默认使用工作目录或二进制旁的
|
||
`hook.sh`;本地开发可以直接修改默认脚本,生产环境通过
|
||
`-hook-script=/path/to/production-hook.sh` 替换。simplegit 不解释或转发 hook
|
||
事件,具体效果完全由该脚本负责。
|
||
|
||
仓库自带的 `hook.sh` 只向 `<root>/hooks.log` 追加 hook 类型、仓库、参数和 stdin,
|
||
不访问任何外部服务,因此 standalone simplegit 不依赖 CI。
|
||
|
||
simpleci 提供集成适配器 `pkgs/simpleci/simplegit-hook.sh`。联合部署让 simplegit
|
||
显式使用该脚本,并配置:
|
||
|
||
```sh
|
||
simplegit daemon \
|
||
-hook-script=/path/to/simplegit-hook.sh \
|
||
-hook-arg=--url=http://simpleci:8095 \
|
||
-hook-arg=--workflow=.github/workflows/deploy.yml \
|
||
-hook-arg=--
|
||
```
|
||
|
||
tag push 和分支删除不会触发构建;simpleci 不可用时通知最多等待 5 秒,且不影响
|
||
push 的成功结果。`POST /runs` 应只暴露在受信任的内部网络。
|
||
|
||
---
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
cmd/ 入口、HTTP/SSH listener、host store
|
||
gitcmd/ git 仓库操作(tree/blob/commit/branch/merge/...)
|
||
gitrpc/ Connect-RPC server + 鉴权 middleware + client;v1 proto 与生成码
|
||
common/ 仓库路径解析(repolayout)
|
||
hook.sh 默认 Git hook 策略脚本
|
||
db/ 私有数据库(规划中)
|
||
updater/ 更新器(规划中)
|
||
build/ 构建产物
|
||
tests/ 集成测试
|
||
```
|
||
|
||
## 开发约束
|
||
|
||
- `state/` 内不允许放置任何 `_test.go` 文件。涉及 state 的行为验证必须放在 `state/` 之外的测试目录中。
|
||
|
||
---
|
||
|
||
## 实现状态
|
||
|
||
本文描述的是 simplegit 的**目标设计哲学**。当前代码正处于向该目标迁移的起点,尚未对齐:
|
||
|
||
- **鉴权**:仍为 console JWT + RBAC 中心(`-auth` / JWKS),HTTP 走 Bearer 或 Basic-with-JWT;待迁移为 PAT + Basic Auth。
|
||
- **私有数据库**:尚不存在,元数据仍由 console 持有;待引入。
|
||
- **更新器**:尚未实现;当前仓库生命周期(init/clone/delete/rename)由 console 以系统 token 同步 RPC 调用,待改为事件订阅。
|
||
|
||
迁移完成后,`-auth`(RBAC 中心)这一外部依赖将被移除。
|