Running script on SSH frontend
Level: Difficult
Duration: 45 minutes
Prerequisites: Configure SSH Access / Submit an experiment with M3 nodes / Experiment CLI client / Nodes Serial Link Aggregation
Description: The goal of this tutorial is to show how to launch a script on the SSH frontend during an experiment. This feature gives you the opportunity to write a simple experiment controller and automate the setup of your scenario (eg. flashing firmwares or getting serial output for M3 nodes, SSH access and configuration for A8 nodes). You have two options, associate a script file at the experiment submission, thus it will be launched automatically at the beginning of the experiment, or launch it dynamically during the experiment. In both cases, this script will be executed in a screen session with your user id. In this tutorial, you will use this feature to store the serial output of the nodes into a file with the serial_aggregator tool.
- Connect to the Grenoble site SSH frontend
my_computer$ ssh <login>@grenoble.iot-lab.info
Note: if you did not already authenticate using iotlab-auth, do it now:
<login>@grenoble:~$ iotlab-auth -u <login>
- Create a file named aggregator_script with the following content:
<login>@grenoble:~$ cat aggregator_script #!/bin/bash # Redirect all nodes serial output to a file readonly OUTFILE="${HOME}/.iot-lab/${EXP_ID}/aggregator_log" echo "Launch serial_aggregator with exp_id==${EXP_ID}" >&2 serial_aggregator -i ${EXP_ID} 2> /dev/null 1> ${OUTFILE}
This bash script uses the serial_aggregator tool to redirect serial output of the experiment nodes in a log file.
Note1: When the script starts, the EXP_ID environment variable is set with the experiment id and can be accessed from your script.
Note2: The script can be written in any scripting language, like Python. - Submit an experiment with:
- five M3 nodes (eg. dynamically allocated by the scheduler)
- a firmware association with sensors-collecting.iotlab-m3 (eg. the firmware prints sensors values every second on the serial link)
- a site association with your aggregator_script
<login>@grenoble:~$ wget https://raw.githubusercontent.com/wiki/iot-lab/iot-lab/firmwares/sensors-collecting.iotlab-m3 -O sensors-collecting.iotlab-m3 <login>@grenoble:~$ iotlab-experiment submit -d 60 -l 5,archi=m3:at86rf231+site=grenoble,sensors-collecting.iotlab-m3 --site-association grenoble,script=aggregator_script
- Wait until the experiment is launched and verify the script execution on the SSH frontend in the screen session
<login>@grenoble:~$ iotlab-experiment wait Waiting that experiment <exp_id> gets in state Running "Running" <login>@grenoble:~$ screen -ls There is a screen on: 4699.<exp-id>-<login> (28/03/2017 15:17:06) (Detached) 1 Socket in /var/run/screen/S-<login>. <login>@grenoble:~$ screen -r Launch serial_aggregator with exp_id==<exp_id>
Use
Ctrl+a d
shortcut to detach from screen session after thescreen -r
command - Verify that the aggregator_log file exists and contains the serial output of the nodes
<login>@grenoble:~$ cat .iot-lab/last/aggregator_log 1490707035.275759;m3-14;gyros: 1776 -446 122 xyz m°/s 1490707035.280817;m3-13;gyros: -332 -280 -288 xyz m°/s 1490707035.342859;m3-13;light: 113.906860 lux 1490707035.343804;m3-13;press: 994.614990 mbar 1490707035.347815;m3-10;light: 427.490234 lux 1490707035.349177;m3-10;press: 994.469238 mbar 1490707035.395238;m3-14;light: 161.621094 lux 1490707035.396399;m3-14;press: 994.343994 mbar 1490707035.426228;m3-11;light: 628.448486 lux 1490707035.426339;m3-11;press: 994.469971 mbar
Note: .iot-lab/last is a symlink to your last experiment directory (.iot-lab/<exp_id>)
- You may also find a log file in your homedir with standard error redirection (eg. stderr)
<login>@grenoble:~$ cat .iot-lab/last/run_script.log Waiting that experiment <exp_id>/<login> gets in state Running "Running" Experiment '<exp_id>/<login>' is Running Running script: 'aggregator_script' Launch serial_aggregator with exp_id==<exp_id>
- You can visualize the status of your script execution and kill it manually
<login>@grenoble:~$ iotlab-experiment script --status { "0": { "grenoble.iot-lab.info": "Running"} } <login>@grenoble:~$ iotlab-experiment script --kill { "0": ["grenoble.iot-lab.info"] } <login>@grenoble:~$ iotlab-experiment script --status { "0": { "grenoble.iot-lab.info": "Idle"} }
- As you can set a running script at experiment submission, it’s possible to launch it dynamically at any moment during your experiment (eg. state=Running). If there is a script execution in progress it will stop it and execute the new one.
<login>@grenoble:~$ iotlab-experiment script --run grenoble,script=aggregator_script { "0": ["grenoble.iot-lab.info"] }
- You can also pass a script config file attached to your script file. In this example, we pass a user password via the aggregator_script_config file and execute
iotlab-auth
command with it in the aggregator_script file.<login>@grenoble:~$ cat aggregator_script_config PASSWORD=<password>
<login>@grenoble:~$ cat aggregator_script #!/bin/bash if [ "$#" -eq 1 ]; then echo "Script config path: $1" >&2 source $1 iotlab-auth -u ${USER} -p ${PASSWORD} || exit 1 fi # Redirect all nodes serial output to a file readonly OUTFILE="${HOME}/.iot-lab/${EXP_ID}/aggregator_log" echo "Launch serial_aggregator with exp_id: ${EXP_ID}" >&2 serial_aggregator -i ${EXP_ID} 2> /dev/null 1> ${OUTFILE}
<login>@grenoble:~$ iotlab-experiment script --run grenoble,script=aggregator_script,scriptconfig=aggregator_script_config { "0": [ "grenoble.iot-lab.info"] } <login>@grenoble:~$ cat .iot-lab/last/run_script.log ... Running script: 'aggregator_script' Using script config: 'aggregator_script_config' Script config path: /var/run/script_tools/script/<exp_id>-config ...
Advanced Features
When the experiment is stopping or you kill manually the script execution a SIGTERM signal is sent to the script. It is possible to catch it and do some post script actions.
- Edit the aggregator_script file to use the trap command and a catch_signal function.
#!/bin/bash trap 'catch_signal; exit' SIGTERM catch_signal() { echo "Catch SIGTERM signal" >&2 # cleanup actions here } if [ "$#" -eq 1 ] then echo "Source script config path: $1" >&2 source $1 iotlab-auth -u ${USER} -p ${PASSWORD} fi # Redirect all nodes serial output to a file readonly OUTFILE="${HOME}/.iot-lab/${EXP_ID}/aggregator_log" echo "Launch serial_aggregator with exp_id: ${EXP_ID}" >&2 serial_aggregator -i ${EXP_ID} 2> /dev/null 1> ${OUTFILE}
- Launch this script and see what’s happening when it is stopped
<login>@grenoble:~$ iotlab-experiment script --run grenoble,script=aggregator_script,scriptconfig=aggregator_script_config { "0": [ "grenoble.iot-lab.info"] } <login>@grenoble:~$ iotlab-experiment script --kill { "0": ["grenoble.iot-lab.info"] } <login>@grenoble:~$ cat .iot-lab/last/run_script.log ... Got kill signal, sending SIGTERM to script and waiting for return... Catch SIGTERM signal Script returned: 0 ...