Vagrant + PowerShellをJenkinsで使った時にハマったときのメモ

NSEG #39で「おひとりさま環境での Chef-solo 使用例」を発表した時に

を使いましたが、いくつかハマった点があったため、メモを残しておきます。


Jenkinsの実行ユーザーの指定

自分のユーザーでJenkinsを実行させたかったため、Jenkinsサービスのログオンの指定を「Local System」から「自分のユーザーアカウント」へと切り替えます。
(サービスのログオンタブにて、「●アカウント」とし、自分のアカウントを指定)



PowerShellをJenkinsで実行させるには

プラグインの導入

素の状態ではPowerShellを実行できないため、以下のプラグインを導入します。手元のバージョンは、1.2でした。

セキュリティポリシーの変更

何もしていない状態だと、PowerShellファイル(*.ps1)は実行することができません。そのため、セキュリティポリシーを変更し、実行できるようにします。
なお、64bitOSの場合、PowerShellx64版とx86版がありますが、Jenkinsはx86版を使用していました。


参考:

環境変数の追加

JenkinsでVagrantを便利に実行するため、以下の環境変数を設定します。

VBOX_USER_HOME

Jenkinsで作成した仮想マシンは、デフォルトでは以下のディレクトリに作成されるようです*1

C:\Windows\System32\config\systemprofile\VirtualBox VMs


上記は、Local Systemアカウントのプロファイルの場所のようです。
参考:windows server 2008 - Where does the LOCAL SYSTEM account store its "personal" files? - Server Fault


ただ、Cドライブの下にできるといろいろと不都合であったため、場所を移動します。
場所を移動するには、環境変数「VBOX_USER_HOME」を設定すれば良いようなので、適当なところ(「D:\vms」など)を指定しておきます。


参考:

VAGRANT_HOME

Jenkinsで実行する際に利用する「.vagrant.d」ディレクトリを指定します。
自分のアカウントで実行する場合には、「%USERPROFILE%\.vagrant.d」を指定します。



PowerShellの記述

PowerShellからコマンドプロンプトを起動する

PowerShell上では「git clone」などは大丈夫だったのですが、「knife solo prepare」などが動作しませんでした。
そのため、一度コマンドプロンプトを起動してから、「knife solo prepare」を引数渡しで実行することにしました。

cmd /C "knife solo prepare vagrant@192.168.33.11 -P vagrant"


参考:PowerShell – DOS コマンドを実行する | ITLAB51.COM



エラー対応とか

ERROR: Errno::ECONNRESET: An existing connection was forcibly closed by the remote host.

vagrant halt」で仮想マシンを停止しない状態で、再度同じJenkinsのジョブを実行したところ、発生しました。
一度仮想マシンを停止させるか、仮想マシンを削除すると、問題なく動作しました。
同じVagrantfileで仮想マシンを作ろうとしたのが原因かと思います。

「knife solo init」でコケる

今回の範囲外ですが、knife-soloを0.3.0.pre3にして「knife solo init」したところ、エラーで落ちました。
必要なものがrequireされていなかったようなので、knife-solo.rbの先頭に、「require 'pathname'」を加えます。
ショートカット: knife solo init で起こるエラー uninitialized constant KnifeSolo::Pathname (NameError)

*1:ドキュメントが見当たらなかったので、Everything search engine を使って実際の出力先を調査

Windows7上で Vagrant + Chef solo + knife-solo の環境を構築した時に出会ったエラー

前回 は環境構築でしたが、試行錯誤する中で、いろいろとエラーに出会いました。
再び同じようなエラーに出会った時に読み返せるよう、エラーの内容と自分の対応を残しておきます。

環境

knife-soloのインストール時のエラー

knife-soloを --preオプションで入れたところ、以下のエラーとなりました。

gem install knife-solo --pre --no-ri --no-rdoc

ERROR:  While executing gem ... (Gem::DependencyError)
    Unable to resolve dependencies: knife-solo requires librarian (~> 0.0.20); c
hef requires net-ssh (~> 2.2.2)


自分の場合は、

gem install knife-solo -v 0.3.0.pre2 --no-ri --no-rdoc

のように、バージョンを指定してインストールすることで対応しました。



vagrant up」時のエラー (VERR_DISK_FULL)

