Esempio n. 1
0
    def test_service_is_up(self):
        fts_func = datetime.datetime.fromtimestamp
        fake_now = 1000
        down_time = 5

        self.flags(service_down_time=down_time)
        self.mox.StubOutWithMock(timeutils, 'utcnow')

        # Up (equal)
        timeutils.utcnow().AndReturn(fts_func(fake_now))
        service = {'updated_at': fts_func(fake_now - down_time),
                   'created_at': fts_func(fake_now - down_time)}
        self.mox.ReplayAll()
        result = utils.service_is_up(service)
        self.assertTrue(result)

        self.mox.ResetAll()
        # Up
        timeutils.utcnow().AndReturn(fts_func(fake_now))
        service = {'updated_at': fts_func(fake_now - down_time + 1),
                   'created_at': fts_func(fake_now - down_time + 1)}
        self.mox.ReplayAll()
        result = utils.service_is_up(service)
        self.assertTrue(result)

        self.mox.ResetAll()
        # Down
        timeutils.utcnow().AndReturn(fts_func(fake_now))
        service = {'updated_at': fts_func(fake_now - down_time - 1),
                   'created_at': fts_func(fake_now - down_time - 1)}
        self.mox.ReplayAll()
        result = utils.service_is_up(service)
        self.assertFalse(result)
Esempio n. 2
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)
Esempio n. 3
0
    def test_service_is_up(self, mock_utcnow):
        fts_func = datetime.datetime.fromtimestamp
        fake_now = 1000
        down_time = 5

        self.flags(service_down_time=down_time)
        mock_utcnow.return_value = fts_func(fake_now)

        # Up (equal)
        service = {'updated_at': fts_func(fake_now - down_time),
                   'created_at': fts_func(fake_now - down_time)}
        result = utils.service_is_up(service)
        self.assertTrue(result)

        # Up
        service = {'updated_at': fts_func(fake_now - down_time + 1),
                   'created_at': fts_func(fake_now - down_time + 1)}
        result = utils.service_is_up(service)
        self.assertTrue(result)

        # Down
        service = {'updated_at': fts_func(fake_now - down_time - 1),
                   'created_at': fts_func(fake_now - down_time - 1)}
        result = utils.service_is_up(service)
        self.assertFalse(result)
Esempio n. 4
0
    def test_service_is_up(self):
        fts_func = datetime.datetime.fromtimestamp
        fake_now = 1000
        down_time = 5

        self.flags(service_down_time=down_time)
        self.mox.StubOutWithMock(timeutils, 'utcnow')

        # Up (equal)
        timeutils.utcnow().AndReturn(fts_func(fake_now))
        service = {'updated_at': fts_func(fake_now - down_time),
                   'created_at': fts_func(fake_now - down_time)}
        self.mox.ReplayAll()
        result = utils.service_is_up(service)
        self.assertTrue(result)

        self.mox.ResetAll()
        # Up
        timeutils.utcnow().AndReturn(fts_func(fake_now))
        service = {'updated_at': fts_func(fake_now - down_time + 1),
                   'created_at': fts_func(fake_now - down_time + 1)}
        self.mox.ReplayAll()
        result = utils.service_is_up(service)
        self.assertTrue(result)

        self.mox.ResetAll()
        # Down
        timeutils.utcnow().AndReturn(fts_func(fake_now))
        service = {'updated_at': fts_func(fake_now - down_time - 1),
                   'created_at': fts_func(fake_now - down_time - 1)}
        self.mox.ReplayAll()
        result = utils.service_is_up(service)
        self.assertFalse(result)
Esempio n. 5
0
    def test_service_is_up(self, mock_utcnow):
        fts_func = datetime.datetime.fromtimestamp
        fake_now = 1000
        down_time = 5

        self.flags(service_down_time=down_time)
        mock_utcnow.return_value = fts_func(fake_now)

        # Up (equal)
        service = {
            'updated_at': fts_func(fake_now - down_time),
            'created_at': fts_func(fake_now - down_time)
        }
        result = utils.service_is_up(service)
        self.assertTrue(result)

        # Up
        service = {
            'updated_at': fts_func(fake_now - down_time + 1),
            'created_at': fts_func(fake_now - down_time + 1)
        }
        result = utils.service_is_up(service)
        self.assertTrue(result)

        # Down
        service = {
            'updated_at': fts_func(fake_now - down_time - 1),
            'created_at': fts_func(fake_now - down_time - 1)
        }
        result = utils.service_is_up(service)
        self.assertFalse(result)
Esempio n. 6
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 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)
Esempio n. 8
0
    def test_hosts_up(self):
        service1 = {"host": "host1"}
        service2 = {"host": "host2"}
        services = [service1, service2]

        self.mox.StubOutWithMock(db, "service_get_all_by_topic")
        self.mox.StubOutWithMock(utils, "service_is_up")

        db.service_get_all_by_topic(self.context, self.topic).AndReturn(services)
        utils.service_is_up(service1).AndReturn(False)
        utils.service_is_up(service2).AndReturn(True)

        self.mox.ReplayAll()
        result = self.driver.hosts_up(self.context, self.topic)
        self.assertEqual(result, ["host2"])
