Использование Packer для создания базового образа Ubuntu 14.04 Vagrant с провайдером Parallels

В предыдущей статье я рассказал, как создать базовый образ Ubuntu 14.04 для Vagrant с провайдером Parallels самым простым способом — с помощью Veewee. Простой, потому что Parallels штатно поддерживается этой утилитой и базовые образы отлично собираются лишь с минимальными ухищрениями.

Сейчас мне тяжело рассказать, что лучше, Packer или Veewee (про отношения Packer«а и Vagrant«а лучше прочитать в сообщении Хашимото. Я просто опишу, как сделать базовый образ для Vagrant с привлечением многообещающего инструмента — Packer.

Скажу сразу, что мне удалось решить задачу не сразу, пришлось попотеть. Начиная с установки самого билдера, заканчивая настройками шаблона и созданием скриптов. Также предупрежу, что я использую OS X, но это и так подразумевается, так как описываю использование Parallels.

Установка Packer

Итак, Packer. Его можно установить или из пакета, или, что лучше, с помощью Homebrew:

$ brew tap homebrew/binary $ brew install packer

Проверяю, всё в порядке:

$ packer usage: packer [--version] [--help] []

Available commands are: build build image (s) from template fix fixes templates from old versions of packer inspect see components of a template validate check that a template is valid

Globally recognized options: -machine-readable Machine-readable output format.

$ packer --version Packer v0.5.2

Установка билдера Parallels для Packer

Использую плагин Rickard von Essen«а.

Предварительно нужно установить Parallels Virtualization SDK 9.

Устанавливаю prl-utils

$ brew tap rickard-von-essen/formulae $ brew install --HEAD prl-utils

Сообщение «Warning: Could not fix libprl_sdk.5.dylib in…/prltype» проигнорировал.

Проверяю, работает:

$ prlctl --version prlctl version 9.0.24229.991745

Устанавливаю Go и Mercurial (git уже давно установлен в составе Command line tools из Xcode):

$ brew install go $ brew install hg

Для Go создаю отдельный каталог и прописываю его в .zshrc или .bashrc:

$ mkdir -p $HOME/Documents/DevOps/go $ vim ~/.zshrc export GOPATH=»$HOME/Documents/DevOps/go» export PATH=»$GOPATH/bin:$PATH» $ source ~/.zshrc

Здесь «тонкий» момент. Я некоторое время бился с проблемой создания образа vagrant«а из-за того, что packer-post-processor-vagrant ставится вместе с плагином и он же есть в штатной установке Packer. Если поставить путь к Go в конце $PATH, то будут ошибки. После наступания на эти грабли я перешёл на явное указание путей в ~/.packerconfig.

Устанавливаю билдер:

$ mkdir -p $GOPATH/src/github.com/rickard-von-essen/ $ cd $GOPATH/src/github.com/rickard-von-essen/ $ git clone https://github.com/rickard-von-essen/packer-parallels.git $ cd packer-parallels

Устанавливаю кросс-компилятор Gox:

$ go get github.com/mitchellh/gox

Если сейчас запустить компиляцию, то будет ошибка:

builder/parallels/common/ssh.go:31: undefined: «code.google.com/p/go.crypto/ssh».ClientAuth

Нужно использовать старую версию библиотеки ssh:

$ vim builder/parallels/common/ssh.go import ( // gossh «code.google.com/p/go.crypto/ssh» gossh «code.google.com/p/gosshold/ssh»

Можно компилировать:

$ make

Вот что поставилось:

$ ls -l $GOPATH/bin -rwxr-xr-x 1 ctrld staff 4112768 Apr 24 17:14 gox -rwxr-xr-x 1 ctrld staff 13444028 Apr 25 11:19 packer-builder-parallels-iso -rwxr-xr-x 1 ctrld staff 13063596 Apr 25 11:19 packer-builder-parallels-pvm -rwxr-xr-x 1 ctrld staff 11707548 Apr 25 11:19 packer-post-processor-vagrant

Следующий очень важный момент — указать, где искать новые билдеры и постпроцессор vagrant, переопределяющий штатный (!):

$ vim ~/.packerconfig { «builders»: { «parallels-iso»:»/Users/ctrld/Documents/DevOps/go/bin/builder-parallels-iso», «parallels-pvm»:»/Users/ctrld/Documents/DevOps/go/bin/builder-parallels-pvm» }, «post-processors»: { «vagrant»:»/Users/ctrld/Documents/DevOps/go/bin/packer-post-processor-vagrant» } }

Создание базового образа для Vagrant

Все инструменты подготовлены. В процессе работы я смотрел на примеры в репозитории rickard-von-essen/packer-examples, а также на сконвертированный из моего предыдущего шаблона с помощью утилиты veewee-to-packer.

Полный шаблон вы можете взять в моём репозитории на github ctrld/packer-parallels-ubuntu-14.04.

Приступаю к созданию шаблона.

$ mkdir -p /Users/ctrld/Documents/DevOps/p4 $ cd /Users/ctrld/Documents/DevOps/p4

$ vim trusty64.json { «variables»: { «ssh_name»: «vagrant», «ssh_pass»: «vagrant», «hostname»: «trusty64» },

«builders»: [{ «type»: «parallels-iso»,

«guest_os_type»: «linux», «guest_os_distribution»: «linux-2.6»,

«iso_url»: «http://releases.ubuntu.com/trusty/ubuntu-14.04-server-amd64.iso», «iso_checksum»:»01545fa976c8367b4f0d59169ac4866c», «iso_checksum_type»: «md5»,

«http_directory» : «http», «http_port_min» : 9001, «http_port_max» : 9001,

«ssh_username»:», «ssh_password»:», «ssh_wait_timeout»:»20m»,

«parallels_tools_mode»: «upload», «parallels_tools_path»: «prl-tools-lin.iso», «parallels_tools_url»:»/Applications/Parallels Desktop.app/Contents/Resources/Tools/prl-tools-lin.iso»,

«boot_wait»:»4s»,

«delete_vm»: «false», «prlctl»: [ [«set»,»,»--memsize»,»512»] ],

«boot_command» : [ », »/install/vmlinuz noapic », «preseed/url=http://:/preseed.cfg », «debian-installer=en_US auto locale=en_US kbd-chooser/method=us », «hostname= », «fb=false debconf/frontend=noninteractive », «keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA », «keyboard-configuration/variant=USA console-setup/ask_detect=false », «initrd=/install/initrd.gz — » ],

«shutdown_command»: «echo | sudo -S shutdown -P now» }], «provisioners»: [{ «type»: «shell», «scripts»: [ «scripts/apt.sh», «scripts/sudo.sh», «scripts/vagrant.sh», «scripts/parallels.sh», «scripts/cleanup.sh» ], «execute_command»: «echo 'vagrant'|sudo -S sh ''» }], «post-processors»: [{ «type»: «vagrant», «output»:».box» }] }

Очередные очень важные моменты:

обратите внимание на parallels_tools_path. Если его явно не указать, то будет списан prl-tools-other.iso, который далеко не для Linux если не выполнить скрипт scripts/cleanup.sh, то в созданной Vagrant«ом виртуальной машине не подымется сеть в скрипте scripts/vagrant.sh списывается ключ для соединения по ssh из Vagrant перечень возможных guest_os_distribution можно посмотреть командой

$ prlctl create x –distribution list

Создаю файл preseed.cfg для автоматизированной установки (копия из veewee-packer с единственным изменением в get_hostname и get_domain):

$ mkdir http $ vim http/preseed.cfg ## Options to set on the command line d-i debian-installer/locale string en_US.utf8 d-i console-setup/ask_detect boolean false d-i console-setup/layout string us

d-i netcfg/get_hostname string this-host d-i netcfg/get_domain string this-host

d-i time/zone string UTC d-i clock-setup/utc-auto boolean true d-i clock-setup/utc boolean true

d-i kbd-chooser/method select American English

d-i netcfg/wireless_wep string

d-i base-installer/kernel/override-image string linux-server

d-i debconf debconf/frontend select Noninteractive

d-i pkgsel/install-language-support boolean false tasksel tasksel/first multiselect standard, ubuntu-server

d-i partman-auto/method string lvm

d-i partman-lvm/confirm boolean true d-i partman-lvm/device_remove_lvm boolean true d-i partman-auto/choose_recipe select atomic

d-i partman/confirm_write_new_label boolean true d-i partman/confirm_nooverwrite boolean true d-i partman/choose_partition select finish d-i partman/confirm boolean true

# Write the changes to disks and configure LVM? d-i partman-lvm/confirm boolean true d-i partman-lvm/confirm_nooverwrite boolean true d-i partman-auto-lvm/guided_size string max

# Default 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 user-setup/encrypt-home boolean false d-i user-setup/allow-password-weak boolean true

# Minimum packages (see postinstall.sh) d-i pkgsel/include string openssh-server ntp

# Upgrade packages after debootstrap? (none, safe-upgrade, full-upgrade) # (note: set to none for speed) d-i pkgsel/upgrade select none

d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true d-i finish-install/reboot_in_progress note

d-i pkgsel/update-policy select none

choose-mirror-bin mirror/http/proxy string

Создаю скрипты (veewee-packer с небольшими изменениями):

$ mkdir scripts

scripts/apt.sh:

$ vim scripts/apt.sh apt-get -y update apt-get -y upgrade apt-get -y install linux-headers-$(uname -r) apt-get -y install dkms apt-get -y install ntp apt-get -y install build-essential apt-get -y install vim

scripts/sudo.sh:

$ vim scripts/sudo.sh groupadd -r admin usermod -a -G admin vagrant cp /etc/sudoers /etc/sudoers.orig sed -i -e '/Defaults\s\+env_reset/a Defaults\texempt_group=admin' /etc/sudoers sed -i -e 's/%admin ALL=(ALL) ALL/%admin ALL=NOPASSWD: ALL/g' /etc/sudoers

scripts/vagrant.sh:

$ vim scripts/vagrant.sh mkdir /home/vagrant/.ssh chmod 700 /home/vagrant/.ssh cd /home/vagrant/.ssh wget --no-check-certificate 'https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub' -O authorized_keys chmod 600 /home/vagrant/.ssh/authorized_keys chown -R vagrant /home/vagrant/.ssh

scripts/parallels.sh:

$ vim scripts/parallels.sh # Install the Parallels Tools PARALLELS_TOOLS_ISO=/home/vagrant/prl-tools-lin.iso mount -o ro -o loop $PARALLELS_TOOLS_ISO /media/cdrom /media/cdrom/install --install-unattended-with-deps --progress umount /media/cdrom

# Cleanup # rm $PARALLELS_TOOLS_ISO

scripts/cleanup.sh:

$ vim scripts/cleanup.sh apt-get -y autoremove

dd if=/dev/zero of=/EMPTY bs=1M rm -f /EMPTY

echo «cleaning up dhcp leases» rm /var/lib/dhcp/*

echo «cleaning up udev rules» rm /etc/udev/rules.d/70-persistent-net.rules mkdir /etc/udev/rules.d/70-persistent-net.rules rm -rf /dev/.udev/ rm /lib/udev/rules.d/75-persistent-net-generator.rules

echo «pre-up sleep 2» >> /etc/network/interfaces exit

Проверяю шаблон:

$ packer validate trusty64.json Template validated successfully.

При создании шаблона полезно включить отладку:

$ export PACKER_LOG=true $ export PACKER_LOG_PATH=/tmp/packer-p4.log

Создаю базовый образ, на моём Mac«е это заняло 11 минут:

$ packer build trusty64.json

==> Builds finished. The artifacts of successful builds are: --> parallels-iso: 'parallels' provider box: trusty64.box

Полный вывод команды можно посмотреть в gist«е ctrld/11286520.

Размер образа:

$ ls -l *box -rw-r--r-- 1 ctrld staff 581315973 Apr 25 17:37 trusty64.box

Добавляю образ в Vagrant (–force был полезен при перестройке образа):

$ vagrant box add --force --provider parallels trusty64 trusty64.box ==> box: Adding box 'trusty64' (v0) for provider: parallels box: Downloading: file:///Users/ctrld/Documents/DevOps/p4/trusty64.box ==> box: Successfully added box 'trusty64' (v0) for 'parallels'!

Готовлю описание виртуальной машины:

$ vagrant init trusty64

Создаю её:

$ vagrant up --provider parallels Bringing machine 'default' up with 'parallels' provider… ==> default: Importing base box 'trusty64'… ==> default: Setting the name of the VM: p4_default_1398437110491_78850 ==> default: Preparing network interfaces based on configuration… default: Adapter 0: shared ==> default: Clearing any previously set network interfaces… ==> default: Booting VM… ==> default: Waiting for machine to boot. This may take a few minutes… default: SSH address: 10.211.55.47:22 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Connection refused. Retrying… ==> default: Machine booted and ready! ==> default: Checking for Parallels Tools installed on the VM… ==> default: Mounting shared folders… default: /vagrant => /Users/ctrld/Documents/DevOps/p4

Игнорирую «Connection refused», так как машина нормально запустилась.

Захожу по ssh:

$ vagrant ssh

Welcome to Ubuntu 14.04 LTS (GNU/Linux 3.13.0–24-generic x86_64)

* Documentation: https://help.ubuntu.com/ Last login: Fri Apr 25 14:35:00 2014 from 10.211.55.2 vagrant@trusty64:~$ uname -a Linux trusty64 3.13.0–24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014×86_64×86_64×86_64 GNU/Linux

Всё работает нормально. После пары десятков запусков за время работы над шаблоном я был почти счастлив.

Полный текст статьи читайте на TheAppleGeek