コード例 #1
0
ファイル: shelve.py プロジェクト: juju812/openstack_kolla
    def _unshelve(self, req, id, body):
        """Restore an instance from shelved mode."""
        context = req.environ["nova.context"]
        context.can(shelve_policies.POLICY_ROOT % 'unshelve')
        instance = common.get_instance(self.compute_api, context, id)

        # We could potentially move this check to conductor and avoid the
        # extra API call to neutron when we support move operations with ports
        # having resource requests.
        if (instance.vm_state == vm_states.SHELVED_OFFLOADED
                and common.instance_has_port_with_resource_request(
                    context, instance.uuid, self.network_api) and
                not common.supports_port_resource_request_during_move(req)):
            msg = _("The unshelve action on a server with ports having "
                    "resource requests, like a port with a QoS minimum "
                    "bandwidth policy, is not supported with this "
                    "microversion")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.unshelve(context, instance)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'unshelve', id)
コード例 #2
0
ファイル: shelve.py プロジェクト: arbrandes/nova
    def _unshelve(self, req, id, body):
        """Restore an instance from shelved mode."""
        context = req.environ["nova.context"]
        context.can(shelve_policies.POLICY_ROOT % 'unshelve')
        instance = common.get_instance(self.compute_api, context, id)

        # We could potentially move this check to conductor and avoid the
        # extra API call to neutron when we support move operations with ports
        # having resource requests.
        if (instance.vm_state == vm_states.SHELVED_OFFLOADED
                and common.instance_has_port_with_resource_request(
                    context, instance.uuid, self.network_api)
                and not common.supports_port_resource_request_during_move(
                    req)):
            msg = _("The unshelve action on a server with ports having "
                    "resource requests, like a port with a QoS minimum "
                    "bandwidth policy, is not supported with this "
                    "microversion")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.unshelve(context, instance)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                                                                  'unshelve',
                                                                  id)
コード例 #3
0
ファイル: shelve.py プロジェクト: Aman306/nova
    def _unshelve(self, req, id, body):
        """Restore an instance from shelved mode."""
        context = req.environ["nova.context"]
        context.can(shelve_policies.POLICY_ROOT % 'unshelve')
        instance = common.get_instance(self.compute_api, context, id)

        if (instance.vm_state == vm_states.SHELVED_OFFLOADED
                and common.instance_has_port_with_resource_request(
                    context, instance.uuid, self.network_api)
                and not common.supports_port_resource_request_during_move(
                    req)):
            msg = _("The unshelve server operation on a shelve offloaded "
                    "server with port having QoS policy is not supported.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.unshelve(context, instance)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                                                                  'unshelve',
                                                                  id)
コード例 #4
0
    def _migrate(self, req, id, body):
        """Permit admins to migrate a server to a new host."""
        context = req.environ['nova.context']
        context.can(ms_policies.POLICY_ROOT % 'migrate')

        host_name = None
        if (api_version_request.is_supported(req, min_version='2.56')
                and body['migrate'] is not None):
            host_name = body['migrate'].get('host')

        instance = common.get_instance(self.compute_api,
                                       context,
                                       id,
                                       expected_attrs=['flavor'])

        # We could potentially move this check to conductor and avoid the
        # extra API call to neutron when we support move operations with ports
        # having resource requests.
        if common.instance_has_port_with_resource_request(
                context, instance.uuid, self.network_api):
            if not common.supports_port_resource_request_during_move(req):
                msg = _("The migrate action on a server with ports having "
                        "resource requests, like a port with a QoS minimum "
                        "bandwidth policy, is not supported with this "
                        "microversion")
                raise exc.HTTPBadRequest(explanation=msg)

            # TODO(gibi): Remove when nova only supports compute newer than
            # Train
            source_service = objects.Service.get_by_host_and_binary(
                context, instance.host, 'nova-compute')
            if source_service.version < MIN_COMPUTE_MOVE_BANDWIDTH:
                msg = _("The migrate action on a server with ports having "
                        "resource requests, like a port with a QoS "
                        "minimum bandwidth policy, is not yet supported "
                        "on the source compute")
                raise exc.HTTPConflict(explanation=msg)

        try:
            self.compute_api.resize(req.environ['nova.context'],
                                    instance,
                                    host_name=host_name)
        except (exception.TooManyInstances, exception.QuotaError) as e:
            raise exc.HTTPForbidden(explanation=e.format_message())
        except (exception.InstanceIsLocked,
                exception.CannotMigrateWithTargetHost,
                exception.AllocationMoveFailed) as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'migrate', id)
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.NoValidHost, exception.ComputeHostNotFound,
                exception.CannotMigrateToSameHost) as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
