Example #1
0
    def test_service_get_by_args(self):
        values = [{"host": "host1", "binary": "a"}, {"host": "host2", "binary": "b"}]
        services = [self._create_service(vals) for vals in values]

        service1 = db.service_get_by_args(self.ctxt, "host1", "a")
        self._assertEqualObjects(services[0], service1)

        service2 = db.service_get_by_args(self.ctxt, "host2", "b")
        self._assertEqualObjects(services[1], service2)
Example #2
0
    def test_service_get_by_args(self):
        values = [
            {'host': 'host1', 'binary': 'a'},
            {'host': 'host2', 'binary': 'b'}
        ]
        services = [self._create_service(vals) for vals in values]

        service1 = db.service_get_by_args(self.ctxt, 'host1', 'a')
        self._assertEqualObjects(services[0], service1)

        service2 = db.service_get_by_args(self.ctxt, 'host2', 'b')
        self._assertEqualObjects(services[1], service2)
Example #3
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']
            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}
Example #4
0
    def schedule_create_volume(self, context, volume_id, *_args, **_kwargs):
        """Picks a host that is up and has the fewest volumes."""
        elevated = context.elevated()

        volume_ref = db.volume_get(context, volume_id)
        availability_zone = volume_ref.get("availability_zone")

        zone, host = None, None
        if availability_zone:
            zone, _x, host = availability_zone.partition(":")
        if host and context.is_admin:
            service = db.service_get_by_args(elevated, host, "cinder-volume")
            if not utils.service_is_up(service):
                raise exception.WillNotSchedule(host=host)
            driver.cast_to_volume_host(context, host, "create_volume", volume_id=volume_id, **_kwargs)
            return None

        results = db.service_get_all_volume_sorted(elevated)
        if zone:
            results = [(service, gigs) for (service, gigs) in results if service["availability_zone"] == zone]
        for result in results:
            (service, volume_gigabytes) = result
            if volume_gigabytes + volume_ref["size"] > FLAGS.max_gigabytes:
                msg = _("Not enough allocatable volume gigabytes remaining")
                raise exception.NoValidHost(reason=msg)
            if utils.service_is_up(service) and not service["disabled"]:
                driver.cast_to_volume_host(context, service["host"], "create_volume", volume_id=volume_id, **_kwargs)
                return None
        msg = _("Is the appropriate service running?")
        raise exception.NoValidHost(reason=msg)
Example #5
0
    def schedule_create_volume(self, context, volume_id, **_kwargs):
        """Picks a host that is up and has the fewest volumes."""
        elevated = context.elevated()

        volume_ref = db.volume_get(context, volume_id)
        availability_zone = volume_ref.get('availability_zone')

        zone, host = None, None
        if availability_zone:
            zone, _x, host = availability_zone.partition(':')
        if host and context.is_admin:
            service = db.service_get_by_args(elevated, host, 'cinder-volume')
            if not utils.service_is_up(service):
                raise exception.WillNotSchedule(host=host)
            driver.cast_to_volume_host(context, host, 'create_volume',
                    volume_id=volume_id, **_kwargs)
            return None

        results = db.service_get_all_volume_sorted(elevated)
        if zone:
            results = [(service, gigs) for (service, gigs) in results
                       if service['availability_zone'] == zone]
        for result in results:
            (service, volume_gigabytes) = result
            if volume_gigabytes + volume_ref['size'] > FLAGS.max_gigabytes:
                msg = _("Not enough allocatable volume gigabytes remaining")
                raise exception.NoValidHost(reason=msg)
            if utils.service_is_up(service) and not service['disabled']:
                driver.cast_to_volume_host(context, service['host'],
                        'create_volume', volume_id=volume_id, **_kwargs)
                return None
        msg = _("Is the appropriate service running?")
        raise exception.NoValidHost(reason=msg)
    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}
Example #7
0
    def update(self, req, id, body):
        """Enable/Disable scheduling for a service."""
        context = req.environ['cinder.context']
        authorize(context, action='update')

        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
