The mind is like a parachute. If it doesn't open, you're meat.

Building with rake: Provisions

19 Mar 2014

This is the third article in the series and it is part two of the setup saga. the whole thing starts here.

In part one we laid the ground work and ended up with a 32bit CentOS 6.5 installation in a virtual machine configured for control via vagrant.

With the groundwork laid it is time for the provisioning part. The main reason for creating a vagrant base box was because I have never before worked with CentOS, or the KPIT toolchain, so naturally I tend to make mistakes. Sometimes I’ll just blunder so bad that the only way to get back to a viable state is to start from the beginning. With the vagrant base box this whole process is as follows:

vagrant up 
vagrant ssh
#blunder about
#mess up
vagrant halt
vagrant destroy #rinse

Anything that works ends up in the provisioning script


tools Provisioning is the act of installing and configuring software on a computer.

Ideally it would be all software, operating system included, so we could plug in a machine and it would start and auto-magically become a fully functional computer without human intervention. And then we would name it SkySomething and it would form a network with it’s siblings which consequently would be SkyNe…omg, I am working towards the destruction of the human race!

Back to the present, we generally pick a basis configuration for the OS (ergo the base box) and then automate everything else. Full grown provisioning tools like Chef, Puppet and Ansible will allow you to keep large numbers of machines working and also let you use the collective expertise of several thousand IT administrators. I’m just using a shell script and I’m going to embed it in the Vagrantfile. So there…

To (finally) start building our C code we will need Ruby (you still remember this whole thing is “Building with Rake” I hope) and the KPIT RX toolchain .


  • Clone the git repository acompanying this blog post series.
  • Download the RPM for the elf-rx tools from KPIT and place it in the setup/ directory
  • vagrant up

The repository has more detailed instructions with all the ifs and buts for those who don’t want to follow convention.

Once ‘vagrant up’ is finished, log in the VM with ‘vagrant ssh’ and you’re set to work.

Practical stuff

Package managers all across *ix distributions are a mess. Specifically for Ruby the versions available are usually about a month away from end-of-life or at best a couple of years behind the current stable.

Even more specific, yum lists a 1.8.7 version that is long dead and consigned to the history books. So installation from source it is. For the purposes of this experiment this is more than adequate. And to make matters more interesting, lets get the latest and greatest at the time of writing, 2.1.1.

The provisioning “script” is:

yum -y install zlib zlib-devel
yum -y install openssl-devel
yum -y install libyaml libyaml-devel
yum -y install wget
tar xvf ruby-2.1.1.tar.gz
cd ruby-2.1.1
make install
echo Setting up environment
cp /home/vagrant/host_share/setup/bash_profile /home/vagrant/.bash_profile
chown vagrant:vagrant /home/vagrant/.bash_profile
chmod 544 /home/vagrant/.bash_profile
rpm --install /home/vagrant/host_share/setup/gnurx_v14.01_elf-1-1.i386.rpm

I mean, really, this thing has no error handling, nothing. It’s a shambles masquerading as a script. But hey, it mostly works

This script will evolve as we add gems, things go wrong, versions change etc. That is OK. More than OK, it is desired. This is the single source for our development environment.

Other tricks

You will notice there is a setup/bash_profile file and in the provisioning script it is used as the .bash_profile for the vagrant user. This is part of a method I use very often when creating development environments under *ix systems.

Instead of creating elaborate scripts that add users, services, environment variables etc. recreate the filesystem structure for the system under version control and save only the differences to the base installation.

To update the system just copy everything over. Any scripting can be done in your working environment.

This is especially useful when your target is a constrained system that lacks most development tools but it has a lot of other advantages as well. To list a few:

Search across all administered systems from the comfort of your workstation, versioned changes and instant reset to a known state with a simple copy action.


For any other project the toolchain RPM and the Ruby tarfile would be in the repository and the provisioning script would start by installing git and then pulling the repository in the VM. This project will live on the bleeding edge :P !

It’s not unusual for embedded projects to have support lifecycles of 5 years or more. Can you remember which CentOS version was state-of-the-art 7 years ago? Can you guarantee that 6.5 will be available in seven years time? The longer a project will be supported for, the more of it’s environment should be in the repository.

that's the dream The goal is to be able to recreate the development environment at any point in time with just a copy of HEAD at hand.

blog comments powered by Disqus