d:\fuga>vagrant up

Bringing machine 'default' up with 'virtualbox' provider...
[default] Importing base box 'hoge'...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["import", "C:/Users//.vagrant.d/boxes/hoge/virtualbox/box.ovf"]

Stderr: 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Interpreting C:\Users\\.vagrant.d\boxes\hoge\virtualbox\box.ovf...
OK.
0%...
Progress state: VBOX_E_FILE_ERROR
VBoxManage.exe: error: Appliance import failed
VBoxManage.exe: error: Could not create the clone medium 'C:\Users\\VirtualBox VMs\ubuntu-cloudimg-precise-vagrant-i386\box-disk1.vmdk'.
VBoxManage.exe: error: VMDK: cannot write allocated data block in 'C:\Users\\VirtualBox VMs\ubuntu-cloudimg-precise-vagrant-i386/box-disk1.vmdk' (VERR_DISK_FULL)
VBoxManage.exe: error: Details: code VBOX_E_FILE_ERROR (0x80bb0004), component Appliance, interface IAppliance
VBoxManage.exe: error: Context: "int __cdecl handleImportAppliance(struct HandlerArg *)" at line 781 of file VBoxManageAppliance.cpp


途中のエラー「VERR_DISK_FULL」にもある通り、ディスクの容量が足りない時に表示されました。
そのため、不要になったVMは「vagrant destroy」で削除します。


なお、このエラーを調べているうちに、以下のパスが分かりました (いずれもデフォルトインストールした場合)。

項目
VagrantによるVMの作成先 %USERPROFILE%\VirtualBox VMs
VBoxManageの場所 C:\Program Files\Oracle\VirtualBox\VBoxManage


手元の環境ではCドライブの容量が少なかったため、VMの作成先をVirtualBoxのVBoxManage.exeにて変更しました。

# VMの作成先のフォルダを生成
d:\>mkdir vms

# 作成先を「d:\vms」の下へと変更
d:\vms>"C:\Program Files\Oracle\VirtualBox\VBoxManage" setproperty machinefolder d:\vms

参考:Chapter 8. VBoxManage



「knife-solo prepare」時のエラー

chef-repoの中で実行しなかった場合、最後のjsonファイル生成が失敗します。

knife solo prepare vagrant@192.168.33.10

Bootstrapping Chef...
(略)
Thank you for installing Chef!
Generating node config 'nodes/192.168.33.10.json'...
ERROR: Errno::ENOENT: No such file or directory - nodes/192.168.33.10.json

cookbookにて、apt-get update無し・「ubuntu-desktop」パッケージのインストールのみを記載し、実行した時のエラー

以下の通りです。ただ、再度同じように試してみた時は発生しませんでした...


D:\fuga\chef-repo\cookbooks\piyo\recipes\default.rb

package "ubuntu-desktop" do
  action :install
end


エラー内容

INFO: Processing package[ubuntu-desktop] action install (hello::default line 13)

================================================================================
Error executing action `install` on resource 'package[ubuntu-desktop]'
================================================================================

Chef::Exceptions::Exec
----------------------

apt-get -q -y install ubuntu-desktop=1.267 returned 100, expected 0

Resource Declaration:
---------------------

# In /tmp/vagrant-chef-1/chef-solo-1/cookbooks/piyo/recipes/default.rb

 12: #
 13: package "ubuntu-desktop" do
 14:   action :install
 15: end
 16:

Compiled Resource:
------------------

# Declared in /tmp/vagrant-chef-1/chef-solo-1/cookbooks/piyo/recipes/default.rb :13:in `from_file'

package("ubuntu-desktop") do
  retry_delay 2
  retries 0
  recipe_name "default"
  action [:install]
  cookbook_name :piyo
  package_name "ubuntu-desktop"
end

ERROR: Running exception handlers
ERROR: Exception handlers complete
FATAL: Stacktrace dumped to /tmp/vagrant-chef-1/chef-stacktrace.out
FATAL: Chef::Exceptions::Exec: package[ubuntu-desktop] (hello::default line 13) had an error: Chef::Exceptions::Exec: apt-get -q -y
install ubuntu-desktop=1.267 returned 100, expected 0
Chef never successfully completed! Any errors should be visible in the output above. Please fix your recipes so that they properly complete.


