PackerでAlpine LinuxのVirtualBox VMを作る


## はじめに

Dockerを動かす環境を配布したく思い、VirtualBox VMを作る事にしました. この記事でしている事は↓

* [VirtualBox] のVM Imageを作る
* Guest OSは [Alpine Linux] を使う
* [Packer] で [Alpine Linux] を仮想マシンイメージにインストールするまでを自動化する

## 環境

* Mac OS 10.12.4 / Windows 10
* Packer v1.0.0
* VirtualBox 5.1.22

## Source code.

↓の手順で作った物がここにあります.

* https://github.com/megmogmog1965/packer-virtualbox-alpine

## Directory Layout.

```
packer-virtualbox-alpine/
├── answerfile
└── packer.json
```

## How to build.

[VirtualBox] をインストールします.

* https://www.virtualbox.org/wiki/Downloads

[Packer] は実行ファイルをダウンロードして使います. Pathの通った所に置いて下さい.

* https://www.packer.io/downloads.html

Terminal (WindowsはPowerShell) を開き、作業ディレクトリを作ります.

```
$ mkdir packer-virtualbox-alpine
$ cd packer-virtualbox-alpine
```

[Packer] の設定ファイルを ``packer-virtualbox-alpine/packer.json`` に書きます.

```json:packer-virtualbox-alpine/packer.json
{
  "variables": {
    "password": "packer"
  },
  "builders": [
    {
      "type": "virtualbox-iso",
      "iso_url": "https://nl.alpinelinux.org/alpine/v3.6/releases/x86_64/alpine-virt-3.6.1-x86_64.iso",
      "iso_checksum": "f4421357ed2c969046b95cef6fc4844aeebfe8a2323049915dbe953d5f1d3c36",
      "iso_checksum_type": "sha256",
      "guest_os_type": "Linux26_64",
      "ssh_username": "root",
      "ssh_password": "{{user `password`}}",
      "vboxmanage": [
        ["modifyvm", "{{.Name}}", "--memory", "1024"],
        ["modifyvm", "{{.Name}}", "--cpus", "2"],
        ["modifyvm", "{{.Name}}", "--audio", "none"],
        ["modifyvm", "{{.Name}}", "--boot1", "disk"],
        ["modifyvm", "{{.Name}}", "--boot2", "dvd"]
      ],
      "disk_size": "2048",
      "boot_wait": "30s",
      "boot_command": [
        "root<enter><wait>",
        "passwd<enter><wait>{{user `password`}}<enter><wait>{{user `password`}}<enter><wait>",
        "setup-interfaces<enter><wait><enter><wait><enter><wait><enter><wait>",
        "/etc/init.d/networking start<enter><wait10>",
        "setup-sshd -c openssh<enter><wait>",
        "echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config<enter><wait>",
        "/etc/init.d/sshd restart<enter><wait5>"
      ],
      "shutdown_command": "poweroff"
    }
  ],
  "provisioners": [
    {
      "type": "file",
      "source": "answerfile",
      "destination": "/tmp/answerfile"
    },
    {
      "type": "shell",
      "expect_disconnect": true,
      "inline": [
        "echo '{{user `password`}}\n{{user `password`}}\ny\n' | setup-alpine -f /tmp/answerfile",
        "/etc/init.d/sshd stop && reboot"
      ]
    },
    {
      "type": "shell",
      "expect_disconnect": true,
      "pause_before": "10s",
      "inline": [
        "sed -i -e 's/^#http/http/g' /etc/apk/repositories"
      ]
    }
  ]
}
```

> * "builders" > "boot_command" でしてること
>     1. NetworkをONにする
>     2. sshdをroot login許可して起動する ("provisioners"の為にsshが必要)
> 
> * "provisioners" でしてること
>     1. [answerfile] \(Alipne Linuxのセットアップスクリプトに食わせる設定\) を送る
>     2. [Alpine Linux] を ``/dev/sda`` にInstallする
>     3. rebootする (Installした仮想ディスクから起動する)
> * reboot中に次のコマンドが実行されないように ``"pause_before": "10s"`` が必要です
>     * https://github.com/hashicorp/packer/issues/4006

[Alpine Linux] のセットアップファイルを ``packer-virtualbox-alpine/answerfile`` に書きます.

```ini:packer-virtualbox-alpine/answerfile
# Example answer file for setup-alpine script
# If you don't want to use a certain option, then comment it out

# Use US layout with US variant
KEYMAPOPTS="us us"

# Set hostname to alpine-test
HOSTNAMEOPTS="-n alpine-vm"

# Contents of /etc/network/interfaces
INTERFACESOPTS="auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
    hostname alpine-vm
"

# Search domain of example.com, Google public nameserver
DNSOPTS="-n 8.8.8.8"

# Set timezone to UTC
TIMEZONEOPTS="-z UTC"

# set http/ftp proxy
PROXYOPTS="none"

# Add a random mirror
APKREPOSOPTS="-f"

# Install Openssh
SSHDOPTS="-c openssh"

# Use openntpd
NTPOPTS="-c openntpd"

# Use /dev/sda as a data disk
DISKOPTS="-m sys /dev/sda"

# Setup in /media/sdb1
#LBUOPTS="/media/sdb1"
#APKCACHEOPTS="/media/sdb1/cache"
```

> answerfile は改行コードが ``CRLF`` (Windows) だとエラーになるので注意

以下のコマンドでビルドをします.

```
$ packer build packer.json
```

うまくいけば ``.ovf`` と ``.vmdk`` ファイルが出来ます.

```shell-session
$ ls -alh output-virtualbox-iso/
total 70800
drwxr-xr-x   4 user  staff   136B  6 12 23:18 .
drwxr-xr-x  11 user  staff   374B  6 12 23:15 ..
-rw-------   1 user  staff    35M  6 12 23:18 packer-virtualbox-iso-1497276927-disk001.vmdk
-rw-------   1 user  staff   6.5K  6 12 23:18 packer-virtualbox-iso-1497276927.ovf
```


[Alpine Linux]:https://alpinelinux.org/
[Packer]:https://www.packer.io/
[VirtualBox]:https://www.virtualbox.org/
[answerfile]:https://wiki.alpinelinux.org/wiki/Alpine_setup_scripts