VirtualBoxをスナップショットごと移行する方法

macからデータを移行しようとOVAファイルでエクスポートしたら，スナップショットのデータが消えてしまった．．．
スナップショットでいくつかの環境を切り替えていたので，これは痛い．．．
というわけで今回はVirtualBoxの設定ファイルを直接書き換えることで移行します．


# 注意
VirtualBoxの公式Documentによると，今回編集するファイルは手動で編集しないことが強く推奨されています．同様の方法を使用する場合は，お気をつけ下さい．


> We intentionally do not document the specifications of the Oracle VM VirtualBox XML files, as we must reserve the right to modify them in the future. We therefore strongly suggest that you do not edit these files manually. Oracle VM VirtualBox provides complete access to its configuration data through its the VBoxManage command line tool, see Chapter 8, VBoxManage and its API, see Chapter 11, Oracle VM VirtualBox Programming Interfaces.
[Oracle VM VirtualBox XML Files](https://www.virtualbox.org/manual/ch10.html#vboxconfigdata-XML-files)

# 実行環境

- macOS 10.15
- VirtualBox 6.0.14 r133895 (Qt5.6.3)


# 調査
まずはVirtualBoxがどのようにしてVMを管理しているかを調査します．

## VirtualBoxの設定ファイル
VirtualBoxでは，仮想マシンの設定とVirtualBox全体の設定を`VirtualBox.xml`というファイルに保存しています．このファイルはVirtualBoxの起動時に読み込まれます．中身の構成はこんな感じです(必要な部分のみ表示，　パスの部分は変更しています)．

```xml:~/Library/VirtualBox/VirtualBox.xml
<VirtualBox xmlns="http://www.virtualbox.org/" version="1.14-macosx">
  <Global>
    <ExtraData>
      <!--VirtualBoxに関する設定-->
      <ExtraDataItem name="GUI/GroupDefinitions/" value="m=e5e92069-11c8-4180-84a6-6bef8222fe8d,m=bc7dfa46-7b5b-4397-be20-254fcef7ffd4,m=f30bbe3f-1112-43d2-9211-f2be80fe3023"/>
    </ExtraData>
    <MachineRegistry>
      <MachineEntry uuid="{e5e92069-11c8-4180-84a6-6bef8222fe8d}" src="/path/VirtualBox/windows10/windows10.vbox"/>
      <MachineEntry uuid="{f30bbe3f-1112-43d2-9211-f2be80fe3023}" src="/path/VirtualBox/Ubuntu1804_en_server/Ubuntu1804_en_server.vbox"/>
    </MachineRegistry>
    <!--VirtualBoxに関する設定-->
  </Global>
</VirtualBox>
```
`ExtraDataItem`タグの`GUI/GroupDefinitions/`要素の中には，GUIに表示される仮想マシンのUUIDが格納されています．そして，`MachineRegistry`タグの中には仮想マシンの構成ファイル(vbox)のパスと，そのマシンのUUIDが格納されています．
移行時にはこの部分の値を書き換えます．

## 仮想マシン本体の格納場所

仮想マシン本体の格納場所は環境や，vmdkファイルからインポートする時などで変化することがありますが，基本的にはVirtualBoxの設定に書かれた場所に格納されています．
<img width="583" alt="スクリーンショット 2019-11-04 16.29.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295848/0d2e3be5-dfc0-9e5f-55e4-4b9d22fe9025.png">
おそらく，vboxファイルに関しては全てここに配置されます．

## 仮想マシンの構成ファイル

VirtualBoxでは，vboxというファイルを用いて仮想マシンの構成などを定義しています．拡張子はvboxですが，中身はただのXMLファイルなので，テキストエディタなどで開けば普通にみることができます．
> ちなみに，OVAファイルもただのtarファイルだったりする．

中身はこんな感じ(必要な部分のみ抜粋)．

```xml:.vbox
<?xml version="1.0"?>
<VirtualBox xmlns="http://www.virtualbox.org/" version="1.16-macosx">
  <Machine uuid="{7f805bfe-191f-427e-ab5a-31e84f342d5f}" name="CentOS_en_minimal" OSType="RedHat_64" snapshotFolder="Snapshots" lastStateChange="2019-10-20T05:50:27Z">
    <Description></Description>
    <MediaRegistry>
      <HardDisks>
        <HardDisk uuid="{7f9179f8-391b-4400-89d8-d407c99ece47}" location="CentOS7_en_minimal-disk001.vdi" format="vdi" type="Normal"/>
      </HardDisks>
    </MediaRegistry>
    <Hardware>
      <CPU count="2">
        <PAE enabled="true"/>
        <LongMode enabled="true"/>
        <X2APIC enabled="true"/>
        <HardwareVirtExLargePages enabled="true"/>
      </CPU>
      <Memory RAMSize="4096"/>
      <Display VRAMSize="64"/>
      <VideoCapture screens="1" options="ac_enabled=false" file="." fps="25"/>
      <StorageController name="SATA" type="AHCI" PortCount="1" useHostIOCache="false" Bootable="true" IDE0MasterEmulationPort="0" IDE0SlaveEmulationPort="1" IDE1MasterEmulationPort="2" IDE1SlaveEmulationPort="3">
        <AttachedDevice type="HardDisk" hotpluggable="false" port="0" device="0">
          <Image uuid="{7f9179f8-391b-4400-89d8-d407c99ece47}"/>
        </AttachedDevice>
      </StorageController>
  </Machine>
</VirtualBox>
```

基本的には仮想マシンの設定画面に出ている物がXMLで定義されているだけっぽい．
↓この画面
<img width="786" alt="スクリーンショット 2019-11-06 0.47.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295848/808a662b-5845-d576-ac6c-3b0441a96827.png">

移行時にはここに書かれているuuidを使用します．

# 移行
## VMデータを転送する

まずはVMのデータを移行しないことには話が始まりません．
外部のHDDにコピーして移行する方法もありますが，個人的には**「新旧のPCをLANケーブルでつないで転送」**した方が，早く，楽に転送できます．
転送先には新しいPCの「デフォルトの仮想マシンフォルダ(上で出てきた奴)」をお勧めします．管理が楽です．

## 新しいPCで設定ファイルを書き換える．

設定ファイルを書き換える時，VirtuaBoxが起動していないことを必ず確認する．

### 古いPCから移行してきたvboxファイル
vboxファイルの中には，HDDファイルの**相対パス**が記述されています．相対パスが書かれているので，正直古いPCから何も考えずにコピーすれば編集する必要はありません．

ただし，vboxファイルの`Machine`タグに書かれたuuidを今後使うので，控えておきます．


### 新しいPCのVirtualBox.xmlファイル

新しいPCの`~/Library/VirtualBox/VirtualBox.xml`を編集します．新しいPCを買ってすぐの場合はVMが何も登録されていないと思うので，古いPCの`VirtualBox.xml`を参考にしながら設定を書き換えます．


#### `ExtraDataItem`タグの`GUI/GroupDefinitions/`要素

先ほど控えたuuidをこの要素の中に記述します．valueにカンマ区切りで`m=uuid`を記述します．

```xml:~/Library/VirtualBox/VirtualBox.xml
<ExtraDataItem name="GUI/GroupDefinitions/" value="m=e5e92069-11c8-4180-84a6-6bef8222fe8d,m=f30bbe3f-1112-43d2-9211-f2be80fe3023,m=7f805bfe-191f-427e-ab5a-31e84f342d5f"/>
```

#### `MachineRegistry`タグ

移行したvboxファイルのパスをこのタグの中に記述します．uuidは上で入力したものをそのまま入力します．

```xml:~/Library/VirtualBox/VirtualBox.xml
 <MachineRegistry>
      <MachineEntry uuid="{e5e92069-11c8-4180-84a6-6bef8222fe8d}" src="/path/windows10.vbox"/>
      <MachineEntry uuid="{f30bbe3f-1112-43d2-9211-f2be80fe3023}" src="/path/Ubuntu1804_en_server.vbox"/>
      <MachineEntry uuid="{7f805bfe-191f-427e-ab5a-31e84f342d5f}" src="/Users/motya/Dropbox/VirtualBox/CentOS_en_minimal/CentOS_en_minimal.vbox"/>
    </MachineRegistry>
```


# 確認

この状態でファイルを保存し，VirtualBoxを起動すると，移行したVMが表示されているハズです．

次は，この技術を使ってハードディスクの要領を確保する方法を紹介します．