Exemple #1
0
def _setup_service(host, name):
    binary = name if name.startswith('nova-') else "nova-%s" % name

    ctxt = context.get_admin_context()
    service_ref = objects.Service.get_by_host_and_binary(ctxt, host, binary)
    if service_ref:
        service._update_service_ref(service_ref)
    else:
        try:
            service_obj = objects.Service(ctxt)
            service_obj.host = host
            service_obj.binary = binary
            service_obj.topic = None
            service_obj.report_count = 0
            service_obj.create()
        except (exception.ServiceTopicExists, exception.ServiceBinaryExists):
            # If we race to create a record with a sibling, don't
            # fail here.
            pass
Exemple #2
0
 def test_cold_migrate_same_host_old_compute_disallow(self):
     """Upgrade compat test where the resource provider does not report
     the COMPUTE_SAME_HOST_COLD_MIGRATE trait but the compute service is
     old so the API falls back to the allow_resize_to_same_host config which
     defaults to False.
     """
     server = self._create_server(networks='none')
     # Stub the compute service version check to make the compute service
     # appear old.
     fake_service = objects.Service()
     fake_service.version = (
         compute_api.MIN_COMPUTE_SAME_HOST_COLD_MIGRATE - 1)
     with mock.patch('nova.objects.Service.get_by_compute_host',
                     return_value=fake_service) as mock_get_service:
         self.api.post_server_action(server['id'], {'migrate': None})
     mock_get_service.assert_called_once_with(
         test.MatchType(nova_context.RequestContext), 'host1')
     # Since allow_resize_to_same_host defaults to False scheduling failed
     # since there are no other hosts.
     self._wait_for_migrate_no_valid_host()
Exemple #3
0
    def test_service_get_by_compute_host(self):
        fake_cell = 'fake-cell'
        fake_service = objects.Service(**FAKE_SERVICES[0])
        fake_response = messaging.Response(self.ctxt, fake_cell, fake_service,
                                           False)
        expected_response = cells_utils.ServiceProxy(fake_service, fake_cell)
        cell_and_host = cells_utils.cell_with_item('fake-cell', 'fake-host')

        self.mox.StubOutWithMock(self.msg_runner,
                                 'service_get_by_compute_host')
        self.mox.StubOutWithMock(cells_utils, 'add_cell_to_service')
        self.msg_runner.service_get_by_compute_host(
            self.ctxt, fake_cell, 'fake-host').AndReturn(fake_response)
        cells_utils.add_cell_to_service(fake_service,
                                        fake_cell).AndReturn(expected_response)

        self.mox.ReplayAll()
        response = self.cells_manager.service_get_by_compute_host(
            self.ctxt, host_name=cell_and_host)
        self.assertEqual(expected_response, response)
    def test_instance_list_old_deleted_service_with_no_uuid(self):
        # Create a nova-compute service record with a host that will match the
        # instance's host, with no uuid. We can't do this through the
        # Service object because it will automatically generate a uuid.
        # Use service version 9, which is too old compared to the minimum
        # version in the rest of the deployment.
        service = db.service_create(self.context, {
            'host': 'fake-host',
            'binary': 'nova-compute',
            'version': 9
        })
        self.assertIsNone(service['uuid'])

        # Now delete it.
        db.service_destroy(self.context, service['id'])

        # Create a new service with the same host name that has a UUID and a
        # current version.
        new_service = objects.Service(context=self.context,
                                      host='fake-host',
                                      binary='nova-compute')
        new_service.create()

        # Create an instance whose host will match both services, including the
        # deleted one.
        inst = objects.Instance(context=self.context,
                                project_id=self.context.project_id,
                                host='fake-host')
        inst.create()

        insts = objects.InstanceList.get_by_filters(
            self.context, {}, expected_attrs=['services'])
        self.assertEqual(1, len(insts))
        self.assertEqual(2, len(insts[0].services))
        # Deleted service should not have a UUID
        for service in insts[0].services:
            if service.deleted:
                self.assertNotIn('uuid', service)
            else:
                self.assertIsNotNone(service.uuid)
Exemple #5
0
 def setUp(self):
     super(ExtendedHyervisorPciSampleJsonTest, self).setUp()
     self.fake_compute_node = objects.ComputeNode(
         cpu_info="?",
         current_workload=0,
         disk_available_least=0,
         host_ip="1.1.1.1",
         state="up",
         status="enabled",
         free_disk_gb=1028,
         free_ram_mb=7680,
         hypervisor_hostname="fake-mini",
         hypervisor_type="fake",
         hypervisor_version=1000,
         id=1,
         local_gb=1028,
         local_gb_used=0,
         memory_mb=8192,
         memory_mb_used=512,
         running_vms=0,
         vcpus=1,
         vcpus_used=0,
         service_id=2,
         host='043b3cacf6f34c90a7245151fc8ebcda',
         pci_device_pools=pci_device_pool.from_pci_stats(
                                   {"count": 5,
                                    "vendor_id": "8086",
                                    "product_id": "1520",
                                    "keya": "valuea",
                                    "extra_info": {
                                        "phys_function": '[["0x0000", '
                                                         '"0x04", "0x00",'
                                                         ' "0x1"]]',
                                        "key1": "value1"}}),)
     self.fake_service = objects.Service(
         id=2,
         host='043b3cacf6f34c90a7245151fc8ebcda',
         disabled=False,
         disabled_reason=None)
Exemple #6
0
    def test_service_update(self):
        fake_cell = 'fake-cell'
        fake_service = objects.Service(**FAKE_SERVICES[0])
        fake_response = messaging.Response(
            self.ctxt, fake_cell, fake_service, False)
        expected_response = cells_utils.ServiceProxy(fake_service, fake_cell)
        cell_and_host = cells_utils.cell_with_item('fake-cell', 'fake-host')
        params_to_update = {'disabled': True}

        self.mox.StubOutWithMock(self.msg_runner, 'service_update')
        self.mox.StubOutWithMock(cells_utils, 'add_cell_to_service')
        self.msg_runner.service_update(self.ctxt,
                fake_cell, 'fake-host', 'nova-api',
                params_to_update).AndReturn(fake_response)
        cells_utils.add_cell_to_service(fake_service, fake_cell).AndReturn(
            expected_response)
        self.mox.ReplayAll()

        response = self.cells_manager.service_update(
            self.ctxt, host_name=cell_and_host, binary='nova-api',
            params_to_update=params_to_update)
        self.assertEqual(expected_response, response)
    def setUp(self):
        super(ServicesCellsTestV21, self).setUp()

        host_api = compute.cells_api.HostAPI()

        self.ext_mgr = extensions.ExtensionManager()
        self.ext_mgr.extensions = {}
        self._set_up_controller()
        self.controller.host_api = host_api

        self.useFixture(utils_fixture.TimeFixture(fake_utcnow()))

        services_list = []
        for service in fake_services_list:
            service = service.copy()
            del service['version']
            service_obj = objects.Service(**service)
            service_proxy = cells_utils.ServiceProxy(service_obj, 'cell1')
            services_list.append(service_proxy)

        host_api.cells_rpcapi.service_get_all = (mock.Mock(
            side_effect=fake_service_get_all(services_list)))
    def test_is_up(self):
        now = timeutils.utcnow()
        service = objects.Service(
            host='fake-host',
            topic='compute',
            binary='nova-compute',
            created_at=now,
            updated_at=now,
            last_seen_up=now,
            forced_down=False,
        )
        time_fixture = self.useFixture(utils_fixture.TimeFixture(now))

        # Up (equal)
        result = self.servicegroup_api.service_is_up(service)
        self.assertTrue(result)

        # Up
        time_fixture.advance_time_seconds(self.down_time)
        result = self.servicegroup_api.service_is_up(service)
        self.assertTrue(result)

        # Down
        time_fixture.advance_time_seconds(1)
        result = self.servicegroup_api.service_is_up(service)
        self.assertFalse(result)

        # "last_seen_up" says down, "updated_at" says up.
        # This can happen if we do a service disable/enable while it's down.
        service.updated_at = timeutils.utcnow()
        result = self.servicegroup_api.service_is_up(service)
        self.assertFalse(result)

        # "last_seen_up" is none before compute node reports its status,
        # just use 'created_at' as last_heartbeat.
        service.last_seen_up = None
        service.created_at = timeutils.utcnow()
        result = self.servicegroup_api.service_is_up(service)
        self.assertTrue(result)