returned 100は、エラーがあったことを示すようです。
参考:Man page of APT-GET



knife solo prepare 時のエラー (2013/5/1 追記)

  1. vagrant up の後、いろいろとやる
  2. vagrant destroy で削除
  3. Vagrantfile内のPrivate IP設定を変更しないまま、再度 vagrant up して再度仮想マシンを作る
  4. knife solo prepare で以下のエラーが発生した
ERROR: Net::SSH::HostKeyMismatch: fingerprint 23:bc:39:d7:f3:dd:9a:1a:01:f3:3b:a4:ec:3b:9d:02 does not match for "192.168.33.10"


原因は、以下のファイル「known_hosts」に、destroyした仮想マシンののエントリが残っていたためです。

%USERPROFILE%\.ssh\known_hosts


そのため、known_hostsから不要なエントリを削除すれば、knife solo prepare することができます。

Windows7上で Vagrant + Chef solo + knife-soloを使い、Ubuntu + ubuntu-desktopの環境を構築してみた

VirtualBoxを使って検証的な環境を作ったり壊したりしているのですが、いい加減手作業はツライので、最近目にするChef関連の環境を構築してみました。
なお、構築にあたり、naoyaさんの本が非常に役立ちました。ありがとうございました。
入門Chef Solo - Infrastructure as Code - 達人出版会


ちなみに、手元のWindows環境では rsnyc がうまく設定できなかったせいか、knife-soloの「knife solo cook」がうまくできませんでした。githubにもissueが上がっているようです。
ただ、「knife solo init」「knife solo prepare」がとても便利なので、knife-soloも環境構築に加えてあります。

環境

  • ホストOS: Windows7 x64
  • VirtualBox: 4.2.10 (4/8追記)
  • Ruby: 1.9.3p392
  • Git: 1.8.2 (SSHクライアントを兼務)
  • Vagrant: 1.1.5
  • Chef: 11.4.0
  • knife-solo: 0.3.0pre2
  • レシピ: Ubuntu12.04を作り、apt-getでubuntu-desktopを入れる (apt-getを試したかったため、日本語Remixではないです)

環境設定

Ruby

RubyInstallerでインストールします。
RubyInstaller for Windows

Git

Git for Windowsでインストールします。
Git

SSHクライアント

knife-soloで使うため、SSHクライアントを入れておきます。
Gitのものでも問題ないため、ssh.exeにパスを通しておきます。デフォルトインストールの場合、以下を環境変数PATHに設定しておきます。

C:\Program Files (x86)\Git\bin\
Vagrant

msiファイルが配布されているので、そちらでインストールします。
Vagrant

Chef

今回、ドキュメント系は不要なため、以下でインストールします。

gem install chef --no-ri --no-rdoc
knife-solo

「--pre」オプション付きではエラーで落ちたため、以下でバージョン指定してインストールしました。

gem install knife-solo -v 0.3.0.pre2 --no-ri --no-rdoc
knife-soloの設定

knife configure以降は、基本EnterでOKです。

