2024/08/31 Trivyのソースコードを読む
imageコマンドを入力する。
コマンドのハンドラが呼び出される(RunE)
artifact.Run()にコマンドのContextとartifact.TargetContainerImageを指定して実行する
ここが処理の入口。
artifact.TargetContainerImageが指定された場合はRunner.ScanImageをコールする
また、今回は読まないがフィルタやレポートのコールもここでやっている
今回は単純にimage名のみを指定したときの処理を読む。
r.scanArtifactにimageStandaloneScannerが渡されて実行される。
今回の仮定では、initalizeScannerは渡されているといえるので、r.scanが呼び出される
今回の仮定でr.scanはimageStandaloneScanneを呼び出す
imageStandaloneScannerを呼び出すと、initializeImageScannerを呼び出してそのまま返す
initializeImageScannerはWireで注入されたStandaloneDockerSetを呼び出して返す?
initializeImageScannerの実体はおそらくこれです
戻り値としてscanner.NewScanner()を返している
scanner.NewScanner()の戻り値のscanArtifactメソッドは何?
scanner.NewScanner()
引数がDriver, ScanArtifact
DriverはLocalScanner
local.NewScanner()
ScanArtifactはArtifactArtifact
image2.NewArtifact()
scanArtifact
artifactにはInspect()が生えてる
driverにはScan()が生えてて、呼び出し時にInspectの戻り値を渡してる
Inspect()の実装
imageIDとかはどうやって取ってるんだろう?
NewArtifact呼び出し時点でImageを貰ってるから、呼び出し側でimageを取得しているみたい
その値はtypesImageっぽい
image.newContainerImage()の戻り値
image.newContainerImage()
imageOpt.imageSourcesに型が入っており、それがtypes.DockerImageSourceであればtryDockerDaemon()にimageNameを渡して呼び出す
types.DockerImageSourceの実体は文字列「docker」
ImageSourceとは、コンテナレジストリやコンテナランタイムなどを識別するための文字列
Optionsは結局Flag(コマンド引数)周りの処理をソースとするデータ。デフォルトだとAllImageSourcesと同一になりそう
tryDockerDaemonは、imageName(string)ではなくname.Referenceのみを用いてdaemon.DockerImageを呼び出す。
tryDockerDaemonの下記の部分で、Docker daemonに対するリクエストを行っている。イメージ情報の取得処理はここが中核と考えられる
イメージ情報の取得はclient.NewClientWithOps()の戻り値オブジェクトに実装されている。
これはDocker APIのGo言語によるラッパーである。
ここまでのまとめ
opts.ImageSourcesはコンテナランタイムなどの識別情報だが、ユーザが直接指定しない限り定義済みのすべての値が入る。
image.NewContainerImage()で、各ImageSourceに対してtrySrc系関数の呼び出しを試行し、nil以外のものが返ってきたら戻り値として返す。
tryDockerDaemon()はdaemon.DockerImage()を呼び出す。
daemon.DockerImage()は、Docker APIを呼び出し、inspectやhistoryを持つオブジェクト daemon.Imageを返す。
tryDockerDaemon()は、取得したdaemon.ImageをImageプロパティに、引数で渡されたimageNameをnameにセットしたtypes.Imageを返す(取得できなければnil)。
まとめ
image.NewContainerImageは、内部でDocker APIなどのDaemonに関するAPIを呼び出し、types.Imageまたはnilを返す。
daemon.Image(types.Imageにおけるimageプロパティ)
history
inspect
感想
IDEは使おう
静的型付け言語であれば簡単に型定義に飛べる。