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()
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}
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
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: '))
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])
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])
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)
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}
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'))
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: '))
def save(self): updates = self.cinder_obj_get_changes() if updates: db.service_update(self._context, self.id, updates) self.obj_reset_changes()