Skip to content

内部実装

コミット 0d8b1c0 のソースから読む。ここの主張はすべてファイルと行を指す。

コードマップ

パス役割
cmd/hub/main.goHTTP API サーバの entrypoint、DI、ディスパッチャ
cmd/tracker/main.go索引生成の entrypoint とリポジトリ走査ループ
cmd/ah/ah.goah CLI
internal/tracker/tracker.gotracking の中核 Run() と clone 分岐
internal/tracker/helpers.gokind から TrackerSource へのディスパッチ
internal/tracker/source/kind 別 source 実装 (helm、krew、olm、tekton、container、generic)
internal/pkg/manager.goパッケージ登録と DB 関数呼び出し
internal/hub/中核ドメイン型 (PackageRepositoryTrackerSource)
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 はタグを列挙する。各チャートバージョンは preparePackagehub.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 に引き渡す:

go
pkgJSON, err := json.Marshal(pkg)
// ...
_, err = m.db.Exec(ctx, registerPkgDBQ, pkgJSON)

registerPkgDBQselect 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.Packagehash:"ignore" タグは、まさに派生メタデータがこの digest を乱さないために存在する。

もう 1 つの驚きは、ML モデルがホットパスにいることだ。tracker は Keras の saved model を読み込み (cmd/tracker/main.go:75)、category 未設定のパッケージに推論を走らせて付与する (internal/tracker/tracker.go:115)。SkipCategoryPrediction を立てると category は Unknown のままになる。