VirtualBox cli + pxe boot で Cent OS 7 vmを一瞬で立ち上げたい

# 目標
コマンドだけでvm作成 + OSインストールまで終わらせたい

# pxe boot

VirtualBoxにはdhcpがついてて、それには特殊なpxeboot用の機能がついてる

公式マニュアル
> 6.3.2. PXE booting with NAT
PXE booting is now supported in NAT mode. The NAT DHCP server provides a boot file name of the form vmname.pxe if the directory TFTP exists in the directory where the user's VirtualBox.xml file is kept. It is the responsibility of the user to provide **vmname.pxe**.
> https://www.virtualbox.org/manual/ch06.html#network_bridged

それを使うのは簡単で、このrepoが素敵

> https://github.com/defunctzombie/virtualbox-pxe-boot/blob/master/README.md

ただ、今回はそれを使わず、自前dhcp/tftp/ftp/httpを内部ネットワークに立てて、それでやってみる。

## 参考
> https://www.perkin.org.uk/posts/create-virtualbox-vm-from-the-command-line.html  
> https://www.linuxtechi.com/configure-pxe-installation-server-centos-7/

## 必要なサービス
あらかじめ立てたpxe server的なvmを内部ネットワークに所属させ、以下を立てる。

1. dhcp
    2. 新vmをpxe bootさせるために必要。ipを割り当て、networkブートの支持を出す。
    3. ipを割り当てるところをvirtualboxにやってほしくないので、内部ネットワークを使う
        4. NAT/NATネットワークを使うと、virtualboxのdhcpが動いてしまうのでNATは使わない
        5. （そのかわりinternetにつなげなくなるのでyum installとかできなくなる）