コード例 #5
0
ファイル: migrate_server.py プロジェクト: liuxinf/nova
    def _migrate(self, req, id, body):
        """Permit admins to migrate a server to a new host."""
        context = req.environ['nova.context']

        instance = common.get_instance(self.compute_api, context, id,
                                       expected_attrs=['flavor', 'services'])
        context.can(ms_policies.POLICY_ROOT % 'migrate',
                    target={'project_id': instance.project_id})

        host_name = None
        if (api_version_request.is_supported(req, min_version='2.56') and
            body['migrate'] is not None):
            host_name = body['migrate'].get('host')

        if common.instance_has_port_with_resource_request(
                instance.uuid, self.network_api):
            # TODO(gibi): Remove when nova only supports compute newer than
            # Train
            source_service = objects.Service.get_by_host_and_binary(
                context, instance.host, 'nova-compute')
            if source_service.version < MIN_COMPUTE_MOVE_BANDWIDTH:
                msg = _("The migrate action on a server with ports having "
                        "resource requests, like a port with a QoS "
                        "minimum bandwidth policy, is not yet supported "
                        "on the source compute")
                raise exc.HTTPConflict(explanation=msg)

        try:
            self.compute_api.resize(req.environ['nova.context'], instance,
                                    host_name=host_name)
        except (exception.TooManyInstances, exception.QuotaError,
                exception.ForbiddenWithAccelerators) as e:
            raise exc.HTTPForbidden(explanation=e.format_message())
        except (
            exception.InstanceIsLocked,
            exception.InstanceNotReady,
            exception.OperationNotSupportedForVTPM,
            exception.ServiceUnavailable,
        ) as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'migrate', id)
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.ComputeHostNotFound,
                exception.CannotMigrateToSameHost) as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
コード例 #6
0
    def test_instance_has_port_with_resource_request(self):
        network_api = mock.Mock(spec=network.API())
        network_api.list_ports.return_value = {'ports': [
            {'resource_request': mock.sentinel.request}
        ]}
        res = common.instance_has_port_with_resource_request(
            mock.sentinel.uuid, network_api)

        self.assertTrue(res)
        network_api.list_ports.assert_called_once_with(
            test.MatchType(context.RequestContext),
            device_id=mock.sentinel.uuid, fields=['resource_request'])
        # assert that the neutron call uses an admin context
        ctxt = network_api.mock_calls[0][1][0]
        self.assertTrue(ctxt.is_admin)
        self.assertIsNone(ctxt.auth_token)
コード例 #7
0
ファイル: shelve.py プロジェクト: wangyc666666/ussuri_nova
    def _unshelve(self, req, id, body):
        """Restore an instance from shelved mode."""
        context = req.environ["nova.context"]
        instance = common.get_instance(self.compute_api, context, id)
        context.can(shelve_policies.POLICY_ROOT % 'unshelve',
                    target={'project_id': instance.project_id})

        new_az = None
        host = None
        unshelve_dict = body['unshelve']
        support_az = api_version_request.is_supported(req, '2.77')
        if support_az and unshelve_dict:
            new_az = unshelve_dict['availability_zone']
            host = unshelve_dict['host']

        # We could potentially move this check to conductor and avoid the
        # extra API call to neutron when we support move operations with ports
        # having resource requests.
        if (instance.vm_state == vm_states.SHELVED_OFFLOADED
                and common.instance_has_port_with_resource_request(
                    instance.uuid, self.network_api)
                and not common.supports_port_resource_request_during_move()):
            LOG.warning("The unshelve action on a server with ports having "
                        "resource requests, like a port with a QoS minimum "
                        "bandwidth policy, is not supported until every "
                        "nova-compute is upgraded to Ussuri")
            msg = _("The unshelve action on a server with ports having "
                    "resource requests, like a port with a QoS minimum "
                    "bandwidth policy, is not supported by this cluster right "
                    "now")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            #change wyc
            self.compute_api.unshelve(context,
                                      instance,
                                      new_az=new_az,
                                      host=host)
        except (exception.InstanceIsLocked,
                exception.UnshelveInstanceInvalidState,
                exception.MismatchVolumeAZException) as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'unshelve', id)
        except exception.InvalidRequest as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
