Contents
Today, we are going to learn how to setup an environment with the awesome tool that any DevOps should know, Vagrant.
Behind this name is a wonderful software which automates the use of virtual machines (VMs) to create reproducible environments on-the-fly.
By creating a simple configuration file, within minutes you will have a fresh virtual machine started and provisioning without any other human interaction. The Vagrant Dev Environment!
Since Vagrant is not a pure virtualization tool by itself, it makes use of providers to do the virtualization such as VMWare, VirtualBox, etc…
And what a better way to demonstrate the power of this tool if not by setting up a distributed file system!
And this is a good thing because RozoFS is exactly what we are going to need. RozoFS is a high performance and scalable open source distributed file system.
You may take a look at what they do, it’s pretty interesting! http:/rozosystems.com/
This demonstration will go as follows: first we will setup the RozoFS cluster, then we will run some rozo commands to show how it works.
In this tutorial, I will suppose that Vagrant and VirtualBox are already installed in your computer, if not here are the download links:
That being said, let’s get to the heart of the matter!
The Vagrant file
The Vagrant file will be the heart of our environment. It contains all the instructions to setup our system.
So to start, create a text file named Vagrantfile and copy paste the code below:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
file_to_disk = "./tmp/large_disk_rozo01.vdi"
node.vm.box = "bento/ubuntu-14.04"
node.vm.hostname = "rozo01"
node.vm.network "private_network", ip: "10.0.42.11"
node.vm.provider :virtualbox do |vb|
vb.cpus = 2
vb.memory = 2048
vb.customize ['createhd', '--filename', file_to_disk, '--size', 50 * 1024]
vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium', file_to_disk]
end
end
Basically, here we have defined all the basic stuff for a VM : Operating System, hostname, IP, disk and the provider (VirtualBox in our case).
But this will create only one VM, and it’s not really what we need. Since we are building a cluster, we will need more machines, so let’s modify this Vagrantfile to look more like our goal.
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
(2..4).each do |i|
file_to_disk = "./tmp/large_disk_rozo0#{i}.vdi"
config.vm.define "rozo0#{i}" do |node|
node.vm.box = "bento/ubuntu-14.04"
node.vm.hostname = "rozo0#{i}"
node.vm.network "private_network", ip: "10.0.42.1#{i}"
node.vm.provider :virtualbox do |vb|
vb.cpus = 2
vb.memory = 2048
unless File.exist?(file_to_disk)
vb.customize ['createhd', '--filename', file_to_disk, '--size', 50 * 1024]
end
vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium', file_to_disk]
end
end
end
end
So now it will deploy 3 VM’s with the same configuration except for the hostname and IP.
Then we will need to execute some shell commands into each VM. So for that, there is a vagrant instruction that allows us to run a shell command just after the VM creation;
node.vm.provision "shell", inline:
The shell commands that we need to run will install and configure everything for RozoFS.
Let’s see now how our Vagrantfile looks.
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
(2..4).each do |i|
file_to_disk = "./tmp/large_disk_rozo0#{i}.vdi"
config.vm.define "rozo0#{i}" do |node|
node.vm.box = "bento/ubuntu-14.04"
node.vm.hostname = "rozo0#{i}"
node.vm.network "private_network", ip: "10.0.42.1#{i}"
node.vm.provider :virtualbox do |vb|
vb.cpus = 2
vb.memory = 2048
unless File.exist?(file_to_disk)
vb.customize ['createhd', '--filename', file_to_disk, '--size', 50 * 1024]
end
vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium', file_to_disk]
end
node.vm.provision "shell", inline: <<-SHELL
wget -O - http:/dl.rozofs.org/deb/devel@rozofs.com.gpg.key | apt-key add -
echo deb http:/dl.rozofs.org/deb/master $(lsb_release -sc) main | tee /etc/apt/sources.list.d/rozofs.list
apt-get update
apt-get install -y rozofs-storaged
apt-get install -y rozofs-exportd
apt-get install -y rozofs-rozofsmount
apt-get install -y rozofs-manager-lib
apt-get install -y rozofs-manager-cli
apt-get install -y rozofs-manager-agent
apt-get install -y rozofs-rozodiag
apt-get install -y nagios-plugins-rozofs
apt-get install -y vim
mkdir -p /srv/rozofs/storages/storage_1_#{i}
mkfs.ext4 /dev/sdb -F
mount /dev/sdb /srv/rozofs/storages/storage_1_#{i}
/etc/init.d/rozofs-storaged restart
cp /vagrant/storage.conf /etc/rozofs/storage.conf
sed -i \'s/storage_1_1/storage_1_#{i}/\' /etc/rozofs/storage.conf
sed -i \'s/sid = 1/sid = #{i}/\' /etc/rozofs/storage.conf
/etc/init.d/rozofs-storaged restart
SHELL
end
end
end
Finally we need to declare one more VM for our master rozo node. The reason why it’s not included in the first loop is because this host needs a specific shell command to run in it.
So here is the final Vagrantfile:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
(2..4).each do |i|
file_to_disk = "./tmp/large_disk_rozo0#{i}.vdi"
config.vm.define "rozo0#{i}" do |node|
node.vm.box = "bento/ubuntu-14.04"
node.vm.hostname = "rozo0#{i}"
node.vm.network "private_network", ip: "10.0.42.1#{i}"
node.vm.provider :virtualbox do |vb|
vb.cpus = 2
vb.memory = 2048
unless File.exist?(file_to_disk)
vb.customize ['createhd', '--filename', file_to_disk, '--size', 50 * 1024]
end
vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium', file_to_disk]
end
node.vm.provision "shell", inline: <<-SHELL
wget -O - http:/dl.rozofs.org/deb/devel@rozofs.com.gpg.key | apt-key add -
echo deb http:/dl.rozofs.org/deb/master $(lsb_release -sc) main | tee /etc/apt/sources.list.d/rozofs.list
apt-get update
apt-get install -y rozofs-storaged
apt-get install -y rozofs-exportd
apt-get install -y rozofs-rozofsmount
apt-get install -y rozofs-manager-lib
apt-get install -y rozofs-manager-cli
apt-get install -y rozofs-manager-agent
apt-get install -y rozofs-rozodiag
apt-get install -y nagios-plugins-rozofs
apt-get install -y vim
mkdir -p /srv/rozofs/storages/storage_1_#{i}
mkfs.ext4 /dev/sdb -F
mount /dev/sdb /srv/rozofs/storages/storage_1_#{i}
/etc/init.d/rozofs-storaged restart
cp /vagrant/storage.conf /etc/rozofs/storage.conf
sed -i \'s/storage_1_1/storage_1_#{i}/\' /etc/rozofs/storage.conf
sed -i \'s/sid = 1/sid = #{i}/\' /etc/rozofs/storage.conf
/etc/init.d/rozofs-storaged restart
SHELL
end
end
config.vm.define "rozomds" do |rozomds|
rozomds.vm.box = "bento/ubuntu-14.04"
rozomds.vm.hostname = "rozomds"
rozomds.vm.network "private_network", ip: "10.0.42.11"
file_to_disk = "./tmp/large_disk_rozo.vdi"
file_to_disk_export = "./tmp/export_disk.vdi"
rozomds.vm.provider :virtualbox do |vb|
vb.cpus = 2
vb.memory = 2048
unless File.exist?(file_to_disk)
vb.customize ['createhd', '--filename', file_to_disk, '--size', 50 * 1024]
end
vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 1, '--device', 0, '--type', 'hdd', '--medium', file_to_disk]
unless File.exist?(file_to_disk_export)
vb.customize ['createhd', '--filename', file_to_disk_export, '--size', 50 * 1024]
end
vb.customize ['storageattach', :id, '--storagectl', 'SATA Controller', '--port', 2, '--device', 0, '--type', 'hdd', '--medium', file_to_disk_export]
end
rozomds.vm.provision "shell", inline: <<-SHELL
wget -O - http:/dl.rozofs.org/deb/devel@rozofs.com.gpg.key | apt-key add -
echo deb http:/dl.rozofs.org/deb/master $(lsb_release -sc) main | tee /etc/apt/sources.list.d/rozofs.list
apt-get update
apt-get install -y rozofs-storaged
apt-get install -y rozofs-exportd
apt-get install -y rozofs-rozofsmount
apt-get install -y rozofs-manager-lib
apt-get install -y rozofs-manager-cli
apt-get install -y rozofs-manager-agent
apt-get install -y rozofs-rozodiag
apt-get install -y nagios-plugins-rozofs
apt-get install -y vim
mkdir -p /srv/rozofs/storages/storage_1_1
mkfs.ext4 /dev/sdb -F
mount /dev/sdb /srv/rozofs/storages/storage_1_1
/etc/init.d/rozofs-storaged restart
cp /vagrant/storage.conf /etc/rozofs/storage.conf
sed -i \'s/storage_1_1/storage_1_1/\' /etc/rozofs/storage.conf
sed -i \'s/sid = 1/sid = 1/\' /etc/rozofs/storage.conf
/etc/init.d/rozofs-storaged restart
rozo agent restart
rozo volume expand 10.0.42.11 10.0.42.12 10.0.42.13 10.0.42.14 -E 10.0.42.11
sleep 20
rozo export create 1 -E 10.0.42.11
sleep 20
rozo mount create -E 10.0.42.11
SHELL
end
config.vm.post_up_message = "
vagrant ssh rozomds
vagrant ssh rozo02
vagrant ssh rozo03
vagrant ssh rozo04"
end
If you want more details on a specific command, you may check Vagrant documentation, you will surely find what you want :Â https://www.vagrantup.com/docs/
Now, from where the Vagrantfile is located, run the following command:
vagrant up
It will execute all the instructions of the Vagrantfile and once it finishes you will get a fresh environment with RozoFS setup in it.

