From 1d05aad5f404b4cda685d7be39d5af1b5fab0882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Tue, 26 Apr 2022 11:53:55 +0200 Subject: [PATCH 01/16] Added Ping tutorial for baleine --- code/E1-baleine_A3.py | 59 +++++++++++++++++++++++++++++ code/E1-baleine_A4.py | 71 +++++++++++++++++++++++++++++++++++ code/E1-baleine_A5.py | 87 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 code/E1-baleine_A3.py create mode 100644 code/E1-baleine_A4.py create mode 100644 code/E1-baleine_A5.py diff --git a/code/E1-baleine_A3.py b/code/E1-baleine_A3.py new file mode 100644 index 00000000..4e4bcac9 --- /dev/null +++ b/code/E1-baleine_A3.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser + +from asynciojobs import Scheduler + +from apssh import SshNode, SshJob +from apssh import Run + +########## +gateway_hostname = 'faraday.inria.fr' +gateway_username = 'inria_r2lab.tutorial' +verbose_ssh = False + +# this time we want to be able to specify username and verbose_ssh +parser = ArgumentParser() +parser.add_argument("-s", "--slice", default=gateway_username, + help="specify an alternate slicename, default={}" + .format(gateway_username)) +parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', + help="run ssh in verbose mode") +args = parser.parse_args() + +gateway_username = args.slice +verbose_ssh = args.verbose_ssh + +########## +faraday = SshNode(hostname = gateway_hostname, username = gateway_username, + verbose = verbose_ssh) + +# saying gateway = faraday means to tunnel ssh through the gateway +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", + verbose = verbose_ssh) +########## +# create an orchestration scheduler +scheduler = Scheduler() + +########## +# the command we want to run in node1 is as simple as it gets +ping = SshJob( + node = faraday, + command = Run('baleine', 'deploy', '--nodes', node1.hostname, '--image', 'ghcr.io/haysberg/baleine:main', '--command', 'ping -c1 google.fr'), + scheduler = scheduler) + +########## +# how to run the same directly with ssh - for troubleshooting +print("""--- for troubleshooting: +ssh -i /dev/null {}@{} ssh root@fit01 ping -c1 google.fr +---""".format(gateway_username, gateway_hostname)) + +########## +# run the scheduler +ok = scheduler.orchestrate() + +# give details if it failed +ok or scheduler.debrief() + +# return something useful to your OS +exit(0 if ok else 1) diff --git a/code/E1-baleine_A4.py b/code/E1-baleine_A4.py new file mode 100644 index 00000000..9bf0f6d4 --- /dev/null +++ b/code/E1-baleine_A4.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser + +from asynciojobs import Scheduler + +from apssh import SshNode, SshJob +from apssh import Run + +########## +gateway_hostname = 'faraday.inria.fr' +gateway_username = 'root' +verbose_ssh = False + +# this time we want to be able to specify username and verbose_ssh +parser = ArgumentParser() +parser.add_argument("-s", "--slice", default=gateway_username, + help="specify an alternate slicename, default={}" + .format(gateway_username)) +parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', + help="run ssh in verbose mode") +args = parser.parse_args() + +gateway_username = args.slice +verbose_ssh = args.verbose_ssh + +########## +faraday = SshNode(hostname = gateway_hostname, username = gateway_username, + verbose = verbose_ssh) + +# saying gateway = faraday means to tunnel ssh through the gateway +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", + verbose = verbose_ssh) +########## +# create an orchestration scheduler +scheduler = Scheduler() + +########## +check_lease = SshJob( + # checking the lease is done on the gateway + node = faraday, + # this means that a failure in any of the commands + # will cause the scheduler to bail out immediately + critical = True, + command = Run("rhubarbe leases --check"), + scheduler = scheduler, +) + +# the command we want to run in node1 is as simple as it gets +ping = SshJob( + node = faraday, + # this says that we wait for check_lease to finish before we start ping + required = check_lease, + command = Run('baleine', 'deploy', '--nodes', node1.hostname, '--image', 'ghcr.io/haysberg/baleine:main', '--command', 'ping -c1 google.fr'), + scheduler = scheduler) + +########## +# how to run the same directly with ssh - for troubleshooting +print("""--- for troubleshooting: +ssh -i /dev/null {}@{} ssh root@fit01 ping -c1 google.fr +---""".format(gateway_username, gateway_hostname)) + +########## +# run the scheduler +ok = scheduler.orchestrate() + +# give details if it failed +ok or scheduler.debrief() + +# return something useful to your OS +exit(0 if ok else 1) diff --git a/code/E1-baleine_A5.py b/code/E1-baleine_A5.py new file mode 100644 index 00000000..8f03a735 --- /dev/null +++ b/code/E1-baleine_A5.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser + +from asynciojobs import Scheduler + +from apssh import SshNode, SshJob +from apssh import Run + +########## +gateway_hostname = 'faraday.inria.fr' +gateway_username = 'root' +verbose_ssh = False + +# this time we want to be able to specify username and verbose_ssh +parser = ArgumentParser() +parser.add_argument("-s", "--slice", default=gateway_username, + help="specify an alternate slicename, default={}" + .format(gateway_username)) +parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', + help="run ssh in verbose mode") +args = parser.parse_args() + +gateway_username = args.slice +verbose_ssh = args.verbose_ssh + +########## +faraday = SshNode(hostname = gateway_hostname, username = gateway_username, + verbose = verbose_ssh) + +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", + verbose = verbose_ssh) +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", + verbose = verbose_ssh) +########## +# create an orchestration scheduler +scheduler = Scheduler() + +########## +check_lease = SshJob( + # checking the lease is done on the gateway + node = faraday, + # this means that a failure in any of the commands + # will cause the scheduler to bail out immediately + critical = True, + command = Run("rhubarbe leases --check"), + scheduler = scheduler, +) + +########## +# setting up the data interface on both fit01 and fit02 +init_node_01 = SshJob( + node = node1, + command = Run("turn-on-data"), + required = check_lease, + scheduler = scheduler, +) +init_node_02 = SshJob( + node = node2, + command = Run("turn-on-data"), + required = check_lease, + scheduler = scheduler, +) + +# the command we want to run in node1 is as simple as it gets +ping = SshJob( + node = faraday, + # this says that we wait for check_lease to finish before we start ping + required = (init_node_01, init_node_02), + command = Run('baleine', 'deploy', '--nodes', node1.hostname, '--image', 'ghcr.io/haysberg/baleine:main', '--command', 'ping -c1 -I data data02'), + scheduler = scheduler) + +########## +# how to run the same directly with ssh - for troubleshooting +print("""--- for troubleshooting: +ssh -i /dev/null {}@{} ssh root@fit01 ping -c1 google.fr +---""".format(gateway_username, gateway_hostname)) + +########## +# run the scheduler +ok = scheduler.orchestrate() + +# give details if it failed +ok or scheduler.debrief() + +# return something useful to your OS +exit(0 if ok else 1) From 65afcf182d7b4f3b0eff96bc0a9594c5020c11d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Fri, 29 Apr 2022 11:19:10 +0200 Subject: [PATCH 02/16] Added B tutorials. Started working on C tutorials. --- code/{E1-baleine_A3.py => A3-ping-docker.py} | 0 code/{E1-baleine_A4.py => A4-ping-docker.py} | 0 code/{E1-baleine_A5.py => A5-ping-docker.py} | 0 code/B1-wireless-docker.py | 156 ++++++++++++++++++ code/B2-wireless-docker.py | 162 +++++++++++++++++++ code/B3-wireless-docker.py | 113 +++++++++++++ code/B3-wireless-docker.sh | 94 +++++++++++ code/C1-files.py | 2 +- code/C2-files.py | 2 +- code/C3-files.py | 2 +- 10 files changed, 528 insertions(+), 3 deletions(-) rename code/{E1-baleine_A3.py => A3-ping-docker.py} (100%) rename code/{E1-baleine_A4.py => A4-ping-docker.py} (100%) rename code/{E1-baleine_A5.py => A5-ping-docker.py} (100%) create mode 100755 code/B1-wireless-docker.py create mode 100755 code/B2-wireless-docker.py create mode 100755 code/B3-wireless-docker.py create mode 100644 code/B3-wireless-docker.sh diff --git a/code/E1-baleine_A3.py b/code/A3-ping-docker.py similarity index 100% rename from code/E1-baleine_A3.py rename to code/A3-ping-docker.py diff --git a/code/E1-baleine_A4.py b/code/A4-ping-docker.py similarity index 100% rename from code/E1-baleine_A4.py rename to code/A4-ping-docker.py diff --git a/code/E1-baleine_A5.py b/code/A5-ping-docker.py similarity index 100% rename from code/E1-baleine_A5.py rename to code/A5-ping-docker.py diff --git a/code/B1-wireless-docker.py b/code/B1-wireless-docker.py new file mode 100755 index 00000000..8871b3a1 --- /dev/null +++ b/code/B1-wireless-docker.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser + +from asynciojobs import Scheduler + +from apssh import SshNode, SshJob +from apssh import Run, RunString + +########## +gateway_hostname = 'faraday.inria.fr' +gateway_username = 'inria_r2lab.tutorial' +verbose_ssh = False +wireless_driver="ath9k" +wireless_interface="atheros" + +parser = ArgumentParser() +parser.add_argument("-s", "--slice", default=gateway_username, + help="specify an alternate slicename, default={}" + .format(gateway_username)) +parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', + help="run ssh in verbose mode") +args = parser.parse_args() + +gateway_username = args.slice +verbose_ssh = args.verbose_ssh + +########## +faraday = SshNode(hostname = gateway_hostname, username = gateway_username, + verbose = verbose_ssh) + +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", + verbose = verbose_ssh) +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "container", + verbose = verbose_ssh) + +########## +# create an orchestration scheduler +scheduler = Scheduler() + +########## +check_lease = SshJob( + # checking the lease is done on the gateway + node = faraday, + # this means that a failure in any of the commands + # will cause the scheduler to bail out immediately + critical = True, + command = Run("rhubarbe leases --check"), + scheduler = scheduler, +) + +#################### +# This is our own brewed script for setting up a wifi network +# it run on the remote machine - either sender or receiver +# and is in charge of initializing a small ad-hoc network +# +# Thanks to the RunString class, we can just define this as +# a python string, and pass it arguments from python variables +# + +turn_on_wireless_script = """#!/bin/bash + +# we expect the following arguments +# * wireless driver name (iwlwifi or ath9k) +# * wireless interface name (intel or atheros) +# * IP-address/mask for that interface +# * the wifi network name to join +# * the wifi frequency to use + +driver=$1; shift +ifname=$1; shift +ipaddr_mask=$1; shift +netname=$1; shift +freq=$1; shift + +# load the r2lab utilities - code can be found here: +# https://github.com/fit-r2lab/r2lab-embedded/blob/master/shell/nodes.sh +source /etc/profile.d/nodes.sh + +# make sure to use the latest code on the node +git-pull-r2lab + +turn-off-wireless + +echo loading module $driver +modprobe $driver + +# some time for udev to trigger its rules +sleep 1 + +echo configuring interface $ifname +# make sure to wipe down everything first so we can run again and again +ip address flush dev $ifname +ip link set $ifname down +# configure wireless +iw dev $ifname set type ibss +ip link set $ifname up +# set to ad-hoc mode +iw dev $ifname ibss join $netname $freq +ip address add $ipaddr_mask dev $ifname +""" + +########## +# setting up the wireless interface on both fit01 and fit02 + +# IMPORTANT NOTE : We could have run the scripts inside the Docker containers +# We would obtain the same results as the containers have full power over the host. +# However we don't here for the sake of staying close to the "non-Docker" tutorial. +init_node_01 = SshJob( + node = node1, + command = RunString( + # first argument is a string containing + # the script to be run remotely + turn_on_wireless_script, + # and now its arguments + wireless_driver, wireless_interface, "10.0.0.1/24", "foobar", 2412, +# verbose=True, + ), + required = check_lease, + scheduler = scheduler, +) +init_node_02 = SshJob( + node = node2, + command = RunString( + turn_on_wireless_script, + wireless_driver, wireless_interface, "10.0.0.2/24", "foobar", 2412, + ), + required = check_lease, + scheduler = scheduler, +) + +# the command we want to run in node1 is as simple as it gets +ping = SshJob( + node = faraday, + required = (init_node_01, init_node_02), + command = Run( + 'baleine', 'deploy', '--nodes', node1.hostname, '--image', 'ghcr.io/haysberg/baleine:main', '--command', 'ping -c20 10.0.0.2 -I', wireless_interface +# verbose=True, + ), + scheduler = scheduler, +) + +########## +# run the scheduler +ok = scheduler.orchestrate() + +# give details if it failed +ok or scheduler.debrief() + +success = ok and ping.result() == 0 + +# producing a dot file for illustration +scheduler.export_as_dotfile("B1.dot") + +# return something useful to your OS +exit(0 if success else 1) diff --git a/code/B2-wireless-docker.py b/code/B2-wireless-docker.py new file mode 100755 index 00000000..9c659525 --- /dev/null +++ b/code/B2-wireless-docker.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser + +from asynciojobs import Scheduler + +from apssh import SshNode, SshJob +from apssh import Run, RunString +from apssh import TimeColonFormatter + +########## +gateway_hostname = 'faraday.inria.fr' +gateway_username = 'inria_r2lab.tutorial' +verbose_ssh = False + +parser = ArgumentParser() +parser.add_argument("-s", "--slice", default=gateway_username, + help="specify an alternate slicename, default={}" + .format(gateway_username)) +parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', + help="run ssh in verbose mode") +parser.add_argument("-d", "--driver", default='ath9k', + choices = ['iwlwifi', 'ath9k'], + help="specify which driver to use") +args = parser.parse_args() + +gateway_username = args.slice +verbose_ssh = args.verbose_ssh +wireless_driver = args.driver + +########## +faraday = SshNode(hostname = gateway_hostname, username = gateway_username, + verbose = verbose_ssh, + formatter = TimeColonFormatter()) + +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", + verbose = verbose_ssh, + formatter = TimeColonFormatter()) +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", + verbose = verbose_ssh, + formatter = TimeColonFormatter()) + +########## +# create an orchestration scheduler +scheduler = Scheduler() + +########## +check_lease = SshJob( + # checking the lease is done on the gateway + node = faraday, + # this means that a failure in any of the commands + # will cause the scheduler to bail out immediately + critical = True, + command = Run("rhubarbe leases --check"), + scheduler = scheduler, +) + +#################### +# This is our own brewed script for setting up a wifi network +# it run on the remote machine - either sender or receiver +# and is in charge of initializing a small ad-hoc network +# +# Thanks to the RunString class, we can just define this as +# a python string, and pass it arguments from python variables +# + +turn_on_wireless_script = """#!/bin/bash + +# we expect the following arguments +# * wireless driver name (iwlwifi or ath9k) +# * the wifi network name to join +# * the wifi frequency to use + +driver=$1; shift +netname=$1; shift +freq=$1; shift + +# load the r2lab utilities - code can be found here: +# https://github.com/fit-r2lab/r2lab-embedded/blob/master/shell/nodes.sh +source /etc/profile.d/nodes.sh + +# make sure to use the latest code on the node +git-pull-r2lab + +turn-off-wireless + +# local IP address to use is computed on the 10.0.0.0/24 +# subnet and based on current node number (using r2lab-ip) +ipaddr_mask=10.0.0.$(r2lab-ip)/24 + +echo loading module $driver +modprobe $driver + +# some time for udev to trigger its rules +sleep 1 + +# use r2lab tools to figure out the interface name +ifname=$(wait-for-interface-on-driver $driver) + +echo configuring interface $ifname +# make sure to wipe down everything first so we can run again and again +ip address flush dev $ifname +ip link set $ifname down +# configure wireless +iw dev $ifname set type ibss +ip link set $ifname up +# set to ad-hoc mode +iw dev $ifname ibss join $netname $freq +ip address add $ipaddr_mask dev $ifname +""" + +########## +# setting up the wireless interface on both fit01 and fit02 +init_node_01 = SshJob( + node = node1, + command = RunString( + turn_on_wireless_script, + wireless_driver, "foobar", 2412, + # setting a remote_name allows to + # improve the graphical rendering + remote_name = 'turn-on-wireless' +# verbose=True, + ), + required = check_lease, + scheduler = scheduler, +) +init_node_02 = SshJob( + node = node2, + command = RunString( + turn_on_wireless_script, + wireless_driver, "foobar", 2412, + remote_name = 'turn-on-wireless' + ), + required = check_lease, + scheduler = scheduler, +) + +# the command we want to run in node1 is as simple as it gets +ping = SshJob( + node = faraday, + required = (init_node_01, init_node_02), + command = Run( + 'baleine', 'deploy', '--nodes', node1.hostname, '--image', 'ghcr.io/haysberg/baleine:main', '--command', 'ping -c20 10.0.0.2', +# verbose=True, + ), + scheduler = scheduler, +) + +########## +# run the scheduler +ok = scheduler.orchestrate() + +# give details if it failed +ok or scheduler.debrief() + +success = ok and ping.result() == 0 + +# producing a dot file for illustration +scheduler.export_as_dotfile("B2.dot") + +# return something useful to your OS +exit(0 if success else 1) diff --git a/code/B3-wireless-docker.py b/code/B3-wireless-docker.py new file mode 100755 index 00000000..041d6452 --- /dev/null +++ b/code/B3-wireless-docker.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser + +from asynciojobs import Scheduler + +from apssh import SshNode, SshJob +from apssh import Run, RunString, RunScript +from apssh import TimeColonFormatter + +########## +gateway_hostname = 'faraday.inria.fr' +gateway_username = 'root' +verbose_ssh = False + +parser = ArgumentParser() +parser.add_argument("-s", "--slice", default=gateway_username, + help="specify an alternate slicename, default={}" + .format(gateway_username)) +parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', + help="run ssh in verbose mode") +parser.add_argument("-d", "--driver", default='ath9k', + choices = ['iwlwifi', 'ath9k'], + help="specify which driver to use") +args = parser.parse_args() + +gateway_username = args.slice +verbose_ssh = args.verbose_ssh +wireless_driver = args.driver + +########## +faraday = SshNode(hostname = gateway_hostname, username = gateway_username, + verbose = verbose_ssh, + formatter = TimeColonFormatter()) + +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", + verbose = verbose_ssh, + formatter = TimeColonFormatter()) +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", + verbose = verbose_ssh, + formatter = TimeColonFormatter()) + +########## +# create an orchestration scheduler +scheduler = Scheduler() + +########## +check_lease = SshJob( + # checking the lease is done on the gateway + node = faraday, + # this means that a failure in any of the commands + # will cause the scheduler to bail out immediately + critical = True, + command = Run("rhubarbe leases --check"), + scheduler = scheduler, +) + +# the shell script has gone into B3-wireless.sh +#################### + +########## +# setting up the wireless interface on both fit01 and fit02 +init_node_01 = SshJob( + node = node1, + # RunString is replaced with RunScript + command = RunScript( + # first argument is the local filename + # where to find the script to run remotely + "B3-wireless.sh", + # then its arguments + "init-ad-hoc-network", wireless_driver, "foobar", 2412, + # no need to set remote_name with RunScript + ), + required = check_lease, + scheduler = scheduler, +) +init_node_02 = SshJob( + node = node2, + command = RunScript( + "B3-wireless.sh", + "init-ad-hoc-network", wireless_driver, "foobar", 2412, + # setting a label to gain space in the graphical output + label="ditto", + ), + required = check_lease, + scheduler = scheduler, +) + +# the command we want to run in node1 is as simple as it gets +ping = SshJob( + node = node1, + required = (init_node_01, init_node_02), + command = RunScript( + "B3-wireless.sh", "my-ping", '10.0.0.2', 20, +# verbose=True, + ), + scheduler = scheduler, +) + +########## +# run the scheduler +ok = scheduler.orchestrate() + +# give details if it failed +ok or scheduler.debrief() + +success = ok and ping.result() == 0 + +# producing a dot file for illustration +scheduler.export_as_dotfile("B3.dot") + +# return something useful to your OS +exit(0 if success else 1) diff --git a/code/B3-wireless-docker.sh b/code/B3-wireless-docker.sh new file mode 100644 index 00000000..84e678dd --- /dev/null +++ b/code/B3-wireless-docker.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +#################### +# This is our own brewed script for setting up a wifi network +# it run on the remote machine - either sender or receiver +# and is in charge of initializing a small ad-hoc network +# +# Thanks to the RunString class, we can just define this as +# a python string, and pass it arguments from python variables +# + + +# we expect the following arguments +# * wireless driver name (iwlwifi or ath9k) +# * the wifi network name to join +# * the wifi frequency to use + +function init-ad-hoc-network (){ + driver=$1; shift + netname=$1; shift + freq=$1; shift + + # load the r2lab utilities - code can be found here: + # https://github.com/fit-r2lab/r2lab-embedded/blob/master/shell/nodes.sh + source /etc/profile.d/nodes.sh + + # make sure to use the latest code on the node + git-pull-r2lab + + turn-off-wireless + + ipaddr_mask=10.0.0.$(r2lab-ip)/24 + + echo loading module $driver + modprobe $driver + + # some time for udev to trigger its rules + sleep 1 + + ifname=$(wait-for-interface-on-driver $driver) + + echo configuring interface $ifname + # make sure to wipe down everything first so we can run again and again + ip address flush dev $ifname + ip link set $ifname down + # configure wireless + iw dev $ifname set type ibss + ip link set $ifname up + # set to ad-hoc mode + iw dev $ifname ibss join $netname $freq + ip address add $ipaddr_mask dev $ifname + + ### addition - would be cool to come up with something along these lines that + # works on both cards + # a recipe from Naoufal for Intel + # modprobe iwlwifi + # iwconfig wlan2 mode ad-hoc + # ip addr add 10.0.0.41/16 dev wlan2 + # ip link set wlan2 up + # iwconfig wlan2 essid mesh channel 1 + +} + +function my-ping (){ + dest=$1; shift + maxwait=$1; shift + + start=$(date +%s) + + while true; do + # allow for one second timeout only; try one packet + if ping -w 1 -c 1 $dest >& /dev/null; then + end=$(date +%s) + duration=$(($end - $start)) + echo "$(hostname) -> $dest: SUCCESS after ${duration}s" + return 0 + else + echo "$dest not reachable" + end=$(date +%s) + duration=$(($end - $start)) + if [ "$duration" -ge "$maxwait" ]; then + echo "$(hostname) -> $dest: FAILURE after ${duration}s" + return 1 + fi + fi + done +} + +######################################## +# just a wrapper so we can call the individual functions. so e.g. +# B3-wireless.sh tracable-ping 10.0.0.2 20 +# results in calling tracable-ping 10.0.0.2 20 + +"$@" diff --git a/code/C1-files.py b/code/C1-files.py index c9d00738..a214c989 100755 --- a/code/C1-files.py +++ b/code/C1-files.py @@ -14,7 +14,7 @@ ########## gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' +gateway_username = 'root' verbose_ssh = False random_size = 2**10 diff --git a/code/C2-files.py b/code/C2-files.py index d82dadbc..b110f507 100755 --- a/code/C2-files.py +++ b/code/C2-files.py @@ -14,7 +14,7 @@ ########## gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' +gateway_username = 'root' verbose_ssh = False random_size = 2**10 netcat_port = 10000 diff --git a/code/C3-files.py b/code/C3-files.py index 2e8a3f8e..526682b2 100755 --- a/code/C3-files.py +++ b/code/C3-files.py @@ -14,7 +14,7 @@ ########## gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' +gateway_username = 'root' verbose_ssh = False random_size = 2**10 netcat_port = 10000 From 0cbbe7610a6e9a7a5f065653f75ce09b5b053b6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Fri, 29 Apr 2022 11:19:17 +0200 Subject: [PATCH 03/16] Updated gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5196e56f..a979c415 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ venv/ assets/unwrap/ *.dot manifold/ +RANDOM \ No newline at end of file From 3d63ded7e599ede89e6a2258f69e25789bd849e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Tue, 3 May 2022 11:24:09 +0200 Subject: [PATCH 04/16] Added 127.0.0.1 to ALLOWED_HOSTS --- r2lab/settings.py | 1 + 1 file changed, 1 insertion(+) diff --git a/r2lab/settings.py b/r2lab/settings.py index 4b3ac516..c51fde0b 100644 --- a/r2lab/settings.py +++ b/r2lab/settings.py @@ -68,6 +68,7 @@ ALLOWED_HOSTS = [ 'r2lab.inria.fr', 'localhost', + '127.0.0.1' ] # Application definition From 103ea9367e6dfd3941b4f1c794f749058556eb62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Tue, 3 May 2022 11:29:40 +0200 Subject: [PATCH 05/16] Updated .gitignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a979c415..f42ff8db 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ venv/ assets/unwrap/ *.dot manifold/ -RANDOM \ No newline at end of file +RANDOM +db.sqlite3 +django.log \ No newline at end of file From 89c5a24259f1687109d2dd8bffbe7f5d89cbafdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Fri, 13 May 2022 08:43:42 +0200 Subject: [PATCH 06/16] Updated shell tools --- markdown/tuto-020-shell-tools.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/markdown/tuto-020-shell-tools.md b/markdown/tuto-020-shell-tools.md index 9300b110..1152a556 100644 --- a/markdown/tuto-020-shell-tools.md +++ b/markdown/tuto-020-shell-tools.md @@ -228,6 +228,13 @@ This command, like all the `rhubarbe`-related commands, has a default timeout, t rwait --timeout 30 +### Using Docker containers with baleine + +Baleine is a CLI tool allowing you to deploy Docker images to nodes running on the R2Lab testbed. +The default disk image to use with all the Docker configuration already done is the `baleine` image. + +If you want exhaustive information about the different options available in the `baleine` CLI, please check out the [official docs](https://github.com/haysberg/baleine/wiki) on GitHub. + ### `ssh`-ing into nodes @@ -245,6 +252,10 @@ You can run a command on all selected nodes with this time of course, you cannot specify another set of nodes than the selection. +If you want to directly access a Bash prompt **inside a Docker container** please choose the username `container`, like this : + + ssh container@fit25 + ### Saving images You have the ablility to save the image - this now of course applies only to **one node** at a time. To save node 25 @@ -255,6 +266,12 @@ This ends up in the common repository `/var/lib/rhubarbe-images`, under a name t Images that may be of common interest usually needto be renamed; get in touch with the admins if you need to do this. +### Saving Docker images + +If you want to save a Docker container that you may have modified from its base image, you can use the [baleine save](https://github.com/haysberg/baleine/wiki/Save-a-custom-container) command. + + baleine save --node 1 --name mycustomimage:1.0 + From 29c0413a5624916f4bed249e8ab8ac53f1359222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Fri, 13 May 2022 08:44:11 +0200 Subject: [PATCH 07/16] Corrected typo --- markdown/tuto-020-shell-tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/markdown/tuto-020-shell-tools.md b/markdown/tuto-020-shell-tools.md index 1152a556..4f69ce15 100644 --- a/markdown/tuto-020-shell-tools.md +++ b/markdown/tuto-020-shell-tools.md @@ -260,7 +260,7 @@ If you want to directly access a Bash prompt **inside a Docker container** pleas You have the ablility to save the image - this now of course applies only to **one node** at a time. To save node 25 - rsave 25 -o my-imge-name + rsave 25 -o my-image-name This ends up in the common repository `/var/lib/rhubarbe-images`, under a name that holds the hostname and saving time. You can also provide an extra name to `rsave` with the `-o` option. From 0ebe67d9b729cd5cb47f84fd5980f1aabb66b8ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Tue, 24 May 2022 08:25:20 +0200 Subject: [PATCH 08/16] Added A3 + A4 + A5 --- code/A3-ping-docker.py | 13 ++++--- code/A4-ping-docker.py | 23 ++++++------- code/A5-ping-docker.py | 35 +++++++++++-------- markdown/tuto-040-A-ping.md | 69 +++++++++++++++++++++++++------------ 4 files changed, 87 insertions(+), 53 deletions(-) diff --git a/code/A3-ping-docker.py b/code/A3-ping-docker.py index 4e4bcac9..99e3b7ba 100644 --- a/code/A3-ping-docker.py +++ b/code/A3-ping-docker.py @@ -29,7 +29,7 @@ verbose = verbose_ssh) # saying gateway = faraday means to tunnel ssh through the gateway -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", verbose = verbose_ssh) ########## # create an orchestration scheduler @@ -38,14 +38,17 @@ ########## # the command we want to run in node1 is as simple as it gets ping = SshJob( - node = faraday, - command = Run('baleine', 'deploy', '--nodes', node1.hostname, '--image', 'ghcr.io/haysberg/baleine:main', '--command', 'ping -c1 google.fr'), - scheduler = scheduler) + node = node1, + # let's be more specific about what to run + # we will soon see other things we can do on an ssh connection + command = Run('ping', '-c1', 'google.fr'), + scheduler = scheduler, +) ########## # how to run the same directly with ssh - for troubleshooting print("""--- for troubleshooting: -ssh -i /dev/null {}@{} ssh root@fit01 ping -c1 google.fr +ssh -i /dev/null {}@{} ssh container@fit01 ping -c1 google.fr ---""".format(gateway_username, gateway_hostname)) ########## diff --git a/code/A4-ping-docker.py b/code/A4-ping-docker.py index 9bf0f6d4..5701820f 100644 --- a/code/A4-ping-docker.py +++ b/code/A4-ping-docker.py @@ -9,10 +9,9 @@ ########## gateway_hostname = 'faraday.inria.fr' -gateway_username = 'root' +gateway_username = 'inria_r2lab.tutorial' verbose_ssh = False -# this time we want to be able to specify username and verbose_ssh parser = ArgumentParser() parser.add_argument("-s", "--slice", default=gateway_username, help="specify an alternate slicename, default={}" @@ -29,7 +28,7 @@ verbose = verbose_ssh) # saying gateway = faraday means to tunnel ssh through the gateway -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", verbose = verbose_ssh) ########## # create an orchestration scheduler @@ -48,17 +47,14 @@ # the command we want to run in node1 is as simple as it gets ping = SshJob( - node = faraday, + node = node1, # this says that we wait for check_lease to finish before we start ping required = check_lease, - command = Run('baleine', 'deploy', '--nodes', node1.hostname, '--image', 'ghcr.io/haysberg/baleine:main', '--command', 'ping -c1 google.fr'), - scheduler = scheduler) - -########## -# how to run the same directly with ssh - for troubleshooting -print("""--- for troubleshooting: -ssh -i /dev/null {}@{} ssh root@fit01 ping -c1 google.fr ----""".format(gateway_username, gateway_hostname)) + # let's be more specific about what to run + # we will soon see other things we can do on an ssh connection + command = Run('ping', '-c1', 'google.fr'), + scheduler = scheduler, +) ########## # run the scheduler @@ -67,5 +63,8 @@ # give details if it failed ok or scheduler.debrief() +# producing a dot file for illustration +scheduler.export_as_dotfile("A4.dot") + # return something useful to your OS exit(0 if ok else 1) diff --git a/code/A5-ping-docker.py b/code/A5-ping-docker.py index 8f03a735..b3e810df 100644 --- a/code/A5-ping-docker.py +++ b/code/A5-ping-docker.py @@ -12,7 +12,6 @@ gateway_username = 'root' verbose_ssh = False -# this time we want to be able to specify username and verbose_ssh parser = ArgumentParser() parser.add_argument("-s", "--slice", default=gateway_username, help="specify an alternate slicename, default={}" @@ -28,10 +27,11 @@ faraday = SshNode(hostname = gateway_hostname, username = gateway_username, verbose = verbose_ssh) -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", verbose = verbose_ssh) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "container", verbose = verbose_ssh) + ########## # create an orchestration scheduler scheduler = Scheduler() @@ -64,17 +64,15 @@ # the command we want to run in node1 is as simple as it gets ping = SshJob( - node = faraday, - # this says that we wait for check_lease to finish before we start ping + node = node1, + # wait for the 2 init jobs instead + # check_release is guaranteed to have completed anyway required = (init_node_01, init_node_02), - command = Run('baleine', 'deploy', '--nodes', node1.hostname, '--image', 'ghcr.io/haysberg/baleine:main', '--command', 'ping -c1 -I data data02'), - scheduler = scheduler) - -########## -# how to run the same directly with ssh - for troubleshooting -print("""--- for troubleshooting: -ssh -i /dev/null {}@{} ssh root@fit01 ping -c1 google.fr ----""".format(gateway_username, gateway_hostname)) + # let's be more specific about what to run + # we will soon see other things we can do on an ssh connection + command = Run('ping', '-c1', '-I', 'data', 'data02'), + scheduler = scheduler, +) ########## # run the scheduler @@ -83,5 +81,14 @@ # give details if it failed ok or scheduler.debrief() +# we say this is a success if the ping command succeeded +# the result() of the SshJob is the value that the command +# returns to the OS +# so it's a success if this value is 0 +success = ok and ping.result() == 0 + +# producing a dot file for illustration +scheduler.export_as_dotfile("A5.dot") + # return something useful to your OS -exit(0 if ok else 1) +exit(0 if success else 1) diff --git a/markdown/tuto-040-A-ping.md b/markdown/tuto-040-A-ping.md index 9c592353..8e110343 100644 --- a/markdown/tuto-040-A-ping.md +++ b/markdown/tuto-040-A-ping.md @@ -36,9 +36,10 @@ in each tutorial. Before we can run these experiments however, we need to have * a valid lease set in the booking system -* the 2 nodes `fit01` and `fit02` up and running +* the 2 nodes `fit01` and `fit02` up and running with the `baleine` disk image +* the `faraday.repo/tutorial` Docker image running on the fit nodes -For this first tutorial we will assume that these 2 steps have been +For this first tutorial we will assume that these 3 steps have been performed manually, and here is how to proceed with that. ### Getting a reservation @@ -60,7 +61,7 @@ The code in this tutorial assumes you have a slice named replace with your actual slice name when trying to run the code yourself. -### Loading images +### Loading disk images For loading the images manually on the 2 nodes needed here, please do this (as usual, make sure to use **your slice name** instead of @@ -86,7 +87,7 @@ explained [in the previous tutorial](tuto-020-shell-tools.md): # select nodes 1 and 2 n 1 2 # load the default image (on the selected nodes) - rload + rload baleine # wait for ssh to be up (still on the selected nodes) rwait @@ -119,27 +120,49 @@ should look like export NBNODES=2 your_slicename@faraday:~$ rload - 16:12:42 - +000s: Selection: fit01 fit02 - 16:12:42 - +000s: Loading image /var/lib/rhubarbe-images/default.ndz - 16:12:42 - +000s: AUTH: checking for a valid lease - 16:12:42 - +000s: AUTH: access granted - 16:12:42 - +000s: fit02 reboot = Sending message 'on' to CMC reboot02 - 16:12:42 - +000s: fit01 reboot = Sending message 'on' to CMC reboot01 - 16:12:43 - +001s: fit02 reboot = idling for 15s - 16:12:43 - +001s: fit01 reboot = idling for 15s - 16:12:59 - +017s: started - 16:12:59 - +017s: fit01 frisbee_status = trying to telnet.. - 16:12:59 - +017s: fit02 frisbee_status = trying to telnet.. - ... - |############################################################################################|100% |29.56s|Time: 0:00:29 - 16:13:44 - +062s: fit02 Uploading successful - 16:13:44 - +062s: fit02 reboot = Sending message 'reset' to CMC reboot02 - 16:13:46 - +064s: stopped + Found binary frisbeed as /usr/sbin/frisbeed + Found binary nc as /usr/bin/nc + 09:38:23 - +000s: Selection: fit01 fit02 + 09:38:23 - +000s: Loading image /var/lib/rhubarbe-images/baleine.ndz + 09:38:23 - +000s: AUTH: checking for a valid lease + 09:38:23 - +000s: AUTH: access granted + 09:38:23 - +000s: fit01 reboot = Sending message 'on' to CMC reboot01 + 09:38:23 - +000s: fit02 reboot = Sending message 'on' to CMC reboot02 + 09:38:24 - +001s: fit02 reboot = idling for 30s + 09:38:24 - +001s: fit01 reboot = idling for 30s + 09:38:55 - +032s: started + 09:38:55 - +032s: fit01 frisbee_status = trying to telnet.. + 09:38:55 - +032s: fit02 frisbee_status = trying to telnet.. + 09:38:56 - +032s: fit01 frisbee_status = backing off for 4.22s + 09:38:56 - +032s: fit02 frisbee_status = backing off for 3.07s + 09:38:59 - +035s: fit02 frisbee_status = trying to telnet.. + 09:38:59 - +036s: fit02 frisbee_status = backing off for 1.61s + 09:39:00 - +036s: fit01 frisbee_status = trying to telnet.. + 09:39:00 - +037s: fit01 frisbee_status = starting frisbee client + 09:39:01 - +037s: fit02 frisbee_status = trying to telnet.. | 0% |0.00s|ETA: --:--:-- + 09:39:01 - +038s: fit02 frisbee_status = starting frisbee client + 09:40:00 - +096s: fit02 reboot = Sending message 'reset' to CMC reboot02#### | 99% |59.46s|ETA: 0:00:00 + |############################################################################|100% |59.81s|Time: 0:00:59 + 09:40:00 - +097s: fit01 reboot = Sending message 'reset' to CMC reboot01 + 09:40:02 - +099s: stopped your_slicename@faraday:~$ rwait :ssh OK :ssh OK +### Loading the Tutorial Docker image + +To load Docker image on the fit nodes, we will now use the `baleine` command : + + baleine deploy --nodes 1 2 --image faraday.repo/tutorial --options -t -d + +Let's give a brief explanation of what we just wrote : +* The `deploy` subcommand allows us to pull an image from a Docker repository and create/launch a container on a fit node. +* The `--nodes` option allows us to mention what nodes we want to target. You can format the nodes just like with the `nodes` command you used before. +* The `--image` argument is the url to pull the image from. This can be from the Faraday repository, GitHub, DockerHub or any public repository. Please not that `faraday.repo` is reachable **ONLY** from the fit nodes. +* The `--options` argument allows to pass specific arguments directly to the Docker daemon running on the fit nodes. By default, if you give no command the `ubuntu` Docker image will stop instantly. To prevent that, we use the `-t -d` options. You can get more details about them [here](https://docs.docker.com/engine/reference/run/). + + At this point, both nodes have been loaded with the default image. So you can log out of `faraday.inria.fr` and go back to your laptop to run [the tutorial in tab A1](javascript:open_tab('A1')). @@ -257,11 +280,13 @@ This materializes the fact that we reach node `fit01` through the gateway. It also ensures that only one ssh connection gets established to the gateway, regardless of the number of nodes actually controlled. +Please note that we are using the `container` user in the script to directly connect to the Docker container shell. + **Double check:** Remember that for this to work, you need to have a currently valid slice (and to use it with the `--slice` option if needed), and you need `fit01` to be up and running. ### The code -<< codeview A3 A3-ping.py previous=A2-ping.py >> +<< codeview A3 A3-ping-docker.py previous=A2-ping.py >> ### Sample output @@ -349,7 +374,7 @@ for an example of that feature. ### The code -<< codeview A4 A4-ping.py previous=A3-ping.py graph=A4.png >> +<< codeview A4 A4-ping-docker.py previous=A3-ping-docker.py graph=A4.png >> ### Sample output From 31b104dd00932d9a6cef3863f8f3b886d18f108e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Mon, 13 Jun 2022 09:01:35 +0200 Subject: [PATCH 09/16] Added A3 and A5 --- code/A3-ping-docker.py | 1 + code/A5-ping-docker.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/A3-ping-docker.py b/code/A3-ping-docker.py index 99e3b7ba..59be1873 100644 --- a/code/A3-ping-docker.py +++ b/code/A3-ping-docker.py @@ -29,6 +29,7 @@ verbose = verbose_ssh) # saying gateway = faraday means to tunnel ssh through the gateway +# using the container username allows us to forward the command directly inside the container node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", verbose = verbose_ssh) ########## diff --git a/code/A5-ping-docker.py b/code/A5-ping-docker.py index b3e810df..8543a1da 100644 --- a/code/A5-ping-docker.py +++ b/code/A5-ping-docker.py @@ -27,9 +27,9 @@ faraday = SshNode(hostname = gateway_hostname, username = gateway_username, verbose = verbose_ssh) -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", +node1 = SshNode(gateway = faraday, hostname = "fit35", username = "container", verbose = verbose_ssh) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "container", +node2 = SshNode(gateway = faraday, hostname = "fit36", username = "container", verbose = verbose_ssh) ########## From 71b2e41e8babdf761f5c620656921b484cc53c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Mon, 13 Jun 2022 20:49:55 +0200 Subject: [PATCH 10/16] Added A5 --- code/A5-ping-docker.py | 23 ++++------------------- code/A5-ping.py | 19 ++----------------- code/B1-wireless-docker.py | 2 +- 3 files changed, 7 insertions(+), 37 deletions(-) diff --git a/code/A5-ping-docker.py b/code/A5-ping-docker.py index 8543a1da..94813116 100644 --- a/code/A5-ping-docker.py +++ b/code/A5-ping-docker.py @@ -27,9 +27,9 @@ faraday = SshNode(hostname = gateway_hostname, username = gateway_username, verbose = verbose_ssh) -node1 = SshNode(gateway = faraday, hostname = "fit35", username = "container", +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", verbose = verbose_ssh) -node2 = SshNode(gateway = faraday, hostname = "fit36", username = "container", +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "container", verbose = verbose_ssh) ########## @@ -47,30 +47,15 @@ scheduler = scheduler, ) -########## -# setting up the data interface on both fit01 and fit02 -init_node_01 = SshJob( - node = node1, - command = Run("turn-on-data"), - required = check_lease, - scheduler = scheduler, -) -init_node_02 = SshJob( - node = node2, - command = Run("turn-on-data"), - required = check_lease, - scheduler = scheduler, -) - # the command we want to run in node1 is as simple as it gets ping = SshJob( node = node1, # wait for the 2 init jobs instead # check_release is guaranteed to have completed anyway - required = (init_node_01, init_node_02), + required = (check_lease), # let's be more specific about what to run # we will soon see other things we can do on an ssh connection - command = Run('ping', '-c1', '-I', 'data', 'data02'), + command = Run('ping', '-c1', 'fit02'), scheduler = scheduler, ) diff --git a/code/A5-ping.py b/code/A5-ping.py index 5a6361a0..09db2e59 100755 --- a/code/A5-ping.py +++ b/code/A5-ping.py @@ -47,30 +47,15 @@ scheduler = scheduler, ) -########## -# setting up the data interface on both fit01 and fit02 -init_node_01 = SshJob( - node = node1, - command = Run("turn-on-data"), - required = check_lease, - scheduler = scheduler, -) -init_node_02 = SshJob( - node = node2, - command = Run("turn-on-data"), - required = check_lease, - scheduler = scheduler, -) - # the command we want to run in node1 is as simple as it gets ping = SshJob( node = node1, # wait for the 2 init jobs instead # check_release is guaranteed to have completed anyway - required = (init_node_01, init_node_02), + required = (check_lease), # let's be more specific about what to run # we will soon see other things we can do on an ssh connection - command = Run('ping', '-c1', '-I', 'data', 'data02'), + command = Run('ping', '-c1', 'fit02'), scheduler = scheduler, ) diff --git a/code/B1-wireless-docker.py b/code/B1-wireless-docker.py index 8871b3a1..e7716432 100755 --- a/code/B1-wireless-docker.py +++ b/code/B1-wireless-docker.py @@ -9,7 +9,7 @@ ########## gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' +gateway_username = 'root' verbose_ssh = False wireless_driver="ath9k" wireless_interface="atheros" From 94661b194f431a2d0124e0e4bc9e90f0f12cc4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Wed, 6 Jul 2022 14:48:02 +0200 Subject: [PATCH 11/16] Ported tutorials A through C2 to use SSH --- code/A3-ping-docker.py | 4 +- code/A4-ping-docker.py | 2 +- code/A5-ping-docker.py | 4 +- code/B1-wireless-docker.py | 10 +-- code/B2-wireless-docker.py | 8 +- code/B3-wireless-docker.py | 6 +- code/B3-wireless-docker.sh | 94 ----------------------- code/B4-wireless-docker.py | 126 ++++++++++++++++++++++++++++++ code/B5-wireless-docker.py | 131 +++++++++++++++++++++++++++++++ code/C1-files-docker.py | 92 ++++++++++++++++++++++ code/C1-files.py | 2 +- code/C2-files-docker.py | 153 +++++++++++++++++++++++++++++++++++++ 12 files changed, 520 insertions(+), 112 deletions(-) delete mode 100644 code/B3-wireless-docker.sh create mode 100755 code/B4-wireless-docker.py create mode 100755 code/B5-wireless-docker.py create mode 100755 code/C1-files-docker.py create mode 100755 code/C2-files-docker.py diff --git a/code/A3-ping-docker.py b/code/A3-ping-docker.py index 59be1873..2bb17b1d 100644 --- a/code/A3-ping-docker.py +++ b/code/A3-ping-docker.py @@ -30,7 +30,7 @@ # saying gateway = faraday means to tunnel ssh through the gateway # using the container username allows us to forward the command directly inside the container -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", port = 2222, verbose = verbose_ssh) ########## # create an orchestration scheduler @@ -49,7 +49,7 @@ ########## # how to run the same directly with ssh - for troubleshooting print("""--- for troubleshooting: -ssh -i /dev/null {}@{} ssh container@fit01 ping -c1 google.fr +ssh -i /dev/null {}@{} ssh container@fit01 -P 2222 ping -c1 google.fr ---""".format(gateway_username, gateway_hostname)) ########## diff --git a/code/A4-ping-docker.py b/code/A4-ping-docker.py index 5701820f..112cddbf 100644 --- a/code/A4-ping-docker.py +++ b/code/A4-ping-docker.py @@ -28,7 +28,7 @@ verbose = verbose_ssh) # saying gateway = faraday means to tunnel ssh through the gateway -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", port = 2222, verbose = verbose_ssh) ########## # create an orchestration scheduler diff --git a/code/A5-ping-docker.py b/code/A5-ping-docker.py index 94813116..fbb0f0c8 100644 --- a/code/A5-ping-docker.py +++ b/code/A5-ping-docker.py @@ -27,9 +27,9 @@ faraday = SshNode(hostname = gateway_hostname, username = gateway_username, verbose = verbose_ssh) -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", port = 2222, verbose = verbose_ssh) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "container", +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "container", port = 2222, verbose = verbose_ssh) ########## diff --git a/code/B1-wireless-docker.py b/code/B1-wireless-docker.py index e7716432..033a2c56 100755 --- a/code/B1-wireless-docker.py +++ b/code/B1-wireless-docker.py @@ -9,7 +9,7 @@ ########## gateway_hostname = 'faraday.inria.fr' -gateway_username = 'root' +gateway_username = 'inria_r2lab.tutorial' verbose_ssh = False wireless_driver="ath9k" wireless_interface="atheros" @@ -29,9 +29,9 @@ faraday = SshNode(hostname = gateway_hostname, username = gateway_username, verbose = verbose_ssh) -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, verbose = verbose_ssh) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "container", +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", port = 2222, verbose = verbose_ssh) ########## @@ -131,10 +131,10 @@ # the command we want to run in node1 is as simple as it gets ping = SshJob( - node = faraday, + node = node1, required = (init_node_01, init_node_02), command = Run( - 'baleine', 'deploy', '--nodes', node1.hostname, '--image', 'ghcr.io/haysberg/baleine:main', '--command', 'ping -c20 10.0.0.2 -I', wireless_interface + 'ping -c20 10.0.0.2 -I', wireless_interface # verbose=True, ), scheduler = scheduler, diff --git a/code/B2-wireless-docker.py b/code/B2-wireless-docker.py index 9c659525..f975c558 100755 --- a/code/B2-wireless-docker.py +++ b/code/B2-wireless-docker.py @@ -33,10 +33,10 @@ verbose = verbose_ssh, formatter = TimeColonFormatter()) -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, verbose = verbose_ssh, formatter = TimeColonFormatter()) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", port = 2222, verbose = verbose_ssh, formatter = TimeColonFormatter()) @@ -137,10 +137,10 @@ # the command we want to run in node1 is as simple as it gets ping = SshJob( - node = faraday, + node = node1, required = (init_node_01, init_node_02), command = Run( - 'baleine', 'deploy', '--nodes', node1.hostname, '--image', 'ghcr.io/haysberg/baleine:main', '--command', 'ping -c20 10.0.0.2', + 'ping', '-c', '20', '10.0.0.2', # verbose=True, ), scheduler = scheduler, diff --git a/code/B3-wireless-docker.py b/code/B3-wireless-docker.py index 041d6452..36e58bc4 100755 --- a/code/B3-wireless-docker.py +++ b/code/B3-wireless-docker.py @@ -10,7 +10,7 @@ ########## gateway_hostname = 'faraday.inria.fr' -gateway_username = 'root' +gateway_username = 'inria_r2lab.tutorial' verbose_ssh = False parser = ArgumentParser() @@ -33,10 +33,10 @@ verbose = verbose_ssh, formatter = TimeColonFormatter()) -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, verbose = verbose_ssh, formatter = TimeColonFormatter()) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", port = 2222, verbose = verbose_ssh, formatter = TimeColonFormatter()) diff --git a/code/B3-wireless-docker.sh b/code/B3-wireless-docker.sh deleted file mode 100644 index 84e678dd..00000000 --- a/code/B3-wireless-docker.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash - -#################### -# This is our own brewed script for setting up a wifi network -# it run on the remote machine - either sender or receiver -# and is in charge of initializing a small ad-hoc network -# -# Thanks to the RunString class, we can just define this as -# a python string, and pass it arguments from python variables -# - - -# we expect the following arguments -# * wireless driver name (iwlwifi or ath9k) -# * the wifi network name to join -# * the wifi frequency to use - -function init-ad-hoc-network (){ - driver=$1; shift - netname=$1; shift - freq=$1; shift - - # load the r2lab utilities - code can be found here: - # https://github.com/fit-r2lab/r2lab-embedded/blob/master/shell/nodes.sh - source /etc/profile.d/nodes.sh - - # make sure to use the latest code on the node - git-pull-r2lab - - turn-off-wireless - - ipaddr_mask=10.0.0.$(r2lab-ip)/24 - - echo loading module $driver - modprobe $driver - - # some time for udev to trigger its rules - sleep 1 - - ifname=$(wait-for-interface-on-driver $driver) - - echo configuring interface $ifname - # make sure to wipe down everything first so we can run again and again - ip address flush dev $ifname - ip link set $ifname down - # configure wireless - iw dev $ifname set type ibss - ip link set $ifname up - # set to ad-hoc mode - iw dev $ifname ibss join $netname $freq - ip address add $ipaddr_mask dev $ifname - - ### addition - would be cool to come up with something along these lines that - # works on both cards - # a recipe from Naoufal for Intel - # modprobe iwlwifi - # iwconfig wlan2 mode ad-hoc - # ip addr add 10.0.0.41/16 dev wlan2 - # ip link set wlan2 up - # iwconfig wlan2 essid mesh channel 1 - -} - -function my-ping (){ - dest=$1; shift - maxwait=$1; shift - - start=$(date +%s) - - while true; do - # allow for one second timeout only; try one packet - if ping -w 1 -c 1 $dest >& /dev/null; then - end=$(date +%s) - duration=$(($end - $start)) - echo "$(hostname) -> $dest: SUCCESS after ${duration}s" - return 0 - else - echo "$dest not reachable" - end=$(date +%s) - duration=$(($end - $start)) - if [ "$duration" -ge "$maxwait" ]; then - echo "$(hostname) -> $dest: FAILURE after ${duration}s" - return 1 - fi - fi - done -} - -######################################## -# just a wrapper so we can call the individual functions. so e.g. -# B3-wireless.sh tracable-ping 10.0.0.2 20 -# results in calling tracable-ping 10.0.0.2 20 - -"$@" diff --git a/code/B4-wireless-docker.py b/code/B4-wireless-docker.py new file mode 100755 index 00000000..d4260b60 --- /dev/null +++ b/code/B4-wireless-docker.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser + +from asynciojobs import Scheduler +from asynciojobs import Job + +from apssh import SshNode, SshJob +from apssh import Run, RunString, RunScript +from apssh import TimeColonFormatter + +########## +gateway_hostname = 'faraday.inria.fr' +gateway_username = 'inria_r2lab.tutorial' +verbose_ssh = False + +parser = ArgumentParser() +parser.add_argument("-s", "--slice", default=gateway_username, + help="specify an alternate slicename, default={}" + .format(gateway_username)) +parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', + help="run ssh in verbose mode") +parser.add_argument("-d", "--driver", default='ath9k', + choices = ['iwlwifi', 'ath9k'], + help="specify which driver to use") +args = parser.parse_args() + +gateway_username = args.slice +verbose_ssh = args.verbose_ssh +wireless_driver = args.driver + +########## +faraday = SshNode(hostname = gateway_hostname, username = gateway_username, + verbose = verbose_ssh, + formatter = TimeColonFormatter()) + +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, + verbose = verbose_ssh, + formatter = TimeColonFormatter()) +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", port = 2222, + verbose = verbose_ssh, + formatter = TimeColonFormatter()) + +########## +# create an orchestration scheduler +scheduler = Scheduler() + +########## +check_lease = SshJob( + # checking the lease is done on the gateway + node = faraday, + # this means that a failure in any of the commands + # will cause the scheduler to bail out immediately + critical = True, + command = Run("rhubarbe leases --check"), + scheduler = scheduler, +) + +########## +# setting up the wireless interface on both fit01 and fit02 +init_node_01 = SshJob( + node = node1, + command = RunScript( + "B3-wireless.sh", + "init-ad-hoc-network", wireless_driver, "foobar", 2412, + ), + required = check_lease, + scheduler = scheduler, +) +init_node_02 = SshJob( + node = node2, + command = RunScript( + "B3-wireless.sh", + "init-ad-hoc-network", wireless_driver, "foobar", 2412, + label = "ditto", + ), + required = check_lease, + scheduler = scheduler, +) + +# the command we want to run in node1 is as simple as it gets +ping = SshJob( + node = node1, + required = (init_node_01, init_node_02), + command = RunScript( + "B3-wireless.sh", "my-ping", '10.0.0.2', 20, +# verbose=True, + ), + scheduler = scheduler, +) + +######## +# for the fun of it, let's add a job that runs forever and writes +# current time every second +import time +import asyncio + +async def infinite_clock(): + while True: + print("--- TICK - {}".format(time.strftime("%H:%M:%S"))) + await asyncio.sleep(1) + +# a forever job is not expected to end, instead +# it gets killed when the rest of the flock is done with +clock_job = Job( + infinite_clock(), + forever=True, + scheduler = scheduler, + # for the illustrated graph + label = "infinite clock", +) + +########## +# run the scheduler +ok = scheduler.orchestrate() + +# give details if it failed +ok or scheduler.debrief() + +success = ok and ping.result() == 0 + +# producing a dot file for illustration +scheduler.export_as_dotfile("B4.dot") + +# return something useful to your OS +exit(0 if success else 1) diff --git a/code/B5-wireless-docker.py b/code/B5-wireless-docker.py new file mode 100755 index 00000000..289f10e8 --- /dev/null +++ b/code/B5-wireless-docker.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 + +from argparse import ArgumentParser + +from asynciojobs import Scheduler +from asynciojobs import Job +from asynciojobs import Watch + +from apssh import SshNode, SshJob +from apssh import Run, RunString, RunScript +from apssh import TimeColonFormatter + +########## +gateway_hostname = 'faraday.inria.fr' +gateway_username = 'inria_r2lab.tutorial' +verbose_ssh = False + +parser = ArgumentParser() +parser.add_argument("-s", "--slice", default=gateway_username, + help="specify an alternate slicename, default={}" + .format(gateway_username)) +parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', + help="run ssh in verbose mode") +parser.add_argument("-d", "--driver", default='ath9k', + choices = ['iwlwifi', 'ath9k'], + help="specify which driver to use") +args = parser.parse_args() + +gateway_username = args.slice +verbose_ssh = args.verbose_ssh +wireless_driver = args.driver + +########## +faraday = SshNode(hostname = gateway_hostname, username = gateway_username, + verbose = verbose_ssh, + formatter = TimeColonFormatter()) + +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, + verbose = verbose_ssh, + formatter = TimeColonFormatter()) +node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", port = 2222, + verbose = verbose_ssh, + formatter = TimeColonFormatter()) + +########## +# create an orchestration scheduler +scheduler = Scheduler() + +########## +check_lease = SshJob( + # checking the lease is done on the gateway + node = faraday, + # this means that a failure in any of the commands + # will cause the scheduler to bail out immediately + critical = True, + command = Run("rhubarbe leases --check"), + scheduler = scheduler, +) + +########## +# setting up the wireless interface on both fit01 and fit02 +init_node_01 = SshJob( + node = node1, + command = RunScript( + "B3-wireless.sh", + "init-ad-hoc-network", wireless_driver, "foobar", 2412, + ), + required = check_lease, + scheduler = scheduler, +) +init_node_02 = SshJob( + node = node2, + command = RunScript( + "B3-wireless.sh", + "init-ad-hoc-network", wireless_driver, "foobar", 2412, + label = "ditto", + ), + required = check_lease, + scheduler = scheduler, +) + +# the command we want to run in node1 is as simple as it gets +ping = SshJob( + node = node1, + required = (init_node_01, init_node_02), + command = RunScript( + "B3-wireless.sh", "my-ping", '10.0.0.2', 20, +# verbose=True, + ), + scheduler = scheduler, +) + +######## +# for the fun of it, let's add a job that runs forever and writes +# current time every second +import time +import asyncio + + +async def infinite_clock(watch): + while True: + print("--- TICK - {}".format(watch.elapsed())) + await asyncio.sleep(1) + +# create a Watch instance for keeping track of elapsed time +watch = Watch() + +# a forever job is not expected to end, instead +# it gets killed when the rest of the flock is done with +clock_job = Job( + infinite_clock(watch), + forever=True, + scheduler = scheduler, + # for the illustrated graph + label = "infinite stopwatch", +) + +########## +# run the scheduler +ok = scheduler.orchestrate() + +# give details if it failed +ok or scheduler.debrief() + +success = ok and ping.result() == 0 + +# producing a dot file for illustration +scheduler.export_as_dotfile("B5.dot") + +# return something useful to your OS +exit(0 if success else 1) diff --git a/code/C1-files-docker.py b/code/C1-files-docker.py new file mode 100755 index 00000000..7b14570c --- /dev/null +++ b/code/C1-files-docker.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 + +import sys, os + +import asyncio + +from argparse import ArgumentParser + +from asynciojobs import Scheduler + +from apssh import SshNode, SshJob, LocalNode +from apssh import Run, RunString, Push + +########## + +gateway_hostname = 'faraday.inria.fr' +gateway_username = 'root' +verbose_ssh = False +random_size = 2**10 + +# this time we want to be able to specify username and verbose_ssh +parser = ArgumentParser() +parser.add_argument("-s", "--slice", default=gateway_username, + help="specify an alternate slicename, default={}" + .format(gateway_username)) +parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', + help="run ssh in verbose mode") +args = parser.parse_args() + +# override globals from the command line +gateway_username = args.slice +verbose_ssh = args.verbose_ssh + +########## the nodes involved + +faraday = SshNode(hostname = gateway_hostname, username = gateway_username, + verbose = verbose_ssh) + +# saying gateway = faraday means to tunnel ssh through the gateway +node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, + verbose = verbose_ssh) + +########## create the scheduler instance upfront +scheduler = Scheduler() + +check_lease = SshJob( + node = faraday, + critical = True, + command = Run("rhubarbe leases --check"), + scheduler = scheduler, +) + +########## 1 step, generate a random data file of 1 M bytes + +create_random_job = SshJob( + # Using LocalNode() means this will run on our laptop + node = LocalNode(), + commands = [ + Run("head", "-c", random_size, "<", "/dev/random", ">", "RANDOM"), + Run("ls", "-l", "RANDOM"), + Run("shasum", "RANDOM"), + ], + required = check_lease, + scheduler = scheduler, +) + +########## 2nd step : push this over to node1 + +push_job = SshJob( + node = node1, + commands = [ + Push( localpaths = [ "RANDOM" ], + remotepath = "."), + Run("ls -l RANDOM"), + Run("sha1sum RANDOM"), + ], + required = create_random_job, + scheduler = scheduler, +) + +########## +# run the scheduler +ok = scheduler.orchestrate() + +# give details if it failed +ok or scheduler.debrief() + +# producing a dot file for illustration +scheduler.export_as_dotfile("C1.dot") + +# return something useful to your OS +exit(0 if ok else 1) diff --git a/code/C1-files.py b/code/C1-files.py index a214c989..9c3d01e6 100755 --- a/code/C1-files.py +++ b/code/C1-files.py @@ -37,7 +37,7 @@ verbose = verbose_ssh) # saying gateway = faraday means to tunnel ssh through the gateway -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", +node1 = SshNode(gateway = faraday, hostname = "fit20", username = "root", port = 2222, verbose = verbose_ssh) ########## create the scheduler instance upfront diff --git a/code/C2-files-docker.py b/code/C2-files-docker.py new file mode 100755 index 00000000..0bbe0c99 --- /dev/null +++ b/code/C2-files-docker.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 + +import sys, os + +import asyncio + +from argparse import ArgumentParser + +from asynciojobs import Scheduler, Sequence + +from apssh import SshNode, SshJob, LocalNode +from apssh import Run, RunString, Push + +########## + +gateway_hostname = 'faraday.inria.fr' +gateway_username = 'root' +verbose_ssh = False +random_size = 2**10 +netcat_port = 10000 + +# this time we want to be able to specify username and verbose_ssh +parser = ArgumentParser() +parser.add_argument("-s", "--slice", default=gateway_username, + help="specify an alternate slicename, default={}" + .format(gateway_username)) +parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', + help="run ssh in verbose mode") +args = parser.parse_args() + +gateway_username = args.slice +verbose_ssh = args.verbose_ssh + +########## the nodes involved + +faraday = SshNode(hostname = gateway_hostname, username = gateway_username, + verbose = verbose_ssh) + +# saying gateway = faraday means to tunnel ssh through the gateway +node1 = SshNode(gateway = faraday, hostname = "fit20", username = "root", port = 2222, + verbose = verbose_ssh) +node2 = SshNode(gateway = faraday, hostname = "fit21", username = "root", port = 2222, + verbose = verbose_ssh) + +# for convenience, a collection of the nodes +# that we need to initialize +nodes = (node1, node2) + +########## create the scheduler instance upfront +scheduler = Scheduler() + +check_lease = SshJob( + node = faraday, + critical = True, + command = Run("rhubarbe leases --check"), + scheduler = scheduler, +) + +########## 1 step, generate a random data file of 1 M bytes + +create_random_job = SshJob( + node = LocalNode(), + commands = [ + Run("head", "-c", random_size, "<", "/dev/random", ">", "RANDOM"), + Run("ls", "-l", "RANDOM"), + Run("shasum", "RANDOM"), + ], + required = check_lease, + scheduler = scheduler, +) + +########## 2nd step : push this over to node1 + +push_job = SshJob( + node = node1, + commands = [ + Push( localpaths = [ "RANDOM" ], + remotepath = "."), + Run("ls -l RANDOM"), + Run("sha1sum RANDOM"), + ], + required = create_random_job, + scheduler = scheduler, +) + +########## step 3 : turn on data interfaces +# a convenient way to create many jobs in a single pass is +# to build a list of jobs using a python comprehension + +turn_on_datas = [ + SshJob( node = node, + command = Run("turn-on-data"), + required = push_job, + scheduler = scheduler, + ) for node in nodes ] + +########## next : run a sender on node1 and a receiver on node 2 +# in order to transfer RANDOM over a netcat session on the data network + +# a Sequence object is a container for jobs, they will have their +# 'required' relationship organized along the sequence order + +transfer_job = Sequence( + + # start the receiver - this of course returns immediately + SshJob( + node = node2, + commands = [ + Run("netcat", "-l", "data02", netcat_port, ">", "RANDOM", "&"), + ], + ), + + # start the sender + SshJob( + node = node1, + # ignore netcat result + critical = False, + commands = [ + # let the server warm up just in case + Run("sleep 1"), + Run("netcat", "data02", netcat_port, "<", "RANDOM"), + Run("echo SENDER DONE"), + ], + ), + + # check contents on the receiving end + SshJob( + node=node2, + commands = [ + Run("ls -l RANDOM"), + Run("sha1sum RANDOM"), + ], + ), + + ### these two apply to the Sequence + # required applies to the first job in the sequence + required = turn_on_datas, + # scheduler applies to all jobs in the sequence + scheduler = scheduler, +) + +########## +# run the scheduler +ok = scheduler.orchestrate() + +# give details if it failed +ok or scheduler.debrief() + +# producing a dot file for illustration +scheduler.export_as_dotfile("C2.dot") + +# return something useful to your OS +exit(0 if ok else 1) From c8d4a2d9a60f96cf37185ffd4dedb47f6d35ae2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Mon, 29 Aug 2022 15:47:45 +0200 Subject: [PATCH 12/16] Update tuto-020-shell-tools.md --- markdown/tuto-020-shell-tools.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/markdown/tuto-020-shell-tools.md b/markdown/tuto-020-shell-tools.md index 4f69ce15..2cf53415 100644 --- a/markdown/tuto-020-shell-tools.md +++ b/markdown/tuto-020-shell-tools.md @@ -295,4 +295,22 @@ to get a reminder. + + +
+ +## Baleine + +Baleine allows you to deploy Docker containers instead of disk images. You can use it on Faraday. + +You can use five different commands to deploy containers. Here is a simple command, which we will explain : + +``` +baleine deploy +``` + +[Please refer to this page](/tuto-130-5g.md#PHONES) for more details on this offering, and how to manage these phones e.g. through a VNC session. + +
+ From 9d8d14a65d11602038aa5e5901553de342312102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Tue, 30 Aug 2022 15:17:51 +0200 Subject: [PATCH 13/16] Added a paragraph about Baleine --- markdown/tuto-020-shell-tools.md | 26 +++++++++++++++++++++++++- r2lab/settings.py | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/markdown/tuto-020-shell-tools.md b/markdown/tuto-020-shell-tools.md index 9300b110..77e618ff 100644 --- a/markdown/tuto-020-shell-tools.md +++ b/markdown/tuto-020-shell-tools.md @@ -7,7 +7,7 @@ skip_header: True -<< tuto_tabs "LOG IN":LOGIN "SELECT NODES":NODES "IMAGES": "PHONES": >> +<< tuto_tabs "LOG IN":LOGIN "SELECT NODES":NODES "IMAGES": "PHONES": "BALEINE": >>
@@ -278,4 +278,28 @@ to get a reminder.
+ +
+ +## Baleine + +Baleine is a gateway tool allowing you to deploy Docker containers inside the R2Lab testbed. + +We will now demonstrate the deploy subcommand that will be very useful to you : + +``` +baleine deploy --image faraday.repo/tutorial --nodes 1 2 --options -t -d +``` + +The `deploy` subcommand allows you to pull and deploy the docker image selected with `--image` on the nodes selected with `--nodes`. +The `--options` option allows you to give an array of argument to pass directly to the Docker Runtime. + +The `faraday.repo/tutorial` image is based on Ubuntu, so the `-t` and `-d` options are necessary for the Docker image to continue running. + +To use the Docker container as your server to run the tutorials, please use port `2222` for SSH as `22` is reserved for the host OS. + +[Check out the wiki](https://github.com/haysberg/baleine/wiki) for exhaustive information on the different commands and options available. + +
+ diff --git a/r2lab/settings.py b/r2lab/settings.py index 4b3ac516..c51fde0b 100644 --- a/r2lab/settings.py +++ b/r2lab/settings.py @@ -68,6 +68,7 @@ ALLOWED_HOSTS = [ 'r2lab.inria.fr', 'localhost', + '127.0.0.1' ] # Application definition From 85f6a981e069b462da86a825011cb9429aaeb13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Tue, 30 Aug 2022 15:19:01 +0200 Subject: [PATCH 14/16] Deleted useless code --- code/A3-ping-docker.py | 63 --------------- code/A4-ping-docker.py | 70 ---------------- code/A5-ping-docker.py | 79 ------------------ code/B1-wireless-docker.py | 156 ----------------------------------- code/B2-wireless-docker.py | 162 ------------------------------------- code/B3-wireless-docker.py | 113 -------------------------- code/B4-wireless-docker.py | 126 ----------------------------- code/B5-wireless-docker.py | 131 ------------------------------ code/C1-files-docker.py | 92 --------------------- code/C2-files-docker.py | 153 ----------------------------------- 10 files changed, 1145 deletions(-) delete mode 100644 code/A3-ping-docker.py delete mode 100644 code/A4-ping-docker.py delete mode 100644 code/A5-ping-docker.py delete mode 100755 code/B1-wireless-docker.py delete mode 100755 code/B2-wireless-docker.py delete mode 100755 code/B3-wireless-docker.py delete mode 100755 code/B4-wireless-docker.py delete mode 100755 code/B5-wireless-docker.py delete mode 100755 code/C1-files-docker.py delete mode 100755 code/C2-files-docker.py diff --git a/code/A3-ping-docker.py b/code/A3-ping-docker.py deleted file mode 100644 index 2bb17b1d..00000000 --- a/code/A3-ping-docker.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python3 - -from argparse import ArgumentParser - -from asynciojobs import Scheduler - -from apssh import SshNode, SshJob -from apssh import Run - -########## -gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' -verbose_ssh = False - -# this time we want to be able to specify username and verbose_ssh -parser = ArgumentParser() -parser.add_argument("-s", "--slice", default=gateway_username, - help="specify an alternate slicename, default={}" - .format(gateway_username)) -parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', - help="run ssh in verbose mode") -args = parser.parse_args() - -gateway_username = args.slice -verbose_ssh = args.verbose_ssh - -########## -faraday = SshNode(hostname = gateway_hostname, username = gateway_username, - verbose = verbose_ssh) - -# saying gateway = faraday means to tunnel ssh through the gateway -# using the container username allows us to forward the command directly inside the container -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", port = 2222, - verbose = verbose_ssh) -########## -# create an orchestration scheduler -scheduler = Scheduler() - -########## -# the command we want to run in node1 is as simple as it gets -ping = SshJob( - node = node1, - # let's be more specific about what to run - # we will soon see other things we can do on an ssh connection - command = Run('ping', '-c1', 'google.fr'), - scheduler = scheduler, -) - -########## -# how to run the same directly with ssh - for troubleshooting -print("""--- for troubleshooting: -ssh -i /dev/null {}@{} ssh container@fit01 -P 2222 ping -c1 google.fr ----""".format(gateway_username, gateway_hostname)) - -########## -# run the scheduler -ok = scheduler.orchestrate() - -# give details if it failed -ok or scheduler.debrief() - -# return something useful to your OS -exit(0 if ok else 1) diff --git a/code/A4-ping-docker.py b/code/A4-ping-docker.py deleted file mode 100644 index 112cddbf..00000000 --- a/code/A4-ping-docker.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python3 - -from argparse import ArgumentParser - -from asynciojobs import Scheduler - -from apssh import SshNode, SshJob -from apssh import Run - -########## -gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' -verbose_ssh = False - -parser = ArgumentParser() -parser.add_argument("-s", "--slice", default=gateway_username, - help="specify an alternate slicename, default={}" - .format(gateway_username)) -parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', - help="run ssh in verbose mode") -args = parser.parse_args() - -gateway_username = args.slice -verbose_ssh = args.verbose_ssh - -########## -faraday = SshNode(hostname = gateway_hostname, username = gateway_username, - verbose = verbose_ssh) - -# saying gateway = faraday means to tunnel ssh through the gateway -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", port = 2222, - verbose = verbose_ssh) -########## -# create an orchestration scheduler -scheduler = Scheduler() - -########## -check_lease = SshJob( - # checking the lease is done on the gateway - node = faraday, - # this means that a failure in any of the commands - # will cause the scheduler to bail out immediately - critical = True, - command = Run("rhubarbe leases --check"), - scheduler = scheduler, -) - -# the command we want to run in node1 is as simple as it gets -ping = SshJob( - node = node1, - # this says that we wait for check_lease to finish before we start ping - required = check_lease, - # let's be more specific about what to run - # we will soon see other things we can do on an ssh connection - command = Run('ping', '-c1', 'google.fr'), - scheduler = scheduler, -) - -########## -# run the scheduler -ok = scheduler.orchestrate() - -# give details if it failed -ok or scheduler.debrief() - -# producing a dot file for illustration -scheduler.export_as_dotfile("A4.dot") - -# return something useful to your OS -exit(0 if ok else 1) diff --git a/code/A5-ping-docker.py b/code/A5-ping-docker.py deleted file mode 100644 index fbb0f0c8..00000000 --- a/code/A5-ping-docker.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python3 - -from argparse import ArgumentParser - -from asynciojobs import Scheduler - -from apssh import SshNode, SshJob -from apssh import Run - -########## -gateway_hostname = 'faraday.inria.fr' -gateway_username = 'root' -verbose_ssh = False - -parser = ArgumentParser() -parser.add_argument("-s", "--slice", default=gateway_username, - help="specify an alternate slicename, default={}" - .format(gateway_username)) -parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', - help="run ssh in verbose mode") -args = parser.parse_args() - -gateway_username = args.slice -verbose_ssh = args.verbose_ssh - -########## -faraday = SshNode(hostname = gateway_hostname, username = gateway_username, - verbose = verbose_ssh) - -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "container", port = 2222, - verbose = verbose_ssh) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "container", port = 2222, - verbose = verbose_ssh) - -########## -# create an orchestration scheduler -scheduler = Scheduler() - -########## -check_lease = SshJob( - # checking the lease is done on the gateway - node = faraday, - # this means that a failure in any of the commands - # will cause the scheduler to bail out immediately - critical = True, - command = Run("rhubarbe leases --check"), - scheduler = scheduler, -) - -# the command we want to run in node1 is as simple as it gets -ping = SshJob( - node = node1, - # wait for the 2 init jobs instead - # check_release is guaranteed to have completed anyway - required = (check_lease), - # let's be more specific about what to run - # we will soon see other things we can do on an ssh connection - command = Run('ping', '-c1', 'fit02'), - scheduler = scheduler, -) - -########## -# run the scheduler -ok = scheduler.orchestrate() - -# give details if it failed -ok or scheduler.debrief() - -# we say this is a success if the ping command succeeded -# the result() of the SshJob is the value that the command -# returns to the OS -# so it's a success if this value is 0 -success = ok and ping.result() == 0 - -# producing a dot file for illustration -scheduler.export_as_dotfile("A5.dot") - -# return something useful to your OS -exit(0 if success else 1) diff --git a/code/B1-wireless-docker.py b/code/B1-wireless-docker.py deleted file mode 100755 index 033a2c56..00000000 --- a/code/B1-wireless-docker.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/env python3 - -from argparse import ArgumentParser - -from asynciojobs import Scheduler - -from apssh import SshNode, SshJob -from apssh import Run, RunString - -########## -gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' -verbose_ssh = False -wireless_driver="ath9k" -wireless_interface="atheros" - -parser = ArgumentParser() -parser.add_argument("-s", "--slice", default=gateway_username, - help="specify an alternate slicename, default={}" - .format(gateway_username)) -parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', - help="run ssh in verbose mode") -args = parser.parse_args() - -gateway_username = args.slice -verbose_ssh = args.verbose_ssh - -########## -faraday = SshNode(hostname = gateway_hostname, username = gateway_username, - verbose = verbose_ssh) - -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, - verbose = verbose_ssh) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", port = 2222, - verbose = verbose_ssh) - -########## -# create an orchestration scheduler -scheduler = Scheduler() - -########## -check_lease = SshJob( - # checking the lease is done on the gateway - node = faraday, - # this means that a failure in any of the commands - # will cause the scheduler to bail out immediately - critical = True, - command = Run("rhubarbe leases --check"), - scheduler = scheduler, -) - -#################### -# This is our own brewed script for setting up a wifi network -# it run on the remote machine - either sender or receiver -# and is in charge of initializing a small ad-hoc network -# -# Thanks to the RunString class, we can just define this as -# a python string, and pass it arguments from python variables -# - -turn_on_wireless_script = """#!/bin/bash - -# we expect the following arguments -# * wireless driver name (iwlwifi or ath9k) -# * wireless interface name (intel or atheros) -# * IP-address/mask for that interface -# * the wifi network name to join -# * the wifi frequency to use - -driver=$1; shift -ifname=$1; shift -ipaddr_mask=$1; shift -netname=$1; shift -freq=$1; shift - -# load the r2lab utilities - code can be found here: -# https://github.com/fit-r2lab/r2lab-embedded/blob/master/shell/nodes.sh -source /etc/profile.d/nodes.sh - -# make sure to use the latest code on the node -git-pull-r2lab - -turn-off-wireless - -echo loading module $driver -modprobe $driver - -# some time for udev to trigger its rules -sleep 1 - -echo configuring interface $ifname -# make sure to wipe down everything first so we can run again and again -ip address flush dev $ifname -ip link set $ifname down -# configure wireless -iw dev $ifname set type ibss -ip link set $ifname up -# set to ad-hoc mode -iw dev $ifname ibss join $netname $freq -ip address add $ipaddr_mask dev $ifname -""" - -########## -# setting up the wireless interface on both fit01 and fit02 - -# IMPORTANT NOTE : We could have run the scripts inside the Docker containers -# We would obtain the same results as the containers have full power over the host. -# However we don't here for the sake of staying close to the "non-Docker" tutorial. -init_node_01 = SshJob( - node = node1, - command = RunString( - # first argument is a string containing - # the script to be run remotely - turn_on_wireless_script, - # and now its arguments - wireless_driver, wireless_interface, "10.0.0.1/24", "foobar", 2412, -# verbose=True, - ), - required = check_lease, - scheduler = scheduler, -) -init_node_02 = SshJob( - node = node2, - command = RunString( - turn_on_wireless_script, - wireless_driver, wireless_interface, "10.0.0.2/24", "foobar", 2412, - ), - required = check_lease, - scheduler = scheduler, -) - -# the command we want to run in node1 is as simple as it gets -ping = SshJob( - node = node1, - required = (init_node_01, init_node_02), - command = Run( - 'ping -c20 10.0.0.2 -I', wireless_interface -# verbose=True, - ), - scheduler = scheduler, -) - -########## -# run the scheduler -ok = scheduler.orchestrate() - -# give details if it failed -ok or scheduler.debrief() - -success = ok and ping.result() == 0 - -# producing a dot file for illustration -scheduler.export_as_dotfile("B1.dot") - -# return something useful to your OS -exit(0 if success else 1) diff --git a/code/B2-wireless-docker.py b/code/B2-wireless-docker.py deleted file mode 100755 index f975c558..00000000 --- a/code/B2-wireless-docker.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env python3 - -from argparse import ArgumentParser - -from asynciojobs import Scheduler - -from apssh import SshNode, SshJob -from apssh import Run, RunString -from apssh import TimeColonFormatter - -########## -gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' -verbose_ssh = False - -parser = ArgumentParser() -parser.add_argument("-s", "--slice", default=gateway_username, - help="specify an alternate slicename, default={}" - .format(gateway_username)) -parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', - help="run ssh in verbose mode") -parser.add_argument("-d", "--driver", default='ath9k', - choices = ['iwlwifi', 'ath9k'], - help="specify which driver to use") -args = parser.parse_args() - -gateway_username = args.slice -verbose_ssh = args.verbose_ssh -wireless_driver = args.driver - -########## -faraday = SshNode(hostname = gateway_hostname, username = gateway_username, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) - -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", port = 2222, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) - -########## -# create an orchestration scheduler -scheduler = Scheduler() - -########## -check_lease = SshJob( - # checking the lease is done on the gateway - node = faraday, - # this means that a failure in any of the commands - # will cause the scheduler to bail out immediately - critical = True, - command = Run("rhubarbe leases --check"), - scheduler = scheduler, -) - -#################### -# This is our own brewed script for setting up a wifi network -# it run on the remote machine - either sender or receiver -# and is in charge of initializing a small ad-hoc network -# -# Thanks to the RunString class, we can just define this as -# a python string, and pass it arguments from python variables -# - -turn_on_wireless_script = """#!/bin/bash - -# we expect the following arguments -# * wireless driver name (iwlwifi or ath9k) -# * the wifi network name to join -# * the wifi frequency to use - -driver=$1; shift -netname=$1; shift -freq=$1; shift - -# load the r2lab utilities - code can be found here: -# https://github.com/fit-r2lab/r2lab-embedded/blob/master/shell/nodes.sh -source /etc/profile.d/nodes.sh - -# make sure to use the latest code on the node -git-pull-r2lab - -turn-off-wireless - -# local IP address to use is computed on the 10.0.0.0/24 -# subnet and based on current node number (using r2lab-ip) -ipaddr_mask=10.0.0.$(r2lab-ip)/24 - -echo loading module $driver -modprobe $driver - -# some time for udev to trigger its rules -sleep 1 - -# use r2lab tools to figure out the interface name -ifname=$(wait-for-interface-on-driver $driver) - -echo configuring interface $ifname -# make sure to wipe down everything first so we can run again and again -ip address flush dev $ifname -ip link set $ifname down -# configure wireless -iw dev $ifname set type ibss -ip link set $ifname up -# set to ad-hoc mode -iw dev $ifname ibss join $netname $freq -ip address add $ipaddr_mask dev $ifname -""" - -########## -# setting up the wireless interface on both fit01 and fit02 -init_node_01 = SshJob( - node = node1, - command = RunString( - turn_on_wireless_script, - wireless_driver, "foobar", 2412, - # setting a remote_name allows to - # improve the graphical rendering - remote_name = 'turn-on-wireless' -# verbose=True, - ), - required = check_lease, - scheduler = scheduler, -) -init_node_02 = SshJob( - node = node2, - command = RunString( - turn_on_wireless_script, - wireless_driver, "foobar", 2412, - remote_name = 'turn-on-wireless' - ), - required = check_lease, - scheduler = scheduler, -) - -# the command we want to run in node1 is as simple as it gets -ping = SshJob( - node = node1, - required = (init_node_01, init_node_02), - command = Run( - 'ping', '-c', '20', '10.0.0.2', -# verbose=True, - ), - scheduler = scheduler, -) - -########## -# run the scheduler -ok = scheduler.orchestrate() - -# give details if it failed -ok or scheduler.debrief() - -success = ok and ping.result() == 0 - -# producing a dot file for illustration -scheduler.export_as_dotfile("B2.dot") - -# return something useful to your OS -exit(0 if success else 1) diff --git a/code/B3-wireless-docker.py b/code/B3-wireless-docker.py deleted file mode 100755 index 36e58bc4..00000000 --- a/code/B3-wireless-docker.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python3 - -from argparse import ArgumentParser - -from asynciojobs import Scheduler - -from apssh import SshNode, SshJob -from apssh import Run, RunString, RunScript -from apssh import TimeColonFormatter - -########## -gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' -verbose_ssh = False - -parser = ArgumentParser() -parser.add_argument("-s", "--slice", default=gateway_username, - help="specify an alternate slicename, default={}" - .format(gateway_username)) -parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', - help="run ssh in verbose mode") -parser.add_argument("-d", "--driver", default='ath9k', - choices = ['iwlwifi', 'ath9k'], - help="specify which driver to use") -args = parser.parse_args() - -gateway_username = args.slice -verbose_ssh = args.verbose_ssh -wireless_driver = args.driver - -########## -faraday = SshNode(hostname = gateway_hostname, username = gateway_username, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) - -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", port = 2222, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) - -########## -# create an orchestration scheduler -scheduler = Scheduler() - -########## -check_lease = SshJob( - # checking the lease is done on the gateway - node = faraday, - # this means that a failure in any of the commands - # will cause the scheduler to bail out immediately - critical = True, - command = Run("rhubarbe leases --check"), - scheduler = scheduler, -) - -# the shell script has gone into B3-wireless.sh -#################### - -########## -# setting up the wireless interface on both fit01 and fit02 -init_node_01 = SshJob( - node = node1, - # RunString is replaced with RunScript - command = RunScript( - # first argument is the local filename - # where to find the script to run remotely - "B3-wireless.sh", - # then its arguments - "init-ad-hoc-network", wireless_driver, "foobar", 2412, - # no need to set remote_name with RunScript - ), - required = check_lease, - scheduler = scheduler, -) -init_node_02 = SshJob( - node = node2, - command = RunScript( - "B3-wireless.sh", - "init-ad-hoc-network", wireless_driver, "foobar", 2412, - # setting a label to gain space in the graphical output - label="ditto", - ), - required = check_lease, - scheduler = scheduler, -) - -# the command we want to run in node1 is as simple as it gets -ping = SshJob( - node = node1, - required = (init_node_01, init_node_02), - command = RunScript( - "B3-wireless.sh", "my-ping", '10.0.0.2', 20, -# verbose=True, - ), - scheduler = scheduler, -) - -########## -# run the scheduler -ok = scheduler.orchestrate() - -# give details if it failed -ok or scheduler.debrief() - -success = ok and ping.result() == 0 - -# producing a dot file for illustration -scheduler.export_as_dotfile("B3.dot") - -# return something useful to your OS -exit(0 if success else 1) diff --git a/code/B4-wireless-docker.py b/code/B4-wireless-docker.py deleted file mode 100755 index d4260b60..00000000 --- a/code/B4-wireless-docker.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env python3 - -from argparse import ArgumentParser - -from asynciojobs import Scheduler -from asynciojobs import Job - -from apssh import SshNode, SshJob -from apssh import Run, RunString, RunScript -from apssh import TimeColonFormatter - -########## -gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' -verbose_ssh = False - -parser = ArgumentParser() -parser.add_argument("-s", "--slice", default=gateway_username, - help="specify an alternate slicename, default={}" - .format(gateway_username)) -parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', - help="run ssh in verbose mode") -parser.add_argument("-d", "--driver", default='ath9k', - choices = ['iwlwifi', 'ath9k'], - help="specify which driver to use") -args = parser.parse_args() - -gateway_username = args.slice -verbose_ssh = args.verbose_ssh -wireless_driver = args.driver - -########## -faraday = SshNode(hostname = gateway_hostname, username = gateway_username, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) - -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", port = 2222, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) - -########## -# create an orchestration scheduler -scheduler = Scheduler() - -########## -check_lease = SshJob( - # checking the lease is done on the gateway - node = faraday, - # this means that a failure in any of the commands - # will cause the scheduler to bail out immediately - critical = True, - command = Run("rhubarbe leases --check"), - scheduler = scheduler, -) - -########## -# setting up the wireless interface on both fit01 and fit02 -init_node_01 = SshJob( - node = node1, - command = RunScript( - "B3-wireless.sh", - "init-ad-hoc-network", wireless_driver, "foobar", 2412, - ), - required = check_lease, - scheduler = scheduler, -) -init_node_02 = SshJob( - node = node2, - command = RunScript( - "B3-wireless.sh", - "init-ad-hoc-network", wireless_driver, "foobar", 2412, - label = "ditto", - ), - required = check_lease, - scheduler = scheduler, -) - -# the command we want to run in node1 is as simple as it gets -ping = SshJob( - node = node1, - required = (init_node_01, init_node_02), - command = RunScript( - "B3-wireless.sh", "my-ping", '10.0.0.2', 20, -# verbose=True, - ), - scheduler = scheduler, -) - -######## -# for the fun of it, let's add a job that runs forever and writes -# current time every second -import time -import asyncio - -async def infinite_clock(): - while True: - print("--- TICK - {}".format(time.strftime("%H:%M:%S"))) - await asyncio.sleep(1) - -# a forever job is not expected to end, instead -# it gets killed when the rest of the flock is done with -clock_job = Job( - infinite_clock(), - forever=True, - scheduler = scheduler, - # for the illustrated graph - label = "infinite clock", -) - -########## -# run the scheduler -ok = scheduler.orchestrate() - -# give details if it failed -ok or scheduler.debrief() - -success = ok and ping.result() == 0 - -# producing a dot file for illustration -scheduler.export_as_dotfile("B4.dot") - -# return something useful to your OS -exit(0 if success else 1) diff --git a/code/B5-wireless-docker.py b/code/B5-wireless-docker.py deleted file mode 100755 index 289f10e8..00000000 --- a/code/B5-wireless-docker.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python3 - -from argparse import ArgumentParser - -from asynciojobs import Scheduler -from asynciojobs import Job -from asynciojobs import Watch - -from apssh import SshNode, SshJob -from apssh import Run, RunString, RunScript -from apssh import TimeColonFormatter - -########## -gateway_hostname = 'faraday.inria.fr' -gateway_username = 'inria_r2lab.tutorial' -verbose_ssh = False - -parser = ArgumentParser() -parser.add_argument("-s", "--slice", default=gateway_username, - help="specify an alternate slicename, default={}" - .format(gateway_username)) -parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', - help="run ssh in verbose mode") -parser.add_argument("-d", "--driver", default='ath9k', - choices = ['iwlwifi', 'ath9k'], - help="specify which driver to use") -args = parser.parse_args() - -gateway_username = args.slice -verbose_ssh = args.verbose_ssh -wireless_driver = args.driver - -########## -faraday = SshNode(hostname = gateway_hostname, username = gateway_username, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) - -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) -node2 = SshNode(gateway = faraday, hostname = "fit02", username = "root", port = 2222, - verbose = verbose_ssh, - formatter = TimeColonFormatter()) - -########## -# create an orchestration scheduler -scheduler = Scheduler() - -########## -check_lease = SshJob( - # checking the lease is done on the gateway - node = faraday, - # this means that a failure in any of the commands - # will cause the scheduler to bail out immediately - critical = True, - command = Run("rhubarbe leases --check"), - scheduler = scheduler, -) - -########## -# setting up the wireless interface on both fit01 and fit02 -init_node_01 = SshJob( - node = node1, - command = RunScript( - "B3-wireless.sh", - "init-ad-hoc-network", wireless_driver, "foobar", 2412, - ), - required = check_lease, - scheduler = scheduler, -) -init_node_02 = SshJob( - node = node2, - command = RunScript( - "B3-wireless.sh", - "init-ad-hoc-network", wireless_driver, "foobar", 2412, - label = "ditto", - ), - required = check_lease, - scheduler = scheduler, -) - -# the command we want to run in node1 is as simple as it gets -ping = SshJob( - node = node1, - required = (init_node_01, init_node_02), - command = RunScript( - "B3-wireless.sh", "my-ping", '10.0.0.2', 20, -# verbose=True, - ), - scheduler = scheduler, -) - -######## -# for the fun of it, let's add a job that runs forever and writes -# current time every second -import time -import asyncio - - -async def infinite_clock(watch): - while True: - print("--- TICK - {}".format(watch.elapsed())) - await asyncio.sleep(1) - -# create a Watch instance for keeping track of elapsed time -watch = Watch() - -# a forever job is not expected to end, instead -# it gets killed when the rest of the flock is done with -clock_job = Job( - infinite_clock(watch), - forever=True, - scheduler = scheduler, - # for the illustrated graph - label = "infinite stopwatch", -) - -########## -# run the scheduler -ok = scheduler.orchestrate() - -# give details if it failed -ok or scheduler.debrief() - -success = ok and ping.result() == 0 - -# producing a dot file for illustration -scheduler.export_as_dotfile("B5.dot") - -# return something useful to your OS -exit(0 if success else 1) diff --git a/code/C1-files-docker.py b/code/C1-files-docker.py deleted file mode 100755 index 7b14570c..00000000 --- a/code/C1-files-docker.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python3 - -import sys, os - -import asyncio - -from argparse import ArgumentParser - -from asynciojobs import Scheduler - -from apssh import SshNode, SshJob, LocalNode -from apssh import Run, RunString, Push - -########## - -gateway_hostname = 'faraday.inria.fr' -gateway_username = 'root' -verbose_ssh = False -random_size = 2**10 - -# this time we want to be able to specify username and verbose_ssh -parser = ArgumentParser() -parser.add_argument("-s", "--slice", default=gateway_username, - help="specify an alternate slicename, default={}" - .format(gateway_username)) -parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', - help="run ssh in verbose mode") -args = parser.parse_args() - -# override globals from the command line -gateway_username = args.slice -verbose_ssh = args.verbose_ssh - -########## the nodes involved - -faraday = SshNode(hostname = gateway_hostname, username = gateway_username, - verbose = verbose_ssh) - -# saying gateway = faraday means to tunnel ssh through the gateway -node1 = SshNode(gateway = faraday, hostname = "fit01", username = "root", port = 2222, - verbose = verbose_ssh) - -########## create the scheduler instance upfront -scheduler = Scheduler() - -check_lease = SshJob( - node = faraday, - critical = True, - command = Run("rhubarbe leases --check"), - scheduler = scheduler, -) - -########## 1 step, generate a random data file of 1 M bytes - -create_random_job = SshJob( - # Using LocalNode() means this will run on our laptop - node = LocalNode(), - commands = [ - Run("head", "-c", random_size, "<", "/dev/random", ">", "RANDOM"), - Run("ls", "-l", "RANDOM"), - Run("shasum", "RANDOM"), - ], - required = check_lease, - scheduler = scheduler, -) - -########## 2nd step : push this over to node1 - -push_job = SshJob( - node = node1, - commands = [ - Push( localpaths = [ "RANDOM" ], - remotepath = "."), - Run("ls -l RANDOM"), - Run("sha1sum RANDOM"), - ], - required = create_random_job, - scheduler = scheduler, -) - -########## -# run the scheduler -ok = scheduler.orchestrate() - -# give details if it failed -ok or scheduler.debrief() - -# producing a dot file for illustration -scheduler.export_as_dotfile("C1.dot") - -# return something useful to your OS -exit(0 if ok else 1) diff --git a/code/C2-files-docker.py b/code/C2-files-docker.py deleted file mode 100755 index 0bbe0c99..00000000 --- a/code/C2-files-docker.py +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/env python3 - -import sys, os - -import asyncio - -from argparse import ArgumentParser - -from asynciojobs import Scheduler, Sequence - -from apssh import SshNode, SshJob, LocalNode -from apssh import Run, RunString, Push - -########## - -gateway_hostname = 'faraday.inria.fr' -gateway_username = 'root' -verbose_ssh = False -random_size = 2**10 -netcat_port = 10000 - -# this time we want to be able to specify username and verbose_ssh -parser = ArgumentParser() -parser.add_argument("-s", "--slice", default=gateway_username, - help="specify an alternate slicename, default={}" - .format(gateway_username)) -parser.add_argument("-v", "--verbose-ssh", default=False, action='store_true', - help="run ssh in verbose mode") -args = parser.parse_args() - -gateway_username = args.slice -verbose_ssh = args.verbose_ssh - -########## the nodes involved - -faraday = SshNode(hostname = gateway_hostname, username = gateway_username, - verbose = verbose_ssh) - -# saying gateway = faraday means to tunnel ssh through the gateway -node1 = SshNode(gateway = faraday, hostname = "fit20", username = "root", port = 2222, - verbose = verbose_ssh) -node2 = SshNode(gateway = faraday, hostname = "fit21", username = "root", port = 2222, - verbose = verbose_ssh) - -# for convenience, a collection of the nodes -# that we need to initialize -nodes = (node1, node2) - -########## create the scheduler instance upfront -scheduler = Scheduler() - -check_lease = SshJob( - node = faraday, - critical = True, - command = Run("rhubarbe leases --check"), - scheduler = scheduler, -) - -########## 1 step, generate a random data file of 1 M bytes - -create_random_job = SshJob( - node = LocalNode(), - commands = [ - Run("head", "-c", random_size, "<", "/dev/random", ">", "RANDOM"), - Run("ls", "-l", "RANDOM"), - Run("shasum", "RANDOM"), - ], - required = check_lease, - scheduler = scheduler, -) - -########## 2nd step : push this over to node1 - -push_job = SshJob( - node = node1, - commands = [ - Push( localpaths = [ "RANDOM" ], - remotepath = "."), - Run("ls -l RANDOM"), - Run("sha1sum RANDOM"), - ], - required = create_random_job, - scheduler = scheduler, -) - -########## step 3 : turn on data interfaces -# a convenient way to create many jobs in a single pass is -# to build a list of jobs using a python comprehension - -turn_on_datas = [ - SshJob( node = node, - command = Run("turn-on-data"), - required = push_job, - scheduler = scheduler, - ) for node in nodes ] - -########## next : run a sender on node1 and a receiver on node 2 -# in order to transfer RANDOM over a netcat session on the data network - -# a Sequence object is a container for jobs, they will have their -# 'required' relationship organized along the sequence order - -transfer_job = Sequence( - - # start the receiver - this of course returns immediately - SshJob( - node = node2, - commands = [ - Run("netcat", "-l", "data02", netcat_port, ">", "RANDOM", "&"), - ], - ), - - # start the sender - SshJob( - node = node1, - # ignore netcat result - critical = False, - commands = [ - # let the server warm up just in case - Run("sleep 1"), - Run("netcat", "data02", netcat_port, "<", "RANDOM"), - Run("echo SENDER DONE"), - ], - ), - - # check contents on the receiving end - SshJob( - node=node2, - commands = [ - Run("ls -l RANDOM"), - Run("sha1sum RANDOM"), - ], - ), - - ### these two apply to the Sequence - # required applies to the first job in the sequence - required = turn_on_datas, - # scheduler applies to all jobs in the sequence - scheduler = scheduler, -) - -########## -# run the scheduler -ok = scheduler.orchestrate() - -# give details if it failed -ok or scheduler.debrief() - -# producing a dot file for illustration -scheduler.export_as_dotfile("C2.dot") - -# return something useful to your OS -exit(0 if ok else 1) From 95e0938eebf41163cac125aaf138fdae6f81ac66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Wed, 31 Aug 2022 13:39:35 +0200 Subject: [PATCH 15/16] Corrected inacurrate information --- code/C1-files.py | 2 +- code/C2-files.py | 2 +- code/C3-files.py | 2 +- markdown/tuto-020-shell-tools.md | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/C1-files.py b/code/C1-files.py index 9c3d01e6..1a27db88 100755 --- a/code/C1-files.py +++ b/code/C1-files.py @@ -14,7 +14,7 @@ ########## gateway_hostname = 'faraday.inria.fr' -gateway_username = 'root' +gateway_username = 'inria_r2lab.tutorial' verbose_ssh = False random_size = 2**10 diff --git a/code/C2-files.py b/code/C2-files.py index b110f507..d82dadbc 100755 --- a/code/C2-files.py +++ b/code/C2-files.py @@ -14,7 +14,7 @@ ########## gateway_hostname = 'faraday.inria.fr' -gateway_username = 'root' +gateway_username = 'inria_r2lab.tutorial' verbose_ssh = False random_size = 2**10 netcat_port = 10000 diff --git a/code/C3-files.py b/code/C3-files.py index 526682b2..2e8a3f8e 100755 --- a/code/C3-files.py +++ b/code/C3-files.py @@ -14,7 +14,7 @@ ########## gateway_hostname = 'faraday.inria.fr' -gateway_username = 'root' +gateway_username = 'inria_r2lab.tutorial' verbose_ssh = False random_size = 2**10 netcat_port = 10000 diff --git a/markdown/tuto-020-shell-tools.md b/markdown/tuto-020-shell-tools.md index 81caa163..2f1b20a6 100644 --- a/markdown/tuto-020-shell-tools.md +++ b/markdown/tuto-020-shell-tools.md @@ -252,9 +252,9 @@ You can run a command on all selected nodes with this time of course, you cannot specify another set of nodes than the selection. -If you want to directly access a Bash prompt **inside a Docker container** please choose the username `container`, like this : +If you want to directly access a Bash prompt **inside a Docker container** please connect through port `2222`, like this : - ssh container@fit25 + ssh -p 2222 root@fit25 ### Saving images From 1a3825591b0d5b09ffc2d3073ee7c2c6742c8367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9o=20Ha=C3=BFs?= Date: Wed, 31 Aug 2022 13:47:07 +0200 Subject: [PATCH 16/16] Corrected some errors in the tutorials --- markdown/tuto-020-shell-tools.md | 14 +++++++------- markdown/tuto-040-A-ping.md | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/markdown/tuto-020-shell-tools.md b/markdown/tuto-020-shell-tools.md index 2f1b20a6..2c53f5b0 100644 --- a/markdown/tuto-020-shell-tools.md +++ b/markdown/tuto-020-shell-tools.md @@ -266,12 +266,6 @@ This ends up in the common repository `/var/lib/rhubarbe-images`, under a name t Images that may be of common interest usually needto be renamed; get in touch with the admins if you need to do this. -### Saving Docker images - -If you want to save a Docker container that you may have modified from its base image, you can use the [baleine save](https://github.com/haysberg/baleine/wiki/Save-a-custom-container) command. - - baleine save --node 1 --name mycustomimage:1.0 - @@ -311,10 +305,16 @@ baleine deploy --image faraday.repo/tutorial --nodes 1 2 --options -t -d The `deploy` subcommand allows you to pull and deploy the docker image selected with `--image` on the nodes selected with `--nodes`. The `--options` option allows you to give an array of argument to pass directly to the Docker Runtime. -The `faraday.repo/tutorial` image is based on Ubuntu, so the `-t` and `-d` options are necessary for the Docker image to continue running. +The `faraday.repo/tutorial` docker image is based on Ubuntu, so the `-t` and `-d` options are necessary for the Docker image to continue running after initial launch. To use the Docker container as your server to run the tutorials, please use port `2222` for SSH as `22` is reserved for the host OS. +### Saving Docker images + +If you want to save a Docker container that you may have modified from its base image, you can use the [baleine save](https://github.com/haysberg/baleine/wiki/Save-a-custom-container) command. + + baleine save --node 1 --name mycustomimage:1.0 + [Check out the wiki](https://github.com/haysberg/baleine/wiki) for exhaustive information on the different commands and options available. diff --git a/markdown/tuto-040-A-ping.md b/markdown/tuto-040-A-ping.md index 8e110343..1a30959b 100644 --- a/markdown/tuto-040-A-ping.md +++ b/markdown/tuto-040-A-ping.md @@ -87,7 +87,7 @@ explained [in the previous tutorial](tuto-020-shell-tools.md): # select nodes 1 and 2 n 1 2 # load the default image (on the selected nodes) - rload baleine + rload -i baleine # wait for ssh to be up (still on the selected nodes) rwait