Windows 10のBash on Ubuntu on Windowsを触ってみる

この記事は、[「クラウド時代のシステム管理」の記事](http://www.takanyan.net/chef12-workstation-bashonwindows10/)を転記したものです。

2016年4月に発表された、「Bash on Ubuntu on Windows10」は、Windows10上でubuntu 14.04のバイナリがそのまま動く（ユーザーモード限定ですが）ため、Linux上のアプリケーション開発やクロスプラットフォーム開発がスピーディーに行えるようになる見込みです。ここでは、Windows 10 Pro Insider Priview 14342の上で動くubuntuでChef Workstationを構築してみます。手順自体は<a href="https://docs.chef.io/install_dk.html" target="_blank">本家サイトの手順</a>に従って行います。なお、すでにCentOS7編で詳細なコマンド出力結果は書いていますので、ここではBash on Ubuntu on Windows10特有の出力以外は実行したコマンドだけを記載します。また、Bash on Ubuntu on Windowsの有効化手順は<a href="http://www.takanyan.net/buow10/" target="_blank">こちらの記事</a>を参照してください。

<more></more>

### 1. Chef Development Kit (Chef DK)のインストールとユーザー作成

ChefのCookbookを開発するためのSDKやコマンドラインツールがセットになった<a href="https://downloads.chef.io/chef-dk/ubuntu/" target="_blank">「Chef Development Kit」（以下Chef DK）をダウンロード</a>します。そしてRPMコマンドでインストールします。

```
root@MYCOMPUTER:/ cd /tmp
root@MYCOMPUTER:/tmp# curl -LO "https://packages.chef.io/stable/ubuntu/12.04/chefdk_0.15.15-1_amd64.deb"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
100  134M  100  134M    0     0   638k      0  0:03:35  0:03:35 --:--:--  846k
root@MYCOMPUTER:/tmp# dpkg -i chefdk_0.15.15-1_amd64.deb
(Reading database ... 24998 files and directories currently installed.)
Preparing to unpack chefdk_0.15.15-1_amd64.deb ...
Unpacking chefdk (0.15.15-1) over (0.15.15-1) ...
Setting up chefdk (0.15.15-1) ...
Thank you for installing Chef Development Kit!
```

dpkgコマンドでのChef DKをインストールする際、<strong>30分以上と非常に時間がかかります</strong>。その様子はWindowsのタスクマネージャからも見ることができます。

<a href="http://www.takanyan.net/wp-content/uploads/2016/06/taskmgr.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/06/taskmgr.png" alt="taskmgr"  class="aligncenter size-full wp-image-137" /></a>


次に、Cookbookの管理などで必要になるgitとunzipをインストールしておきます。

```
root@MYCOMPUTER:/# apt-get install git unzip
Reading package lists... Done
（以下省略）
Setting up liberror-perl (0.17-1.1) ...
Setting up git-man (1:1.9.1-1ubuntu0.3) ...
Setting up git (1:1.9.1-1ubuntu0.3) ...
Setting up unzip (6.0-9ubuntu1.5) ...
```

ChefのCookbook作成などの作業には管理者権限は不要なので、開発用の一般ユーザーを作成します。ここではChefにログインするときに作ったユーザーと同じ名前にしておきます。（例では「chef-admin」)

```sh
root@MYCOMPUTER:/# useradd -m chef-admin
root@MYCOMPUTER:/# passwd chef-admin
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
```

### 2. Chef開発用ユーザーの環境設定

chef-adminユーザーに切り替えた後、Gitの初期設定を行い、その後Chef DKが正常にインストールされているか確認するコマンドを実行します。以前のCentOS上でのChef Workstation構築の記事ではGitの初期設定をしていませんでしたが、Chef DK 0.15系からはGit初期設定が必要になったようです。設定しないとエラーがたくさん出てしまいます。

