Help us shape the future of Go! Take the 2026 Go Developer Survey

gitserver

package
v0.1.0-rc1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 19, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

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

View Source
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

View Source
var ErrFetchFailed = errors.New("git fetch failed")

ErrFetchFailed 是拉源失败的包内哨兵。

View Source
var ErrSourceNotConfigured = errors.New("app source not configured")

ErrSourceNotConfigured 表示 app 未配置拉源 source(webhook 拉源前置)。

View Source
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

func ValidAppName

func ValidAppName(name string) bool

ValidAppName 报告 app 名是否可用于 bare 仓库路径。

func ValidSHA

func ValidSHA(sha string) bool

ValidSHA 报告 commit 是否为 40 位十六进制。

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.* 只有重放窗口一键,随本配置节装配)。

func (Config) Normalize

func (c Config) Normalize() Config

Normalize 回落缺省值(装配期调用;Root 为空不在此兜底——它依赖 state 库路径,由 cmd/fleetlyd 装配点计算,此处仅在启用时校验非空)。

func (Config) Validate

func (c Config) Validate() error

Validate 启用态配置完整性检查(装配期 fail-fast)。

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 New

func New(cfg Config, st *state.Store, box *secrets.Box, log *slog.Logger) *Source

New 构造 Source(cfg 先经 Normalize;启用态完整性 Validate 由装配点 在 Init 阶段 fail-fast)。

func (*Source) CheckHealth

func (s *Source) CheckHealth() error

CheckHealth 报告 git 入口层健康:启用态配置完整性 + state 可达。SSH 监听失败属 Start 阶段显式失败,不在健康面二次上报(与 ingress 服务壳 同口径)。

func (*Source) Config

func (s *Source) Config() Config

Config 返回归一后的配置(只读投影)。

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

func (s *Source) EnsureBareRepo(ctx context.Context, app string) (string, bool, error)

EnsureBareRepo 懒创建 app 的 bare 仓库并确保 post-receive 钩子在位:

  • 仓库缺失 → git init --bare + 新钩子 token + 写钩子(0600 + POSIX 可执行位;明文 token 只写进钩子文件);
  • 仓库在、钩子缺失(仓库重建/手工误删)→ 轮换钩子 token(按名吊销 旧 token)+ 重写钩子——daemon 重建仓库时轮换的绑定语义。

幂等;返回仓库路径与是否发生了创建。

func (*Source) FetchRemote

func (s *Source) FetchRemote(ctx context.Context, app string) error

FetchRemote 执行拉源:确保 bare 仓库在位 → 按计划 fetch。失败一律包装 ErrFetchFailed(调用方映射错误族信封)。

func (*Source) ListenAndServe

func (s *Source) ListenAndServe(ctx context.Context, addr string) error

ListenAndServe 监听 SSH git 面(阻塞至 ctx 取消或监听错误);启用态由 lynx.Service 壳(cmd/fleetlyd)驱动。

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)。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL