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