Beispiel #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
Beispiel #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
Beispiel #3
0
    def __init__(self, node, pty=None, logger=None, is_sandbox=False):
        assert isinstance(node, Node)

        self._node = node
        self._pty = pty or DummyPty()
        self._logger = logger or DummyLoggerInterface()
        self._is_sandbox = is_sandbox

        # When the node is callable (when it has a default action),
        # make sure that this env becomes collable as well.
        if callable(self._node):
            # Per instance overriding
            def call(self, *a, **kw):
                return self.__getattr__('__call__')(*a, **kw)

            self.__class__ = type(self.__class__.__name__, (self.__class__, ),
                                  {'__call__': call})

        # Create a new HostsContainer object which is identical to the one of
        # the Node object, but add pty/logger/sandbox settings. (So, this
        # doesn't create new Host instances, only a new container.)
        # (do this in this constructor. Each call to Env.hosts should return
        # the same host container instance.)
        self._hosts = HostsContainer(self._node.hosts.get_hosts_as_dict(),
                                     pty=self._pty,
                                     logger=self._logger,
                                     is_sandbox=is_sandbox)

        # Lock Env
        self._lock_env = True
    def get_definition(self):
        class Hosts:
            role1 = LocalHost1, LocalHost2
            role2 = LocalHost3, LocalHost4, LocalHost5
            role3 = LocalHost1

        return HostsContainer.from_definition(Hosts, pty=DummyPty())
Beispiel #5
0
    def get_definition(self):
        hosts = self.get_hosts()
        class Hosts:
            role1 = { hosts.h1, hosts.h2}
            role2 = { hosts.h3, hosts.h4, hosts.h5 }
            role3 = { hosts.h1 }

        return HostsContainer.from_definition(Hosts, pty=DummyPty())
Beispiel #6
0
    def __init__(self, parent=None):
        #: Reference to the parent :class:`~deployer.node.base.Node`.
        #: (This is always assigned in the constructor. You should never override it.)
        self.parent = parent

        if self._node_type in (NodeTypes.SIMPLE_ARRAY,
                               NodeTypes.SIMPLE_ONE) and not parent:
            raise Exception(
                'Cannot initialize a node of type %s without a parent' %
                self._node_type)

        # Create host container (from hosts definition, or mapping from parent hosts.)
        Hosts = self.Hosts or DefaultRoleMapping()

        if isinstance(Hosts, RoleMapping):
            self.hosts = Hosts.apply(parent) if parent else HostsContainer({})
        else:
            self.hosts = HostsContainer.from_definition(Hosts)
Beispiel #7
0
def Connect(self):
    """
    Open interactive SSH connection with this host.
    """
    from deployer.contrib.services import connect
    from deployer.host_container import HostsContainer
    c = connect.Connect(HostsContainer({ 'host': self.service.hosts._all }))

    # Run as any other action. (Nice exception handling, e.g. in case of NoInput on host selection.)
    Action(c.with_host, self.shell, False)()
Beispiel #8
0
    def __init__(self, parent=None):
        self.parent = parent
        if self._node_type in (NodeTypes.SIMPLE_ARRAY, NodeTypes.SIMPLE_ONE) and not parent:
            raise Exception('Cannot initialize a node of type %s without a parent' % self._node_type)

        # Create host container (from hosts definition, or mapping from parent hosts.)
        Hosts = self.Hosts or DefaultRoleMapping()

        if isinstance(Hosts, RoleMapping):
            self.hosts = Hosts.apply(parent) if parent else HostsContainer({ })
        else:
            self.hosts = HostsContainer.from_definition(Hosts)
Beispiel #9
0
    def __init__(self, parent=None):
        #: Reference to the parent :class:`~deployer.node.base.Node`.
        #: (This is always assigned in the constructor. You should never override it.)
        self.parent = parent

        if self._node_type in (NodeTypes.SIMPLE_ARRAY, NodeTypes.SIMPLE_ONE) and not parent:
            raise Exception('Cannot initialize a node of type %s without a parent' % self._node_type)

        # Create host container (from hosts definition, or mapping from parent hosts.)
        Hosts = self.Hosts or DefaultRoleMapping()

        if isinstance(Hosts, RoleMapping):
            self.hosts = Hosts.apply(parent) if parent else HostsContainer({ })
        else:
            self.hosts = HostsContainer.from_definition(Hosts)
Beispiel #10
0
    def apply(self, parent_node_instance):
        """
        Map roles from the parent to the child node and create a new
        :class:`HostsContainer` instance by applying it.
        """
        parent_container = parent_node_instance.hosts

        def get(f):
            if f == ALL_HOSTS:
                return parent_container.get_hosts()
            else:
                assert isinstance(f, tuple), TypeError(
                    'Invalid value found in mapping: %r' % f)
                return parent_container.filter(*f).get_hosts()

        return HostsContainer(
            {role: get(f)
             for role, f in self._mappings.items()},
            pty=parent_container._pty,
            logger=parent_container._logger,
            is_sandbox=parent_container._sandbox)