Esempio n. 9
0
 def list(self):
     """Show a list of all cinder services."""
     ctxt = context.get_admin_context()
     services = objects.ServiceList.get_all(ctxt)
     print_format = "%-16s %-36s %-16s %-10s %-5s %-20s %-12s %-15s %-36s"
     print(print_format % (_('Binary'),
                           _('Host'),
                           _('Zone'),
                           _('Status'),
                           _('State'),
                           _('Updated At'),
                           _('RPC Version'),
                           _('Object Version'),
                           _('Cluster')))
     for svc in services:
         art = self._state_repr(utils.service_is_up(svc))
         status = 'disabled' if svc.disabled else 'enabled'
         updated_at = self._normalize_time(svc.updated_at)
         rpc_version = (svc.rpc_current_version or
                        rpc.LIBERTY_RPC_VERSIONS.get(svc.binary, ''))
         object_version = (svc.object_current_version or 'liberty')
         cluster = svc.cluster_name or ''
         print(print_format % (svc.binary, svc.host.partition('.')[0],
                               svc.availability_zone, status, art,
                               updated_at, rpc_version, object_version,
                               cluster))
    def test_hosts_up(self):
        service1 = {'host': 'host1'}
        service2 = {'host': 'host2'}
        services = [service1, service2]

        self.mox.StubOutWithMock(db, 'service_get_all_by_topic')
        self.mox.StubOutWithMock(utils, 'service_is_up')

        db.service_get_all_by_topic(self.context,
                                    self.topic).AndReturn(services)
        utils.service_is_up(service1).AndReturn(False)
        utils.service_is_up(service2).AndReturn(True)

        self.mox.ReplayAll()
        result = self.driver.hosts_up(self.context, self.topic)
        self.assertEqual(result, ['host2'])
Esempio n. 11
0
    def test_hosts_up(self):
        service1 = {'host': 'host1'}
        service2 = {'host': 'host2'}
        services = [service1, service2]

        self.mox.StubOutWithMock(db, 'service_get_all_by_topic')
        self.mox.StubOutWithMock(utils, 'service_is_up')

        db.service_get_all_by_topic(self.context,
                                    self.topic).AndReturn(services)
        utils.service_is_up(service1).AndReturn(False)
        utils.service_is_up(service2).AndReturn(True)

        self.mox.ReplayAll()
        result = self.driver.hosts_up(self.context, self.topic)
        self.assertEqual(result, ['host2'])
Esempio n. 12
0
    def hosts_up(self, context, topic):
        """Return the list of hosts that have a running service for topic."""

        services = db.service_get_all_by_topic(context, topic)
        return [service['host']
                for service in services
                if utils.service_is_up(service)]
Esempio n. 13
0
    def get_all_host_states(self, context):
        """Returns a dict of all the hosts the HostManager
          knows about. Also, each of the consumable resources in HostState
          are pre-populated and adjusted based on data in the db.

          For example:
          {'192.168.1.100': HostState(), ...}
        """

        # Get resource usage across the available volume nodes:
        topic = CONF.volume_topic
        volume_services = db.service_get_all_by_topic(context, topic)
        self.host_state_map.clear()
        for service in volume_services:
            host = service['host']
            if not utils.service_is_up(service) or service['disabled']:
                LOG.warn(_("volume service is down or disabled. "
                           "(host: %s)") % host)
                continue
            capabilities = self.service_states.get(host, None)
            host_state = self.host_state_map.get(host)
            if host_state:
                # copy capabilities to host_state.capabilities
                host_state.update_capabilities(capabilities,
                                               dict(service.iteritems()))
            else:
                host_state = self.host_state_cls(host,
                                                 capabilities=capabilities,
                                                 service=
                                                 dict(service.iteritems()))
                self.host_state_map[host] = host_state
            # update host_state
            host_state.update_from_volume_capability(capabilities)

        return self.host_state_map.itervalues()
Esempio n. 14
0
    def migrate_volume(self, context, volume, host, force_host_copy):
        """Migrate the volume to the specified host."""

        # We only handle "available" volumes for now
        if volume['status'] not in ['available', 'in-use']:
            msg = _('Volume status must be available/in-use.')
            LOG.error(msg)
            raise exception.InvalidVolume(reason=msg)

        # Make sure volume is not part of a migration
        if volume['migration_status'] is not None:
            msg = _("Volume is already part of an active migration")
            raise exception.InvalidVolume(reason=msg)

        # We only handle volumes without snapshots for now
        snaps = self.db.snapshot_get_all_for_volume(context, volume['id'])
        if snaps:
            msg = _("volume must not have snapshots")
            LOG.error(msg)
            raise exception.InvalidVolume(reason=msg)

        # Make sure the host is in the list of available hosts
        elevated = context.elevated()
        topic = CONF.volume_topic
        services = self.db.service_get_all_by_topic(elevated,
                                                    topic,
                                                    disabled=False)
        found = False
        for service in services:
            if utils.service_is_up(service) and service['host'] == host:
                found = True
        if not found:
            msg = (_('No available service named %s') % host)
            LOG.error(msg)
            raise exception.InvalidHost(reason=msg)

        # Make sure the destination host is different than the current one
        if host == volume['host']:
            msg = _('Destination host must be different than current host')
            LOG.error(msg)
            raise exception.InvalidHost(reason=msg)

        self.update(context, volume, {'migration_status': 'starting'})

        # Call the scheduler to ensure that the host exists and that it can
        # accept the volume
        volume_type = {}
        volume_type_id = volume['volume_type_id']
        if volume_type_id:
            volume_type = volume_types.get_volume_type(context, volume_type_id)
        request_spec = {
            'volume_properties': volume,
            'volume_type': volume_type,
            'volume_id': volume['id']
        }
        self.scheduler_rpcapi.migrate_volume_to_host(context,
                                                     CONF.volume_topic,
                                                     volume['id'], host,
                                                     force_host_copy,
                                                     request_spec)
Esempio n. 15
0
    def hosts_up(self, context, topic):
        """Return the list of hosts that have a running service for topic."""

        services = db.service_get_all_by_topic(context, topic)
        return [service['host']
                for service in services
                if utils.service_is_up(service)]
Esempio n. 16
0
    def _update_host_state_map(self, context):

        # Get resource usage across the available volume nodes:
        topic = CONF.volume_topic
        volume_services = db.service_get_all_by_topic(context,
                                                      topic,
                                                      disabled=False)
        active_hosts = set()
        for service in volume_services:
            host = service['host']
            if not utils.service_is_up(service):
                LOG.warn(_LW("volume service is down. (host: %s)") % host)
                continue
            capabilities = self.service_states.get(host, None)
            host_state = self.host_state_map.get(host)
            if not host_state:
                host_state = self.host_state_cls(host,
                                                 capabilities=capabilities,
                                                 service=
                                                 dict(service.iteritems()))
                self.host_state_map[host] = host_state
            # update capabilities and attributes in host_state
            host_state.update_from_volume_capability(capabilities,
                                                     service=
                                                     dict(service.iteritems()))
            active_hosts.add(host)

        # remove non-active hosts from host_state_map
        nonactive_hosts = set(self.host_state_map.keys()) - active_hosts
        for host in nonactive_hosts:
            LOG.info(_LI("Removing non-active host: %(host)s from "
                         "scheduler cache.") % {'host': host})
            del self.host_state_map[host]
Esempio n. 17
0
 def list(self):
     """Show a list of all cinder services."""
     ctxt = context.get_admin_context()
     services = objects.ServiceList.get_all(ctxt)
     print_format = "%-16s %-36s %-16s %-10s %-5s %-20s %-12s %-15s %-36s"
     print(print_format % (_('Binary'),
                           _('Host'),
                           _('Zone'),
                           _('Status'),
                           _('State'),
                           _('Updated At'),
                           _('RPC Version'),
                           _('Object Version'),
                           _('Cluster')))
     for svc in services:
         art = self._state_repr(utils.service_is_up(svc))
         status = 'disabled' if svc.disabled else 'enabled'
         updated_at = self._normalize_time(svc.updated_at)
         rpc_version = svc.rpc_current_version
         object_version = svc.object_current_version
         cluster = svc.cluster_name or ''
         print(print_format % (svc.binary, svc.host.partition('.')[0],
                               svc.availability_zone, status, art,
                               updated_at, rpc_version, object_version,
                               cluster))
Esempio n. 18
0
    def _update_host_state_map(self, context):

        # Get resource usage across the available volume nodes:
        topic = CONF.volume_topic
        volume_services = db.service_get_all_by_topic(context,
                                                      topic,
                                                      disabled=False)
        active_hosts = set()
        for service in volume_services:
            host = service['host']
            if not utils.service_is_up(service):
                LOG.warn(_LW("volume service is down. (host: %s)") % host)
                continue
            capabilities = self.service_states.get(host, None)
            host_state = self.host_state_map.get(host)
            if not host_state:
                host_state = self.host_state_cls(host,
                                                 capabilities=capabilities,
                                                 service=dict(
                                                     service.iteritems()))
                self.host_state_map[host] = host_state
            # update capabilities and attributes in host_state
            host_state.update_from_volume_capability(capabilities,
                                                     service=dict(
                                                         service.iteritems()))
            active_hosts.add(host)

        # remove non-active hosts from host_state_map
        nonactive_hosts = set(self.host_state_map.keys()) - active_hosts
        for host in nonactive_hosts:
            LOG.info(
                _LI("Removing non-active host: %(host)s from "
                    "scheduler cache.") % {'host': host})
            del self.host_state_map[host]
Esempio n. 19
0
    def get_all_host_states(self, context):
        """Returns a dict of all the hosts the HostManager
          knows about. Also, each of the consumable resources in HostState
          are pre-populated and adjusted based on data in the db.

          For example:
          {'192.168.1.100': HostState(), ...}
        """

        # Get resource usage across the available volume nodes:
        topic = FLAGS.volume_topic
        volume_services = db.service_get_all_by_topic(context, topic)
        for service in volume_services:
            if not utils.service_is_up(service) or service['disabled']:
                LOG.warn(_("service is down or disabled."))
                continue
            host = service['host']
            capabilities = self.service_states.get(host, None)
            host_state = self.host_state_map.get(host)
            if host_state:
                # copy capabilities to host_state.capabilities
                host_state.update_capabilities(capabilities,
                                               dict(service.iteritems()))
            else:
                host_state = self.host_state_cls(host,
                                                 capabilities=capabilities,
                                                 service=dict(
                                                     service.iteritems()))
                self.host_state_map[host] = host_state
            # update host_state
            host_state.update_from_volume_capability(capabilities)

        return self.host_state_map.itervalues()
Esempio n. 20
0
 def list(self):
     """Show a list of all cinder services."""
     ctxt = context.get_admin_context()
     services = objects.ServiceList.get_all(ctxt)
     print_format = "%-16s %-36s %-16s %-10s %-5s %-20s %-12s %-15s"
     print(print_format % (_('Binary'),
                           _('Host'),
                           _('Zone'),
                           _('Status'),
                           _('State'),
                           _('Updated At'),
                           _('RPC Version'),
                           _('Object Version')))
     for svc in services:
         alive = utils.service_is_up(svc)
         art = ":-)" if alive else "XXX"
         status = 'enabled'
         if svc.disabled:
             status = 'disabled'
         updated_at = svc.updated_at
         if updated_at:
             updated_at = timeutils.normalize_time(updated_at)
         rpc_version = (svc.rpc_current_version or
                        rpc.LIBERTY_RPC_VERSIONS.get(svc.binary, ''))
         object_version = (svc.object_current_version or 'liberty')
         print(print_format % (svc.binary, svc.host.partition('.')[0],
                               svc.availability_zone, status, art,
                               updated_at, rpc_version,
                               object_version))
Esempio n. 21
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)
Esempio n. 22
0
    def migrate_volume(self, context, volume, host, force_host_copy):
        """Migrate the volume to the specified host."""

        # We only handle "available" volumes for now
        if volume['status'] not in ['available', 'in-use']:
            msg = _('Volume status must be available/in-use.')
            LOG.error(msg)
            raise exception.InvalidVolume(reason=msg)

        # Make sure volume is not part of a migration
        if volume['migration_status'] is not None:
            msg = _("Volume is already part of an active migration")
            raise exception.InvalidVolume(reason=msg)

        # We only handle volumes without snapshots for now
        snaps = self.db.snapshot_get_all_for_volume(context, volume['id'])
        if snaps:
            msg = _("volume must not have snapshots")
            LOG.error(msg)
            raise exception.InvalidVolume(reason=msg)

        # Make sure the host is in the list of available hosts
        elevated = context.elevated()
        topic = CONF.volume_topic
        services = self.db.service_get_all_by_topic(elevated,
                                                    topic,
                                                    disabled=False)
        found = False
        for service in services:
            if utils.service_is_up(service) and service['host'] == host:
                found = True
        if not found:
            msg = (_('No available service named %s') % host)
            LOG.error(msg)
            raise exception.InvalidHost(reason=msg)

        # Make sure the destination host is different than the current one
        if host == volume['host']:
            msg = _('Destination host must be different than current host')
            LOG.error(msg)
            raise exception.InvalidHost(reason=msg)

        self.update(context, volume, {'migration_status': 'starting'})

        # Call the scheduler to ensure that the host exists and that it can
        # accept the volume
        volume_type = {}
        volume_type_id = volume['volume_type_id']
        if volume_type_id:
            volume_type = volume_types.get_volume_type(context, volume_type_id)
        request_spec = {'volume_properties': volume,
                        'volume_type': volume_type,
                        'volume_id': volume['id']}
        self.scheduler_rpcapi.migrate_volume_to_host(context,
                                                     CONF.volume_topic,
                                                     volume['id'],
                                                     host,
                                                     force_host_copy,
                                                     request_spec)
Esempio n. 23
0
 def _is_backup_service_enabled(self, volume, volume_host):
     """Check if there is a backup service available."""
     topic = CONF.backup_topic
     ctxt = context.get_admin_context()
     services = self.db.service_get_all_by_topic(ctxt, topic)
     for srv in services:
         if (srv['availability_zone'] == volume['availability_zone'] and
                 srv['host'] == volume_host and not srv['disabled'] and
                 utils.service_is_up(srv)):
             return True
     return False
