Grid’5000 and FIT/IoT-LAB - IPv6#
Introduction#
This example shows how to interact with both platforms in a single experiment.
An IPv6 network is built in IoT-LAB platform, composed of a border sensor and CoAP servers. A node in Grid’5000 is the client, which uses a CoAP client to read the sensor using its global IPv6 address.
Inspired on: https://www.iot-lab.info/legacy/tutorials/contiki-coap-m3/index.html
[ ]:
from enoslib import *
import logging
import sys
Configuring logging: save DEBUG to a file and INFO to stdout
[ ]:
log = logging.getLogger()
log.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fileHandler = logging.FileHandler("debug.log", 'a')
fileHandler.setLevel(logging.DEBUG)
fileHandler.setFormatter(formatter)
log.addHandler(fileHandler)
cformat = logging.Formatter("[%(levelname)8s] : %(message)s")
consoleHandler = logging.StreamHandler(sys.stdout)
consoleHandler.setFormatter(cformat)
consoleHandler.setLevel(logging.INFO)
log.addHandler(consoleHandler)
Getting resources#
IoT-LAB provider configuration: reserve M3 nodes in saclay site#
Note: It uses the following M3 images: border-router.iotlab-m3 and er-example-server.iotlab-m3.
More details on how to generate these images in: https://www.iot-lab.info/legacy/tutorials/contiki-coap-m3/index.html
[ ]:
job_name="iotlab_g5k-ipv6"
iotlab_dict = {
"walltime": "01:00",
"job_name": job_name,
"resources": {
"machines": [
{
"roles": ["border_router"],
"archi": "m3:at86rf231",
"site": "saclay",
"number": 1,
"image": "border-router.iotlab-m3",
},
{
"roles": ["sensor"],
"archi": "m3:at86rf231",
"site": "saclay",
"number": 2,
"image": "er-example-server.iotlab-m3",
},
]
},
}
iotlab_conf = IotlabConf.from_dictionary(iotlab_dict)
Grid’5000 provider configuration: reserve nodes in grenoble#
[ ]:
g5k_dict = {
"job_type": [],
"job_name": job_name,
"resources": {
"machines": [
{
"roles": ["client"],
"cluster": "yeti",
"nodes": 1,
"primary_network": "default",
"secondary_networks": [],
},
],
"networks": [
{"id": "default", "type": "prod", "roles": ["my_network"], "site": "grenoble"}
],
},
}
g5k_conf = G5kConf.from_dictionnary(g5k_dict)
We still need a Static provider to interact with the IoT-LAB frontend machine#
[ ]:
import iotlabcli.auth
iotlab_user, _ = iotlabcli.auth.get_user_credentials()
iotlab_frontend_conf = (
StaticConf()
.add_machine(
roles=["frontend"],
address="saclay.iot-lab.info",
alias="saclay",
user=iotlab_user
)
.finalize()
)
IoT-LAB: getting resources#
[ ]:
iotlab_provider = Iotlab(iotlab_conf)
iotlab_roles, _ = iotlab_provider.init()
print(iotlab_roles)
Grid’5000: getting resources#
[ ]:
g5k_provider = G5k(g5k_conf)
g5k_roles, g5knetworks = g5k_provider.init()
print(g5k_roles)
Static: getting resources#
[ ]:
frontend_provider = Static(iotlab_frontend_conf)
frontend_roles, _ = frontend_provider.init()
print(frontend_roles)
Configuring network connectivity#
Enabling IPv6 on Grid’5000 nodes (https://www.grid5000.fr/w/IPv6)#
[ ]:
result=run_command("dhclient -6 br0", roles=g5k_roles)
[ ]:
result = run_command("ip address show dev br0", roles=g5k_roles)
print(result['ok'])
Starting tunslip command in frontend.#
Redirect tunslip command output to a file to read it later.
[ ]:
iotlab_ipv6_net="2001:660:3207:4c0::"
tun_cmd = "sudo tunslip6.py -v2 -L -a %s -p 20000 %s1/64 > tunslip.output 2>&1" % (iotlab_roles["border_router"][0].alias, iotlab_ipv6_net)
result=run_command(tun_cmd, roles=frontend_roles, asynch=3600, poll=0)
Reseting border router#
[ ]:
iotlab_roles["border_router"][0].reset()
Get the Border Router IPv6 address from tunslip output#
[ ]:
result = run_command("cat tunslip.output", roles=frontend_roles)
print(result['ok'])
[ ]:
import re
out = result['ok']['saclay']['stdout']
print(out)
match = re.search(rf'Server IPv6 addresses:\n.+({iotlab_ipv6_net}\w{{4}})', out, re.MULTILINE|re.DOTALL)
br_ipv6 = match.groups()[0]
print("Border Router IPv6 address from tunslip output: %s" % br_ipv6)
Checking ping from Grid’5000 to border router node#
[ ]:
result = run_command("ping6 -c3 %s" % br_ipv6, pattern_hosts="client*", roles=g5k_roles)
print(result['ok'])
Installing and using CoAP clients#
Install aiocoap client and lynx on grid’5000 nodes#
[ ]:
with play_on(roles=g5k_roles) as p:
p.apt(name=["python3-aiocoap", "lynx"], state="present")
Grab the CoAP server node’s IPv6 address from the BR’s web interface#
[ ]:
result = run_command("lynx -dump http://[%s]" % br_ipv6, roles=g5k_roles)
print(result['ok'])
For a CoAP server, GET light sensor#
[ ]:
out = result['ok'][g5k_roles["client"][0].address]['stdout']
print(out)
match = re.search(r'fe80::(\w{4})', out, re.MULTILINE|re.DOTALL)
node_uid = match.groups()[0]
print(node_uid)
[ ]:
result = run_command("aiocoap-client coap://[%s%s]:5683/sensors/light" % (iotlab_ipv6_net, node_uid), roles=g5k_roles)
print(result['ok'])
GET pressure for the same sensor#
[ ]:
result = run_command("aiocoap-client coap://[%s%s]:5683/sensors/pressure" % (iotlab_ipv6_net, node_uid), roles=g5k_roles)
print(result['ok'])
Clean-up phase#
Stop tunslip in frontend node#
[ ]:
result = run_command("pgrep tunslip6 | xargs kill", roles=frontend_roles)
Destroy jobs in testbeds#
[ ]:
g5k_provider.destroy()
iotlab_provider.destroy()