コード例 #8
0
ファイル: migrate_server.py プロジェクト: arbrandes/nova
    def _migrate(self, req, id, body):
        """Permit admins to migrate a server to a new host."""
        context = req.environ['nova.context']
        context.can(ms_policies.POLICY_ROOT % 'migrate')

        host_name = None
        if (api_version_request.is_supported(req, min_version='2.56') and
            body['migrate'] is not None):
            host_name = body['migrate'].get('host')

        instance = common.get_instance(self.compute_api, context, id)

        # We could potentially move this check to conductor and avoid the
        # extra API call to neutron when we support move operations with ports
        # having resource requests.
        if (common.instance_has_port_with_resource_request(
                    context, instance.uuid, self.network_api) and not
                common.supports_port_resource_request_during_move(req)):
            msg = _("The migrate action on a server with ports having "
                    "resource requests, like a port with a QoS minimum "
                    "bandwidth policy, is not supported with this "
                    "microversion")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.resize(req.environ['nova.context'], instance,
                                    host_name=host_name)
        except (exception.TooManyInstances, exception.QuotaError) as e:
            raise exc.HTTPForbidden(explanation=e.format_message())
        except (exception.InstanceIsLocked,
                exception.CannotMigrateWithTargetHost,
                exception.AllocationMoveFailed) as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'migrate', id)
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.NoValidHost, exception.ComputeHostNotFound,
                exception.CannotMigrateToSameHost) as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
コード例 #9
0
ファイル: shelve.py プロジェクト: otc-mfc/nova
    def _unshelve(self, req, id, body):
        """Restore an instance from shelved mode."""
        context = req.environ["nova.context"]
        context.can(shelve_policies.POLICY_ROOT % 'unshelve')
        instance = common.get_instance(self.compute_api, context, id)

        new_az = None
        unshelve_dict = body['unshelve']
        if unshelve_dict and 'availability_zone' in unshelve_dict:
            support_az = api_version_request.is_supported(req, '2.77')
            if support_az:
                new_az = unshelve_dict['availability_zone']

        # We could potentially move this check to conductor and avoid the
        # extra API call to neutron when we support move operations with ports
        # having resource requests.
        if (instance.vm_state == vm_states.SHELVED_OFFLOADED
                and common.instance_has_port_with_resource_request(
                    context, instance.uuid, self.network_api) and
                not common.supports_port_resource_request_during_move(req)):
            msg = _("The unshelve action on a server with ports having "
                    "resource requests, like a port with a QoS minimum "
                    "bandwidth policy, is not supported with this "
                    "microversion")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.unshelve(context, instance, new_az=new_az)
        except (exception.InstanceIsLocked,
                exception.UnshelveInstanceInvalidState,
                exception.MismatchVolumeAZException) as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'unshelve', id)
        except exception.InvalidRequest as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
コード例 #10
0
ファイル: migrate_server.py プロジェクト: Aman306/nova
    def _migrate(self, req, id, body):
        """Permit admins to migrate a server to a new host."""
        context = req.environ['nova.context']
        context.can(ms_policies.POLICY_ROOT % 'migrate')

        host_name = None
        if (api_version_request.is_supported(req, min_version='2.56')
                and body['migrate'] is not None):
            host_name = body['migrate'].get('host')

        instance = common.get_instance(self.compute_api, context, id)

        if (common.instance_has_port_with_resource_request(
                context, instance.uuid, self.network_api) and
                not common.supports_port_resource_request_during_move(req)):
            msg = _("The migrate server operation with port having QoS policy "
                    "is not supported.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.resize(req.environ['nova.context'],
                                    instance,
                                    host_name=host_name)
        except (exception.TooManyInstances, exception.QuotaError) as e:
            raise exc.HTTPForbidden(explanation=e.format_message())
        except (exception.InstanceIsLocked,
                exception.CannotMigrateWithTargetHost,
                exception.AllocationMoveFailed) as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'migrate', id)
        except exception.InstanceNotFound as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.NoValidHost, exception.ComputeHostNotFound,
                exception.CannotMigrateToSameHost) as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
