Virtualbox + Vagrant における共用ディスク構成

# 2023/04更新
以下の様に最初のインスタンスの場合にのみ共用ディスクを作成することでvagrant up単体で起動できる。
```ruby:Vagrantfile
file_shared_disk = 'sdisk.vdi'
size_shared_disk = 1

Vagrant.configure('2') do |config|
  %w(node1 noder1540482).each_with_index do |_node, index|    # <= 変更1
    config.vm.define _node do |ins|
      ins.vm.box = 'fedora/36-cloud-base'
      ins.vm.box_version = '36-20220504.1'
      ins.vm.provider 'virtualbox' do |vb|

        # 最初のインスタンスの場合のみ共用ディスクを作成
        if index == 0                                         # <= 変更2

          # VDIフォーマットで仮想ディスクを作成
          vb.customize [
            'createhd', 
            '--filename', file_shared_disk, 
            '--format', 'VDI', 
            '--size', size_shared_disk * 1024, 
            '--variant', 'Fixed'
          ]

          # shareableに変更
          vb.customize [
            'modifyhd', file_shared_disk, 
            '--type', 'shareable'
          ]
        end

        # インスタンスに接続
        vb.customize [
          'storageattach', :id, 
          '--storagectl', 'IDE Controller', 
          '--port', 1, 
          '--device', 0, 
          '--type', 'hdd', 
          '--medium', file_shared_disk
        ]

      end
    end
  end
end
```

Db2 11.5.8 がLinux 環境において Pacemaker による共用ディスク構成をサポートした。
その挙動を確認する為に、Virtualbox上に共用ディスク構成を用意したが、その際に引っかかった箇所の備忘。

# 目的
Virtualbox + Vagrant 環境で、共用ディスク構成をデプロイする

# 環境
- Fedora Linux 36 (Workstation Edition)
- Vagrant 2.3.1
- VirtualBox 6.1.40

# Vagrantfile例

```ruby:Vagrantfile
file_shared_disk = 'sdisk.vdi'
size_shared_disk = 1

Vagrant.configure('2') do |config|
  %w(node1 noder1540482).each do |_node|
    config.vm.define _node do |ins|
      ins.vm.box = 'fedora/36-cloud-base'
      ins.vm.box_version = '36-20220504.1'
      ins.vm.provider 'virtualbox' do |vb|

        # もし./sdisk.vdiファイルが存在しなかったら
        unless File.exist?(file_shared_disk)

          # VDIフォーマットで仮想ディスクを作成
          vb.customize [
            'createhd', 
            '--filename', file_shared_disk, 
            '--format', 'VDI', 
            '--size', size_shared_disk * 1024, 
            '--variant', 'Fixed'
          ]

          # shareableに変更
          vb.customize [
            'modifyhd', file_shared_disk, 
            '--type', 'shareable'
          ]
        end

        # インスタンスに接続
        vb.customize [
          'storageattach', :id, 
          '--storagectl', 'IDE Controller', 
          '--port', 1, 
          '--device', 0, 
          '--type', 'hdd', 
          '--medium', file_shared_disk
        ]

      end
    end
  end
end
```
- unlessにより、共用ディスク用のファイルが存在しなければ作成させる
- 共用可能なshareable属性とするには、容量固定(Fixed)で作成後にshareableに変更する
- storagectlの'IDE Controller'などは環境により異なる
    - 確認方法: https://qiita.com/kojiwell/items/8f3e92e029e46f826754#%E8%A3%9C%E8%B6%B3


# vagrant upによる同時起動は失敗

unless File.exist?(file_shared_disk)は、両ノード作成前に判断される様子。
そのため、インスタンス未作成状態から単純にvagrant upを実行し、全環境を一度に作成する操作を試みると、node2起動時点で、既にそのディスクは構成されているとして失敗する。


