内部実装
コミット
0d8b1c0のソースから読む。ここの主張はすべてファイルと行を指す。
コードマップ
| パス | 役割 |
|---|---|
cmd/hub/main.go | HTTP API サーバの entrypoint、DI、ディスパッチャ |
cmd/tracker/main.go | 索引生成の entrypoint とリポジトリ走査ループ |
cmd/ah/ah.go | ah CLI |
internal/tracker/tracker.go | tracking の中核 Run() と clone 分岐 |
internal/tracker/helpers.go | kind から TrackerSource へのディスパッチ |
internal/tracker/source/ | kind 別 source 実装 (helm、krew、olm、tekton、container、generic) |
internal/pkg/manager.go | パッケージ登録と DB 関数呼び出し |
internal/hub/ | 中核ドメイン型 (Package、Repository、TrackerSource) |
internal/scanner/ | Trivy ベースの脆弱性レポート |
database/migrations/functions/ | 永続化ロジックを持つ PL/pgSQL 関数 |
中核データ構造
hub.Package (internal/hub/pkg.go:65) は索引全体が依拠する巨大な集約だ。digest は SetAutoGeneratedDigest (internal/hub/pkg.go:121) が hashstructure で構造体をハッシュして計算する。hash:"ignore" タグの付いたフィールド (package ID、stats、security report summary などの派生情報) は除外され、派生情報の変化が再登録を招かないようにする。
hub.Repository (internal/hub/repo.go:290) は tracker が回す単位で、repository ID、kind、URL、branch、保存済み digest、認証情報、VerifiedPublisher / Official / CNCF / PackagesDeletionProtection などのフラグを持つ。
RepositoryKind は整数の enum で (internal/hub/repo.go:50)、Helm RepositoryKind = 0 から始まる。値は固定の整数で、kind は今や 20 種類超ある。
TrackerSource (internal/hub/tracker.go:37) は戦略インタフェースで、メソッドは GetPackagesAvailable() (map[string]*Package, error) の 1 つだけ。入力の TrackerSourceInput (internal/hub/tracker.go:49) は repository、digest、既登録 map、base path、各種 svc を渡す。
PackageCategory (internal/hub/pkg.go:136) は ML 分類のラベル集合で、8 種類 (ai-machine-learning、database、integration-delivery、monitoring-logging、networking、security、storage、streaming-messaging) に Unknown と Skip を加える。
追う価値のあるパス
Helm チャートを、リポジトリ走査から DB の行まで追う。
Helm source は GetPackagesAvailable でチャートを列挙する (internal/tracker/source/helm/helm.go:119)。http(s) リポジトリは index loader で index.yaml を読み、oci はタグを列挙する。各チャートバージョンは preparePackage で hub.Package になり (internal/tracker/source/helm/helm.go:221)、チャートアーカイブの取得 (readme / license の付加) はパッケージが新規か digest が変化したときだけ行う。
tracker ループに戻ると (internal/tracker/tracker.go:93)、利用可能な各パッケージを Pm.Register で登録する (internal/tracker/tracker.go:122)。その検証は Container 以外の全 kind に semver を要求し (internal/pkg/manager.go:259)、その後 DB に引き渡す:
pkgJSON, err := json.Marshal(pkg)
// ...
_, err = m.db.Exec(ctx, registerPkgDBQ, pkgJSON)registerPkgDBQ は select register_package($1::jsonb) (internal/pkg/manager.go:43)。database/migrations/functions/packages/register_package.sql の PL/pgSQL 関数が、パッケージの upsert、version snapshot 登録、maintainers の調整、全文検索用配列の組み立てを担う。
驚いた点
digest が効きどころの最適化で、3 つの層に現れる。リポジトリ digest が Run() を短絡し (internal/tracker/tracker.go:41)、パッケージ digest がループ内で未変更パッケージをスキップし (internal/tracker/tracker.go:103)、Helm source はパッケージの digest が変わったときだけチャートアーカイブを取得する。hub.Package の hash:"ignore" タグは、まさに派生メタデータがこの digest を乱さないために存在する。
もう 1 つの驚きは、ML モデルがホットパスにいることだ。tracker は Keras の saved model を読み込み (cmd/tracker/main.go:75)、category 未設定のパッケージに推論を走らせて付与する (internal/tracker/tracker.go:115)。SkipCategoryPrediction を立てると category は Unknown のままになる。