Esempio n. 1
0
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))
Esempio n. 2
0
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))