summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Leafe <ed@leafe.com>2011-08-08 20:06:54 +0000
committerEd Leafe <ed@leafe.com>2011-08-08 20:06:54 +0000
commit8f6b59f0a12a60ef7e45607d9dbcb8bf1c707297 (patch)
tree6e59b869fd2836b316e0c97e3d53f5e9b31c5ef7
parentde23e5ad63f6293060835e496363c935044480d6 (diff)
parent439afc337fec1064ff8eff58625f54f8450dce47 (diff)
downloadnova-8f6b59f0a12a60ef7e45607d9dbcb8bf1c707297.tar.gz
nova-8f6b59f0a12a60ef7e45607d9dbcb8bf1c707297.tar.xz
nova-8f6b59f0a12a60ef7e45607d9dbcb8bf1c707297.zip
Merged trunk.
-rw-r--r--nova/api/openstack/common.py2
-rw-r--r--nova/api/openstack/contrib/hosts.py21
-rw-r--r--nova/api/openstack/zones.py2
-rw-r--r--nova/auth/novarc.template1
-rw-r--r--nova/compute/api.py7
-rw-r--r--nova/compute/manager.py8
-rw-r--r--nova/db/sqlalchemy/api.py2
-rw-r--r--nova/exception.py9
-rw-r--r--nova/flags.py2
-rw-r--r--nova/scheduler/api.py13
-rw-r--r--nova/scheduler/zone_aware_scheduler.py9
-rw-r--r--nova/scheduler/zone_manager.py7
-rw-r--r--nova/tests/scheduler/test_scheduler.py12
-rw-r--r--nova/tests/test_hosts.py5
-rw-r--r--nova/tests/test_zones.py1
-rw-r--r--nova/virt/driver.py2
-rw-r--r--nova/virt/fake.py2
-rw-r--r--nova/virt/hyperv.py2
-rw-r--r--nova/virt/libvirt/connection.py2
-rw-r--r--nova/virt/vmwareapi_conn.py2
-rw-r--r--nova/virt/xenapi/vmops.py2
-rw-r--r--nova/virt/xenapi_conn.py13
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost2
-rw-r--r--tools/pip-requires2
24 files changed, 74 insertions, 56 deletions
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index 5226cdf9a..ac2104a5f 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -156,7 +156,7 @@ def remove_version_from_href(href):
"""
parsed_url = urlparse.urlsplit(href)
new_path = re.sub(r'^/v[0-9]+\.[0-9]+(/|$)', r'\1', parsed_url.path,
- count=1)
+ count=1)
if new_path == parsed_url.path:
msg = _('href %s does not contain version') % href
diff --git a/nova/api/openstack/contrib/hosts.py b/nova/api/openstack/contrib/hosts.py
index 2714d7888..63e5f545f 100644
--- a/nova/api/openstack/contrib/hosts.py
+++ b/nova/api/openstack/contrib/hosts.py
@@ -110,21 +110,16 @@ class HostController(object):
return {"host": host, "status": result}
def _host_power_action(self, req, host, action):
- """Reboots or shuts down the host."""
+ """Reboots, shuts down or powers up the host."""
context = req.environ['nova.context']
- result = self.compute_api.host_power_action(context, host=host,
- action=action)
- return {"host": host, "power_action": result}
+ try:
+ result = self.compute_api.host_power_action(context, host=host,
+ action=action)
+ except NotImplementedError as e:
+ raise webob.exc.HTTPBadRequest(explanation=e.msg)
def startup(self, req, id):
- """The only valid values for 'action' are 'reboot' or
- 'shutdown'. For completeness' sake there is the
- 'startup' option to start up a host, but this is not
- technically feasible now, as we run the host on the
- XenServer box.
- """
- msg = _("Host startup on XenServer is not supported.")
- raise webob.exc.HTTPBadRequest(explanation=msg)
+ return self._host_power_action(req, host=id, action="startup")
def shutdown(self, req, id):
return self._host_power_action(req, host=id, action="shutdown")
@@ -151,7 +146,7 @@ class Hosts(extensions.ExtensionDescriptor):
@admin_only.admin_only
def get_resources(self):
- resources = [extensions.ResourceExtension('os-hosts',
+ resources = [extensions.ResourceExtension('os-hosts',
HostController(), collection_actions={'update': 'PUT'},
member_actions={"startup": "GET", "shutdown": "GET",
"reboot": "GET"})]
diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py
index f7fd87bcd..a2bf267ed 100644
--- a/nova/api/openstack/zones.py
+++ b/nova/api/openstack/zones.py
@@ -166,7 +166,7 @@ class Controller(object):
return self.helper._get_server_admin_password_old_style(server)
-class ControllerV11(object):
+class ControllerV11(Controller):
"""Controller for 1.1 Zone resources."""
def _get_server_admin_password(self, server):
diff --git a/nova/auth/novarc.template b/nova/auth/novarc.template
index d05c099d7..978ffb210 100644
--- a/nova/auth/novarc.template
+++ b/nova/auth/novarc.template
@@ -16,3 +16,4 @@ export NOVA_API_KEY="%(access)s"
export NOVA_USERNAME="%(user)s"
export NOVA_PROJECT_ID="%(project)s"
export NOVA_URL="%(os)s"
+export NOVA_VERSION="1.1"
diff --git a/nova/compute/api.py b/nova/compute/api.py
index e5e5f7f57..ccff421fe 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -997,7 +997,12 @@ class API(base.Base):
def set_host_enabled(self, context, host, enabled):
"""Sets the specified host's ability to accept new instances."""
return self._call_compute_message("set_host_enabled", context,
- instance_id=None, host=host, params={"enabled": enabled})
+ host=host, params={"enabled": enabled})
+
+ def host_power_action(self, context, host, action):
+ """Reboots, shuts down or powers up the host."""
+ return self._call_compute_message("host_power_action", context,
+ host=host, params={"action": action})
def host_power_action(self, context, host, action):
"""Reboots or shuts down the host."""
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index fb135e1f2..cb6617c33 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -958,14 +958,12 @@ class ComputeManager(manager.SchedulerDependentManager):
result))
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
- def host_power_action(self, context, instance_id=None, host=None,
- action=None):
- """Reboots or shuts down the host."""
+ def host_power_action(self, context, host=None, action=None):
+ """Reboots, shuts down or powers up the host."""
return self.driver.host_power_action(host, action)
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
- def set_host_enabled(self, context, instance_id=None, host=None,
- enabled=None):
+ def set_host_enabled(self, context, host=None, enabled=None):
"""Sets the specified host's ability to accept new instances."""
return self.driver.set_host_enabled(host, enabled)
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index f469dc0e5..003eb8bcb 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -3307,7 +3307,7 @@ def instance_type_extra_specs_delete(context, instance_type_id, key):
@require_context
def instance_type_extra_specs_get_item(context, instance_type_id, key,
- session=None):
+ session=None):
if not session:
session = get_session()
diff --git a/nova/exception.py b/nova/exception.py
index 792e306c1..a87728fff 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -25,6 +25,7 @@ SHOULD include dedicated exception logging.
"""
from functools import wraps
+import sys
from nova import log as logging
@@ -96,6 +97,10 @@ def wrap_exception(notifier=None, publisher_id=None, event_type=None,
try:
return f(*args, **kw)
except Exception, e:
+ # Save exception since it can be clobbered during processing
+ # below before we can re-raise
+ exc_info = sys.exc_info()
+
if notifier:
payload = dict(args=args, exception=e)
payload.update(kw)
@@ -122,7 +127,9 @@ def wrap_exception(notifier=None, publisher_id=None, event_type=None,
LOG.exception(_('Uncaught exception'))
#logging.error(traceback.extract_stack(exc_traceback))
raise Error(str(e))
- raise
+
+ # re-raise original exception since it may have been clobbered
+ raise exc_info[0], exc_info[1], exc_info[2]
return wraps(f)(wrapped)
return inner
diff --git a/nova/flags.py b/nova/flags.py
index 12c6d1356..eb6366ed9 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -317,7 +317,7 @@ DEFINE_string('osapi_extensions_path', '/var/lib/nova/extensions',
DEFINE_string('osapi_host', '$my_ip', 'ip of api server')
DEFINE_string('osapi_scheme', 'http', 'prefix for openstack')
DEFINE_integer('osapi_port', 8774, 'OpenStack API port')
-DEFINE_string('osapi_path', '/v1.0/', 'suffix for openstack')
+DEFINE_string('osapi_path', '/v1.1/', 'suffix for openstack')
DEFINE_integer('osapi_max_limit', 1000,
'max number of items returned in a collection response')
diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py
index 137b671c0..55cea5f8f 100644
--- a/nova/scheduler/api.py
+++ b/nova/scheduler/api.py
@@ -17,7 +17,8 @@
Handles all requests relating to schedulers.
"""
-import novaclient
+from novaclient import v1_1 as novaclient
+from novaclient import exceptions as novaclient_exceptions
from nova import db
from nova import exception
@@ -112,7 +113,7 @@ def _wrap_method(function, self):
def _process(func, zone):
"""Worker stub for green thread pool. Give the worker
an authenticated nova client and zone info."""
- nova = novaclient.OpenStack(zone.username, zone.password, None,
+ nova = novaclient.Client(zone.username, zone.password, None,
zone.api_url)
nova.authenticate()
return func(nova, zone)
@@ -132,10 +133,10 @@ def call_zone_method(context, method_name, errors_to_ignore=None,
zones = db.zone_get_all(context)
for zone in zones:
try:
- nova = novaclient.OpenStack(zone.username, zone.password, None,
+ nova = novaclient.Client(zone.username, zone.password, None,
zone.api_url)
nova.authenticate()
- except novaclient.exceptions.BadRequest, e:
+ except novaclient_exceptions.BadRequest, e:
url = zone.api_url
LOG.warn(_("Failed request to zone; URL=%(url)s: %(e)s")
% locals())
@@ -188,7 +189,7 @@ def _issue_novaclient_command(nova, zone, collection,
if method_name in ['find', 'findall']:
try:
return getattr(manager, method_name)(**kwargs)
- except novaclient.NotFound:
+ except novaclient_exceptions.NotFound:
url = zone.api_url
LOG.debug(_("%(collection)s.%(method_name)s didn't find "
"anything matching '%(kwargs)s' on '%(url)s'" %
@@ -200,7 +201,7 @@ def _issue_novaclient_command(nova, zone, collection,
item = args.pop(0)
try:
result = manager.get(item)
- except novaclient.NotFound:
+ except novaclient_exceptions.NotFound:
url = zone.api_url
LOG.debug(_("%(collection)s '%(item)s' not found on '%(url)s'" %
locals()))
diff --git a/nova/scheduler/zone_aware_scheduler.py b/nova/scheduler/zone_aware_scheduler.py
index a47bf7fe7..047dafa6f 100644
--- a/nova/scheduler/zone_aware_scheduler.py
+++ b/nova/scheduler/zone_aware_scheduler.py
@@ -24,7 +24,9 @@ import operator
import json
import M2Crypto
-import novaclient
+
+from novaclient import v1_1 as novaclient
+from novaclient import exceptions as novaclient_exceptions
from nova import crypto
from nova import db
@@ -118,10 +120,9 @@ class ZoneAwareScheduler(driver.Scheduler):
% locals())
nova = None
try:
- nova = novaclient.OpenStack(zone.username, zone.password, None,
- url)
+ nova = novaclient.Client(zone.username, zone.password, None, url)
nova.authenticate()
- except novaclient.exceptions.BadRequest, e:
+ except novaclient_exceptions.BadRequest, e:
raise exception.NotAuthorized(_("Bad credentials attempting "
"to talk to zone at %(url)s.") % locals())
diff --git a/nova/scheduler/zone_manager.py b/nova/scheduler/zone_manager.py
index efdac06e1..97bdf3d44 100644
--- a/nova/scheduler/zone_manager.py
+++ b/nova/scheduler/zone_manager.py
@@ -18,10 +18,11 @@ ZoneManager oversees all communications with child Zones.
"""
import datetime
-import novaclient
import thread
import traceback
+from novaclient import v1_1 as novaclient
+
from eventlet import greenpool
from nova import db
@@ -89,8 +90,8 @@ class ZoneState(object):
def _call_novaclient(zone):
"""Call novaclient. Broken out for testing purposes."""
- client = novaclient.OpenStack(zone.username, zone.password, None,
- zone.api_url)
+ client = novaclient.Client(zone.username, zone.password, None,
+ zone.api_url)
return client.zones.info()._info
diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py
index f60eb6433..330dab5e5 100644
--- a/nova/tests/scheduler/test_scheduler.py
+++ b/nova/tests/scheduler/test_scheduler.py
@@ -21,9 +21,11 @@ Tests For Scheduler
import datetime
import mox
-import novaclient.exceptions
import stubout
+from novaclient import v1_1 as novaclient
+from novaclient import exceptions as novaclient_exceptions
+
from mox import IgnoreArg
from nova import context
from nova import db
@@ -1036,10 +1038,10 @@ class FakeServerCollection(object):
class FakeEmptyServerCollection(object):
def get(self, f):
- raise novaclient.NotFound(1)
+ raise novaclient_exceptions.NotFound(1)
def find(self, name):
- raise novaclient.NotFound(2)
+ raise novaclient_exceptions.NotFound(2)
class FakeNovaClient(object):
@@ -1085,7 +1087,7 @@ class FakeZonesProxy(object):
raise Exception('testing')
-class FakeNovaClientOpenStack(object):
+class FakeNovaClientZones(object):
def __init__(self, *args, **kwargs):
self.zones = FakeZonesProxy()
@@ -1098,7 +1100,7 @@ class CallZoneMethodTest(test.TestCase):
super(CallZoneMethodTest, self).setUp()
self.stubs = stubout.StubOutForTesting()
self.stubs.Set(db, 'zone_get_all', zone_get_all)
- self.stubs.Set(novaclient, 'OpenStack', FakeNovaClientOpenStack)
+ self.stubs.Set(novaclient, 'Client', FakeNovaClientZones)
def tearDown(self):
self.stubs.UnsetAll()
diff --git a/nova/tests/test_hosts.py b/nova/tests/test_hosts.py
index cd22571e6..a724db9da 100644
--- a/nova/tests/test_hosts.py
+++ b/nova/tests/test_hosts.py
@@ -94,12 +94,11 @@ class HostTestCase(test.TestCase):
self.assertEqual(result_c2["status"], "disabled")
def test_host_startup(self):
- self.assertRaises(webob.exc.HTTPBadRequest, self.controller.startup,
- self.req, "host_c1")
+ result = self.controller.startup(self.req, "host_c1")
+ self.assertEqual(result["power_action"], "startup")
def test_host_shutdown(self):
result = self.controller.shutdown(self.req, "host_c1")
- print "RES", result
self.assertEqual(result["power_action"], "shutdown")
def test_host_reboot(self):
diff --git a/nova/tests/test_zones.py b/nova/tests/test_zones.py
index a943fee27..9efa23015 100644
--- a/nova/tests/test_zones.py
+++ b/nova/tests/test_zones.py
@@ -18,7 +18,6 @@ Tests For ZoneManager
import datetime
import mox
-import novaclient
from nova import context
from nova import db
diff --git a/nova/virt/driver.py b/nova/virt/driver.py
index 052c6607e..5d73eefc7 100644
--- a/nova/virt/driver.py
+++ b/nova/virt/driver.py
@@ -283,7 +283,7 @@ class ComputeDriver(object):
raise NotImplementedError()
def host_power_action(self, host, action):
- """Reboots or shuts down the host."""
+ """Reboots, shuts down or powers up the host."""
raise NotImplementedError()
def set_host_enabled(self, host, enabled):
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index db51c258b..89ad20494 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -513,7 +513,7 @@ class FakeConnection(driver.ComputeDriver):
return self.host_status
def host_power_action(self, host, action):
- """Reboots or shuts down the host."""
+ """Reboots, shuts down or powers up the host."""
pass
def set_host_enabled(self, host, enabled):
diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py
index f0efeb581..ae30c62f0 100644
--- a/nova/virt/hyperv.py
+++ b/nova/virt/hyperv.py
@@ -500,7 +500,7 @@ class HyperVConnection(driver.ComputeDriver):
pass
def host_power_action(self, host, action):
- """Reboots or shuts down the host."""
+ """Reboots, shuts down or powers up the host."""
pass
def set_host_enabled(self, host, enabled):
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index 4cb5f87cb..7655bf386 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -1563,7 +1563,7 @@ class LibvirtConnection(driver.ComputeDriver):
pass
def host_power_action(self, host, action):
- """Reboots or shuts down the host."""
+ """Reboots, shuts down or powers up the host."""
pass
def set_host_enabled(self, host, enabled):
diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py
index 5937d9585..aaa384374 100644
--- a/nova/virt/vmwareapi_conn.py
+++ b/nova/virt/vmwareapi_conn.py
@@ -192,7 +192,7 @@ class VMWareESXConnection(driver.ComputeDriver):
return
def host_power_action(self, host, action):
- """Reboots or shuts down the host."""
+ """Reboots, shuts down or powers up the host."""
pass
def set_host_enabled(self, host, enabled):
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index b549b33d1..b913e764e 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -1045,7 +1045,7 @@ class VMOps(object):
xenapi_resp = self._call_xenhost("set_host_enabled", args)
try:
resp = json.loads(xenapi_resp)
- except TypeError as e:
+ except TypeError as e:
# Already logged; return the message
return xenapi_resp.details[-1]
return resp["status"]
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index a1b5dba27..a1c9a1e30 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -333,8 +333,17 @@ class XenAPIConnection(driver.ComputeDriver):
return self.HostState.get_host_stats(refresh=refresh)
def host_power_action(self, host, action):
- """Reboots or shuts down the host."""
- return self._vmops.host_power_action(host, action)
+ """The only valid values for 'action' on XenServer are 'reboot' or
+ 'shutdown', even though the API also accepts 'startup'. As this is
+ not technically possible on XenServer, since the host is the same
+ physical machine as the hypervisor, if this is requested, we need to
+ raise an exception.
+ """
+ if action in ("reboot", "shutdown"):
+ return self._vmops.host_power_action(host, action)
+ else:
+ msg = _("Host startup on XenServer is not supported.")
+ raise NotImplementedError(msg)
def set_host_enabled(self, host, enabled):
"""Sets the specified host's ability to accept new instances."""
diff --git a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
index 4028fdc7a..8bd376264 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
@@ -196,7 +196,7 @@ def host_shutdown(self, arg_dict):
@jsonify
def host_start(self, arg_dict):
- """Starts the host. NOTE: Currently not feasible, since the host
+ """Starts the host. Currently not feasible, since the host
runs on the same machine as Xen.
"""
return _power_action("startup")
diff --git a/tools/pip-requires b/tools/pip-requires
index 23e707034..fd0ca639d 100644
--- a/tools/pip-requires
+++ b/tools/pip-requires
@@ -9,7 +9,7 @@ boto==1.9b
carrot==0.10.5
eventlet
lockfile==0.8
-python-novaclient==2.5.9
+python-novaclient==2.6.0
python-daemon==1.5.5
python-gflags==1.3
redis==2.0.0