In this blog I'll post news about Ubuntu, Linux, Android, my current hardware experiments, etc. Most of the posts will be some sort of mental notes which I think will be useful for others. Please be patient because it might take some time...

zondag 5 januari 2014

Setting up a vagrant basebox for Oracle Linux by using veewee

Introduction

Note: Due to my professional life I use Oracle Linux a lot (Which is a distro that tracks Red Hat so it is very similar to RH and CentOS) therefore I will use Oracle Linux for the VM's in this blogpost as well. Don't worry about a possible price tag; Oracle Linux is free and you can get free updates from their Oracle public yum servers. I am no Oracle employee, so if you want their vision: https://linux.oracle.com.

Another reason why I use Oracle linux is because vagrant boxes were not easy to find for this distro. At least not for usage with libvirt. This makes it more interesting topic for a blog post.

For home usage I really like mint. So the building of the basebox is done on my home PC which runs mint (which is Ubuntu based and thus a Debian derivative).

Overview

In order to build a vagrant basebox we will need to go through the following steps

Install Ruby version manager (rvm)

Install bundler gem

Install veewee as a gemset in rvm

Installing kvm support for your system.

Installing ruby-libvirt gem

Create a storage pool

Create a basebox

Install a compatible Vagrant with libvirt

Create a vagrant config and test.

