3 # NEPI, a framework to manage network experiments
4 # Copyright (C) 2013 INRIA
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 # Author: Lucia Guevgeozian <lucia.guevgeozian_odizzio@inria.fr>
21 # Example of how to run this experiment (replace with your information):
24 # python examples/planetlab/ping_with_filters.py -s <pl-slice> -u <pl-user> -p <pl-password> -k <pl-ssh-key>
26 from nepi.execution.ec import ExperimentController
27 from nepi.execution.resource import ResourceAction, ResourceState
29 from optparse import OptionParser
33 def create_node(ec, pl_slice, pl_ssh_key, pl_user, pl_password,
34 hostname = None, country = None, operatingSystem = None,
35 minBandwidth = None, minCpu = None):
37 node = ec.register_resource("planetlab::Node")
39 ec.set(node, "username", pl_slice)
40 ec.set(node, "identity", pl_ssh_key)
41 ec.set(node, "pluser", pl_user)
42 ec.set(node, "plpassword", pl_password)
45 ec.set(node, "hostname", hostname)
47 ec.set(node, "country", country)
49 ec.set(node, "operatingSystem", operatingSystem)
51 ec.set(node, "minBandwidth", minBandwidth)
53 ec.set(node, "minCpu", minCpu)
55 ec.set(node, "cleanExperiment", True)
56 ec.set(node, "cleanProcesses", True)
60 def add_app(ec, command, node, newname = None, sudo = None,
61 video = None, depends = None, forward_x11 = None, env = None):
62 app = ec.register_resource("linux::Application")
65 ec.set(app, "sudo", sudo)
67 ec.set(app, "sources", video)
68 if depends is not None:
69 ec.set(app, "depends", depends)
70 if forward_x11 is not None:
71 ec.set(app, "forwardX11", forward_x11)
73 ec.set(app, "env", env)
75 ec.set(app, "command", command)
77 ec.register_connection(app, node)
79 # add collector to download application standar output
80 collector = ec.register_resource("Collector")
81 ec.set(collector, "traceName", "stdout")
83 ec.set(collector, "rename", newname)
84 ec.register_connection(app, collector)
88 usage = ("usage: %prog -s <pl-slice> -u <pl-user> -p <pl-password> "
89 "-k <pl-ssh-key> -c <country> -o <operating-system> -H <hostname> ")
91 parser = OptionParser(usage = usage)
92 parser.add_option("-s", "--pl-slice", dest="pl_slice",
93 help="PlanetLab slicename", type="str")
94 parser.add_option("-u", "--pl-user", dest="pl_user",
95 help="PlanetLab web username", type="str")
96 parser.add_option("-p", "--pl-password", dest="pl_password",
97 help="PlanetLab web password", type="str")
98 parser.add_option("-k", "--pl-ssh-key", dest="pl_ssh_key",
99 help="Path to private SSH key associated with the PL account",
101 parser.add_option("-c", "--country", dest="country",
102 help="Country for the PL hosts",
104 parser.add_option("-o", "--os", dest="os",
105 help="Operating system for the PL hosts", default="f14",
107 parser.add_option("-H", "--hostname", dest="hostname",
108 help="PlanetLab hostname",
111 (options, args) = parser.parse_args()
113 pl_slice = options.pl_slice
114 pl_ssh_key = options.pl_ssh_key
115 pl_user = options.pl_user
116 pl_password = options.pl_password
117 hostname = options.hostname
118 country = options.country
121 # Create the entity Experiment Controller:
122 ec = ExperimentController("pl_ping_filters")
124 # Register the nodes resources:
126 # Choose the PlanetLab nodes for the experiment, in this example 5 nodes are
127 # used, and they are picked according to different criterias.
129 # First node will be the one defined by its hostname.
130 node1 = create_node(ec, pl_slice, pl_ssh_key, pl_user, pl_password,
133 # Second node will be any node in the selected country.
134 node2 = create_node(ec, pl_slice, pl_ssh_key, pl_user, pl_password,
137 # Third node will be a node in the selected country and with the selected
139 node3 = create_node(ec, pl_slice, pl_ssh_key, pl_user, pl_password,
141 operatingSystem = os)
143 # Forth node will have at least 50% of CPU available
145 node4 = create_node(ec, pl_slice, pl_ssh_key, pl_user, pl_password,
148 # Fifth node can be any node, constrains are not important.
149 node5 = create_node(ec, pl_slice, pl_ssh_key, pl_user, pl_password)
151 # Register the applications to run in the nodes, in this case just ping to the
154 for node in [node2, node3, node4, node5]:
155 command = "ping -c5 %s" % hostname
156 trace_name = "%s.ping" % hostname
157 app = add_app(ec, command, node, newname = trace_name)
160 # Register conditions
162 # The nodes that are completely identified by their hostnames have to be provisioned
163 # before the rest of the nodes. This assures that no other resource will use the
164 # identified node even if the constraints matchs.
165 # In this example node2, node3, node4 and node5, are deployed after node1 is
166 # provisioned. node1 must be the node hostname, meanwhile node2, node3,
167 # node4 and node5 just need to fulfill certain constraints.
168 # Applications are always deployed after nodes, so no need to register conditions
169 # for the apps in this example.
171 ec.register_condition(node2, ResourceAction.DEPLOY, node1, ResourceState.PROVISIONED)
172 ec.register_condition(node3, ResourceAction.DEPLOY, node1, ResourceState.PROVISIONED)
173 ec.register_condition(node4, ResourceAction.DEPLOY, node1, ResourceState.PROVISIONED)
174 ec.register_condition(node5, ResourceAction.DEPLOY, node1, ResourceState.PROVISIONED)
176 # Deploy the experiment:
179 # Wait until the applications are finish to retrive the traces:
180 ec.wait_finished(apps)
182 print "Results stored at", ec.exp_dir
184 # Do the experiment controller shutdown: