Vagrant, Virtualisation and the SenseHat

Vagrant · Virtualisation · SSH · Network · SenseHat

Objectives

  • Provision a virtual machine(VM) using Vagrant
  • Connect to the VM using Secure shell(SSH)
  • Create a file on the VM in the synced directory and edit it on the host
  • Run a simple Java program on the VM
  • Use common Linux network commands

Prerequesites

  • Completed preparatory lab

Vagrant up!

Command Line Interface(CLI)

The script examples in this lab use the Linux operating system. We will be using linux Command Line Interface(CLI) extensively and the term 'terminal' is often used to describe a program that provides a CLI.

Vagrant

Vagrant's purpose is to manage and configure our virtual machines. In the preparatory lab, you created a Vagrant project from scratch using the "vagrant init" command. You will now modify the Vagrantfile to add more detail.

The Vagrantfile describes the machine(s) used in the project, and how to configure and provision these machines.

In the preparatory lab you created a directory called vagrant-onsite-day. Open the Vagrantfile in this directory and have a look at the contents. You'll see that it's filled with example code. Vagrantfiles are written in the programming language Ruby. Don't worry, knowledge of the Ruby programming language is not necessary.

Replace the contents of the file with the following:

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    config.vm.define "pc0" do |pc0|
        pc0.vm.hostname = "pc0"
        pc0.vm.network :private_network, ip: "192.168.5.2"
    end
    config.vm.box = "frankwalsh/labvm"
    config.ssh.forward_x11 = true
end

An IP address provides an identity to a networked device. Similar to your home or business address supplying that specific physical location with an identifiable address, devices on a network are differentiated from one another through IP addresses. The above script configures a virtual machine, "pc0", with IP address of 192.168.5.2 in a virtual private network (think of a private network as a separate network contained inside the virtual environment). The config.vm.box variable describes the image used for the machine. In this case it's the same one used in the preparatory lab so you should have it downloaded already.

Now open a terminal window in the root directory and enter the following command to start the VM:

$ vagrant up

This will take a few minutes to complete if you haven't done the preliminary lab as the VM image will need to be downloaded the first time it's started. It will be much quicker for subsequent start ups. After it finishes, it will have created the following virtual environment on your machine: Virtual Network

All going well, we should now be able to "see" and connect to pc0 using a remote shell (like ssh), using the dedicated IP address, just as if it was a "real" remote machine.

Secure Shell (SSH)

Although you've started a new virtual machine, you will not actually see anything since Vagrant runs the virtual machine without a Graphical User Interface (one good reason for this is that no UI requires less resources on the host machine, i.e. your laptop). To access the machine, we will use Secure Shell (SSH).

SSH provides a secure channel connecting an SSH client with an SSH server. We will use it in one of it's most common usages. remote command-line login and remote command execution.

Vagrant has a built in command to start a SSH session with a virtual machine.

Open a terminal window in the directory containing the Vagrantfile and enter:

vagrant ssh pc0

This will start a session with pc0. The session should start by displaying VM info:

$ vagrant ssh pc0
Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-37-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

  System information as of Wed Mar  7 12:37:30 UTC 2018

  System load:  0.04              Processes:           77
  Usage of /:   3.8% of 39.34GB   Users logged in:     0
  Memory usage: 25%               IP address for eth0: 10.0.2.15
  Swap usage:   0%                IP address for eth1: 192.168.5.2

  Graph this data and manage this system at:
    https://landscape.canonical.com/

  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud

New release '16.04.4 LTS' available.
Run 'do-release-upgrade' to upgrade to it.


Last login: Wed Mar  7 12:37:30 2018 from 10.0.2.2
vagrant@pc0:~$

You are now logged in to the VM via SSH. This is a linux machine so you can use all the usual linux CLI commands to navigate, configure, change etc.

  1. Change directory to /vagrant
    vagrant@pc0:~$ cd /vagrant
    vagrant@pc0:/vagrant$

You are now in the defaults vagrant directory which shares with the root Vagrant project directory on the host machine. Check this is the case by running ls. You should see your Vagrantfile.

Vagrantfile basics

Lets take a closer look at the Vagrantfile. Note the following:

  1. The location of the vagrantfile indicates the root directory of your vagrant project.
  2. The contents of the Vagrantfile describes the machine and resources you need to run your project.
  3. The Vagrantfile specifies what software to install and how you want to access it.

As you've already seen, Vagrant shares your project directory to the /vagrant directory in your guest machine.

In the SSH session with pc0, type cd /vagrant at the command prompt to change directory to the shared directory:

