Local testbed

Run a small IoT-LAB on one Linux machine, with your own nodes on a switch, between quick tests on a desk and tests on the testbed.

The local testbed is a small IoT-LAB on one Linux machine: the services of a main server and of one site run in Docker, your nodes are on a switch connected to a dedicated Ethernet interface (a USB adapter is enough). It has one user, you, and no web portal, SSH frontend or VPN: the CLI tools talk to the REST API on your machine, which reaches the nodes directly.

The same CLI tools, API and node images as the testbed: an experiment running on your desk runs on IoT-LAB. Use it to bring up a board that IoT-LAB doesn’t have, or to test without waiting for the nodes of a site.

The complete documentation is doc/LOCAL_TESTBED.md in the iot-lab-install repository. This page gives the overview.

What you need

  • a machine with Debian 12 or 13, or Ubuntu 24.04 or later, x86_64, with NetworkManager
  • Docker with the compose plugin, rsync, iptables, Ansible (ansible-core 2.15 or later)
  • an Ethernet interface for the nodes only, not connected to another network: the testbed runs a DHCP server on it. A USB adapter goes directly on the machine, not on a USB hub
  • an SSH key pair in ~/.ssh
  • nodes and a switch
Nodes Boot Power
Raspberry Pi 2, 3, 4 SD card written by a playbook own supply, or PoE
Raspberry Pi 5 network boot of its EEPROM own supply, or PoE
IoT-LAB A8 U-Boot of its NAND own supply, or PoE
NVIDIA Jetson Nano, Orin network boot of their firmware PoE

Two power modes: manual, nodes on their own supply with any switch, and poe, a managed PoE switch that power cycles the nodes.

A gateway node drives an open node, a board such as an nRF52840DK connected to it by USB. Open Linux nodes run your experiment themselves.

Setup

$ git clone https://github.com/iot-lab/iot-lab-install.git
$ cd iot-lab-install
$ ansible-galaxy collection install -r requirements.yml
$ cp conf/local/local.yml.example conf/local/local.yml
$ vi conf/local/local.yml        # interface of the nodes, nodes
$ ./iotlab-local preflight       # what to fix first
$ ./iotlab-local setup

./iotlab-local is the front end of the testbed: it checks your machine, your configuration and your sudo password, runs the playbooks and says what failed, why and what to do. setup is safe to run again after a change of conf/local/local.yml.

conf/local/local.yml lists your nodes:

nodes:
  - group: custom
    node_id: 1
    alias: nrf52840dk-1
    hwaddr: "dc:a6:32:fb:c1:ef"
    archi: nrf52840dk:multi
    gw_type: rpi4
    cn_type: "no"

Then write the SD card of a Raspberry Pi, and check the testbed and its nodes once they boot:

$ ./iotlab-local sdcard nrf52840dk-1 /dev/sdX
$ ./iotlab-local check

Daily commands

$ ./iotlab-local check [<node>]           # what doesn't work, and the fix
$ ./iotlab-local stop [--force]           # refused with experiments, unless --force
$ ./iotlab-local start
$ ./iotlab-local logs <service> [-f]
$ ./iotlab-local power <node> <action>    # on, off or cycle, with a PoE switch

All the output of a playbook is in ~/.local/share/iotlab-local/<playbook>.log.

To start from scratch, stop the testbed before deleting iotlab_dir and ~/.local/share/iotlab-local: containers still running would keep their old passwords.

Run an experiment

The setup creates your account and an environment file for the CLI tools. Your ~/.iotlabrc is left untouched:

$ source ~/.local/share/iotlab-local/env
$ iotlab-status --nodes
$ iotlab-experiment submit -n test -d 20 -l local,nrf52840dk,1,firmware.elf
$ nc nrf52840dk-1 20000         # serial port of the open node
$ ssh root@nrf52840dk-1         # the gateway