```sh
root@MYCOMPUTER:/# su - chef-admin
chef-admin@MYCOMPUTER:~$ git config --global user.email "chef-admin@example.local"
chef-admin@MYCOMPUTER:~$ git config --global user.name "Your Name"
chef-admin@MYCOMPUTER:~$ chef verify
Running verification for component 'berkshelf'
Running verification for component 'test-kitchen'
Running verification for component 'tk-policyfile-provisioner'
Running verification for component 'chef-client'
Running verification for component 'chef-dk'
Running verification for component 'chef-provisioning'
Running verification for component 'chefspec'
Running verification for component 'generated-cookbooks-pass-chefspec'
Running verification for component 'rubocop'
Running verification for component 'fauxhai'
Running verification for component 'knife-spork'
Running verification for component 'kitchen-vagrant'
Running verification for component 'package installation'
Running verification for component 'openssl'
Running verification for component 'inspec'
Running verification for component 'delivery-cli'
Running verification for component 'git'
Running verification for component 'opscode-pushy-client'
Running verification for component 'chef-sugar'
Running verification for component 'knife-supermarket'
.......................................................
---------------------------------------------
Verification of component 'rubocop' succeeded.
Verification of component 'kitchen-vagrant' succeeded.
Verification of component 'openssl' succeeded.
Verification of component 'delivery-cli' succeeded.
Verification of component 'test-kitchen' succeeded.
Verification of component 'fauxhai' succeeded.
Verification of component 'inspec' succeeded.
Verification of component 'opscode-pushy-client' succeeded.
Verification of component 'knife-supermarket' succeeded.
Verification of component 'berkshelf' succeeded.
Verification of component 'knife-spork' succeeded.
Verification of component 'git' succeeded.
Verification of component 'tk-policyfile-provisioner' succeeded.
Verification of component 'chef-dk' succeeded.
Verification of component 'chef-sugar' succeeded.
Verification of component 'chef-client' succeeded.
Verification of component 'chefspec' succeeded.
Verification of component 'generated-cookbooks-pass-chefspec' succeeded.
Verification of component 'chef-provisioning' succeeded.
Verification of component 'package installation' succeeded.
```

ただし、Insider PreviewのバージョンがBuild 14352より古い場合は不具合があり、メモリ確保に失敗した旨のエラーが出てしまいます。執筆時点では修正版がリリースされています。不具合の詳細は<a href="https://github.com/Microsoft/BashOnWindows/issues/92" target="_blank">Githubのこちらのサイト</a>に記述がありました。

```sh
chef-admin@MYCOMPUTER:~$ chef verify
（省略）
/opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout/unix.rb:338:in `exec': Cannot allocate memory - /opt/chefdk/bin/berks (Errno::ENOMEM)
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout/unix.rb:338:in `block in fork_subprocess'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout/unix.rb:316:in `fork'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout/unix.rb:316:in `fork_subprocess'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout/unix.rb:93:in `run_command'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/mixlib-shellout-2.2.6/lib/mixlib/shellout.rb:259:in `run_command'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/helpers.rb:30:in `system_command'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/component_test.rb:117:in `sh'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/command/verify.rb:96:in `block (3 levels) in <class:Verify>'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/component_test.rb:165:in `block in tmpdir'
        from /opt/chefdk/embedded/lib/ruby/2.1.0/tmpdir.rb:88:in `mktmpdir'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/component_test.rb:164:in `tmpdir'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/command/verify.rb:94:in `block (2 levels) in <class:Verify>'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/component_test.rb:99:in `instance_eval'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/component_test.rb:99:in `run_smoke_test'
        from /opt/chefdk/embedded/lib/ruby/gems/2.1.0/gems/chef-dk-0.15.15/lib/chef-dk/command/verify.rb:580:in `block (2 levels) in invoke_tests'
```

出力結果の後半で、すべてのコンポーネントの結果が「succeeded」となっていることを確認します。次に、このユーザーでのデフォルトRubyのパスをChef DKと一緒にインストールされているものに設定します。そのためには、<code>~/.bashrc</code>に１行追記し、<code>~/.bashrc</code>の設定を再読み込みします。

<pre class="decode:true " >$ echo 'eval "$(chef shell-init bash)"' &gt;&gt; ~/.bashrc
chef-admin@MYCOMPUTER:~$ source ~/.bashrc
chef-admin@MYCOMPUTER:~$ which ruby
/opt/chefdk/embedded/bin/ruby</pre> 

これでchef-adminユーザーのデフォルトrubyがChef DKに同梱されたものになりました。なお、実際に設定される環境変数などを確認すると、以下のようになります。

```
chef-admin@MYCOMPUTER:~$ chef shell-init bash
export PATH="/opt/chefdk/bin:/home/chef-admin/.chefdk/gem/ruby/2.1.0/bin:/opt/chefdk/embedded/bin:/opt/chefdk/bin:/home/chef-admin/.chefdk/gem/ruby/2.1.0/bin:/opt/chefdk/embedded/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
export GEM_ROOT="/opt/chefdk/embedded/lib/ruby/gems/2.1.0"
export GEM_HOME="/home/chef-admin/.chefdk/gem/ruby/2.1.0"
export GEM_PATH="/home/chef-admin/.chefdk/gem/ruby/2.1.0:/opt/chefdk/embedded/lib/ruby/gems/2.1.0"
_chef_comp() {
    local COMMANDS="exec env gem generate shell-init install update push push-archive show-policy diff provision export clean-policy-revisions clean-policy-cookbooks delete-policy-group delete-policy undelete verify"
    COMPREPLY=($(compgen -W "$COMMANDS" -- ${COMP_WORDS[COMP_CWORD]} ))
}
complete -F _chef_comp chef
```