Example #8
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
    def schedule_create_volume(self, context, request_spec, filter_properties):
        """Picks a host that is up and has the fewest volumes."""
        elevated = context.elevated()

        volume_id = request_spec.get('volume_id')
        snapshot_id = request_spec.get('snapshot_id')
        image_id = request_spec.get('image_id')
        volume_properties = request_spec.get('volume_properties')
        volume_size = volume_properties.get('size')
        availability_zone = volume_properties.get('availability_zone')

        zone, host = None, None
        if availability_zone:
            zone, _x, host = availability_zone.partition(':')
        if host and context.is_admin:
            topic = CONF.volume_topic
            service = db.service_get_by_args(elevated, host, topic)
            if not utils.service_is_up(service):
                raise exception.WillNotSchedule(host=host)
            updated_volume = driver.volume_update_db(context, volume_id, host)
            self.volume_rpcapi.create_volume(context,
                                             updated_volume,
                                             host,
                                             request_spec,
                                             filter_properties,
                                             snapshot_id=snapshot_id,
                                             image_id=image_id)
            return None

        results = db.service_get_all_volume_sorted(elevated)
        if zone:
            results = [(s, gigs) for (s, gigs) in results
                       if s['availability_zone'] == zone]
        for result in results:
            (service, volume_gigabytes) = result
            if volume_gigabytes + volume_size > CONF.max_gigabytes:
                msg = _("Not enough allocatable volume gigabytes remaining")
                raise exception.NoValidHost(reason=msg)
            if utils.service_is_up(service) and not service['disabled']:
                updated_volume = driver.volume_update_db(
                    context, volume_id, service['host'])
                self.volume_rpcapi.create_volume(context,
                                                 updated_volume,
                                                 service['host'],
                                                 request_spec,
                                                 filter_properties,
                                                 snapshot_id=snapshot_id,
                                                 image_id=image_id)
                return None
        msg = _("Is the appropriate service running?")
        raise exception.NoValidHost(reason=msg)
Example #10
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
Example #11
0
    def start(self):
        vcs_string = version.version_string_with_vcs()
        LOG.audit(_('Starting %(topic)s node (version %(vcs_string)s)'),
                  {'topic': self.topic, 'vcs_string': vcs_string})
        utils.cleanup_file_locks()
        rpc.register_opts(FLAGS)
        self.manager.init_host()
        self.model_disconnected = False
        ctxt = context.get_admin_context()
        try:
            service_ref = db.service_get_by_args(ctxt,
                                                 self.host,
                                                 self.binary)
            self.service_id = service_ref['id']
        except exception.NotFound:
            self._create_service_ref(ctxt)

        if 'cinder-compute' == self.binary:
            self.manager.update_available_resource(ctxt)

        self.conn = rpc.create_connection(new=True)
        LOG.debug(_("Creating Consumer connection for Service %s") %
                  self.topic)

        # Share this same connection for these Consumers
        self.conn.create_consumer(self.topic, self, fanout=False)

        node_topic = '%s.%s' % (self.topic, self.host)
        self.conn.create_consumer(node_topic, self, fanout=False)

        self.conn.create_consumer(self.topic, self, fanout=True)

        # Consume from all consumers in a thread
        self.conn.consume_in_thread()

        if self.report_interval:
            pulse = utils.LoopingCall(self.report_state)
            pulse.start(interval=self.report_interval,
                        initial_delay=self.report_interval)
            self.timers.append(pulse)

        if self.periodic_interval:
            if self.periodic_fuzzy_delay:
                initial_delay = random.randint(0, self.periodic_fuzzy_delay)
            else:
                initial_delay = None

            periodic = utils.LoopingCall(self.periodic_tasks)
            periodic.start(interval=self.periodic_interval,
                           initial_delay=initial_delay)
            self.timers.append(periodic)
Example #12
0
 def remove(self, binary, host_name):
     """Completely removes a service."""
     ctxt = context.get_admin_context()
     try:
         svc = db.service_get_by_args(ctxt, host_name, binary)
         db.service_destroy(ctxt, svc['id'])
     except exception.HostBinaryNotFound as e:
         print(_("Host not found. Failed to remove %(service)s"
                 " on %(host)s.") %
               {'service': binary, 'host': host_name})
         print (u"%s" % e.args)
         return 2
     print(_("Service %(service)s on host %(host)s removed.") %
           {'service': binary, 'host': host_name})