コード例 #11
0
ファイル: migrate_server.py プロジェクト: potato-chip/nova
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["nova.context"]
        context.can(ms_policies.POLICY_ROOT % 'migrate_live')

        host = body["os-migrateLive"]["host"]
        block_migration = body["os-migrateLive"]["block_migration"]
        force = None
        async_ = api_version_request.is_supported(req, min_version='2.34')
        if api_version_request.is_supported(req, min_version='2.30'):
            force = self._get_force_param_for_live_migration(body, host)
        if api_version_request.is_supported(req, min_version='2.25'):
            if block_migration == 'auto':
                block_migration = None
            else:
                block_migration = strutils.bool_from_string(block_migration,
                                                            strict=True)
            disk_over_commit = None
        else:
            disk_over_commit = body["os-migrateLive"]["disk_over_commit"]

            block_migration = strutils.bool_from_string(block_migration,
                                                        strict=True)
            disk_over_commit = strutils.bool_from_string(disk_over_commit,
                                                         strict=True)

        # NOTE(stephenfin): we need 'numa_topology' because of the
        # 'LiveMigrationTask._check_instance_has_no_numa' check in the
        # conductor
        instance = common.get_instance(self.compute_api,
                                       context,
                                       id,
                                       expected_attrs=['numa_topology'])

        # We could potentially move this check to conductor and avoid the
        # extra API call to neutron when we support move operations with ports
        # having resource requests.
        if (common.instance_has_port_with_resource_request(
                context, instance.uuid, self.network_api) and
                not common.supports_port_resource_request_during_move(req)):
            msg = _("The os-migrateLive action on a server with ports having "
                    "resource requests, like a port with a QoS minimum "
                    "bandwidth policy, is not supported with this "
                    "microversion")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.live_migrate(context, instance, block_migration,
                                          disk_over_commit, host, force,
                                          async_)
        except (exception.NoValidHost, exception.ComputeServiceUnavailable,
                exception.InvalidHypervisorType, exception.InvalidCPUInfo,
                exception.UnableToMigrateToSelf,
                exception.DestinationHypervisorTooOld,
                exception.InvalidLocalStorage, exception.InvalidSharedStorage,
                exception.HypervisorUnavailable,
                exception.MigrationPreCheckError) as ex:
            if async_:
                with excutils.save_and_reraise_exception():
                    LOG.error(
                        "Unexpected exception received from "
                        "conductor during pre-live-migration checks "
                        "'%(ex)s'", {'ex': ex})
            else:
                raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.ComputeHostNotFound as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'os-migrateLive', id)