```
$ vagrant up 
Bringing machine 'node1' up with 'virtualbox' provider...
Bringing machine 'node2' up with 'virtualbox' provider...
==> node1: Importing base box 'fedora/36-cloud-base'...
==> node1: Matching MAC address for NAT networking...
...
    node1: Guest Additions Version: 6.0.0 r127566
    node1: VirtualBox Version: 6.1
==> node1: Rsyncing folder: /home/hiroyukionodera/repo/db2hadr_cluster/roles/molecule-db2hadr_cluster/molecule/shard_disk_test/ => /vagrant
==> node2: Importing base box 'fedora/36-cloud-base'...
==> node2: Matching MAC address for NAT networking...
==> node2: Checking if box 'fedora/36-cloud-base' version '36-20220504.1' is up to date...
==> node2: Setting the name of the VM: shard_disk_test_node2_1667198445523_82578
...
==> node2: Running 'pre-boot' VM customizations...
A customization command failed:

["createhd", "--filename", "sdisk.vdi", "--format", "VDI", "--size", 1024, "--variant", "Fixed"]

The following error was experienced:

#<Vagrant::Errors::VBoxManageError: There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["createhd", "--filename", "sdisk.vdi", "--format", "VDI", "--size", "1024", "--variant", "Fixed"]

Stderr: 0%...
Progress state: VBOX_E_FILE_ERROR
VBoxManage: error: Failed to create medium
VBoxManage: error: Could not create the medium storage unit '/xxxx/sdisk.vdi'.
VBoxManage: error: VDI: cannot create image '/xxxx/sdisk.vdi' (VERR_ALREADY_EXISTS)
VBoxManage: error: Details: code VBOX_E_FILE_ERROR (0x80bb0004), component MediumWrap, interface IMedium
VBoxManage: error: Context: "RTEXITCODE handleCreateMedium(HandlerArg*)" at line 510 of file VBoxManageDisk.cpp
>

Please fix this customization and try again.

```


# vagrant up <ノード名> により個別に起動させると成功

```
$ vagrant up node1
Bringing machine 'node1' up with 'virtualbox' provider...
==> node1: Importing base box 'fedora/36-cloud-base'...
==> node1: Matching MAC address for NAT networking...
==> node1: Checking if box 'fedora/36-cloud-base' version '36-20220504.1' is up to date...
...

$ vagrant up node2
Bringing machine 'node2' up with 'virtualbox' provider...
==> node2: Importing base box 'fedora/36-cloud-base'...
==> node2: Matching MAC address for NAT networking...
==> node2: Checking if box 'fedora/36-cloud-base' version '36-20220504.1' is up to date...
...

$ ls -l sdisk.vdi 
-rw------- 1 foo bar 10739515392 Oct 31 14:44 sdisk.vdi

$ VBoxManage showhdinfo sdisk.vdi 
UUID:           10ab0bd6-bf66-44c3-b42f-253fdb789d47
Parent UUID:    base
State:          locked read
Type:           shareable
Location:       /xxxx/sdisk.vdi
Storage format: VDI
Format variant: fixed default
Capacity:       10240 MBytes
Size on disk:   10242 MBytes
Encryption:     disabled
Property:       AllocationBlockSize=1048576
In use by VMs:  shard_disk_test_node1_1667195063815_77780 (UUID: 8a2374d4-3afd-41cd-8a9b-36f2c18a73d3)
                shard_disk_test_node2_1667195144105_73581 (UUID: 9c0ac0cc-2911-484d-b2a0-ec8c66335503)
```
In use by VMsにて、２つのVMに共用されていることが判る。

# 確認1
個別作成後、実際に環境にログインして共用ディスクが使用できるか確認する。