Example #13
0
 def remove(self, binary, host_name):
     """Completely removes a service."""
     ctxt = context.get_admin_context()
     try:
         svc = db.service_get_by_args(ctxt, host_name, binary)
         db.service_destroy(ctxt, svc['id'])
     except exception.HostBinaryNotFound as e:
         print(_("Host not found. Failed to remove %(service)s"
                 " on %(host)s.") %
               {'service': binary, 'host': host_name})
         print (u"%s" % e.args)
         return 2
     print(_("Service %(service)s on host %(host)s removed.") %
           {'service': binary, 'host': host_name})
Example #14
0
    def start(self):
        version_string = version.version_string()
        LOG.audit(_('Starting %(topic)s node (version %(version_string)s)'),
                  {'topic': self.topic, 'version_string': version_string})
        self.model_disconnected = False
        ctxt = context.get_admin_context()
        try:
            service_ref = db.service_get_by_args(ctxt,
                                                 self.host,
                                                 self.binary)
            self.service_id = service_ref['id']
        except exception.NotFound:
            self._create_service_ref(ctxt)

        self.conn = rpc.create_connection(new=True)
        LOG.debug(_("Creating Consumer connection for Service %s") %
                  self.topic)

        rpc_dispatcher = self.manager.create_rpc_dispatcher()

        # Share this same connection for these Consumers
        self.conn.create_consumer(self.topic, rpc_dispatcher, fanout=False)

        node_topic = '%s:%s' % (self.topic, self.host)
        self.conn.create_consumer(node_topic, rpc_dispatcher, fanout=False)

        self.conn.create_consumer(self.topic, rpc_dispatcher, fanout=True)

        # Consume from all consumers in a thread
        self.conn.consume_in_thread()
        self.manager.init_host()

        if self.report_interval:
            pulse = utils.LoopingCall(self.report_state)
            pulse.start(interval=self.report_interval,
                        initial_delay=self.report_interval)
            self.timers.append(pulse)

        if self.periodic_interval:
            if self.periodic_fuzzy_delay:
                initial_delay = random.randint(0, self.periodic_fuzzy_delay)
            else:
                initial_delay = None

            periodic = utils.LoopingCall(self.periodic_tasks)
            periodic.start(interval=self.periodic_interval,
                           initial_delay=initial_delay)
            self.timers.append(periodic)
Example #15
0
    def start(self):
        version_string = version.version_string()
        LOG.audit(_('Starting %(topic)s node (version %(version_string)s)'), {
            'topic': self.topic,
            'version_string': version_string
        })
        self.model_disconnected = False
        ctxt = context.get_admin_context()
        try:
            service_ref = db.service_get_by_args(ctxt, self.host, self.binary)
            self.service_id = service_ref['id']
        except exception.NotFound:
            self._create_service_ref(ctxt)

        self.conn = rpc.create_connection(new=True)
        LOG.debug(
            _("Creating Consumer connection for Service %s") % self.topic)

        rpc_dispatcher = self.manager.create_rpc_dispatcher()

        # Share this same connection for these Consumers
        self.conn.create_consumer(self.topic, rpc_dispatcher, fanout=False)

        node_topic = '%s:%s' % (self.topic, self.host)
        self.conn.create_consumer(node_topic, rpc_dispatcher, fanout=False)

        self.conn.create_consumer(self.topic, rpc_dispatcher, fanout=True)

        # Consume from all consumers in a thread
        self.conn.consume_in_thread()
        self.manager.init_host()

        if self.report_interval:
            pulse = utils.LoopingCall(self.report_state)
            pulse.start(interval=self.report_interval,
                        initial_delay=self.report_interval)
            self.timers.append(pulse)

        if self.periodic_interval:
            if self.periodic_fuzzy_delay:
                initial_delay = random.randint(0, self.periodic_fuzzy_delay)
            else:
                initial_delay = None

            periodic = utils.LoopingCall(self.periodic_tasks)
            periodic.start(interval=self.periodic_interval,
                           initial_delay=initial_delay)
            self.timers.append(periodic)