コード例 #12
0
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["nova.context"]
        instance = common.get_instance(self.compute_api, context, id)
        context.can(evac_policies.BASE_POLICY_NAME,
                    target={'user_id': instance.user_id,
                            'project_id': instance.project_id})

        evacuate_body = body["evacuate"]
        host = evacuate_body.get("host")
        force = None

        on_shared_storage = self._get_on_shared_storage(req, evacuate_body)

        if api_version_request.is_supported(req, min_version='2.29'):
            force = body["evacuate"].get("force", False)
            force = strutils.bool_from_string(force, strict=True)
            if force is True and not host:
                message = _("Can't force to a non-provided destination")
                raise exc.HTTPBadRequest(explanation=message)
        if api_version_request.is_supported(req, min_version='2.14'):
            password = self._get_password_v214(req, evacuate_body)
        else:
            password = self._get_password(req, evacuate_body,
                                          on_shared_storage)

        if host is not None:
            try:
                self.host_api.service_get_by_compute_host(context, host)
            except (exception.ComputeHostNotFound,
                    exception.HostMappingNotFound):
                msg = _("Compute host %s not found.") % host
                raise exc.HTTPNotFound(explanation=msg)

        if instance.host == host:
            msg = _("The target host can't be the same one.")
            raise exc.HTTPBadRequest(explanation=msg)

        # We could potentially move this check to conductor and avoid the
        # extra API call to neutron when we support move operations with ports
        # having resource requests.
        if (common.instance_has_port_with_resource_request(
                instance.uuid, self.network_api) and not
                common.supports_port_resource_request_during_move()):
            LOG.warning("The evacuate action on a server with ports "
                        "having resource requests, like a port with a QoS "
                        "minimum bandwidth policy, is not supported until "
                        "every nova-compute is upgraded to Ussuri")
            msg = _("The evacuate action on a server with ports having "
                    "resource requests, like a port with a QoS minimum "
                    "bandwidth policy, is not supported by this cluster right "
                    "now")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password, force)
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'evacuate', id)
        except exception.ComputeServiceInUse as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        except exception.ForbiddenWithAccelerators as e:
            raise exc.HTTPForbidden(explanation=e.format_message())
        except exception.OperationNotSupportedForVTPM as e:
            raise exc.HTTPConflict(explanation=e.format_message())

        if (not api_version_request.is_supported(req, min_version='2.14') and
                CONF.api.enable_instance_password):
            return {'adminPass': password}
        else:
            return None
コード例 #13
0
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["nova.context"]
        instance = common.get_instance(self.compute_api, context, id)
        context.can(evac_policies.BASE_POLICY_NAME,
                    target={
                        'user_id': instance.user_id,
                        'project_id': instance.project_id
                    })

        evacuate_body = body["evacuate"]
        host = evacuate_body.get("host")
        force = None

        on_shared_storage = self._get_on_shared_storage(req, evacuate_body)

        if api_version_request.is_supported(req, min_version='2.29'):
            force = body["evacuate"].get("force", False)
            force = strutils.bool_from_string(force, strict=True)
            if force is True and not host:
                message = _("Can't force to a non-provided destination")
                raise exc.HTTPBadRequest(explanation=message)
        if api_version_request.is_supported(req, min_version='2.14'):
            password = self._get_password_v214(req, evacuate_body)
        else:
            password = self._get_password(req, evacuate_body,
                                          on_shared_storage)

        if host is not None:
            try:
                self.host_api.service_get_by_compute_host(context, host)
            except (exception.ComputeHostNotFound,
                    exception.HostMappingNotFound):
                msg = _("Compute host %s not found.") % host
                raise exc.HTTPNotFound(explanation=msg)

        if instance.host == host:
            msg = _("The target host can't be the same one.")
            raise exc.HTTPBadRequest(explanation=msg)

        if (common.instance_has_port_with_resource_request(
                context, instance.uuid, self.network_api) and
                not common.supports_port_resource_request_during_move(req)):
            msg = _("The evacuate server operation with port having QoS "
                    "policy is not supported.")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password, force)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(
                state_error, 'evacuate', id)
        except exception.ComputeServiceInUse as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if (not api_version_request.is_supported(req, min_version='2.14')
                and CONF.api.enable_instance_password):
            return {'adminPass': password}
        else:
            return None
