Build and boot your own Linux image
Build a Linux image for the open Linux nodes on top of the IoT-LAB image, push it to Docker Hub and boot it on IoT-LAB A8-M3 nodes.
The open Linux nodes boot an OCI image as their root filesystem (see Linux). In this tutorial you build your own image, with the tools of your experiment already installed, and boot it on two IoT-LAB A8-M3 nodes of Grenoble.
You need, on your computer:
- Docker with buildx
and the emulation of the ARM platforms (Docker Desktop has both; on Linux:
docker run --privileged --rm tonistiigi/binfmt --install arm); - a Docker Hub account,
<you>below; - the CLI tools 3.4.0 or later, or the SSH frontend where they are installed.
Write the image
In an empty directory, a file to add to the image:
mkdir -p rootfs/usr/local/bin
cat > rootfs/usr/local/bin/hello-iotlab <<'EOF'
#!/bin/sh
echo "Hello from $(hostname), my own image"
EOF
chmod +x rootfs/usr/local/bin/hello-iotlab
and the Dockerfile, on top of the IoT-LAB base image of the A8-M3 nodes,
at the version of the sites. The base image has what a node needs in
IoT-LAB (SSH, /root/shared, the tools of the M3), you add the packages
of your experiment:
FROM fitiotlab/iot-lab-open-linux-base:1.0.4
RUN apt-get update \
&& apt-get install -y --no-install-recommends htop tcpdump \
&& rm -rf /var/lib/apt/lists/*
COPY rootfs/ /
Keep the FROM image: its org.iot-lab.linux-base.version label tells the
site that the image can boot on its nodes. Don’t touch /boot/iotlab.
Build and push
The A8-M3 nodes are 32 bits ARM boards (linux/arm/v7). Build for that
platform and push to Docker Hub in one command:
docker login
docker buildx create --name iotlab --use
docker buildx build --platform linux/arm/v7 -t docker.io/<you>/hello-iotlab:1 --push .
The repository must be public: the sites pull it without credentials. Check the label:
docker buildx imagetools inspect docker.io/<you>/hello-iotlab:1 \
--format '{{ range .Image }}{{ index .Config.Labels "org.iot-lab.linux-base.version" }} {{ end }}'
It prints 1.0.4, the version of the IoT-LAB image.
Boot it
Submit an experiment with two A8-M3 nodes booting your image:
iotlab-experiment submit -n hello-image -d 30 -l grenoble,a8,1-2,image=docker.io/<you>/hello-iotlab:1
iotlab-experiment wait
The site pulls the image at the start of the experiment: the start takes a bit longer than with the default image. Then, from the SSH frontend of Grenoble:
iotlab-ssh wait-for-boot
ssh root@node-a8-1 hello-iotlab
ssh root@node-a8-1 htop
Each node has its own copy of the root filesystem: what you change on
node-a8-1 is not on node-a8-2, and everything is removed at the end of
the experiment. Put what you want to keep in /root/shared, your
~/shared directory of the frontend.
When the image is not booted
If hello-iotlab is not found, the nodes booted the default IoT-LAB
image. The reason is in the files of the experiment, on the frontend:
cat ~/.iot-lab/<experiment id>/log/user-image.log
Common causes: a private repository, an image too large (4 GB to download,
8 GB unpacked), another platform than linux/arm/v7, or another FROM
image than the IoT-LAB base image of the node type.
Other node types
The same steps work for the other open Linux nodes, with their IoT-LAB image and platform:
| Nodes | FROM |
--platform |
|---|---|---|
| Raspberry Pi 4 | fitiotlab/iot-lab-open-linux-base:1.0.4 |
linux/arm/v7 |
| Raspberry Pi 5 | fitiotlab/iot-lab-open-linux-base:1.0.4 |
linux/arm64 |
| Jetson Nano | fitiotlab/iot-lab-open-linux-jetson-nano:1.0.4 |
linux/arm64 |
| Jetson Orin | fitiotlab/iot-lab-open-linux-jetson-orin:1.0.4 |
linux/arm64 |
The Jetson images are Ubuntu: use the Ubuntu package names. On the Raspberry Pi and Jetson nodes, Docker runs too: your experiment can also pull and run containers on the nodes.