Beispiel #1
0
 def test_all_resources(self):
     for i in range(5):
         rid = str(uuid.uuid4())
         driver = fakes.fake_driver(rid)
         sm = state.Automaton(driver=driver,
                              worker_context=self.ctx,
                              resource_id=driver.id,
                              tenant_id=self.tenant_id,
                              delete_callback=None,
                              bandwidth_callback=None,
                              queue_warning_threshold=5,
                              reboot_error_threshold=5)
         self.trm.state_machines[rid] = sm
     r = event.Resource(
         tenant_id=self.tenant_id,
         id='*',
         driver=router.Router.RESOURCE_NAME,
     )
     msg = event.Event(
         resource=r,
         crud=event.CREATE,
         body={'key': 'value'},
     )
     sms = self.trm.get_state_machines(msg, self.ctx)
     self.assertEqual(5, len(sms))
Beispiel #2
0
 def test_all_routers(self):
     self.trm.state_machines.state_machines = {
         str(i): state.Automaton(str(i), '1234',
                                 None, None, None, 5, 5)
         for i in range(5)
     }
     msg = event.Event(
         tenant_id='1234',
         router_id='*',
         crud=event.CREATE,
         body={'key': 'value'},
     )
     sms = self.trm.get_state_machines(msg, self.ctx)
     self.assertEqual(5, len(sms))
Beispiel #3
0
def debug_one_router(args=sys.argv[1:]):

    main.register_and_load_opts()

    # Add our extra option for specifying the router-id to debug
    cfg.CONF.register_cli_opts([
        cfg.StrOpt(
            'router-id',
            required=True,
            help='The UUID for the router to debug',
        ),
    ])
    cfg.CONF(args, project='akanda-rug')
    cfg.CONF.set_override('boot_timeout', 60000)

    logging.basicConfig(
        level=logging.DEBUG,
        format=':'.join(
            '%(' + n + ')s' for n in
            ['processName', 'threadName', 'name', 'levelname', 'message']),
    )

    log = logging.getLogger(__name__)
    log.debug('Proxy settings: %r', os.getenv('no_proxy'))

    context = worker.WorkerContext()
    router_obj = context.neutron.get_router_detail(cfg.CONF.router_id)
    a = state.Automaton(
        router_id=cfg.CONF.router_id,
        tenant_id=router_obj.tenant_id,
        delete_callback=delete_callback,
        bandwidth_callback=bandwidth_callback,
        worker_context=context,
        queue_warning_threshold=100,
        reboot_error_threshold=1,
    )

    a.send_message(Fake('update'))

    import pdb
    pdb.set_trace()

    a.update(context)
Beispiel #4
0
    def setUp(self):
        super(TestAutomaton, self).setUp()

        self.ctx = mock.Mock()  # worker context

        self.vm_mgr_cls = mock.patch('akanda.rug.vm_manager.VmManager').start()
        self.addCleanup(mock.patch.stopall)

        self.delete_callback = mock.Mock()
        self.bandwidth_callback = mock.Mock()

        self.sm = state.Automaton(
            router_id='9306bbd8-f3cc-11e2-bd68-080027e60b25',
            tenant_id='tenant-id',
            delete_callback=self.delete_callback,
            bandwidth_callback=self.bandwidth_callback,
            worker_context=self.ctx,
            queue_warning_threshold=3,
            reboot_error_threshold=5,
        )
Beispiel #5
0
 def test_errored_routers(self):
     self.trm.state_machines.state_machines = {}
     for i in range(5):
         sm = state.Automaton(str(i), '1234',
                              None, None, None, 5, 5)
         # Replace the default mock with one that has 'state' set.
         if i == 2:
             status = vm_manager.ERROR
         else:
             status = vm_manager.UP
         sm.vm = mock.Mock(state=status)
         self.trm.state_machines.state_machines[str(i)] = sm
     msg = event.Event(
         tenant_id='1234',
         router_id='error',
         crud=event.CREATE,
         body={'key': 'value'},
     )
     sms = self.trm.get_state_machines(msg, self.ctx)
     self.assertEqual(1, len(sms))
     self.assertEqual('2', sms[0].router_id)
     self.assertIs(self.trm.state_machines.state_machines['2'], sms[0])
Beispiel #6
0
    def test_errored_routers(self):
        self.trm.state_machines.state_machines = {}
        for i in range(5):
            rid = str(uuid.uuid4())
            driver = fakes.fake_driver(rid)
            sm = state.Automaton(driver=driver,
                                 worker_context=self.ctx,
                                 resource_id=i,
                                 tenant_id=self.tenant_id,
                                 delete_callback=None,
                                 bandwidth_callback=None,
                                 queue_warning_threshold=5,
                                 reboot_error_threshold=5)
            self.trm.state_machines[rid] = sm

            # Replace the default mock with one that has 'state' set.
            if i == 2:
                status = states.ERROR
            else:
                status = states.UP

            sm.instance = mock.Mock(state=status)
            self.trm.state_machines.state_machines[str(i)] = sm

        r = event.Resource(
            tenant_id=self.tenant_id,
            id='2',
            driver=router.Router.RESOURCE_NAME,
        )
        msg = event.Event(
            resource=r,
            crud=event.CREATE,
            body={'key': 'value'},
        )
        sms = self.trm.get_state_machines(msg, self.ctx)
        self.assertEqual(1, len(sms))
        self.assertEqual(2, sms[0].resource_id)
        self.assertIs(self.trm.state_machines.state_machines['2'], sms[0])