Example #16
0
    def schedule_create_volume(self, context, request_spec, filter_properties):
        """Picks a host that is up and has the fewest volumes."""
        elevated = context.elevated()

        volume_id = request_spec.get('volume_id')
        snapshot_id = request_spec.get('snapshot_id')
        image_id = request_spec.get('image_id')
        volume_properties = request_spec.get('volume_properties')
        volume_size = volume_properties.get('size')
        availability_zone = volume_properties.get('availability_zone')

        zone, host = None, None
        if availability_zone:
            zone, _x, host = availability_zone.partition(':')
        if host and context.is_admin:
            topic = FLAGS.volume_topic
            service = db.service_get_by_args(elevated, host, topic)
            if not utils.service_is_up(service):
                raise exception.WillNotSchedule(host=host)
            updated_volume = driver.volume_update_db(context, volume_id, host)
            self.volume_rpcapi.create_volume(context,
                                             updated_volume,
                                             host,
                                             snapshot_id,
                                             image_id)
            return None

        results = db.service_get_all_volume_sorted(elevated)
        if zone:
            results = [(service, gigs) for (service, gigs) in results
                       if service['availability_zone'] == zone]
        for result in results:
            (service, volume_gigabytes) = result
            if volume_gigabytes + volume_size > FLAGS.max_gigabytes:
                msg = _("Not enough allocatable volume gigabytes remaining")
                raise exception.NoValidHost(reason=msg)
            if utils.service_is_up(service) and not service['disabled']:
                updated_volume = driver.volume_update_db(context, volume_id,
                                                         service['host'])
                self.volume_rpcapi.create_volume(context,
                                                 updated_volume,
                                                 service['host'],
                                                 snapshot_id,
                                                 image_id)
                return None
        msg = _("Is the appropriate service running?")
        raise exception.NoValidHost(reason=msg)
Example #17
0
    def start(self):
        version_string = version.version_string()
        LOG.info(_LI('Starting %(topic)s node (version %(version_string)s)'),
                 {'topic': self.topic, 'version_string': version_string})
        self.model_disconnected = False
        self.manager.init_host()
        ctxt = context.get_admin_context()
        try:
            service_ref = db.service_get_by_args(ctxt,
                                                 self.host,
                                                 self.binary)
            self.service_id = service_ref['id']
        except exception.NotFound:
            self._create_service_ref(ctxt)

        LOG.debug("Creating RPC server for service %s", self.topic)

        target = messaging.Target(topic=self.topic, server=self.host)
        endpoints = [self.manager]
        endpoints.extend(self.manager.additional_endpoints)
        serializer = objects_base.CinderObjectSerializer()
        self.rpcserver = rpc.get_server(target, endpoints, serializer)
        self.rpcserver.start()

        self.manager.init_host_with_rpc()

        if self.report_interval:
            pulse = loopingcall.FixedIntervalLoopingCall(
                self.report_state)
            pulse.start(interval=self.report_interval,
                        initial_delay=self.report_interval)
            self.timers.append(pulse)

        if self.periodic_interval:
            if self.periodic_fuzzy_delay:
                initial_delay = random.randint(0, self.periodic_fuzzy_delay)
            else:
                initial_delay = None

            periodic = loopingcall.FixedIntervalLoopingCall(
                self.periodic_tasks)
            periodic.start(interval=self.periodic_interval,
                           initial_delay=initial_delay)
            self.timers.append(periodic)