Esempio n. 24
0
    def get_all_host_states(self, context):
        """Returns a dict of all the hosts the HostManager knows about.

        Each of the consumable resources in HostState are
        populated with capabilities scheduler received from RPC.

        For example:
          {'192.168.1.100': HostState(), ...}
        """

        # Get resource usage across the available volume nodes:
        topic = CONF.volume_topic
        volume_services = db.service_get_all_by_topic(context,
                                                      topic,
                                                      disabled=False)
        active_hosts = set()
        for service in volume_services:
            host = service['host']
            if not utils.service_is_up(service):
                LOG.warn(_("volume service is down. (host: %s)") % host)
                continue
            capabilities = self.service_states.get(host, None)
            host_state = self.host_state_map.get(host)
            if not host_state:
                host_state = self.host_state_cls(host,
                                                 capabilities=capabilities,
                                                 service=dict(
                                                     service.iteritems()))
                self.host_state_map[host] = host_state
            # update capabilities and attributes in host_state
            host_state.update_from_volume_capability(capabilities,
                                                     service=dict(
                                                         service.iteritems()))
            active_hosts.add(host)

        # remove non-active hosts from host_state_map
        nonactive_hosts = set(self.host_state_map.keys()) - active_hosts
        for host in nonactive_hosts:
            LOG.info(
                _("Removing non-active host: %(host)s from "
                  "scheduler cache.") % {'host': host})
            del self.host_state_map[host]

        # build a pool_state map and return that map instead of host_state_map
        all_pools = {}
        for host in active_hosts:
            state = self.host_state_map[host]
            for key in state.pools:
                pool = state.pools[key]
                # use host.pool_name to make sure key is unique
                pool_key = '.'.join([host, pool.pool_name])
                all_pools[pool_key] = pool

        return all_pools.itervalues()
Esempio n. 25
0
 def _check_backup_service(self, volume):
     """Check if there is an backup service available"""
     topic = CONF.backup_topic
     ctxt = context.get_admin_context()
     services = self.db.service_get_all_by_topic(ctxt, topic)
     for srv in services:
         if (srv['availability_zone'] == volume['availability_zone']
                 and srv['host'] == volume['host'] and not srv['disabled']
                 and utils.service_is_up(srv)):
             return True
     return False
Esempio n. 26
0
 def _is_backup_service_enabled(self, volume, volume_host):
     """Check if there is a backup service available."""
     topic = CONF.backup_topic
     ctxt = context.get_admin_context()
     services = objects.ServiceList.get_all_by_topic(
         ctxt, topic, disabled=False)
     for srv in services:
         if (srv.availability_zone == volume['availability_zone'] and
                 srv.host == volume_host and
                 utils.service_is_up(srv)):
             return True
     return False
Esempio n. 27
0
File: api.py Progetto: NetApp/cinder
 def _is_backup_service_enabled(self, availability_zone, host):
     """Check if there is a backup service available."""
     topic = constants.BACKUP_TOPIC
     ctxt = context.get_admin_context()
     services = objects.ServiceList.get_all_by_topic(
         ctxt, topic, disabled=False)
     for srv in services:
         if (self._az_matched(srv, availability_zone) and
                 srv.host == host and
                 utils.service_is_up(srv)):
             return True
     return False
Esempio n. 28
0
 def _is_backup_service_enabled(self, availability_zone, host):
     """Check if there is a backup service available."""
     topic = CONF.backup_topic
     ctxt = context.get_admin_context()
     services = objects.ServiceList.get_all_by_topic(ctxt,
                                                     topic,
                                                     disabled=False)
     for srv in services:
         if (self._az_matched(srv, availability_zone) and srv.host == host
                 and utils.service_is_up(srv)):
             return True
     return False
Esempio n. 29
0
    def get_all_host_states(self, context):
        """Returns a dict of all the hosts the HostManager knows about.

        Each of the consumable resources in HostState are
        populated with capabilities scheduler received from RPC.

        For example:
          {'192.168.1.100': HostState(), ...}
        """

        # Get resource usage across the available volume nodes:
        topic = CONF.volume_topic
        volume_services = db.service_get_all_by_topic(context,
                                                      topic,
                                                      disabled=False)
        active_hosts = set()
        for service in volume_services:
            host = service['host']
            if not utils.service_is_up(service):
                LOG.warn(_("volume service is down. (host: %s)") % host)
                continue
            capabilities = self.service_states.get(host, None)
            host_state = self.host_state_map.get(host)
            if not host_state:
                host_state = self.host_state_cls(host,
                                                 capabilities=capabilities,
                                                 service=
                                                 dict(service.iteritems()))
                self.host_state_map[host] = host_state
            # update capabilities and attributes in host_state
            host_state.update_from_volume_capability(capabilities,
                                                     service=
                                                     dict(service.iteritems()))
            active_hosts.add(host)

        # remove non-active hosts from host_state_map
        nonactive_hosts = set(self.host_state_map.keys()) - active_hosts
        for host in nonactive_hosts:
            LOG.info(_LI("Removing non-active host: %(host)s from "
                         "scheduler cache.") % {'host': host})
            del self.host_state_map[host]

        # build a pool_state map and return that map instead of host_state_map
        all_pools = {}
        for host in active_hosts:
            state = self.host_state_map[host]
            for key in state.pools:
                pool = state.pools[key]
                # use host.pool_name to make sure key is unique
                pool_key = '.'.join([host, pool.pool_name])
                all_pools[pool_key] = pool

        return all_pools.itervalues()