Beispiel #7
0
    def setUp(self):
        super(TestAutomaton, self).setUp()

        self.ctx = mock.Mock()  # worker context
        self.fake_driver = fakes.fake_driver()

        self.instance_mgr_cls = \
            mock.patch('akanda.rug.instance_manager.InstanceManager').start()
        self.addCleanup(mock.patch.stopall)

        self.delete_callback = mock.Mock()
        self.bandwidth_callback = mock.Mock()

        self.sm = state.Automaton(
            driver=self.fake_driver,
            resource_id=self.fake_driver.id,
            tenant_id='tenant-id',
            delete_callback=self.delete_callback,
            bandwidth_callback=self.bandwidth_callback,
            worker_context=self.ctx,
            queue_warning_threshold=3,
            reboot_error_threshold=5,
        )
Beispiel #8
0
    def get_state_machines(self, message, worker_context):
        """Return the state machines and the queue for sending it messages for
        the logical resource being addressed by the message.
        """
        if (not message.resource
                or (message.resource and not message.resource.id)):
            LOG.error(
                _LE('Cannot get state machine for message with '
                    'no message.resource'))
            raise InvalidIncomingMessage()

        state_machines = []

        # Send to all of our resources.
        if message.resource.id == '*':
            LOG.debug('routing to all state machines')
            state_machines = self.state_machines.values()

        # Ignore messages to deleted resources.
        elif self.state_machines.has_been_deleted(message.resource.id):
            LOG.debug('dropping message for deleted resource')
            return []

        # Send to resources that have an ERROR status
        elif message.resource.id == 'error':
            state_machines = [
                sm for sm in self.state_machines.values() if sm.has_error()
            ]
            LOG.debug('routing to %d errored state machines',
                      len(state_machines))

        # Create a new state machine for this router.
        elif message.resource.id not in self.state_machines:
            LOG.debug('creating state machine for %s', message.resource.id)

            # load the driver
            if not message.resource.driver:
                LOG.error(
                    _LE('cannot create state machine without specifying'
                        'a driver.'))
                return []

            driver_obj = \
                drivers.get(message.resource.driver)(worker_context,
                                                     message.resource.id)

            if not driver_obj:
                # this means the driver didn't load for some reason..
                # this might not be needed at all.
                LOG.debug('for some reason loading the driver failed')
                return []

            def deleter():
                self._delete_resource(message.resource.id)

            new_state_machine = state.Automaton(
                driver=driver_obj,
                resource_id=message.resource.id,
                tenant_id=self.tenant_id,
                delete_callback=deleter,
                bandwidth_callback=self._report_bandwidth,
                worker_context=worker_context,
                queue_warning_threshold=self._queue_warning_threshold,
                reboot_error_threshold=self._reboot_error_threshold,
            )
            self.state_machines[message.resource.id] = new_state_machine
            state_machines = [new_state_machine]

        # Send directly to an existing router.
        elif message.resource.id:
            state_machines = [self.state_machines[message.resource.id]]

        # Filter out any deleted state machines.
        return [
            machine for machine in state_machines
            if (not machine.deleted and
                not self.state_machines.has_been_deleted(machine.resource_id))
        ]
Beispiel #9
0
    def get_state_machines(self, message, worker_context):
        """Return the state machines and the queue for sending it messages for
        the router being addressed by the message.
        """
        router_id = message.router_id
        if not router_id:
            LOG.debug('looking for router for %s', message.tenant_id)
            if self._default_router_id is None:
                # TODO(mark): handle muliple router lookup
                router = worker_context.neutron.get_router_for_tenant(
                    message.tenant_id,
                )
                if not router:
                    LOG.debug(
                        'router not found for tenant %s',
                        message.tenant_id
                    )
                    return []
                self._default_router_id = router.id
            router_id = self._default_router_id
            LOG.debug('using router id %s', router_id)

        # Ignore messages to deleted routers.
        if self.state_machines.has_been_deleted(router_id):
            LOG.debug('dropping message for deleted router')
            return []

        state_machines = []

        # Send to all of our routers.
        if router_id == '*':
            LOG.debug('routing to all state machines')
            state_machines = self.state_machines.values()

        # Send to routers that have an ERROR status
        elif router_id == 'error':
            state_machines = [
                sm for sm in self.state_machines.values()
                if sm.has_error()
            ]
            LOG.debug('routing to %d errored state machines',
                      len(state_machines))

        # Create a new state machine for this router.
        elif router_id not in self.state_machines:
            LOG.debug('creating state machine for %s', router_id)

            def deleter():
                self._delete_router(router_id)

            sm = state.Automaton(
                router_id=router_id,
                tenant_id=self.tenant_id,
                delete_callback=deleter,
                bandwidth_callback=self._report_bandwidth,
                worker_context=worker_context,
                queue_warning_threshold=self._queue_warning_threshold,
                reboot_error_threshold=self._reboot_error_threshold,
            )
            self.state_machines[router_id] = sm
            state_machines = [sm]

        # Send directly to an existing router.
        elif router_id:
            sm = self.state_machines[router_id]
            state_machines = [sm]

        # Filter out any deleted state machines.
        return [
            machine
            for machine in state_machines
            if (not machine.deleted and
                not self.state_machines.has_been_deleted(machine.router_id))
        ]