Example #18
0
    def start(self):
        version_string = version.version_string()
        LOG.info(_LI('Starting %(topic)s node (version %(version_string)s)'),
                 {'topic': self.topic, 'version_string': version_string})
        self.model_disconnected = False
        self.manager.init_host()
        ctxt = context.get_admin_context()
        try:
            service_ref = db.service_get_by_args(ctxt,
                                                 self.host,
                                                 self.binary)
            self.service_id = service_ref['id']
        except exception.NotFound:
            self._create_service_ref(ctxt)

        LOG.debug("Creating RPC server for service %s", self.topic)

        target = messaging.Target(topic=self.topic, server=self.host)
        endpoints = [self.manager]
        endpoints.extend(self.manager.additional_endpoints)
        serializer = objects_base.CinderObjectSerializer()
        self.rpcserver = rpc.get_server(target, endpoints, serializer)
        self.rpcserver.start()

        self.manager.init_host_with_rpc()

        if self.report_interval:
            pulse = loopingcall.FixedIntervalLoopingCall(
                self.report_state)
            pulse.start(interval=self.report_interval,
                        initial_delay=self.report_interval)
            self.timers.append(pulse)

        if self.periodic_interval:
            if self.periodic_fuzzy_delay:
                initial_delay = random.randint(0, self.periodic_fuzzy_delay)
            else:
                initial_delay = None

            periodic = loopingcall.FixedIntervalLoopingCall(
                self.periodic_tasks)
            periodic.start(interval=self.periodic_interval,
                           initial_delay=initial_delay)
            self.timers.append(periodic)
Example #19
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
        }
Example #20
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}
Example #21
0
    def _get_weighted_candidates(self, context, topic, request_spec, **kwargs):
        """Picks a host that is up and has the fewest volumes."""
        elevated = context.elevated()

        volume_id = request_spec.get('volume_id')
        snapshot_id = request_spec.get('snapshot_id')
        image_id = request_spec.get('image_id')
        volume_properties = request_spec.get('volume_properties')
        volume_size = volume_properties.get('size')
        availability_zone = volume_properties.get('availability_zone')
        filter_properties = kwargs.get('filter_properties', {})

        zone, host = None, None
        if availability_zone:
            zone, _x, host = availability_zone.partition(':')
        if host and context.is_admin:
            service = db.service_get_by_args(elevated, host, topic)
            if not utils.service_is_up(service):
                raise exception.WillNotSchedule(host=host)
            return [host]

        candidates = []
        results = db.service_get_all_volume_sorted(elevated)
        if zone:
            results = [(s, gigs) for (s, gigs) in results
                       if s['availability_zone'] == zone]
        for result in results:
            (service, volume_gigabytes) = result
            no_skip = service['host'] != filter_properties.get('vol_exists_on')
            if no_skip and volume_gigabytes + volume_size > CONF.max_gigabytes:
                continue
            if utils.service_is_up(service) and not service['disabled']:
                candidates.append(service['host'])

        if candidates:
            return candidates
        else:
            msg = _("No service with adequate space or no service running")
            raise exception.NoValidHost(reason=msg)
Example #22
0
    def _schedule_instance(self, context, instance_opts, *_args, **_kwargs):
        """Picks a host that is up and has the fewest running instances."""
        elevated = context.elevated()

        availability_zone = instance_opts.get('availability_zone')

        zone, host = FLAGS.default_schedule_zone, None
        if availability_zone:
            zone, _x, host = availability_zone.partition(':')

        if host and context.is_admin:
            service = db.service_get_by_args(elevated, host, 'cinder-compute')
            if not utils.service_is_up(service):
                raise exception.WillNotSchedule(host=host)
            return host

        results = db.service_get_all_compute_sorted(elevated)
        in_isolation = instance_opts['image_ref'] in FLAGS.isolated_images
        check_cores = not in_isolation or not FLAGS.skip_isolated_core_check
        if zone:
            results = [(service, cores) for (service, cores) in results
                       if service['availability_zone'] == zone]
        for result in results:
            (service, instance_cores) = result
            if in_isolation and service['host'] not in FLAGS.isolated_hosts:
                # isloated images run on isolated hosts
                continue
            if service['host'] in FLAGS.isolated_hosts and not in_isolation:
                # images that aren't isolated only run on general hosts
                continue
            if (check_cores and
                instance_cores + instance_opts['vcpus'] > FLAGS.max_cores):
                msg = _("Not enough allocatable CPU cores remaining")
                raise exception.NoValidHost(reason=msg)
            if utils.service_is_up(service) and not service['disabled']:
                return service['host']
        msg = _("Is the appropriate service running?")
        raise exception.NoValidHost(reason=msg)
Example #23
0
 def get_by_args(cls, context, host, binary_key):
     db_service = db.service_get_by_args(context, host, binary_key)
     return cls._from_db_object(context, cls(context), db_service)