Beispiel #1
0
 def save(self):
     updates = self.cinder_obj_get_changes()
     if "cluster" in updates:
         raise exception.ObjectActionError(action="save", reason=_("cluster changed"))
     if updates:
         db.service_update(self._context, self.id, updates)
         self.obj_reset_changes()
Beispiel #2
0
    def report_state(self):
        """Update the state of this service in the datastore."""
        ctxt = context.get_admin_context()
        zone = CONF.storage_availability_zone
        state_catalog = {}
        try:
            try:
                service_ref = db.service_get(ctxt, self.service_id)
            except exception.NotFound:
                LOG.debug(_('The service database object disappeared, '
                            'Recreating it.'))
                self._create_service_ref(ctxt)
                service_ref = db.service_get(ctxt, self.service_id)

            state_catalog['report_count'] = service_ref['report_count'] + 1
            if zone != service_ref['availability_zone']:
                state_catalog['availability_zone'] = zone

            db.service_update(ctxt,
                              self.service_id, state_catalog)

            # TODO(termie): make this pattern be more elegant.
            if getattr(self, 'model_disconnected', False):
                self.model_disconnected = False
                LOG.error(_('Recovered model server connection!'))

        # TODO(vish): this should probably only catch connection errors
        except Exception:  # pylint: disable=W0702
            if not getattr(self, 'model_disconnected', False):
                self.model_disconnected = True
                LOG.exception(_('model server went away'))
    def test_migrate_volume_generic_cross_az(self, migrate_volume_completion,
                                             nova_api):
        """Test that we set the right AZ in cross AZ migrations."""
        original_create = objects.Volume.create
        dst_az = 'AZ2'
        db.service_update(self.context, self._service.id,
                          {'availability_zone': dst_az})

        def my_create(self, *args, **kwargs):
            self.status = 'available'
            original_create(self, *args, **kwargs)

        volume = tests_utils.create_volume(self.context, size=1,
                                           host=CONF.host)

        host_obj = {'host': 'newhost', 'capabilities': {}}
        create_vol = self.patch('cinder.objects.Volume.create',
                                side_effect=my_create, autospec=True)

        with mock.patch.object(self.volume, '_copy_volume_data') as copy_mock:
            self.volume._migrate_volume_generic(self.context, volume, host_obj,
                                                None)
            copy_mock.assert_called_with(self.context, volume, mock.ANY,
                                         remote='dest')
        migrate_volume_completion.assert_called_with(
            self.context, volume, mock.ANY, error=False)

        nova_api.return_value.update_server_volume.assert_not_called()

        self.assertEqual(dst_az,
                         create_vol.call_args[0][0]['availability_zone'])
    def update(self, req, id, body):
        """Enable/Disable scheduling for a service"""
        context = req.environ['cinder.context']
        authorize(context)

        if id == "enable":
            disabled = False
        elif id == "disable":
            disabled = True
        else:
            raise webob.exc.HTTPNotFound("Unknown action")

        try:
            host = body['host']
            service = body['service']
        except (TypeError, KeyError):
            raise webob.exc.HTTPBadRequest()

        try:
            svc = db.service_get_by_args(context, host, service)
            if not svc:
                raise webob.exc.HTTPNotFound('Unknown service')

            db.service_update(context, svc['id'], {'disabled': disabled})
        except exception.ServiceNotFound:
            raise webob.exc.HTTPNotFound("service not found")

        return {'host': host, 'service': service, 'disabled': disabled}
Beispiel #5
0
    def update(self, req, id, body):
        """Enable/Disable scheduling for a service."""
        context = req.environ['cinder.context']
        authorize(context)

        ext_loaded = self.ext_mgr.is_loaded('os-extended-services')
        ret_val = {}
        if id == "enable":
            disabled = False
            status = "enabled"
            if ext_loaded:
                ret_val['disabled_reason'] = None
        elif (id == "disable" or
                (id == "disable-log-reason" and ext_loaded)):
            disabled = True
            status = "disabled"
        else:
            raise webob.exc.HTTPNotFound(explanation=_("Unknown action"))

        try:
            host = body['host']
        except (TypeError, KeyError):
            raise webob.exc.HTTPBadRequest()

        ret_val['disabled'] = disabled
        if id == "disable-log-reason" and ext_loaded:
            reason = body.get('disabled_reason')
            if not self._is_valid_as_reason(reason):
                msg = _('Disabled reason contains invalid characters '
                        'or is too long')
                raise webob.exc.HTTPBadRequest(explanation=msg)
            ret_val['disabled_reason'] = reason

        # NOTE(uni): deprecating service request key, binary takes precedence
        # Still keeping service key here for API compatibility sake.
        service = body.get('service', '')
        binary = body.get('binary', '')
        binary_key = binary or service
        if not binary_key:
            raise webob.exc.HTTPBadRequest()

        try:
            svc = db.service_get_by_args(context, host, binary_key)
            if not svc:
                raise webob.exc.HTTPNotFound(explanation=_('Unknown service'))

            db.service_update(context, svc['id'], ret_val)
        except exception.HostBinaryNotFound:
            raise webob.exc.HTTPNotFound(explanation=_("host or binary not found"))
        except exception.ServiceNotFound:
            raise webob.exc.HTTPNotFound(explanation=_("service not found"))

        ret_val.update({'host': host, 'service': service,
                        'binary': binary, 'status': status})
        return ret_val