Exemple #9
0
    def setUp(self):
        super(ServicesCellsTestV21, self).setUp()

        host_api = cells_api.HostAPI()

        self.ext_mgr = extensions.ExtensionManager()
        self.ext_mgr.extensions = {}
        self._set_up_controller()
        self.controller.host_api = host_api

        self.stubs.Set(timeutils, "utcnow", fake_utcnow)
        self.stubs.Set(timeutils, "utcnow_ts", fake_utcnow_ts)

        services_list = []
        for service in fake_services_list:
            service = service.copy()
            service_obj = objects.Service(**service)
            service_proxy = cells_utils.ServiceProxy(service_obj, 'cell1')
            services_list.append(service_proxy)

        self.stubs.Set(host_api.cells_rpcapi, "service_get_all",
                       fake_service_get_all(services_list))
Exemple #10
0
    def service_get_by_compute_host(self, context, host_name):
        try:
            db_service = self.cells_rpcapi.service_get_by_compute_host(
                context, host_name)
        except exception.CellRoutingInconsistency:
            raise exception.ComputeHostNotFound(host=host_name)

        # NOTE(danms): Currently cells does not support objects as
        # return values, so just convert the db-formatted service objects
        # to new-world objects here

        # NOTE(dheeraj): Use ServiceProxy here too. See johannes'
        # note on service_get_all
        if db_service:
            # NOTE(alaski): Creation of the Service object involves creating
            # a ComputeNode object in this case.  This will fail because with
            # cells the 'id' is a string of the format 'region!child@1' but
            # the object expects the 'id' to be an int.
            if 'compute_node' in db_service:
                # NOTE(alaski): compute_node is a list that should have one
                # item in it, except in the case of Ironic.  But the Service
                # object only uses the first compute_node for its relationship
                # so we only need to pull the first one here.
                db_compute = db_service['compute_node'][0]
                comp_cell_path, comp_id = cells_utils.split_cell_and_item(
                    db_compute['id'])
                db_compute['id'] = comp_id

            cell_path, _id = cells_utils.split_cell_and_item(db_service['id'])
            db_service['id'] = _id
            ser_obj = objects.Service._from_db_object(context,
                                                      objects.Service(),
                                                      db_service)
            compute_proxy = None
            if 'compute_node' in db_service:
                compute_proxy = ComputeNodeProxy(ser_obj.compute_node,
                                                 comp_cell_path)

            return ServiceProxy(ser_obj, cell_path, compute_node=compute_proxy)
Exemple #11
0
 def test_service_get_all_cells_with_minimal_constructs(
         self, mock_sg, mock_get_hm, mock_cm_list):
     service = objects.Service(binary='nova-compute',
                               host='host-%s' % uuids.cell0)
     cells = [
         objects.CellMapping(uuid=uuids.cell1, id=1),
         objects.CellMapping(uuid=uuids.cell2, id=2),
     ]
     mock_cm_list.return_value = cells
     context.load_cells()
     # create two hms in cell1, which is the down cell in this test.
     hm1 = objects.HostMapping(self.ctxt,
                               host='host1-unavailable',
                               cell_mapping=cells[0])
     hm1.create()
     hm2 = objects.HostMapping(self.ctxt,
                               host='host2-unavailable',
                               cell_mapping=cells[0])
     hm2.create()
     mock_sg.return_value = {
         cells[0].uuid: [service],
         cells[1].uuid: context.did_not_respond_sentinel,
     }
     mock_get_hm.return_value = [hm1, hm2]
     services = self.host_api.service_get_all(self.ctxt,
                                              all_cells=True,
                                              cell_down_support=True)
     # returns the results from cell0 and minimal construct from cell1.
     self.assertEqual(
         sorted([
             'host-%s' % uuids.cell0, 'host1-unavailable',
             'host2-unavailable'
         ]), sorted([svc.host for svc in services]))
     mock_sg.assert_called_once_with(self.ctxt,
                                     objects.ServiceList.get_all,
                                     None,
                                     set_zones=False)
     mock_get_hm.assert_called_once_with(self.ctxt, cells[1].id)
Exemple #12
0
    def service_update(self, context, host_name, binary, params_to_update):
        """Used to enable/disable a service. For compute services, setting to
        disabled stops new builds arriving on that host.

        :param host_name: the name of the host machine that the service is
                          running
        :param binary: The name of the executable that the service runs as
        :param params_to_update: eg. {'disabled': True}
        """
        db_service = self.cells_rpcapi.service_update(
            context, host_name, binary, params_to_update)
        # NOTE(danms): Currently cells does not support objects as
        # return values, so just convert the db-formatted service objects
        # to new-world objects here

        # NOTE(dheeraj): Use ServiceProxy here too. See johannes'
        # note on service_get_all
        if db_service:
            cell_path, _id = cells_utils.split_cell_and_item(db_service['id'])
            db_service['id'] = _id
            ser_obj = objects.Service._from_db_object(context,
                                                      objects.Service(),
                                                      db_service)
            return ServiceProxy(ser_obj, cell_path)
Exemple #13
0
    def test_get_host_supporting_request_first_host_is_old_no_alternates(
            self, mock_get_service, mock_delete_allocation,
            mock_claim_resources):
        self.request_spec.requested_resources = [objects.RequestGroup()]
        task = self._generate_task()
        resources = {
            "resources": {
                "VCPU": 1,
                "MEMORY_MB": 1024,
                "DISK_GB": 100
            }
        }

        first = objects.Selection(service_host="host1",
                                  nodename="node1",
                                  cell_uuid=uuids.cell1,
                                  allocation_request=jsonutils.dumps({
                                      "allocations": {
                                          uuids.host1: resources
                                      }
                                  }),
                                  allocation_request_version='1.19')
        selection_list = [first]

        first_service = objects.Service(service_host='host1')
        first_service.version = 38
        mock_get_service.return_value = first_service

        self.assertRaises(exception.MaxRetriesExceeded,
                          task._get_host_supporting_request, selection_list)

        mock_get_service.assert_called_once_with(task.context, 'host1',
                                                 'nova-compute')
        mock_delete_allocation.assert_called_once_with(task.context,
                                                       self.instance.uuid)
        mock_claim_resources.assert_not_called()
Exemple #14
0
 def _create_service(ctxt, host, binary, version):
     svc = objects.Service(ctxt, host=host, binary=binary)
     svc.version = version
     svc.create()
     return svc
 def _node(host, total_mem, total_disk, free_mem, free_disk):
     now = timeutils.utcnow()
     return objects.Service(host=host,
                            disabled=False,
                            forced_down=False,
                            last_seen_up=now)
