Documentation
¶
Overview ¶
Package gitserver 是 git push(SSH) 与 webhook 两条部署触发入口的 daemon 侧实现(T2.19):
- SSH 服务器(golang.org/x/crypto/ssh):认证 = 平台管理的 git 公钥 (state 层 git_keys 表,SHA256 指纹匹配);exec 白名单限定 git-receive-pack / git-upload-pack(防 shell 注入——git 直接 exec、 app 名严格校验);bare 仓库按 app 懒创建并生成 post-receive 钩子;
- webhook(gateway 原生 HTTP handler 消费本包 Handler):强制 HMAC- SHA256 验签 + delivery ID TTL 防重放 + (app, sha) 幂等去重 + 拉源;
- 两条入口汇入同一 DeployFromCommit:compose 真源在 git 对象库 (`git show <sha>:compose.{yaml,yml}`),不信任客户端传字节。
包纪律:不 import 任何框架类型(lynx.Service 壳在 cmd/fleetlyd);git 操作全部 exec 系统 git(宿主 git 为前置条件,不引入 go-git 等重框架)。
Index ¶
- Constants
- Variables
- func ValidAppName(name string) bool
- func ValidSHA(sha string) bool
- type Config
- type DeployInput
- type Source
- func (s *Source) CheckHealth() error
- func (s *Source) Config() Config
- func (s *Source) DeployFromCommit(ctx context.Context, in DeployInput) (state.DeployRecord, []compose.Warning, error)
- func (s *Source) DeployFromGitPush(ctx context.Context, app, sha, ref, actorTokenID string) (state.DeployRecord, []compose.Warning, error)
- func (s *Source) EnsureBareRepo(ctx context.Context, app string) (string, bool, error)
- func (s *Source) FetchRemote(ctx context.Context, app string) error
- func (s *Source) ListenAndServe(ctx context.Context, addr string) error
- type WebhookHandler
Constants ¶
const ( // DefaultAddr 是 SSH git 面的缺省监听地址。 DefaultAddr = "127.0.0.1:8424" // DefaultReplayTTL 是 webhook delivery ID 防重放缓存窗口(config // webhook.replay_ttl_seconds 缺省 900s = 15 分钟)。 DefaultReplayTTL = 15 * time.Minute // TimestampWindow 是自定义投递方时间戳头(X-Fleetly-Timestamp)的 // 接受窗口(±5 分钟)——绑定口径,不可配置。 TimestampWindow = 5 * time.Minute )
安全默认基线(architecture §4.2):SSH git 面默认只绑回环——VPS 上由 安装/文档指引改为对外;重放窗口默认 15 分钟。
Variables ¶
var ErrFetchFailed = errors.New("git fetch failed")
ErrFetchFailed 是拉源失败的包内哨兵。
var ErrSourceNotConfigured = errors.New("app source not configured")
ErrSourceNotConfigured 表示 app 未配置拉源 source(webhook 拉源前置)。
var WebhookPathPattern = regexp.MustCompile(`^/v1/apps/([a-z0-9][a-z0-9-]{0,62})/webhooks/(github|gitea)$`)
WebhookPathPattern 是原生端点的精确路径形态(provider 白名单内联—— 未知 provider 一律 404,豁免面不放宽)。gateway 侧根 handler 用同一线性 词形做分派(豁免面 = 分派面,cmd/fleetlyd/gateway.go 例外清单)。
Functions ¶
Types ¶
type Config ¶
type Config struct {
// Enabled 报告是否启用 SSH git 面(git.enabled;缺省 true)。
Enabled bool
// Addr 是 SSH 监听地址(git.addr;缺省 127.0.0.1:8424)。
Addr string
// Root 是 bare 仓库根目录(git.root;缺省与 state 库同目录下 git/,
// 由装配方计算回落——本包不感知 db 路径)。
Root string
// HostKeyFile 是 SSH host key 文件路径(git.host_key_file;缺省
// <root>/host_ed25519。首启不存在自动生成 ed25519 并持久化,二次
// 启动复用——类比平台节点身份;私钥绝不打印)。
HostKeyFile string
// HookEndpoint 是 post-receive 钩子回调的控制面 HTTP 基址
// (如 http://127.0.0.1:8420;装配方由 addr 键推导)。
HookEndpoint string
// ReplayTTL 是 webhook delivery ID 防重放窗口
//(webhook.replay_ttl_seconds;缺省 15 分钟)。
ReplayTTL time.Duration
}
Config 是 git 触发入口配置(config 键 git.* 与 webhook.* 归并承载—— webhook.* 只有重放窗口一键,随本配置节装配)。
type DeployInput ¶
type DeployInput struct {
// App 是仓库对应的 app 名(compose name 与它不一致 → 拒绝——仓库
// 路径即应用身份,跨名部署会被静默错置)。
App string
// SHA 是 40 位 commit。
SHA string
// Ref 是来源引用(refs/heads/<branch>;仅记录)。
Ref string
// AuditAction 是部署入队审计 action 词根。
AuditAction string
// ActorTokenID 是入队调用方 token(钩子 token id;webhook 进程内路径
// 为空)。
ActorTokenID string
}
DeployFromCommit 是两条 git 触发入口的汇合点:compose 字节由服务端从 bare 仓库 `git show <sha>:compose.{yaml,yml}` 自取(真源在 git 对象库, 不信任客户端传字节),落临时文件走受控子集校验(与 API Deploy 同路径) 后入队部署,deployments.source_git_* 记录来源。
幂等口径(绑定):git push 是显式用户动作——每次调用都建部署记录(引擎 对同 spec 重放安全,Spike B2);(app, sha) 去重仅属 webhook 入口(在其 上游承载)。事件流复用既有 deployment.queued;审计 action 由入参区分 (git.push_deploy / git.webhook_deploy),actor 恒 system(机器动作)。
type Source ¶
type Source struct {
// contains filtered or unexported fields
}
Source 是 git 触发入口的核心:bare 仓库管理与 post-receive 钩子、 DeployFromCommit 入队、webhook 验签/防重放/去重/拉源、SSH 服务器。 它聚合 state 层(git keys/tokens/apps/deployments)与平台密钥盒 (webhook secret / 拉源认证材料的 envelope 加解密),对上暴露:
- SSH:ListenAndServe(lynx.Service 壳在 cmd/fleetlyd 驱动)
- HTTP:WebhookHandler(gateway 原生端点例外清单挂载)
- API:DeployFromGitPush(DeployFromGit RPC 的端口实现——端口接口 定义在 internal/api,方向纪律:api 不感知本包类型)
func (*Source) CheckHealth ¶
CheckHealth 报告 git 入口层健康:启用态配置完整性 + state 可达。SSH 监听失败属 Start 阶段显式失败,不在健康面二次上报(与 ingress 服务壳 同口径)。
func (*Source) DeployFromCommit ¶
func (s *Source) DeployFromCommit(ctx context.Context, in DeployInput) (state.DeployRecord, []compose.Warning, error)
DeployFromCommit 执行读源 → 校验 → 入队;返回 queued 部署记录与校验 期警告(非阻断标注,与 API Deploy 同面)。compose 违约(受控子集之外) 经 compose.Load 原样透传 E_COMPOSE_* 信封。
func (*Source) DeployFromGitPush ¶
func (s *Source) DeployFromGitPush(ctx context.Context, app, sha, ref, actorTokenID string) (state.DeployRecord, []compose.Warning, error)
DeployFromGitPush 是 DeployFromGit RPC 的端口实现(git push 路径;每次 push 都建部署记录)。actorTokenID 记录钩子回调 token(可追溯)。
func (*Source) EnsureBareRepo ¶
EnsureBareRepo 懒创建 app 的 bare 仓库并确保 post-receive 钩子在位:
- 仓库缺失 → git init --bare + 新钩子 token + 写钩子(0600 + POSIX 可执行位;明文 token 只写进钩子文件);
- 仓库在、钩子缺失(仓库重建/手工误删)→ 轮换钩子 token(按名吊销 旧 token)+ 重写钩子——daemon 重建仓库时轮换的绑定语义。
幂等;返回仓库路径与是否发生了创建。
func (*Source) FetchRemote ¶
FetchRemote 执行拉源:确保 bare 仓库在位 → 按计划 fetch。失败一律包装 ErrFetchFailed(调用方映射错误族信封)。
type WebhookHandler ¶
type WebhookHandler struct {
// contains filtered or unexported fields
}
WebhookHandler 是原生 webhook 端点处理器。
func NewWebhookHandler ¶
func NewWebhookHandler(src *Source) *WebhookHandler
NewWebhookHandler 构造(src 提供验签材料/防重放缓存/拉源/入队)。
func (*WebhookHandler) ServeHTTP ¶
func (h *WebhookHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP 实现 http.Handler(路径精确匹配 WebhookPathPattern)。