scramble cadenza

技術ネタのガラクタ置き場

packer 触っててハマった時は veewee 眺めると幸せになれる

イントロ

veewee じゃなくて packer 触ってみた話。今だからこそ veewee のおさらい

何故タイトルのようなことを思うかと言うと 「veewee」で作られたテンプレートが、ありとあらゆる地雷を潜り抜けて作られた物だから です。

私は基本的にpacker の公式を読みながらテンプレート作っていきました。非常にわかりやすいのですが、何もない状態から作ろうとすると当然詰まったところもあるわけで。そんな時に veewee にお世話になりましたよ、というお話です。

今回作ったのは ubuntu 10.4 で virtualbox 用の box です。

(Q&A 形式っぽくしてみました)

Q. proceed.cfg が見つからない

現象

f:id:mgi:20131209232434p:plain

原因

  • ubuntu を boot するコマンドをまとめたファイル(preceed.cfg)が見つからない、という内容
    • 当然ながら、これがないと ubuntu 立ち上がらない

A. 解決法

  • packer は virtualbox から http 経由でローカルマシンにあるファイルを参照できる
  • http_directory を指定する
    • ローカルマシンの 現在の directory から見た、preseed.cfg が置かれている directory の相対パス を指定する
      • 'preseed.cfg' まで書いてしまうと失敗するので、directory を書く。
      • 今回は ./templates/ubuntu-12.04.3-server-amd64/preseed.cfg に置いてある前提。
    • ファイル名ではなく、directory を指定する
    • 公式だと ここに書いていてある
{
  "builders" : [{
     ....
     "http_directory": "./templates/ubuntu-12.04.3-server-amd64/",
     }]
}

Q. ssh login で失敗する

現象

==> virtualbox: Downloading or copying Guest additions checksums
    virtualbox: Downloading or copying: http://download.virtualbox.org/virtualbox/4.2.18/SHA256SUMS
==> virtualbox: Downloading or copying Guest additions
    virtualbox: Downloading or copying: http://download.virtualbox.org/virtualbox/4.2.18/VBoxGuestAdditions_4.2.18.iso
==> virtualbox: Downloading or copying ISO
    virtualbox: Downloading or copying: http://releases.ubuntu.com/12.04/ubuntu-12.04.3-server-amd64.iso
==> virtualbox: Starting HTTP server on port 8081
==> virtualbox: Creating virtual machine...
==> virtualbox: Creating hard drive...
==> virtualbox: Creating forwarded port mapping for SSH (host port 3213)
==> virtualbox: Executing custom
    virtualbox: Executing: modifyvm packer-virtualbox --memory 1024
    virtualbox: Executing: modifyvm packer-virtualbox --cpus 1
==> virtualbox: Starting the virtual machine...
==> virtualbox: Waiting 10s for boot...
==> virtualbox: Typing the boot command...
==> virtualbox: Waiting for SSH to become available...
==> virtualbox: Error waiting for SSH: handshake failed: ssh: unable to authenticate, attempted methods [none password], no supported methods remain
==> virtualbox: Unregistering and deleting virtual machine...
==> virtualbox: Deleting output directory...
Build 'virtualbox' errored: Build was halted.

原因

  • パスワードが間違っていてログインできなかった
    • 直す箇所が 2 箇所あって片方間違えるとうまくいかないので、気をつける

A. 解決法

  • パスワードを統一する
    • 今回は vagrant で使う予定なので、username, password ともに vagrant にした
    • shutdown_command でも 'vagrant' とするのを忘れずに。
      • これを忘れてて少しハマった。

template.json

