예제 #1
0
    def _wrap_attribute(cls, attr_name, attribute, node_name, node_type):
        """
        Wrap a Node attribute into the correct descriptor class.
        """
        # The Hosts definition (should be a Hosts class ore RoleMapping)
        if attr_name == 'Hosts':
            # Validate 'Hosts' value
            if not isinstance(attribute, RoleMapping):
                if isclass(attribute):
                    # Try to initialize a HostContainer. If that fails, something is wrong.
                    HostsContainer.from_definition(attribute)
                else:
                    raise Exception(
                        'Node.Hosts should be a class definition or a RoleMapping instance.'
                    )
            return attribute

        # Wrap functions into an ActionDescriptor
        elif isfunction(attribute) and attr_name not in ('__getitem__',
                                                         '__iter__', '__new__',
                                                         '__init__'):
            return ActionDescriptor(attr_name, attribute)

        # Wrap Nodes into a ChildNodeDescriptor
        elif isclass(attribute) and issubclass(attribute, Node):
            # Check the node nesting rules.
            if not NodeNestingRules.check(node_type, attribute._node_type):
                raise Exception(
                    'Invalid nesting of %s in %s (%r in %r).' %
                    (attribute._node_type, node_type, attribute, node_name))

            if not NodeNestingRules.check_mapping(
                    node_type, attribute._node_type, bool(attribute.Hosts)):
                raise Exception(
                    'The Node-attribute %s of type %s does not have a valid role_mapping.'
                    % (attr_name, attribute._node_type))

            return ChildNodeDescriptor(attr_name, attribute)

        # Properties should be wrapped again in an Action
        # descriptor
        elif isinstance(attribute, property):
            if isinstance(attribute, required_property):
                attribute.name = attr_name
                attribute.owner = node_name
            return PropertyDescriptor(attr_name, attribute)

        # Query objects are like properties and should also be
        # wrapped into a descriptor
        elif isinstance(attribute, Query):
            return QueryDescriptor(node_name, attr_name, attribute)

        else:
            return attribute
예제 #2
0
    def _wrap_attribute(cls, attr_name, attribute, node_name, node_type):
        """
        Wrap a Node attribute into the correct descriptor class.
        """
        # The Hosts definition (should be a Hosts class ore RoleMapping)
        if attr_name == 'Hosts':
            # Validate 'Hosts' value
            if not isinstance(attribute, RoleMapping):
                if isclass(attribute):
                    # Try to initialize a HostContainer. If that fails, something is wrong.
                    HostsContainer.from_definition(attribute)
                else:
                    raise Exception('Node.Hosts should be a class definition or a RoleMapping instance.')
            return attribute

        # Wrap functions into an ActionDescriptor
        elif isfunction(attribute) and attr_name not in ('__getitem__', '__iter__', '__new__', '__init__'):
            return ActionDescriptor(attr_name, attribute)

        # Wrap Nodes into a ChildNodeDescriptor
        elif isclass(attribute) and issubclass(attribute, Node):
            # Check the node nesting rules.
            if not NodeNestingRules.check(node_type, attribute._node_type):
                raise Exception('Invalid nesting of %s in %s (%r in %r).' % (
                            attribute._node_type, node_type, attribute, node_name))

            if not NodeNestingRules.check_mapping(node_type, attribute._node_type, bool(attribute.Hosts)):
                raise Exception('The Node-attribute %s of type %s does not have a valid role_mapping.' %
                                            (attr_name, attribute._node_type))


            return ChildNodeDescriptor(attr_name, attribute)

        # Properties should be wrapped again in an Action
        # descriptor
        elif isinstance(attribute, property):
            if isinstance(attribute, required_property):
                attribute.name = attr_name
                attribute.owner = node_name
            return PropertyDescriptor(attr_name, attribute)

        # Query objects are like properties and should also be
        # wrapped into a descriptor
        elif isinstance(attribute, Query):
            return QueryDescriptor(node_name, attr_name, attribute)

        else:
            return attribute
