ixpict.com

small artificial life

Сборка образов для Vagrant с помощью packer.io

Многие кто пользуются шефом используют vagrant для тестирования своих кукбуков. Есть много способов собирать образа под vagrant, пожалуй самый простой - это установить нужный вам Linux в VirtualBox, произвести первоначальные настройки, добавить ключи, вызвать vagrant package и упаковать получившийся box. Технология проста и понятна. Но в какой-то момент становится понятным что parallels существенно производительнее, а поддерживать ручную сборку образов под две виртуалки - довольно утомительно. И тут на помощь приходит packer.io.

Итак, сегодня цель проста, получить два идентичных образа Debian Jessie один для virtualbox, другой для parallels. Причем процесс создания этих образов должен быть максимально автоматизирована.

Подготовка

  1. Скачиваем и устанавливаем packer.io.
  2. Уже должны быть установлены и работать VirtualBox и Parallels Desktop
  3. Скачиваем и устанавливаем Parallels Virtualization SDK
  4. Скачиваем и устанавливаем Vagrant

В общем-то и всё, начальные шаги завершены.

Готивим с packer.io

Обычно подрузамевается что вы будете работать с уже готовой виртуалкой, но в нашем случае мы хотим выполнить следующее:

  • скачать iso-образ с репозитория
  • запустить установку debian jessie с нашим preseed файлом
  • прогнать скрипты для “финальной” подгонки образа под корпоративный стандарт

Создадим файл debian-jessie.json, в этом файле мы будем описывать конфигурацию будущего образа. Вот примерная конфигурация такого файла для virtualbox:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{
  "variables": {
    "mirror": "http://mirror.yandex.ru/debian-cd/8.3.0/amd64/iso-cd/",
    "iso_name": "debian-8.3.0-amd64-netinst.iso",
    "checksum_md5": "a9b490b4215d1e72e876b031dafa7184",
    "preseed_file": "/debian/preseed.cfg",
    "hostname": "jessie-amd64-chef",
    "ssh_username": "vagrant",
    "ssh_password": "vagrant"
  },
  "builders": [
    {
      "name": "virtualbox",
      "type": "virtualbox-iso",
      "headless": "true",
      "vboxmanage": [
        ["modifyvm", "{{.Name}}", "--memory", "1024"],
        ["modifyvm", "{{.Name}}", "--cpus", "1"]
      ],
      "guest_os_type": "Debian_64",
      "iso_url": "{{user `mirror`}}{{user `iso_name`}}",
      "iso_checksum": "{{user `checksum_md5`}}",
      "iso_checksum_type": "md5",
      "disk_size": "8000",
      "guest_additions_url":"file:///Applications/VirtualBox.app/Contents//MacOS/VBoxGuestAdditions.iso",
      "http_directory": "http",
      "ssh_username": "{{user `ssh_username`}}",
      "ssh_password": "{{user `ssh_password`}}",
      "ssh_port": 22,
      "ssh_wait_timeout": "10000s",
      "shutdown_command": "echo '{{user `ssh_password`}}'|sudo -S /sbin/shutdown -hP now",
      "boot_wait": "4s",
      "boot_command" : [
        "<esc><wait>",
        "install ",
        "preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}{{user `preseed_file`}} <wait>",
        "debian-installer=en_US ",
        "auto ",
        "locale=en_US ",
        "kbd-chooser/method=us ",
        "netcfg/get_hostname={{ user `hostname` }} ",
        "netcfg/get_domain=vagrant ",
        "fb=false ",
        "debconf/frontend=noninteractive ",
        "console-setup/ask_detect=false ",
        "console-keymaps-at/keymap=us ",
        "keyboard-configuration/xkb-keymap=us ",
        "<enter><wait>"
      ]
    }
  ]

}

Для верификации json-а можно воспользоваться jsonlint.

Теперь немного о том что мы здесь делаем:

  • Раздел variables, определяет значения которыем мы можем переопеределить при сборке образа с помощью ключика -var (удобно если вы планируете например позже написать Makefile, дабы автоматизировать процесс)
  • builders - раздел в котором мы можем описать различные инструменты для сборки образов. Параметры лучше смотреть в документации.
  • обратите внимание, http_directory - невеороятно полезная штука, фактически это поднимет http-сервер, который будет смотреть на указанную директорию и отдавать файлы из неё, через неё мы прокинем pressed.cfg файл.
  • boot_wait - это время ожидания, после которого будут внесены команды из boot_command

Этого темплайта должно хватить на то чтобы загрузить VirtualBox, скачать образ с зеркала mirror.yandex.ru, после чего запустить установку, используя наш файлик pressed.cfg

Выполняем проверку шаблона:

1
2
$ packer validate debian-jessie.json
Template validated successfully.

Создаем папку для нашего пресид файла и папки для скриптов:

1
mkdir -p http/debian scripts/debian

Создаем файлик для сетапа образа, для этого можно воспользоваться например генератором таких файлов или заполнить руками:

preesed.cfg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
####################################################################
#  PRESEED - Created Mon Feb 22 23:40:50 2016
####################################################################

# Wiki: http://wiki.debian.org/DebianInstaller/Preseed
# Great work!  Thanks for preseed and the d-i installer


####################################################################
# Installation Sources
####################################################################

# Where are we pulling bits from?

# Note:  To use your own local repository, this is what you want
# to edit.
#
# It should look like this:
#d-i     mirror/http/hostname    string (IP Address of your local server)
#d-i     mirror/http/directory   string (HTTP Path to your Repository - like /natty )
d-i     mirror/country          string ru
d-i     mirror/http/hostname    string mirror.yandex.ru
d-i     mirror/http/directory   string /debian/
d-i     mirror/http/proxy       string
d-i     mirror/suite            string stable

# Post install APT setup
d-i     apt-setup/uri_type      select http
d-i     apt-setup/hostname      string mirror.yandex.ru
d-i     apt-setup/directory     string /debian/
d-i     apt-setup/another       boolean false
d-i     apt-setup/security-updates      boolean false
d-i     finish-install/reboot_in_progress note
d-i     prebaseconfig/reboot_in_progress        note

d-i     apt-setup/non-free  boolean true
d-i     apt-setup/contrib   boolean true

####################################################################
# Networking
####################################################################

# Network Configuration
d-i     netcfg/disable_dhcp     boolean false
d-i     mirror/http/proxy string
d-i     netcfg/choose_interface select eth0
d-i     netcfg/wireless_wep     string

####################################################################
# Disk Partitioning/Boot loader
####################################################################

d-i     partman-auto/disk               string /dev/sda
d-i     partman-auto/method             string lvm
d-i     partman-lvm/confirm boolean true
d-i     partman-lvm/confirm_nooverwrite boolean true
d-i     partman-auto/choose_recipe select atomic
d-i     partman-partitioning/confirm_write_new_label boolean true
d-i     partman/choose_partition select finish
d-i     partman/choose_partition select finish
d-i     grub-installer/with_other_os    boolean false
d-i     grub-installer/only_debian boolean true
d-i     grub-installer/bootdev  string default
d-i     partman/confirm_nooverwrite boolean true

####################################################################
# Localizations
####################################################################

# Install Time 
d-i console-tools/archs string skip-config
d-i   debian-installer/locale string en_US
d-i   console-keymaps-at/keymap select us

d-i     languagechooser/language-name-fb    select English
d-i     debian-installer/locale             select en_US.UTF-8

# Timezone
d-i     tzconfig/gmt            boolean false
d-i     tzconfig/choose_country_zone/Europe select Moscow
d-i     tzconfig/choose_country_zone_single boolean true
d-i     time/zone select  Europe/Moscow
d-i     clock-setup/utc boolean true
d-i     kbd-chooser/method  select  American English
d-i     mirror/country  string  manual
d-i     clock-setup/ntp boolean false

# X11 config
xserver-xorg     xserver-xorg/autodetect_monitor              boolean true
xserver-xorg     xserver-xorg/config/monitor/selection-method select medium
xserver-xorg     xserver-xorg/config/monitor/mode-list        select 1024x768 @ 60 Hz
xserver-xorg     xserver-xorg/config/display/modes            multiselect 1024x768, 800x600

####################################################################
# User Creation
####################################################################

# Root User
d-i passwd/root-password            password vagrant
d-i passwd/root-password-again      password vagrant

# Mortal User
d-i passwd/user-fullname            string vagrant
d-i passwd/username                 string vagrant
d-i passwd/user-password            password vagrant
d-i passwd/user-password-again      password vagrant
d-i passwd/user-default-groups string audio cdrom video admin sudo

####################################################################
# Software Selections
####################################################################
popularity-contest popularity-contest/participate boolean false
tasksel tasksel/first multiselect ssh-server standard
d-i pkgsel/include string sudo

####################################################################
# Additional preseed entries (from data/debconf)

exim4-config exim4/no_config boolean true

####################################################################
# Finishing
####################################################################

d-i cdrom-detect/eject boolean true

Вот как примерно это будет выглядить, если выставить опцию “headless” в “false”,

