ZeroMQ is a powerful library for network programming.

But it’s no fun to just connecting to localhost! By building a single Ubuntu VM and saving it as a Vagrant box, we can spin up as many clients as the machine can handle!

Install Ubuntu 14.04 into a VirtualBox VM

Remeber to Install Ubuntu with user ‘Vagrant’ and forward port 22 to work from the host. Tested with ubuntu-14.04.3-server-amd64.iso

Setting up Vagrant

It is best just to follow https://docs.vagrantup.com/v2/boxes/base.html

This is the default Vagrant public key. Add it to .ssh/authorized_keys by default. Vagrant will change it later:

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key

Also enable passwordless sudo for the vagrant user to the end of the sudoers file:

vagrant ALL=(ALL) NOPASSWD: ALL

Install VirtualBox Additions

sudo apt-get -y install libtool pkg-config linux-headers-generic build-essential dkms autoconf automake git Install the VirtualBox guest additions. Devices -> Insert Guest Additions CD Image sudo mount /dev/cdrom /media/cdrom sudo sh /media/cdrom/VBoxLinuxAdditions.run

Install Dependencies

ZeroMQ uses Libsodium for encryption, but this is not available in the 14.04 LTS repos.

wget -c https://download.libsodium.org/libsodium/releases/libsodium-1.0.8.tar.gz  http://download.zeromq.org/zeromq-4.1.4.tar.gz  
tar -xf libsodium-1.0.8.tar.gz
./configure --prefix=/usr && make
sudo make install

Install ZeroMQ

cd ~
tar -xzf zeromq-4.1.4.tar.gz && cd zeromq-4.1.4
./configure --prefix=/usr && make
sudo make install
cd ~
git clone https://github.com/zeromq/cppzmq

Install rmate (Optional)

For any TextMate users that prefer to use their host machine for editing:

sudo apt-get -y install ruby && sudo gem install rmate

Textmate remote:

ssh -p8022 -R 52698:localhost:52698 127.0.0.1

So now a command in the VM such as:

rmate test.cc

Will open textmate locally if rmate is enabled under TextMate preferences.

Testing that it works

Download the hwserver example from the ZeroMQ documentation and compile it:

gcc hwserver.c -o hwserver -lzmq

With the C++ bindings come in the box we should also be able to compile the hwserver C++ example:

g++ hwserver.cpp -o hwserver -lzmq

Remember to include the zmq.hpp cloned previously.

Packaging the VM

Once we have verified that the VM will build a ZeroMQ project, we can package it using Vagrant for reuse.

Create a box called NodeTemplate from a VM called BaseNode into the directory ~/Boxes:

vagrant package --base BaseNode --output ~/Boxes/NodeTemplate.box

Create a new directory containing a VagrantFile:

Vagrant.configure("2") do |config|
  # Number of nodes to provision
  numNodes = 2
  # IP Address Base for private network
  ipAddrPrefix = "172.16.0.0"
  # Download the initial box from this url
  config.vm.box_url = "file:///Users/nspool/Boxes/NodeTemplate.box"
  # Provision Config for each of the nodes
  1.upto(numNodes) do |num|
    nodeName = ("node" + num.to_s).to_sym
      config.vm.define nodeName do |node|
        node.vm.box = "NodeTemplate"
        node.vm.network :private_network, ip: ipAddrPrefix + num.to_s
        node.vm.provider "virtualbox" do |v|
          v.name = "Cluster Node " + num.to_s
        end
      end
    end
  end

It should now be possible to SSH into each box by name, ie. vagrant ssh node1


Alternative approaches

Here are some approached that I tried, but gave up on for one or another reason.

Alternative 1. Installing from source

Add this to /etc/apt/sources.list:

deb http://us.archive.ubuntu.com/ubuntu vivid main universe 

Then run:

sudo apt-get update &&
sudo apt-get -y upgrade &&
sudo apt-get -y install ruby libtool pkg-config build-essential autoconf automake git libsodium-dev &&
sudo gem install rmate &&
wget -c http://download.zeromq.org/zeromq-4.1.4.tar.gz &&
tar -xzf zeromq-4.1.4.tar.gz && cd zeromq-4.1.4 &&
./configure --prefix=/usr && make && sudo make install &&
cd ~ &&
git clone https://github.com/zeromq/cppzmq

Now reboot. Connect using:

ssh -i ~/.vagrant.d/insecure_private_key -p8022 -R 52698:localhost:52698 vagrant@127.0.0.1

This should compile the example without errors:

g++ hwserver.cpp -o hwserver -lzmq

Then run:

./hwserver 

Now shutdown and package the node.. Except that upgrading

Alternative 2. Using Ubuntu Server 15.10

Libsodium is available for in the 15.10 packages, meaning that it doesn’t need to be built.

Copy SSH public key into authorized_keys. Add to sources:

deb http://httpredir.debian.org/debian/ experimental main contrib non-free
deb-src http://httpredir.debian.org/debian/ experimental main contrib non-free

Then:

apt-get update
apt-get install libzmq5-dev ruby
apt-get gem install rmate