If a C programmer asks "do you want to see something cool?", run away.
--John Van Enk

Monday, March 21, 2011

Use Vagrant, Luke

В моем списке hassle free tools прибавление - теперь там прочно обоснуется Vagrant. Vagrant - это средство для управления виртуализацией вашего development environment. Представьте что у вас есть несколько проектов,  каждый из которых использует какой-то сервер баз данных, какой-то фреймворк, набор библиотек и т.д. И если весь этот зоопарк развернут на вашей рабочей машине, то запутаться не особо-то и долго какая библиотека относится к какому проекту, какие сервисы должны быть запущены. Vagrant предоставляет инструменты для создания виртуальных сэндбоксов конфигурация которых описывается в небольшом файле, который без проблем можно зачекинить в систему контроля версий и тогда другие разработчики для того чтобы получить абсолютно такой же конфигурации сэндбокс для запуска проекта в нем должны будут выполнить лишь пару комманд. Такой подход гарантирует также что разработчики будут использовать идентичный набор сервисов и библиотек при разработке приложения.

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

Vagrant использует Virtualbox в качестве средства виртуализации девелопмент окружения, поэтому он должен быть установлен у вас в системе (последние версии - 4.0.x). Сам инструмент написан на Ruby  и упакован в виде gem'а поэтому сначала необходимо установить ruby & rubygems. Как это сделать пользователям linux рассказывать не надо. А пользователям windows - надо. После установки вышеперечисленного установить Vagrant можно следующим способом:
$ gem install vagrant
Дальше необходимо добавить базовую VM на основе которой и будут создаваться последующие сэндбоксы.
$ vagrant box add base http://files.vagrantup.com/lucid32.box
эта комманда скачает виртуальную машину с установленной ubuntu 10.04 и разместит ее в ~/.vagrant. После этого можно начинать использовать Vagrant при разработке какого-нибудь проекта.
$ mkdir project
$ cd project
$ vagrant init
vagrant init создаст файл project/Vagrantfile который и служит для описания конфигурации сэндбокса.
$ vagrant up
vagrant up создаст новую виртуальную машину, скопировав базовую из ~/.vagrant и запустит ее, на что уйдет некоторое время.

Проверить состояние виртуальных машин можно, выполнив комманду
$ vagrant status
А получить доступ по ssh
$ vagrant ssh
Немного поигравшись можно выяснить некоторые подробности касающиеся того, что за машина нам досталась

vagrant@vagrantup:~$ uname -a
Linux vagrantup 2.6.32-21-generic #32-Ubuntu SMP Fri Apr 16 08:10:02 UTC 2010 i686 GNU/Linux
vagrant@vagrantup:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 10.04.1 LTS
Release: 10.04
Codename: lucid
vagrant@vagrantup:~$ ruby -v
ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]
vagrant@vagrantup:~$ gem -v
1.4.2
vagrant@vagrantup:~$ gem list

*** LOCAL GEMS ***

abstract (1.0.0)
bunny (0.6.0)
chef (0.9.12)
erubis (2.6.6)
extlib (0.9.15)
facter (1.5.8)
highline (1.6.1)
json (1.4.6)
mime-types (1.16)
mixlib-authentication (1.1.4)
mixlib-cli (1.2.0)
mixlib-config (1.1.2)
mixlib-log (1.2.0)
moneta (0.6.0)
ohai (0.5.8)
puppet (2.6.4)
rest-client (1.6.1)
rubygems-update (1.4.2)
systemu (1.2.0)
uuidtools (2.1.1)

vagrant@vagrantup:~$ cat /home/vagrant/.bash_history 
groups
sudo visudo
sudo /etc/init.d/sudo restart
sudo halt
sudo apt-get update
sudo apt-get upgrade dist-upgrade
sudo halt
sudo apt-get install linux-headers-$(uname -r) build-essential
sudo mount /media/cdrom
ls /mnt
ls /media
sudo mount /dev/scd0 /cdrom
ls /cdrom
sudo sh /cdrom/VBoxLinuxAdditions.run 
sudo umount /cdrom
sudo apt-get install openssh-client openssh-server
wget
wget https://github.com/mitchellh/vagrant/raw/master/keys/vagrant.pub
wget http://github.com/mitchellh/vagrant/raw/master/keys/vagrant.pub
wget --no-check-certificatehttp://github.com/mitchellh/vagrant/raw/master/keys/vagrant.pub
wget --no-check-certificate http://github.com/mitchellh/vagrant/raw/master/keys/vagrant.pub
ls
mkdir .ssh
mv vagrant.pub .ssh/authorized_keys
chmod 0700 .ssh
chmod 0600 .ssh/authorized_keys 
sudo apt-get install ruby ruby-dev libopenssl-ruby1.8 irb ri rdoc
ruby -v
wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.6.tgz
ls
tar xvzf rubygems-1.3.6.tgz 
cd rubygems-1.3.6/
ls
sudo ruby setup.rb
sudo ln -s /usr/bin/gem1.8 /usr/bin/gem
cd ..
rm -rf rubygems-1.3.6*
sudo gem update --system
gem -v
sudo gem install chef --no-ri --no-rdoc
sudo gem install puppet --no-ri --no-rdoc
sudo apt-get install nfs-tools
sudo apt-cache search nfs
sudo apt-get install nfs-client nfs-common
sudo nano /etc/ssh/sshd_config 
ls
sudo halt
ls -al /etc | grep motd
cat /var/run/motd
ls /etc/init.d | grep motd
nano /etc/update-motd.d/
ls -al /etc | grep m otd
ls -al /etc | grep motd
rm /etc/motd
sudo rm /etc/motd
sudo nano /etc/motd
sudo chmod 0777 /etc/motd 
exit
sudo reboot
sudo halt
sudo rm -rf .gem/
sudo halt
ls /cdrom/
ls /mnt/
sudo mount /dev/scd0 /cdrom
ls /cdrom/
sudo /cdrom/VBoxLinuxAdditions.run 
sudo reboot
ps aux | grep -i vbox
sudo halt
Кроме того, следует отметить, что каталог проекта расшарен на виртуальную машину и любые изменения в нем носят двусторонний характер

Пустая VM конечно мало подходит для разработки, поэтому следующим логичным шагом является установка необходимого софта. Vagrant поддерживает автоматизированную установку всего необходимого на виртуальную машину, используя для этого Puppet или Chef (на ваш выбор). Оба эти инструмента заслуживают отдельного поста каждый, поэтому описывать какой-либо из них здесь я не буду :). Достаточно сказать лишь, что поместив в Vagrantfile код следующего содержания и запустив vagrant up (или vagrant reload, если виртуальная машина уже и так запущена) в виртуальной машине будет установлен и сконфигурирован Apache:

Vagrant::Config.run do |config|
  config.vm.box = "base"
  config.vm.provision :chef_solo do |chef|
    chef.recipe_url = "http://files.vagrantup.com/getting_started/cookbooks.tar.gz"
    chef.add_recipe("vagrant_main")
  end
end
Совершенно аналогично можно настроить любой другой софт, просто указав местоположение chef cookbooks (возможно, что для этого их придется самим написать).
Ну и последнее, что необходимо сделать - это настроить порт-форвардинг хоста на гостевую ОС

Vagrant::Config.run do |config|
  config.vm.forward_port("web", 80, 4567)
end
Создайте например static html файл в папке project хоста

$ echo "<h1>Hello from a Vagrant VM</h1>" > index.html
Сделайте vagrant up или vagrant reload и откройте в браузере хоста адрес http://lolcathost:4567

Пример, конечно, простой, но идея думаю понятна.

Ссылки: