「Vagrantで、apt-get upgradeを含んだプロビジョニングで発生するエラーについて」
はじめに
VagrantでUbuntu14.04 Serverの環境構築を行っていたところ、今まで成功していたプロビジョニングのコードが失敗するようになりました。
調査の結果、原因と解決方法を以下にまとめます。
作業環境
ホストOS
Ubuntu14.04 Desktop 64bit
Vagrant 1.6.3
VirtualBox 4.3.12.r93733
ゲストOS
Ubuntu14.04 Server 64bit
概要
- プロビジョニングが失敗した時の状態
- 原因の調査
- 解決方法の調査
- 解決方法
- まとめ
1.プロビジョニングが失敗した時の状態
環境構築に使用したコード
Vagrantfile
# -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "ubuntu1404" config.vm.provision :shell, inline:<<-EOS apt-get upgrade apt-get -y upgrade EOS end
失敗した時の出力(抜粋)
... ==> default: Package configuration┌──────────────────────────┤ Configuring grub-pc ├──────────────────────────┐│││ The GRUB boot loader was previously installed to a disk that is no││ longer present, or whose unique identifier has changed for some reason. ││ It is important to make sure that the installed GRUB core image stays in ││ sync with GRUB modules and grub.cfg. Please check again to make sure││ that GRUB is written to the appropriate boot devices.││││ If you're unsure which drive is designated as boot drive by your BIOS, ││ it is often a good idea to install GRUB to all of them.││││ Note: it is possible to install GRUB to partition boot records as well, ││ and some appropriate partitions are offered here. However, this forces ││ GRUB to use the blocklist mechanism, which makes it less reliable, and ││ therefore is not recommended.││││<Ok>│││└───────────────────────────────────────────────────────────────────────────┘ ==> default: Failed to open terminal.64 (1:5.14-2ubuntu3.1) ... ==> default: debconf: whiptail output the above errors, giving up! ==> default: dpkg: error processing package grub-pc (--configure): ==> default: subprocess installed post-installation script returned error exit status 255 ...
2.原因の調査
失敗時の出力からプロビジョニング中にgrub-pcの設定画面を開こうとして失敗していることが分かります。
プロビジョニング中に入力を求める設定画面は使用できません。
この設定画面を回避する必要があります。
何故、grub-pcパッケージの設定画面が開くようになったか?
apt-get upgradeで更新対象になっているので、BOXファイル作成時よりgrub-pcのバージョンが上がった事が推測できます。
プロビジョニングをせずに、環境を構築しSSHで接続後、grub-pcパッケージのバージョンを確認します。
vagrant@ubuntu-1404:~$ sudo dpkg --list | grep grub ii grub-common 2.02~beta2-9 amd64 GRand Unified Bootloader (common files) ii grub-gfxpayload-lists 0.6 amd64 GRUB gfxpayload blacklist ii grub-pc 2.02~beta2-9 amd64 GRand Unified Bootloader, version 2 (PC/BIOS version) ii grub-pc-bin 2.02~beta2-9 amd64 GRand Unified Bootloader, version 2 (PC/BIOS binaries) ii grub2-common 2.02~beta2-9 amd64 GRand Unified Bootloader (common files for version 2)
「2.02-beta2-9」である事が分かります。
次に手入力で、apt-get upgradeを行います。
設定画面が表示されるのですが、何故かGRUBのインストール先デバイスの問い合せです(原因は後ほど)。
構築している仮想環境のHDDは1つなので、/dev/sda (42949 MB: VBOX_HARDDISK)にチェックを入れてOKとします。
ちょっと小さいですが whiptail を使用した画面が表示されることの確認です。
apt-get upgrade後の、grub-pcパッケージのバージョンを確認します。
vagrant@ubuntu-1404:~$ sudo dpkg --list | grep grub sudo dpkg --list | greo grub ii grub-common 2.02~beta2-9ubuntu1 amd64 GRand Unified Bootloader (common files) ii grub-gfxpayload-lists 0.6 amd64 GRUB gfxpayload blacklist ii grub-pc 2.02~beta2-9ubuntu1 amd64 GRand Unified Bootloader, version 2 (PC/BIOS version) ii grub-pc-bin 2.02~beta2-9ubuntu1 amd64 GRand Unified Bootloader, version 2 (PC/BIOS binaries) ii grub2-common 2.02~beta2-9ubuntu1 amd64 GRand Unified Bootloader (common files for version 2)
「2.02-beta2-9ubuntu1」にバージョンが変わっています。
「UbuntuUpdates.org」で確認すると「2.02-beta2-9」をベースにしてパッチが当たってるようです。
http://www.ubuntuupdates.org/package/core/trusty/universe/updates/grub2
grub-pcのバージョンが上がったことは確認できました。
3.解決方法の調査
この設定画面を非表示で/dev/sdaが選択される方法を考えます。
環境変数 DEBIAN_FRONTEND に noninteractive を設定後、デフォルト値を指定してupgradeする方法を考えましが、今回の問題を解決することはできませんでした。
別の方法を調べていたところ、debianには自動化のための設定値をテキストファイルではなくデータベースで与える仕組みがあることが分かりました。
その仕組みに対応しているパッケージでは、データベースから設定値を取得するそうです。
データベースを操作するコマンドとして、debconf系のコマンドが用意されています。
設定と参照に使用するコマンドの例
設定(パッケージ/項目単位)
$ echo "set grub-pc/install_devices /dev/sda" | debconf-communicate
参照(パッケージ/項目単位)
$ echo "get grub-pc/install_devices /dev/sda" | debconf-communicate
参照(パッケージ単位)
$ debconf-show grub-pc
grub-pcパッケージは、この仕組みに対応しているようです。
検証のために、環境を再構築して upgrade 実行前に戻します。
upgrade 前にgrub-pcの設定値を確認します。
vagrant@ubuntu-1404:~$ sudo debconf-show grub-pc grub2/linux_cmdline_default: quiet splash grub-pc/kopt_extracted: false grub-pc/mixed_legacy_and_grub2: true grub-pc/postrm_purge_boot_grub: false grub-pc/install_devices_empty: false grub-pc/install_devices_disks_changed: grub2/linux_cmdline: grub-pc/hidden_timeout: true grub2/kfreebsd_cmdline: grub-pc/disk_description: grub2/kfreebsd_cmdline_default: quiet splash * grub-pc/install_devices: /dev/disk/by-id/ata-VBOX_HARDDISK_VB36ceb79a-609a9c78 grub-pc/timeout: 10 grub-pc/chainload_from_menu.lst: true grub-pc/install_devices_failed_upgrade: true grub-pc/partition_description: grub2/device_map_regenerated: grub-pc/install_devices_failed: false
これから設定する予定の install_devices に値が設定されていますが、/dev/sda ではなく/dev/disk/by-id 以下のパスになってます。
ちょっと、/dev/disk/by-id 以下を覗いてみます。
vagrant@ubuntu-1404:~$ ll /dev/disk/by-id total 0 drwxr-xr-x 2 root root 200 Aug 8 13:58 ./ drwxr-xr-x 4 root root 80 Aug 8 13:58 ../ lrwxrwxrwx 1 root root 9 Aug 8 13:58 ata-VBOX_HARDDISK_VBe49e1f29-745fffe8 -> ../../sda lrwxrwxrwx 1 root root 10 Aug 8 13:58 ata-VBOX_HARDDISK_VBe49e1f29-745fffe8-part1 -> ../../sda1 lrwxrwxrwx 1 root root 10 Aug 8 13:58 ata-VBOX_HARDDISK_VBe49e1f29-745fffe8-part2 -> ../../sda2 lrwxrwxrwx 1 root root 10 Aug 8 13:58 ata-VBOX_HARDDISK_VBe49e1f29-745fffe8-part5 -> ../../sda5 lrwxrwxrwx 1 root root 10 Aug 8 13:59 dm-name-ubuntu--1404--vg-root -> ../../dm-0 lrwxrwxrwx 1 root root 10 Aug 8 13:59 dm-name-ubuntu--1404--vg-swap_1 -> ../../dm-1 lrwxrwxrwx 1 root root 10 Aug 8 13:59 dm-uuid-LVM-RCIg1EIc6CV1RnqFdUzmRFCB3TyX01FBj9TLfcBDKgLxCDXaac9gZ9FnuetB2xmM -> ../../dm-0 lrwxrwxrwx 1 root root 10 Aug 8 13:59 dm-uuid-LVM-RCIg1EIc6CV1RnqFdUzmRFCB3TyX01FBnmTl3brIQysPjdZwUTwfqdwChucxk6jW -> ../../dm-1 vagrant@ubuntu-1404:~$
現在の設定値に相当するパスが存在していません。
結論から言うと、BOXファイルから環境を構築する度に VBOX_HARDDISK_VB~のid部分が変わります。
データベース上の設定値は更新されません。
よって、実在しないパスとなり、grub-pcパッケージはインストール先を問い合せる画面を表示することになります。
環境変数 DEBIAN_FRONTEND でも表示を抑えられなかった理由はこれです。
では、手入力により解決できるか検証します。
設定値の登録と確認
debconf-コマンドの実行には root権限が必要となります。
プロビジョニング中はコマンドが root権限で実行されますが手入力なので sudo が必要です。
vagrant@ubuntu-1404:~$ sudo sh -c 'echo "set grub-pc/install_devices /dev/sda" | debconf-communicate' 0 value set vagrant@ubuntu-1404:~$ sudo sh -c 'echo "get grub-pc/install_devices" | debconf-communicate' 0 /dev/sda vagrant@ubuntu-1404:~$
upgradeの実行
vagrant@ubuntu-1404:~$ sudo apt-get -y upgrade ... Setting up grub-common (2.02~beta2-9ubuntu1) ... Setting up grub2-common (2.02~beta2-9ubuntu1) ... Setting up grub-pc-bin (2.02~beta2-9ubuntu1) ... Setting up grub-pc (2.02~beta2-9ubuntu1) ... Installing for i386-pc platform. Installation finished. No error reported. Generating grub configuration file ... Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported. Found linux image: /boot/vmlinuz-3.13.0-24-generic Found initrd image: /boot/initrd.img-3.13.0-24-generic done Setting up linux-firmware (1.127.5) ... Setting up language-pack-en (1:14.04+20140707) ... Setting up language-pack-en-base (1:14.04+20140707) ... Generating locales... en_AG.UTF-8... up-to-date en_AU.UTF-8... up-to-date en_BW.UTF-8... up-to-date en_CA.UTF-8... up-to-date en_DK.UTF-8... up-to-date en_GB.UTF-8... up-to-date en_HK.UTF-8... up-to-date en_IE.UTF-8... up-to-date en_IN.UTF-8... up-to-date en_NG.UTF-8... up-to-date en_NZ.UTF-8... up-to-date en_PH.UTF-8... up-to-date en_SG.UTF-8... up-to-date en_US.UTF-8... up-to-date en_ZA.UTF-8... up-to-date en_ZM.UTF-8... up-to-date en_ZW.UTF-8... up-to-date Generation complete. Setting up language-pack-gnome-en (1:14.04+20140707) ... Setting up language-pack-gnome-en-base (1:14.04+20140707) ... Processing triggers for libc-bin (2.19-0ubuntu6.1) ... Processing triggers for ureadahead (0.100.0-16) ... Processing triggers for initramfs-tools (0.103ubuntu4.2) ... update-initramfs: Generating /boot/initrd.img-3.13.0-24-generic vagrant@ubuntu-1404:~$ sudo dpkg --list | grep grub ii grub-common 2.02~beta2-9ubuntu1 amd64 GRand Unified Bootloader (common files) ii grub-gfxpayload-lists 0.6 amd64 GRUB gfxpayload blacklist ii grub-pc 2.02~beta2-9ubuntu1 amd64 GRand Unified Bootloader, version 2 (PC/BIOS version) ii grub-pc-bin 2.02~beta2-9ubuntu1 amd64 GRand Unified Bootloader, version 2 (PC/BIOS binaries) ii grub2-common 2.02~beta2-9ubuntu1 amd64 GRand Unified Bootloader (common files for version 2) vagrant@ubuntu-1404:~$
4.解決方法
今回の問題に対応したプロビジョニングのコードを含んだ Vagrantfile の内容が以下になります。
debconf-communicate の一行を追加しただけですが・・・
# -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "ubuntu1404" config.vm.provision :shell, inline:<<-EOS echo "set grub-pc/install_devices /dev/sda" | debconf-communicate apt-get update apt-get -y upgrade EOS end
5.まとめ
実際に問題が発生した Vagrantfile は、もっと複雑な処理を行っていたのですが、変更していない箇所でエラーが発生していたので原因の特定に回り道をしてしまいました。
今回初めて debconf関連の情報を知ることができて良かった。
これで、この仕組みに対応している他のパッケージで同じ問題が発生しても悩む事はなさそうです♪