LoginSignup
9

posted at

updated at

Finch の内部実装を見てみた。

今 話題になっている Finch

などを見ていただければ分かりますが、Finch は ローカルマシン上に仮想環境とコンテナランタイム、ビルドツールなど一式を楽〜に導入 できるツールになっています。
そのコードが

にあります。
コードは Go で書かれていて、Cobra(Go の CLIツール)を使って CLIのコマンドラインを作っています。
簡単に言えば バージョン 0.1.0 の名前から分かるように、Cobra で nerdctl や lima を呼び出しているだけの簡潔な内容に見えます。

それでは、その内容を見てみましょう。

Cobra のエントリーポイント

Cobra の説明は、

を参照してみて下さい。

Cobra のエントリーポイントは、finch/cmd/main.go にあります(コードは ここ にあります)。
この main.gonewApp で コマンドラインの登録を行なっていて、それまでは logger や path などの初期化を行なっています。

まず、大枠で説明すると、

    usage := fmt.Sprintf("%v <command>", finchRootCmd)
	rootCmd := &cobra.Command{
		Use:           usage,
		Short:         "Finch: open-source container development tool",
		SilenceUsage:  true,
		SilenceErrors: true,
		Version:       finchVersion(),
	}

で、ルートコマンドの登録をして、
最終的に、

	rootCmd.AddCommand(allCommands...)

部分で、allCommands の内容を登録しています。
それまでに出てくるものも説明しましょう。

  • ecc は、Create 関数 を通して、"os/exec" からコマンド入力(ls など)を行います(コードはここ)。
  • lcc は、Create 関数を通して、lima コマンドを 上の ecc から呼び出しています(コードはここ)。

lima は

などを参照にしてみて下さい。

allCommands の中身

では、allCommands の内容を見てみると、

	allCommands := initializeNerdctlCommands(lcc, logger)

のように initializeNerdctlCommands を呼び出しています。
ここで出てくる nerdctl は docker と同じコマンドライン(pullrunimageなど。コードだと ここに一覧が載っています。)でコンテナを触れるライブラリになっています。

initializeNerdctlCommands

initializeNerdctlCommands に話を戻すと、その中身nerdctlCommandCreator.create で append する動作を for文で回しているだけなのが分かりますね。

その nerdctlCommandCreator.create を見てみると、command の RunErunAdapter を呼んでいるだけに見えますね。nc.creater には前に出てきた lcc が入ります。そして、runAdapterrun 内の

	limaArgs := append([]string{"shell", limaInstanceName, nerdctlCmdName, cmdName}, nerdctlArgs...)

で、lima の args を指定して、

	return nc.creator.Create(limaArgs...).Run()

で、

	cmd := lcc.cmdCreator.Create(lcc.limactlPath, args...)

で、limactl shell finch nerdctl [command] を実行します。この limactl shellここ に書いているように、Linux 上で command を叩く内容になっていますので、そのまま nerdctl を実行する内容になっています。

これらのコマンドは、RunE で引数が渡されていませんが、コマンド入力の時に引数が渡されて実行される流れになっています。

ここまでの流れだけでも、finch の docker ライクなコマンドの実行が、単純に limactl shell finch nerdctl コマンド を叩いているだけなのが分かりました。意外とやっていることは簡単でしたね。

virtualMachineCommands

では、allCommands の初期化の次の部分である

	allCommands = append(allCommands,
		newVersionCommand(),
		virtualMachineCommands(logger, fp, lcc, ecc, fs, fc),
	)

を見てみます。
特に重要なのは virtualMachineCommands 部分なので、そこから読んでみます。
コードを読めば分かるんですが、ここ
の部分で、コマンドを追加しています。

	virtualMachineCommand.AddCommand(
		newStartVMCommand(limaCmdCreator, logger, optionalDepGroups, lca, nca, fs, fp.LimaSSHPrivateKeyPath()),
		newStopVMCommand(limaCmdCreator, logger),
		newRemoveVMCommand(limaCmdCreator, logger),
		newInitVMCommand(limaCmdCreator, logger, optionalDepGroups, lca, nca, fp.BaseYamlFilePath(), fs, fp.LimaSSHPrivateKeyPath()),
	)

ここでは、前に出てきた lima の Linux 仮想環境を開始したり、削除したりの動作を行なっています。仮想環境のセットアップもなしで、limactl が動くわけもないですよね。
同じような内容もあるので、ここでは newStartVMCommand を中心に見てみます。
この newStartVMCommand でも、RunE がエントリーポイントになり、runAdapter -> run で実行されます。
ここでは、

	limaCmd := sva.creator.CreateWithoutStdio("start", limaInstanceName)

から(creator は上で出てきた lcc )、limactl start finchコマンドを入力しています。これで、lima の Linux 仮想環境が実行されます。
他の、newStopVMCommand や newRemoveVMCommand も同じような感じなので読んでみるといいかもしれませんね。

最後に

Finch ってかっこよく宣伝されている割には、中身が limectlnerdctl の実行を行なっているだけで特に難しいことはしていないようなラッパーのみに見えるので、今後の Finch の開発に期待ですね。
皆様もこれを機に、nerdctlFinch を使うようになれば幸いです。

Go 初めて呼んだ割には、読めてよかったです。
nerdctl も ps だけ読んでみたのですが、containerd を CLI で叩くためのラッパーみたいな感じでしたね。Finch を読めば、結構読みやすいと思うので nerdctl を読むのもオススメです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
9