Docker pullをちょっとだけ楽にするCLIつくりました

本稿は Qiita DockerAdventCalendar2019 22日目の記事です。

つくったもの

dockerのimageからtagを検索&選択してpullできるCLI

※動画の圧縮になれておらず、、画質が悪いです。。


バージョン等

  • Go 1.13.5
  • spf13/cobra … CLIアプリケーションのライブラリ。
  • manifoldco/promptui … 対話型プロンプトのライブラリ。
  • macOS Catalina 10.15.1
  • Docker version 19.03.5

Goの経験は、以前ポストしたLチカセブンくらいでほぼ触ったことがありません。
「shellなら楽じゃん」と言われそうですが、今回は Dockerのアドベントカレンダー
必然的にDockerの開発言語であるGo言語を使うしかありません!

CLIのライブラリは、urfave/cliも情報がたくさんありました。
しかし、今回は Dockerのアドベントカレンダー
必然的にDockerに採用されているcobraを使うしかありません!


ソース

https://github.com/kohbis/dimg

※ 201919/12/22時点では、公式イメージ(library)だけ対応しています。


ポイント

タグ一覧取得

curlコマンドだと、下記でタグ一覧が取得できます。
(後述の公式ドキュメント参照)

curl -s https://registry.hub.docker.com/v2/repositories/library/alpine/tags/ | jq -r '.results|.[]|.name'

返ってくるJSONを、Goの構造体で表すとこうなります。
JSON->Structには、JSON-to-Goというサイトが、とても便利でした。

type Tags struct {
Count int `json:"count"`
Next string `json:"next"`
Previous interface{} `json:"previous"`
Results []struct {
Name string `json:"name"`
FullSize int `json:"full_size"`
Images []struct {
Size int `json:"size"`
Digest string `json:"digest"`
Architecture string `json:"architecture"`
Os string `json:"os"`
OsVersion interface{} `json:"os_version"`
OsFeatures string `json:"os_features"`
Variant interface{} `json:"variant"`
Features string `json:"features"`
} `json:"images"`
ID int `json:"id"`
Repository int `json:"repository"`
Creator int `json:"creator"`
LastUpdater int `json:"last_updater"`
LastUpdaterUsername string `json:"last_updater_username"`
ImageID interface{} `json:"image_id"`
V2 bool `json:"v2"`
LastUpdated time.Time `json:"last_updated"`
} `json:"results"`
}

このままだと1ページあたり10件しか取得できないため Next に次ページのURLがnullにならない限りループして、、、という面倒くさいことになります。
そのため、最初からクエリパラメータ ?page_size=10000 をつけて取得しています。
(そんなにタグ数があるイメージってあるのかしら)

タグ検索

promptuiは自前のsearcherを実装することができます。(感動)
これにより、マイナーバージョンが多い言語の実行環境イメージも見つけやすくなっています。

$ go run main.go
Image Name: ruby
Searching "ruby" tags...
"ruby" has 615 tags.
Search: 2.6.█
? Select Tag:
▸ 2.6.5-stretch
2.6.5-slim-stretch
2.6.5-slim-buster
2.6.5-slim
↓ 2.6.5-buster

cobraも、promptuiも色々できることがありそうなので、今後拡張していきたいです。


まとめ

Docker アドベントカレンダー担当日の1日前に思いたったのですが、ライブラリが非常に強力で1日かからずにものをつくることができました!

今回作ったものは足りないところがたくさんありますが、実際つくってみると個人的には欲しい機能がどんどん思いついていきたので、今後継続的に開発していきたいと思います。

実は今年最初やりたいことのひとつに「CLIツールをつくる」がありまして、ぎりぎり達成することができたのでよかったです!!
(この記事を書いている最終に思い出しました笑)

参考

Examples using the Docker Engine SDKs and Docker API
How do I authenticate with the V2 API?

どうでもいいからささっとGoでCLIつくりたいとき
Go初心者がGoでコマンドラインツールの作成に挑戦した話