HighSierra/Mojave の検証環境をワンライナーで一発構築する（Vagrant+VirtualBox）

> Vagrant のゲストOS に HighSierra や Mojave で動作検証や開発環境を簡単に構築したい。

- 「新しい Mac を購入したが Mojave 入りなので HighSierra を新規インストールできない[^macos]ため、アプリの動作検証ができない」
- 「サポートの問い合わせが来たが、macOS の画面まわりがわからない」
- 「『Mac 対応？それ美味しいの？』と言われたので検証してみたい」
- 「プレーンな macOS でビルドやテストをしたい」

[^macos]: <h4>【HighSierra に OS をダウングレードできない】</h4>Mac マシンは、購入時に**プリインストールされている macOS より低いバージョンの macOS はインストールできない**仕様になっています。<br>そのため古いソフトや現在利用しているソフトのバージョンが、新しい macOS に対応していない場合、ハード（マシン）が壊れた場合は中古マシンを買わざるを得なくなります。新しいマシンを使いたい場合は、基本的に古いソフトを諦めるか、新しいバージョンのソフトを購入する必要があります。Adobe や CAD ソフトなどが、昔のように買い切りでなく、月々払いになったのも、買い替えを半ば強要する Apple のエコ・システムに便乗したとも言えます。問題は、開発側はサポートのために古いマシンをキープし続ける必要があることです。

## TL; DR <sub><sup><sub><sup>（今北産業）</sup></sub></sup></sub>

VirtualBox と Vagrant がインストールされていて OS 1 つぶん（50 GB）以上の空き容量があれば簡単です。

```shell-session:mojaveをGUIモードで起動する例@Bash
$ mkdir mojave && cd $_
$ curl -o Vagrantfile https://KEINOS.github.io/Vagrantfile_for_macOS/Vagrantfiles/Vanilla_GUI_v10.14.1
$ vagrant up
```