Beispiel #6
0
    def report_state(self):
        """Update the state of this service in the datastore."""
        if not self.manager.is_working():
            # NOTE(dulek): If manager reports a problem we're not sending
            # heartbeats - to indicate that service is actually down.
            LOG.error(_LE('Manager for service %(binary)s %(host)s is '
                          'reporting problems, not sending heartbeat. '
                          'Service will appear "down".'),
                      {'binary': self.binary,
                       'host': self.host})
            return

        ctxt = context.get_admin_context()
        zone = CONF.storage_availability_zone
        state_catalog = {}
        try:
            try:
                service_ref = db.service_get(ctxt, self.service_id)
            except exception.NotFound:
                LOG.debug('The service database object disappeared, '
                          'recreating it.')
                self._create_service_ref(ctxt)
                service_ref = db.service_get(ctxt, self.service_id)

            state_catalog['report_count'] = service_ref['report_count'] + 1
            if zone != service_ref['availability_zone']:
                state_catalog['availability_zone'] = zone

            db.service_update(ctxt,
                              self.service_id, state_catalog)

            # TODO(termie): make this pattern be more elegant.
            if getattr(self, 'model_disconnected', False):
                self.model_disconnected = False
                LOG.error(_LE('Recovered model server connection!'))

        except db_exc.DBConnectionError:
            if not getattr(self, 'model_disconnected', False):
                self.model_disconnected = True
                LOG.exception(_LE('model server went away'))

        # NOTE(jsbryant) Other DB errors can happen in HA configurations.
        # such errors shouldn't kill this thread, so we handle them here.
        except db_exc.DBError:
            if not getattr(self, 'model_disconnected', False):
                self.model_disconnected = True
                LOG.exception(_LE('DBError encountered: '))

        except Exception:
            if not getattr(self, 'model_disconnected', False):
                self.model_disconnected = True
                LOG.exception(_LE('Exception encountered: '))
Beispiel #7
0
 def test_service_update(self):
     service = self._create_service({})
     new_values = {
         'host': 'fake_host1',
         'binary': 'fake_binary1',
         'topic': 'fake_topic1',
         'report_count': 4,
         'disabled': True
     }
     db.service_update(self.ctxt, service['id'], new_values)
     updated_service = db.service_get(self.ctxt, service['id'])
     for key, value in new_values.iteritems():
         self.assertEqual(value, updated_service[key])
Beispiel #8
0
 def test_service_update(self):
     service = self._create_service({})
     new_values = {
         "host": "fake_host1",
         "binary": "fake_binary1",
         "topic": "fake_topic1",
         "report_count": 4,
         "disabled": True,
     }
     db.service_update(self.ctxt, service["id"], new_values)
     updated_service = db.service_get(self.ctxt, service["id"])
     for key, value in new_values.iteritems():
         self.assertEqual(value, updated_service[key])
Beispiel #9
0
    def update(self, req, id, body):
        """Enable/Disable scheduling for a service."""
        context = req.environ["cinder.context"]
        authorize(context)

        ext_loaded = self.ext_mgr.is_loaded("os-extended-services")
        ret_val = {}
        if id == "enable":
            disabled = False
            status = "enabled"
            if ext_loaded:
                ret_val["disabled_reason"] = None
        elif id == "disable" or (id == "disable-log-reason" and ext_loaded):
            disabled = True
            status = "disabled"
        else:
            raise webob.exc.HTTPNotFound(explanation=_("Unknown action"))

        try:
            host = body["host"]
        except (TypeError, KeyError):
            msg = _("Missing required element 'host' in request body.")
            raise webob.exc.HTTPBadRequest(explanation=msg)

        ret_val["disabled"] = disabled
        if id == "disable-log-reason" and ext_loaded:
            reason = body.get("disabled_reason")
            if not self._is_valid_as_reason(reason):
                msg = _("Disabled reason contains invalid characters " "or is too long")
                raise webob.exc.HTTPBadRequest(explanation=msg)
            ret_val["disabled_reason"] = reason

        # NOTE(uni): deprecating service request key, binary takes precedence
        # Still keeping service key here for API compatibility sake.
        service = body.get("service", "")
        binary = body.get("binary", "")
        binary_key = binary or service
        if not binary_key:
            raise webob.exc.HTTPBadRequest()

        try:
            svc = db.service_get_by_args(context, host, binary_key)
            if not svc:
                raise webob.exc.HTTPNotFound(explanation=_("Unknown service"))

            db.service_update(context, svc["id"], ret_val)
        except exception.ServiceNotFound:
            raise webob.exc.HTTPNotFound(explanation=_("service not found"))

        ret_val.update({"host": host, "service": service, "binary": binary, "status": status})
        return ret_val
    def test_migrate_volume_driver_cross_az(self):
        """Test volume migration done by driver."""
        # Mock driver and rpc functions
        self.mock_object(self.volume.driver, 'migrate_volume',
                         lambda x, y, z, new_type_id=None: (
                             True, {'user_id': fake.USER_ID}))
        dst_az = 'AZ2'
        db.service_update(self.context, self._service.id,
                          {'availability_zone': dst_az})

        volume = tests_utils.create_volume(self.context, size=0,
                                           host=CONF.host,
                                           migration_status='migrating')
        host_obj = {'host': 'newhost', 'capabilities': {}}
        self.volume.migrate_volume(self.context, volume, host_obj, False)

        # check volume properties
        volume.refresh()
        self.assertEqual('newhost', volume.host)
        self.assertEqual('success', volume.migration_status)
        self.assertEqual(dst_az, volume.availability_zone)
