最初に結論を書きます。めちゃくちゃに手を抜きまくっても意外と大丈夫です。
https://github.com/hytdsh/minimalpacker
動機
Vagrant を使うのに他所から box をダウンロードするのがダルいというか遅いのが我慢できませんでした。
他所からダウンロードした box に何が入ってるのかよくわからなくて落ち着かないのもフラストレーションでした。
いまいち中身のはっきりしない box をホイホイと使うのはダメなのでは?
かといって Vagrant を捨てた挙句に「画面遷移ごとに手入力してインストールした仮想マシン」に回帰するのも as Code の観点からどうなの?
⇒ box を手元で自動的に作成できれば良いのでは
ダウンロードした box だと VirtualBox の更新に追随しないのがツラい・・・Guest Additions を入れなおすのが面倒くさい・・・
⇒ box を手元で自動的に作成できれば VirtualBox の更新に追随するのも楽なのでは
box が秘伝のタレ化する予感がある
⇒ box を手元で自動的に作成できれば気軽にリセットできて秘伝のタレ化を回避できるのでは
https://github.com/chef/bento とか、もちろん便利なんだとは思います。
ですが、汎用のレシピとかは対象が多すぎて、どのファイルが必要でそのファイルが不要か、見分けるだけで疲れてしまうのも否めません。
⇒⇒⇒ 簡潔な Packer の構成が欲しい!!!
わりと頑張ったところ
とにかく記述を軽くした
どこまでデフォルト設定を活かせるか、定石の書き方からかなり削ったつもりです。
限界を詰めたわけではないので、まだ削れる余地はあるかもしれませんが、まあまあ軽量になったのではないかと思います。
Base Box としての最低限の機能
限界まで手を抜きつつも Vagrant が提示する Base Box としての要件 は満たしています。
- vagrant/vagrant なユーザーアカウントに SSH でログインできる
- root/vagrant になっている
- vagrant ユーザーがパスワード無しで sudo できる
- Guest Additions がインストールされている
- 副作用として
vagrant up
で仮想マシン内の/vagrant
ディレクトリがデフォルトで共有される
- 副作用として
preseed だけで hostname
を指定できる
Packer 系の記事で preseed ファイルを HTTP で渡しつつ、その渡した preseed ファイルの中では
netcfg/get_hostname
でホスト名を指定している、という内容をよく見ますが、そのままだと(append 行で指定するなどしないと)たぶん実際に出来上がるマシンのホスト名は "debian" とか "ubuntu" とかの、デフォルト名になってしまうのではないでしょうか。
少なくとも自分の手元で試した限りでは netcfg/get_hostname
や netcfg/hostname
のみの指定ではホスト名の反映ができませんでした。
これは preseed を HTTP で渡すと確定で発生する仕様であるようです。
同文書に記載のある kill-all-dhcp; netcfg
を採用して preseed 内でホスト名を指定できるようにしています。
手元の環境では netcfg/hostname
による指定を併用する必要がありました。
微妙にいけてないところ
"boot_command"
がダサい
率直に言って <wait>
とか使いたくないです。
Packer が失敗する時は、たいてい "boot_command"
の送出がチャタリングしてブートできていないケースです。
本稿の手順の中で最も脆弱なポイントで可能な限り回避したい箇所です。
ホストが Linux とか macOS とかなら netboot.tar.gz
を VirtualBox の TFTP 配下に展開してちょっと pxelinux.cfg/default
をいじってから Packer に渡す JSON の中で "vboxmanage"
と "vboxmanage_post"
に --nattftpfile
や --boot
などを指定してブートデバイスを変更してやれば "boot_command"
の使用を回避(空文字列の指定)できるのではないかと思います(未確認)。
Windows ホストの VirtualBox では主にシンボリックリンク周りが思うように取り回せず、ひとまず諦めました。
netboot.tar.gz
から必要なファイルを拾って TFTP 配下に置けばうまく行くかもしれません。
config.ssh.password
の指定が必要
初回の vagrant up
の時だけ config.ssh.password = "vagrant"
の指定が必要です。
これは Packer の工程で insecure keypair を導入していないためです。
vagrant up
の際の手間と鍵ペアの導入の手間を考えて、今回は鍵ペア導入の手間を回避しました。
成果物
https://github.com/hytdsh/minimalpacker
対象は VirtualBox のみです。
Packer に渡す JSON は40行。
Debian インストーラーに渡す preseed は50行(コメントを除く)。
Guest Addition の追加に使うシェルスクリプトは10行。
総計100行ほどと、あらかじめ用意しておいた ISO ファイル(50MBくらい)を使って packer build
を叩いてから20分(Core i5 M520, 8GB)程度でファイルサイズ約1GBの box が作成できます。
作成中はネットワーク帯域をそれなりに使います。
おまけ
ファイルの改行コードは気にしなくて良い
例えば chef/bento
ではしっかり .gitattributes
で改行コードを明示的に扱っていたりしています。
それはやっぱり普段の作業では改行コードに気を付けるほうが良いのはわかっていますが、本件に関しては改行コードは各サービスがよろしく扱ってくれるようで、全く気にしなくて良いです。
preseed ファイルとかも CR-LF で大丈夫です。
これは preseed ファイルを渡すのに使う HTTP がうまいことやってくれているんだと思われます。たぶん。
(同じ理由で kickstart ファイルも HTTP で渡す限りは改行コードを気にしなくて良いように思いますが、確認はしていません。)
他のファイルの改行コードも Packer や Vagrant がうまいこと扱ってくれるようです。
共有フォルダの設定は明示しなくて良い
Guest Additions のインストールに成功していれば Vagrant はデフォルトで仮想マシン内の /vagrant
を synced_folder
として共有してくれます。
今後の展望
Windows Subsystem for Linux が daemon を普通に扱えるようになったら、本稿の内容は不要になるかもしれません。