2 # NEPI, a framework to manage network experiments
3 # Copyright (C) 2013 INRIA
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;
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.
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/>.
17 # Authors: Alina Quereilhac <alina.quereilhac@inria.fr>
18 # Julien Tribino <julien.tribino@inria.fr>
21 from nepi.execution.attribute import Attribute, Flags, Types
22 from nepi.execution.resource import ResourceManager, clsinit_copy, \
25 #clsinit_copy is used to inherit attributes from the parent class
27 class RMClass(ResourceManager):
28 # Name that will be used in the NEPI script to identify the resource type
29 _rtype = "platform::RMType"
30 # User friendly description of the RM
31 _help = "Describes what this RM does"
32 # Name of the platform this RM belongs to
33 _platform = "platform"
34 # list of valid connection for this RM
35 _authorized_connections = ["platform::AnotherRMType1" , "platform::AnotherRMType2"]
38 def _register_attributes(cls):
40 This method is used to register all the attribute of this RM. Check the
41 file src/execution/attribute.py to see all the fields of this class
44 attribute1 = Attribute("nameOfAttribute1", "Description of Attribute 1",
47 attribute2 = Attribute("nameOfAttribute2", "Description of Attribute 2",
50 cls._register_attribute(attribute1)
51 cls._register_attribute(attribute2)
53 def __init__(self, ec, guid):
55 Declares and initializes variables of the RM that are not Attributes.
56 Attributes represent resource configuration exposed to the user,
57 other class variables can declared here for RM internal use.
60 super(RMClass, self).__init__(ec, guid)
62 def log_message(self, msg):
64 Prints a log message adding a identification prefix.
66 The log message for the RMClass can be redefined here.
67 It can be used to add information about related resources such as
68 the hostname of the node RM associated to an application RM.
71 return " %s guid %d - %s " % (self._rtype, self.guid, msg)
73 def valid_connection(self, guid):
75 Checks whether the RMClass instance can be connected to the
76 other RM corresponding to the given guid.
79 rm = self.ec.get_resource(guid)
81 if rm.get_rtype() not in self._authorized_connections:
82 msg = ("Connection between %s %s and %s %s refused: "
83 "An Application can be connected only to a Node" ) % \
84 (self.get_rtype(), self._guid, rm.get_rtype(), guid)
88 elif len(self.connections) != 0 :
89 msg = ("Connection between %s %s and %s %s refused: "
90 "This Application is already connected" ) % \
91 (self.get_rtype(), self._guid, rm.get_rtype(), guid)
98 def do_discover(self):
100 Perform actions required to discover resources matching some criteria
101 specified by the user through the configuration of Attributes.
104 super(RMClass, self).do_discover()
106 def do_reserve(self):
108 Perform actions required to reserve resources matching some criteria
109 specified by the user through the configuration of Attributes.
112 super(RMClass, self).do_reserve()
114 def do_provision(self):
116 Perform actions required to provision a resource in the platform,
117 matching the criteria specified by the user.
120 super(RMClass, self).do_provision()
124 Perform actions required to deploy a resource in the platform.
126 Deploying a resource most frequently involves invoking the
127 do_discover and do_provision methods. In order to deploy a
128 resource it might be necessary wait until other associated
129 resource is in a given state, as in the following example:
131 other_rm_list = self.get_connected(OtherRMClass.get_rtype())
132 other_rm = other_rm_list[0]
134 if other_rm.state < ResourceState.READY:
135 self.ec.schedule(self.reschedule_delay, self.deploy)
137 elif other_rm.state == ResourceState.FAILED:
138 msg = "Failed to deploy resource"
140 raise RuntimeError(msg)
146 super(RMClass, self).do_deploy()
150 super(RMClass, self).do_deploy()
154 Perform actions required to start a resource in the platform.
157 super(RMClass, self).do_start()
161 Perform actions required to stop a resource in the platform.
164 super(RMClass, self).do_stop()
166 def do_release(self):
168 Perform actions required to release a resource in the platform.
171 super(RMClass, self).do_release()
176 Returns the state of the RM.
178 The state method should never raise an exception, instead if an
179 error occurs it should log the error and invoke the self.do_fail
182 self.error(msg, out, err)
186 return super(RMClass, self).state