vagrant@pc0:~$ cd /vagrant

Now type ls at the command prompt to list the contents of the shared directory

vagrant@pc0:/vagrant$ ls
vagrantfile

You will see at the moment you only have one file in that directory at the moment.

Type touch HelloWorld.java at the command promu to create a new, empty, file called 'HelloWorld.java'

vagrant@pc0:/vagrant$ touch HelloWorld.java
vagrant@pc0:/vagrant$ ls
HelloWorld.java vagrantfile
vagrant@pc0:/vagrant$

Now close the vagrant ssh session using the 'exit' command:

$ exit

Have a look at the the contents the your project directory on your host machine. You should see HelloWorld.java that you created in pc0. Using an editor on your host machine, add the following code to the file and save.

public class HelloWorld {

    public static void main(String[] args) {
        // Prints "Hello, World" to the terminal window.
        System.out.println("Hello, World");
    }

}

As you know from programming module, we need to compile the above source code to byte code (i.e. HelloWorld.class) before we can run it. Java 8 has already been installed on the VM box you are using. Let us now compile and run some source code.

Open a new SSH session with pc0 and enter the following commands in the SSH session to compile and run HelloWorld.java:

vagrant@pc0:/vagrant$ javac HelloWorld.java
vagrant@pc0:/vagrant$ java HelloWorld
Hello, World

The Network

Lets have a look at the environment you've created from a network perspective...

If don't already have a SSH session open, SSH into pc0 by opening a terminal window in your vagrant-onsite-day directory and enter "vagrant ssh" at the command prompt.

Now lets explore some Linux terminal commands that are useful for networking.

ifconfig

In order for a device to connect to a network, it needs a network interface. The ifconfig utility provides a quick and easy way to view network interface information on a machine.
In your ssh session, type ifconfig to view the status of all currently active network interfaces, including their names. You should see something similar to the following: ifconfig

Note some significant information here, namely the interface names and their IP(Internet Protocol) addresses. Note that the interface eth1 with ip address(inet addr) 192.168.5.2 is what you specified in the Vagrantfile.

Now open a new, separate terminal window on the host machine and type ifconfig to view the status of all currently active network interfaces on your host. You should see something similar to this:

Who am I?

