From 2925ca3ac3010b9a65276ad2cfc8118679827da3 Mon Sep 17 00:00:00 2001 From: masumotok Date: Tue, 7 Dec 2010 19:25:43 +0900 Subject: rev439ベースにライブマイグレーションの機能をマージ このバージョンはEBSなし、CPUフラグのチェックなし MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nova/compute/api.py | 3 ++ nova/compute/manager.py | 138 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 929342a1e..03922c272 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -84,6 +84,7 @@ class ComputeAPI(base.Base): if not type(security_group) is list: security_group = [security_group] + print '<<<<<<<<<<<<<<<<<<<<<<<<<<1' security_groups = [] self.ensure_default_security_group(context) for security_group_name in security_group: @@ -92,6 +93,7 @@ class ComputeAPI(base.Base): security_group_name) security_groups.append(group['id']) + print '<<<<<<<<<<<<<<<<<<<<<<<<<<2' if key_data is None and key_name: key_pair = db.key_pair_get(context, context.user_id, key_name) key_data = key_pair['public_key'] @@ -115,6 +117,7 @@ class ComputeAPI(base.Base): 'key_name': key_name, 'key_data': key_data} + print '<<<<<<<<<<<<<<<<<<<<<<<<<<3' elevated = context.elevated() instances = [] logging.debug("Going to run %s instances...", num_instances) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index dd8d41129..4c42153b6 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -36,6 +36,13 @@ terminating it. import datetime import logging +# added by masumotok +import sys +# added by masumotok +import traceback +# added by masumotok +import os + from twisted.internet import defer @@ -44,12 +51,19 @@ from nova import flags from nova import manager from nova import utils from nova.compute import power_state +# added by masumotok +from nova import rpc +# added by masumotok +from nova import db FLAGS = flags.FLAGS flags.DEFINE_string('instances_path', '$state_path/instances', 'where instances are stored on disk') flags.DEFINE_string('compute_driver', 'nova.virt.connection.get_connection', 'Driver to use for controlling virtualization') +# created by masumotok +flags.DEFINE_string('live_migration_timeout', 30, + 'Timeout value for pre_live_migration is completed.') class ComputeManager(manager.Manager): @@ -251,3 +265,127 @@ class ComputeManager(manager.Manager): yield self.volume_manager.remove_compute_volume(context, volume_id) self.db.volume_detached(context, volume_id) defer.returnValue(True) + + # created by masumotok + def get_cpu_number(self): + """Get the number of physical computer cpu core .""" + return open('/proc/cpuinfo').read().count('processor') + + # created by masumotok + def get_mem_size(self): + """Get the memory size of physical computer .""" + meminfo = open('/proc/meminfo').read().split() + idx = meminfo.index('MemTotal:') + # transforming kb to mb. + return int(meminfo[idx + 1]) / 1024 + + # created by masumotok + def get_hdd_size(self): + """Get the hdd size of physical computer .""" + hddinfo = os.statvfs(FLAGS.instances_path) + return hddinfo.f_bsize * hddinfo.f_blocks / 1024 / 1024 / 1024 + + # created by masumotok + def pre_live_migration(self, context, instance_id, dest): + """Any preparation for live migration at dst host.""" + + # 1. getting volume info ( shlf/slot number ) + instance_ref = db.instance_get(context, instance_id) + ec2_id = instance_ref['hostname'] + + volumes = [] + try: + volumes = db.volume_get_by_ec2_id(context, ec2_id) + except exception.NotFound: + logging.debug('%s has no volume.', ec2_id) + + shelf_slots = {} + for vol in volumes: + shelf, slot = db.volume_get_shelf_and_blade(context, vol['id']) + shelf_slots[vol.id] = (shelf, slot) + + # 2. getting fixed ips + fixed_ip = db.instance_get_fixed_address(context, instance_id) + if None == fixed_ip: + logging.error('Not found fixedip for %s\n%s', + ec2_id, + ''.join(traceback.format_tb(sys.exc_info()[2]))) + return + + # 3. getting network refs + network_ref = db.fixed_ip_get_network(context, fixed_ip) + + # 4. security rules (filtering rules) + secgrp_refs = db.security_group_get_by_instance(context, instance_id) + + # 5. if any volume is mounted, prepare here. + if 0 != len(shelf_slots): + pass + + # 6. create nova-instance-instance-xxx in hypervisor through libvirt + # (This rule can be seen by executing virsh nwfilter-list) + self.driver.setup_nwfilters_for_instance(instance_ref) + + # 7. insert filtering rule + for secgrp_ref in secgrp_refs: + self.driver.refresh_security_group(secgrp_ref.id) + + # 8. vlan settings + self.network_manager.driver.ensure_vlan_bridge(network_ref['vlan'], + network_ref['bridge']) + + # created by masumotok + def nwfilter_for_instance_exists(self, context, instance_id): + """Check nova-instance-instance-xxx filter exists """ + instance_ref = db.instance_get(context, instance_id) + return self.driver.nwfilter_for_instance_exists(instance_ref) + + # created by masumotok + def live_migration(self, context, instance_id, dest): + """executes live migration.""" + + import time + # 1. ask dest host to preparing live migration. + compute_topic = db.queue_get_for(context, FLAGS.compute_topic, dest) + ret = rpc.call(context, + compute_topic, + {"method": "pre_live_migration", + "args": {'instance_id': instance_id, + 'dest': dest}}) + + if rpc.RemoteError == type(ret): + logging.error('Live migration failed(err at %s)', dest) + db.instance_set_state(context, + instance_id, + power_state.RUNNING, + 'running') + return + + # waiting for setting up nwfilter(nova-instance-instance-xxx) + # otherwise, live migration fail. + timeout_count = range(FLAGS.live_migration_timeout) + while 0 != len(timeout_count): + ret = rpc.call(context, + compute_topic, + {"method": "nwfilter_for_instance_exists", + "args": {'instance_id': instance_id}}) + if ret: + break + + timeout_count.pop() + time.sleep(1) + + if not ret: + logging.error('Timeout for pre_live_migration at %s', dest) + return + + # 2. executing live migration + # live_migration might raises ProcessExecution error, but + # nothing must be recovered in this version. + instance_ref = db.instance_get(context, instance_id) + ret = self.driver.live_migration(instance_ref, dest) + if not ret: + logging.debug('Fail to live migration') + return + + -- cgit From 3313a5170a83feb6e571faa6296ffea7f065ec25 Mon Sep 17 00:00:00 2001 From: masumotok Date: Wed, 8 Dec 2010 17:21:04 +0900 Subject: コメントを除去 README.live_migration.txtのレビュー結果を修正 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nova/compute/api.py | 3 --- nova/compute/manager.py | 12 ------------ 2 files changed, 15 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 03922c272..929342a1e 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -84,7 +84,6 @@ class ComputeAPI(base.Base): if not type(security_group) is list: security_group = [security_group] - print '<<<<<<<<<<<<<<<<<<<<<<<<<<1' security_groups = [] self.ensure_default_security_group(context) for security_group_name in security_group: @@ -93,7 +92,6 @@ class ComputeAPI(base.Base): security_group_name) security_groups.append(group['id']) - print '<<<<<<<<<<<<<<<<<<<<<<<<<<2' if key_data is None and key_name: key_pair = db.key_pair_get(context, context.user_id, key_name) key_data = key_pair['public_key'] @@ -117,7 +115,6 @@ class ComputeAPI(base.Base): 'key_name': key_name, 'key_data': key_data} - print '<<<<<<<<<<<<<<<<<<<<<<<<<<3' elevated = context.elevated() instances = [] logging.debug("Going to run %s instances...", num_instances) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 4c42153b6..d271d17a4 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -36,11 +36,8 @@ terminating it. import datetime import logging -# added by masumotok import sys -# added by masumotok import traceback -# added by masumotok import os @@ -51,9 +48,7 @@ from nova import flags from nova import manager from nova import utils from nova.compute import power_state -# added by masumotok from nova import rpc -# added by masumotok from nova import db FLAGS = flags.FLAGS @@ -61,7 +56,6 @@ flags.DEFINE_string('instances_path', '$state_path/instances', 'where instances are stored on disk') flags.DEFINE_string('compute_driver', 'nova.virt.connection.get_connection', 'Driver to use for controlling virtualization') -# created by masumotok flags.DEFINE_string('live_migration_timeout', 30, 'Timeout value for pre_live_migration is completed.') @@ -266,12 +260,10 @@ class ComputeManager(manager.Manager): self.db.volume_detached(context, volume_id) defer.returnValue(True) - # created by masumotok def get_cpu_number(self): """Get the number of physical computer cpu core .""" return open('/proc/cpuinfo').read().count('processor') - # created by masumotok def get_mem_size(self): """Get the memory size of physical computer .""" meminfo = open('/proc/meminfo').read().split() @@ -279,13 +271,11 @@ class ComputeManager(manager.Manager): # transforming kb to mb. return int(meminfo[idx + 1]) / 1024 - # created by masumotok def get_hdd_size(self): """Get the hdd size of physical computer .""" hddinfo = os.statvfs(FLAGS.instances_path) return hddinfo.f_bsize * hddinfo.f_blocks / 1024 / 1024 / 1024 - # created by masumotok def pre_live_migration(self, context, instance_id, dest): """Any preparation for live migration at dst host.""" @@ -334,13 +324,11 @@ class ComputeManager(manager.Manager): self.network_manager.driver.ensure_vlan_bridge(network_ref['vlan'], network_ref['bridge']) - # created by masumotok def nwfilter_for_instance_exists(self, context, instance_id): """Check nova-instance-instance-xxx filter exists """ instance_ref = db.instance_get(context, instance_id) return self.driver.nwfilter_for_instance_exists(instance_ref) - # created by masumotok def live_migration(self, context, instance_id, dest): """executes live migration.""" -- cgit From 4809c1bf82130f969614a8f0458636a462b81a88 Mon Sep 17 00:00:00 2001 From: masumotok Date: Thu, 16 Dec 2010 18:20:04 +0900 Subject: Hostテーブルのカラム名を修正 FlatManager, FlatDHCPManagerに対応 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nova/compute/manager.py | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index d271d17a4..81cca7770 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -260,9 +260,9 @@ class ComputeManager(manager.Manager): self.db.volume_detached(context, volume_id) defer.returnValue(True) - def get_cpu_number(self): - """Get the number of physical computer cpu core .""" - return open('/proc/cpuinfo').read().count('processor') + def get_vcpu_number(self): + """Get the number of vcpu on physical computer.""" + return self.driver.get_vcpu_number() def get_mem_size(self): """Get the memory size of physical computer .""" @@ -302,27 +302,19 @@ class ComputeManager(manager.Manager): ''.join(traceback.format_tb(sys.exc_info()[2]))) return - # 3. getting network refs - network_ref = db.fixed_ip_get_network(context, fixed_ip) - - # 4. security rules (filtering rules) - secgrp_refs = db.security_group_get_by_instance(context, instance_id) - - # 5. if any volume is mounted, prepare here. + # 3. if any volume is mounted, prepare here. if 0 != len(shelf_slots): pass - # 6. create nova-instance-instance-xxx in hypervisor through libvirt - # (This rule can be seen by executing virsh nwfilter-list) + # 4. Creating nova-instance-instance-xxx, this is written to libvirt.xml, + # and can be seen when executin "virsh nwfiter-list" On destination host, + # this nwfilter is necessary. + # In addition this method is creating security rule ingress rule onto + # destination host. self.driver.setup_nwfilters_for_instance(instance_ref) - # 7. insert filtering rule - for secgrp_ref in secgrp_refs: - self.driver.refresh_security_group(secgrp_ref.id) - - # 8. vlan settings - self.network_manager.driver.ensure_vlan_bridge(network_ref['vlan'], - network_ref['bridge']) + # 5. bridge settings + self.network_manager.setup_compute_network(instance_id) def nwfilter_for_instance_exists(self, context, instance_id): """Check nova-instance-instance-xxx filter exists """ @@ -375,5 +367,3 @@ class ComputeManager(manager.Manager): if not ret: logging.debug('Fail to live migration') return - - -- cgit From 70f1f0d8c7a7214c5b6683c0be863cdbf0f060af Mon Sep 17 00:00:00 2001 From: masumotok Date: Mon, 20 Dec 2010 08:03:25 +0900 Subject: テストコードをレポジトリに追加 nova.compute.manager.pre_live_migration()について、異常終了しているのに正常終了の戻り値を返すことがあったため変更 - 正常終了の戻り値をTrueに変更 - fixed_ipが見つからないときにはRemoteErrorをraiseする - それに合わせてnova.compute.manager.live_migrationも変更 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nova/compute/manager.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 81cca7770..bad525115 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -39,6 +39,7 @@ import logging import sys import traceback import os +import time from twisted.internet import defer @@ -297,10 +298,10 @@ class ComputeManager(manager.Manager): # 2. getting fixed ips fixed_ip = db.instance_get_fixed_address(context, instance_id) if None == fixed_ip: - logging.error('Not found fixedip for %s\n%s', - ec2_id, - ''.join(traceback.format_tb(sys.exc_info()[2]))) - return + exc_type = 'NotFoundError' + val = '%s(%s) doesnt have fixed_ip ' % (instance_id, ec2_id) + tb = ''.join(traceback.format_tb(sys.exc_info()[2])) + raise rpc.RemoteError(exc_type, val, tb) # 3. if any volume is mounted, prepare here. if 0 != len(shelf_slots): @@ -315,6 +316,7 @@ class ComputeManager(manager.Manager): # 5. bridge settings self.network_manager.setup_compute_network(instance_id) + return True def nwfilter_for_instance_exists(self, context, instance_id): """Check nova-instance-instance-xxx filter exists """ @@ -324,7 +326,6 @@ class ComputeManager(manager.Manager): def live_migration(self, context, instance_id, dest): """executes live migration.""" - import time # 1. ask dest host to preparing live migration. compute_topic = db.queue_get_for(context, FLAGS.compute_topic, dest) ret = rpc.call(context, @@ -333,7 +334,7 @@ class ComputeManager(manager.Manager): "args": {'instance_id': instance_id, 'dest': dest}}) - if rpc.RemoteError == type(ret): + if True != ret: logging.error('Live migration failed(err at %s)', dest) db.instance_set_state(context, instance_id, -- cgit From df045f9252f6a50171d477c265564f062294e47a Mon Sep 17 00:00:00 2001 From: masumotok Date: Mon, 20 Dec 2010 08:06:11 +0900 Subject: テストコードをレポジトリに追加 nova.compute.manager.pre_live_migration()について、異常終了しているのに正常終了の戻り値を返すことがあったため変更 - 正常終了の戻り値をTrueに変更 - fixed_ipが見つからないときにはRemoteErrorをraiseする - それに合わせてnova.compute.manager.live_migrationも変更 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nova/compute/manager.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 81cca7770..bad525115 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -39,6 +39,7 @@ import logging import sys import traceback import os +import time from twisted.internet import defer @@ -297,10 +298,10 @@ class ComputeManager(manager.Manager): # 2. getting fixed ips fixed_ip = db.instance_get_fixed_address(context, instance_id) if None == fixed_ip: - logging.error('Not found fixedip for %s\n%s', - ec2_id, - ''.join(traceback.format_tb(sys.exc_info()[2]))) - return + exc_type = 'NotFoundError' + val = '%s(%s) doesnt have fixed_ip ' % (instance_id, ec2_id) + tb = ''.join(traceback.format_tb(sys.exc_info()[2])) + raise rpc.RemoteError(exc_type, val, tb) # 3. if any volume is mounted, prepare here. if 0 != len(shelf_slots): @@ -315,6 +316,7 @@ class ComputeManager(manager.Manager): # 5. bridge settings self.network_manager.setup_compute_network(instance_id) + return True def nwfilter_for_instance_exists(self, context, instance_id): """Check nova-instance-instance-xxx filter exists """ @@ -324,7 +326,6 @@ class ComputeManager(manager.Manager): def live_migration(self, context, instance_id, dest): """executes live migration.""" - import time # 1. ask dest host to preparing live migration. compute_topic = db.queue_get_for(context, FLAGS.compute_topic, dest) ret = rpc.call(context, @@ -333,7 +334,7 @@ class ComputeManager(manager.Manager): "args": {'instance_id': instance_id, 'dest': dest}}) - if rpc.RemoteError == type(ret): + if True != ret: logging.error('Live migration failed(err at %s)', dest) db.instance_set_state(context, instance_id, -- cgit From f983884dd262f46907f80a04121d957347881240 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 24 Dec 2010 15:09:05 +0900 Subject: nova.compute.managerがこれまでの修正でデグレしていたので修正 CPUID, その他のチェックルーチンをnova.scheduler.manager.live_migrationに追加 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nova/compute/manager.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index bad525115..c2c532c6d 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -105,7 +105,7 @@ class ComputeManager(manager.Manager): self.network_manager.setup_compute_network(context, instance_id) self.db.instance_update(context, instance_id, - {'host': self.host}) + {'host': self.host, 'launch_at':self.host}) # TODO(vish) check to make sure the availability zone matches self.db.instance_set_state(context, @@ -261,18 +261,19 @@ class ComputeManager(manager.Manager): self.db.volume_detached(context, volume_id) defer.returnValue(True) - def get_vcpu_number(self): - """Get the number of vcpu on physical computer.""" - return self.driver.get_vcpu_number() + def compareCPU(self, context, xml): + """ Check the host cpu is compatible to a cpu given by xml.""" + logging.warn('good!') + return self.driver.compareCPU(xml) - def get_mem_size(self): + def get_memory_mb(self): """Get the memory size of physical computer .""" meminfo = open('/proc/meminfo').read().split() idx = meminfo.index('MemTotal:') # transforming kb to mb. return int(meminfo[idx + 1]) / 1024 - def get_hdd_size(self): + def get_local_gb(self): """Get the hdd size of physical computer .""" hddinfo = os.statvfs(FLAGS.instances_path) return hddinfo.f_bsize * hddinfo.f_blocks / 1024 / 1024 / 1024 @@ -315,7 +316,7 @@ class ComputeManager(manager.Manager): self.driver.setup_nwfilters_for_instance(instance_ref) # 5. bridge settings - self.network_manager.setup_compute_network(instance_id) + self.network_manager.setup_compute_network(context, instance_id) return True def nwfilter_for_instance_exists(self, context, instance_id): -- cgit From 85acbbe916df8b2d18f0dc3a0b8cad9fcfdd6907 Mon Sep 17 00:00:00 2001 From: masumotok Date: Mon, 27 Dec 2010 17:49:07 +0900 Subject: launch_at を前回コミット時に追加したが、lauched_atというカラムが既に存在し、 紛らわしいのでlauched_onにした。 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nova/compute/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 3e468b3a4..66bbb8d5a 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -105,7 +105,7 @@ class ComputeManager(manager.Manager): self.network_manager.setup_compute_network(context, instance_id) self.db.instance_update(context, instance_id, - {'host': self.host, 'launch_at':self.host}) + {'host': self.host, 'launched_on':self.host}) # TODO(vish) check to make sure the availability zone matches self.db.instance_set_state(context, -- cgit From 3bf9bc6f6c0fbf90e3f4eab68a9bd99d85fcc422 Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Thu, 6 Jan 2011 21:37:33 -0600 Subject: Reserving image before uploading --- nova/compute/api.py | 10 +++++++++- nova/compute/manager.py | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 07c69bd31..5bb6fac91 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -263,10 +263,18 @@ class ComputeAPI(base.Base): """Snapshot the given instance.""" instance = self.db.instance_get_by_internal_id(context, instance_id) host = instance['host'] + + image_service = utils.import_object(FLAGS.image_service) + + data = {'name': name, 'is_public': True} + image_meta = image_service.create(context, data) rpc.cast(context, self.db.queue_get_for(context, FLAGS.compute_topic, host), {"method": "snapshot_instance", - "args": {"instance_id": instance['id'], "name": name}}) + "args": {"instance_id": instance['id'], + "image_id": image_meta['id']}}) + + return image_meta def reboot(self, context, instance_id): """Reboot the given instance.""" diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 6e8f34347..27e07ed59 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -225,7 +225,7 @@ class ComputeManager(manager.Manager): self._update_state(context, instance_id) @exception.wrap_exception - def snapshot_instance(self, context, instance_id, name): + def snapshot_instance(self, context, instance_id, image_id): """Snapshot an instance on this server.""" context = context.elevated() instance_ref = self.db.instance_get(context, instance_id) @@ -243,7 +243,7 @@ class ComputeManager(manager.Manager): instance_ref['state'], power_state.RUNNING) - self.driver.snapshot(instance_ref, name) + self.driver.snapshot(instance_ref, image_id) @exception.wrap_exception def rescue_instance(self, context, instance_id): -- cgit From 8de96296dfb22d0e6c491fcaf072210dfbaa67e8 Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Thu, 6 Jan 2011 23:38:01 -0600 Subject: Removing some FIXMEs --- nova/compute/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 5bb6fac91..75759744d 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -263,7 +263,7 @@ class ComputeAPI(base.Base): """Snapshot the given instance.""" instance = self.db.instance_get_by_internal_id(context, instance_id) host = instance['host'] - + image_service = utils.import_object(FLAGS.image_service) data = {'name': name, 'is_public': True} -- cgit From 5afd9848ad09414c00062ceebdad45bca0604888 Mon Sep 17 00:00:00 2001 From: Muneyuki Noguchi Date: Tue, 11 Jan 2011 18:01:23 +0900 Subject: Add support for EBS volumes to the live migration feature. Currently, only AoE is supported. --- nova/compute/api.py | 3 ++- nova/compute/manager.py | 55 ++++++++++++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 24 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 5a776afa5..da41cc63c 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -233,7 +233,8 @@ class ComputeAPI(base.Base): terminated_at=datetime.datetime.utcnow()) host = instance['host'] - logging.error('terminate %s %s %s %s',context, FLAGS.compute_topic, host, self.db.queue_get_for(context, FLAGS.compute_topic, host)) + logging.error('terminate %s %s %s %s', context, FLAGS.compute_topic, + host, self.db.queue_get_for(context, FLAGS.compute_topic, host)) if host: rpc.cast(context, self.db.queue_get_for(context, FLAGS.compute_topic, host), diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 1e8e11d04..a78789e63 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -122,7 +122,7 @@ class ComputeManager(manager.Manager): raise exception.Error(_("Instance has already been created")) self.db.instance_update(context, instance_id, - {'host': self.host, 'launched_on':self.host}) + {'host': self.host, 'launched_on': self.host}) self.db.instance_set_state(context, instance_id, @@ -443,21 +443,10 @@ class ComputeManager(manager.Manager): def pre_live_migration(self, context, instance_id, dest): """Any preparation for live migration at dst host.""" - # Getting volume info ( shlf/slot number ) + # Getting volume info instance_ref = db.instance_get(context, instance_id) ec2_id = instance_ref['hostname'] - volumes = [] - try: - volumes = db.volume_get_by_ec2_id(context, ec2_id) - except exception.NotFound: - logging.info(_('%s has no volume.'), ec2_id) - - shelf_slots = {} - for vol in volumes: - shelf, slot = db.volume_get_shelf_and_blade(context, vol['id']) - shelf_slots[vol.id] = (shelf, slot) - # Getting fixed ips fixed_ip = db.instance_get_fixed_address(context, instance_id) if None == fixed_ip: @@ -466,18 +455,22 @@ class ComputeManager(manager.Manager): tb = ''.join(traceback.format_tb(sys.exc_info()[2])) raise rpc.RemoteError(exc_type, val, tb) - # If any volume is mounted, prepare here. - if 0 != len(shelf_slots): - pass - - # Creating nova-instance-instance-xxx, this is written to libvirt.xml, - # and can be seen when executin "virsh nwfiter-list" On destination host, - # this nwfilter is necessary. - # In addition this method is creating security rule ingress rule onto - # destination host. + # if any volume is mounted, prepare here. + try: + for vol in db.volume_get_all_by_instance(context, instance_id): + self.volume_manager.setup_compute_volume(context, vol['id']) + except exception.NotFound: + logging.info(_("%s has no volume.") % ec2_id) + + # Creating nova-instance-instance-xxx, + # this is written to libvirt.xml, + # and can be seen when executin "virsh nwfiter-list" + # On destination host, this nwfilter is necessary. + # In addition this method is creating security rule ingress rule + # onto destination host. self.driver.setup_nwfilters_for_instance(instance_ref) - # 5. bridge settings + # bridge settings self.network_manager.setup_compute_network(context, instance_id) return True @@ -497,12 +490,23 @@ class ComputeManager(manager.Manager): "args": {'instance_id': instance_id, 'dest': dest}}) + instance_ref = db.instance_get(context, instance_id) + ec2_id = instance_ref['hostname'] if True != ret: logging.error(_('Pre live migration failed(err at %s)'), dest) db.instance_set_state(context, instance_id, power_state.RUNNING, 'running') + + try: + for vol in db.volume_get_all_by_instance(context, instance_id): + db.volume_update(context, + vol['id'], + {'status': 'in-use'}) + except exception.NotFound: + pass + return # Waiting for setting up nwfilter such as, nova-instance-instance-xxx. @@ -523,6 +527,11 @@ class ComputeManager(manager.Manager): logging.error(_('Timeout for pre_live_migration at %s'), dest) return + rpc.call(context, + FLAGS.volume_topic, + {"method": "check_for_export", + "args": {'instance_id': instance_id}}) + # Executing live migration # live_migration might raises ProcessExecution error, but # nothing must be recovered in this version. -- cgit From 69a2612be4e865063fa5982462673f1843e8befc Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Tue, 11 Jan 2011 13:54:23 -0600 Subject: Changes per Edays comments --- nova/compute/api.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 7e30d45d6..c02550419 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -333,10 +333,8 @@ class API(base.Base): instance = self.get(context, instance_id) host = instance['host'] - image_service = utils.import_object(FLAGS.image_service) - data = {'name': name, 'is_public': True} - image_meta = image_service.create(context, data) + image_meta = self.image_service.create(context, data) rpc.cast(context, self.db.queue_get_for(context, FLAGS.compute_topic, host), {"method": "snapshot_instance", -- cgit From 204e5a2d9a481abba64ce31c12510d7e1bf288a6 Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Wed, 12 Jan 2011 16:03:51 -0600 Subject: Adding TODO to clarify status --- nova/compute/api.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 63d0c59c1..923234e3a 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -337,6 +337,9 @@ class API(base.Base): instance = self.get(context, instance_id) host = instance['host'] + # TODO(sirp): When Glance supports images tied to servers, this should + # be replaced by something like 'is_public': False, 'server_id': + # instance_id data = {'name': name, 'is_public': True} image_meta = self.image_service.create(context, data) rpc.cast(context, -- cgit From 98cb2518467374ae87d7dbc70890f79bb5084960 Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Thu, 13 Jan 2011 14:01:21 -0600 Subject: Marking snapshots as private for now --- nova/compute/api.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index 923234e3a..6d9d4fbbb 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -337,10 +337,7 @@ class API(base.Base): instance = self.get(context, instance_id) host = instance['host'] - # TODO(sirp): When Glance supports images tied to servers, this should - # be replaced by something like 'is_public': False, 'server_id': - # instance_id - data = {'name': name, 'is_public': True} + data = {'name': name, 'is_public': False} image_meta = self.image_service.create(context, data) rpc.cast(context, self.db.queue_get_for(context, FLAGS.compute_topic, host), -- cgit From c57ccba743c54786e28317194000bcf22dc5b69e Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Fri, 14 Jan 2011 08:26:25 +0900 Subject: checking based on pep8 --- nova/compute/manager.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 00de85828..5db756362 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -561,7 +561,7 @@ class ComputeManager(manager.Manager): self.network_manager.setup_compute_network(context, instance_id) # Creating filters to hypervisors and firewalls. - # An example is that nova-instance-instance-xxx, + # An example is that nova-instance-instance-xxx, # which is written to libvirt.xml( check "virsh nwfilter-list ) # On destination host, this nwfilter is necessary. # In addition, this method is creating filtering rule @@ -575,8 +575,8 @@ class ComputeManager(manager.Manager): instance_ref = db.instance_get(context, instance_id) ec2_id = instance_ref['hostname'] - try: - # Checking volume node is working correctly when any volumes + try: + # Checking volume node is working correctly when any volumes # are attached to instances. rpc.call(context, FLAGS.volume_topic, @@ -584,7 +584,9 @@ class ComputeManager(manager.Manager): "args": {'instance_id': instance_id}}) # Asking dest host to preparing live migration. - compute_topic = db.queue_get_for(context, FLAGS.compute_topic, dest) + compute_topic = db.queue_get_for(context, + FLAGS.compute_topic, + dest) rpc.call(context, compute_topic, -- cgit From 525544e689334346305ecc11552105fc1b32a5dd Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Sun, 16 Jan 2011 14:54:35 +0900 Subject: merged to rev 561 and fixed based on reviewer's comment --- nova/compute/manager.py | 65 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 18 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 5db756362..9c8cb363c 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -39,6 +39,7 @@ import logging import socket import functools +from nova import context from nova import db from nova import exception from nova import flags @@ -117,6 +118,37 @@ class ComputeManager(manager.Manager): """ self.driver.init_host() + + def update_service(self, ctxt, host, binary): + """Insert compute node specific information to DB.""" + + try: + service_ref = db.service_get_by_args(ctxt, + host, + binary) + except exception.NotFound: + msg = _(("""Cannot insert compute manager specific info""" + """Because no service record found.""")) + raise exception.invalid(msg) + + # Updating host information + vcpu = self.driver.get_vcpu_number() + memory_mb = self.driver.get_memory_mb() + local_gb = self.driver.get_local_gb() + hypervisor = self.driver.get_hypervisor_type() + version = self.driver.get_hypervisor_version() + cpu_info = self.driver.get_cpu_info() + + db.service_update(ctxt, + service_ref['id'], + {'vcpus': vcpu, + 'memory_mb': memory_mb, + 'local_gb': local_gb, + 'hypervisor_type': hypervisor, + 'hypervisor_version': version, + 'cpu_info': cpu_info}) + + def _update_state(self, context, instance_id): """Update the state of an instance from the driver info.""" # FIXME(ja): include other fields from state? @@ -530,9 +562,9 @@ class ComputeManager(manager.Manager): self.db.volume_detached(context, volume_id) return True - def compare_cpu(self, context, xml): + def compare_cpu(self, context, cpu_info): """ Check the host cpu is compatible to a cpu given by xml.""" - return self.driver.compare_cpu(xml) + return self.driver.compare_cpu(cpu_info) def pre_live_migration(self, context, instance_id, dest): """Any preparation for live migration at dst host.""" @@ -548,11 +580,11 @@ class ComputeManager(manager.Manager): raise exception.NotFound(msg) # If any volume is mounted, prepare here. - try: - for vol in db.volume_get_all_by_instance(context, instance_id): - self.volume_manager.setup_compute_volume(context, vol['id']) - except exception.NotFound: + if len(instance_ref['volumes']) == 0: logging.info(_("%s has no volume.") % ec2_id) + else: + for v in instance_ref['volumes']: + self.volume_manager.setup_compute_volume(context, v['id']) # Bridge settings # call this method prior to ensure_filtering_rules_for_instance, @@ -578,16 +610,16 @@ class ComputeManager(manager.Manager): try: # Checking volume node is working correctly when any volumes # are attached to instances. - rpc.call(context, - FLAGS.volume_topic, - {"method": "check_for_export", - "args": {'instance_id': instance_id}}) + if len(instance_ref['volumes']) != 0: + rpc.call(context, + FLAGS.volume_topic, + {"method": "check_for_export", + "args": {'instance_id': instance_id}}) # Asking dest host to preparing live migration. compute_topic = db.queue_get_for(context, FLAGS.compute_topic, dest) - rpc.call(context, compute_topic, {"method": "pre_live_migration", @@ -602,13 +634,10 @@ class ComputeManager(manager.Manager): power_state.RUNNING, 'running') - try: - for vol in db.volume_get_all_by_instance(context, instance_id): - db.volume_update(context, - vol['id'], - {'status': 'in-use'}) - except exception.NotFound: - pass + for v in instance_ref['volumes']: + db.volume_update(context, + v['id'], + {'status': 'in-use'}) # e should be raised. just calling "raise" may raise NotFound. raise e -- cgit From 523d7788acd6ecb0835dfda73d4cd5540a651a85 Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Mon, 17 Jan 2011 11:21:56 -0600 Subject: Returning image_metadata from snapshot() --- nova/compute/api.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index d3fa4d786..d5c70e0cd 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -361,7 +361,7 @@ class API(base.Base): :param params: Optional dictionary of arguments to be passed to the compute worker - :retval Result returned by compute worker + :retval: Result returned by compute worker """ if not params: params = {} @@ -374,12 +374,16 @@ class API(base.Base): return rpc.call(context, queue, kwargs) def snapshot(self, context, instance_id, name): - """Snapshot the given instance.""" + """Snapshot the given instance. + + :retval: A dict containing image metadata + """ data = {'name': name, 'is_public': False} image_meta = self.image_service.create(context, data) params = {'image_id': image_meta['id']} self._cast_compute_message('snapshot_instance', context, instance_id, params=params) + return image_meta def reboot(self, context, instance_id): """Reboot the given instance.""" -- cgit From c947f4ed1214c83434436a8e5263233f945aa4f9 Mon Sep 17 00:00:00 2001 From: Rick Harris Date: Mon, 17 Jan 2011 11:34:01 -0600 Subject: Fixing whitespace --- nova/compute/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/api.py b/nova/compute/api.py index d5c70e0cd..a6b99c1cb 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -375,8 +375,8 @@ class API(base.Base): def snapshot(self, context, instance_id, name): """Snapshot the given instance. - - :retval: A dict containing image metadata + + :retval: A dict containing image metadata """ data = {'name': name, 'is_public': False} image_meta = self.image_service.create(context, data) -- cgit From f935cf4c6e679d1c8eed99bcabe0d4515c2ba254 Mon Sep 17 00:00:00 2001 From: Kei Masumoto Date: Wed, 19 Jan 2011 09:46:43 +0900 Subject: previous commit breaks volume.driver. fix it.. --- nova/compute/manager.py | 1 - 1 file changed, 1 deletion(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 644f601af..efb5753aa 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -41,7 +41,6 @@ import logging import socket import functools -from nova import context from nova import db from nova import exception from nova import flags -- cgit From d91229f7a3b60095677e1bb76a548668c59ee9e2 Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Tue, 18 Jan 2011 11:01:16 -0800 Subject: revert live_migration branch --- nova/compute/manager.py | 118 +----------------------------------------------- 1 file changed, 1 insertion(+), 117 deletions(-) (limited to 'nova/compute') diff --git a/nova/compute/manager.py b/nova/compute/manager.py index efb5753aa..6f09ce674 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -41,7 +41,6 @@ import logging import socket import functools -from nova import db from nova import exception from nova import flags from nova import log as logging @@ -121,35 +120,6 @@ class ComputeManager(manager.Manager): """ self.driver.init_host() - def update_service(self, ctxt, host, binary): - """Insert compute node specific information to DB.""" - - try: - service_ref = db.service_get_by_args(ctxt, - host, - binary) - except exception.NotFound: - msg = _(("""Cannot insert compute manager specific info""" - """Because no service record found.""")) - raise exception.Invalid(msg) - - # Updating host information - vcpu = self.driver.get_vcpu_number() - memory_mb = self.driver.get_memory_mb() - local_gb = self.driver.get_local_gb() - hypervisor = self.driver.get_hypervisor_type() - version = self.driver.get_hypervisor_version() - cpu_info = self.driver.get_cpu_info() - - db.service_update(ctxt, - service_ref['id'], - {'vcpus': vcpu, - 'memory_mb': memory_mb, - 'local_gb': local_gb, - 'hypervisor_type': hypervisor, - 'hypervisor_version': version, - 'cpu_info': cpu_info}) - def _update_state(self, context, instance_id): """Update the state of an instance from the driver info.""" # FIXME(ja): include other fields from state? @@ -208,10 +178,9 @@ class ComputeManager(manager.Manager): raise exception.Error(_("Instance has already been created")) LOG.audit(_("instance %s: starting..."), instance_id, context=context) - self.db.instance_update(context, instance_id, - {'host': self.host, 'launched_on': self.host}) + {'host': self.host}) self.db.instance_set_state(context, instance_id, @@ -591,88 +560,3 @@ class ComputeManager(manager.Manager): self.volume_manager.remove_compute_volume(context, volume_id) self.db.volume_detached(context, volume_id) return True - - def compare_cpu(self, context, cpu_info): - """ Check the host cpu is compatible to a cpu given by xml.""" - return self.driver.compare_cpu(cpu_info) - - def pre_live_migration(self, context, instance_id, dest): - """Any preparation for live migration at dst host.""" - - # Getting instance info - instance_ref = db.instance_get(context, instance_id) - ec2_id = instance_ref['hostname'] - - # Getting fixed ips - fixed_ip = db.instance_get_fixed_address(context, instance_id) - if not fixed_ip: - msg = _('%s(%s) doesnt have fixed_ip') % (instance_id, ec2_id) - raise exception.NotFound(msg) - - # If any volume is mounted, prepare here. - if len(instance_ref['volumes']) == 0: - logging.info(_("%s has no volume.") % ec2_id) - else: - for v in instance_ref['volumes']: - self.volume_manager.setup_compute_volume(context, v['id']) - - # Bridge settings - # call this method prior to ensure_filtering_rules_for_instance, - # since bridge is not set up, ensure_filtering_rules_for instance - # fails. - self.network_manager.setup_compute_network(context, instance_id) - - # Creating filters to hypervisors and firewalls. - # An example is that nova-instance-instance-xxx, - # which is written to libvirt.xml( check "virsh nwfilter-list ) - # On destination host, this nwfilter is necessary. - # In addition, this method is creating filtering rule - # onto destination host. - self.driver.ensure_filtering_rules_for_instance(instance_ref) - - def live_migration(self, context, instance_id, dest): - """executes live migration.""" - - # Get instance for error handling. - instance_ref = db.instance_get(context, instance_id) - ec2_id = instance_ref['hostname'] - - try: - # Checking volume node is working correctly when any volumes - # are attached to instances. - if len(instance_ref['volumes']) != 0: - rpc.call(context, - FLAGS.volume_topic, - {"method": "check_for_export", - "args": {'instance_id': instance_id}}) - - # Asking dest host to preparing live migration. - compute_topic = db.queue_get_for(context, - FLAGS.compute_topic, - dest) - rpc.call(context, - compute_topic, - {"method": "pre_live_migration", - "args": {'instance_id': instance_id, - 'dest': dest}}) - - except Exception, e: - msg = _('Pre live migration for %s failed at %s') - logging.error(msg, ec2_id, dest) - db.instance_set_state(context, - instance_id, - power_state.RUNNING, - 'running') - - for v in instance_ref['volumes']: - db.volume_update(context, - v['id'], - {'status': 'in-use'}) - - # e should be raised. just calling "raise" may raise NotFound. - raise e - - # Executing live migration - # live_migration might raises exceptions, but - # nothing must be recovered in this version. - self.driver.live_migration(context, instance_ref, dest) -- cgit