Introduction
This is a guide for future tutors of the NoT A Lab that will guide you through the necessary hardware and software setups.
These instructions assume that you have a running installation of Debian Buster or new which, at the time of writing, is the current Debian testing version.
If you have such a system running or are willing to adapt you can continue to generating the lab instructions.
Software Setup
Generating the instructions
The first task will be to generate a more readable form of these setup instructions and of the instructions for the students.
To generate these mdBook is used. To install mdBook and other build requirements you have to follow these steps:
- Install requirements from the debian reposiory:
$ sudo apt install git make cargo
- Install mdBook using cargo:
$ cargo install mdbook
- Add cargo’s binary directory to your
PATH
:$ echo 'PATH=${PATH}:${HOME}/.cargo/bin' >> ~/.bashrc`
- Open a new terminal and check if everything worked
by running:
$ mdbook
If none of the commands above threw any errors you should now be ready to download and compile the lab instructions using the following steps:
- Clone the repository:
$ cd Downloads $ git clone "https://gitlab.com/nota-lab/nota-lab"
- Build the bootstrap instructions:
$ cd nota-lab/bootstrap/ $ make
- Build the lab instructions:
$ cd ../instructions/ $ make
- The generated instructions can be found in
the
bootstrap/book
andinstructions/book
folders and can be viewed using a web browser:$ cd ../bootstrap/ $ firefox book/index.html
You can now change the source files in the bootstrap/src
and instructions/src
folders as you see fit and re-run
make
to generate an HTML version.
Generating disk images
The operating system images for the Raspberry Pis and the cloud application are automatically generated using vmdb2. To install it and other build requirements run:
$ sudo apt install make vmdb2 qemu-system qemu-user-static openssl debian-keyring
We will be using the official Debian repositories instead of Raspbian on the Raspberry Pis, this means that first-generation Raspberry Pis, which use an older CPU, will not work with the generated image file.
The cloud image is also based on Debian and is expected to run in a virtual machine in the same network as the Raspberry Pis, or at least be reachable by them.
To generate the image file change into the directory containing
the image descriptions and run make
to generate the image
files.
$ cd ~/Downloads/nota-lab/disk_images
$ make
Note: On a computer with a spinning harddrive (e.g.: not an SSD) this process can take hours, and you will have to check then and now if you have to enter your password.
You may need to enter a password multiple times as parts of the build
process use sudo
to gain root priviliges.
While the Raspberry Pi image is building you can follow the status using the following command:
$ sudo tail -n 1000 -f ~/Downloads/nota-lab/disk_images/rpi_student.img.log
While the Cloud image is building you can follow the status using this command instead:
$ sudo tail -n 1000 -f ~/Downloads/nota-lab/disk_images/vm_server.img.log
If everything goes well you should, after some minutes,
end up with a file called rpi_student.img
and another
file called vm_server.img
.
Server setup
The server setup should be performed first as the Raspberry Pi setup instructions expect the server to be available.
The cloud image can be set as the harddisk image in your virtualization environment of choice. You may also have some luck with writing the image to an USB drive like you would write the Raspberry Pi image to an SD card and boot from that drive.
To simplify the setup the network should be setup to be bridged to the ethernet interface of the server.
To test the image without the necessary network setup you can also try running:
$ make run_server
Server first boot
On the first start the image will ask some
questions and setup a tutor
account with
a provided password.
Raspberry Pi setup
You can flash the Raspberry Pi images on an SD-Card with a dd
command like the following:
$ sudo dd if=~/Downloads/nota-lab/disk_images/rpi_student.img bs=8M of=/dev/sd_
Where you replace /dev/sd_
by the drive name of your SD-Card
as discovered by e.g. dmesg -w
or blkid
.
The Raspberry Pi file will be 7Gb large, so that it will fit safely
on an 8Gb SD-Card. If you need more storage space you may
use cfdisk
and resize2fs
on the running Raspberry Pi,
if you need the image to fit on smaller cards you can change
the first lines of rpi_student.vmdb
to generate a different
image size.
Raspberry Pi first boot
Upon first boot the Raspberry Pis will ask some questions regarding the keyboard layout and timezone.
For most questions you can go with whatever
the example says, note however that the
keyboard layout is not set before the first reboot,
so you will have to deal with an american keyboard layout
where the /
character is left of the right shift key.
The ids you give the setup script have to be unique in the lab as the hostname and WiFi SSID will be derived from them. You can however use characters or numbers or whatever suits you best.
When you are done answering questions
the Pi will reboot and you can log in using
the student
account and the password you provided.
When asked about the xfce4-panel configuration answer “Use defaults”.
Finally we have to work around a quirk in the firefox
version used that makes it difficult for image builders
to install custom certificates and easy for enduser, which
is totally stupid their design decision.
With the cloud server running in the same network perform the following steps in the webbrowser to install the certificate:
You can also perform this step on other computers in the network in order to access the lab materials from them.
Maintainance
You should run the image creation process each year before the lab takes place to stay on top of security updates.
Even if you do not generate a new image you should at least re-flash the image to the SD-Cards to make sure the students work in a fresh environment.
Flashing NodeMCU
Building
The Microcontroller boards need to be manually flashed with the NodeMCU firmware in order to run the Lua programs developed by the students.
Luckily we do not need to set up the complex ESP8266 SDK and can instead use the Online builder provided by the NodeMCU devs.
Go to the builder website, enter a valid mail address and select the following modules to include:
- DHT
- file
- GPIO
- MQTT
- net
- node
- PWM
- timer
- UART
- WiFi
Finally hit “Build” and wait for the firmware file to arrive via E-Mail.
Flashing
In the E-Mail you will receive a link to a float and an integer version of the firmware. We will be using the float version.
Download the firmware and use esptool (which comes pre-installed on the Raspberry Pi images) to upload it to the microcontroller boards:
$ esptool.py --port /dev/ttyUSB0 write_flash 0 nodemcu-master-…-float.bin
esptool.py v2.5.0
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
MAC: 12:34:56:78:9A:CD
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0240
Compressed 430704 bytes to 277188...
Wrote 430704 bytes (277188 compressed) at 0x00000000 in 24.4 seconds (effective 141.2 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
Note: Depending on the source of your esptool installation
the command name may be esptool.py
or esptool
.
This flashing has to be performed once per board.
Maintainance
You should run the image creation process each year before the lab takes place to stay on top of security updates.
Even if you do not generate a new image you should at least re-flash the image to the microcontrollers to make sure the students work in a fresh environment.
Hardware Setup
Behind the scenes
This chapter tries to document how certain aspects of the lab work to make future work on it easier.
Network configuration
Address configuration
The student Raspberry Pis and the virtual machine try getting an IPv4 address on their ethernet adapter via DHCP.
The simplest setup is to connect them all to a simpler consumer router that hands out IP addresses from a pool.
Each Raspberry Pi will, in addition, run an isolated network on the WiFi interface on which it gives out IP addresses using DHCP.
Clients connected to that network can not access the internet, the other Raspberry Pis, or the cloud server.
The network is condigured using systemd-networkd
in the configuration files in /etc/system/network
.
The WiFi setup is done using hostapd
.
The WiFi interface can not be used to connect to
wireless networks.
The old ifconfig
line of tools are deprecated,
use for example ip addr
to show the IP addresses
assigned to you network interfaces.
DNS
The Raspberry Pis and the virtual machine get assigned their DNS server to use using DHCP.
It is not assumed that custom domain names can
be added to the zones of that DNS server.
In order to get human-readable names
for e.g. the nota-cloud
virtual machine
LLMNR is used, which sends DNS requests to
the whole subnet using multicast packets
and the corresponding host answers with its
IP address.
This will not work if the virtual machine and the Pis are not in the same multicast domain (≈ separated by a router). The you will have to configure DNS to resolve the domain name of the cloud server and generate an appropriate server certificate.
Internet Access
Also the Lab is mostly self contained there are reasons to give internet access to the Raspberry Pis and virtual machine, namely:
- The Raspberry Pis do not contain a real time clock, they need access to an NTP server to get the correct time. The server certificates can appear invalid when the the time is wrong.
- The students should be able to look up programming ressources while working.
Certificate Authority
A design goal of the cloud unit is for the students to learn that communication over the public internet may not happen unencrypted.
This is why the fake cloud environment also uses encrypted HTTPS.
In order to enable HTTPS we need certificates signed by a certificate authority trusted by all the participants in the network. Acquiring certificates signed by a real CA would complicate the lab setup so a fake CA is created during the disk image build process.
This is all done by the Makefile
in
disk_images/certificates/
that sets up the
CA, creates a key for the cloud server to use
and creates a signed certificate for that key.
If you decide to run the server with a custom domain
name you should add that domain name to
the disk_images/certificates/nota-cloud.conf
file.
FAQ
- The certificates appear invalid:
- Check that the system time is correct and that the devices can reach an NTP server.
- Make sure the virtual machine and Raspberry Pi images ware built on the same host and in one go.
Cloud Server
Web Server
Running on the virtual machine is an instance of nginx that serves static files and acts as reverse proxy.
When connected to on port 80, using unencrypted
HTTP, it serves the files in /var/www/nota-nossl
.
When connected to on port 443, using encrypted
HTTPS, it serves the files in /var/www/nota
and will proxy requests to URLs below https://nota-cloud/api/
to the cloud API server.
This server is configured using the files in /etc/nginx
and controlled using $ sudo systemctl restart nginx
.
API Server
The API server serves the interactive part of the cloud app, it runs with the user id of the tutor user.
It is written in Python 3, using Bottle to perform the request routing and gevents to realize the event streaming. Gunicorn is used to deploy the server.
This server is controlled using
$ systemctl --user restart nota_api
.
The server expects data to be POST
ed
to the /api/log/<sensor>
endpoints,
where <sensor>
is replaced by an arbitrary
name for the sensor.
The request Body has to be JSON encoded
and contain a “value” key with a float value
({ "value" : 10.0 }
).
Such a request can be created like this, using HTTPie:
http POST https://nota-cloud/api/log/nota_2 value:=-2.0
The other important endpoint is /api/stream
,
which sends a history of the most recent sensor
values and newly ariving ones as
server sent events.
You can watch this stream using the command below:
curl https://nota-cloud/api/stream
Web App
The web app subscribes to the /api/stream
using EventSource
and plots a new point
on a line diagram whenever an event is received
using Chart.js.
Recording Screencasts
The process of recording screencasts can not be performed on a Raspberry Pi and must instead be performed on a powerful computer as the video encoding slows the Pi to much for fluent screencasts.
Getting a fresh browser instance
For screencasts you want a browser session that is fresh as-installed.
The command below sets the language to be english and uses a newly generated browser profile.
$ LANG= firefox --new-instance --profile $(mktemp -d)
Cathing the window
The command below starts recording the screen with the correct size for screencasts and shows it in a new window.
Adjust the window you want to film to fit.
Adjust the +2,28
to catch another part of the screen.
$ ffplay -video_size 750x480 -framerate 30 -f x11grab -i :0.0+2,28
Starting the recording
The command below will record the screen into the file
screencast.mp4
. Hit Ctrl+C when you are done.
$ ffmpeg -video_size 750x480 -framerate 30 -f x11grab -i :0.0+2,28 -an -vcodec libx264 -pix_fmt yuv420p -profile:v baseline -level 3 screencast.mp4
Extract still images
The command takes a screenshot 16.1 seconds into
screencast.mp4
and saves it as still_image.png
.
$ ffmpeg -ss 16.1 -i screencast.mp4 -vframes 1 still_image.png