Ubuntu Server 14.04.1 + VirtualBox Headless（GUIなし）でWindows7を使う

# はじめに

我が家のWindowsを撤廃してしまおうと思い、メインのサーバをUbuntu Serverにしました。
ところが、これまでWindows上で使っていたモノはほぼUbuntu上で実現できたものの、どうしてもWindowsでしか使えないモノが残ってしまいました。しかし、それはごく稀に必要になるだけです。

そこで、Ubuntuにインストール済みのVirtualBoxでWindowsを動かします。
ただし、UbuntuにはXを入れていないので、GUI操作はできません。
なので、下記のように環境を構築しました。

1. **GUI操作できる環境下のVirtualBox上で、Windows7をインストールしたイメージファイルを作成する**
2. **Windows7をインストールしたイメージファイルからVagrant Boxを作成する**
3. **Ubuntu Server上でWindowsを起動する**
4. **Remote Desktop経由でWindowsにログインする**

Windows7をvagrant upするのはUbuntu Server上で、そのインスタンスは１個だけ（自分が使うだけ）です。

# 必要になる機材、ソフトウェアなど

必要になる機材というか、こういう環境下で動かしたかったというだけなんですが…。

* **MacBook Air with Yosemite**
* **Ubuntu Server 14.04.1 LTS**

上記マシンそれぞれにインストールするVirtualBoxとvagrantのバージョンは揃えました。また、ここで使用するvagrant plugin、vagrant-windowsがサポートするWindowsのバージョンに制限があるので、ここに記載されているバージョン以外の組み合わせで試す際にはご注意ください。

* **VirtualBox 4.3.10**
* **vagrant 1.6.5**
* **vagrant-windows plugin 1.6.0**

# 構築手順
## GUI操作できる環境下のVirtualBox上で、Windows7をインストールしたイメージファイルを作成する

ここの手順はMacで行いました。
VirtualBoxを使ったWindows7インストール手順については、普通にGUI操作するだけなので、詳細は省きます。ここでのキモは、WinRMの設定です。

1. [ここ](http://download.virtualbox.org/virtualbox/4.3.10/)からVirtualBoxをダウンロードしてインストールする。
2. VirtualBoxマネージャ（GUI）を起動して、Windows7を新規インストールする。仮想マシンの名前を、ここでは仮にespresso_win7とする。
3. Windows7に、VirtualBox Guest Additionをインストールする。（後で入れるのは面倒なので…）
4. Windows7のリモートデスクトップ機能を有効化する。
4. 後でWindowsをリモート操作するため、[vagrant-windows plugin](https://github.com/WinRb/vagrant-windows)のreadmeを参考に、Windows7のコマンドプロンプト上で下記のようにWinRMを設定する。

    ```bash:configure_winrm
    winrm quickconfig -q
    winrm set winrm/config/winrs @{MaxMemoryPerShellMB="512"}
    winrm set winrm/config @{MaxTimeoutms="1800000"}
    winrm set winrm/config/service @{AllowUnencrypted="true"}
    winrm set winrm/config/service/auth @{Basic="true"}
    sc config WinRM start= auto
    ```

5. 設定が一通り完了したら、Windowsの電源を落とす。

## Windowsをインストールしたイメージファイルからvagrant boxを作成する

ここの手順もMacで行いました。
MacとUbuntuとでvagrantのバージョンを揃えるため、公式サイトからインストールパッケージをダウンロードして手動でインストールしていきます。

1. [ここ](https://www.vagrantup.com/download-archive/v1.6.5.html)からvagrantをダウンロード、インストールする。
2. vagrant-windows pluginをインストールする。

    ```bash:plugin_install
    $ sudo vagrant plugin install vagrant-windows
    ```

3. boxファイルを作成する。ここで--baseオプション引数に指定している文字列には、VirtualBoxで作成した仮想マシンの名前を指定する。--outputオプション引数に指定しているboxファイル名は適当でよい。

    ```bash:package
    $ vagrant package --base "espresso_win7" --output espress_win7_20141223.box
    ```

4. 作成したboxファイルをUbuntu Server側に転送する。ここでは仮にvagrantユーザのhome下とする。

    ```bash:scp
    $ scp espress_win7_20141223.box ubuntu_server.local.net:/home/vagrant/boxes/
    ```

## Ubuntu Server上でWindowsを起動する

ここの手順はUbuntu Server上で行います。

1. [ここ](http://download.virtualbox.org/virtualbox/4.3.10/)からVirtualBoxをダウンロードしてインストールする。
2. VirtualBoxのExtention Packをインストールする。

    ```bash:install_extpack
    $ sudo VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-4.3.10-93012.vbox-extpack
    ```

3. Vagrantfileを作成する。ここでは/home/vagrant/win7/下にする。

    ```bash:create_vagrantfile
    $ mkdir -p /home/vagrant/win7
    $ vi /home/vagrant/win7/Vagrantfile
    ```

    ```rb:Vagrantfile
    # -*- mode: ruby -*-
    # vi: set ft=ruby :

    # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
    VAGRANTFILE_API_VERSION = "2"

    Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
        # Configure base box parameters
        config.vm.box = "vagrant-windows7sp1"
        config.vm.box_url = "/home/vagrant/boxes/espress_win7_20141223.box"
        config.vm.guest = :windows

        # Ensure that all networks are set to private
        config.windows.set_work_network = true

        # Port forward WinRM and RDP
        config.vm.network :forwarded_port, guest: 3389, host: 3389
        config.vm.network :forwarded_port, guest: 5985, host: 5985, id: "winrm", auto_correct: true
    end
    ```

4. Windows7を起動する。

    ```bash:boot_win7
    $ cd /home/vagrant/win7/
    $ vagrant up
    Bringing machine 'default' up with 'virtualbox' provider...
    [default] Clearing any previously set forwarded ports...
    [default] Clearing any previously set network interfaces...
    [default] Preparing network interfaces based on configuration...
    [default] Forwarding ports...
    [default] -- 22 => 2222 (adapter 1)
    [default] -- 3389 => 3389 (adapter 1)
    [default] -- 5985 => 5985 (adapter 1)
    [default] Booting VM...
    [default] Waiting for machine to boot. This may take a few minutes...
    [default] Machine booted and ready!
    Sorry, don't know how to check guest version of Virtualbox Guest Additions on this platform. Stopping installation.
    [default] Mounting shared folders...
    [default] -- /vagrant
    [default] VM already provisioned. Run `vagrant provision` or use `--provision` to force it
    ```
## Remote Desktop経由でWindowsにログインする

ここの手順はMacで行います。

1. [Microsoft Remote Desktop](https://itunes.apple.com/jp/app/microsoft-remote-desktop/id715768417?mt=12)をインストールして起動し、Windows接続用の設定を新規作成する。  
![スクリーンショット 2014-12-29 11.18.30.png](https://qiita-image-store.s3.amazonaws.com/0/27086/9617b9a0-386c-8623-d5fb-b6e42e110f73.png)
2. 接続する。  
![スクリーンショット 2014-12-29 11.29.34.png](https://qiita-image-store.s3.amazonaws.com/0/27086/a84350d4-62fb-e4fe-6bb8-d0405821026c.png)
3. あとは普通に操作できる。 
![スクリーンショット 2014-12-29 11.23.23.png](https://qiita-image-store.s3.amazonaws.com/0/27086/5b2045b3-ed7c-237c-94db-b54bb323a6fb.png)

# おまけ

Vagrantfileの```Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|```スコープ内に以下のコードを追加すると、bridgeタイプのNICを仮想マシンに追加することができます。

```rb:Vagrantfile
    # Local networking
    config.vm.provider :virtualbox do |vb|
        vb.customize ["modifyvm", :id, "--nic2", "bridged"]
        vb.customize ["modifyvm", :id, "--nictype2", "82540EM"]
        vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
        vb.customize ["modifyvm", :id, "--cableconnected2", "on"]
        vb.customize ["modifyvm", :id, "--bridgeadapter2", "eth0"]
    end
```

同様に、```Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|```スコープ内に以下のコードを追加すると、仮想マシンにpass throughする形でホストマシンの光学ドライブを追加できます。
これで、例えば仮想マシン上でBDを焼くことも可能になります。

```rb:Vagrantfile
    # Directly mount the host drive.
    config.vm.provider :virtualbox do |vb|
        vb.customize ["storageattach", :id, "--storagectl", "SATA", "--port", "1", "--type", "dvddrive", "--medium", "host:/dev/sr0", "--passthrough", "on"]
    end
```

これらのコマンド、オプションについての詳細は、[VirtualBoxのVBoxManageコマンドヘルプ](http://www.virtualbox.org/manual/ch08.html#vboxmanage-storageattach)に記載されています。他にもいろいろできそう。

# 参考文献

* [vagrant-windows plugin readme](https://github.com/WinRb/vagrant-windows)
* [VRDP（仮想リモートディスプレイプロトコル）](http://vboxmania.net/content/vrdp%EF%BC%88%E4%BB%AE%E6%83%B3%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB%EF%BC%89)
* [Windows リモート管理 (WinRM)](http://technet.microsoft.com/ja-jp/library/dn265971.aspx)
* [FreeBSD に VirtualBox を入れて、ヘッドレスで VM を自動起動する](http://qiita.com/erukiti/items/6193aaeb2c6c9b9bef7e)
* [8.18. VBoxManage storageattach](http://www.virtualbox.org/manual/ch08.html#vboxmanage-storageattach)
* [How to add storage settings to Vagrant file?](http://stackoverflow.com/questions/21986511/how-to-add-storage-settings-to-vagrant-file?newreg=59d589697ccc4d3e8f5ffb9af5edee94)
* [Add a second disk to system using vagrant](https://gist.github.com/leifg/4713995)