Теперь дополним файл шаблона аналогичными настройками для parallels:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
{
  "variables": {
    "mirror": "http://mirror.yandex.ru/debian-cd/8.3.0/amd64/iso-cd/",
    "iso_name": "debian-8.3.0-amd64-netinst.iso",
    "checksum_md5": "a9b490b4215d1e72e876b031dafa7184",
    "preseed_file": "/debian/preseed.cfg",
    "hostname": "jessie-amd64-chef",
    "ssh_username": "vagrant",
    "ssh_password": "vagrant"
  },
  "builders": [
    {
      "name": "virtualbox",
      "type": "virtualbox-iso",
      "vboxmanage": [
        ["modifyvm", "{{.Name}}", "--memory", "1024"],
        ["modifyvm", "{{.Name}}", "--cpus", "1"]
      ],
      "guest_os_type": "Debian_64",
      "iso_url": "{{user `mirror`}}{{user `iso_name`}}",
      "iso_checksum": "{{user `checksum_md5`}}",
      "iso_checksum_type": "md5",
      "disk_size": "8000",
      "guest_additions_url":"file:///Applications/VirtualBox.app/Contents//MacOS/VBoxGuestAdditions.iso",
      "http_directory": "http",
      "ssh_username": "{{user `ssh_username`}}",
      "ssh_password": "{{user `ssh_password`}}",
      "ssh_port": 22,
      "ssh_wait_timeout": "10000s",
      "shutdown_command": "echo '{{user `ssh_password`}}'|sudo -S /sbin/shutdown -hP now",
      "boot_wait": "4s",
      "boot_command" : [
        "<esc><wait>",
        "install ",
        "preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}{{user `preseed_file`}} <wait>",
        "debian-installer=en_US ",
        "auto ",
        "locale=en_US ",
        "kbd-chooser/method=us ",
        "netcfg/get_hostname={{ user `hostname` }} ",
        "netcfg/get_domain=vagrant ",
        "fb=false ",
        "debconf/frontend=noninteractive ",
        "console-setup/ask_detect=false ",
        "console-keymaps-at/keymap=us ",
        "keyboard-configuration/xkb-keymap=us ",
        "<enter><wait>"
      ]
    },
    {
      "name": "parallels",
      "type": "parallels-iso",
      "iso_url": "{{user `mirror`}}{{user `iso_name`}}",
      "iso_checksum": "{{user `checksum_md5`}}",
      "iso_checksum_type": "md5",
      "ssh_username": "{{user `ssh_username`}}",
      "ssh_password": "{{user `ssh_password`}}",
      "ssh_port": 22,
      "ssh_wait_timeout": "10000s",
      "parallels_tools_flavor":"lin",
      "prlctl": [
        ["set", "{{.Name}}", "--memsize", "1024"],
        ["set", "{{.Name}}", "--cpus", "1"]
      ],
      "hard_drive_interface": "sata",
      "parallels_tools_guest_path": "Flavor",
      "guest_os_type": "debian",
      "vm_name": "{{ user `hostname` }}",
      "http_directory": "http",
      "http_port_min": "8900",
      "http_port_max": "9000",
      "shutdown_command": "echo '{{user `ssh_password`}}'|sudo -S /sbin/shutdown -hP now",
      "boot_wait": "4s",
      "boot_command" : [
        "<esc><wait>",
        "install ",
        "preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}{{user `preseed_file`}} <wait>",
        "debian-installer=en_US ",
        "auto ",
        "locale=en_US ",
        "kbd-chooser/method=us ",
        "netcfg/get_hostname={{ user `hostname` }} ",
        "netcfg/get_domain=vagrant ",
        "fb=false ",
        "debconf/frontend=noninteractive ",
        "console-setup/ask_detect=false ",
        "console-keymaps-at/keymap=us ",
        "keyboard-configuration/xkb-keymap=us ",
        "<enter><wait>"
      ]
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "execute_command": "echo '{{user `ssh_password`}}'|sudo -S bash '{{.Path}}'",
      "scripts": [
        "scripts/debian/common/vagrant.sh",
        "scripts/debian/common/fixes-for-vagrant.sh",
        "scripts/debian/common/sudoers.sh"
      ]
    }
  ],
  "post-processors": [
    {
      "type": "vagrant",
      "only": ["virtualbox"],
      "compression_level": 9,
      "include": "files/virtualbox/metadata.json",
      "output": "boxes/debian-8.3.0-virtualbox.box"
    },
    {
      "type": "vagrant",
      "only": ["parallels"],
      "compression_level": 9,
      "include": "files/virtualbox/metadata.json",
      "output": "boxes/debian-8.3.0-paralles.box"
    }
  ]
}

Сбилдим образы с разрешенной опцией parallel:

1
packer build --parallel=true debian-jessie.json

Все сопутсвующие файлики (провижион и пост-процессинг) я положил в github.