Vagrantには、仮想マシンを構築する際にプロビジョニングという、仮想マシン上のOSに対してさまざまな処理を実行することができる。
このプロビジョニングの機能を使って、例えば仮想マシン上のOSにソフトウェアをあらかじめインストールしたり、環境を構築したりすることができる。
僕の場合は、仮想マシンでRISC-Vの開発環境を構築する際に、必要なソフトウェアを全部ダウンロードして、ビルドする環境を構築している。例えば仮想マシンを構築する際、以下のように記述することでプロビジョニングを実行できる。
vagrant up --provision
Vagrantfileには以下のようなプロビジョニング用の記述が入っている。ここでは、プロビジョニングツールとしてはChefを利用している。
config.vm.provision "chef_solo" do |chef| chef.cookbooks_path = "./riscv-repo/site-cookbooks" chef.roles_path = "./riscv-repo/roles" chef.data_bags_path = "./riscv-repo/data_bags" chef.add_recipe "riscv-tools" # chef.add_role "web" # You may also specify custom JSON attributes: # chef.json = { mysql_password: "foo" } end
さらに、プロビジョニングにより具体的にどのような処理を行わせるかは、./riscv-repo/site-cookbooks/riscv-tools/recipes/default.rb
に記述されている。
execute "sed apt-source" do command "sed -i -e 's%http://archive.ubuntu.com/ubuntu%http://ftp.iij.ad.jp/pub/linux/ubuntu/archive%g' /etc/apt/sources.list" end.run_action(:run) execute "update package index" do command "apt-get update" ignore_failure true action :nothing end.run_action(:run) ...
FreeBSDなど、デフォルトでBashがインストールされていない場合
どうやらVagrantの環境は、対象OSにはデフォルトでBashかShが入っていることが前提になっているようだ。ところが、FreeBSDはデフォルトでcshがインストールされており、Bashはインストールすらされていない。
この場合、プロビジョニングを実行すると、以下のようなエラーが発生して実行できなかった。
export: Command not found
export
は明らかにbashの構文なので、cshの環境を想定していないようだ。sshのデフォルトのシェルを変更することもできるが、これはプロビジョニングの環境を変更する、というものではなく、効果は無い。
config.ssh.shell = "csh"
しばらくここで突っ掛かっており、FreeBSDでのプロビジョニングを行う環境を作れていなかったのだが、結局少し邪道な方法だが、一度FreeBSDにプロビジョニング無しでログインし、bashをインストールしてから再度プロビジョニングするという荒技を実行することにした。
# ホストOS コマンドプロンプトにて vagrant ssh # FreeBSD csh上にて sudo pkg install bash
これでプロビジョニングを行う。 このとき、やはりChefの構文ではうまく動作しないため、cshのスクリプトを用意し、単純にそれを実行する。
- Vagrantfile (一部)
config.vm.provision "shell", path: "provision.csh"
- provision.sh (一部)
#!/bin/csh pkg update -f pkg install -y bison gmp mpfr mpc git subversion gawk
これで、FreeBSDのようなBashを持たない環境でも、プロビジョニングできるようになった。
一応Makefileにまとめて、自動的に実行できるようにしたいが、最初にプロビジョニング無しで実行する方法が良く分からない。下記の環境では、何回かmake
を叩く必要がある。
up: vagrant up vagrant ssh --command "sudo pkg install -y bash" vagrant provision halt: vagrant halt destroy: vagrant destroy --force