コード例 #14
0
ファイル: migrate_server.py プロジェクト: arbrandes/nova
    def _migrate_live(self, req, id, body):
        """Permit admins to (live) migrate a server to a new host."""
        context = req.environ["nova.context"]
        context.can(ms_policies.POLICY_ROOT % 'migrate_live')

        host = body["os-migrateLive"]["host"]
        block_migration = body["os-migrateLive"]["block_migration"]
        force = None
        async_ = api_version_request.is_supported(req, min_version='2.34')
        if api_version_request.is_supported(req, min_version='2.30'):
            force = self._get_force_param_for_live_migration(body, host)
        if api_version_request.is_supported(req, min_version='2.25'):
            if block_migration == 'auto':
                block_migration = None
            else:
                block_migration = strutils.bool_from_string(block_migration,
                                                            strict=True)
            disk_over_commit = None
        else:
            disk_over_commit = body["os-migrateLive"]["disk_over_commit"]

            block_migration = strutils.bool_from_string(block_migration,
                                                        strict=True)
            disk_over_commit = strutils.bool_from_string(disk_over_commit,
                                                         strict=True)

        # NOTE(stephenfin): we need 'numa_topology' because of the
        # 'LiveMigrationTask._check_instance_has_no_numa' check in the
        # conductor
        instance = common.get_instance(self.compute_api, context, id,
                                       expected_attrs=['numa_topology'])

        # We could potentially move this check to conductor and avoid the
        # extra API call to neutron when we support move operations with ports
        # having resource requests.
        if (common.instance_has_port_with_resource_request(
                    context, instance.uuid, self.network_api) and not
                common.supports_port_resource_request_during_move(req)):
            msg = _("The os-migrateLive action on a server with ports having "
                    "resource requests, like a port with a QoS minimum "
                    "bandwidth policy, is not supported with this "
                    "microversion")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.live_migrate(context, instance, block_migration,
                                          disk_over_commit, host, force,
                                          async_)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except (exception.NoValidHost,
                exception.ComputeServiceUnavailable,
                exception.InvalidHypervisorType,
                exception.InvalidCPUInfo,
                exception.UnableToMigrateToSelf,
                exception.DestinationHypervisorTooOld,
                exception.InvalidLocalStorage,
                exception.InvalidSharedStorage,
                exception.HypervisorUnavailable,
                exception.MigrationPreCheckError) as ex:
            if async_:
                with excutils.save_and_reraise_exception():
                    LOG.error("Unexpected exception received from "
                              "conductor during pre-live-migration checks "
                              "'%(ex)s'", {'ex': ex})
            else:
                raise exc.HTTPBadRequest(explanation=ex.format_message())
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.ComputeHostNotFound as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'os-migrateLive', id)
コード例 #15
0
ファイル: evacuate.py プロジェクト: arbrandes/nova
    def _evacuate(self, req, id, body):
        """Permit admins to evacuate a server from a failed host
        to a new one.
        """
        context = req.environ["nova.context"]
        instance = common.get_instance(self.compute_api, context, id)
        context.can(evac_policies.BASE_POLICY_NAME,
                    target={'user_id': instance.user_id,
                            'project_id': instance.project_id})

        evacuate_body = body["evacuate"]
        host = evacuate_body.get("host")
        force = None

        on_shared_storage = self._get_on_shared_storage(req, evacuate_body)

        if api_version_request.is_supported(req, min_version='2.29'):
            force = body["evacuate"].get("force", False)
            force = strutils.bool_from_string(force, strict=True)
            if force is True and not host:
                message = _("Can't force to a non-provided destination")
                raise exc.HTTPBadRequest(explanation=message)
        if api_version_request.is_supported(req, min_version='2.14'):
            password = self._get_password_v214(req, evacuate_body)
        else:
            password = self._get_password(req, evacuate_body,
                                          on_shared_storage)

        if host is not None:
            try:
                self.host_api.service_get_by_compute_host(context, host)
            except (exception.ComputeHostNotFound,
                    exception.HostMappingNotFound):
                msg = _("Compute host %s not found.") % host
                raise exc.HTTPNotFound(explanation=msg)

        if instance.host == host:
            msg = _("The target host can't be the same one.")
            raise exc.HTTPBadRequest(explanation=msg)

        # We could potentially move this check to conductor and avoid the
        # extra API call to neutron when we support move operations with ports
        # having resource requests.
        if (common.instance_has_port_with_resource_request(
                    context, instance.uuid, self.network_api) and not
                common.supports_port_resource_request_during_move(req)):
            msg = _("The evacuate action on a server with ports having "
                    "resource requests, like a port with a QoS minimum "
                    "bandwidth policy, is not supported with this "
                    "microversion")
            raise exc.HTTPBadRequest(explanation=msg)

        try:
            self.compute_api.evacuate(context, instance, host,
                                      on_shared_storage, password, force)
        except exception.InstanceUnknownCell as e:
            raise exc.HTTPNotFound(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'evacuate', id)
        except exception.ComputeServiceInUse as e:
            raise exc.HTTPBadRequest(explanation=e.format_message())

        if (not api_version_request.is_supported(req, min_version='2.14') and
                CONF.api.enable_instance_password):
            return {'adminPass': password}
        else:
            return None