summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/nova-all3
-rwxr-xr-xbin/nova-api3
-rwxr-xr-xbin/nova-api-ec23
-rwxr-xr-xbin/nova-api-metadata3
-rwxr-xr-xbin/nova-api-os-compute3
-rwxr-xr-xbin/nova-cert3
-rwxr-xr-xbin/nova-clear-rabbit-queues3
-rwxr-xr-xbin/nova-compute3
-rwxr-xr-xbin/nova-console3
-rwxr-xr-xbin/nova-consoleauth3
-rwxr-xr-xbin/nova-dhcpbridge3
-rwxr-xr-xbin/nova-manage3
-rwxr-xr-xbin/nova-network3
-rwxr-xr-xbin/nova-novncproxy3
-rwxr-xr-xbin/nova-objectstore3
-rwxr-xr-xbin/nova-rpc-zmq-receiver3
-rwxr-xr-xbin/nova-scheduler3
-rwxr-xr-xbin/nova-xvpvncproxy3
-rw-r--r--nova/api/ec2/ec2utils.py8
-rw-r--r--nova/api/openstack/compute/contrib/floating_ips.py4
-rw-r--r--nova/api/openstack/compute/servers.py9
-rw-r--r--nova/compute/api.py7
-rw-r--r--nova/compute/manager.py47
-rw-r--r--nova/compute/rpcapi.py26
-rw-r--r--nova/config.py29
-rw-r--r--nova/console/api.py4
-rw-r--r--nova/db/sqlalchemy/api.py35
-rw-r--r--nova/flags.py7
-rw-r--r--nova/network/api.py2
-rw-r--r--nova/network/manager.py5
-rw-r--r--nova/network/quantumv2/api.py4
-rw-r--r--nova/network/rpcapi.py22
-rw-r--r--nova/test.py3
-rw-r--r--nova/tests/compute/test_compute.py72
-rw-r--r--nova/tests/compute/test_rpcapi.py13
-rw-r--r--nova/tests/network/test_api.py64
-rw-r--r--nova/tests/network/test_rpcapi.py50
-rw-r--r--nova/tests/test_flags.py7
-rw-r--r--nova/tests/test_utils.py3
-rw-r--r--nova/tests/test_virt_drivers.py3
-rw-r--r--nova/tests/test_xenapi.py43
-rw-r--r--nova/utils.py12
-rw-r--r--nova/virt/driver.py10
-rw-r--r--nova/virt/fake.py2
-rw-r--r--nova/virt/libvirt/driver.py2
-rw-r--r--nova/virt/xenapi/driver.py4
-rw-r--r--nova/virt/xenapi/pool.py2
-rw-r--r--nova/virt/xenapi/vmops.py5
-rw-r--r--tools/xenserver/destroy_cached_images.py3
49 files changed, 383 insertions, 178 deletions
diff --git a/bin/nova-all b/bin/nova-all
index 2bbc27c82..ce0a459b4 100755
--- a/bin/nova-all
+++ b/bin/nova-all
@@ -40,6 +40,7 @@ if os.path.exists(os.path.join(possible_topdir, "nova", "__init__.py")):
sys.path.insert(0, possible_topdir)
+from nova import config
from nova import flags
from nova.objectstore import s3server
from nova.openstack.common import log as logging
@@ -51,7 +52,7 @@ from nova.vnc import xvp_proxy
LOG = logging.getLogger('nova.all')
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
logging.setup("nova")
utils.monkey_patch()
launcher = service.ProcessLauncher()
diff --git a/bin/nova-api b/bin/nova-api
index f55eca719..4bcfa7f79 100755
--- a/bin/nova-api
+++ b/bin/nova-api
@@ -36,13 +36,14 @@ if os.path.exists(os.path.join(possible_topdir, "nova", "__init__.py")):
sys.path.insert(0, possible_topdir)
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova import service
from nova import utils
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
logging.setup("nova")
utils.monkey_patch()
launcher = service.ProcessLauncher()
diff --git a/bin/nova-api-ec2 b/bin/nova-api-ec2
index 8e66ab874..f165b5ce9 100755
--- a/bin/nova-api-ec2
+++ b/bin/nova-api-ec2
@@ -32,13 +32,14 @@ if os.path.exists(os.path.join(possible_topdir, "nova", "__init__.py")):
sys.path.insert(0, possible_topdir)
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova import service
from nova import utils
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
logging.setup("nova")
utils.monkey_patch()
server = service.WSGIService('ec2')
diff --git a/bin/nova-api-metadata b/bin/nova-api-metadata
index d445a16a9..f50e5ce84 100755
--- a/bin/nova-api-metadata
+++ b/bin/nova-api-metadata
@@ -32,13 +32,14 @@ if os.path.exists(os.path.join(possible_topdir, "nova", "__init__.py")):
sys.path.insert(0, possible_topdir)
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova import service
from nova import utils
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
logging.setup("nova")
utils.monkey_patch()
server = service.WSGIService('metadata')
diff --git a/bin/nova-api-os-compute b/bin/nova-api-os-compute
index 529d58821..5cf5f6910 100755
--- a/bin/nova-api-os-compute
+++ b/bin/nova-api-os-compute
@@ -32,13 +32,14 @@ if os.path.exists(os.path.join(possible_topdir, "nova", "__init__.py")):
sys.path.insert(0, possible_topdir)
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova import service
from nova import utils
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
logging.setup("nova")
utils.monkey_patch()
server = service.WSGIService('osapi_compute')
diff --git a/bin/nova-cert b/bin/nova-cert
index ebdd0e0b9..317739329 100755
--- a/bin/nova-cert
+++ b/bin/nova-cert
@@ -32,13 +32,14 @@ if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova import service
from nova import utils
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
FLAGS = flags.FLAGS
logging.setup("nova")
utils.monkey_patch()
diff --git a/bin/nova-clear-rabbit-queues b/bin/nova-clear-rabbit-queues
index 0cbf5ab19..05531de9b 100755
--- a/bin/nova-clear-rabbit-queues
+++ b/bin/nova-clear-rabbit-queues
@@ -42,6 +42,7 @@ gettext.install('nova', unicode=1)
from nova import context
from nova import exception
+from nova import config
from nova import flags
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
@@ -69,7 +70,7 @@ def delete_queues(queues):
x.queue_delete(q)
if __name__ == '__main__':
- args = flags.parse_args(sys.argv)
+ args = config.parse_args(sys.argv)
logging.setup("nova")
delete_queues(args[1:])
if FLAGS.delete_exchange:
diff --git a/bin/nova-compute b/bin/nova-compute
index 2a2a0013a..2ff98ccfc 100755
--- a/bin/nova-compute
+++ b/bin/nova-compute
@@ -34,13 +34,14 @@ if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova import service
from nova import utils
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
FLAGS = flags.FLAGS
logging.setup('nova')
utils.monkey_patch()
diff --git a/bin/nova-console b/bin/nova-console
index f664040b7..92b99edfb 100755
--- a/bin/nova-console
+++ b/bin/nova-console
@@ -33,12 +33,13 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova import service
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
FLAGS = flags.FLAGS
logging.setup("nova")
server = service.Service.create(binary='nova-console',
diff --git a/bin/nova-consoleauth b/bin/nova-consoleauth
index 58ecd37b3..14ef701a7 100755
--- a/bin/nova-consoleauth
+++ b/bin/nova-consoleauth
@@ -32,13 +32,14 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
from nova.consoleauth import manager
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova import service
if __name__ == "__main__":
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
FLAGS = flags.FLAGS
logging.setup("nova")
server = service.Service.create(binary='nova-consoleauth',
diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge
index 0fc7751fc..48639ce87 100755
--- a/bin/nova-dhcpbridge
+++ b/bin/nova-dhcpbridge
@@ -37,6 +37,7 @@ gettext.install('nova', unicode=1)
from nova import context
from nova import db
+from nova import config
from nova import flags
from nova.network import linux_net
from nova.network import rpcapi as network_rpcapi
@@ -94,7 +95,7 @@ def init_leases(network_id):
def main():
"""Parse environment and arguments and call the approproate action."""
flagfile = os.environ.get('FLAGFILE', FLAGS.dhcpbridge_flagfile)
- argv = flags.parse_args(sys.argv, default_config_files=[flagfile])
+ argv = config.parse_args(sys.argv, default_config_files=[flagfile])
logging.setup("nova")
if int(os.environ.get('TESTING', '0')):
diff --git a/bin/nova-manage b/bin/nova-manage
index 93b079488..1cb2dabb7 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -73,6 +73,7 @@ gettext.install('nova', unicode=1)
from nova.api.ec2 import ec2utils
from nova.compute import instance_types
from nova.compute import rpcapi as compute_rpcapi
+from nova import config
from nova import context
from nova import db
from nova.db import migration
@@ -1220,7 +1221,7 @@ def main():
"""Parse options and call the appropriate class/method."""
try:
- argv = flags.parse_args(sys.argv)
+ argv = config.parse_args(sys.argv)
logging.setup("nova")
except cfg.ConfigFilesNotFoundError:
cfgfile = FLAGS.config_file[-1] if FLAGS.config_file else None
diff --git a/bin/nova-network b/bin/nova-network
index 36343bb73..d23d7882c 100755
--- a/bin/nova-network
+++ b/bin/nova-network
@@ -34,13 +34,14 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova import service
from nova import utils
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
FLAGS = flags.FLAGS
logging.setup("nova")
utils.monkey_patch()
diff --git a/bin/nova-novncproxy b/bin/nova-novncproxy
index 483c72e81..d3d9702af 100755
--- a/bin/nova-novncproxy
+++ b/bin/nova-novncproxy
@@ -28,6 +28,7 @@ import sys
import websockify
+from nova import config
from nova.consoleauth import rpcapi as consoleauth_rpcapi
from nova import context
from nova import flags
@@ -133,7 +134,7 @@ if __name__ == '__main__':
parser.error("SSL only and %s not found" % FLAGS.cert)
# Setup flags
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
# Check to see if novnc html/js/css files are present
if not os.path.exists(FLAGS.web):
diff --git a/bin/nova-objectstore b/bin/nova-objectstore
index 2149b1610..9b9e2b7a7 100755
--- a/bin/nova-objectstore
+++ b/bin/nova-objectstore
@@ -34,6 +34,7 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+from nova import config
from nova import flags
from nova.objectstore import s3server
from nova.openstack.common import log as logging
@@ -42,7 +43,7 @@ from nova import utils
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
logging.setup("nova")
utils.monkey_patch()
server = s3server.get_wsgi_server()
diff --git a/bin/nova-rpc-zmq-receiver b/bin/nova-rpc-zmq-receiver
index 5636718a2..d63ea108e 100755
--- a/bin/nova-rpc-zmq-receiver
+++ b/bin/nova-rpc-zmq-receiver
@@ -32,6 +32,7 @@ POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
+from nova import config
from nova import exception
from nova import flags
from nova.openstack.common import log as logging
@@ -45,7 +46,7 @@ FLAGS.register_opts(impl_zmq.zmq_opts)
def main():
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
logging.setup("nova")
utils.monkey_patch()
diff --git a/bin/nova-scheduler b/bin/nova-scheduler
index 64dadb9e4..fc345808a 100755
--- a/bin/nova-scheduler
+++ b/bin/nova-scheduler
@@ -36,13 +36,14 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
gettext.install('nova', unicode=1)
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova import service
from nova import utils
if __name__ == '__main__':
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
FLAGS = flags.FLAGS
logging.setup("nova")
utils.monkey_patch()
diff --git a/bin/nova-xvpvncproxy b/bin/nova-xvpvncproxy
index 5929a33b5..e884b3f52 100755
--- a/bin/nova-xvpvncproxy
+++ b/bin/nova-xvpvncproxy
@@ -31,6 +31,7 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
+from nova import config
from nova import flags
from nova.openstack.common import log as logging
from nova.openstack.common import rpc
@@ -40,7 +41,7 @@ from nova.vnc import xvp_proxy
FLAGS = flags.FLAGS
if __name__ == "__main__":
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
logging.setup("nova")
wsgi_server = xvp_proxy.get_wsgi_server()
diff --git a/nova/api/ec2/ec2utils.py b/nova/api/ec2/ec2utils.py
index 4d0a926df..580cfdac7 100644
--- a/nova/api/ec2/ec2utils.py
+++ b/nova/api/ec2/ec2utils.py
@@ -25,7 +25,7 @@ from nova import flags
from nova.network import model as network_model
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
-from nova import utils
+from nova.openstack.common import uuidutils
FLAGS = flags.FLAGS
@@ -130,7 +130,7 @@ def id_to_ec2_id(instance_id, template='i-%08x'):
def id_to_ec2_inst_id(instance_id):
"""Get or create an ec2 instance ID (i-[base 16 number]) from uuid."""
- if utils.is_uuid_like(instance_id):
+ if uuidutils.is_uuid_like(instance_id):
ctxt = context.get_admin_context()
int_id = get_int_id_from_instance_uuid(ctxt, instance_id)
return id_to_ec2_id(int_id)
@@ -150,7 +150,7 @@ def get_instance_uuid_from_int_id(context, int_id):
def id_to_ec2_snap_id(snapshot_id):
"""Get or create an ec2 volume ID (vol-[base 16 number]) from uuid."""
- if utils.is_uuid_like(snapshot_id):
+ if uuidutils.is_uuid_like(snapshot_id):
ctxt = context.get_admin_context()
int_id = get_int_id_from_snapshot_uuid(ctxt, snapshot_id)
return id_to_ec2_id(int_id, 'snap-%08x')
@@ -160,7 +160,7 @@ def id_to_ec2_snap_id(snapshot_id):
def id_to_ec2_vol_id(volume_id):
"""Get or create an ec2 volume ID (vol-[base 16 number]) from uuid."""
- if utils.is_uuid_like(volume_id):
+ if uuidutils.is_uuid_like(volume_id):
ctxt = context.get_admin_context()
int_id = get_int_id_from_volume_uuid(ctxt, volume_id)
return id_to_ec2_id(int_id, 'vol-%08x')
diff --git a/nova/api/openstack/compute/contrib/floating_ips.py b/nova/api/openstack/compute/contrib/floating_ips.py
index 56a6a8fad..4f6dbffdb 100644
--- a/nova/api/openstack/compute/contrib/floating_ips.py
+++ b/nova/api/openstack/compute/contrib/floating_ips.py
@@ -27,7 +27,7 @@ from nova.compute import utils as compute_utils
from nova import exception
from nova import network
from nova.openstack.common import log as logging
-from nova import utils
+from nova.openstack.common import uuidutils
LOG = logging.getLogger(__name__)
@@ -307,7 +307,7 @@ class FloatingIPActionController(wsgi.Controller):
# disassociate if associated
if (instance and
floating_ip.get('fixed_ip_id') and
- (utils.is_uuid_like(id) and
+ (uuidutils.is_uuid_like(id) and
[instance['uuid'] == id] or
[instance['id'] == id])[0]):
disassociate_floating_ip(self, context, instance, address)
diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py
index ba88d72e7..c4293255d 100644
--- a/nova/api/openstack/compute/servers.py
+++ b/nova/api/openstack/compute/servers.py
@@ -36,6 +36,7 @@ from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.openstack.common.rpc import common as rpc_common
from nova.openstack.common import timeutils
+from nova.openstack.common import uuidutils
from nova import utils
@@ -621,7 +622,7 @@ class Controller(wsgi.Controller):
# port parameter is only for qunatum v2.0
msg = _("Unknown argment : port")
raise exc.HTTPBadRequest(explanation=msg)
- if not utils.is_uuid_like(port_id):
+ if not uuidutils.is_uuid_like(port_id):
msg = _("Bad port format: port uuid is "
"not in proper format "
"(%s)") % port_id
@@ -629,9 +630,9 @@ class Controller(wsgi.Controller):
else:
network_uuid = network['uuid']
- if not port_id and not utils.is_uuid_like(network_uuid):
+ if not port_id and not uuidutils.is_uuid_like(network_uuid):
br_uuid = network_uuid.split('-', 1)[-1]
- if not utils.is_uuid_like(br_uuid):
+ if not uuidutils.is_uuid_like(br_uuid):
msg = _("Bad networks format: network uuid is "
"not in proper format "
"(%s)") % network_uuid
@@ -1099,7 +1100,7 @@ class Controller(wsgi.Controller):
# down to an id and use the default glance connection params
image_uuid = image_href.split('/').pop()
- if not utils.is_uuid_like(image_uuid):
+ if not uuidutils.is_uuid_like(image_uuid):
msg = _("Invalid imageRef provided.")
raise exc.HTTPBadRequest(explanation=msg)
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 1bbcdbda9..28c7068ba 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -48,6 +48,7 @@ from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
+from nova.openstack.common import uuidutils
import nova.policy
from nova import quota
from nova.scheduler import rpcapi as scheduler_rpcapi
@@ -1067,7 +1068,7 @@ class API(base.Base):
def get(self, context, instance_id):
"""Get a single instance with the given instance_id."""
# NOTE(ameade): we still need to support integer ids for ec2
- if utils.is_uuid_like(instance_id):
+ if uuidutils.is_uuid_like(instance_id):
instance = self.db.instance_get_by_uuid(context, instance_id)
else:
instance = self.db.instance_get(context, instance_id)
@@ -1557,7 +1558,7 @@ class API(base.Base):
expected_task_state=None)
self.compute_rpcapi.revert_resize(context,
- instance=instance, migration_id=migration_ref['id'],
+ instance=instance, migration=migration_ref,
host=migration_ref['dest_compute'], reservations=reservations)
self.db.migration_update(elevated, migration_ref['id'],
@@ -2173,7 +2174,7 @@ class AggregateAPI(base.Base):
self.db.aggregate_host_add(context, aggregate_id, host)
#NOTE(jogo): Send message to host to support resource pools
self.compute_rpcapi.add_aggregate_host(context,
- aggregate_id=aggregate_id, host_param=host, host=host)
+ aggregate=aggregate, host_param=host, host=host)
return self.get_aggregate(context, aggregate_id)
def remove_host_from_aggregate(self, context, aggregate_id, host):
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 39c3faddf..de848abdd 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -230,7 +230,7 @@ class ComputeVirtAPI(virtapi.VirtAPI):
class ComputeManager(manager.SchedulerDependentManager):
"""Manages the running instances from creation to destruction."""
- RPC_API_VERSION = '2.11'
+ RPC_API_VERSION = '2.14'
def __init__(self, compute_driver=None, *args, **kwargs):
"""Load configuration options and connect to the hypervisor."""
@@ -1532,16 +1532,17 @@ class ComputeManager(manager.SchedulerDependentManager):
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@reverts_task_state
@wrap_instance_fault
- def revert_resize(self, context, instance, migration_id,
- reservations=None):
+ def revert_resize(self, context, instance, migration=None,
+ migration_id=None, reservations=None):
"""Destroys the new instance on the destination machine.
Reverts the model changes, and powers on the old instance on the
source machine.
"""
- migration_ref = self.db.migration_get(context.elevated(),
- migration_id)
+ if not migration:
+ migration = self.db.migration_get(context.elevated(),
+ migration_id)
# NOTE(comstud): A revert_resize is essentially a resize back to
# the old size, so we need to send a usage event here.
@@ -1555,7 +1556,7 @@ class ComputeManager(manager.SchedulerDependentManager):
teardown=True)
self.network_api.migrate_instance_start(context, instance,
- migration_ref)
+ migration)
network_info = self._get_instance_nw_info(context, instance)
block_device_info = self._get_instance_volume_block_device_info(
@@ -1567,14 +1568,14 @@ class ComputeManager(manager.SchedulerDependentManager):
self._terminate_volume_connections(context, instance)
self.compute_rpcapi.finish_revert_resize(context, instance,
- migration_ref['id'], migration_ref['source_compute'],
+ migration, migration['source_compute'],
reservations)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
@reverts_task_state
@wrap_instance_fault
- def finish_revert_resize(self, context, migration_id, instance,
- reservations=None):
+ def finish_revert_resize(self, context, instance, reservations=None,
+ migration=None, migration_id=None):
"""Finishes the second half of reverting a resize.
Power back on the source instance and revert the resized attributes
@@ -1582,7 +1583,9 @@ class ComputeManager(manager.SchedulerDependentManager):
"""
elevated = context.elevated()
- migration_ref = self.db.migration_get(elevated, migration_id)
+
+ if not migration:
+ migration = self.db.migration_get(elevated, migration_id)
with self._error_out_instance_on_exception(context, instance['uuid'],
reservations):
@@ -1593,11 +1596,11 @@ class ComputeManager(manager.SchedulerDependentManager):
instance = self._instance_update(context,
instance['uuid'],
- host=migration_ref['source_compute'])
+ host=migration['source_compute'])
self.network_api.setup_networks_on_host(context, instance,
- migration_ref['source_compute'])
+ migration['source_compute'])
- old_instance_type = migration_ref['old_instance_type_id']
+ old_instance_type = migration['old_instance_type_id']
instance_type = instance_types.get_instance_type(old_instance_type)
bdms = self._get_instance_volume_bdms(context, instance['uuid'])
@@ -1628,13 +1631,13 @@ class ComputeManager(manager.SchedulerDependentManager):
RESIZE_REVERTING)
self.network_api.migrate_instance_finish(context, instance,
- migration_ref)
+ migration)
self._instance_update(context, instance['uuid'],
vm_state=vm_states.ACTIVE,
task_state=None)
- self.db.migration_update(elevated, migration_id,
+ self.db.migration_update(elevated, migration['id'],
{'status': 'reverted'})
self._notify_about_instance_usage(
@@ -2667,7 +2670,10 @@ class ComputeManager(manager.SchedulerDependentManager):
@manager.periodic_task
def _poll_rebooting_instances(self, context):
if FLAGS.reboot_timeout > 0:
- self.driver.poll_rebooting_instances(FLAGS.reboot_timeout)
+ instances = self.db.instance_get_all_hung_in_rebooting(
+ context, FLAGS.reboot_timeout)
+ self.driver.poll_rebooting_instances(FLAGS.reboot_timeout,
+ instances)
@manager.periodic_task
def _poll_rescued_instances(self, context):
@@ -3108,9 +3114,12 @@ class ComputeManager(manager.SchedulerDependentManager):
self._set_instance_error_state(context, instance_uuid)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
- def add_aggregate_host(self, context, aggregate_id, host, slave_info=None):
+ def add_aggregate_host(self, context, host, slave_info=None,
+ aggregate=None, aggregate_id=None):
"""Notify hypervisor of change (for hypervisor pools)."""
- aggregate = self.db.aggregate_get(context, aggregate_id)
+ if not aggregate:
+ aggregate = self.db.aggregate_get(context, aggregate_id)
+
try:
self.driver.add_to_aggregate(context, aggregate, host,
slave_info=slave_info)
@@ -3118,7 +3127,7 @@ class ComputeManager(manager.SchedulerDependentManager):
with excutils.save_and_reraise_exception():
self.driver.undo_aggregate_operation(context,
self.db.aggregate_host_delete,
- aggregate.id, host)
+ aggregate['id'], host)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
def remove_aggregate_host(self, context, aggregate_id,
diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py
index e42e025dc..5bf17adcd 100644
--- a/nova/compute/rpcapi.py
+++ b/nova/compute/rpcapi.py
@@ -139,6 +139,9 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
2.9 - Add publish_service_capabilities()
2.10 - Adds filter_properties and request_spec to prep_resize()
2.11 - Adds soft_delete_instance() and restore_instance()
+ 2.12 - Remove migration_id, add migration to revert_resize
+ 2.13 - Remove migration_id, add migration to finish_revert_resize
+ 2.14 - Remove aggregate_id, add aggregate to add_aggregate_host
'''
#
@@ -156,7 +159,7 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
topic=FLAGS.compute_topic,
default_version=self.BASE_RPC_API_VERSION)
- def add_aggregate_host(self, ctxt, aggregate_id, host_param, host,
+ def add_aggregate_host(self, ctxt, aggregate, host_param, host,
slave_info=None):
'''Add aggregate host.
@@ -167,11 +170,12 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
:param host: This is the host to send the message to.
'''
+ aggregate_p = jsonutils.to_primitive(aggregate)
self.cast(ctxt, self.make_msg('add_aggregate_host',
- aggregate_id=aggregate_id, host=host_param,
+ aggregate=aggregate_p, host=host_param,
slave_info=slave_info),
topic=_compute_topic(self.topic, ctxt, host, None),
- version='2.2')
+ version='2.14')
def add_fixed_ip_to_instance(self, ctxt, instance, network_id):
instance_p = jsonutils.to_primitive(instance)
@@ -237,13 +241,15 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
topic=_compute_topic(self.topic, ctxt, host, None),
version='2.8')
- def finish_revert_resize(self, ctxt, instance, migration_id, host,
+ def finish_revert_resize(self, ctxt, instance, migration, host,
reservations=None):
instance_p = jsonutils.to_primitive(instance)
+ migration_p = jsonutils.to_primitive(migration)
self.cast(ctxt, self.make_msg('finish_revert_resize',
- instance=instance_p, migration_id=migration_id,
+ instance=instance_p, migration=migration_p,
reservations=reservations),
- topic=_compute_topic(self.topic, ctxt, host, None))
+ topic=_compute_topic(self.topic, ctxt, host, None),
+ version='2.13')
def get_console_output(self, ctxt, instance, tail_length):
instance_p = jsonutils.to_primitive(instance)
@@ -441,13 +447,15 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy):
instance=instance_p),
topic=_compute_topic(self.topic, ctxt, None, instance))
- def revert_resize(self, ctxt, instance, migration_id, host,
+ def revert_resize(self, ctxt, instance, migration, host,
reservations=None):
instance_p = jsonutils.to_primitive(instance)
+ migration_p = jsonutils.to_primitive(migration)
self.cast(ctxt, self.make_msg('revert_resize',
- instance=instance_p, migration_id=migration_id,
+ instance=instance_p, migration=migration_p,
reservations=reservations),
- topic=_compute_topic(self.topic, ctxt, host, instance))
+ topic=_compute_topic(self.topic, ctxt, host, instance),
+ version='2.12')
def rollback_live_migration_at_destination(self, ctxt, instance, host):
instance_p = jsonutils.to_primitive(instance)
diff --git a/nova/config.py b/nova/config.py
new file mode 100644
index 000000000..608a3ee53
--- /dev/null
+++ b/nova/config.py
@@ -0,0 +1,29 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# All Rights Reserved.
+# Copyright 2012 Red Hat, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from nova.openstack.common import cfg
+
+CONF = cfg.CONF
+
+
+def parse_args(argv, default_config_files=None):
+ CONF.disable_interspersed_args()
+ return argv[:1] + CONF(argv[1:],
+ project='nova',
+ default_config_files=default_config_files)
diff --git a/nova/console/api.py b/nova/console/api.py
index 8becf35cf..5a9294ce7 100644
--- a/nova/console/api.py
+++ b/nova/console/api.py
@@ -22,7 +22,7 @@ from nova.console import rpcapi as console_rpcapi
from nova.db import base
from nova import flags
from nova.openstack.common import rpc
-from nova import utils
+from nova.openstack.common import uuidutils
FLAGS = flags.FLAGS
@@ -63,7 +63,7 @@ class API(base.Base):
return rpcapi.get_console_topic(context, instance_host)
def _get_instance(self, context, instance_uuid):
- if utils.is_uuid_like(instance_uuid):
+ if uuidutils.is_uuid_like(instance_uuid):
instance = self.db.instance_get_by_uuid(context, instance_uuid)
else:
instance = self.db.instance_get(context, instance_uuid)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index a00895c57..ea7e665cf 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -25,6 +25,16 @@ import datetime
import functools
import warnings
+from sqlalchemy import and_
+from sqlalchemy.exc import IntegrityError
+from sqlalchemy import or_
+from sqlalchemy.orm import joinedload
+from sqlalchemy.orm import joinedload_all
+from sqlalchemy.sql.expression import asc
+from sqlalchemy.sql.expression import desc
+from sqlalchemy.sql.expression import literal_column
+from sqlalchemy.sql import func
+
from nova import block_device
from nova.common.sqlalchemyutils import paginate_query
from nova.compute import vm_states
@@ -35,16 +45,9 @@ from nova import exception
from nova import flags
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
+from nova.openstack.common import uuidutils
from nova import utils
-from sqlalchemy import and_
-from sqlalchemy.exc import IntegrityError
-from sqlalchemy import or_
-from sqlalchemy.orm import joinedload
-from sqlalchemy.orm import joinedload_all
-from sqlalchemy.sql.expression import asc
-from sqlalchemy.sql.expression import desc
-from sqlalchemy.sql.expression import literal_column
-from sqlalchemy.sql import func
+
FLAGS = flags.FLAGS
@@ -1035,7 +1038,7 @@ def fixed_ip_associate(context, address, instance_uuid, network_id=None,
reserved -- should be a boolean value(True or False), exact value will be
used to filter on the fixed ip address
"""
- if not utils.is_uuid_like(instance_uuid):
+ if not uuidutils.is_uuid_like(instance_uuid):
raise exception.InvalidUUID(uuid=instance_uuid)
session = get_session()
@@ -1067,7 +1070,7 @@ def fixed_ip_associate(context, address, instance_uuid, network_id=None,
@require_admin_context
def fixed_ip_associate_pool(context, network_id, instance_uuid=None,
host=None):
- if instance_uuid and not utils.is_uuid_like(instance_uuid):
+ if instance_uuid and not uuidutils.is_uuid_like(instance_uuid):
raise exception.InvalidUUID(uuid=instance_uuid)
session = get_session()
@@ -1211,7 +1214,7 @@ def fixed_ip_get_by_address(context, address, session=None):
@require_context
def fixed_ip_get_by_instance(context, instance_uuid):
- if not utils.is_uuid_like(instance_uuid):
+ if not uuidutils.is_uuid_like(instance_uuid):
raise exception.InvalidUUID(uuid=instance_uuid)
result = model_query(context, models.FixedIp, read_deleted="no").\
@@ -1463,7 +1466,7 @@ def instance_data_get_for_project(context, project_id, session=None):
def instance_destroy(context, instance_uuid, constraint=None):
session = get_session()
with session.begin():
- if utils.is_uuid_like(instance_uuid):
+ if uuidutils.is_uuid_like(instance_uuid):
instance_ref = instance_get_by_uuid(context, instance_uuid,
session=session)
else:
@@ -1783,7 +1786,7 @@ def instance_test_and_set(context, instance_uuid, attr, ok_states,
query = model_query(context, models.Instance, session=session,
project_only=True)
- if utils.is_uuid_like(instance_uuid):
+ if uuidutils.is_uuid_like(instance_uuid):
query = query.filter_by(uuid=instance_uuid)
else:
raise exception.InvalidUUID(instance_uuid)
@@ -1835,7 +1838,7 @@ def instance_update_and_get_original(context, instance_uuid, values):
def _instance_update(context, instance_uuid, values, copy_old_instance=False):
session = get_session()
- if not utils.is_uuid_like(instance_uuid):
+ if not uuidutils.is_uuid_like(instance_uuid):
raise exception.InvalidUUID(instance_uuid)
with session.begin():
@@ -2926,7 +2929,7 @@ def volume_allocate_iscsi_target(context, volume_id, host):
@require_admin_context
def volume_attached(context, volume_id, instance_uuid, mountpoint):
- if not utils.is_uuid_like(instance_uuid):
+ if not uuidutils.is_uuid_like(instance_uuid):
raise exception.InvalidUUID(instance_uuid)
session = get_session()
diff --git a/nova/flags.py b/nova/flags.py
index 7d09915a5..a27674472 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -36,13 +36,6 @@ from nova.openstack.common import cfg
FLAGS = cfg.CONF
-def parse_args(argv, default_config_files=None):
- FLAGS.disable_interspersed_args()
- return argv[:1] + FLAGS(argv[1:],
- project='nova',
- default_config_files=default_config_files)
-
-
class UnrecognizedFlag(Exception):
pass
diff --git a/nova/network/api.py b/nova/network/api.py
index bb05a0c2a..d2ce876b8 100644
--- a/nova/network/api.py
+++ b/nova/network/api.py
@@ -353,6 +353,7 @@ class API(base.Base):
if self._is_multi_host(context, instance):
args['floating_addresses'] = \
self._get_floating_ip_addresses(context, instance)
+ args['host'] = migration['dest_compute']
self.network_rpcapi.migrate_instance_start(context, **args)
@@ -370,5 +371,6 @@ class API(base.Base):
if self._is_multi_host(context, instance):
args['floating_addresses'] = \
self._get_floating_ip_addresses(context, instance)
+ args['host'] = migration['dest_compute']
self.network_rpcapi.migrate_instance_finish(context, **args)
diff --git a/nova/network/manager.py b/nova/network/manager.py
index afe79a664..cfd1a320f 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -69,6 +69,7 @@ from nova.openstack.common import lockutils
from nova.openstack.common import log as logging
from nova.openstack.common.notifier import api as notifier
from nova.openstack.common import timeutils
+from nova.openstack.common import uuidutils
import nova.policy
from nova import quota
from nova import utils
@@ -943,7 +944,7 @@ class NetworkManager(manager.SchedulerDependentManager):
# NOTE(francois.charlier): the instance may have been deleted already
# thus enabling `read_deleted`
admin_context = context.get_admin_context(read_deleted='yes')
- if utils.is_uuid_like(instance_id):
+ if uuidutils.is_uuid_like(instance_id):
instance_ref = self.db.instance_get_by_uuid(admin_context,
instance_id)
else:
@@ -1277,7 +1278,7 @@ class NetworkManager(manager.SchedulerDependentManager):
@wrap_check_policy
def add_fixed_ip_to_instance(self, context, instance_id, host, network_id):
"""Adds a fixed ip to an instance from specified network."""
- if utils.is_uuid_like(network_id):
+ if uuidutils.is_uuid_like(network_id):
network = self.get_network(context, network_id)
else:
network = self._get_network_by_id(context, network_id)
diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py
index e8d672835..2cc607684 100644
--- a/nova/network/quantumv2/api.py
+++ b/nova/network/quantumv2/api.py
@@ -26,7 +26,7 @@ from nova.network import quantumv2
from nova.openstack.common import cfg
from nova.openstack.common import excutils
from nova.openstack.common import log as logging
-from nova import utils
+from nova.openstack.common import uuidutils
quantum_opts = [
@@ -437,7 +437,7 @@ class API(base.Base):
def _get_floating_ip_pool_id_by_name_or_id(self, client, name_or_id):
search_opts = {NET_EXTERNAL: True, 'fields': 'id'}
- if utils.is_uuid_like(name_or_id):
+ if uuidutils.is_uuid_like(name_or_id):
search_opts.update({'id': name_or_id})
else:
search_opts.update({'name': name_or_id})
diff --git a/nova/network/rpcapi.py b/nova/network/rpcapi.py
index 6f31e140b..8dd5e3a69 100644
--- a/nova/network/rpcapi.py
+++ b/nova/network/rpcapi.py
@@ -267,7 +267,11 @@ class NetworkAPI(rpc_proxy.RpcProxy):
def migrate_instance_start(self, ctxt, instance_uuid, rxtx_factor,
project_id, source_compute, dest_compute,
- floating_addresses):
+ floating_addresses, host=None):
+ if host is not None:
+ topic = rpc.queue_get_for(ctxt, self.topic, host)
+ else:
+ topic = self.topic
return self.call(ctxt, self.make_msg(
'migrate_instance_start',
instance_uuid=instance_uuid,
@@ -276,13 +280,16 @@ class NetworkAPI(rpc_proxy.RpcProxy):
source=source_compute,
dest=dest_compute,
floating_addresses=floating_addresses),
- topic=rpc.queue_get_for(ctxt, self.topic,
- dest_compute),
- version='1.2')
+ topic=topic,
+ version='1.2')
def migrate_instance_finish(self, ctxt, instance_uuid, rxtx_factor,
project_id, source_compute, dest_compute,
- floating_addresses):
+ floating_addresses, host=None):
+ if host is not None:
+ topic = rpc.queue_get_for(ctxt, self.topic, host)
+ else:
+ topic = self.topic
return self.call(ctxt, self.make_msg(
'migrate_instance_finish',
instance_uuid=instance_uuid,
@@ -291,6 +298,5 @@ class NetworkAPI(rpc_proxy.RpcProxy):
source=source_compute,
dest=dest_compute,
floating_addresses=floating_addresses),
- topic=rpc.queue_get_for(ctxt, self.topic,
- dest_compute),
- version='1.2')
+ topic=topic,
+ version='1.2')
diff --git a/nova/test.py b/nova/test.py
index 911ad1390..cd82d74e2 100644
--- a/nova/test.py
+++ b/nova/test.py
@@ -32,6 +32,7 @@ import nose.plugins.skip
import stubout
import testtools
+from nova import config
from nova import flags
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
@@ -68,7 +69,7 @@ class TestCase(testtools.TestCase):
super(TestCase, self).setUp()
fake_flags.set_defaults(FLAGS)
- flags.parse_args([], default_config_files=[])
+ config.parse_args([], default_config_files=[])
# NOTE(vish): We need a better method for creating fixtures for tests
# now that we have some required db setup for the system
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index a7cb2f856..d8bc34883 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -207,6 +207,8 @@ class ComputeTestCase(BaseTestCase):
self.stubs.Set(network_api.API, 'allocate_for_instance',
fake_get_nw_info)
self.compute_api = compute.API()
+ # Just to make long lines short
+ self.rt = self.compute.resource_tracker
def tearDown(self):
super(ComputeTestCase, self).tearDown()
@@ -305,20 +307,17 @@ class ComputeTestCase(BaseTestCase):
def test_create_instance_unlimited_memory(self):
"""Default of memory limit=None is unlimited"""
self.flags(reserved_host_disk_mb=0, reserved_host_memory_mb=0)
- self.compute.resource_tracker.update_available_resource(
- self.context.elevated())
+ self.rt.update_available_resource(self.context.elevated())
params = {"memory_mb": 999999999999}
filter_properties = {'limits': {'memory_mb': None}}
instance = self._create_fake_instance(params)
self.compute.run_instance(self.context, instance=instance,
filter_properties=filter_properties)
- self.assertEqual(999999999999,
- self.compute.resource_tracker.compute_node['memory_mb_used'])
+ self.assertEqual(999999999999, self.rt.compute_node['memory_mb_used'])
def test_create_instance_unlimited_disk(self):
self.flags(reserved_host_disk_mb=0, reserved_host_memory_mb=0)
- self.compute.resource_tracker.update_available_resource(
- self.context.elevated())
+ self.rt.update_available_resource(self.context.elevated())
params = {"root_gb": 999999999999,
"ephemeral_gb": 99999999999}
filter_properties = {'limits': {'disk_gb': None}}
@@ -328,26 +327,21 @@ class ComputeTestCase(BaseTestCase):
def test_create_multiple_instances_then_starve(self):
self.flags(reserved_host_disk_mb=0, reserved_host_memory_mb=0)
- self.compute.resource_tracker.update_available_resource(
- self.context.elevated())
+ self.rt.update_available_resource(self.context.elevated())
filter_properties = {'limits': {'memory_mb': 4096, 'disk_gb': 1000}}
params = {"memory_mb": 1024, "root_gb": 128, "ephemeral_gb": 128}
instance = self._create_fake_instance(params)
self.compute.run_instance(self.context, instance=instance,
filter_properties=filter_properties)
- self.assertEquals(1024,
- self.compute.resource_tracker.compute_node['memory_mb_used'])
- self.assertEquals(256,
- self.compute.resource_tracker.compute_node['local_gb_used'])
+ self.assertEquals(1024, self.rt.compute_node['memory_mb_used'])
+ self.assertEquals(256, self.rt.compute_node['local_gb_used'])
params = {"memory_mb": 2048, "root_gb": 256, "ephemeral_gb": 256}
instance = self._create_fake_instance(params)
self.compute.run_instance(self.context, instance=instance,
filter_properties=filter_properties)
- self.assertEquals(3072,
- self.compute.resource_tracker.compute_node['memory_mb_used'])
- self.assertEquals(768,
- self.compute.resource_tracker.compute_node['local_gb_used'])
+ self.assertEquals(3072, self.rt.compute_node['memory_mb_used'])
+ self.assertEquals(768, self.rt.compute_node['local_gb_used'])
params = {"memory_mb": 8192, "root_gb": 8192, "ephemeral_gb": 8192}
instance = self._create_fake_instance(params)
@@ -359,8 +353,7 @@ class ComputeTestCase(BaseTestCase):
"""Test passing of oversubscribed ram policy from the scheduler."""
self.flags(reserved_host_disk_mb=0, reserved_host_memory_mb=0)
- self.compute.resource_tracker.update_available_resource(
- self.context.elevated())
+ self.rt.update_available_resource(self.context.elevated())
# get total memory as reported by virt driver:
resources = self.compute.driver.get_available_resource()
@@ -380,16 +373,14 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, instance=instance,
filter_properties=filter_properties)
- self.assertEqual(instance_mb,
- self.compute.resource_tracker.compute_node['memory_mb_used'])
+ self.assertEqual(instance_mb, self.rt.compute_node['memory_mb_used'])
def test_create_instance_with_oversubscribed_ram_fail(self):
"""Test passing of oversubscribed ram policy from the scheduler, but
with insufficient memory.
"""
self.flags(reserved_host_disk_mb=0, reserved_host_memory_mb=0)
- self.compute.resource_tracker.update_available_resource(
- self.context.elevated())
+ self.rt.update_available_resource(self.context.elevated())
# get total memory as reported by virt driver:
resources = self.compute.driver.get_available_resource()
@@ -414,8 +405,7 @@ class ComputeTestCase(BaseTestCase):
"""Test passing of oversubscribed cpu policy from the scheduler."""
self.flags(reserved_host_disk_mb=0, reserved_host_memory_mb=0)
- self.compute.resource_tracker.update_available_resource(
- self.context.elevated())
+ self.rt.update_available_resource(self.context.elevated())
limits = {'vcpu': 3}
filter_properties = {'limits': limits}
@@ -431,8 +421,7 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, instance=instance,
filter_properties=filter_properties)
- self.assertEqual(2,
- self.compute.resource_tracker.compute_node['vcpus_used'])
+ self.assertEqual(2, self.rt.compute_node['vcpus_used'])
# create one more instance:
params = {"memory_mb": 10, "root_gb": 1,
@@ -441,16 +430,14 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, instance=instance,
filter_properties=filter_properties)
- self.assertEqual(3,
- self.compute.resource_tracker.compute_node['vcpus_used'])
+ self.assertEqual(3, self.rt.compute_node['vcpus_used'])
# delete the instance:
instance['vm_state'] = vm_states.DELETED
- self.compute.resource_tracker.update_usage(self.context,
+ self.rt.update_usage(self.context,
instance=instance)
- self.assertEqual(2,
- self.compute.resource_tracker.compute_node['vcpus_used'])
+ self.assertEqual(2, self.rt.compute_node['vcpus_used'])
# now oversubscribe vcpus and fail:
params = {"memory_mb": 10, "root_gb": 1,
@@ -467,8 +454,7 @@ class ComputeTestCase(BaseTestCase):
"""Test passing of oversubscribed disk policy from the scheduler."""
self.flags(reserved_host_disk_mb=0, reserved_host_memory_mb=0)
- self.compute.resource_tracker.update_available_resource(
- self.context.elevated())
+ self.rt.update_available_resource(self.context.elevated())
# get total memory as reported by virt driver:
resources = self.compute.driver.get_available_resource()
@@ -487,16 +473,14 @@ class ComputeTestCase(BaseTestCase):
self.compute.run_instance(self.context, instance=instance,
filter_properties=filter_properties)
- self.assertEqual(instance_gb,
- self.compute.resource_tracker.compute_node['local_gb_used'])
+ self.assertEqual(instance_gb, self.rt.compute_node['local_gb_used'])
def test_create_instance_with_oversubscribed_disk_fail(self):
"""Test passing of oversubscribed disk policy from the scheduler, but
with insufficient disk.
"""
self.flags(reserved_host_disk_mb=0, reserved_host_memory_mb=0)
- self.compute.resource_tracker.update_available_resource(
- self.context.elevated())
+ self.rt.update_available_resource(self.context.elevated())
# get total memory as reported by virt driver:
resources = self.compute.driver.get_available_resource()
@@ -2002,8 +1986,8 @@ class ComputeTestCase(BaseTestCase):
fake_setup_networks_on_host)
self.compute.finish_revert_resize(self.context,
- migration_id=migration_ref['id'], instance=rpcinst,
- reservations=reservations)
+ migration=jsonutils.to_primitive(migration_ref),
+ instance=rpcinst, reservations=reservations)
instance = db.instance_get_by_uuid(self.context, instance_uuid)
self.assertEqual(instance['vm_state'], vm_states.ACTIVE)
@@ -5085,7 +5069,8 @@ class ComputeAggrTestCase(BaseTestCase):
self.stubs.Set(self.compute.driver, "add_to_aggregate",
fake_driver_add_to_aggregate)
- self.compute.add_aggregate_host(self.context, self.aggr.id, "host")
+ self.compute.add_aggregate_host(self.context, "host",
+ aggregate=jsonutils.to_primitive(self.aggr))
self.assertTrue(fake_driver_add_to_aggregate.called)
def test_remove_aggregate_host(self):
@@ -5103,15 +5088,16 @@ class ComputeAggrTestCase(BaseTestCase):
def test_add_aggregate_host_passes_slave_info_to_driver(self):
def driver_add_to_aggregate(context, aggregate, host, **kwargs):
self.assertEquals(self.context, context)
- self.assertEquals(aggregate.id, self.aggr.id)
+ self.assertEquals(aggregate['id'], self.aggr.id)
self.assertEquals(host, "the_host")
self.assertEquals("SLAVE_INFO", kwargs.get("slave_info"))
self.stubs.Set(self.compute.driver, "add_to_aggregate",
driver_add_to_aggregate)
- self.compute.add_aggregate_host(self.context, self.aggr.id,
- "the_host", slave_info="SLAVE_INFO")
+ self.compute.add_aggregate_host(self.context, "the_host",
+ slave_info="SLAVE_INFO",
+ aggregate=jsonutils.to_primitive(self.aggr))
def test_remove_from_aggregate_passes_slave_info_to_driver(self):
def driver_remove_from_aggregate(context, aggregate, host, **kwargs):
diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py
index f94cca857..1edfa771f 100644
--- a/nova/tests/compute/test_rpcapi.py
+++ b/nova/tests/compute/test_rpcapi.py
@@ -95,8 +95,9 @@ class ComputeRpcAPITestCase(test.TestCase):
self.assertEqual(arg, expected_arg)
def test_add_aggregate_host(self):
- self._test_compute_api('add_aggregate_host', 'cast', aggregate_id='id',
- host_param='host', host='host', slave_info={}, version='2.2')
+ self._test_compute_api('add_aggregate_host', 'cast',
+ aggregate={'id': 'fake_id'}, host_param='host', host='host',
+ slave_info={}, version='2.14')
def test_add_fixed_ip_to_instance(self):
self._test_compute_api('add_fixed_ip_to_instance', 'cast',
@@ -143,8 +144,8 @@ class ComputeRpcAPITestCase(test.TestCase):
def test_finish_revert_resize(self):
self._test_compute_api('finish_revert_resize', 'cast',
- instance=self.fake_instance, migration_id='id', host='host',
- reservations=list('fake_res'))
+ instance=self.fake_instance, migration={'id': 'fake_id'},
+ host='host', reservations=list('fake_res'), version='2.13')
def test_get_console_output(self):
self._test_compute_api('get_console_output', 'call',
@@ -293,8 +294,8 @@ class ComputeRpcAPITestCase(test.TestCase):
def test_revert_resize(self):
self._test_compute_api('revert_resize', 'cast',
- instance=self.fake_instance, migration_id='id', host='host',
- reservations=list('fake_res'))
+ instance=self.fake_instance, migration={'id': 'fake_id'},
+ host='host', reservations=list('fake_res'), version='2.12')
def test_rollback_live_migration_at_destination(self):
self._test_compute_api('rollback_live_migration_at_destination',
diff --git a/nova/tests/network/test_api.py b/nova/tests/network/test_api.py
index 9bbd7ba92..04f646ef0 100644
--- a/nova/tests/network/test_api.py
+++ b/nova/tests/network/test_api.py
@@ -19,6 +19,7 @@
from nova import context
from nova import network
+from nova.network import rpcapi as network_rpcapi
from nova.openstack.common import rpc
from nova import test
@@ -78,3 +79,66 @@ class ApiTestCase(test.TestCase):
def test_associate_unassociated_floating_ip(self):
self._do_test_associate_floating_ip(None)
+
+ def _stub_migrate_instance_calls(self, method, multi_host, info):
+ fake_instance_type = {'rxtx_factor': 'fake_factor'}
+ fake_instance = {'uuid': 'fake_uuid',
+ 'instance_type': fake_instance_type,
+ 'project_id': 'fake_project_id'}
+ fake_migration = {'source_compute': 'fake_compute_source',
+ 'dest_compute': 'fake_compute_dest'}
+
+ def fake_mig_inst_method(*args, **kwargs):
+ info['kwargs'] = kwargs
+
+ def fake_is_multi_host(*args, **kwargs):
+ return multi_host
+
+ def fake_get_floaters(*args, **kwargs):
+ return ['fake_float1', 'fake_float2']
+
+ self.stubs.Set(network_rpcapi.NetworkAPI, method,
+ fake_mig_inst_method)
+ self.stubs.Set(self.network_api, '_is_multi_host',
+ fake_is_multi_host)
+ self.stubs.Set(self.network_api, '_get_floating_ip_addresses',
+ fake_get_floaters)
+
+ expected = {'instance_uuid': 'fake_uuid',
+ 'source_compute': 'fake_compute_source',
+ 'dest_compute': 'fake_compute_dest',
+ 'rxtx_factor': 'fake_factor',
+ 'project_id': 'fake_project_id',
+ 'floating_addresses': None}
+ if multi_host:
+ expected['host'] = 'fake_compute_dest'
+ expected['floating_addresses'] = ['fake_float1', 'fake_float2']
+ return fake_instance, fake_migration, expected
+
+ def test_migrate_instance_start_with_multhost(self):
+ info = {'kwargs': {}}
+ arg1, arg2, expected = self._stub_migrate_instance_calls(
+ 'migrate_instance_start', True, info)
+ self.network_api.migrate_instance_start(self.context, arg1, arg2)
+ self.assertEqual(info['kwargs'], expected)
+
+ def test_migrate_instance_start_without_multhost(self):
+ info = {'kwargs': {}}
+ arg1, arg2, expected = self._stub_migrate_instance_calls(
+ 'migrate_instance_start', False, info)
+ self.network_api.migrate_instance_start(self.context, arg1, arg2)
+ self.assertEqual(info['kwargs'], expected)
+
+ def test_migrate_instance_finish_with_multhost(self):
+ info = {'kwargs': {}}
+ arg1, arg2, expected = self._stub_migrate_instance_calls(
+ 'migrate_instance_finish', True, info)
+ self.network_api.migrate_instance_finish(self.context, arg1, arg2)
+ self.assertEqual(info['kwargs'], expected)
+
+ def test_migrate_instance_finish_without_multhost(self):
+ info = {'kwargs': {}}
+ arg1, arg2, expected = self._stub_migrate_instance_calls(
+ 'migrate_instance_finish', False, info)
+ self.network_api.migrate_instance_finish(self.context, arg1, arg2)
+ self.assertEqual(info['kwargs'], expected)
diff --git a/nova/tests/network/test_rpcapi.py b/nova/tests/network/test_rpcapi.py
index a087ba97f..de3f19cea 100644
--- a/nova/tests/network/test_rpcapi.py
+++ b/nova/tests/network/test_rpcapi.py
@@ -36,11 +36,17 @@ class NetworkRpcAPITestCase(test.TestCase):
expected_version = kwargs.pop('version', rpcapi.BASE_RPC_API_VERSION)
expected_topic = FLAGS.network_topic
expected_msg = rpcapi.make_msg(method, **kwargs)
+ if 'source_compute' in expected_msg['args']:
+ # Fix up for migrate_instance_* calls.
+ args = expected_msg['args']
+ args['source'] = args.pop('source_compute')
+ args['dest'] = args.pop('dest_compute')
targeted_methods = [
'lease_fixed_ip', 'release_fixed_ip', 'rpc_setup_network_on_host',
'_rpc_allocate_fixed_ip', 'deallocate_fixed_ip',
'_associate_floating_ip', '_disassociate_floating_ip',
- 'lease_fixed_ip', 'release_fixed_ip'
+ 'lease_fixed_ip', 'release_fixed_ip',
+ 'migrate_instance_start', 'migrate_instance_finish',
]
if method in targeted_methods and 'host' in kwargs:
if method != 'deallocate_fixed_ip':
@@ -258,3 +264,45 @@ class NetworkRpcAPITestCase(test.TestCase):
def test_release_fixed_ip(self):
self._test_network_api('release_fixed_ip', rpc_method='cast',
address='fake_addr', host='fake_host')
+
+ def test_migrate_instance_start(self):
+ self._test_network_api('migrate_instance_start', rpc_method='call',
+ instance_uuid='fake_instance_uuid',
+ rxtx_factor='fake_factor',
+ project_id='fake_project',
+ source_compute='fake_src_compute',
+ dest_compute='fake_dest_compute',
+ floating_addresses='fake_floating_addresses',
+ version='1.2')
+
+ def test_migrate_instance_start_multi_host(self):
+ self._test_network_api('migrate_instance_start', rpc_method='call',
+ instance_uuid='fake_instance_uuid',
+ rxtx_factor='fake_factor',
+ project_id='fake_project',
+ source_compute='fake_src_compute',
+ dest_compute='fake_dest_compute',
+ floating_addresses='fake_floating_addresses',
+ host='fake_host',
+ version='1.2')
+
+ def test_migrate_instance_finish(self):
+ self._test_network_api('migrate_instance_finish', rpc_method='call',
+ instance_uuid='fake_instance_uuid',
+ rxtx_factor='fake_factor',
+ project_id='fake_project',
+ source_compute='fake_src_compute',
+ dest_compute='fake_dest_compute',
+ floating_addresses='fake_floating_addresses',
+ version='1.2')
+
+ def test_migrate_instance_finish_multi_host(self):
+ self._test_network_api('migrate_instance_finish', rpc_method='call',
+ instance_uuid='fake_instance_uuid',
+ rxtx_factor='fake_factor',
+ project_id='fake_project',
+ source_compute='fake_src_compute',
+ dest_compute='fake_dest_compute',
+ floating_addresses='fake_floating_addresses',
+ host='fake_host',
+ version='1.2')
diff --git a/nova/tests/test_flags.py b/nova/tests/test_flags.py
index 973d54a1f..15dec56b9 100644
--- a/nova/tests/test_flags.py
+++ b/nova/tests/test_flags.py
@@ -17,6 +17,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+from nova import config
from nova import flags
from nova.openstack.common import cfg
from nova import test
@@ -44,7 +45,7 @@ class FlagsTestCase(test.TestCase):
self.assert_('runtime_answer' not in FLAGS)
argv = ['flags_test', 'extra_arg', '--runtime_answer=60']
- args = flags.parse_args(argv, default_config_files=[])
+ args = config.parse_args(argv, default_config_files=[])
self.assertEqual(len(args), 3)
self.assertEqual(argv, args)
@@ -60,7 +61,7 @@ class FlagsTestCase(test.TestCase):
default='val',
help='desc'))
argv = ['flags_test', '--duplicate_answer=60', 'extra_arg']
- args = flags.parse_args(argv, default_config_files=[])
+ args = config.parse_args(argv, default_config_files=[])
self.assert_('duplicate_answer' not in FLAGS)
self.assert_(FLAGS.duplicate_answer_long, 60)
@@ -68,7 +69,7 @@ class FlagsTestCase(test.TestCase):
FLAGS.clear()
FLAGS.register_cli_opt(cfg.IntOpt('duplicate_answer',
default=60, help='desc'))
- args = flags.parse_args(argv, default_config_files=[])
+ args = config.parse_args(argv, default_config_files=[])
self.assertEqual(FLAGS.duplicate_answer, 60)
self.assertEqual(FLAGS.duplicate_answer_long, 'val')
diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py
index 1b84b858d..8b883f755 100644
--- a/nova/tests/test_utils.py
+++ b/nova/tests/test_utils.py
@@ -30,6 +30,7 @@ import nova
from nova import exception
from nova import flags
from nova.openstack.common import timeutils
+from nova.openstack.common import uuidutils
from nova import test
from nova import utils
@@ -510,7 +511,7 @@ class GenericUtilsTestCase(test.TestCase):
class IsUUIDLikeTestCase(test.TestCase):
def assertUUIDLike(self, val, expected):
- result = utils.is_uuid_like(val)
+ result = uuidutils.is_uuid_like(val)
self.assertEqual(result, expected)
def test_good_uuid(self):
diff --git a/nova/tests/test_virt_drivers.py b/nova/tests/test_virt_drivers.py
index 1f30ee695..9d48cdf06 100644
--- a/nova/tests/test_virt_drivers.py
+++ b/nova/tests/test_virt_drivers.py
@@ -269,7 +269,8 @@ class _VirtDriverTestCase(_FakeDriverBackendTestCase):
@catch_notimplementederror
def test_poll_rebooting_instances(self):
- self.connection.poll_rebooting_instances(10)
+ instances = [self._get_running_instance()]
+ self.connection.poll_rebooting_instances(10, instances)
@catch_notimplementederror
def test_poll_rescued_instances(self):
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 404c183a0..54f7948b6 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -27,6 +27,8 @@ import re
from nova.compute import api as compute_api
from nova.compute import instance_types
from nova.compute import power_state
+from nova.compute import task_states
+from nova.compute import vm_states
from nova import context
from nova import db
from nova import exception
@@ -896,6 +898,37 @@ class XenAPIVMTestCase(stubs.XenAPITestBase):
self.assertRaises(xenapi_fake.Failure, conn.reboot, instance,
None, "SOFT")
+ def test_maintenance_mode(self):
+ real_call_xenapi = self.conn._session.call_xenapi
+ instance = self._create_instance(spawn=True)
+ api_calls = {}
+
+ # Record all the xenapi calls, and return a fake list of hosts
+ # for the host.get_all call
+ def fake_call_xenapi(method, *args):
+ api_calls[method] = args
+ if method == 'host.get_all':
+ return ['foo', 'bar', 'baz']
+ return real_call_xenapi(method, *args)
+ self.stubs.Set(self.conn._session, 'call_xenapi', fake_call_xenapi)
+
+ # Always find the 'bar' destination host
+ def fake_host_find(context, session, src, dst):
+ return 'bar'
+ self.stubs.Set(host, '_host_find', fake_host_find)
+
+ result = self.conn.host_maintenance_mode('bar', 'on_maintenance')
+ self.assertEqual(result, 'on_maintenance')
+
+ # We expect the VM.pool_migrate call to have been called to
+ # migrate our instance to the 'bar' host
+ expected = (instance['uuid'], 'bar', {})
+ self.assertTrue(api_calls.get('VM.pool_migrate'), expected)
+
+ instance = db.instance_get_by_uuid(self.context, instance['uuid'])
+ self.assertTrue(instance['vm_state'], vm_states.ACTIVE)
+ self.assertTrue(instance['task_state'], task_states.MIGRATING)
+
def _create_instance(self, instance_id=1, spawn=True):
"""Creates and spawns a test instance."""
instance_values = {
@@ -2241,7 +2274,8 @@ class XenAPIAggregateTestCase(stubs.XenAPITestBase):
self.assertRaises(exception.AggregateError,
self.compute.add_aggregate_host,
- self.context, self.aggr.id, "fake_host")
+ self.context, "fake_host",
+ aggregate=jsonutils.to_primitive(self.aggr))
excepted = db.aggregate_get(self.context, self.aggr.id)
self.assertEqual(excepted.metadetails[pool_states.KEY],
pool_states.ERROR)
@@ -2258,10 +2292,10 @@ class MockComputeAPI(object):
def __init__(self):
self._mock_calls = []
- def add_aggregate_host(self, ctxt, aggregate_id,
+ def add_aggregate_host(self, ctxt, aggregate,
host_param, host, slave_info):
self._mock_calls.append((
- self.add_aggregate_host, ctxt, aggregate_id,
+ self.add_aggregate_host, ctxt, aggregate,
host_param, host, slave_info))
def remove_aggregate_host(self, ctxt, aggregate_id, host_param,
@@ -2304,7 +2338,8 @@ class HypervisorPoolTestCase(test.TestCase):
self.assertIn(
(slave.compute_rpcapi.add_aggregate_host,
- "CONTEXT", 98, "slave", "master", "SLAVE_INFO"),
+ "CONTEXT", jsonutils.to_primitive(aggregate),
+ "slave", "master", "SLAVE_INFO"),
slave.compute_rpcapi._mock_calls)
def test_slave_asks_master_to_remove_slave_from_pool(self):
diff --git a/nova/utils.py b/nova/utils.py
index 284d72b55..d97c2ce3f 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -772,18 +772,6 @@ def gen_uuid():
return uuid.uuid4()
-def is_uuid_like(val):
- """For our purposes, a UUID is a string in canonical form:
-
- aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa
- """
- try:
- uuid.UUID(val)
- return True
- except (TypeError, ValueError, AttributeError):
- return False
-
-
def bool_from_str(val):
"""Convert a string representation of a bool into a bool value"""
diff --git a/nova/virt/driver.py b/nova/virt/driver.py
index 9c8a6448d..a466fa180 100644
--- a/nova/virt/driver.py
+++ b/nova/virt/driver.py
@@ -604,8 +604,14 @@ class ComputeDriver(object):
# TODO(Vek): Need to pass context in for access to auth_token
pass
- def poll_rebooting_instances(self, timeout):
- """Poll for rebooting instances"""
+ def poll_rebooting_instances(self, timeout, instances):
+ """Poll for rebooting instances
+
+ :param timeout: the currently configured timeout for considering
+ rebooting instances to be stuck
+ :param instances: instances that have been in rebooting state
+ longer than the configured timeout
+ """
# TODO(Vek): Need to pass context in for access to auth_token
raise NotImplementedError()
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index 03711fe98..877fb7603 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -123,7 +123,7 @@ class FakeDriver(driver.ComputeDriver):
def unrescue(self, instance, network_info):
pass
- def poll_rebooting_instances(self, timeout):
+ def poll_rebooting_instances(self, timeout, instances):
pass
def poll_rescued_instances(self, timeout):
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 97ce1710c..3104fafd3 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -1052,7 +1052,7 @@ class LibvirtDriver(driver.ComputeDriver):
libvirt_utils.file_delete(rescue_file)
@exception.wrap_exception()
- def poll_rebooting_instances(self, timeout):
+ def poll_rebooting_instances(self, timeout, instances):
pass
@exception.wrap_exception()
diff --git a/nova/virt/xenapi/driver.py b/nova/virt/xenapi/driver.py
index e4c4150a8..a928bf861 100644
--- a/nova/virt/xenapi/driver.py
+++ b/nova/virt/xenapi/driver.py
@@ -290,9 +290,9 @@ class XenAPIDriver(driver.ComputeDriver):
"""Restore the specified instance"""
self._vmops.restore(instance)
- def poll_rebooting_instances(self, timeout):
+ def poll_rebooting_instances(self, timeout, instances):
"""Poll for rebooting instances"""
- self._vmops.poll_rebooting_instances(timeout)
+ self._vmops.poll_rebooting_instances(timeout, instances)
def poll_rescued_instances(self, timeout):
"""Poll for rescued instances"""
diff --git a/nova/virt/xenapi/pool.py b/nova/virt/xenapi/pool.py
index 71b21ce24..0c2565dbd 100644
--- a/nova/virt/xenapi/pool.py
+++ b/nova/virt/xenapi/pool.py
@@ -126,7 +126,7 @@ class ResourcePool(object):
slave_info = self._create_slave_info()
self.compute_rpcapi.add_aggregate_host(
- context, aggregate.id, host, master_compute, slave_info)
+ context, aggregate, host, master_compute, slave_info)
def remove_from_aggregate(self, context, aggregate, host, slave_info=None):
"""Remove a compute host from an aggregate."""
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 5a295d194..7aa4a20ce 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -1145,10 +1145,12 @@ class VMOps(object):
instance=instance)
else:
vm_utils.shutdown_vm(self._session, instance, vm_ref, hard=True)
+ self._acquire_bootlock(vm_ref)
def restore(self, instance):
"""Restore the specified instance."""
vm_ref = self._get_vm_opaque_ref(instance)
+ self._release_bootlock(vm_ref)
self._start(instance, vm_ref)
def power_off(self, instance):
@@ -1172,7 +1174,7 @@ class VMOps(object):
if timeutils.is_older_than(task_created, timeout):
self._session.call_xenapi("task.cancel", task_ref)
- def poll_rebooting_instances(self, timeout):
+ def poll_rebooting_instances(self, timeout, instances):
"""Look for expirable rebooting instances.
- issue a "hard" reboot to any instance that has been stuck in a
@@ -1183,7 +1185,6 @@ class VMOps(object):
self._cancel_stale_tasks(timeout, 'VM.clean_reboot')
ctxt = nova_context.get_admin_context()
- instances = db.instance_get_all_hung_in_rebooting(ctxt, timeout)
instances_info = dict(instance_count=len(instances),
timeout=timeout)
diff --git a/tools/xenserver/destroy_cached_images.py b/tools/xenserver/destroy_cached_images.py
index dd6e91adc..a9045cd61 100644
--- a/tools/xenserver/destroy_cached_images.py
+++ b/tools/xenserver/destroy_cached_images.py
@@ -25,6 +25,7 @@ POSSIBLE_TOPDIR = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
if os.path.exists(os.path.join(POSSIBLE_TOPDIR, 'nova', '__init__.py')):
sys.path.insert(0, POSSIBLE_TOPDIR)
+from nova import config
from nova import flags
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
@@ -47,7 +48,7 @@ FLAGS.register_cli_opts(destroy_opts)
def main():
- flags.parse_args(sys.argv)
+ config.parse_args(sys.argv)
utils.monkey_patch()
xenapi = xenapi_driver.XenAPIDriver()