Beispiel #11
0
    def update(self, req, id, body):
        """Enable/Disable scheduling for a service."""
        context = req.environ['cinder.context']
        authorize(context)

        if id == "enable":
            disabled = False
        elif id == "disable":
            disabled = True
        else:
            raise webob.exc.HTTPNotFound("Unknown action")

        try:
            host = body['host']
        except (TypeError, KeyError):
            raise webob.exc.HTTPBadRequest()

        # NOTE(uni): deprecating service request key, binary takes precedence
        # Still keeping service key here for API compatibility sake.
        service = body.get('service', '')
        binary = body.get('binary', '')
        binary_key = binary or service
        if not binary_key:
            raise webob.exc.HTTPBadRequest()

        try:
            svc = db.service_get_by_args(context, host, binary_key)
            if not svc:
                raise webob.exc.HTTPNotFound('Unknown service')

            db.service_update(context, svc['id'], {'disabled': disabled})
        except exception.ServiceNotFound:
            raise webob.exc.HTTPNotFound("service not found")

        status = id + 'd'
        return {'host': host,
                'service': service,
                'disabled': disabled,
                'binary': binary,
                'status': status}
Beispiel #12
0
    def report_state(self):
        """Update the state of this service in the datastore."""
        if not self.manager.is_working():
            # NOTE(dulek): If manager reports a problem we're not sending
            # heartbeats - to indicate that service is actually down.
            LOG.error(_LE('Manager for service %s is reporting problems, skip '
                          'sending heartbeat. Service will appear "down".'),
                      self.binary)
            return

        ctxt = context.get_admin_context()
        zone = CONF.storage_availability_zone
        state_catalog = {}
        try:
            try:
                service_ref = db.service_get(ctxt, self.service_id)
            except exception.NotFound:
                LOG.debug('The service database object disappeared, '
                          'recreating it.')
                self._create_service_ref(ctxt)
                service_ref = db.service_get(ctxt, self.service_id)

            state_catalog['report_count'] = service_ref['report_count'] + 1
            if zone != service_ref['availability_zone']:
                state_catalog['availability_zone'] = zone

            db.service_update(ctxt,
                              self.service_id, state_catalog)

            # TODO(termie): make this pattern be more elegant.
            if getattr(self, 'model_disconnected', False):
                self.model_disconnected = False
                LOG.error(_LE('Recovered model server connection!'))

        except db_exc.DBConnectionError:
            if not getattr(self, 'model_disconnected', False):
                self.model_disconnected = True
                LOG.exception(_LE('model server went away'))
Beispiel #13
0
    def report_state(self):
        """Update the state of this service in the datastore."""
        ctxt = context.get_admin_context()
        zone = CONF.storage_availability_zone
        state_catalog = {}
        try:
            try:
                service_ref = db.service_get(ctxt, self.service_id)
            except exception.NotFound:
                LOG.debug('The service database object disappeared, '
                          'recreating it.')
                self._create_service_ref(ctxt)
                service_ref = db.service_get(ctxt, self.service_id)

            state_catalog['report_count'] = service_ref['report_count'] + 1
            if zone != service_ref['availability_zone']:
                state_catalog['availability_zone'] = zone

            db.service_update(ctxt,
                              self.service_id, state_catalog)

            # TODO(termie): make this pattern be more elegant.
            if getattr(self, 'model_disconnected', False):
                self.model_disconnected = False
                LOG.error(_LE('Recovered model server connection!'))

        except db_exc.DBConnectionError:
            if not getattr(self, 'model_disconnected', False):
                self.model_disconnected = True
                LOG.exception(_LE('model server went away'))

        # NOTE(jsbryant) Other DB errors can happen in HA configurations.
        # such errors shouldn't kill this thread, so we handle them here.
        except db_exc.DBError:
            if not getattr(self, 'model_disconnected', False):
                self.model_disconnected = True
                LOG.exception(_LE('DBError encountered: '))
Beispiel #14
0
 def save(self):
     updates = self.cinder_obj_get_changes()
     if updates:
         db.service_update(self._context, self.id, updates)
         self.obj_reset_changes()
Beispiel #15
0
 def save(self):
     updates = self.cinder_obj_get_changes()
     if updates:
         db.service_update(self._context, self.id, updates)
         self.obj_reset_changes()