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
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
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 }
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
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__, })
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__, })
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)
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)
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)