So now, let’s run some RozoFS commands!
Test the environment with RozoFS commands
Like many cluster architectures, there is a master server. It will be from the master server that the RozoFSÂ commands will be run.
So to connect to this master, named rozomds (according to our Vagrantfile), run the vagrant command:
vagrant ssh rozomds
Now we are inside our Vagrant box. From there, we are going to create an export and with one command we’ll mount it on our cluster.
First, let’s see if we already have an export. Run the following command:
root@rozomds:~# rozo node status -E 10.0.42.11 10.0.42.12: - STORAGED: running - ROZOFSMOUNT: - /mnt/rozofs@10.0.42.11/export_1: mounted 10.0.42.13: - STORAGED: running - ROZOFSMOUNT: - /mnt/rozofs@10.0.42.11/export_1: mounted 10.0.42.11: - EXPORTD: running - STORAGED: running - ROZOFSMOUNT: - /mnt/rozofs@10.0.42.11/export_1: mounted 10.0.42.14: - STORAGED: running - ROZOFSMOUNT: - /mnt/rozofs@10.0.42.11/export_1: mounted
As you can see, we already have an export named export_1 and it’s already mounted on all our vagrant hosts.
The other command to see all your exports with more details is:
root@rozomds:~# rozo export get -E 10.0.42.11 EXPORTS: - EXPORT 1: - vid: 1 - root: /srv/rozofs/exports/export_1 - md5: '' - squota: '' - hquota: ''
Note that the rozo command has a very detailed manual and it could be very useful! man rozoÂ
Now we want to create a new export. It’s as simple as following:
root@rozomds:~# rozo export create -n export_2 1 -E 10.0.42.11
Run the command again to get our exports:
root@rozomds:~# rozo export get -E 10.0.42.11 EXPORTS: - EXPORT 1: - vid: 1 - root: /srv/rozofs/exports/export_1 - md5: '' - squota: '' - hquota: '' - EXPORT 2: - vid: 1 - root: /srv/rozofs/exports/export_2 - md5: '' - squota: '' - hquota: ''
Now we mount our export:
root@rozomds:~# rozo mount create -e export_2 -E 10.0.42.11
10.0.42.12:
- export export_2 (eid=2) on /mnt/rozofs@10.0.42.11/export_2:
configuration: added
status: mounted
10.0.42.13:
- export export_2 (eid=2) on /mnt/rozofs@10.0.42.11/export_2:
configuration: added
status: mounted
10.0.42.11:
- export export_2 (eid=2) on /mnt/rozofs@10.0.42.11/export_2:
configuration: added
status: mounted
10.0.42.14:
- export export_2 (eid=2) on /mnt/rozofs@10.0.42.11/export_2:
configuration: added
status: mounted
Our export has been successfully mounted on all our hosts.
If you want to go further with RozoFS file system, this documentation will be very helpful: https://media.readthedocs.org/pdf/rozofs/latest/rozofs.pdf
Conclusion
In this article, we have seen how to build a functional distributed file system running anywhere with the help of Vagrant. Now you can provide to all your developers this Vagrantfile and they will be able to run the embedded solution from their laptop or their development machine.
About TrackIt
TrackIt is an international AWS cloud consulting, systems integration, and software development firm headquartered in Marina del Rey, CA.
We have built our reputation on helping media companies architect and implement cost-effective, reliable, and scalable Media & Entertainment workflows in the cloud. These include streaming and on-demand video solutions, media asset management, and archiving, incorporating the latest AI technology to build bespoke media solutions tailored to customer requirements.
Cloud-native software development is at the foundation of what we do. We specialize in Application Modernization, Containerization, Infrastructure as Code and event-driven serverless architectures by leveraging the latest AWS services. Along with our Managed Services offerings which provide 24/7 cloud infrastructure maintenance and support, we are able to provide complete solutions for the media industry.