### 3. Starter Kitの展開とChef Serverとの接続設定

Chef DKの環境を簡単に整えるために、Chef ServerのWeb管理画面からStarter Kitをダウンロードします。そのために、Web管理画面にログイン後、画面TOPの「Administration」をクリックします。

<a href="http://www.takanyan.net/wp-content/uploads/2016/06/chefserver-organization01.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/06/chefserver-organization01.png" alt="chefserver-organization01" class="aligncenter size-full wp-image-97" /></a>


次に、画面左にある「Organization」をクリック後、表示された組織一覧から前回の記事で作成した組織を選びます。その後、画面左にある「Starter Kit」をクリックします。その後、画面中央に表示される「Download Starter Kit」ボタンをクリックします。

<a href="http://www.takanyan.net/wp-content/uploads/2016/06/chefserver-organization02.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/06/chefserver-organization02.png" alt="chefserver-organization02" class="aligncenter size-full wp-image-98" /></a>

ボタンをクリックすると警告が表示されますが、「Proceed」をクリックしてダウンロードを行います。

<a href="http://www.takanyan.net/wp-content/uploads/2016/06/chefserver-starterkit.png"><img src="http://www.takanyan.net/wp-content/uploads/2016/06/chefserver-starterkit.png" alt="chefserver-starterkit" class="aligncenter size-full wp-image-99" /></a>

ここでダウンロードした「chef-starter.zip」は<code>/mnt/c/Users/(ユーザー名)/Downloads</code>以下にあるのでコピーを行い、unizpコマンドで展開します。

```
chef-admin@MYCOMPUTER:~$ cp /mnt/c/Users/aniku/Downloads/chef-starter.zip ~
chef-admin@MYCOMPUTER:~$ ls
chef-starter.zip
chef-admin@MYCOMPUTER:~$ unzip -q chef-starter.zip
chef-admin@MYCOMPUTER:~$ ls
chef-repo  chef-starter.zip
```

ここで作られた<code>chef-repo</code>ディレクトリでCookbookを作成できるよう初期化を行います。