Exemple #16
0
class ComputeHostAPITestCase(test.TestCase):
    def setUp(self):
        super(ComputeHostAPITestCase, self).setUp()
        self.host_api = compute.HostAPI()
        self.aggregate_api = compute.AggregateAPI()
        self.ctxt = context.get_admin_context()
        fake_notifier.stub_notifier(self)
        self.addCleanup(fake_notifier.reset)
        self.req = fakes.HTTPRequest.blank('')
        self.controller = services.ServiceController()
        self.useFixture(nova_fixtures.SingleCellSimple())

    def _compare_obj(self, obj, db_obj):
        test_objects.compare_obj(self,
                                 obj,
                                 db_obj,
                                 allow_missing=test_service.OPTIONAL)

    def _compare_objs(self, obj_list, db_obj_list):
        self.assertEqual(len(obj_list), len(db_obj_list),
                         "The length of two object lists are different.")
        for index, obj in enumerate(obj_list):
            self._compare_obj(obj, db_obj_list[index])

    def test_set_host_enabled(self):
        fake_notifier.NOTIFICATIONS = []

        @mock.patch.object(self.host_api.rpcapi,
                           'set_host_enabled',
                           return_value='fake-result')
        @mock.patch.object(self.host_api,
                           '_assert_host_exists',
                           return_value='fake_host')
        def _do_test(mock_assert_host_exists, mock_set_host_enabled):
            result = self.host_api.set_host_enabled(self.ctxt, 'fake_host',
                                                    'fake_enabled')
            self.assertEqual('fake-result', result)
            self.assertEqual(2, len(fake_notifier.NOTIFICATIONS))
            msg = fake_notifier.NOTIFICATIONS[0]
            self.assertEqual('HostAPI.set_enabled.start', msg.event_type)
            self.assertEqual('api.fake_host', msg.publisher_id)
            self.assertEqual('INFO', msg.priority)
            self.assertEqual('fake_enabled', msg.payload['enabled'])
            self.assertEqual('fake_host', msg.payload['host_name'])
            msg = fake_notifier.NOTIFICATIONS[1]
            self.assertEqual('HostAPI.set_enabled.end', msg.event_type)
            self.assertEqual('api.fake_host', msg.publisher_id)
            self.assertEqual('INFO', msg.priority)
            self.assertEqual('fake_enabled', msg.payload['enabled'])
            self.assertEqual('fake_host', msg.payload['host_name'])

        _do_test()

    def test_host_name_from_assert_hosts_exists(self):
        @mock.patch.object(self.host_api.rpcapi,
                           'set_host_enabled',
                           return_value='fake-result')
        @mock.patch.object(self.host_api,
                           '_assert_host_exists',
                           return_value='fake_host')
        def _do_test(mock_assert_host_exists, mock_set_host_enabled):
            result = self.host_api.set_host_enabled(self.ctxt, 'fake_host',
                                                    'fake_enabled')
            self.assertEqual('fake-result', result)

        _do_test()

    def test_get_host_uptime(self):
        @mock.patch.object(self.host_api.rpcapi,
                           'get_host_uptime',
                           return_value='fake-result')
        @mock.patch.object(self.host_api,
                           '_assert_host_exists',
                           return_value='fake_host')
        def _do_test(mock_assert_host_exists, mock_get_host_uptime):
            result = self.host_api.get_host_uptime(self.ctxt, 'fake_host')
            self.assertEqual('fake-result', result)

        _do_test()

    def test_get_host_uptime_service_down(self):
        @mock.patch.object(self.host_api.db,
                           'service_get_by_compute_host',
                           return_value=dict(test_service.fake_service, id=1))
        @mock.patch.object(self.host_api.servicegroup_api,
                           'service_is_up',
                           return_value=False)
        def _do_test(mock_service_is_up, mock_service_get_by_compute_host):
            self.assertRaises(exception.ComputeServiceUnavailable,
                              self.host_api.get_host_uptime, self.ctxt,
                              'fake_host')

        _do_test()

    def test_host_power_action(self):
        fake_notifier.NOTIFICATIONS = []

        @mock.patch.object(self.host_api.rpcapi,
                           'host_power_action',
                           return_value='fake-result')
        @mock.patch.object(self.host_api,
                           '_assert_host_exists',
                           return_value='fake_host')
        def _do_test(mock_assert_host_exists, mock_host_power_action):
            result = self.host_api.host_power_action(self.ctxt, 'fake_host',
                                                     'fake_action')
            self.assertEqual('fake-result', result)
            self.assertEqual(2, len(fake_notifier.NOTIFICATIONS))
            msg = fake_notifier.NOTIFICATIONS[0]
            self.assertEqual('HostAPI.power_action.start', msg.event_type)
            self.assertEqual('api.fake_host', msg.publisher_id)
            self.assertEqual('INFO', msg.priority)
            self.assertEqual('fake_action', msg.payload['action'])
            self.assertEqual('fake_host', msg.payload['host_name'])
            msg = fake_notifier.NOTIFICATIONS[1]
            self.assertEqual('HostAPI.power_action.end', msg.event_type)
            self.assertEqual('api.fake_host', msg.publisher_id)
            self.assertEqual('INFO', msg.priority)
            self.assertEqual('fake_action', msg.payload['action'])
            self.assertEqual('fake_host', msg.payload['host_name'])

        _do_test()

    def test_set_host_maintenance(self):
        fake_notifier.NOTIFICATIONS = []

        @mock.patch.object(self.host_api.rpcapi,
                           'host_maintenance_mode',
                           return_value='fake-result')
        @mock.patch.object(self.host_api,
                           '_assert_host_exists',
                           return_value='fake_host')
        def _do_test(mock_assert_host_exists, mock_host_maintenance_mode):
            result = self.host_api.set_host_maintenance(
                self.ctxt, 'fake_host', 'fake_mode')
            self.assertEqual('fake-result', result)
            self.assertEqual(2, len(fake_notifier.NOTIFICATIONS))
            msg = fake_notifier.NOTIFICATIONS[0]
            self.assertEqual('HostAPI.set_maintenance.start', msg.event_type)
            self.assertEqual('api.fake_host', msg.publisher_id)
            self.assertEqual('INFO', msg.priority)
            self.assertEqual('fake_host', msg.payload['host_name'])
            self.assertEqual('fake_mode', msg.payload['mode'])
            msg = fake_notifier.NOTIFICATIONS[1]
            self.assertEqual('HostAPI.set_maintenance.end', msg.event_type)
            self.assertEqual('api.fake_host', msg.publisher_id)
            self.assertEqual('INFO', msg.priority)
            self.assertEqual('fake_host', msg.payload['host_name'])
            self.assertEqual('fake_mode', msg.payload['mode'])

        _do_test()

    def test_service_get_all_cells(self):
        cells = objects.CellMappingList.get_all(self.ctxt)
        for cell in cells:
            with context.target_cell(self.ctxt, cell) as cctxt:
                objects.Service(context=cctxt,
                                binary='nova-compute',
                                host='host-%s' % cell.uuid).create()
        services = self.host_api.service_get_all(self.ctxt, all_cells=True)
        self.assertEqual(sorted(['host-%s' % cell.uuid for cell in cells]),
                         sorted([svc.host for svc in services]))

    @mock.patch('nova.context.scatter_gather_cells')
    def test_service_get_all_cells_with_failures(self, mock_sg):
        service = objects.Service(binary='nova-compute',
                                  host='host-%s' % uuids.cell1)
        mock_sg.return_value = {
            uuids.cell1: [service],
            uuids.cell2: context.did_not_respond_sentinel
        }
        services = self.host_api.service_get_all(self.ctxt, all_cells=True)
        # returns the results from cell1 and ignores cell2.
        self.assertEqual(['host-%s' % uuids.cell1],
                         [svc.host for svc in services])

    @mock.patch('nova.objects.CellMappingList.get_all')
    @mock.patch.object(objects.HostMappingList, 'get_by_cell_id')
    @mock.patch('nova.context.scatter_gather_all_cells')
    def test_service_get_all_cells_with_minimal_constructs(
            self, mock_sg, mock_get_hm, mock_cm_list):
        service = objects.Service(binary='nova-compute',
                                  host='host-%s' % uuids.cell0)
        cells = [
            objects.CellMapping(uuid=uuids.cell1, id=1),
            objects.CellMapping(uuid=uuids.cell2, id=2),
        ]
        mock_cm_list.return_value = cells
        context.load_cells()
        # create two hms in cell1, which is the down cell in this test.
        hm1 = objects.HostMapping(self.ctxt,
                                  host='host1-unavailable',
                                  cell_mapping=cells[0])
        hm1.create()
        hm2 = objects.HostMapping(self.ctxt,
                                  host='host2-unavailable',
                                  cell_mapping=cells[0])
        hm2.create()
        mock_sg.return_value = {
            cells[0].uuid: [service],
            cells[1].uuid: context.did_not_respond_sentinel,
        }
        mock_get_hm.return_value = [hm1, hm2]
        services = self.host_api.service_get_all(self.ctxt,
                                                 all_cells=True,
                                                 cell_down_support=True)
        # returns the results from cell0 and minimal construct from cell1.
        self.assertEqual(
            sorted([
                'host-%s' % uuids.cell0, 'host1-unavailable',
                'host2-unavailable'
            ]), sorted([svc.host for svc in services]))
        mock_sg.assert_called_once_with(self.ctxt,
                                        objects.ServiceList.get_all,
                                        None,
                                        set_zones=False)
        mock_get_hm.assert_called_once_with(self.ctxt, cells[1].id)

    def test_service_get_all_no_zones(self):
        services = [
            dict(test_service.fake_service,
                 id=1,
                 topic='compute',
                 host='host1'),
            dict(test_service.fake_service, topic='compute', host='host2')
        ]

        @mock.patch.object(self.host_api.db, 'service_get_all')
        def _do_test(mock_service_get_all):
            mock_service_get_all.return_value = services
            # Test no filters
            result = self.host_api.service_get_all(self.ctxt)
            mock_service_get_all.assert_called_once_with(self.ctxt,
                                                         disabled=None)
            self._compare_objs(result, services)

            # Test no filters #2
            mock_service_get_all.reset_mock()
            result = self.host_api.service_get_all(self.ctxt, filters={})
            mock_service_get_all.assert_called_once_with(self.ctxt,
                                                         disabled=None)
            self._compare_objs(result, services)

            # Test w/ filter
            mock_service_get_all.reset_mock()
            result = self.host_api.service_get_all(self.ctxt,
                                                   filters=dict(host='host2'))
            mock_service_get_all.assert_called_once_with(self.ctxt,
                                                         disabled=None)
            self._compare_objs(result, [services[1]])

        _do_test()

    def test_service_get_all(self):
        services = [
            dict(test_service.fake_service, topic='compute', host='host1'),
            dict(test_service.fake_service, topic='compute', host='host2')
        ]
        exp_services = []
        for service in services:
            exp_service = {}
            exp_service.update(availability_zone='nova', **service)
            exp_services.append(exp_service)

        @mock.patch.object(self.host_api.db, 'service_get_all')
        def _do_test(mock_service_get_all):
            mock_service_get_all.return_value = services

            # Test no filters
            result = self.host_api.service_get_all(self.ctxt, set_zones=True)
            mock_service_get_all.assert_called_once_with(self.ctxt,
                                                         disabled=None)
            self._compare_objs(result, exp_services)

            # Test no filters #2
            mock_service_get_all.reset_mock()
            result = self.host_api.service_get_all(self.ctxt,
                                                   filters={},
                                                   set_zones=True)
            mock_service_get_all.assert_called_once_with(self.ctxt,
                                                         disabled=None)
            self._compare_objs(result, exp_services)

            # Test w/ filter
            mock_service_get_all.reset_mock()
            result = self.host_api.service_get_all(self.ctxt,
                                                   filters=dict(host='host2'),
                                                   set_zones=True)
            mock_service_get_all.assert_called_once_with(self.ctxt,
                                                         disabled=None)
            self._compare_objs(result, [exp_services[1]])

            # Test w/ zone filter but no set_zones arg.
            mock_service_get_all.reset_mock()
            filters = {'availability_zone': 'nova'}
            result = self.host_api.service_get_all(self.ctxt, filters=filters)
            mock_service_get_all.assert_called_once_with(self.ctxt,
                                                         disabled=None)
            self._compare_objs(result, exp_services)

        _do_test()

    def test_service_get_by_compute_host(self):
        @mock.patch.object(self.host_api.db,
                           'service_get_by_compute_host',
                           return_value=test_service.fake_service)
        def _do_test(mock_service_get_by_compute_host):
            result = self.host_api.service_get_by_compute_host(
                self.ctxt, 'fake-host')
            self.assertEqual(test_service.fake_service['id'], result.id)

        _do_test()

    def test_service_update_by_host_and_binary(self):
        host_name = 'fake-host'
        binary = 'nova-compute'
        params_to_update = dict(disabled=True)
        service_id = 42
        expected_result = dict(test_service.fake_service, id=service_id)

        @mock.patch.object(self.host_api, '_update_compute_provider_status')
        @mock.patch.object(self.host_api.db, 'service_get_by_host_and_binary')
        @mock.patch.object(self.host_api.db, 'service_update')
        def _do_test(mock_service_update, mock_service_get_by_host_and_binary,
                     mock_update_compute_provider_status):
            mock_service_get_by_host_and_binary.return_value = expected_result
            mock_service_update.return_value = expected_result

            result = self.host_api.service_update_by_host_and_binary(
                self.ctxt, host_name, binary, params_to_update)
            self._compare_obj(result, expected_result)
            mock_update_compute_provider_status.assert_called_once_with(
                self.ctxt, test.MatchType(objects.Service))

        _do_test()

    @mock.patch('nova.compute.api.HostAPI._update_compute_provider_status',
                new_callable=mock.NonCallableMock)
    def test_service_update_no_update_provider_status(self, mock_ucps):
        """Tests the scenario that the service is updated but the disabled
        field is not changed, for example the forced_down field is only
        updated. In this case _update_compute_provider_status should not be
        called.
        """
        service = objects.Service(forced_down=True)
        self.assertIn('forced_down', service.obj_what_changed())
        with mock.patch.object(service, 'save') as mock_save:
            retval = self.host_api.service_update(self.ctxt, service)
            self.assertIs(retval, service)
            mock_save.assert_called_once_with()

    @mock.patch('nova.compute.rpcapi.ComputeAPI.set_host_enabled',
                new_callable=mock.NonCallableMock)
    def test_update_compute_provider_status_service_too_old(self, mock_she):
        """Tests the scenario that the service is up but is too old to sync the
        COMPUTE_STATUS_DISABLED trait.
        """
        service = objects.Service(host='fake-host')
        service.version = compute.MIN_COMPUTE_SYNC_COMPUTE_STATUS_DISABLED - 1
        with mock.patch.object(self.host_api.servicegroup_api,
                               'service_is_up',
                               return_value=True) as service_is_up:
            self.host_api._update_compute_provider_status(self.ctxt, service)
            service_is_up.assert_called_once_with(service)
        self.assertIn(
            'Compute service on host fake-host is too old to sync '
            'the COMPUTE_STATUS_DISABLED trait in Placement.',
            self.stdlog.logger.output)

    @mock.patch('nova.compute.rpcapi.ComputeAPI.set_host_enabled',
                side_effect=messaging.MessagingTimeout)
    def test_update_compute_provider_status_service_rpc_error(self, mock_she):
        """Tests the scenario that the RPC call to the compute service raised
        some exception.
        """
        service = objects.Service(host='fake-host', disabled=True)
        with mock.patch.object(self.host_api.servicegroup_api,
                               'service_is_up',
                               return_value=True) as service_is_up:
            self.host_api._update_compute_provider_status(self.ctxt, service)
            service_is_up.assert_called_once_with(service)
        mock_she.assert_called_once_with(self.ctxt, 'fake-host', False)
        log_output = self.stdlog.logger.output
        self.assertIn(
            'An error occurred while updating the '
            'COMPUTE_STATUS_DISABLED trait on compute node '
            'resource providers managed by host fake-host.', log_output)
        self.assertIn('MessagingTimeout', log_output)

    @mock.patch.object(objects.InstanceList,
                       'get_by_host',
                       return_value=['fake-responses'])
    def test_instance_get_all_by_host(self, mock_get):
        result = self.host_api.instance_get_all_by_host(self.ctxt, 'fake-host')
        self.assertEqual(['fake-responses'], result)

    def test_task_log_get_all(self):
        @mock.patch.object(self.host_api.db,
                           'task_log_get_all',
                           return_value='fake-response')
        def _do_test(mock_task_log_get_all):
            result = self.host_api.task_log_get_all(self.ctxt,
                                                    'fake-name',
                                                    'fake-begin',
                                                    'fake-end',
                                                    host='fake-host',
                                                    state='fake-state')
            self.assertEqual('fake-response', result)

        _do_test()

    @mock.patch.object(
        objects.CellMappingList,
        'get_all',
        return_value=objects.CellMappingList(objects=[
            objects.CellMapping(uuid=uuids.cell1_uuid,
                                transport_url='mq://fake1',
                                database_connection='db://fake1'),
            objects.CellMapping(uuid=uuids.cell2_uuid,
                                transport_url='mq://fake2',
                                database_connection='db://fake2'),
            objects.CellMapping(uuid=uuids.cell3_uuid,
                                transport_url='mq://fake3',
                                database_connection='db://fake3')
        ]))
    @mock.patch.object(
        objects.Service,
        'get_by_uuid',
        side_effect=[
            exception.ServiceNotFound(service_id=uuids.service_uuid),
            objects.Service(uuid=uuids.service_uuid)
        ])
    def test_service_get_by_id_using_uuid(self, service_get_by_uuid,
                                          cell_mappings_get_all):
        """Tests that we can lookup a service in the HostAPI using a uuid.
        There are two calls to objects.Service.get_by_uuid and the first
        raises ServiceNotFound so that we ensure we keep looping over the
        cells. We'll find the service in the second cell and break the loop
        so that we don't needlessly check in the third cell.
        """
        def _fake_set_target_cell(ctxt, cell_mapping):
            if cell_mapping:
                # These aren't really what would be set for values but let's
                # keep this simple so we can assert something is set when a
                # mapping is provided.
                ctxt.db_connection = cell_mapping.database_connection
                ctxt.mq_connection = cell_mapping.transport_url

        # We have to override the SingleCellSimple fixture.
        self.useFixture(
            fixtures.MonkeyPatch('nova.context.set_target_cell',
                                 _fake_set_target_cell))
        ctxt = context.get_admin_context()
        self.assertIsNone(ctxt.db_connection)
        self.host_api.service_get_by_id(ctxt, uuids.service_uuid)
        # We should have broken the loop over the cells and set the target cell
        # on the context.
        service_get_by_uuid.assert_has_calls(
            [mock.call(ctxt, uuids.service_uuid)] * 2)
        self.assertEqual('db://fake2', ctxt.db_connection)

    @mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
                'aggregate_remove_host')
    @mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
                'aggregate_add_host')
    @mock.patch.object(objects.ComputeNodeList, 'get_all_by_host')
    @mock.patch.object(objects.HostMapping, 'get_by_host')
    def test_service_delete_compute_in_aggregate(self, mock_hm, mock_get_cn,
                                                 mock_add_host,
                                                 mock_remove_host):
        compute = objects.Service(
            self.ctxt, **{
                'host': 'fake-compute-host',
                'binary': 'nova-compute',
                'topic': 'compute',
                'report_count': 0
            })
        compute.create()
        # This is needed because of lazy-loading service.compute_node
        cn = objects.ComputeNode(uuid=uuids.cn,
                                 host="fake-compute-host",
                                 hypervisor_hostname="fake-compute-host")
        mock_get_cn.return_value = [cn]
        aggregate = self.aggregate_api.create_aggregate(
            self.ctxt, 'aggregate', None)
        self.aggregate_api.add_host_to_aggregate(self.ctxt, aggregate.id,
                                                 'fake-compute-host')
        mock_add_host.assert_called_once_with(mock.ANY,
                                              aggregate.uuid,
                                              host_name='fake-compute-host')
        self.controller.delete(self.req, compute.id)
        result = self.aggregate_api.get_aggregate(self.ctxt,
                                                  aggregate.id).hosts
        self.assertEqual([], result)
        mock_hm.return_value.destroy.assert_called_once_with()
        mock_remove_host.assert_called_once_with(mock.ANY, aggregate.uuid,
                                                 'fake-compute-host')

    @mock.patch('nova.db.api.compute_node_statistics')
    def test_compute_node_statistics(self, mock_cns):
        # Note this should only be called twice
        mock_cns.side_effect = [
            {
                'stat1': 1,
                'stat2': 4.0
            },
            {
                'stat1': 5,
                'stat2': 1.2
            },
        ]
        compute.CELLS = [
            objects.CellMapping(uuid=uuids.cell1),
            objects.CellMapping(uuid=objects.CellMapping.CELL0_UUID),
            objects.CellMapping(uuid=uuids.cell2)
        ]
        stats = self.host_api.compute_node_statistics(self.ctxt)
        self.assertEqual({'stat1': 6, 'stat2': 5.2}, stats)

    @mock.patch.object(
        objects.CellMappingList,
        'get_all',
        return_value=objects.CellMappingList(objects=[
            objects.CellMapping(uuid=objects.CellMapping.CELL0_UUID,
                                transport_url='mq://cell0',
                                database_connection='db://cell0'),
            objects.CellMapping(uuid=uuids.cell1_uuid,
                                transport_url='mq://fake1',
                                database_connection='db://fake1'),
            objects.CellMapping(uuid=uuids.cell2_uuid,
                                transport_url='mq://fake2',
                                database_connection='db://fake2')
        ]))
    @mock.patch.object(objects.ComputeNode,
                       'get_by_uuid',
                       side_effect=[
                           exception.ComputeHostNotFound(host=uuids.cn_uuid),
                           objects.ComputeNode(uuid=uuids.cn_uuid)
                       ])
    def test_compute_node_get_using_uuid(self, compute_get_by_uuid,
                                         cell_mappings_get_all):
        """Tests that we can lookup a compute node in the HostAPI using a uuid.
        """
        self.host_api.compute_node_get(self.ctxt, uuids.cn_uuid)
        # cell0 should have been skipped, and the compute node wasn't found
        # in cell1 so we checked cell2 and found it
        self.assertEqual(2, compute_get_by_uuid.call_count)
        compute_get_by_uuid.assert_has_calls(
            [mock.call(self.ctxt, uuids.cn_uuid)] * 2)

    @mock.patch.object(
        objects.CellMappingList,
        'get_all',
        return_value=objects.CellMappingList(objects=[
            objects.CellMapping(uuid=objects.CellMapping.CELL0_UUID,
                                transport_url='mq://cell0',
                                database_connection='db://cell0'),
            objects.CellMapping(uuid=uuids.cell1_uuid,
                                transport_url='mq://fake1',
                                database_connection='db://fake1'),
            objects.CellMapping(uuid=uuids.cell2_uuid,
                                transport_url='mq://fake2',
                                database_connection='db://fake2')
        ]))
    @mock.patch.object(
        objects.ComputeNode,
        'get_by_uuid',
        side_effect=exception.ComputeHostNotFound(host=uuids.cn_uuid))
    def test_compute_node_get_not_found(self, compute_get_by_uuid,
                                        cell_mappings_get_all):
        """Tests that we can lookup a compute node in the HostAPI using a uuid
        and will fail with ComputeHostNotFound if we didn't find it in any
        cell.
        """
        self.assertRaises(exception.ComputeHostNotFound,
                          self.host_api.compute_node_get, self.ctxt,
                          uuids.cn_uuid)
        # cell0 should have been skipped, and the compute node wasn't found
        # in cell1 or cell2.
        self.assertEqual(2, compute_get_by_uuid.call_count)
        compute_get_by_uuid.assert_has_calls(
            [mock.call(self.ctxt, uuids.cn_uuid)] * 2)
 def _node(host, total_mem, total_disk, free_mem, free_disk):
     return objects.Service(host=host, disabled=False)