Just in case you forget who you are (as in what user you're currently working as on a machine) you can use the whoami command. Type whoami at the command prompt and it should well you you're vagrant (as that's who you logged in as with the ssh session).
ifconfig

hostname

The hostname command lets you know what host name is being used to identify you in the network. In the ssh session, type hostname at the command prompt to see the hostname of your machine. As you can see, it's what we specified in the Vagrantfile, pc0.
ifconfig

PING

PING(Packet INternet Groper) sends ECHO_REQUEST packets to the IP address you specify. It’s a handy way to see whether your machine can communicate with the Internet or another machine. However many machines are configured not to respond to pings so, if you don't get a response, it doesn't mean the machine is not connected and available for communication. In you ssh session with the pc0, let's ping the host machine (i.e. your laptop). Vagrant would have created a virtual network interface with the address 192.168.5.1. In the SSH session, type ping 192.168.5.1 to see of it connects. You should see responses similar to the following:
ifconfig

You can also use Ping to check if you can connect to the internet. Type ping google.ie to see if you can get a response from Google. This time, you should see something like this:
ifconfig Notice that you used a domain name this time. In this case, your machine would have used Domain Name System (DNS) to get the IP address for a "google.ie". As you can see, in this example the IP address is 209.85.203.94 and we got a successful reply so the virtual machine, pc0, is connected to the internet!
We'll cover more about DNS in future coursework.

Tracepath

Tracepath is a network troubleshooting utility which shows the number of "hops" taken by network "packets" to reach a destination and also determine the travelling path through the network. In the SSH session, type tracepath www.tssg.ie to see the path though the network to the tssg web site. You should see responses similar to the following:
ifconfig

Route

Most connected machines use routing tables to compute the next hop for a packet. you can use the route command to show the local ip routing table for the machine pc0. To see default routing table in Linux, type route at the command prompt. ifconfig
You will see three entries. The default entry indicates the "default gateway" address. This is the destination address where all traffic will be sent if the destination is not on any of the other connected routes (this is analogous to the "all other routes" road signs you might see on the road). The other two entries relate to the networks connected to interface eth0 and eth1. Run the ifconfig command again and examine this in relation to the routing table. Based on this, we can say the any network traffic from this machine to a destination address starting with 192.168.5.* will be routed(sent out) to eth1, everything else will be on eth0.

Exercises

So you've all connected to the Wifi with your host machines So you should be able to ping each others host machines from your virtual machine, pc0. Try the following:

  • Determine the ip address of your host machine on the Wifi network.
  • Ask your neighbour (or help them) what their IP address is.
  • SSH into your virtual machine (pc0) and ping them. All things going well you should see a successful response.
  • Also, do a tracepath using a neighbours IP address. Does it complete successfully and how many hops does it take?

Raspberry Pi Sense HAT Emulator

Try a pi before you buy!

As you know we will be using a Raspberry Pi in the latter part of the module to explore wireless networking and "device-level" connected applications. You will need to buy a Raspberry pi and Sense HAT to complete and assignments and labs. The Sense HAT(Hardware Attached on Top), the multi-purpose add-on board for the Raspberry Pi that contains various sensors and an array of RGB LEDs. IT was also sent into space as part of the Astro Pi project on the International Space Station. Sense HAT

However, we don't need the Pi and Sense Hat to start working with it. A US-based startup called Trinket with Raspberry Pi have developed a web-based emulator for Sense Hat. The emulator is a useful development tool as it allows you to test, debug and share applications without putting them on an actual device (you will probably use an emulator for your Mobile App Dev module).
Sense HAT Emulator
You can get loads more info at https://www.raspberrypi.org/blog/sense-hat-emulator/

Programming the Emulator

The emulator uses a programming language called Python. You have probably not come across Python before but you do have knowledge of programming now and we will use Trinket to "hack" existing code example. Try the following with Trinket:

  • Open the following Sensor Hat template in Trinket: https://trinket.io/python/a242f4535b

  • Have a close look at the script and try to deduce what's going to happen when you run it.

  • Run the example by clicking the run button.

As you can see, it prints the message across the LEDs. See if you can change the program to: + print you name instead of "HDip Comp Sci" + change the colour to red.

Environment Data

The Sense HAT has temperature, pressure and humidity sensors that can sense environment variables. Notice that the emulator has sliders you can move to change these values. Sense Hat
You can use this to test how your code responds to environmental variables.
Have a look at the following trinket code that uses the temperature sensor:

Now let use the temperature sensor on the board to make a kind of "smart" thermostat. Check out the following example that uses the temperature sensor: https://trinket.io/library/trinkets/cceba5489f

Run the example and you'll see the temperature printed in the lower console output window. Let's combine modify this simple example to use the temperature to do the following: + If the temperature greater than or equal to 25 degrees celcius print "HOT!" on the Sense Hat, otherwise print "Fine!" in green(i.e if it's below 25)

In the trinket temperature example, replace the code in main.py with the following:

from sense_hat import SenseHat

sense = SenseHat()
sense.clear()
green = (0, 255, 0)
red = (255,0,0)
while True:
  temp = sense.get_temperature()
  if temp >=25:
    sense.show_message("HOT!", text_colour = red)
  else:
    sense.show_message("Fine!", text_colour = green)
  print(temp)

Now we are using an environment variable (temperature) in our program to make a decision(i.e. decide if it's hot or not) and visually indicating this using the Sense Hat.

Internet of Things

This is a networking module so now lets stick some networking into the program and connect our emulated device to the internet. Let's presume this device is part of a network of environment sensors that need to send their data to a central messaging service.
In this example, we will send our data to a "channel" on the Thingspeak platform. We can do this by programmatically sending a HTTP request with an encoded URL. This is similar to what you did in Web Dev with HTML forms except we're doing it programmatically using Python.

Update your program with the following code:

from sense_hat import SenseHat
import urllib.request
import time


sense = SenseHat()
sense.clear()
green = (0, 255, 0)
red = (255,0,0)
#You'll need to update the following statement...
serviceurl = 'https://api.thingspeak.com/update?field1=YOUR_DEVICE_NAME&api_key=USE_YOUR_OWN_OR_GET_IT_IN_CLASS>'

while True:
  temp = sense.get_temperature()
  url = serviceurl + '&field2='+str(temp)
  if temp >=25:
    sense.show_message("HOT!", text_colour = red)
  else:
    sense.show_message("Fine!", text_colour = green)    
  urllib.request.urlopen(url)
  time.sleep(5)
  print(temp)

Replace the YOUR_DEVICE_NAME with a unique name of your device (I'll leave that up to you) and replace USE_YOUR_OWN_OR_GET_IT_IN_CLASS with the api key given in class.

Want to do more...

Create an account at https://thingspeak.com/ and set up your own channel to receive data from your device.