FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

VagrantでBashの入っていないOSをプロビジョニングする際の注意点

f:id:msyksphinz:20160520003556j:plain

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