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 as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
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.
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/>.
18 # Authors: Alina Quereilhac <alina.quereilhac@inria.fr>
19 # Julien Tribino <julien.tribino@inria.fr>
22 from nepi.execution.attribute import Attribute, Flags, Types
23 from nepi.execution.resource import ResourceManager, clsinit_copy, \
26 #clsinit_copy is used to inherit attributes from the parent class
28 class RMClass(ResourceManager):
29 # Name that will be used in the NEPI script to identify the resource type
30 _rtype = "platform::RMType"
31 # User friendly description of the RM
32 _help = "Describes what this RM does"
33 # Name of the platform this RM belongs to
34 _platform = "platform"
35 # list of valid connection for this RM
36 _authorized_connections = ["platform::AnotherRMType1" , "platform::AnotherRMType2"]
39 def _register_attributes(cls):
41 This method is used to register all the attribute of this RM. Check the
42 file src/execution/attribute.py to see all the fields of this class
45 attribute1 = Attribute("nameOfAttribute1", "Description of Attribute 1",
48 attribute2 = Attribute("nameOfAttribute2", "Description of Attribute 2",
51 cls._register_attribute(attribute1)
52 cls._register_attribute(attribute2)
54 def __init__(self, ec, guid):
56 Declares and initializes variables of the RM that are not Attributes.
57 Attributes represent resource configuration exposed to the user,
58 other class variables can declared here for RM internal use.
61 super(RMClass, self).__init__(ec, guid)
63 def log_message(self, msg):
65 Prints a log message adding a identification prefix.
67 The log message for the RMClass can be redefined here.
68 It can be used to add information about related resources such as
69 the hostname of the node RM associated to an application RM.
72 return " %s guid %d - %s " % (self._rtype, self.guid, msg)
74 def valid_connection(self, guid):
76 Checks whether the RMClass instance can be connected to the
77 other RM corresponding to the given guid.
80 rm = self.ec.get_resource(guid)
82 if rm.get_rtype() not in self._authorized_connections:
83 msg = ("Connection between %s %s and %s %s refused: "
84 "An Application can be connected only to a Node" ) % \
85 (self.get_rtype(), self._guid, rm.get_rtype(), guid)
89 elif len(self.connections) != 0 :
90 msg = ("Connection between %s %s and %s %s refused: "
91 "This Application is already connected" ) % \
92 (self.get_rtype(), self._guid, rm.get_rtype(), guid)
99 def do_discover(self):
101 Perform actions required to discover resources matching some criteria
102 specified by the user through the configuration of Attributes.
105 super(RMClass, self).do_discover()
107 def do_reserve(self):
109 Perform actions required to reserve resources matching some criteria
110 specified by the user through the configuration of Attributes.
113 super(RMClass, self).do_reserve()
115 def do_provision(self):
117 Perform actions required to provision a resource in the platform,
118 matching the criteria specified by the user.
121 super(RMClass, self).do_provision()
125 Perform actions required to deploy a resource in the platform.
127 Deploying a resource most frequently involves invoking the
128 do_discover and do_provision methods. In order to deploy a
129 resource it might be necessary wait until other associated
130 resource is in a given state, as in the following example:
132 other_rm_list = self.get_connected(OtherRMClass.get_rtype())
133 other_rm = other_rm_list[0]
135 if other_rm.state < ResourceState.READY:
136 self.ec.schedule(self.reschedule_delay, self.deploy)
138 elif other_rm.state == ResourceState.FAILED:
139 msg = "Failed to deploy resource"
141 raise RuntimeError(msg)
147 super(RMClass, self).do_deploy()
151 super(RMClass, self).do_deploy()
155 Perform actions required to start a resource in the platform.
158 super(RMClass, self).do_start()
162 Perform actions required to stop a resource in the platform.
165 super(RMClass, self).do_stop()
167 def do_release(self):
169 Perform actions required to release a resource in the platform.
172 super(RMClass, self).do_release()
177 Returns the state of the RM.
179 The state method should never raise an exception, instead if an
180 error occurs it should log the error and invoke the self.do_fail
183 self.error(msg, out, err)
187 return super(RMClass, self).state