2.  tftp
    3.  pxebootしたときの必要ファイル(initrd.img, vmlinuz, pxeboot.cfg/default を新vmにわたすために必要。
        4.  xinetdで起動するのがいいらしい
5.  ftp
    6.  pxebootあとのcent installer(cent〜.isoの中身）を配信する
    7.  vsftpdで/var/lib/pub
8.  http
    9.  cent installerがkickstartするときのks.cfgを配信するために使う
        10.  ftpだとcent installerが受け取れない様子
        11.  cent installerと同じ/var/lib/pubにks.cfg置いておいてsymlinkを/var/www/htmlに置けばok

ftpとhttpのリンクをpxeboot.cfg/defaultのgrub menuにしっかり書くのが大事。

```sh
default menu.c32
prompt 0
timeout 30
#ONTIMEOUT local

menu title ################PXE BOOt MENU ####################

label 1
    menu default
    menu label ^1 ) Install Cent OS 7 via PXE BOOT
    kernel centos7_x64/images/pxeboot/vmlinuz
    append initrd=centos7_x64/images/pxeboot/initrd.img method=ftp://192.168.99.2/pub/ ks=http://192.168.99.2/pub/kickstart/ks.cfg devfs=nomount ramdisk_size=131072 ip=dhcp lang=en_US keymap=us
```

# VboxManageコマンドの勉強
virtualboxをinstallするとVBoxManageコマンドが使える。その基本を学ぶ

つまずいたのはbridgeアダプターの設定。結局cliではできず、cliを叩くと書き換えられるファイル ~.vboxを直接編集することになった。このあとのpxeboot実践では内部ネットワークしか使ってないので、今は知らないふり。

```sh
which VBoxManage

VboxManage list vms
VBoxManage list runningvms

# start
VBoxManage startvm "cent7_0"
# shutdown
VBoxManage controlvm  $VM poweroff
# restart
VBoxManage controlvm  $VM reset

VBoxManage showvminfo "cent7_0"

# 10GB
VBoxManage createhd --filename $VM.vdi --size 10000

VBoxManage list hdds | grep vdi

VBoxManage list ostypes | grep Red

# Create VM
VBoxManage createvm --name $VM --ostype "RedHat_64" --register

# Create SATA Controller
VBoxManage storagectl $VM --name "SATA Controller" --add sata --controller IntelAHCI

# Create the first disk
VBoxManage storageattach $VM --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium $VM.vdi

## without MBR
# make zero MBR at first
dd if=/dev/zero of=mbr.img bs=512 count=1
cat mbr.img | od



# When your storage is ssd
VBoxManage storageattach $VM --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium $VM.vdi --nonrotational on

# Create IDE Controller
VBoxManage storagectl $VM --name "IDE Controller" --add ide

# Create DVD drive
VBoxManage storageattach $VM --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium emptydrive

# When wanna attach to an OS installer image
VBoxManage storageattach $VM --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium /path/to/CentOS-7-x86_64-Minimal-1804.iso

# When wanna attach to a host dvd drive
VBoxManage list hostdvds
VBoxManage storageattach $VM --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium "host:OPTIARC DVD RW AD-7170A"

## Other settings
# multicore対応 I/O APICを有効化
VBoxManage modifyvm $VM --ioapic on
# cpu, memory
VBoxManage modifyvm $VM --cpus 8
VBoxManage modifyvm $VM --memory 8192 --vram 256

## NICの設定 NAT(pxe boot用DHCP)とbridge adapter(FTP用)
VBoxManage modifyvm $VM --nic1 nat

# bridge（hostのeth名）を取得
VBoxManage list bridgedifs
# しかし効きません
VBoxManage modifyvm $VM --nic2 bridged --bridgeadapter1 "en1: Ethernet 2"

# 仕方なくGUIからやります。するとここが変わります
cat VirtualBox\ VMs/vmcli/vmcli.vbox | grep BridgedInterface
            <BridgedInterface name="en1: Ethernet 2"/>

# 内部ネットワーク(自前dhcp)
VBoxManage modifyvm $VM --nic1 intnet --intnet1 intnet

# bootオーダーをnetwork優先に
VBoxManage modifyvm $VM --boot1 net --boot2 dvd --boot3 disk --boot4 none
```



# できあがった起動コマンド
自分の環境ではterminalからこれを叩くと、勝手にcent7ができるようになった。

```sh
## kuji create vm and pxe boot

VM=vmcli

which VBoxManage

VboxManage list vms | grep $VM

# 10GB
VBoxManage createhd --filename $VM.vdi --size 30000

VBoxManage list hdds | grep vdi

VBoxManage list ostypes | grep Red

# Create VM
VBoxManage createvm --name $VM --ostype "RedHat_64" --register

VboxManage list vms | grep $VM

# Create SATA Controller
VBoxManage storagectl $VM --name "SATA Controller" --add sata --controller IntelAHCI

# Create the first disk 
VBoxManage storageattach $VM --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium $VM.vdi --nonrotational on

# Create IDE Controller
#VBoxManage storagectl $VM --name "IDE Controller" --add ide

# Create DVD drive
#VBoxManage storageattach $VM --storagectl "IDE Controller" --port 0 --device 0 --type dvddrive --medium emptydrive

## Other settings
# multicore対応 I/O APICを有効化
VBoxManage modifyvm $VM --ioapic on
# cpu, memory
VBoxManage modifyvm $VM --cpus 8
VBoxManage modifyvm $VM --memory 8192 --vram 256

## NICの設定 
# 内部ネットワーク(自前dhcp)
VBoxManage modifyvm $VM --nic1 intnet --intnet1 intnet

# bootオーダーをnetwork優先に
VBoxManage modifyvm $VM --boot1 disk --boot2 net --boot3 none --boot4 none

# start
VBoxManage startvm $VM

```


この状態だとinternetつながらないので、あとは手でNATとbridgeにネットワークを変更して、それで終わりでいいんじゃないかな。

# 便利なところ
pxe bootだとks.cfgとかpxeboot.cfg/defaultをわざわざiso化してホストOSに配置する必要ないので（pxe server上のfile systemで編集してそのまま置いとくだけで勝手にftp/tftp/httpで配信される）からvm作り直すだけでやり直せて楽ー。

# boot orderについて
1. boot orderがdisk優先だと普通は system not found になるけど、作ったばかりのvdiはMBR(先頭512 byte)が0なのでスルーして二番目のboot(net)が走ってくれる。
    2. 素敵。


# 足りないところ（誰か教えて）
3. bridgeネットワークを最初から当てたいが `Nonexistent host networking interface` エラーでvm起動しない。bugなのだろうか・・


ま、とりあえずこれでcent立てまくりだわー！