예제 #3
0
    def __init__(self, hosts, pty=None, logger=None, is_sandbox=False, host_contexts=None):
        # the hosts parameter is a dictionary, mapping roles to <Host> instances, or lists
        # of <Host>-instances.
        # e.g. hosts = { 'www': [ <host1>, <host2> ], 'queue': <host3> }
        self._hosts = hosts
        self._logger = logger
        self._pty = pty
        self._sandbox = is_sandbox

        # Make set of all hosts.
        all_hosts = set()
        for h in hosts.values():
            if isclass(h) and issubclass(h, Host):
                all_hosts.add(h)
            else:
                for i in h:
                    all_hosts.add(i)

        self._all = list(all_hosts) # TODO: Why is this a set???

        # Validate hosts. No two host with the same slug can occur in a
        # container.
        slugs = set()
        for h in self._all:
            if h.slug in slugs:
                raise Exception('Duplicate host slug %s found.' % h.slug)
            else:
                slugs.add(h.slug)

        # Host statuses ( { Host class : HostStatus } )
        if host_contexts:
            self._host_contexts = { h: host_contexts.get(h, HostContext()) for h in self._all }
        else:
            self._host_contexts = { h: HostContext() for h in self._all }
예제 #4
0
 def get(h):
     # Create host instance if class was given. Otherwise return
     # instance.
     if isclass(h):
         assert issubclass(h, Host)
         return h(pty=pty, logger=logger)
     else:
         assert isinstance(h, Host)
         return h
예제 #5
0
 def get(h):
     # Create host instance if class was given. Otherwise return
     # instance.
     if isclass(h):
         assert issubclass(h, Host)
         return h(pty=pty, logger=logger)
     else:
         assert isinstance(h, Host)
         return h
예제 #6
0
    def __call__(self, node_class):
        if not isclass(node_class) or not issubclass(node_class, Node):
            raise TypeError('Role mapping decorator incorrectly applied. '
                            '%r is not a Node class' % node_class)

        # Apply role mapping on a copy of the node class.
        return type(node_class.__name__, (node_class, ), {
                    'Hosts': self,
                    # Keep the module, to make sure that inspect.getsourcelines still works.
                    '__module__': node_class.__module__,
                    })
예제 #7
0
    def __call__(self, node_class):
        from deployer.node import Node
        if not isclass(node_class) or not issubclass(node_class, Node):
            raise TypeError('Role mapping decorator incorrectly applied. '
                            '%r is not a Node class' % node_class)

        # Apply role mapping on a copy of the node class.
        return type(
            node_class.__name__,
            (node_class, ),
            {
                'Hosts': self,
                # Keep the module, to make sure that inspect.getsourcelines still works.
                '__module__': node_class.__module__,
            })
예제 #8
0
    def from_definition(cls, hosts_class, **kw):
        """
        Create a ``HostContainer`` from a Hosts class.
        """
        hosts = { }
        for k in dir(hosts_class):
            v = getattr(hosts_class, k)

            if isinstance(v, HostsContainer):
                hosts[k] = v._all
            elif isclass(v) and issubclass(v, Host):
                hosts[k] = [ v ]
            elif isinstance(v, (list, tuple)):
                hosts[k] = v
            elif not k.startswith('_'):
                raise TypeError('Invalid attribute in Hosts: %r=%r' % (k, v))

        return cls(hosts, **kw)
예제 #9
0
    def from_definition(cls, hosts_class, **kw):
        """
        Create a :class:`HostsContainer` from a Hosts class.
        """
        hosts = { }
        for k in dir(hosts_class):
            v = getattr(hosts_class, k)

            if isinstance(v, HostsContainer):
                # This happens when we define Hosts inline in an action, to be
                # initialized, e.g. by initialize_node.
                hosts[k] = v.get_hosts()
            elif isclass(v) and issubclass(v, Host):
                hosts[k] = { v }
            elif isinstance(v, (set, tuple)):
                for h in v:
                    assert issubclass(h, Host)
                hosts[k] = { h for h in v }
            elif not k.startswith('_'):
                raise TypeError('Invalid attribute in host definition %s: %r=%r' % (hosts_class, k, v))

        return cls(hosts, **kw)
예제 #10
0
    def from_definition(cls, hosts_class, **kw):
        """
        Create a :class:`HostsContainer` from a Hosts class.
        """
        hosts = {}
        for k in dir(hosts_class):
            v = getattr(hosts_class, k)

            if isinstance(v, HostsContainer):
                # This happens when we define Hosts inline in an action, to be
                # initialized, e.g. by initialize_node.
                hosts[k] = v.get_hosts()
            elif isclass(v) and issubclass(v, Host):
                hosts[k] = {v}
            elif isinstance(v, (set, tuple)):
                for h in v:
                    assert issubclass(h, Host)
                hosts[k] = {h for h in v}
            elif not k.startswith('_'):
                raise TypeError(
                    'Invalid attribute in host definition %s: %r=%r' %
                    (hosts_class, k, v))

        return cls(hosts, **kw)