```
chef-admin@MYCOMPUTER:~$ cd chef-repo
chef-admin@MYCOMPUTER:~/chef-repo$ chef generate app chef-repo
Installing Cookbook Gems:
Compiling Cookbooks...
Recipe: code_generator::app
  * directory[/home/chef-admin/chef-repo] action create (up to date)
  * template[/home/chef-admin/chef-repo/.kitchen.yml] action create
    - create new file /home/chef-admin/chef-repo/.kitchen.yml
    - update content in file /home/chef-admin/chef-repo/.kitchen.yml from none to 210d0b
    (diff output suppressed by config)
  * directory[/home/chef-admin/chef-repo/test/integration/default/serverspec] action create
    - create new directory /home/chef-admin/chef-repo/test/integration/default/serverspec
  * directory[/home/chef-admin/chef-repo/test/integration/helpers/serverspec] action create
    - create new directory /home/chef-admin/chef-repo/test/integration/helpers/serverspec
  * cookbook_file[/home/chef-admin/chef-repo/test/integration/helpers/serverspec/spec_helper.rb] action create_if_missing
    - create new file /home/chef-admin/chef-repo/test/integration/helpers/serverspec/spec_helper.rb
    - update content in file /home/chef-admin/chef-repo/test/integration/helpers/serverspec/spec_helper.rb from none to a226b8
    (diff output suppressed by config)
  * template[/home/chef-admin/chef-repo/test/integration/default/serverspec/default_spec.rb] action create_if_missing
    - create new file /home/chef-admin/chef-repo/test/integration/default/serverspec/default_spec.rb
    - update content in file /home/chef-admin/chef-repo/test/integration/default/serverspec/default_spec.rb from none to 1e81da
    (diff output suppressed by config)
  * template[/home/chef-admin/chef-repo/README.md] action create
    - update content in file /home/chef-admin/chef-repo/README.md from 2b98f1 to 6401b8
    (diff output suppressed by config)
  * directory[/home/chef-admin/chef-repo/cookbooks] action create (up to date)
  * directory[/home/chef-admin/chef-repo/cookbooks/chef-repo] action create
    - create new directory /home/chef-admin/chef-repo/cookbooks/chef-repo
  * template[/home/chef-admin/chef-repo/cookbooks/chef-repo/metadata.rb] action create
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/metadata.rb
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/metadata.rb from none to b8624d
    (diff output suppressed by config)
  * cookbook_file[/home/chef-admin/chef-repo/cookbooks/chef-repo/chefignore] action create
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/chefignore
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/chefignore from none to e394e1
    (diff output suppressed by config)
  * cookbook_file[/home/chef-admin/chef-repo/cookbooks/chef-repo/Berksfile] action create
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/Berksfile
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/Berksfile from none to 5ec92e
    (diff output suppressed by config)
  * directory[/home/chef-admin/chef-repo/cookbooks/chef-repo/recipes] action create
    - create new directory /home/chef-admin/chef-repo/cookbooks/chef-repo/recipes
  * template[/home/chef-admin/chef-repo/cookbooks/chef-repo/recipes/default.rb] action create
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/recipes/default.rb
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/recipes/default.rb from none to 2cdf1a
    (diff output suppressed by config)
  * directory[/home/chef-admin/chef-repo/cookbooks/chef-repo/spec/unit/recipes] action create
    - create new directory /home/chef-admin/chef-repo/cookbooks/chef-repo/spec/unit/recipes
  * cookbook_file[/home/chef-admin/chef-repo/cookbooks/chef-repo/spec/spec_helper.rb] action create_if_missing
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/spec/spec_helper.rb
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/spec/spec_helper.rb from none to 945e09
    (diff output suppressed by config)
  * template[/home/chef-admin/chef-repo/cookbooks/chef-repo/spec/unit/recipes/default_spec.rb] action create_if_missing
    - create new file /home/chef-admin/chef-repo/cookbooks/chef-repo/spec/unit/recipes/default_spec.rb
    - update content in file /home/chef-admin/chef-repo/cookbooks/chef-repo/spec/unit/recipes/default_spec.rb from none to be7503
    (diff output suppressed by config)
  * execute[initialize-git] action run
    - execute git init .
  * cookbook_file[/home/chef-admin/chef-repo/.gitignore] action create
    - update content in file /home/chef-admin/chef-repo/.gitignore from f7d9f8 to dd37b2
    (diff output suppressed by config)
```


次に、秘密鍵などが保管されている<code>.chef</code>ディレクトリをgit管理対象外にするための設定を行います。

<pre class="decode:true " >$ echo '.chef' &gt;&gt; ~/chef-repo/.gitignore </pre>

最後にChef ServerのSSL証明書（自己証明書）を信頼するよう設定します。前提条件として、Chef Serverの名前解決ができることと、<code>~/chef-repo/.chef/knife.rb</code>に書かれているChef ServerのURLが正しいこと（ホスト名がFQDNになっているかなど）を確認しておきます。また、<del datetime="2016-07-18T06:06:25+00:00">このコマンドも<strong>非常に長い時間がかかります</strong>。</del><strong>(2016/7/18追記：Windows10 build 14390にアップデート後、時間がかからず完了するようになりました。)</strong>

```
root@MYCOMPUTER:/home/chef-admin/chef-repo# knife ssl fetch
WARNING: Certificates from chefserver will be fetched and placed in your trusted_cert
directory (/home/chef-admin/chef-repo/.chef/trusted_certs).

Knife has no means to verify these are the correct certificates. You should
verify the authenticity of these certificates after downloading.

Adding certificate for chefserver in /home/chef-admin/chef-repo/.chef/trusted_certs/chefserver.crt
```

以上で、Chef DKの環境が整いました。

### 4. Chef Serverとの接続確認

<code>~/chef-repo</code>ディレクトリ以下で<code>knife</code>コマンドを実行することで、Chef Serverと接続でき、クライアントや管理者ユーザーのリストが取得できることを確認します。

```
$ knife user list
chef-admin
$ knife client list
takanyan-validator
```

以上で、<del datetime="2016-07-03T01:18:02+00:00">一般的な</del>Bash on Ubuntu on Windows環境内にChef Workstation環境が出来上がりました。<del datetime="2016-07-18T06:06:25+00:00">ただ、時間がかかりすぎて今はまだ実運用までたどり着けない、かもしれません・・・</del>（2016/7/18追記：Windows 10 Build 14390以降はスムーズに実行されるようになりました。使える、かもしれません！）