diff --git a/.mailmap b/.mailmap index 2af2d7cd..d13219ab 100644 --- a/.mailmap +++ b/.mailmap @@ -16,6 +16,8 @@ + + Masumoto diff --git a/Authors b/Authors index bcb2cd0f..82e07a6b 100644 --- a/Authors +++ b/Authors @@ -26,6 +26,7 @@ Josh Durgin Josh Kearney Joshua McKenty Justin Santa Barbara +Kei Masumoto Ken Pepple Koji Iida Lorin Hochstein @@ -34,6 +35,7 @@ Michael Gundlach Monsyne Dragon Monty Taylor MORITA Kazutaka +Muneyuki Noguchi Nachi Ueno Paul Voccio Rick Clark diff --git a/bin/nova-manage b/bin/nova-manage index b5842b59..1ad3120b 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -62,6 +62,7 @@ import time import IPy + # If ../nova/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), @@ -81,8 +82,9 @@ from nova import log as logging from nova import quota from nova import utils from nova.auth import manager +from nova import rpc from nova.cloudpipe import pipelib - +from nova.api.ec2 import cloud logging.basicConfig() FLAGS = flags.FLAGS @@ -465,6 +467,82 @@ class NetworkCommands(object): int(vpn_start), fixed_range_v6) +class InstanceCommands(object): + """Class for mangaging VM instances.""" + + def live_migration(self, ec2_id, dest): + """live_migration""" + + ctxt = context.get_admin_context() + instance_id = cloud.ec2_id_to_id(ec2_id) + + if FLAGS.connection_type != 'libvirt': + msg = _('Only KVM is supported for now. Sorry!') + raise exception.Error(msg) + + if FLAGS.volume_driver != 'nova.volume.driver.AOEDriver': + instance_ref = db.instance_get(ctxt, instance_id) + if len(instance_ref['volumes']) != 0: + msg = _(("""Volumes attached by ISCSIDriver""" + """ are not supported. Sorry!""")) + raise exception.Error(msg) + + rpc.call(ctxt, + FLAGS.scheduler_topic, + {"method": "live_migration", + "args": {"instance_id": instance_id, + "dest": dest, + "topic": FLAGS.compute_topic}}) + + msg = 'Migration of %s initiated. ' % ec2_id + msg += 'Check its progress using euca-describe-instances.' + print msg + + +class HostCommands(object): + """Class for mangaging host(physical nodes).""" + + def list(self): + """describe host list.""" + + # To supress msg: No handlers could be found for logger "amqplib" + logging.basicConfig() + + service_refs = db.service_get_all(context.get_admin_context()) + hosts = [h['host'] for h in service_refs] + hosts = list(set(hosts)) + for host in hosts: + print host + + def show(self, host): + """describe cpu/memory/hdd info for host.""" + + result = rpc.call(context.get_admin_context(), + FLAGS.scheduler_topic, + {"method": "show_host_resource", + "args": {"host": host}}) + + # Checking result msg format is necessary, that will have done + # when this feture is included in API. + if type(result) != dict: + print 'Unexpected error occurs' + elif not result['ret']: + print '%s' % result['msg'] + else: + cpu = result['phy_resource']['vcpus'] + mem = result['phy_resource']['memory_mb'] + hdd = result['phy_resource']['local_gb'] + + print 'HOST\t\tPROJECT\t\tcpu\tmem(mb)\tdisk(gb)' + print '%s\t\t\t%s\t%s\t%s' % (host, cpu, mem, hdd) + for p_id, val in result['usage'].items(): + print '%s\t%s\t\t%s\t%s\t%s' % (host, + p_id, + val['vcpus'], + val['memory_mb'], + val['local_gb']) + + class ServiceCommands(object): """Enable and disable running services""" @@ -527,6 +605,8 @@ CATEGORIES = [ ('vpn', VpnCommands), ('floating', FloatingIpCommands), ('network', NetworkCommands), + ('instance', InstanceCommands), + ('host', HostCommands), ('service', ServiceCommands), ('log', LogCommands)]