{
  "builders" : [{
     ....
    "ssh_username": "vagrant",
    "ssh_password": "vagrant",
    "shutdown_command": "echo 'vagrant' | sudo -S shutdown -P now",
     ....
  }],

preseed.cfg

d-i passwd/user-fullname string vagrant
d-i passwd/username string vagrant
d-i passwd/user-password password vagrant
d-i passwd/user-password-again password vagrant

Q. vagrant up でタイムアウトする

現象

[default] Waiting for machine to boot. This may take a few minutes...
Timed out while waiting for the machine to boot. This means that
Vagrant was unable to communicate with the guest machine within
the configured ("config.vm.boot_timeout" value) time period. This can
mean a number of things.

If you're using a custom box, make sure that networking is properly
working and you're able to connect to the machine. It is a common
problem that networking isn't setup properly in these boxes.
Verify that authentication configurations are also setup properly,
as well.

If the box appears to be booting properly, you may want to increase
the timeout ("config.vm.boot_timeout") value.

と言われて落ちる。

原因

2つあった。

  • build に -force オプションを付けてなかったせいで、古い box が使われていた。
    • 修正した内容を build したつもりが、実はキャッシュが使われていた
  • これも実は ssh で失敗していることが原因
    • ログをデバッグレベルで出すと、確認できる
    • ssh の認証でこけていることが、最後のログでわかる。
$ VAGRANT_LOG=debug vagrant up

#=>
D, [2013-12-01T10:32:13.851119 #66421] DEBUG -- tcpsocket[8059b19c]: received packet nr 5 type 51 len 44
D, [2013-12-01T10:32:13.851397 #66421] DEBUG -- net.ssh.authentication.session[80440464]: allowed methods: publickey,password
D, [2013-12-01T10:32:13.851553 #66421] DEBUG -- net.ssh.authentication.session[80440464]: trying password
E, [2013-12-01T10:32:13.851825 #66421] ERROR -- net.ssh.authentication.session[80440464]: all authorization methods failed (tried none, publickey, password)

A. 解決法

  • -force オプションを付けて再 build
packer build -force templates.json 
  • setup_ssh.sh のようなスクリプトを作って、provisioner で呼び出した
    • 何もしないと ssh でログインする準備が整ってない。
    • veewee での vagrant.sh に相当する。 そのまま拝借してきた。
mkdir -pm 700 /home/vagrant/.ssh
curl -Lo /home/vagrant/.ssh/authorized_keys \
  'https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub'
chmod 0600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant:vagrant /home/vagrant/.ssh

Q. curl が無いと言われる

現象

==> virtualbox: Uploading VirtualBox version info (4.2.18)
==> virtualbox: Uploading VirtualBox guest additions ISO...
==> virtualbox: Provisioning with shell script: templates/ubuntu-12.04.3-server-amd64/setup_ssh.sh
    virtualbox: /tmp/script.sh: line 3: curl: command not found
    virtualbox: chmod: cannot access `/home/vagrant/.ssh/authorized_keys': No such file or directory
    virtualbox:
    virtualbox:

と言われて落ちる。

原因

  • 上の setup_ssh.sh の 2 行目の curl コマンドを実行しようとして、そんなコマンドねーよと言われている

A. 解決法

2つやらなければならない

  • curl の install
    • install.sh というファイルを作る。
apt-get -y install curl
  • provisioner で sudo 権限で実行できるように設定する
    • sudo 権限が必要な apt-install 系を実行したいならば、この設定が必要。
    • "override": のあたりを追加
{
  "provisioners": [{
    "type": "shell",
    "scripts": [
      "templates/ubuntu-12.04.3-server-amd64/setup_ssh.sh"
    ],
    "override": {
      "virtualbox": {
      "execute_command": "echo 'vagrant' | {{ .Vars }} sudo -E -S sh '{{ .Path }}'"
      }
    }
  }],
}

Q. "vboxsf" file system is not available と言われる

現象

[default] Mounting shared folders...
[default] -- /vagrant
Failed to mount folders in Linux guest. This is usually beacuse
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` /vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` /vagrant /vagrant

と言われる。

原因

  • shared folder をうまく共有できていない
    • vagrant は /vagrant 配下を shared folder にして、ローカルマシンとホストマシンでファイルを橋渡しする仕組みを持っている。
      • vagrant ssh して ls /vagrant してみると、どんなことが行われているか、ひと目で分かる。
    • shared folder 設定ができないと、provisioning ができず。
      • 公式だとここに説明が書いてある。

A. 解決法

  • vagrant plugin install vagrant-vbguest
    • vagrant のプラグインを install する。
  • 必要なものを install していくが、何を install すれば良いかは veewee の base.sh に書いてある。 そのまま拝借。
    • 必要だってコメントにそのまんま書いてあるし...
# Apt-install various things necessary for Ruby, guest additions,
# etc., and remove optional things to trim down the machine.
apt-get -y update
apt-get -y upgrade
apt-get -y install gcc build-essential linux-headers-$(uname -r)
apt-get -y install zlib1g-dev libssl-dev libreadline-gplv2-dev libyaml-dev
apt-get -y install vim curl
apt-get clean

まとめ

  • veewee のシェルスクリプトを読むと「あ、この現象を回避するために必要なんだな」が理解できることがあります。
  • 問題に遭遇した時に debug は難しいけど VAGRANT_LOG=debug で 環境変数与えて vagrant up で何かわかるかも。
    • ダメなら google 先生をどつく。