The remaining of this blogpost will have sections corresponding with these steps. The reader can skip steps that are of no interest to him (I don't track your reading).

Install the pre-requisites

Install rvm

Ruby works by sourcing a script. By sourcing this script rvm gets 'activated'.

source /home/$USER/.rvm/scripts/rvm

Once rvm is ready for setup we will install ruby 1.9.2 in it since this is the version we will use to run veewee

rvm install 1.9.2

Additional remark regarding rvm: rvm will be a function but in order for this to be initialized correclty you need to use a loginshell (if this is chinese to you and you wish to translate do a 'man bash' and start reading the 'INVOCATION' section). Since I was using guake (a dropdown terminal) this was not done automatically when opening a new terminal. Luckily there is a checkbox 'Run command as a login shell' in the guake preferences, after selecting this box rvm was loaded automaticlly in every new guake shell.

Install veewee as a gemset

Now that rvm is installed and a ruby 1.9.2 is available we can install veewee. We will get the latest version by cloning the github repository of the original creator.

$USER@$HOST ~ $ cd
$USER@$HOST ~ $ git clone https://github.com/jedi4ever/veewee.git
Cloning into 'veewee'...
remote: Reusing existing pack: 13273, done.
remote: Total 13273 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (13273/13273), 4.13 MiB | 1.86 MiB/s, done.
Resolving deltas: 100% (8370/8370), done.
Checking connectivity... done
$USER@$HOST ~ $ cd veewee/
You are using '.rvmrc', it requires trusting, it is slower and it is not compatible with other ruby managers,
you can switch to '.ruby-version' using 'rvm rvmrc to [.]ruby-version'
or ignore this warning with 'rvm rvmrc warning ignore /home/$USER/veewee/.rvmrc',
'.rvmrc' will continue to be the default project file in RVM 1 and RVM 2,
to ignore the warning for all files run 'rvm rvmrc warning ignore all.rvmrcs'.
********************************************************************************************************************
* NOTICE *
********************************************************************************************************************
* RVM has encountered a new or modified .rvmrc file in the current directory, this is a shell script and *
* therefore may contain any shell commands. *
* *
* Examine the contents of this file carefully to be sure the contents are safe before trusting it! *
* Do you wish to trust '/home/$USER/veewee/.rvmrc'? *
* Choose v[iew] below to view the contents *
********************************************************************************************************************
y[es], n[o], v[iew], c[ancel]> v
********************************************************************************************************************
* The contents of the .rvmrc file will now be displayed. *
* After reading the file, you will be prompted again for 'yes or no' to set the trust level for this particular *
* version of the file. *
* *
* Note: You will be re-prompted each time the .rvmrc file's contents change *
* changes, and may change the trust setting manually at any time. *
********************************************************************************************************************
(( press a key to review the .rvmrc file ))
rvm use ruby-1.9.2@veewee --create
#rvm use ruby-1.8.7@veewee --create
alias veewee="bundle exec veewee"
alias irb="bundle exec irb"
#alias vagrant="bundle exec vagrant"
********************************************************************************************************************
* Viewing of /home/$USER/veewee/.rvmrc complete. *
********************************************************************************************************************
* Trusting an .rvmrc file means that whenever you cd into this directory, RVM will run this .rvmrc shell script. *
* Note that if the contents of the file change, you will be re-prompted to review the file and adjust its trust *
* settings. You may also change the trust settings manually at any time with the 'rvm rvmrc' command. *
********************************************************************************************************************
y[es], n[o], v[iew], c[ancel]> y
gemset veewee is not existing, creating.
ruby-1.9.2-p320 - #gemset created /home/$USER/.rvm/gems/ruby-1.9.2-p320@veewee
ruby-1.9.2-p320 - #generating veewee wrappers.
Using /home/$USER/.rvm/gems/ruby-1.9.2-p320 with gemset veewee

A lot has happened in the previous code block.

We descended into the home folder of the current user (you can install veewee somewhere else if you want).

There we cloned the github repository.

Next we descended into the cloned directory. This activated rvm since it contained a .rvmrc file. Which is a project configuration file for rvm. More info on this can be found here.

By looking at the .rvmrc file we see that this script creates an environment ruby-1.9.2@veewee. This means a named gemset called veewee for ruby-1.9.2. It also sets up an alias which allows the linux users to just call veewee.

Install bundler gem

For this make sure that rvm is in the correct environment. You can check the current environment with:

Finally install veewee

We have got the veewee source code in $HOME/veewee thanks to the clone of the github repository. We will descend into this directory and install veewee as a gem by executing bundle install. (As in previous section it is important that the ruby-1.9.2-p320@veewee environment is active).

Logout and login before building kvms (otherwise you might get a permission denied like:)

There was a problem opening a connection to libvirt: Error making a connection to libvirt URI qemu:///system:
Call to virConnectOpen failed: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied

This error is a permission error. Possibly because the user executing the command is not in the libvirtd group.

Create a libvirt storage pool

The following ruby script can be used to create a storage pool. A storage pool is necessary as there the disks will be placed. For libvirt one of the possiblities is to set a directory as a repository. Since this is an easy solution we go for these approach. The following script is borrowed from http://libvirt.org/ruby/examples/storage.rb. It is just adapted in order to only create the storage pool and no volumes. Make sure you change the path (it has the dummy value USER in it).

# http://libvirt.org/ruby/examples/storage.rb
# this program demonstrates the use of the libvirt storage APIs. In particular
# it demonstrates directory pool creation, volume creation, and teardown.
# libvirt supports many other kinds of storage pools, including iSCSI, NFS,
# etc. See http://libvirt.org/formatstorage.html for more details
require 'libvirt'
# a directory storage pool.
storage_pool_xml = <libvirt-pool/home/$USER/libvirt-pool
EOF
# open up the connection to libvirt
conn = Libvirt::open('qemu:///system')
# print out how many storage pools are currently active
puts "Number of storage pools: #{conn.num_of_storage_pools}"
# create our new storage pool
pool = conn.define_storage_pool_xml(storage_pool_xml)
# build the storage pool. The operation that this performs is pool-specific;
# in the case of a directory pool, it does the equivalent of mkdir to create
# the directory
pool.build
# start up the pool
pool.create
# print out how many active storage pools are now there; this should be one
# more than before
puts "Number of storage pools: #{conn.num_of_storage_pools}"
# print out some information about the pool. Note that allocation can be
# much less than capacity; see the discussion for the storage volume XML for
# more details
puts "Storage Pool:"
puts " Name: #{pool.name}"
puts " UUID: #{pool.uuid}"
puts " Autostart?: #{pool.autostart?}"
conn.close

Run this in your rvm environment (ruby-1.9.2-p320@veewee) and with ruby

Create a basebox using veewee

Now we are ready to create our basebox. We will create a basebox for Oracle Linux 6.5. Veewee make use of template directories describing VMs out of which it builds the baseboxes. In the version that I cloned from github there was no template for Oracle Linux 6.5 yet. Since the differences between Oracle Linux 6.4 and 6.5 do not impose big changes on the installation procedure we can create a new template directory based on the template of Oracle Linux 6.

Next we can create a definition for a kvm VM out of the template, we call it oel65_kvm. A definition is like a working copy of a template. It alows you to create definitions for servers with different software installed on them. For this first example we keep the definition the same as the template:

$USER@$HOST ~/veewee $ veewee kvm define 'oel65_kvm' 'OracleLinux-6.5-x86_64-DVD' --workdir=/home/$USER/veewee
The basebox 'oel65_kvm' has been successfully created from the template 'OracleLinux-6.5-x86_64-DVD'
You can now edit the definition files stored in /home/$USER/veewee/definitions/oel65_kvm or build the box with:
veewee kvm build 'oel65_kvm' --workdir=/home/$USER/veewee

A console windows will show and you can login (veewee/veewee). Once logged in you can look at /etc/udev/rules.d/70-persistent-net.rules. It will look like:

So udev finds an e1000 interface which is bound to eth0 but the interface is not available. So it will never come up. There is as well a interface which gets number eth1. But for eth1 there is no valid configuration present (/etc/sysconfig/network-scripts/ifcfg-eth1).

Change the file so only the entry for virtio-pci is still present. For that entry change NAME eth0 to eth1

1 opmerking:

When building your boxes fails with could not open .....qcow2 and you notice that those files are owned by root you should set the user and group in /etc/libvirt/qemu.conf appropriately. This is explained in more detail on https://github.com/jedi4ever/veewee/issues/996