Esempio n. 30
0
 def _is_backup_service_enabled(self, volume, volume_host):
     """Check if there is a backup service available."""
     topic = CONF.backup_topic
     ctxt = context.get_admin_context()
     services = self.db.service_get_all_by_topic(ctxt,
                                                 topic,
                                                 disabled=False)
     for srv in services:
         if (srv['availability_zone'] == volume['availability_zone'] and
                 srv['host'] == volume_host and
                 utils.service_is_up(srv)):
             return True
     return False
Esempio n. 31
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)
Esempio n. 32
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)
Esempio n. 33
0
 def _check_backup_service(self, volume):
     """Check if there is an backup service available"""
     topic = CONF.backup_topic
     ctxt = context.get_admin_context()
     services = self.db.service_get_all_by_topic(ctxt, topic)
     for srv in services:
         if (
             srv["availability_zone"] == volume["availability_zone"]
             and srv["host"] == volume["host"]
             and not srv["disabled"]
             and utils.service_is_up(srv)
         ):
             return True
     return False
Esempio n. 34
0
 def list(self):
     """Show a list of all cinder services."""
     ctxt = context.get_admin_context()
     services = db.service_get_all(ctxt)
     print_format = "%-16s %-36s %-16s %-10s %-5s %-10s"
     print(print_format % (_('Binary'), _('Host'), _('Zone'), _('Status'),
                           _('State'), _('Updated At')))
     for svc in services:
         alive = utils.service_is_up(svc)
         art = ":-)" if alive else "XXX"
         status = 'enabled'
         if svc['disabled']:
             status = 'disabled'
         print(print_format %
               (svc['binary'], svc['host'].partition('.')[0],
                svc['availability_zone'], status, art, svc['updated_at']))
Esempio n. 35
0
    def get_all_host_states(self, context):
        """Returns a dict of all the hosts the HostManager knows about.

        Each of the consumable resources in HostState are
        populated with capabilities scheduler received from RPC.

        For example:
          {'192.168.1.100': HostState(), ...}
        """
        # Get resource usage across the available volume nodes:
        topic = CONF.volume_topic
        volume_services = db.service_get_all_by_topic(context, topic)
        active_hosts = set()
        for service in volume_services:
            host = service['host']

            if not utils.service_is_up(service) or service['disabled']:
                LOG.warn(_("volume service is down or disabled. "
                           "(host: %s)") % host)
                continue
            capabilities = self.service_states.get(host, None)
            host_state = self.host_state_map.get(host)
            if host_state:
                # copy capabilities to host_state.capabilities
                host_state.update_capabilities(capabilities,
                                               dict(service.iteritems()))
            else:
                host_state = self.host_state_cls(host,
                                                 capabilities=capabilities,
                                                 service=
                                                 dict(service.iteritems()))
                self.host_state_map[host] = host_state
            # update attributes in host_state that scheduler is interested in
            host_state.update_from_volume_capability(capabilities)
            active_hosts.add(host)
            
            if context.host and context.host == host:
                active_hosts = set()
                active_hosts.add(host)
                break
        # remove non-active hosts from host_state_map
        nonactive_hosts = set(self.host_state_map.keys()) - active_hosts
        for host in nonactive_hosts:
            LOG.info(_("Removing non-active host: %(host)s from "
                       "scheduler cache.") % {'host': host})
            del self.host_state_map[host]
        return self.host_state_map.itervalues()
Esempio n. 36
0
    def get_all_host_states(self, context):
        """Returns a dict of all the hosts the HostManager knows about.

        Each of the consumable resources in HostState are
        populated with capabilities scheduler received from RPC.

        For example:
          {'192.168.1.100': HostState(), ...}
        """

        # Get resource usage across the available volume nodes:
        topic = CONF.volume_topic
        volume_services = db.service_get_all_by_topic(context,
                                                      topic,
                                                      disabled=False)
        active_hosts = set()
        for service in volume_services:
            host = service['host']
            if not utils.service_is_up(service):
                LOG.warn(_("volume service is down. (host: %s)") % host)
                continue
            capabilities = self.service_states.get(host, None)
            host_state = self.host_state_map.get(host)
            if host_state:
                # copy capabilities to host_state.capabilities
                host_state.update_capabilities(capabilities,
                                               dict(service.iteritems()))
            else:
                host_state = self.host_state_cls(host,
                                                 capabilities=capabilities,
                                                 service=dict(
                                                     service.iteritems()))
                self.host_state_map[host] = host_state
            # update attributes in host_state that scheduler is interested in
            host_state.update_from_volume_capability(capabilities)
            active_hosts.add(host)

        # remove non-active hosts from host_state_map
        nonactive_hosts = set(self.host_state_map.keys()) - active_hosts
        for host in nonactive_hosts:
            LOG.info(
                _("Removing non-active host: %(host)s from "
                  "scheduler cache.") % {'host': host})
            del self.host_state_map[host]

        return self.host_state_map.itervalues()
Esempio n. 37
0
File: api.py Progetto: NetApp/cinder
    def _get_any_available_backup_service(self, availability_zone):
        """Get an available backup service host.

        Get an available backup service host in the specified
        availability zone.
        """
        services = [srv for srv in self._list_backup_services()]
        random.shuffle(services)
        # Get the next running service with matching availability zone.
        idx = 0
        while idx < len(services):
            srv = services[idx]
            if(self._az_matched(srv, availability_zone) and
               utils.service_is_up(srv)):
                return srv.host
            idx = idx + 1
        return None
Esempio n. 38
0
 def list(self):
     """Show a list of all cinder services."""
     ctxt = context.get_admin_context()
     services = objects.ServiceList.get_all(ctxt)
     print_format = "%-16s %-36s %-16s %-10s %-5s %-10s"
     print(print_format % (_('Binary'), _('Host'), _('Zone'), _('Status'),
                           _('State'), _('Updated At')))
     for svc in services:
         alive = utils.service_is_up(svc)
         art = ":-)" if alive else "XXX"
         status = 'enabled'
         if svc.disabled:
             status = 'disabled'
         print(
             print_format %
             (svc.binary, svc.host.partition('.')[0], svc.availability_zone,
              status, art, timeutils.normalize_time(svc.updated_at)))
Esempio n. 39
0
    def _get_any_available_backup_service(self, availability_zone):
        """Get an available backup service host.

        Get an available backup service host in the specified
        availability zone.
        """
        services = [srv for srv in self._list_backup_services()]
        random.shuffle(services)
        # Get the next running service with matching availability zone.
        idx = 0
        while idx < len(services):
            srv = services[idx]
            if (self._az_matched(srv, availability_zone)
                    and utils.service_is_up(srv)):
                return srv.host
            idx = idx + 1
        return None
Esempio n. 40
0
 def list(self):
     """Show a list of all cinder services."""
     ctxt = context.get_admin_context()
     services = objects.ServiceList.get_all(ctxt)
     print_format = "%-16s %-36s %-16s %-10s %-5s %-10s"
     print(print_format % (_("Binary"), _("Host"), _("Zone"), _("Status"), _("State"), _("Updated At")))
     for svc in services:
         alive = utils.service_is_up(svc)
         art = ":-)" if alive else "XXX"
         status = "enabled"
         if svc.disabled:
             status = "disabled"
         updated_at = svc.updated_at
         if updated_at:
             updated_at = timeutils.normalize_time(updated_at)
         print(
             print_format % (svc.binary, svc.host.partition(".")[0], svc.availability_zone, status, art, updated_at)
         )
Esempio n. 41
0
 def list(self):
     """Show a list of all cinder services."""
     ctxt = context.get_admin_context()
     services = db.service_get_all(ctxt)
     print_format = "%-16s %-36s %-16s %-10s %-5s %-10s"
     print(print_format % (_('Binary'),
                           _('Host'),
                           _('Zone'),
                           _('Status'),
                           _('State'),
                           _('Updated At')))
     for svc in services:
         alive = utils.service_is_up(svc)
         art = ":-)" if alive else "XXX"
         status = 'enabled'
         if svc['disabled']:
             status = 'disabled'
         print(print_format % (svc['binary'], svc['host'].partition('.')[0],
                               svc['availability_zone'], status, art,
                               svc['updated_at']))
Esempio n. 42
0
 def list(self):
     """Show a list of all cinder services."""
     ctxt = context.get_admin_context()
     services = objects.ServiceList.get_all(ctxt)
     print_format = "%-16s %-36s %-16s %-10s %-5s %-10s"
     print(print_format % (_('Binary'),
                           _('Host'),
                           _('Zone'),
                           _('Status'),
                           _('State'),
                           _('Updated At')))
     for svc in services:
         alive = utils.service_is_up(svc)
         art = ":-)" if alive else "XXX"
         status = 'enabled'
         if svc.disabled:
             status = 'disabled'
         print(print_format % (svc.binary, svc.host.partition('.')[0],
                               svc.availability_zone, status, art,
                               timeutils.normalize_time(svc.updated_at)))
Esempio n. 43
0
    def _update_host_state_map(self, context):

        # Get resource usage across the available volume nodes:
        topic = constants.VOLUME_TOPIC
        volume_services = objects.ServiceList.get_all_by_topic(context,
                                                               topic,
                                                               disabled=False)
        active_hosts = set()
        no_capabilities_hosts = set()
        for service in volume_services.objects:
            host = service.host
            if not utils.service_is_up(service):
                LOG.warning(_LW("volume service is down. (host: %s)"), host)
                continue
            capabilities = self.service_states.get(host, None)
            if capabilities is None:
                no_capabilities_hosts.add(host)
                continue

            host_state = self.host_state_map.get(host)
            if not host_state:
                host_state = self.host_state_cls(host,
                                                 capabilities=capabilities,
                                                 service=
                                                 dict(service))
                self.host_state_map[host] = host_state
            # update capabilities and attributes in host_state
            host_state.update_from_volume_capability(capabilities,
                                                     service=
                                                     dict(service))
            active_hosts.add(host)

        self._no_capabilities_hosts = no_capabilities_hosts

        # remove non-active hosts from host_state_map
        nonactive_hosts = set(self.host_state_map.keys()) - active_hosts
        for host in nonactive_hosts:
            LOG.info(_LI("Removing non-active host: %(host)s from "
                         "scheduler cache."), {'host': host})
            del self.host_state_map[host]