Exemple #18
0
 def test_version_set_on_init(self):
     self.assertEqual(service.SERVICE_VERSION, objects.Service().version)
Exemple #19
0
         hypervisor_version=3,
         hypervisor_hostname="hyper2",
         free_ram_mb=5 * 1024,
         free_disk_gb=125,
         current_workload=2,
         running_vms=2,
         cpu_info='cpu_info',
         disk_available_least=100,
         host_ip=netaddr.IPAddress('2.2.2.2'))
]

TEST_SERVICES = [
    objects.Service(id=1,
                    host="compute1",
                    binary="nova-compute",
                    topic="compute_topic",
                    report_count=5,
                    disabled=False,
                    disabled_reason=None,
                    availability_zone="nova"),
    objects.Service(id=2,
                    host="compute2",
                    binary="nova-compute",
                    topic="compute_topic",
                    report_count=5,
                    disabled=False,
                    disabled_reason=None,
                    availability_zone="nova"),
]

TEST_HYPERS_OBJ = [
    objects.ComputeNode(**hyper_dct) for hyper_dct in TEST_HYPERS
    def _create_instance_data(self):
        """Creates an instance record and associated data like BDMs, VIFs,
        migrations, etc in the source cell and returns the Instance object.

        The idea is to create as many things from the
        Instance.INSTANCE_OPTIONAL_ATTRS list as possible.

        :returns: The created Instance and Migration objects
        """
        # Create the nova-compute services record first.
        fake_service = test_service._fake_service()
        fake_service.pop('version', None)  # version field is immutable
        fake_service.pop('id', None)  # cannot create with an id set
        service = objects.Service(self.source_context, **fake_service)
        service.create()
        # Create the compute node using the service.
        fake_compute_node = copy.copy(test_compute_node.fake_compute_node)
        fake_compute_node['host'] = service.host
        fake_compute_node['hypervisor_hostname'] = service.host
        fake_compute_node['stats'] = {}  # the object requires a dict
        fake_compute_node['service_id'] = service.id
        fake_compute_node.pop('id', None)  # cannot create with an id set
        compute_node = objects.ComputeNode(self.source_context,
                                           **fake_compute_node)
        compute_node.create()

        # Build an Instance object with basic fields set.
        updates = {
            'metadata': {
                'foo': 'bar'
            },
            'system_metadata': {
                'roles': ['member']
            },
            'host': compute_node.host,
            'node': compute_node.hypervisor_hostname
        }
        inst = fake_instance.fake_instance_obj(self.source_context, **updates)
        delattr(inst, 'id')  # cannot create an instance with an id set
        # Now we have to dirty all of the fields because fake_instance_obj
        # uses Instance._from_db_object to create the Instance object we have
        # but _from_db_object calls obj_reset_changes() which resets all of
        # the fields that were on the object, including the basic stuff like
        # the 'host' field, which means those fields don't get set in the DB.
        # TODO(mriedem): This should live in fake_instance_obj with a
        # make_creatable kwarg.
        for field in inst.obj_fields:
            if field in inst:
                setattr(inst, field, getattr(inst, field))
        # Make sure at least one expected basic field is dirty on the Instance.
        self.assertIn('host', inst.obj_what_changed())
        # Set the optional fields on the instance before creating it.
        inst.pci_requests = objects.InstancePCIRequests(requests=[
            objects.InstancePCIRequest(
                **test_instance_pci_requests.fake_pci_requests[0])
        ])
        inst.numa_topology = objects.InstanceNUMATopology(
            cells=test_instance_numa.fake_obj_numa_topology.cells)
        inst.trusted_certs = objects.TrustedCerts(ids=[uuids.cert])
        inst.vcpu_model = test_vcpu_model.fake_vcpumodel
        inst.keypairs = objects.KeyPairList(
            objects=[objects.KeyPair(**test_keypair.fake_keypair)])
        inst.device_metadata = (
            test_instance_device_metadata.get_fake_obj_device_metadata(
                self.source_context))
        # FIXME(mriedem): db.instance_create does not handle tags
        inst.obj_reset_changes(['tags'])
        inst.create()

        bdm = {
            'instance_uuid': inst.uuid,
            'source_type': 'volume',
            'destination_type': 'volume',
            'volume_id': uuids.volume_id,
            'volume_size': 1,
            'device_name': '/dev/vda',
        }
        bdm = objects.BlockDeviceMapping(
            self.source_context,
            **fake_block_device.FakeDbBlockDeviceDict(bdm_dict=bdm))
        delattr(bdm, 'id')  # cannot create a bdm with an id set
        bdm.obj_reset_changes(['id'])
        bdm.create()

        vif = objects.VirtualInterface(self.source_context,
                                       address='de:ad:be:ef:ca:fe',
                                       uuid=uuids.port,
                                       instance_uuid=inst.uuid)
        vif.create()

        info_cache = objects.InstanceInfoCache().new(self.source_context,
                                                     inst.uuid)
        info_cache.network_info = network_model.NetworkInfo(
            [network_model.VIF(id=vif.uuid, address=vif.address)])
        info_cache.save(update_cells=False)

        objects.TagList.create(self.source_context, inst.uuid, ['test'])

        try:
            raise test.TestingException('test-fault')
        except test.TestingException as fault:
            compute_utils.add_instance_fault_from_exc(self.source_context,
                                                      inst, fault)

        objects.InstanceAction().action_start(self.source_context,
                                              inst.uuid,
                                              'resize',
                                              want_result=False)
        objects.InstanceActionEvent().event_start(self.source_context,
                                                  inst.uuid,
                                                  'migrate_server',
                                                  want_result=False)

        # Create a fake migration for the cross-cell resize operation.
        migration = objects.Migration(
            self.source_context,
            **test_migration.fake_db_migration(instance_uuid=inst.uuid,
                                               cross_cell_move=True,
                                               migration_type='resize'))
        delattr(migration, 'id')  # cannot create a migration with an id set
        migration.obj_reset_changes(['id'])
        migration.create()

        # Create an old non-resize migration to make sure it is copied to the
        # target cell database properly.
        old_migration = objects.Migration(
            self.source_context,
            **test_migration.fake_db_migration(instance_uuid=inst.uuid,
                                               migration_type='live-migration',
                                               status='completed',
                                               uuid=uuids.old_migration))
        delattr(old_migration, 'id')  # cannot create a migration with an id
        old_migration.obj_reset_changes(['id'])
        old_migration.create()

        fake_pci_device = copy.copy(test_pci_device.fake_db_dev)
        fake_pci_device['extra_info'] = {}  # the object requires a dict
        fake_pci_device['compute_node_id'] = compute_node.id
        pci_device = objects.PciDevice.create(self.source_context,
                                              fake_pci_device)
        pci_device.allocate(inst)  # sets the status and instance_uuid fields
        pci_device.save()

        # Return a fresh copy of the instance from the DB with as many joined
        # fields loaded as possible.
        expected_attrs = copy.copy(instance_obj.INSTANCE_OPTIONAL_ATTRS)
        # Cannot load fault from get_by_uuid.
        expected_attrs.remove('fault')
        inst = objects.Instance.get_by_uuid(self.source_context,
                                            inst.uuid,
                                            expected_attrs=expected_attrs)
        return inst, migration
Exemple #21
0
 def test_create_equal_to_minimum(self, mock_get):
     with mock.patch('nova.objects.service.SERVICE_VERSION', new=2):
         objects.Service(context=self.context,
                         binary='nova-compute').create()
Exemple #22
0
 def test_create_above_minimum(self, mock_get, mock_notify):
     with mock.patch('nova.objects.service.SERVICE_VERSION', new=3):
         objects.Service(context=self.context,
                         binary='nova-compute').create()
Exemple #23
0
    def setUp(self):
        super(NovaManageDBIronicTest, self).setUp()
        self.commands = manage.DbCommands()
        self.context = context.RequestContext('fake-user', 'fake-project')

        self.service1 = objects.Service(context=self.context,
                                        host='fake-host1',
                                        binary='nova-compute',
                                        topic='fake-host1',
                                        report_count=1,
                                        disabled=False,
                                        disabled_reason=None,
                                        availability_zone='nova',
                                        forced_down=False)
        self.service1.create()

        self.service2 = objects.Service(context=self.context,
                                        host='fake-host2',
                                        binary='nova-compute',
                                        topic='fake-host2',
                                        report_count=1,
                                        disabled=False,
                                        disabled_reason=None,
                                        availability_zone='nova',
                                        forced_down=False)
        self.service2.create()

        self.service3 = objects.Service(context=self.context,
                                        host='fake-host3',
                                        binary='nova-compute',
                                        topic='fake-host3',
                                        report_count=1,
                                        disabled=False,
                                        disabled_reason=None,
                                        availability_zone='nova',
                                        forced_down=False)
        self.service3.create()

        self.cn1 = objects.ComputeNode(context=self.context,
                                       service_id=self.service1.id,
                                       host='fake-host1',
                                       hypervisor_type='ironic',
                                       vcpus=1,
                                       memory_mb=1024,
                                       local_gb=10,
                                       vcpus_used=1,
                                       memory_mb_used=1024,
                                       local_gb_used=10,
                                       hypervisor_version=0,
                                       hypervisor_hostname='fake-node1',
                                       cpu_info='{}')
        self.cn1.create()

        self.cn2 = objects.ComputeNode(context=self.context,
                                       service_id=self.service1.id,
                                       host='fake-host1',
                                       hypervisor_type='ironic',
                                       vcpus=1,
                                       memory_mb=1024,
                                       local_gb=10,
                                       vcpus_used=1,
                                       memory_mb_used=1024,
                                       local_gb_used=10,
                                       hypervisor_version=0,
                                       hypervisor_hostname='fake-node2',
                                       cpu_info='{}')
        self.cn2.create()

        self.cn3 = objects.ComputeNode(context=self.context,
                                       service_id=self.service2.id,
                                       host='fake-host2',
                                       hypervisor_type='ironic',
                                       vcpus=1,
                                       memory_mb=1024,
                                       local_gb=10,
                                       vcpus_used=1,
                                       memory_mb_used=1024,
                                       local_gb_used=10,
                                       hypervisor_version=0,
                                       hypervisor_hostname='fake-node3',
                                       cpu_info='{}')
        self.cn3.create()

        self.cn4 = objects.ComputeNode(context=self.context,
                                       service_id=self.service3.id,
                                       host='fake-host3',
                                       hypervisor_type='libvirt',
                                       vcpus=1,
                                       memory_mb=1024,
                                       local_gb=10,
                                       vcpus_used=1,
                                       memory_mb_used=1024,
                                       local_gb_used=10,
                                       hypervisor_version=0,
                                       hypervisor_hostname='fake-node4',
                                       cpu_info='{}')
        self.cn4.create()

        self.cn5 = objects.ComputeNode(context=self.context,
                                       service_id=self.service2.id,
                                       host='fake-host2',
                                       hypervisor_type='ironic',
                                       vcpus=1,
                                       memory_mb=1024,
                                       local_gb=10,
                                       vcpus_used=1,
                                       memory_mb_used=1024,
                                       local_gb_used=10,
                                       hypervisor_version=0,
                                       hypervisor_hostname='fake-node5',
                                       cpu_info='{}')
        self.cn5.create()

        self.insts = []
        for cn in (self.cn1, self.cn2, self.cn3, self.cn4, self.cn4, self.cn5):
            flavor = objects.Flavor(extra_specs={})
            inst = objects.Instance(context=self.context,
                                    user_id=self.context.user_id,
                                    project_id=self.context.project_id,
                                    flavor=flavor,
                                    node=cn.hypervisor_hostname)
            inst.create()
            self.insts.append(inst)

        self.ironic_insts = [
            i for i in self.insts if i.node != self.cn4.hypervisor_hostname
        ]
        self.virt_insts = [
            i for i in self.insts if i.node == self.cn4.hypervisor_hostname
        ]
Exemple #24
0
 def test_service_create_with_notification(self, mock_db_service_create):
     service_obj = objects.Service(context=self.ctxt)
     service_obj["uuid"] = fake_service["uuid"]
     mock_db_service_create.return_value = fake_service
     self._verify_notification(service_obj,
                               fields.NotificationAction.CREATE)
Exemple #25
0
        disk_allocation_ratio=1.0),
    # Broken entry
    objects.ComputeNode(
        id=5,
        local_gb=50,
        memory_mb=5120,
        vcpus=1,
        host='fake',
        cpu_info='baremetal cpu',
        stats=dict(ironic_driver="nova.virt.ironic.driver.IronicDriver",
                   cpu_arch='i386'),
        supported_hv_specs=[
            objects.HVSpec.from_list(["i386", "baremetal", "baremetal"])
        ],
        free_disk_gb=50,
        free_ram_mb=5120,
        hypervisor_hostname='fake-hyp'),
]