knife configure
WARNING: No knife configuration file found
Where should I put the config file? [C:/Users//.chef/knife.rb] (Enter)
Please enter the chef server URL: [http://localhost:4000] (Enter)
Please enter an existing username or clientname for the API: [] (Enter)
Please enter the validation clientname: [chef-validator] (Enter)
Please enter the location of the validation key: [/etc/chef/validation.pem] (Enter)
Please enter the path to a chef repository (or leave blank): (Enter)

You must place your client key in:
  C:/Users//.chef/.pem
Before running commands with Knife!

You must place your validation key in:
  C:/etc//validation.pem
Before generating instance data with Knife!

Configuration file written to C:/Users//.chef/knife.rb

ただ、自分の場合は実行時に以下のエラーが出たため、「ffi」gemを追加しました。
エラー

custom_require.rb:36:in `require':cannot load such file -- ffi (LoadError)


追加

gem install ffi --no-ri --no-rdoc

作業の流れ

1. VagrantのBoxを追加

今回は、以下にて公開されているBoxを追加します。
その中のうち、ubuntu.comで配布されている「Official Ubuntu 12.04 daily Cloud Image i386 (No Guest Additions)」を「hoge」という名前で追加します。 (それなりに時間がかかります)
A list of base boxes for Vagrant - Vagrantbox.es


なお、セキュリティの関係などで共有boxを利用できない場合は、veeweeを利用します。
参考:vagrant ユーザよ、その VM は安全なのか? (veewee のすゝめ) - Hack like a rolling stone


実行

vagrant box add hoge http://cloud-images.ubuntu.com/precise/current/precise-server-cloudimg-vagrant-i386-disk1.box

Downloading with Vagrant::Downloaders::HTTP...
Downloading box: http://cloud-images.ubuntu.com/precise/current/precise-server-cloudimg-vagrant-i386-disk1.box
Downloading box: http://cloud-images.ubuntu.com/vagrant/precise/current/precise-server-cloudimg-i386-vagrant-disk1.box
Extracting box...5118927 / 345303040)
Cleaning up downloaded box...
Successfully added box 'hoge' with provider 'virtualbox'!
2. 任意の場所にフォルダを作成・移動

今回はD直下に「fuga」というフォルダを作成します。

cd /d d:\
mkdir fuga
cd fuga
3. knife-soloを使って、Chef用のリポジトリを作成

事前に作成しておきます。作成結果は特に表示されません。

d:\fuga>knife solo init chef-repo
4. vagrantのchefをアップデート

Vagrant1.1.5時点では、少し古いChef10.14.2が入っていたため、一度VMを起動してChefのアップデートを行います。なお、Chefのアップデートが不要な場合には省略も可能です。


まずは上記で追加したbox「hoge」をもとに、VMのひな形を作ります。

d:\fuga>vagrant init hoge

A `Vagrantfile` has been placed in this directory. You are nowready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on vagrantup.com` for more information on using Vagrant.


作成されたVagrantfileを編集し、chef-soloからSSH接続ができるよう、private networkの設定をします。
D:\fuga\Vagrantfile の23行目あたり

# Create a private network, which allows host-only access to the machine
  # using a specific IP.
  # 以下をアンコメントします
  config.vm.network :private_network, ip: "192.168.33.10"

VMを起動します。

d:\fuga>vagrant up

Bringing machine 'default' up with 'virtualbox' provider...
(略)
[default] -- /vagrant


Chefのアップデートの他、Chefで必要な「192.168.33.10.json」ファイルを自動生成するため、chef-repoの中に入って、knife solo prepareを実行します。

d:\fuga>cd chef-repo
d:\fuga\chef-repo>knife solo prepare vagrant@192.168.33.10

Bootstrapping Chef...


途中でVagrantのパスワードが求められるので、「vagrant」を入力します。

Enter the password for vagrant@192.168.33.10: vagrant


  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  6471  100  6471    0     0   4156      0  0:00:01  0:00:01 --:--:--  5039
Downloading Chef 11.4.0 for ubuntu...
Installing Chef 11.4.0
Selecting previously unselected package chef.
(Reading database ... 61658 files and directories currently installed.)
Unpacking chef (from .../chef_11.4.0_i386.deb) ...
Setting up chef (11.4.0-1.ubuntu.11.04) ...
Thank you for installing Chef!
Generating node config 'nodes/192.168.33.10.json'...


recipeまわりの設定をするため、一度停止します。

d:\fuga\chef-repo>vagrant halt
5. recipeへの記載

まずはcookbookを作成します。今回はcookbook「piyo」をcookbooksフォルダへ作成します。

d:\fuga\chef-repo>knife cookbook create piyo -o cookbooks

 ** Creating cookbook ubuntu-desktop
 ** Creating README for cookbook: ubuntu-desktop
 ** Creating CHANGELOG for cookbook: ubuntu-desktop
 ** Creating metadata for cookbook: ubuntu-desktop


以下のrecipeファイルを編集します。
D:\fuga\chef-repo\cookbooks\piyo\recipes\default.rb
apt-getの前にパッケージのアップデートを行わないと、エラーでapt-getができないため、最初にその処理を行なっています。
参考:cookbook - Installing multiple packages via Vagrant + Chef - Stack Overflow

# 「update package index」の処理を記載
execute "update package index" do
  command "apt-get update"
  ignore_failure true
  action :nothing
end.run_action(:run)

# update が終わったことをログ出力
log "done update"

# 「ubuntu-desktop」パッケージをインストールする
package "ubuntu-desktop" do
  action :install
end

# ubuntu-desktop のインストールが終わったことをログ出力
log "done install"
6. 各設定ファイルの設定

上記で作成したrecipeを使うよう、各ファイルを設定します。

  • d:\hoge\Vagrantfile

74行目辺りに追加します。

  # Enable provisioning with chef solo, specifying a cookbooks path, roles
  # path, and data_bags path (all relative to this Vagrantfile), and adding
  # some recipes and/or roles.
  config.vm.provision :chef_solo do |chef|
    # cookbookのありか。Vagrantfileからの相対パス
    chef.cookbooks_path = "./chef-repo/cookbooks"

    # 使用するrecipeの名前
    chef.add_recipe "piyo"
  end
  • D:\fuga\chef-repo\nodes\192.168.33.10.json
{"run_list":[" recipe [ piyo ]"]}
7. VMの起動・インストール・終了

再度起動します。起動中にChefが走り、ubuntu-desktopがインストールされます (結構時間がかかります)。

d:\fuga\chef-repo>vagrant up

# 結果
[default] -- /tmp/vagrant-chef-1/chef-solo-1/cookbooks
[default] Running provisioner: VagrantPlugins::Chef::Provisioner::ChefSolo...
Generating chef JSON and uploading...
Running chef-solo...
stdin: is not a tty
[2013-04-06T21:48:13+00:00] INFO: *** Chef 11.4.0 ***
[2013-04-06T21:48:14+00:00] INFO: Setting the run_list to ["recipe[piyo]"] from JSON
[2013-04-06T21:48:14+00:00] INFO: Run List is [recipe[piyo]]
[2013-04-06T21:48:14+00:00] INFO: Run List expands to [piyo]
[2013-04-06T21:48:14+00:00] INFO: Starting Chef Run for vagrant-ubuntu-precise-2
[2013-04-06T21:48:14+00:00] INFO: Running start handlers
[2013-04-06T21:48:14+00:00] INFO: Start handlers complete.
[2013-04-06T21:48:14+00:00] INFO: Processing execute[update package index] actin run (piyo::default line 11)
[2013-04-06T21:48:25+00:00] INFO: execute[update package index] ran successfull
[2013-04-06T21:48:25+00:00] INFO: Processing execute[update package index] actin nothing (piyo::default line 11)
[2013-04-06T21:48:25+00:00] INFO: Processing log[done update] action write (piyo::default line 18)
[2013-04-06T21:48:25+00:00] INFO: done update
[2013-04-06T21:48:25+00:00] INFO: Processing package[ubuntu-desktop] action install (piyo::default line 21)
[2013-04-06T22:50:14+00:00] INFO: Processing log[done install] action write (piyo::default line 26)
[2013-04-06T22:50:14+00:00] INFO: done install
[2013-04-06T22:50:14+00:00] INFO: Chef Run complete in 3720.292520252 seconds
[2013-04-06T22:50:14+00:00] INFO: Running report handlers
[2013-04-06T22:50:14+00:00] INFO: Report handlers complete


インストールが終わったら、インストール成功を確認するために、一度VMを停止します。

d:\fuga\chef-repo>vagrant halt
8. インストールの確認

Vagrantfileを修正し、GUI表示をするように変更します。
Vagrantfile の40行目あたり

  config.vm.provider :virtualbox do |vb|
    vb.gui = true
  end


起動して、GUIが表示されることを確認します。
recipeのapt-getのinstallなどが再実行されてしまいますが、特に問題なく起動します。気になる場合は、Vagrantファイルのrecipe設定を変更します。

d:\fuga\chef-repo>vagrant up


以上で、環境を構築することができました。
手作業に比べればかなり容易なため、これからもいろいろと試してみようと思います。



参考書籍

前述のnaoyaさんの書籍でChefについて理解した後は、SoftwareDesignの2012年10月号が参考になりました。
今でしたら、総集編に収録されているため、そちらのほうがおすすめです。

Software Design 総集編 【2001~2012】

Software Design 総集編 【2001~2012】