Esempio n. 44
0
 def list(self):
     """Show a list of all cinder services."""
     ctxt = context.get_admin_context()
     services = db.service_get_all(ctxt)
     print_format = "%-16s %-36s %-16s %-10s %-5s %-10s"
     print(print_format % (_("Binary"), _("Host"), _("Zone"), _("Status"), _("State"), _("Updated At")))
     for svc in services:
         alive = utils.service_is_up(svc)
         art = ":-)" if alive else "XXX"
         status = "enabled"
         if svc["disabled"]:
             status = "disabled"
         print(
             print_format
             % (
                 svc["binary"],
                 svc["host"].partition(".")[0],
                 svc["availability_zone"],
                 status,
                 art,
                 svc["updated_at"],
             )
         )
Esempio n. 45
0
 def list(self):
     """Show a list of all cinder services."""
     ctxt = context.get_admin_context()
     services = objects.ServiceList.get_all(ctxt)
     print_format = "%-16s %-36s %-16s %-10s %-5s %-20s %-12s %-15s"
     print(print_format %
           (_('Binary'), _('Host'), _('Zone'), _('Status'), _('State'),
            _('Updated At'), _('RPC Version'), _('Object Version')))
     for svc in services:
         alive = utils.service_is_up(svc)
         art = ":-)" if alive else "XXX"
         status = 'enabled'
         if svc.disabled:
             status = 'disabled'
         updated_at = svc.updated_at
         if updated_at:
             updated_at = timeutils.normalize_time(updated_at)
         rpc_version = (svc.rpc_current_version
                        or rpc.LIBERTY_RPC_VERSIONS.get(svc.binary, ''))
         object_version = (svc.object_current_version or 'liberty')
         print(
             print_format %
             (svc.binary, svc.host.partition('.')[0], svc.availability_zone,
              status, art, updated_at, rpc_version, object_version))
Esempio n. 46
0
    def migrate_volume(self, context, volume, host, force_host_copy):
        """Migrate the volume to the specified host."""

        # We only handle "available" volumes for now
        if volume["status"] not in ["available", "in-use"]:
            msg = _("Volume status must be available/in-use.")
            LOG.error(msg)
            raise exception.InvalidVolume(reason=msg)

        # Make sure volume is not part of a migration
        if volume["migration_status"] is not None:
            msg = _("Volume is already part of an active migration")
            raise exception.InvalidVolume(reason=msg)

        # We only handle volumes without snapshots for now
        snaps = self.db.snapshot_get_all_for_volume(context, volume["id"])
        if snaps:
            msg = _("volume must not have snapshots")
            LOG.error(msg)
            raise exception.InvalidVolume(reason=msg)

        # We only handle non-replicated volumes for now
        rep_status = volume["replication_status"]
        if rep_status is not None and rep_status != "disabled":
            msg = _("Volume must not be replicated.")
            LOG.error(msg)
            raise exception.InvalidVolume(reason=msg)

        cg_id = volume.get("consistencygroup_id", None)
        if cg_id:
            msg = _("Volume must not be part of a consistency group.")
            LOG.error(msg)
            raise exception.InvalidVolume(reason=msg)

        # Make sure the host is in the list of available hosts
        elevated = context.elevated()
        topic = CONF.volume_topic
        services = self.db.service_get_all_by_topic(elevated, topic, disabled=False)
        found = False
        for service in services:
            svc_host = volume_utils.extract_host(host, "backend")
            if utils.service_is_up(service) and service["host"] == svc_host:
                found = True
        if not found:
            msg = _("No available service named %s") % host
            LOG.error(msg)
            raise exception.InvalidHost(reason=msg)

        # Make sure the destination host is different than the current one
        if host == volume["host"]:
            msg = _("Destination host must be different than current host")
            LOG.error(msg)
            raise exception.InvalidHost(reason=msg)

        self.update(context, volume, {"migration_status": "starting"})

        # Call the scheduler to ensure that the host exists and that it can
        # accept the volume
        volume_type = {}
        volume_type_id = volume["volume_type_id"]
        if volume_type_id:
            volume_type = volume_types.get_volume_type(context, volume_type_id)
        request_spec = {"volume_properties": volume, "volume_type": volume_type, "volume_id": volume["id"]}
        self.scheduler_rpcapi.migrate_volume_to_host(
            context, CONF.volume_topic, volume["id"], host, force_host_copy, request_spec
        )
Esempio n. 47
0
 def _list_backup_hosts(self):
     services = self._list_backup_services()
     return [
         srv.host for srv in services
         if not srv.disabled and utils.service_is_up(srv)
     ]
Esempio n. 48
0
File: api.py Progetto: NetApp/cinder
 def _list_backup_hosts(self):
     services = self._list_backup_services()
     return [srv.host for srv in services
             if not srv.disabled and utils.service_is_up(srv)]