SERVICES = [
    objects.Service(host='host1', disabled=False),
    objects.Service(host='host2', disabled=True),
    objects.Service(host='host3', disabled=False),
    objects.Service(host='host4', disabled=False),
]


def get_service_by_host(host):
    services = [service for service in SERVICES if service.host == host]
    return services[0]
Exemple #26
0
 def test_service_destroy_with_notification(self, mock_db_service_destroy):
     service = copy.deepcopy(fake_service)
     service.pop("version")
     service_obj = objects.Service(context=self.ctxt, **service)
     self._verify_notification(service_obj,
                               fields.NotificationAction.DELETE)
Exemple #27
0
 def fake_service_get_by_compute_host(self, context, host):
     return cells_utils.ServiceProxy(
         objects.Service(id=1,
                         host='fake-mini',
                         disabled=False,
                         disabled_reason=None), 'cell1')
Exemple #28
0
    def test_get_host_supporting_request_both_first_and_second_too_old(
            self, mock_get_service, mock_delete_allocation,
            mock_claim_resources, mock_debug):
        self.request_spec.requested_resources = [objects.RequestGroup()]
        task = self._generate_task()
        resources = {
            "resources": {
                "VCPU": 1,
                "MEMORY_MB": 1024,
                "DISK_GB": 100
            }
        }

        first = objects.Selection(service_host="host1",
                                  nodename="node1",
                                  cell_uuid=uuids.cell1,
                                  allocation_request=jsonutils.dumps({
                                      "allocations": {
                                          uuids.host1: resources
                                      }
                                  }),
                                  allocation_request_version='1.19')
        second = objects.Selection(service_host="host2",
                                   nodename="node2",
                                   cell_uuid=uuids.cell1,
                                   allocation_request=jsonutils.dumps({
                                       "allocations": {
                                           uuids.host2: resources
                                       }
                                   }),
                                   allocation_request_version='1.19')
        third = objects.Selection(service_host="host3",
                                  nodename="node3",
                                  cell_uuid=uuids.cell1,
                                  allocation_request=jsonutils.dumps({
                                      "allocations": {
                                          uuids.host3: resources
                                      }
                                  }),
                                  allocation_request_version='1.19')
        fourth = objects.Selection(service_host="host4",
                                   nodename="node4",
                                   cell_uuid=uuids.cell1,
                                   allocation_request=jsonutils.dumps({
                                       "allocations": {
                                           uuids.host4: resources
                                       }
                                   }),
                                   allocation_request_version='1.19')
        selection_list = [first, second, third, fourth]

        first_service = objects.Service(service_host='host1')
        first_service.version = 38
        second_service = objects.Service(service_host='host2')
        second_service.version = 38
        third_service = objects.Service(service_host='host3')
        third_service.version = 39
        mock_get_service.side_effect = [
            first_service, second_service, third_service
        ]
        # not called for the first and second hosts but called for the third
        mock_claim_resources.side_effect = [True]

        selected, alternates = task._get_host_supporting_request(
            selection_list)

        self.assertEqual(third, selected)
        self.assertEqual([fourth], alternates)
        mock_get_service.assert_has_calls([
            mock.call(task.context, 'host1', 'nova-compute'),
            mock.call(task.context, 'host2', 'nova-compute'),
            mock.call(task.context, 'host3', 'nova-compute'),
        ])
        mock_delete_allocation.assert_called_once_with(task.context,
                                                       self.instance.uuid)
        mock_claim_resources.assert_called_once_with(
            self.context, task.reportclient, task.request_spec,
            self.instance.uuid, {"allocations": {
                uuids.host3: resources
            }}, '1.19')
        mock_debug.assert_has_calls([
            mock.call(
                'Scheduler returned host %(host)s as a possible migration '
                'target but that host is not new enough to support the '
                'migration with resource request %(request)s or the compute '
                'RPC is pinned to less than 5.2. Trying alternate hosts.', {
                    'host': 'host1',
                    'request': self.request_spec.requested_resources
                },
                instance=self.instance),
            mock.call(
                'Scheduler returned alternate host %(host)s as a possible '
                'migration target but that host is not new enough to support '
                'the migration with resource request %(request)s or the '
                'compute RPC is pinned to less than 5.2. Trying another '
                'alternate.', {
                    'host': 'host2',
                    'request': self.request_spec.requested_resources
                },
                instance=self.instance),
        ])
 def test_compat_service_id(self, mock_get):
     mock_get.return_value = objects.Service(id=1)
     compute = objects.ComputeNode(host='fake-host', service_id=None)
     primitive = compute.obj_to_primitive(target_version='1.12')
     self.assertEqual(1, primitive['nova_object.data']['service_id'])
