class CircuitBase(object): """ Data container of circuit. Provides the base operations with phases and builds all the needed references between phases and dispatcher. """ # commands_on_host id id = None # commands id cmd_id = None status = CC_STATUS.ACTIVE # Main container of selected phases phases = None # methods called by scheduler-proxy _proxy_methods = {} # list of phases to refer phase objects installed_phases = {} # Main container of selected phases _phases = None # msc data persistence model cohq = None # running phase reference running_phase = None # detected IP address of target host = None # detected network address of target network_address = None # first initialisation flag initialized = False # A callable to self-releasing from the container releaser = None # last activity timestamp last_activity_time = None # launcher = None launchers_provider = None def __init__(self, _id, installed_phases, config, pull=False): """ @param id: CommandOnHost id @type id: int @param installed_phases: all possible phases classes to use @type installed_phases: dict @param config: scheduler's configuration container @type config: SchedulerConfig @param pull: True if pull mode @type pull: bool """ self.logger = logging.getLogger() self.id = _id self.config = config self.cohq = CoHQuery(int(_id)) self.cmd_id = self.cohq.cmd.id self.installed_phases = installed_phases self.pull = pull @property def is_running(self): return isinstance(self.running_phase, Phase) def setup(self, recurrent=False): """ Post-init - detecting the networking info of target. @param recurrent: if True, the circuit is on pull mode @type recurrent: bool """ self.recurrent = recurrent if not self.initialized : d = maybeDeferred(self._flow_create) if not recurrent : d.addCallback(self._chooseClientNetwork) d.addCallback(self._host_detect) d.addCallback(self._network_detect) d.addCallback(self._init_end) d.addErrback(self._init_failed) return d else : return Deferred() def _flow_create(self): """ Builds the workflow of circuit """ phases = [] selected = self.cohq.get_phases() if self.pull: d_mode = "pull" else : d_mode = "push" self.logger.debug("Circuit #%s: started on %s mode" %(self.id, d_mode)) for phase_name in selected : matches = [p for p in self.installed_phases[d_mode] if p.name==phase_name] if len(matches) == 1: phases.append(matches[0]) else : # TODO - log it and process something .. ? raise KeyError self.phases = phases return True @property def phases(self): """Gets the phases iterator""" return self._phases @phases.setter # pyflakes.ignore def phases(self, value): """ Phases property set processing. - Initial verifications of list of phases - converting the _phases attribute to iterator """ if isinstance(value, list) and all(p for p in value if issubclass(p, Phase)): self._phases = iter(value) else : raise TypeError("All elements must be <Phase> type") self.__phases_list = value def on_last_phase(self): try: last_phase_names = [p.name for p in self.__phases_list[-2:]] return self.running_phase.name in last_phase_names except Exception, e: self.logger.error("\033[32mlast phase failed: %s\033[0m" % str(e))
class CircuitBase(object): """ Data container of circuit. Provides the base operations with phases and builds all the needed references between phases and dispatcher. """ # commands_on_host id id = None # commands id cmd_id = None status = CC_STATUS.ACTIVE # methods called by scheduler-proxy _proxy_methods = {} # list of phases to refer phase objects installed_phases = {} # Main container of selected phases _phases = None # msc data persistence model cohq = None # running phase reference running_phase = None # detected IP address of target host = None # detected network address of target network_address = None # first initialisation flag initialized = False # A callable to self-releasing from the container releaser = None # last activity timestamp last_activity_time = None # launcher = None launchers_provider = None def __init__(self, _id, installed_phases, config, pull=False): """ @param id: CommandOnHost id @type id: int @param installed_phases: all possible phases classes to use @type installed_phases: dict @param config: scheduler's configuration container @type config: SchedulerConfig @param pull: True if pull mode @type pull: bool """ self.logger = logging.getLogger() self.id = _id self.config = config self.cohq = CoHQuery(int(_id)) self.cmd_id = self.cohq.cmd.id self.installed_phases = installed_phases self.pull = pull self.__phases_list = [] @property def is_running(self): return isinstance(self.running_phase, Phase) def setup(self, recurrent=False): """ Post-init - detecting the networking info of target. @param recurrent: if True, the circuit is on pull mode @type recurrent: bool """ self.recurrent = recurrent if not self.initialized : d = maybeDeferred(self._flow_create) if not recurrent : d.addCallback(self._set_host) d.addCallback(self._init_end) d.addErrback(self._init_failed) return d else : return Deferred() def _set_host(self, reason): """Sets the detected IP address from CM""" if self.cohq.target.last_update and self.cohq.target.target_ipaddr: self.host = self.cohq.target.target_ipaddr ntw = NetworkDetect(self.cohq.target.target_ipaddr, self.cohq.target.target_network) self.network_address = ntw.network return True else: self.logger.debug("Circuit #%s: IP address not updated yet" % (self.id)) return False def _flow_create(self): """ Builds the workflow of circuit """ phases = [] selected = self.cohq.get_phases() if self.pull: d_mode = "pull" else : d_mode = "push" self.logger.debug("Circuit #%s: started on %s mode" %(self.id, d_mode)) for phase_name in selected : matches = [p for p in self.installed_phases[d_mode] if p.name==phase_name] if len(matches) == 1: phases.append(matches[0]) else : # TODO - log it and process something .. ? raise KeyError self.set_phases(phases) return True @property def phases(self): """ Main container of selected phases. Gets the phases iterator. """ return self._phases def set_phases(self, value): """ Phases property set processing. - Initial verifications of list of phases - converting the _phases attribute to iterator """ if isinstance(value, list) and all(p for p in value if issubclass(p, Phase)): self._phases = iter(value) else : raise TypeError("All elements must be <Phase> type") self.__phases_list = value def on_last_phase(self): try: last_phase_names = [p.name for p in self.__phases_list[-2:]] return self.running_phase.name in last_phase_names except Exception, e: self.logger.error("\033[32mlast phase failed: %s\033[0m" % str(e))