示例#1
0
 def get_by_binary(cls, context, binary, include_disabled=False):
     db_services = db.service_get_all_by_binary(
         context, binary, include_disabled=include_disabled)
     return base.obj_make_list(context, cls(context), objects.Service,
                               db_services)
示例#2
0
    def test_instance_list_deleted_service_with_no_uuid(self):
        """This test covers the following scenario:

        1. create an instance on a host which we'll simulate to be old
           by not having a uuid set
        2. migrate the instance to the "newer" host that has a service uuid
        3. delete the old service/compute node
        4. start a new service with the old hostname (still host1); this will
           also create a new compute_nodes table record for that host/node
        5. migrate the instance back to the host1 service
        6. list instances which will try to online migrate the old service uuid
        """
        host1 = self.start_service('compute', host='host1')

        # Create an instance which will be on host1 since it's the only host.
        server_req = self._build_server(networks='none')
        server = self.api.post_server({'server': server_req})
        self._wait_for_state_change(server, 'ACTIVE')

        # Now we start a 2nd compute which is "upgraded" (has a uuid) and
        # we'll migrate the instance to that host.
        host2 = self.start_service('compute', host='host2')
        self.assertIsNotNone(host2.service_ref.uuid)

        server = self._migrate_server(server, 'host2')

        # Delete the host1 service (which implicitly deletes the host1 compute
        # node record).
        host1.stop()
        self.admin_api.api_delete('/os-services/%s' % host1.service_ref.uuid)
        # We should now only have 1 compute service (host2).
        compute_services = self.admin_api.api_get(
            '/os-services?binary=nova-compute').body['services']
        self.assertEqual(1, len(compute_services))
        # Make sure the compute node is also gone.
        self.admin_api.api_get(
            '/os-hypervisors?hypervisor_hostname_pattern=host1',
            check_response_status=[404])

        # Now recreate the host1 service and compute node by restarting the
        # service.
        self.restart_compute_service(host1)
        # At this point, host1's service should have a uuid.
        self.assertIsNotNone(host1.service_ref.uuid)

        # Sanity check that there are 3 services in the database, but only 1
        # is deleted.
        ctxt = nova_context.get_admin_context()
        with utils.temporary_mutation(ctxt, read_deleted='yes'):
            services = db.service_get_all_by_binary(ctxt, 'nova-compute')
            self.assertEqual(3, len(services))
            deleted_services = [svc for svc in services if svc['deleted']]
            self.assertEqual(1, len(deleted_services))
            deleted_service = deleted_services[0]
            self.assertEqual('host1', deleted_service['host'])

        # Now migrate the instance back to host1.
        self._migrate_server(server, 'host1')

        # Now null out the service uuid to simulate that the deleted host1
        # is old. We have to do this through the DB API directly since the
        # Service object won't allow a null uuid field. We also have to do
        # this *after* deleting the service via the REST API and migrating the
        # server because otherwise that will set a uuid when looking up the
        # service.
        with utils.temporary_mutation(ctxt, read_deleted='yes'):
            service_ref = db.service_update(ctxt, deleted_service['id'],
                                            {'uuid': None})
            self.assertIsNone(service_ref['uuid'])

        # Finally, list servers as an admin so it joins on services to get host
        # information.
        servers = self.admin_api.get_servers(detail=True)
        for server in servers:
            self.assertEqual('UP', server['host_status'])