Exemple #30
0
    def test_reschedule_old_computes_no_more_alternates(
            self, mock_get_service, mock_claim_resources, mock_fill_mapping,
            mock_debug):
        self.request_spec.requested_resources = [objects.RequestGroup()]
        task = self._generate_task()
        resources = {
            "resources": {
                "VCPU": 1,
                "MEMORY_MB": 1024,
                "DISK_GB": 100
            }
        }

        first = objects.Selection(service_host="host1",
                                  nodename="node1",
                                  cell_uuid=uuids.cell1,
                                  allocation_request=jsonutils.dumps({
                                      "allocations": {
                                          uuids.host1: resources
                                      }
                                  }),
                                  allocation_request_version='1.19')
        second = objects.Selection(service_host="host2",
                                   nodename="node2",
                                   cell_uuid=uuids.cell1,
                                   allocation_request=jsonutils.dumps({
                                       "allocations": {
                                           uuids.host2: resources
                                       }
                                   }),
                                   allocation_request_version='1.19')

        first_service = objects.Service(service_host='host1')
        first_service.version = 38
        second_service = objects.Service(service_host='host2')
        second_service.version = 38
        mock_get_service.side_effect = [first_service, second_service]

        # set up task for re-schedule
        task.host_list = [first, second]

        self.assertRaises(exception.MaxRetriesExceeded, task._reschedule)

        self.assertEqual([], task.host_list)
        mock_get_service.assert_has_calls([
            mock.call(task.context, 'host1', 'nova-compute'),
            mock.call(task.context, 'host2', 'nova-compute'),
        ])
        mock_claim_resources.assert_not_called()
        mock_fill_mapping.assert_not_called()
        mock_debug.assert_has_calls([
            mock.call(
                'Scheduler returned alternate host %(host)s as a possible '
                'migration target for re-schedule but that host is not '
                'new enough to support the migration with resource '
                'request %(request)s. Trying another alternate.', {
                    'host': 'host1',
                    'request': self.request_spec.requested_resources
                },
                instance=self.instance),
            mock.call(
                'Scheduler returned alternate host %(host)s as a possible '
                'migration target for re-schedule but that host is not '
                'new enough to support the migration with resource '
                'request %(request)s. Trying another alternate.', {
                    'host': 'host2',
                    'request': self.request_spec.requested_resources
                },
                instance=self.instance),
        ])