0291d03f209bfd3b73abf22676c4984cc2c97c0c
[nepi.git] / examples / linux / ccnx / vlc_2_hosts.py
1 #!/usr/bin/env python
2
3 #
4 #    NEPI, a framework to manage network experiments
5 #    Copyright (C) 2013 INRIA
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU General Public License as published by
9 #    the Free Software Foundation, either version 3 of the License, or
10 #    (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU General Public License for more details.
16 #
17 #    You should have received a copy of the GNU General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
21
22 from nepi.execution.ec import ExperimentController, ECState 
23 from nepi.execution.resource import ResourceState, ResourceAction, \
24         populate_factory
25
26 from optparse import OptionParser, SUPPRESS_HELP
27
28 import os
29 import time
30
31 def add_node(ec, host, user):
32     node = ec.register_resource("LinuxNode")
33     ec.set(node, "hostname", host)
34     ec.set(node, "username", user)
35     #ec.set(node, "cleanHome", True)
36     ec.set(node, "cleanProcesses", True)
37     return node
38
39 def add_ccnd(ec, os_type, peers):
40     if os_type == "f12":
41         depends = ( " autoconf openssl-devel  expat-devel libpcap-devel "
42                 " ecryptfs-utils-devel libxml2-devel automake gawk " 
43                 " gcc gcc-c++ git pcre-devel ")
44     elif os_type == "ubuntu":
45         depends = ( " autoconf libssl-dev libexpat-dev libpcap-dev "
46                 " libecryptfs0 libxml2-utils automake gawk gcc g++ "
47                 " git-core pkg-config libpcre3-dev ")
48
49     sources = "http://www.ccnx.org/releases/ccnx-0.7.1.tar.gz"
50
51     build = (
52         # Evaluate if ccnx binaries are already installed
53         " ( "
54             "  test -d ${EXP_HOME}/ccnx/bin"
55         " ) || ( "
56         # If not, untar and build
57             " ( "
58                 " mkdir -p ${SOURCES}/ccnx && "
59                 " tar xf ${SOURCES}/ccnx-0.7.1.tar.gz --strip-components=1 -C ${SOURCES}/ccnx "
60              " ) && "
61                 "cd ${SOURCES}/ccnx && "
62                 # Just execute and silence warnings...
63                 "(  ( ./configure && make )  2>&1 )"
64          " )") 
65
66     install = (
67         # Evaluate if ccnx binaries are already installed
68         " ( "
69             "  test -d ${EXP_HOME}/ccnx/bin "
70         " ) || ( "
71             "  mkdir -p ${EXP_HOME}/ccnx/bin && "
72             "  cp -r ${SOURCES}/ccnx ${EXP_HOME}"
73         " )"
74     )
75
76     env = "PATH=$PATH:${EXP_HOME}/ccnx/bin"
77
78     # BASH command -> ' ccndstart 2>&1 ; ccndc add ccnx:/ udp  host ;  ccnr 2>&1 '
79     command = "ccndstart 2>&1 ; "
80     peers = map(lambda peer: "ccndc add ccnx:/ udp  %s" % peer, peers)
81     command += " ; ".join(peers) + " ; "
82     command += " ccnr 2>&1 "
83
84     app = ec.register_resource("LinuxApplication")
85     ec.set(app, "depends", depends)
86     ec.set(app, "sources", sources)
87     ec.set(app, "install", install)
88     ec.set(app, "build", build)
89     ec.set(app, "env", env)
90     ec.set(app, "command", command)
91
92     return app
93
94 def add_publish(ec, movie):
95     env = "PATH=$PATH:${EXP_HOME}/ccnx/bin"
96     command = "ccnseqwriter -r ccnx:/VIDEO"
97
98     app = ec.register_resource("LinuxApplication")
99     ec.set(app, "stdin", movie)
100     ec.set(app, "env", env)
101     ec.set(app, "command", command)
102
103     return app
104
105 def add_stream(ec):
106     env = "PATH=$PATH:${EXP_HOME}/ccnx/bin"
107     command = "sudo -S dbus-uuidgen --ensure ; ( ccncat ccnx:/VIDEO | vlc - ) 2>&1"
108
109     app = ec.register_resource("LinuxApplication")
110     ec.set(app, "depends", "vlc")
111     ec.set(app, "forwardX11", True)
112     ec.set(app, "env", env)
113     ec.set(app, "command", command)
114
115     return app
116
117 def get_options():
118     slicename = os.environ.get("PL_SLICE")
119
120     usage = "usage: %prog -s <pl-slice> -u <user-2> -m <movie> -l <exp-id>"
121
122     parser = OptionParser(usage=usage)
123     parser.add_option("-s", "--pl-slice", dest="pl_slice", 
124             help="PlanetLab slicename", default=slicename, type="str")
125     parser.add_option("-u", "--user-2", dest="user2", 
126             help="User for non PlanetLab machine", type="str")
127     parser.add_option("-m", "--movie", dest="movie", 
128             help="Stream movie", type="str")
129     parser.add_option("-l", "--exp-id", dest="exp_id", 
130             help="Label to identify experiment", type="str")
131
132     (options, args) = parser.parse_args()
133
134     if not options.movie:
135         parser.error("movie is a required argument")
136
137     return (options.pl_slice, options.user2, options.movie, options.exp_id)
138
139 if __name__ == '__main__':
140     ( pl_slice, user2, movie, exp_id ) = get_options()
141
142     # Search for available RMs
143     populate_factory()
144     
145     host1 = 'planetlab2.u-strasbg.fr'
146     host2 = 'roseval.pl.sophia.inria.fr'
147
148     ec = ExperimentController(exp_id = exp_id)
149
150     node1 = add_node(ec, host1, pl_slice)
151     
152     peers = [host2]
153     ccnd1 = add_ccnd(ec, "f12", peers)
154
155     ec.register_connection(ccnd1, node1)
156
157     pub = add_publish(ec, movie)
158     ec.register_connection(pub, node1)
159
160     # The movie can only be published after ccnd is running
161     ec.register_condition(pub, ResourceAction.START, 
162             ccnd1, ResourceState.STARTED)
163     
164     node2 = add_node(ec, host2, user2)
165     peers = [host1]
166     ccnd2 = add_ccnd(ec, "ubuntu", peers)
167     ec.register_connection(ccnd2, node2)
168      
169     stream = add_stream(ec)
170     ec.register_connection(stream, node2)
171
172     # The stream can only be retrieved after ccnd is running
173     ec.register_condition(stream, ResourceAction.START, 
174             ccnd2, ResourceState.STARTED)
175
176     # And also, the stream can only be retrieved after it was published
177     ec.register_condition(stream, ResourceAction.START, 
178             pub, ResourceState.STARTED)
179  
180     ec.deploy()
181
182     apps = [ccnd1, pub, ccnd2, stream]
183     ec.wait_finished(apps)
184
185     ec.shutdown()
186