summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorSandy Walsh <sandy.walsh@rackspace.com>2010-11-15 01:26:34 -0400
committerSandy Walsh <sandy.walsh@rackspace.com>2010-11-15 01:26:34 -0400
commit18555a55d186d72d1bb2fd806790ef5a31cdfd33 (patch)
tree655af1983197faaadfea78315c07b16b09e516cb /nova
parent398ec325160acf039e1070718e898339a4b2d268 (diff)
parenta81547f780afec4eee88e87a301b32c903943c2c (diff)
downloadnova-18555a55d186d72d1bb2fd806790ef5a31cdfd33.tar.gz
nova-18555a55d186d72d1bb2fd806790ef5a31cdfd33.tar.xz
nova-18555a55d186d72d1bb2fd806790ef5a31cdfd33.zip
merge with trunk
Diffstat (limited to 'nova')
-rw-r--r--nova/flags.py2
-rw-r--r--nova/objectstore/handler.py4
-rw-r--r--nova/rpc.py27
-rw-r--r--nova/virt/xenapi.py34
-rw-r--r--nova/wsgi.py2
5 files changed, 56 insertions, 13 deletions
diff --git a/nova/flags.py b/nova/flags.py
index 07b469bca..121b9ca25 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -196,6 +196,8 @@ DEFINE_integer('rabbit_port', 5672, 'rabbit port')
DEFINE_string('rabbit_userid', 'guest', 'rabbit userid')
DEFINE_string('rabbit_password', 'guest', 'rabbit password')
DEFINE_string('rabbit_virtual_host', '/', 'rabbit virtual host')
+DEFINE_integer('rabbit_retry_interval', 10, 'rabbit connection retry interval')
+DEFINE_integer('rabbit_max_retries', 12, 'rabbit connection attempts')
DEFINE_string('control_exchange', 'nova', 'the main exchange to connect to')
DEFINE_string('cc_host', '127.0.0.1', 'ip of api server')
DEFINE_integer('cc_port', 8773, 'cloud controller port')
diff --git a/nova/objectstore/handler.py b/nova/objectstore/handler.py
index b26906001..c8920b00c 100644
--- a/nova/objectstore/handler.py
+++ b/nova/objectstore/handler.py
@@ -61,6 +61,7 @@ from nova.objectstore import image
FLAGS = flags.FLAGS
+flags.DEFINE_string('s3_listen_host', '', 'Host to listen on.')
def render_xml(request, value):
@@ -438,6 +439,7 @@ def get_application():
# Disabled because of lack of proper introspection in Twisted
# or possibly different versions of twisted?
# pylint: disable-msg=E1101
- objectStoreService = internet.TCPServer(FLAGS.s3_port, factory)
+ objectStoreService = internet.TCPServer(FLAGS.s3_port, factory,
+ interface=FLAGS.s3_listen_host)
objectStoreService.setServiceParent(application)
return application
diff --git a/nova/rpc.py b/nova/rpc.py
index 9938b0838..86a29574f 100644
--- a/nova/rpc.py
+++ b/nova/rpc.py
@@ -38,8 +38,8 @@ from nova import fakerabbit
from nova import flags
from nova import context
-FLAGS = flags.FLAGS
+FLAGS = flags.FLAGS
LOG = logging.getLogger('amqplib')
LOG.setLevel(logging.DEBUG)
@@ -83,19 +83,24 @@ class Consumer(messaging.Consumer):
Contains methods for connecting the fetch method to async loops
"""
def __init__(self, *args, **kwargs):
- self.failed_connection = False
-
- while True:
+ for i in xrange(FLAGS.rabbit_max_retries):
+ if i > 0:
+ time.sleep(FLAGS.rabbit_retry_interval)
try:
super(Consumer, self).__init__(*args, **kwargs)
+ self.failed_connection = False
break
except: # Catching all because carrot sucks
- logging.exception("AMQP server on %s:%d is unreachable. " \
- "Trying again in 30 seconds." % (
- FLAGS.rabbit_host,
- FLAGS.rabbit_port))
- time.sleep(30)
- continue
+ logging.exception("AMQP server on %s:%d is unreachable." \
+ " Trying again in %d seconds." % (
+ FLAGS.rabbit_host,
+ FLAGS.rabbit_port,
+ FLAGS.rabbit_retry_interval))
+ self.failed_connection = True
+ if self.failed_connection:
+ logging.exception("Unable to connect to AMQP server" \
+ " after %d tries. Shutting down." % FLAGS.rabbit_max_retries)
+ sys.exit(1)
def fetch(self, no_ack=None, auto_ack=None, enable_callbacks=False):
"""Wraps the parent fetch with some logic for failed connections"""
@@ -103,7 +108,7 @@ class Consumer(messaging.Consumer):
# refactored into some sort of connection manager object
try:
if self.failed_connection:
- # NOTE(vish): conn is defined in the parent class, we can
+ # NOTE(vish): connection is defined in the parent class, we can
# recreate it as long as we create the backend too
# pylint: disable-msg=W0201
self.connection = Connection.recreate()
diff --git a/nova/virt/xenapi.py b/nova/virt/xenapi.py
index 0f563aa41..3169562a5 100644
--- a/nova/virt/xenapi.py
+++ b/nova/virt/xenapi.py
@@ -286,11 +286,21 @@ class XenAPIConnection(object):
# Don't complain, just return. This lets us clean up instances
# that have already disappeared from the underlying platform.
defer.returnValue(None)
+ # Get the VDIs related to the VM
+ vdis = yield self._lookup_vm_vdis(vm)
try:
task = yield self._call_xenapi('Async.VM.hard_shutdown', vm)
yield self._wait_for_task(task)
except Exception, exc:
logging.warn(exc)
+ # Disk clean-up
+ if vdis:
+ for vdi in vdis:
+ try:
+ task = yield self._call_xenapi('Async.VDI.destroy', vdi)
+ yield self._wait_for_task(task)
+ except Exception, exc:
+ logging.warn(exc)
try:
task = yield self._call_xenapi('Async.VM.destroy', vm)
yield self._wait_for_task(task)
@@ -325,6 +335,30 @@ class XenAPIConnection(object):
else:
return vms[0]
+ @utils.deferredToThread
+ def _lookup_vm_vdis(self, vm):
+ return self._lookup_vm_vdis_blocking(vm)
+
+ def _lookup_vm_vdis_blocking(self, vm):
+ # Firstly we get the VBDs, then the VDIs.
+ # TODO: do we leave the read-only devices?
+ vbds = self._conn.xenapi.VM.get_VBDs(vm)
+ vdis = []
+ if vbds:
+ for vbd in vbds:
+ try:
+ vdi = self._conn.xenapi.VBD.get_VDI(vbd)
+ # Test valid VDI
+ record = self._conn.xenapi.VDI.get_record(vdi)
+ except Exception, exc:
+ logging.warn(exc)
+ else:
+ vdis.append(vdi)
+ if len(vdis) > 0:
+ return vdis
+ else:
+ return None
+
def _wait_for_task(self, task):
"""Return a Deferred that will give the result of the given task.
The task is polled until it completes."""
diff --git a/nova/wsgi.py b/nova/wsgi.py
index b04b487ea..c7ee9ed14 100644
--- a/nova/wsgi.py
+++ b/nova/wsgi.py
@@ -28,7 +28,7 @@ from xml.dom import minidom
import eventlet
import eventlet.wsgi
-eventlet.patcher.monkey_patch(all=False, socket=True)
+eventlet.patcher.monkey_patch(all=False, socket=True, time=True)
import routes
import routes.middleware
import webob