def _live_migration_dest_check(self, context, instance_ref, dest, block_migration): """Live migration check routine (for destination host). :param context: security context :param instance_ref: engine.db.sqlalchemy.models.Instance object :param dest: destination host """ # Checking dest exists and compute node. dservice_refs = db.service_get_all_compute_by_host(context, dest) dservice_ref = dservice_refs[0] # Checking dest host is alive. if not self.service_is_up(dservice_ref): raise exception.ComputeServiceUnavailable(host=dest) # Checking whether The host where instance is running # and dest is not same. src = instance_ref['host'] if dest == src: instance_id = ec2utils.id_to_ec2_id(instance_ref['id']) raise exception.UnableToMigrateToSelf(instance_id=instance_id, host=dest) # Checking dst host still has enough capacities. self.assert_compute_node_has_enough_resources(context, instance_ref, dest, block_migration)
def update_available_resource(self, ctxt, host): """Updates compute manager resource info on ComputeNode table. Since we don't have a real hypervisor, pretend we have lots of disk and ram. """ try: service_ref = db.service_get_all_compute_by_host(ctxt, host)[0] except exception.NotFound: raise exception.ComputeServiceUnavailable(host=host) # Updating host information dic = {'vcpus': 1, 'memory_mb': 4096, 'local_gb': 1028, 'vcpus_used': 0, 'memory_mb_used': 0, 'local_gb_used': 0, 'hypervisor_type': 'fake', 'hypervisor_version': '1.0', 'cpu_info': '?'} compute_node_ref = service_ref['compute_node'] if not compute_node_ref: LOG.info(_('Compute_service record created for %s ') % host) dic['service_id'] = service_ref['id'] db.compute_node_create(ctxt, dic) else: LOG.info(_('Compute_service record updated for %s ') % host) db.compute_node_update(ctxt, compute_node_ref[0]['id'], dic)
def _live_migration_src_check(self, context, instance_ref): """Live migration check routine (for src host). :param context: security context :param instance_ref: engine.db.sqlalchemy.models.Instance object """ # Checking instance is running. if instance_ref['power_state'] != power_state.RUNNING: instance_id = ec2utils.id_to_ec2_id(instance_ref['id']) raise exception.InstanceNotRunning(instance_id=instance_id) # Checing volume node is running when any volumes are mounted # to the instance. if len(instance_ref['volumes']) != 0: services = db.service_get_all_by_topic(context, 'volume') if len(services) < 1 or not self.service_is_up(services[0]): raise exception.VolumeServiceUnavailable() # Checking src host exists and compute node src = instance_ref['host'] services = db.service_get_all_compute_by_host(context, src) # Checking src host is alive. if not self.service_is_up(services[0]): raise exception.ComputeServiceUnavailable(host=src)
def _live_migration_dest_check(self, context, instance_ref, dest, block_migration): """Live migration check routine (for destination host). :param context: security context :param instance_ref: engine.db.sqlalchemy.models.Instance object :param dest: destination host """ # Checking dest exists and compute node. dservice_refs = db.service_get_all_compute_by_host(context, dest) dservice_ref = dservice_refs[0] # Checking dest host is alive. if not self.service_is_up(dservice_ref): raise exception.ComputeServiceUnavailable(host=dest) # Checking whether The host where instance is running # and dest is not same. src = instance_ref['host'] if dest == src: instance_id = ec2utils.id_to_ec2_id(instance_ref['id']) raise exception.UnableToMigrateToSelf(instance_id=instance_id, host=dest) # Checking dst host still has enough capacities. self.assert_compute_node_has_enough_resources(context, instance_ref, dest, block_migration)
def _live_migration_src_check(self, context, instance_ref): """Live migration check routine (for src host). :param context: security context :param instance_ref: engine.db.sqlalchemy.models.Instance object """ # Checking instance is running. if instance_ref['power_state'] != power_state.RUNNING: instance_id = ec2utils.id_to_ec2_id(instance_ref['id']) raise exception.InstanceNotRunning(instance_id=instance_id) # Checing volume node is running when any volumes are mounted # to the instance. if len(instance_ref['volumes']) != 0: services = db.service_get_all_by_topic(context, 'volume') if len(services) < 1 or not self.service_is_up(services[0]): raise exception.VolumeServiceUnavailable() # Checking src host exists and compute node src = instance_ref['host'] services = db.service_get_all_compute_by_host(context, src) # Checking src host is alive. if not self.service_is_up(services[0]): raise exception.ComputeServiceUnavailable(host=src)
def _get_compute_info(self, context, host, key): """get compute node's information specified by key :param context: security context :param host: hostname(must be compute node) :param key: column name of compute_nodes :return: value specified by key """ compute_node_ref = db.service_get_all_compute_by_host(context, host) compute_node_ref = compute_node_ref[0]['compute_node'][0] return compute_node_ref[key]
def _get_compute_info(self, context, host, key): """get compute node's information specified by key :param context: security context :param host: hostname(must be compute node) :param key: column name of compute_nodes :return: value specified by key """ compute_node_ref = db.service_get_all_compute_by_host(context, host) compute_node_ref = compute_node_ref[0]['compute_node'][0] return compute_node_ref[key]
def show_host_resources(self, context, host): """Shows the physical/usage resource given by hosts. :param context: security context :param host: hostname :returns: example format is below. {'resource':D, 'usage':{proj_id1:D, proj_id2:D}} D: {'vcpus': 3, 'memory_mb': 2048, 'local_gb': 2048, 'vcpus_used': 12, 'memory_mb_used': 10240, 'local_gb_used': 64} """ # Getting compute node info and related instances info compute_ref = db.service_get_all_compute_by_host(context, host) compute_ref = compute_ref[0] instance_refs = db.instance_get_all_by_host(context, compute_ref['host']) # Getting total available/used resource compute_ref = compute_ref['compute_node'][0] resource = {'vcpus': compute_ref['vcpus'], 'memory_mb': compute_ref['memory_mb'], 'local_gb': compute_ref['local_gb'], 'vcpus_used': compute_ref['vcpus_used'], 'memory_mb_used': compute_ref['memory_mb_used'], 'local_gb_used': compute_ref['local_gb_used']} usage = dict() if not instance_refs: return {'resource': resource, 'usage': usage} # Getting usage resource per project project_ids = [i['project_id'] for i in instance_refs] project_ids = list(set(project_ids)) for project_id in project_ids: vcpus = [i['vcpus'] for i in instance_refs \ if i['project_id'] == project_id] mem = [i['memory_mb'] for i in instance_refs \ if i['project_id'] == project_id] disk = [i['local_gb'] for i in instance_refs \ if i['project_id'] == project_id] usage[project_id] = {'vcpus': reduce(lambda x, y: x + y, vcpus), 'memory_mb': reduce(lambda x, y: x + y, mem), 'local_gb': reduce(lambda x, y: x + y, disk)} return {'resource': resource, 'usage': usage}
def update_available_resource(self, ctxt, host): """Updates compute manager resource info on ComputeNode table. This method is called when engine-compute launches, and whenever admin executes "engine-manage service update_resource". :param ctxt: security context :param host: hostname that compute manager is currently running """ try: service_ref = db.service_get_all_compute_by_host(ctxt, host)[0] except exception.NotFound: raise exception.ComputeServiceUnavailable(host=host) host_stats = self.get_host_stats(refresh=True) # Updating host information total_ram_mb = host_stats['host_memory_total'] / (1024 * 1024) free_ram_mb = host_stats['host_memory_free'] / (1024 * 1024) total_disk_gb = host_stats['disk_total'] / (1024 * 1024 * 1024) used_disk_gb = host_stats['disk_used'] / (1024 * 1024 * 1024) dic = { 'vcpus': 0, 'memory_mb': total_ram_mb, 'local_gb': total_disk_gb, 'vcpus_used': 0, 'memory_mb_used': total_ram_mb - free_ram_mb, 'local_gb_used': used_disk_gb, 'hypervisor_type': 'xen', 'hypervisor_version': 0, 'cpu_info': host_stats['host_cpu_info']['cpu_count'] } compute_node_ref = service_ref['compute_node'] if not compute_node_ref: LOG.info(_('Compute_service record created for %s ') % host) dic['service_id'] = service_ref['id'] db.compute_node_create(ctxt, dic) else: LOG.info(_('Compute_service record updated for %s ') % host) db.compute_node_update(ctxt, compute_node_ref[0]['id'], dic)
def update_available_resource(self, ctxt, host): """Updates compute manager resource info on ComputeNode table. This method is called when engine-compute launches, and whenever admin executes "engine-manage service update_resource". :param ctxt: security context :param host: hostname that compute manager is currently running """ try: service_ref = db.service_get_all_compute_by_host(ctxt, host)[0] except exception.NotFound: raise exception.ComputeServiceUnavailable(host=host) host_stats = self.get_host_stats(refresh=True) # Updating host information total_ram_mb = host_stats['host_memory_total'] / (1024 * 1024) free_ram_mb = host_stats['host_memory_free'] / (1024 * 1024) total_disk_gb = host_stats['disk_total'] / (1024 * 1024 * 1024) used_disk_gb = host_stats['disk_used'] / (1024 * 1024 * 1024) dic = {'vcpus': 0, 'memory_mb': total_ram_mb, 'local_gb': total_disk_gb, 'vcpus_used': 0, 'memory_mb_used': total_ram_mb - free_ram_mb, 'local_gb_used': used_disk_gb, 'hypervisor_type': 'xen', 'hypervisor_version': 0, 'cpu_info': host_stats['host_cpu_info']['cpu_count']} compute_node_ref = service_ref['compute_node'] if not compute_node_ref: LOG.info(_('Compute_service record created for %s ') % host) dic['service_id'] = service_ref['id'] db.compute_node_create(ctxt, dic) else: LOG.info(_('Compute_service record updated for %s ') % host) db.compute_node_update(ctxt, compute_node_ref[0]['id'], dic)
def _live_migration_common_check(self, context, instance_ref, dest, block_migration): """Live migration common check routine. Below checkings are followed by http://wiki.libvirt.org/page/TodoPreMigrationChecks :param context: security context :param instance_ref: engine.db.sqlalchemy.models.Instance object :param dest: destination host :param block_migration if True, check for block_migration. """ # Checking shared storage connectivity # if block migration, instances_paths should not be on shared storage. try: self.mounted_on_same_shared_storage(context, instance_ref, dest) if block_migration: reason = _("Block migration can not be used " "with shared storage.") raise exception.InvalidSharedStorage(reason=reason, path=dest) except exception.FileNotFound: if not block_migration: src = instance_ref['host'] ipath = FLAGS.instances_path LOG.error( _("Cannot confirm tmpfile at %(ipath)s is on " "same shared storage between %(src)s " "and %(dest)s.") % locals()) raise # Checking dest exists. dservice_refs = db.service_get_all_compute_by_host(context, dest) dservice_ref = dservice_refs[0]['compute_node'][0] # Checking original host( where instance was launched at) exists. try: oservice_refs = db.service_get_all_compute_by_host( context, instance_ref['launched_on']) except exception.NotFound: raise exception.SourceHostUnavailable() oservice_ref = oservice_refs[0]['compute_node'][0] # Checking hypervisor is same. orig_hypervisor = oservice_ref['hypervisor_type'] dest_hypervisor = dservice_ref['hypervisor_type'] if orig_hypervisor != dest_hypervisor: raise exception.InvalidHypervisorType() # Checkng hypervisor version. orig_hypervisor = oservice_ref['hypervisor_version'] dest_hypervisor = dservice_ref['hypervisor_version'] if orig_hypervisor > dest_hypervisor: raise exception.DestinationHypervisorTooOld() # Checking cpuinfo. try: rpc.call( context, db.queue_get_for(context, FLAGS.compute_topic, dest), { "method": 'compare_cpu', "args": { 'cpu_info': oservice_ref['cpu_info'] } }) except rpc.RemoteError: src = instance_ref['host'] LOG.exception( _("host %(dest)s is not compatible with " "original host %(src)s.") % locals()) raise
def _live_migration_common_check(self, context, instance_ref, dest, block_migration): """Live migration common check routine. Below checkings are followed by http://wiki.libvirt.org/page/TodoPreMigrationChecks :param context: security context :param instance_ref: engine.db.sqlalchemy.models.Instance object :param dest: destination host :param block_migration if True, check for block_migration. """ # Checking shared storage connectivity # if block migration, instances_paths should not be on shared storage. try: self.mounted_on_same_shared_storage(context, instance_ref, dest) if block_migration: reason = _("Block migration can not be used " "with shared storage.") raise exception.InvalidSharedStorage(reason=reason, path=dest) except exception.FileNotFound: if not block_migration: src = instance_ref['host'] ipath = FLAGS.instances_path LOG.error(_("Cannot confirm tmpfile at %(ipath)s is on " "same shared storage between %(src)s " "and %(dest)s.") % locals()) raise # Checking dest exists. dservice_refs = db.service_get_all_compute_by_host(context, dest) dservice_ref = dservice_refs[0]['compute_node'][0] # Checking original host( where instance was launched at) exists. try: oservice_refs = db.service_get_all_compute_by_host(context, instance_ref['launched_on']) except exception.NotFound: raise exception.SourceHostUnavailable() oservice_ref = oservice_refs[0]['compute_node'][0] # Checking hypervisor is same. orig_hypervisor = oservice_ref['hypervisor_type'] dest_hypervisor = dservice_ref['hypervisor_type'] if orig_hypervisor != dest_hypervisor: raise exception.InvalidHypervisorType() # Checkng hypervisor version. orig_hypervisor = oservice_ref['hypervisor_version'] dest_hypervisor = dservice_ref['hypervisor_version'] if orig_hypervisor > dest_hypervisor: raise exception.DestinationHypervisorTooOld() # Checking cpuinfo. try: rpc.call(context, db.queue_get_for(context, FLAGS.compute_topic, dest), {"method": 'compare_cpu', "args": {'cpu_info': oservice_ref['cpu_info']}}) except rpc.RemoteError: src = instance_ref['host'] LOG.exception(_("host %(dest)s is not compatible with " "original host %(src)s.") % locals()) raise