applied the except and raise fixers to the master branch to close the gap with py3
[nepi.git] / src / nepi / resources / planetlab / vroute.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 version 2 as
7 #    published by the Free Software Foundation;
8 #
9 #    This program is distributed in the hope that it will be useful,
10 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 #    GNU General Public License for more details.
13 #
14 #    You should have received a copy of the GNU General Public License
15 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 #
17 # Author: Alina Quereilhac <alina.quereilhac@inria.fr>
18
19 from nepi.execution.attribute import Attribute, Flags, Types
20 from nepi.execution.resource import clsinit_copy, ResourceState 
21 from nepi.resources.linux.application import LinuxApplication
22 from nepi.resources.planetlab.node import PlanetlabNode
23 from nepi.resources.planetlab.tap import PlanetlabTap
24 from nepi.util.timefuncs import tnow, tdiffsec
25
26 import os
27 import time
28
29 PYTHON_VSYS_VERSION = "1.0"
30
31 @clsinit_copy
32 class PlanetlabVroute(LinuxApplication):
33     _rtype = "planetlab::Vroute"
34     _help = "Creates a Vroute on a PlanetLab host"
35     _platform = "planetlab"
36
37     @classmethod
38     def _register_attributes(cls):
39         action = Attribute("action", "Either add or del",
40               allowed = ["add", "del"],
41               default = "add",
42               flags = Flags.Design)
43
44         prefix = Attribute("prefix", "IPv4 Prefix",
45               flags = Flags.Design)
46
47         nexthop = Attribute("nexthop", "IPv4 Address of the next hop",
48               flags = Flags.Design)
49
50         network = Attribute("network", "IPv4 Network Address",
51               flags = Flags.Design)
52
53         cls._register_attribute(action)
54         cls._register_attribute(prefix)
55         cls._register_attribute(nexthop)
56         cls._register_attribute(network)
57
58     def __init__(self, ec, guid):
59         super(PlanetlabVroute, self).__init__(ec, guid)
60         self._home = "vroute-%s" % self.guid
61
62     @property
63     def tap(self):
64         tap = self.get_connected(PlanetlabTap.get_rtype())
65         if tap: return tap[0]
66         return None
67
68     @property
69     def node(self):
70         node = self.tap.get_connected(PlanetlabNode.get_rtype())
71         if node: return node[0]
72         return None
73
74     def upload_sources(self):
75         # upload vif-creation python script
76         pl_vroute = os.path.join(os.path.dirname(__file__), 
77                 "scripts",
78                 "pl-vroute.py")
79
80         self.node.upload(pl_vroute,
81                 os.path.join(self.node.src_dir, "pl-vroute.py"),
82                 overwrite = False)
83
84         # upload stop.sh script
85         stop_command = self.replace_paths(self._stop_command)
86         self.node.upload(stop_command,
87                 os.path.join(self.app_home, "stop.sh"),
88                 text = True,
89                 # Overwrite file every time. 
90                 # The stop.sh has the path to the socket, wich should change
91                 # on every experiment run.
92                 overwrite = True)
93
94     def upload_start_command(self):
95         # Overwrite file every time. 
96         # The stop.sh has the path to the socket, wich should change
97         # on every experiment run.
98         command = self.get("command")
99         shfile = os.path.join(self.app_home, "start.sh")
100         self.node.run_and_wait(command, self.run_home,
101                 shfile=shfile,
102                 overwrite=True)
103   
104     def do_deploy(self):
105         if not self.tap or self.tap.state < ResourceState.PROVISIONED:
106             self.ec.schedule(self.reschedule_delay, self.deploy)
107         else:
108             if not self.get("command"):
109                 self.set("command", self._start_command)
110
111             self.do_discover()
112             self.do_provision()
113
114             self.debug("----- READY ---- ")
115             self.set_ready()
116
117     def do_start(self):
118         if self.state == ResourceState.READY:
119             command = self.get("command")
120             self.info("Starting command '%s'" % command)
121
122             # Vroute started during deployment
123             self.set_started()
124         else:
125             msg = " Failed to execute command '%s'" % command
126             self.error(msg, out, err)
127             raise RuntimeError(msg)
128
129     def do_stop(self):
130
131         command = self.get('command') or ''
132
133         if self.state == ResourceState.STARTED:
134             self.info("Stopping command '%s'" % self._stop_command)
135
136             command = "bash %s" % os.path.join(self.app_home, "stop.sh")
137             (out, err), proc = self.execute_command(command,
138                     blocking = True)
139
140             self.set_stopped()
141
142     def do_release(self):
143         # Node needs to wait until all associated RMs are released
144         # to be released
145         if not self.get("tearDown"):
146             self.set("tearDown", self._tear_down_command())
147
148         super(PlanetlabVroute, self).do_release()
149
150     def _tear_down_command(self):
151         if self.get("action") == "del":
152             return
153
154         return self._stop_command
155
156     @property
157     def _start_command(self):
158         command = ["sudo -S python ${SRC}/pl-vroute.py"]
159         command.append("-a %s" % self.get("action"))
160         command.append("-n %s" % self.get("network"))
161         command.append("-p %s" % self.get("prefix"))
162         command.append("-g %s" % self.tap.get("pointopoint"))
163         command.append("-f %s" % self.tap.get("deviceName"))
164         command = " ".join(command)
165
166         command = self.replace_paths(command)
167         return command
168
169     @property
170     def _stop_command(self):
171         command = ["sudo -S python ${SRC}/pl-vroute.py"]
172         command.append("-a %s" % "del")
173         command.append("-n %s" % self.get("network"))
174         command.append("-p %s" % self.get("prefix"))
175         command.append("-g %s" % self.get("nexthop"))
176         command.append("-f %s" % self.tap.get("deviceName"))
177         command = " ".join(command)
178         
179         command = self.replace_paths(command)
180         return command
181
182     def valid_connection(self, guid):
183         # TODO: Validate!
184         return True
185