Beispiel #11
0
    def test_host_container(self):
        hosts = self.get_hosts()
        hosts_container = self.get_definition()

        # (fuzzy) __repr__
        self.assertIn('role1', repr(hosts_container))
        self.assertIn('role2', repr(hosts_container))
        self.assertIn('role3', repr(hosts_container))

        # __eq__ of get_hosts_as_dict
        # (__eq__ of HostsContainer itself is not supported anymore.)
        self.assertEqual(hosts_container.get_hosts_as_dict(),
                    self.get_definition().get_hosts_as_dict())

        # __len__ (One host appeared in two roles, both will be counted, so 6)
        self.assertEqual(len(hosts_container), 6)

        # __nonzero__
        self.assertEqual(bool(hosts_container), True)

        # roles
        self.assertEqual(hosts_container.roles, ['role1', 'role2', 'role3'])

     #   # __contains__
     #   self.assertIn(LocalHost3, hosts_container)

        # Filter
        self.assertEqual(len(hosts_container.filter('role1')), 2)
        self.assertEqual(len(hosts_container.filter('role2')), 3)
        self.assertEqual(len(hosts_container.filter('role3')), 1)

        # Non string filter should raise exception.
        self.assertRaises(TypeError, HostsContainer.filter, 123)

        class MyHosts1:
            role1 = { hosts.h1, hosts.h2 }
        class MyHosts2:
            role2 = { hosts.h3, hosts.h4, hosts.h5 }

        self.assertIsInstance(hosts_container.filter('role1'), HostsContainer)
        self.assertIsInstance(hosts_container.filter('role2'), HostsContainer)
        self.assertEqual(hosts_container.filter('role1').get_hosts(), set(MyHosts1.role1))
        self.assertEqual(hosts_container.filter('role2').get_hosts(), set(MyHosts2.role2))

        self.assertEqual(hosts_container.filter('role1').get_hosts_as_dict(),
                HostsContainer.from_definition(MyHosts1).get_hosts_as_dict())
        self.assertEqual(hosts_container.filter('role2').get_hosts_as_dict(),
                HostsContainer.from_definition(MyHosts2).get_hosts_as_dict())
        self.assertNotEqual(hosts_container.filter('role1').get_hosts_as_dict(),
                HostsContainer.from_definition(MyHosts2).get_hosts_as_dict())
        self.assertNotEqual(hosts_container.filter('role2').get_hosts_as_dict(),
                HostsContainer.from_definition(MyHosts1).get_hosts_as_dict())

        # Filter on two roles.

        class MyHosts1_and_2:
            role1 = { hosts.h1, hosts.h2 }
            role2 = { hosts.h3, hosts.h4, hosts.h5 }

        self.assertEqual(hosts_container.filter('role1', 'role2').get_hosts_as_dict(),
                    HostsContainer.from_definition(MyHosts1_and_2).get_hosts_as_dict())

        # __iter__ (will yield 6 items: when several roles contain the same
        # host, it are different instances.)
        count = 0
        for i in hosts_container:
            self.assertIsInstance(i, HostContainer)
            count += 1
        self.assertEqual(count, 6)
    def test_host_container(self):
        hosts_container = self.get_definition()

        # (fuzzy) __repr__
        self.assertIn('role1', repr(hosts_container))
        self.assertIn('role2', repr(hosts_container))
        self.assertIn('role3', repr(hosts_container))

        # __eq__
        self.assertEqual(hosts_container, self.get_definition())

        # __len__
        self.assertEqual(len(hosts_container), 5)

        # __nonzero__
        self.assertEqual(bool(hosts_container), True)

        # roles
        self.assertEqual(hosts_container.roles, ['role1', 'role2', 'role3'])

     #   # __contains__
     #   print hosts_container._all
     #   print LocalHost3 in hosts_container._all
     #   print LocalHost3 == LocalHost3
     #   self.assertIn(LocalHost3, hosts_container)

        # get_from_slug
        self.assertEqual(hosts_container.get_from_slug('localhost2')._host, LocalHost2)

        # contains_host_with_slug
        self.assertEqual(hosts_container.contains_host_with_slug('localhost2'), True)
        self.assertEqual(hosts_container.contains_host_with_slug('unknown-host'), False)

        # Filter
        self.assertEqual(len(hosts_container.filter('role1')), 2)
        self.assertEqual(len(hosts_container.filter('role2')), 3)
        self.assertEqual(len(hosts_container.filter('role3')), 1)

        # Filter-*
        self.assertEqual(len(hosts_container.filter('*')), 5)

        class MyHosts1:
            role1 = LocalHost1, LocalHost2
        class MyHosts2:
            role2 = LocalHost3, LocalHost4, LocalHost5

        self.assertEqual(hosts_container.filter('role1'), HostsContainer.from_definition(MyHosts1))
        self.assertEqual(hosts_container.filter('role2'), HostsContainer.from_definition(MyHosts2))
        self.assertNotEqual(hosts_container.filter('role1'), HostsContainer.from_definition(MyHosts2))
        self.assertNotEqual(hosts_container.filter('role2'), HostsContainer.from_definition(MyHosts1))

        # Filter on two roles.

        class MyHosts1_and_2:
            role1 = LocalHost1, LocalHost2
            role2 = LocalHost3, LocalHost4, LocalHost5

        self.assertEqual(hosts_container.filter('role1', 'role2'), HostsContainer.from_definition(MyHosts1_and_2))
        self.assertNotEqual(hosts_container.filter('role1', 'role2'), HostsContainer.from_definition(MyHosts1))

        # get
        self.assertRaises(AttributeError, hosts_container.get, 'role1') # Role with multiple hosts
        self.assertRaises(AttributeError, hosts_container.get, 'unknown-role')
        self.assertEqual(hosts_container.get('role3')._host, LocalHost1)

        # __iter__
        count = 0
        for i in hosts_container:
            self.assertIsInstance(i, HostContainer)
            count += 1
        self.assertEqual(count, 5)