READY = 3
STARTED = 4
STOPPED = 5
- FINISHED = 6
- FAILED = 7
- RELEASED = 8
+ FAILED = 6
+ RELEASED = 7
ResourceState2str = dict({
ResourceState.NEW : "NEW",
ResourceState.READY : "READY",
ResourceState.STARTED : "STARTED",
ResourceState.STOPPED : "STOPPED",
- ResourceState.FINISHED : "FINISHED",
ResourceState.FAILED : "FAILED",
ResourceState.RELEASED : "RELEASED",
})
def failtrap(func):
""" Decorator function for instance methods that should set the
RM state to FAILED when an error is raised. The methods that must be
- decorated are: discover, provision, deploy, start, stop and finish.
+ decorated are: discover, provision, deploy, start, stop.
"""
def wrapped(self, *args, **kwargs):
cls._register_traces()
@classmethod
- def rtype(cls):
+ def get_rtype(cls):
""" Returns the type of the Resource Manager
"""
"""
return copy.deepcopy(cls._attributes.values())
+ @classmethod
+ def get_attribute(cls, name):
+ """ Returns a copy of the attribute with name 'name'
+
+ """
+ return copy.deepcopy(cls._attributes[name])
+
+
@classmethod
def get_traces(cls):
""" Returns a copy of the traces
return cls._backend
def __init__(self, ec, guid):
- super(ResourceManager, self).__init__(self.rtype())
+ super(ResourceManager, self).__init__(self.get_rtype())
self._guid = guid
self._ec = weakref.ref(ec)
self._provision_time = None
self._ready_time = None
self._release_time = None
- self._finish_time = None
self._failed_time = None
self._state = ResourceState.NEW
""" Returns the release time of the RM as a timestamp """
return self._release_time
- @property
- def finish_time(self):
- """ Returns the finalization time of the RM as a timestamp """
- return self._finish_time
-
@property
def failed_time(self):
""" Returns the time failure occured for the RM as a timestamp """
should be added in the do_start method.
"""
+
if not self.state in [ResourceState.READY, ResourceState.STOPPED]:
self.error("Wrong state %s for start" % self.state)
return
self.set_released()
self.debug("----- RELEASED ---- ")
- @failtrap
- def finish(self):
- """ Sets the RM to state FINISHED.
-
- The FINISHED state is different from STOPPED state in that it
- should not be directly invoked by the user.
- STOPPED indicates that the user interrupted the RM, FINISHED means
- that the RM concluded normally the actions it was supposed to perform.
-
- This method should not be overriden directly. Specific functionality
- should be added in the do_finish method.
-
- """
- with self._release_lock:
- if self._state != ResourceState.RELEASED:
- self.do_finish()
-
def fail(self):
""" Sets the RM to state FAILED.
connected.append(rm)
return connected
+ @failtrap
def _needs_reschedule(self, group, state, time):
""" Internal method that verify if 'time' has elapsed since
all elements in 'group' have reached state 'state'.
# check state and time elapsed on all RMs
for guid in group:
rm = self.ec.get_resource(guid)
+
+ # If one of the RMs this resource needs to wait for has FAILED
+ # we raise an exception
+ if rm.state == ResourceState.FAILED:
+ msg = "Resource can not wait for FAILED RM %d. Setting Resource to FAILED"
+ raise RuntimeError, msg
+
# If the RM state is lower than the requested state we must
# reschedule (e.g. if RM is READY but we required STARTED).
if rm.state < state:
t = rm.start_time
elif state == ResourceState.STOPPED:
t = rm.stop_time
+ elif state == ResourceState.RELEASED:
+ t = rm.release_time
else:
break
action 'START' are satisfied.
"""
+ #import pdb;pdb.set_trace()
+
reschedule = False
delay = reschedule_delay
+
## evaluate if conditions to start are met
if self.ec.abort:
return
# Verify all start conditions are met
for (group, state, time) in start_conditions:
# Uncomment for debug
- #unmet = []
- #for guid in group:
- # rm = self.ec.get_resource(guid)
- # unmet.append((guid, rm._state))
- #
- #self.debug("---- WAITED STATES ---- %s" % unmet )
+ unmet = []
+ for guid in group:
+ rm = self.ec.get_resource(guid)
+ unmet.append((guid, rm._state))
+
+ self.debug("---- WAITED STATES ---- %s" % unmet )
reschedule, delay = self._needs_reschedule(group, state, time)
if reschedule:
if reschedule:
self.ec.schedule(delay, self.deploy_with_conditions)
else:
- self.debug("----- STARTING ---- ")
+ self.debug("----- DEPLOYING ---- ")
self.deploy()
def do_connect(self, guid):
def do_release(self):
pass
- def do_finish(self):
- self.set_finished()
-
def do_fail(self):
self.set_failed()
""" Mark ResourceManager as REALEASED """
self.set_state(ResourceState.RELEASED, "_release_time")
- def set_finished(self):
- """ Mark ResourceManager as FINISHED """
- self.set_state(ResourceState.FINISHED, "_finish_time")
-
def set_failed(self):
""" Mark ResourceManager as FAILED """
self.set_state(ResourceState.FAILED, "_failed_time")
@classmethod
def register_type(cls, rclass):
"""Register a new Ressource Manager"""
- cls._resource_types[rclass.rtype()] = rclass
+ cls._resource_types[rclass.get_rtype()] = rclass
@classmethod
def create(cls, rtype, ec, guid):