```
$ vagrant ssh node1

[vagrant@fedora ~]$ ls -l /dev/sd*
brw-rw----. 1 root disk 8,  0 Oct 31 05:44 /dev/sda
brw-rw----. 1 root disk 8,  1 Oct 31 05:44 /dev/sda1
brw-rw----. 1 root disk 8,  2 Oct 31 05:44 /dev/sda2
brw-rw----. 1 root disk 8,  3 Oct 31 05:44 /dev/sda3
brw-rw----. 1 root disk 8,  4 Oct 31 05:44 /dev/sda4
brw-rw----. 1 root disk 8,  5 Oct 31 05:44 /dev/sda5
brw-rw----. 1 root disk 8, 16 Oct 31 05:44 /dev/sdb

[vagrant@fedora ~]$ sudo mkfs -t ext4 /dev/sdb 
mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 2621440 4k blocks and 655360 inodes
Filesystem UUID: 98e4baee-d80f-4bdb-bcfe-b0f389128996
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done 

[vagrant@fedora ~]$ sudo mount /dev/sdb /mnt 
mount: (hint) your fstab has been modified, but systemd still uses
       the old version; use 'systemctl daemon-reload' to reload.

[vagrant@fedora ~]$ df /mnt
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/sdb        10218772    24   9678076   1% /mnt

[vagrant@fedora ~]$ ls /mnt
lost+found

[vagrant@fedora ~]$ sudo su -

[root@fedora ~]# date > /mnt/date

[root@fedora ~]# cat /mnt/date
Mon Oct 31 06:19:13 AM UTC 2022

[root@fedora ~]# exit
logout

[vagrant@fedora ~]$ exit
logout
Connection to 127.0.0.1 closed.

$
```
- 少し乱暴だが/dev/sdbを直接フォーマットしてmountし、書き込み
- umountは忘れていた

# 確認2


相手ノードにログインしてmountして内容を確認
```
$ vagrant ssh node2

[vagrant@fedora ~]$ sudo su -

[root@fedora ~]# ls -l /dev/sd*
brw-rw----. 1 root disk 8,  0 Oct 31 05:45 /dev/sda
brw-rw----. 1 root disk 8,  1 Oct 31 05:45 /dev/sda1
brw-rw----. 1 root disk 8,  2 Oct 31 05:45 /dev/sda2
brw-rw----. 1 root disk 8,  3 Oct 31 05:45 /dev/sda3
brw-rw----. 1 root disk 8,  4 Oct 31 05:45 /dev/sda4
brw-rw----. 1 root disk 8,  5 Oct 31 05:45 /dev/sda5
brw-rw----. 1 root disk 8, 16 Oct 31 05:45 /dev/sdb

[root@fedora ~]# mount /dev/sdb /mnt 
mount: (hint) your fstab has been modified, but systemd still uses
       the old version; use 'systemctl daemon-reload' to reload.

[root@fedora ~]# ls /mnt
date  lost+found

[root@fedora ~]# cat /mnt/date
Mon Oct 31 06:19:13 AM UTC 2022

[root@fedora ~]# exit
logout
[vagrant@fedora ~]$ exit
logout
Connection to 127.0.0.1 closed.

$ 
```


# 環境削除
```
$ vagrant destroy -f
==> node2: Forcing shutdown of VM...
==> node2: Destroying VM and associated drives...
==> node1: Forcing shutdown of VM...
==> node1: Destroying VM and associated drives...

$ vagrant status
Current machine states:

node1                     not created (virtualbox)
node2                     not created (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

$ ls sdisk.vdi
ls: cannot access 'sdisk.vdi': No such file or directory
```
- ディスク用ファイルも削除される


# 参考/参照
- VirtualBoxで共有ディスク
    - http://gowatana.blogspot.com/2013/01/virtualbox.html
- [Vagrant] VirtualBox作成時にストレージを追加
    - https://qiita.com/maueki/items/c4ce7c2b7834e3f4ad7d
- VagrantのVMに複数のディスクを追加する方法: 補足
    - https://qiita.com/kojiwell/items/8f3e92e029e46f826754#%E8%A3%9C%E8%B6%B3
- VirtualBox Mania: 仮想ハードディスクの属性
    - https://vboxmania.net/%E4%BB%AE%E6%83%B3%E3%83%8F%E3%83%BC%E3%83%89%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%81%AE%E5%B1%9E%E6%80%A7/
- VirtualBoxで共有DISKファイルを作る
    - https://yoku0825.blogspot.com/2012/10/virtualboxdisk.html
- vb.customize 'storageattach' mounts my disk first time, but changes are lost after vagrant halt ; vagrant up
    - https://stackoverflow.com/questions/27501019/vb-customize-storageattach-mounts-my-disk-first-time-but-changes-are-lost-aft
- DRBD+Corosync+PacemakerでHA MySQL構築
    - https://iteem.tgen.jp.net/?p=342