updating user manual
[nepi.git] / doc / user_manual / getting_started.tex
1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 %
3 %    NEPI, a framework to manage network experiments
4 %    Copyright (C) 2013 INRIA
5 %
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.
10 %
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.
15 %
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/>.
18 %
19 % Author: Alina Quereilhac <alina.quereilhac@inria.fr>
20 %
21 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22
23 NEPI is written in Python, so you will need to install Python before 
24 being able to run experiments with NEPI. 
25 NEPI is known to work on Linux (Fedore, Debian, Ubuntu) and Mac (OS X).
26
27 \section{Dependencies}
28
29 Dependencies for NEPI vary according to the features you want to enable.
30 Make sure the following dependencies are correctly installed in your system
31 before using NEPI. \\
32
33 Mandatory dependencies:
34 \begin{itemize}
35     \item Python 2.6+
36     \item Mercurial
37     \item python-ipaddr
38     \item python-networkx
39     \item python-pygraphviz
40     \item python-matplotlib 
41 \end{itemize}
42
43 Optional dependencies:
44 \begin{itemize}
45     \item SleekXMPP - Required to run experiments on OMF testbeds
46 \end{itemize}
47
48 \subsection{Install dependencies on Debian/Ubuntu}
49
50 \begingroup
51     \fontsize{10pt}{12pt}\selectfont
52
53 \begin{verbatim}
54     $ sudo apt-get -y install python mercurial python-ipaddr python-networkx python-pygraphviz python-matplotlib
55 \end{verbatim}
56
57 \endgroup
58
59 \subsection{Install dependencies on Fedora}
60
61 \begingroup
62     \fontsize{10pt}{12pt}\selectfont
63
64 \begin{verbatim}
65     $ sudo yum -y install python mercurial python-ipaddr python-networkx graphviz-python python-matplotlib
66 \end{verbatim}
67
68 \endgroup
69
70 \subsection{Install dependencies on Mac}
71
72 First install homebrew (\url{http://mxcl.github.io/homebrew/}),
73 then you can install Python and the rest of the dependencies as follows:
74
75 \begingroup
76     \fontsize{10pt}{12pt}\selectfont
77
78 \begin{verbatim}
79    $ brew install python
80    $ sudo port install mercurial
81    $ sudo easy_install pip
82    $ sudo pip install ipaddr
83    $ sudo pip install networkx
84    $ sudo  pip install pygraphviz
85    $ sudo  pip install matplotlib
86 \end{verbatim}
87
88 \endgroup
89
90 To use Python you will need to set the PATH environmental variable as:
91
92 \begingroup
93     \fontsize{10pt}{12pt}\selectfont
94
95 \begin{verbatim}
96    $ export PATH=$PATH:/usr/local/share/python
97 \end{verbatim}
98
99 \endgroup
100
101 \subsection{Install SleekXMPP}
102
103 You will need \textit{git} to get the SleekXMPP sources.
104
105 \begingroup
106     \fontsize{10pt}{12pt}\selectfont
107
108 \begin{verbatim}
109     $ git clone -b develop git://github.com/fritzy/SleekXMPP.git
110     $ cd SleekXMPP
111     $ sudo python setup.py install
112 \end{verbatim}
113
114 \endgroup
115
116 \section{The source code}
117
118 To get NEPI's source code you will need Mercurial version 
119 control system. The Mercurial NEPI repo can also be browsed online at: \\
120
121 \url{http://nepi.inria.fr/code/nepi/} 
122
123 \subsection{Clone the repo}
124
125 \begingroup
126     \fontsize{10pt}{12pt}\selectfont
127
128 \begin{verbatim}
129 $ hg clone http://nepi.inria.fr/code/nepi -r nepi-3-dev
130 \end{verbatim}
131
132 \endgroup
133
134 \section{Install NEPI in your system}
135
136 You don't need to install NEPI in your system to be able to run 
137 experiments. However this might be convenient if you don't 
138 plan to modify or extend the sources.
139
140 To install NEPI, just run \emph{make install} in the NEPI source
141 folder.
142
143 \begingroup
144     \fontsize{10pt}{12pt}\selectfont
145
146 \begin{verbatim}
147     $ cd nepi
148     $ make install 
149 \end{verbatim}
150
151 \endgroup
152
153 If you are developing your own NEPI extensions, the installed 
154 NEPI version might interfere with your work.
155 In this case it is probably more convenient to tell
156 Python where to find the NEPI sources, using the PYTHONPATH
157 environmental variable, when you run a NEPI script.
158
159 \begingroup
160     \fontsize{10pt}{12pt}\selectfont
161
162 \begin{verbatim}
163     $ export PYTHONPATH=$PYTHONPATH:<path-to-nepi>/src 
164 \end{verbatim}
165
166 \endgroup
167
168 \section{Run experiments}
169
170 There are two ways you can use NEPI to run your experiments.
171 The first one is writing a Python script, which will import
172 NEPI libraries, and run it. 
173 The second one is in interactive mode by using Python console.
174
175 \subsection{Run from script}
176
177 Writing a simple NEPI expeiment script is easy.
178 Take a look at the example in the FAQ section \ref{faq:ping_example}.
179 Once you have written down the script, you can run it using
180 Python. If NEPI is not installed in your system,
181 you will need to export the path to NEPI's source code to 
182 the PYTHONPATH environment variable, so that Python can find
183 NEPI's libraries.
184
185 \begingroup
186     \fontsize{10pt}{12pt}\selectfont
187
188 \begin{verbatim}
189     $ export PYTHONPATH=<path-to-nepi>/src:$PYTHONPATH
190     $ cd <path-to-nepi> 
191     $ python examples/linux/ping.py -a localhost
192 \end{verbatim}
193
194 \endgroup
195
196 \subsection{Run NEPI interactively}
197
198 The IPython console can be used as an interactive interpreter to 
199 execute Python instructions. We can take advantage of this feature, 
200 to interactively run NEPI experiments. 
201 We will use the IPython console for the example below. 
202
203 You can easily install IPython on Debian, Ubuntu, Fedora or Mac as follows:\\
204
205 \textbf{Debian/Ubuntu}
206
207 \begingroup
208     \fontsize{10pt}{12pt}\selectfont
209
210 \begin{verbatim}
211     $ sudo apt-get install ipython
212 \end{verbatim}
213
214 \endgroup
215
216 \textbf{Fedora}\\
217
218 \begingroup
219     \fontsize{10pt}{12pt}\selectfont
220
221 \begin{verbatim}
222     $ sudo yum install ipython
223 \end{verbatim}
224
225 \endgroup
226
227 \textbf{Mac}\\
228
229 \begingroup
230     \fontsize{10pt}{12pt}\selectfont
231
232 \begin{verbatim}
233     $ pip install ipython
234 \end{verbatim}
235
236 \endgroup
237
238 Before starting, make sure to add Python and IPython source directory 
239 path to the PYTHONPATH environment variable
240
241 \begingroup
242     \fontsize{10pt}{12pt}\selectfont
243
244 \begin{verbatim}
245     $ export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python:/usr/local/share/python/ipython
246 \end{verbatim}
247
248 \endgroup
249
250 Then you can start IPython as follows: 
251
252 \begin{verbatim}
253 $ export PYTHONPATH=<path-to-nepi>/src:$PYTHONPATH
254 $ ipython
255 Python 2.7.3 (default, Jan  2 2013, 13:56:14) 
256 Type "copyright", "credits" or "license" for more information.
257
258 IPython 0.13.1 -- An enhanced Interactive Python.
259 ?         -> Introduction and overview of IPython's features.
260 %quickref -> Quick reference.
261 help      -> Python's own help system.
262 object?   -> Details about 'object', use 'object??' for extra details.
263
264 \end{verbatim}
265
266 If you want to paste many lines at once in IPython, you will need 
267 to type \emph{\%cpaste} and finish the paste block with \emph{\-\-}.
268
269 The first thing we need to do to describe an experiment with NEPI 
270 is to import the NEPI Python modules. 
271 In particular we need to import the ExperimentController class. 
272 To do this type the following in the Python console: 
273
274 \begin{lstlisting}[language=Python]
275
276 from nepi.execution.ec import ExperimentController
277
278 \end{lstlisting}
279
280 After importing the ExperimentController class, it is possible to 
281 create a new instance of an the ExperimentController (EC) for 
282 your experiment. 
283 The <exp-id> argument is the name you want to give the experiment 
284 to identify it and distinguish it from other experiments. 
285
286 \begin{lstlisting}[language=Python]
287
288 ec = ExperimentController(exp_id = "<your-exp-id>")
289
290 \end{lstlisting}
291
292 Next we will define two Python functions: \emph{add\_node} and \emph{add\_app}.
293 The first one to register \textit{LinuxNodes} resources and the second one to 
294 register LinuxApplications resources. 
295
296 \begin{lstlisting}[language=Python]
297
298 %cpaste
299 def add_node(ec, hostname, username, ssh_key):
300     node = ec.register_resource("LinuxNode")
301     ec.set(node, "hostname", hostname)
302     ec.set(node, "username", username)
303     ec.set(node, "identity", ssh_key)
304     ec.set(node, "cleanHome", True)
305     ec.set(node, "cleanProcesses", True)
306     return node
307
308 def add_app(ec, command, node):
309     app = ec.register_resource("LinuxApplication")
310     ec.set(app, "command", command)
311     ec.register_connection(app, node)
312     return app
313 --
314
315 \end{lstlisting}
316
317 The method \textit{register\_resource} registers a resource instance with the 
318 ExperimentController. The method \textit{register\_connection} indicates
319 that two resources will interact during the experiment. 
320 Note that invoking \textit{add\_node} or \textit{add\_app} has no effect other
321 than informing the EC about the resources that will be used during the experiment.
322 The actual deployment of the experiment requires the method \textit{deploy} to
323 be invoked.
324
325 The \textit{LinuxNode} resource exposes the hostname, username and identity 
326 attributes. This attributes provide information about the SSH credentials 
327 needed to log in to the Linux host. 
328 The \textit{hostname} is the one that identifies the physical host you want
329 to access during the experiment. The \textit{username} must correspond to a
330 valid account on that host, and the \textit{identity} attribute is the 
331 'absolute' path to the SSH private key in your local computer that allows you 
332 to log in to the host.
333
334 The \textit{command} attribute of the \textit{LinuxApplication} resource 
335 expects a BASH command line string to be executed in the remote host.
336 Apart from the \emph{command} attribute, the \emph{LinuxApplication} 
337 resource exposes several other attributes that allow to upload, 
338 compile and install arbitrary sources. 
339 The add\_app function registers a connection between a \textit{LinuxNode} and a 
340 \textit{LinuxApplication}. 
341
342 Lets now use these functions to describe a simple experiment. 
343 Choose a host where you have an account, and can access using SSH
344 key authentication. 
345
346 \begin{lstlisting}[language=Python]
347
348 hostname = "<the-hostname>"
349 username = "<my-username>"
350 identity = "</home/myuser/.ssh/id_rsa>"
351
352 node = add_node(ec, hostname, username, ssh_key)
353 app = add_app(ec, "ping -c3 nepi.inria.fr",  node)
354
355 \end{lstlisting}
356
357 The values returned by the functions add\_node and add\_app are global 
358 unique identifiers (guid) of the resources that were registered with the EC. 
359 The guid is used to reference the ResourceManager associated to a registered
360 resource (for instance to retrieve results or change attribute values).
361
362 Now that we have registered some resources, we can ask the ExperimentController
363 (EC) to deploy them. 
364 Invoking the \emph{deploy} command will not only configure the 
365 resource but also automatically launch the applications.
366
367 \begin{lstlisting}[language=Python]
368
369  ec.deploy()
370
371 \end{lstlisting}
372
373 After some seconds, we should see some output messages informing us about the
374 progress in the host deployment.
375 If you now open another terminal and you connect to the host using 
376 SSH (as indicated below), you should see that a directory for your experiment 
377 has been created in the host. In the remote host you will see that two NEPI 
378 directories were created in the \$HOME directory: \emph{nepi-src} and \emph{nepi-exp}. 
379 The first one is where NEPI will store files that might be re used by many 
380 experiments (e.g. source code, input files) . The second directory \emph{nepi-exp}, 
381 is where experiment specific files (e.g. results, deployment scripts) will be stored. 
382
383 \begingroup
384     \fontsize{10pt}{12pt}\selectfont
385
386 \begin{verbatim}
387
388 $ ssh -i identity username@hostname
389
390 \end{verbatim}
391
392 \endgroup
393
394 Inside the \emph{nepi-exp} directory, you will find another directory with 
395 the <exp-id> assigned to your EC, and inside that directory you should find 
396 one directory named node-1 which will contain the files (e.g. result traces) 
397 associated to the LinuxNode reosurce you just deployed. 
398 In fact for every resource deployed associated to that host (e.g. each 
399 LinuxApplication), NEPI will create a directory to place files related to it. 
400 The name of the directory identifies the type of resources (e.g. 'node', 
401 'app', etc) and it is followed by the global unique identifier (guid).
402
403 We can see if a resource finished deploying by querying its state through the EC 
404
405 \begin{lstlisting}[language=Python]
406
407 ec.state(app, hr=True)
408
409 \end{lstlisting}
410
411 Once a \textit{LinuxApplication} has reached the state 'STARTED', 
412 we can retrieve the 'stdout' trace, which should contain the output 
413 of the PING command. 
414
415 \begin{lstlisting}[language=Python]
416
417  ec.trace(app, "stdout")
418
419 \end{lstlisting}
420
421 That is it. We can terminate the experiment by invoking the method \emph{shutdown}.
422
423 \begin{lstlisting}[language=Python]
424
425  ec.shutdown()
426
427 \end{lstlisting}
428
429 \subsection{Define a workflow}
430
431 Now that we have introduced to the basics of NEPI, we will register 
432 two more applications and define a workflow where one application 
433 will start after the other one has finished executing. 
434 For this we will use the EC \textit{register\_condition} method described below:
435
436 \begin{lstlisting}[language=Python]
437
438 register_condition(self, guids1, action, guids2, state, time=None):
439     Registers an action START, STOP or DEPLOY for all RM on list
440     guids1 to occur at time 'time' after all elements in list guids2 
441     have reached state 'state'.
442     
443         :param guids1: List of guids of RMs subjected to action
444         :type guids1: list
445     
446         :param action: Action to perform (either START, STOP or DEPLOY)
447         :type action: ResourceAction
448     
449         :param guids2: List of guids of RMs to we waited for
450         :type guids2: list
451     
452         :param state: State to wait for on RMs of list guids2 (STARTED,
453             STOPPED, etc)
454         :type state: ResourceState
455     
456         :param time: Time to wait after guids2 has reached status 
457         :type time: string
458
459 \end{lstlisting}
460
461 To use the \textit{register\_condition} method we will need to import the 
462 ResourceState and the ResourceAction classes
463
464 \begin{lstlisting}[language=Python]
465
466 from nepi.execution.resource import ResourceState, ResourceAction
467
468 \end{lstlisting}
469
470 Then, we register the two applications. The first application will 
471 wait for 5 seconds and the create a file in the host called "greetings" 
472 with the content "HELLO WORLD". 
473 The second application will read the content of the file and output it 
474 to standard output. If the file doesn't exist il will instead output the 
475 string "FAILED".
476
477 \begin{lstlisting}[language=Python]
478
479 app1 = add_app(ec, "sleep 5; echo 'HELLO WORLD!' > ~/greetings", node)
480 app2 = add_app(ec, "cat ~/greetings || echo 'FAILED'", node)
481
482 \end{lstlisting}
483
484 In order to guarantee that the second application is successful, we need to 
485 make sure that the first application is executed first. For this we register 
486 a condition:
487
488 \begin{lstlisting}[language=Python]
489
490 ec.register_condition (app2, ResourceAction.START, app1, ResourceState.STOPPED)
491
492 \end{lstlisting}
493
494 We then deploy the two application:
495
496 \begin{lstlisting}[language=Python]
497
498 ec.deploy(guids=[app1,app2])
499
500 \end{lstlisting}
501
502 Finally, we retrieve the standard output of the second application, 
503 which should return the string "HELLO WORLD!".
504
505 \begin{lstlisting}[language=Python]
506
507 ec.trace(app2, "stdout")
508
509 \end{lstlisting}
510