> 🐒 &nbsp; **ブート時の `UEFI` 画面で "mapping table error" が出で `Shell>` で止まる場合**は、どのパーティション（`FS1:` や `FS2:` など）にある `boot.efi` を選んで良いのかわからない状態になっています。
>
> ![スクリーンショット 2021-03-23 12.44.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78776/b80d72bd-2abb-7e5c-3c83-094a0ac16879.png)
>
> `Shell> FS1:` もしくは `Shell> FS2:` と打ってから `ls` コマンドで `/System/` があるパーティションを選び、`cd \System\Library\CoreServices` に移動（バックスラッシュに注意）して `boot.efi` があるか確認したら、`boot.efi` を実行してください。`/EFI` しかない場合はハズレのパーティションなので `exit` コマンドで抜けて、再度 `continue` を選んで振り出しに戻ってください。
>
> - 参考動画: [Virtualbox UEFI Shell startup.nsh Error Fixed (MacOS, Linux, Windows any OS)](https://youtu.be/A3z64QUTJsM) @ Youtube
> - `vagrant` ユーザのパスワードは `vagrant` です。

## TS; DR <sub><sup>（HighSierra/Mojave の開発環境のベースをゲスト OS に）</sup></sub>

VirtualBox と Vagrant がインストール[^install]されていれば、（ダウンロードに時間かかるけど）以下のワンライナーで日本語の macOS が CUI モードで起動します。もちろん GUI モードでも起動できますが、macOS で自作コマンドが動くかといった検証であれば CUI の方が軽いです。

なお、下記の各々のワンライナーは、[Vagrant Cloud](https://app.vagrantup.com/) から Box イメージをダウンロード＆起動して `ssh` 接続します。

[^install]: <h4>【VirtualBox と Vagrant のインストール】</h4>macOS の場合、[Homebrew](https://www.google.com/search?q=site:qiita.com+homebrew+%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%96%B9%E6%B3%95&tbs=qdr:y) がインストールされていれば、`brew cask install virtualbox` および `brew cask install virtualbox-extension-pack` コマンドで VirtualBox がインストールできます。<br>Vagrant も `brew cask install vagrant` コマンドでインストールできます。<br><h5>VirtualBox とは</h5>[Oracle 社](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB_(%E4%BC%81%E6%A5%AD))の仮想化アプリ。<br>仮想的にマシンを作り、そこに OS をインストールすることで異なる OS 上でも特定の OS を使えるようにするためのアプリ。VirtualBox （の仮想マシン）上で動く OS をゲスト OS と呼び、VirtualBox アプリ自体がインストールされている OS をホスト OS と呼んでいる。似たような仮想化アプリには、手法や技術は異なるが VMware, Hyper-V, Docker などがある。仮想とはいえマシンではあるので、そこに OS をインストールする場合、OS （のライセンス）によっては別途シリアル番号やライセンスキーが必要だったり、利用制限があるので注意が必要である。「[VirtualBox](https://ja.wikipedia.org/wiki/VirtualBox)」@ Wikipedia, <br><h5>Vagrant とは</h5>[HashiCorp 社](https://www.hashicorp.com/)の各種仮想アプリを管理するツール。<br>VirtualBox/VMware/Docker などの仮想化アプリをコマンドで操作することができるツール。仮想化アプリ自身もコマンドで操作可能だがアプリごとにコマンドが異なるため、Vagrant を通すことで操作を一本化できる。例えば、ゲスト OS の立ち上げ、コピー、クローン、削除、スナップショットだけでなく、ゲスト OS 上でのスクリプト実行といった操作が行える。これにより各々の仮想化アプリのメリットを活かして（適材適所で）使えるため、[CI](https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3) といったテストやビルドや自動化に使われる。このような総括的なツールやアプリを使い、自動化することを[オーケストレーション](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%BC%E3%82%B1%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF))という。「[Vagrant(ソフトウェア)](https://ja.wikipedia.org/wiki/Vagrant_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2))」@ Wikipedia

以下は、10.13.6 へアップデートだけ済んだ[バニラ](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%8B%E3%83%A9_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2))状態の日本語 [HighSierra](https://app.vagrantup.com/boxes/search?q=high+sierra+japanese) です。

```bash:GuestOSがHighSierraの構築ワンライナー
vagrant init -m KEINOS/macOS.10.13.6_Japanese && vagrant up && vagrant ssh
```

以下は、ほぼバニラ（`git` だけ入った）状態の[日本語 Mojave](https://app.vagrantup.com/boxes/search?q=mojave+japanese) です。

```bash:GuestOSがMojaveの構築ワンライナー
vagrant init -m KEINOS/macOS.10.14.1_Japanese && vagrant up && vagrant ssh
```

- 動作確認済み環境
    - Vagrant v2.2.4/v2.2.5
    - VirtubalBOX v6.0.4 r128413/6.0.12r133076
    - ホストOS： macOS HighSierra(OSX 10.13.6), Mojave(OSX 10.14.4)
    - [その他動作確認済み環境一覧](https://github.com/KEINOS/Vagrantfile_for_macOS/issues/1) | HighSierra の Box @ GitHub
    - [その他動作確認済み環境一覧](https://github.com/KEINOS/Vagrantfile_for_macOS/issues/2) | Mojave の Box @ GitHub

- SSH 接続時に「Timed out while waiting for the machine to boot.」が出る場合
    - VM（仮想マシン） を再起動（`vagrant halt` してから、再度 `vagrant up` ）します。詳しくは以下を参照。
        - Issue #6 [Timed out while waiting for the machine to boot then fails SSH on Mojave #6](https://github.com/KEINOS/Vagrantfile_for_macOS/issues/6) @ GitHub

## Vagrantfile のサンプル集

各々を `Vagrantfile` として保存し、`$ vagrant up` で起動します。

- ヘッドレス(CLI モード）で Mac を起動させて、他のマシンから VNC アクセス（Mac だと画面共有）可能なサンプル
    - [HighSierra](https://github.com/KEINOS/Vagrantfile_for_macOS/blob/master/Vagrantfiles/VNC_to_Headless_v10.13.6) @ GitHub
    - [Mojave](https://github.com/KEINOS/Vagrantfile_for_macOS/blob/master/Vagrantfiles/VNC_to_Headless_v10.14.1) @ GitHub
- ローカルのファイル/ディレクトリを、ヘッドレス(CLI モード）の Mac にマウントして起動させるサンプル
    - [Mojave](https://github.com/KEINOS/Vagrantfile_for_macOS/blob/master/Vagrantfiles/Mount_local_dir_CUI_v10.14.1) @ GitHub
    - 注意事項：マウントするタイミングで親機のパスワード入力を求められます。
- Homebrew 入りのヘッドレス(CLI モード）の Mac を起動するサンプル
    - [Mojave](https://github.com/KEINOS/Vagrantfile_for_macOS/blob/master/Vagrantfiles/Homebrew_CLI_v10.14.1) @ GitHub
- [Wineskin](http://wineskin.urgesoftware.com/tiki-index.php) 入りのヘッドレス(CLI モード）の Mac を起動するサンプル
    - [Mojave](https://github.com/KEINOS/Vagrantfile_for_macOS/blob/master/Vagrantfiles/Wineskin_GUI_v10.14.1) @ GitHub

- その他の [Vagrantfile のサンプル集](https://github.com/KEINOS/Vagrantfile_for_macOS/tree/master/Vagrantfiles) @ GitHub

### 基本仕様

- VirtualBox >= 6.0.3
- Vagrant >= 2.2.3
- リポジトリ： https://github.com/KEINOS/Vagrantfile_for_macOS @ GitHub
- この Vagrant Box は **Mac/iOS 向けのアプリ開発および動作確認専用**です。Mac mini で Bootcamp の Windows10 でも動作したらしいのですが、筆者の MacBookPro には空き容量がなく macOS でしか検証しておりません。なお、ご利用の際は [Apple の OS 利用ライセンスに同意したものとし、自己責任](https://github.com/KEINOS/Vagrantfile_for_macOS#%E5%85%8D%E8%B2%AC%E4%BA%8B%E9%A0%85)でご利用ください。

### HighSierra の Vagrant BOX イメージ

- ゲスト OS：macOS HighSierra（OSX 10.13.6）
    - 日本語、アップデート以外の追加インストールなし
    - イメージサイズ： 12.4 GB
    - 想定ダウンロード時間： 2時間（SpeedTest CLI: Download = 93.14 Mbit/s）
    - https://app.vagrantup.com/KEINOS/boxes/macOS.10.13.6_Japanese @ Vagrant Cloud

```shell-session:Boxイメージ検索
$ vagrant cloud search highsierra
| NAME                          | VERSION | DOWNLOADS | PROVIDERS  |
+-------------------------------+---------+-----------+------------+
| KEINOS/macOS.10.13.6_Japanese | 0.0.4   |        13 | virtualbox |
+-------------------------------+---------+-----------+------------+
```

```shell-session:ダウンロード（時間かかるよっ）
$ vagrant box add KEINOS/macOS.10.13.6_Japanese
```

```shell-session:CUIモードで起動
$ mkdir highsierra && cd $_
$ vagrant init -m KEINOS/macOS.10.13.6_Japanese
$ ls
Vagrantfile
$ vagrant up
$ vagrant ssh
```

CI などでの用途を前提としているため、デフォルトではヘッドレス起動（CLI モード：`gui=false`）になっています。デスクトップの通常起動（GUI モード）で起動させたい場合は Vagrantfile で `.gui` を `true` に設定します。`vagrant` ユーザーのパスワードは `vagrant` です。

```ruby:Vagrantfile（GUIモードで起動する設定）
Vagrant.configure("2") do |config|
  config.vm.box = "KEINOS/macOS.10.13.6_Japanese"
  config.vm.provider "virtualbox" do |vb|
    vb.gui = true
  end
end
```

```bash:GUIモードのVagrantfile編集が面倒な人向け
mkdir highsierra && cd $_
curl -o Vagrantfile https://KEINOS.github.io/Vagrantfile_for_macOS/Vagrantfiles/Vanilla_GUI_v10.13.6
vagrant up
```

### Mojave の Vagrant BOX イメージ

- ゲスト OS：macOS Mojave（OSX 10.14.1）
    - 日本語、アップデートおよび `git` 以外の追加インストールなし
- イメージサイズ： 8.68 GB
- 想定ダウンロード時間： 1.5時間（SpeedTest CLI: Download = 93.14 Mbit/s）
    - https://app.vagrantup.com/KEINOS/boxes/macOS.10.14.1_Japanese @ Vagrant Cloud

```shell-session:Boxイメージ検索
$ vagrant cloud search mojave
| NAME                          | VERSION | DOWNLOADS | PROVIDERS      |
+-------------------------------+---------+-----------+----------------+
| ashiq/osx-10.14               | 0.1     |       878 | virtualbox     |
| yzgyyang/macOS-10.14          | 10.14.4 |       463 | virtualbox     |
| scoreyou/baseMac              | 0.1     |        20 | virtualbox     |
| KEINOS/macOS.10.14.1_Japanese | 0.0.3   |        17 | virtualbox     | ← これ
| msl/macos_mojave_10.14        | 1.1.0   |        15 | vmware_desktop |
| adasilva/Mojave               | 1.0     |         7 | virtualbox     |
+-------------------------------+---------+-----------+----------------+
```

```shell-session:ダウンロード（時間かかるよっ）
$ vagrant box add KEINOS/macOS.10.14.1_Japanese
```

```shell-session:CUIモードで起動
$ mkdir mojave && cd $_
$ vagrant init -m KEINOS/macOS.10.14.1_Japanese
$ ls
Vagrantfile
$ vagrant up
$ vagrant ssh
```

CI などでの用途を前提としているため、デフォルトではヘッドレス起動（CLI モード：`gui=false`）になっています。

そのため、通常起動（GUI モード）で起動させたい場合は Vagrantfile で `vb.gui` を `true` に設定します。`vagrant` ユーザーのパスワードは `vagrant` です。

```ruby:Vagrantfile（GUIモードで起動する設定）
Vagrant.configure("2") do |config|
  config.vm.box = "KEINOS/macOS.10.14.1_Japanese"
  config.vm.provider "virtualbox" do |vb|
    vb.gui = true
  end
end
```

```bash:GUIモードのVagrantfile編集が面倒な人向け
mkdir mojave && cd $_
curl -o Vagrantfile https://KEINOS.github.io/Vagrantfile_for_macOS/Vagrantfiles/Vanilla_GUI_v10.14.1
vagrant up
```