summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Leafe <ed@leafe.com>2011-08-04 21:17:21 +0000
committerEd Leafe <ed@leafe.com>2011-08-04 21:17:21 +0000
commiteb66810f6034a29724630e89739217a83b858d86 (patch)
tree74a6bc9cfa3dc8988255ff43a7980f1713010123
parentb5ff9bc2add98444773a26ce37e1ceb82e9531ae (diff)
parentdcac4bc6c7be9832704e37cca7ce815e083974f5 (diff)
downloadnova-eb66810f6034a29724630e89739217a83b858d86.tar.gz
nova-eb66810f6034a29724630e89739217a83b858d86.tar.xz
nova-eb66810f6034a29724630e89739217a83b858d86.zip
Merged in the power action changes
-rw-r--r--nova/api/openstack/contrib/hosts.py37
-rw-r--r--nova/compute/api.py6
-rw-r--r--nova/compute/manager.py6
-rw-r--r--nova/tests/test_hosts.py31
-rw-r--r--nova/tests/test_xenapi.py7
-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.py12
-rw-r--r--nova/virt/xenapi_conn.py4
-rwxr-xr-xplugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost13
13 files changed, 73 insertions, 53 deletions
diff --git a/nova/api/openstack/contrib/hosts.py b/nova/api/openstack/contrib/hosts.py
index 7290360ad..2714d7888 100644
--- a/nova/api/openstack/contrib/hosts.py
+++ b/nova/api/openstack/contrib/hosts.py
@@ -71,7 +71,7 @@ class HostController(object):
key = raw_key.lower().strip()
val = raw_val.lower().strip()
# NOTE: (dabo) Right now only 'status' can be set, but other
- # actions may follow.
+ # settings may follow.
if key == "status":
if val[:6] in ("enable", "disabl"):
return self._set_enabled_status(req, id,
@@ -109,12 +109,28 @@ class HostController(object):
raise webob.exc.HTTPBadRequest(explanation=result)
return {"host": host, "status": result}
- def _set_powerstate(self, req, host, state):
+ def _host_power_action(self, req, host, action):
"""Reboots or shuts down the host."""
context = req.environ['nova.context']
- result = self.compute_api.set_host_powerstate(context, host=host,
- state=state)
- return {"host": host, "power_state": result}
+ result = self.compute_api.host_power_action(context, host=host,
+ action=action)
+ return {"host": host, "power_action": result}
+
+ 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)
+
+ def shutdown(self, req, id):
+ return self._host_power_action(req, host=id, action="shutdown")
+
+ def reboot(self, req, id):
+ return self._host_power_action(req, host=id, action="reboot")
class Hosts(extensions.ExtensionDescriptor):
@@ -135,11 +151,8 @@ class Hosts(extensions.ExtensionDescriptor):
@admin_only.admin_only
def get_resources(self):
- resources = []
- # If we are not in an admin env, don't add the resource. Regular users
- # shouldn't have access to the host.
- if FLAGS.allow_admin_api:
- resources = [extensions.ResourceExtension('os-hosts',
- HostController(), collection_actions={'update': 'PUT'},
- member_actions={})]
+ resources = [extensions.ResourceExtension('os-hosts',
+ HostController(), collection_actions={'update': 'PUT'},
+ member_actions={"startup": "GET", "shutdown": "GET",
+ "reboot": "GET"})]
return resources
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 3e0cd7cfa..5f85ca908 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -995,10 +995,10 @@ class API(base.Base):
return self._call_compute_message("set_host_enabled", context,
instance_id=None, host=host, params={"enabled": enabled})
- def set_host_powerstate(self, context, host, state):
+ def host_power_action(self, context, host, action):
"""Reboots or shuts down the host."""
- return self._call_compute_message("set_host_powerstate", context,
- instance_id=None, host=host, params={"state": state})
+ return self._call_compute_message("host_power_action", context,
+ instance_id=None, host=host, params={"action": action})
@scheduler_api.reroute_compute("diagnostics")
def get_diagnostics(self, context, instance_id):
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 220b09554..c2c12a9a2 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -955,10 +955,10 @@ class ComputeManager(manager.SchedulerDependentManager):
result))
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
- def set_host_powerstate(self, context, instance_id=None, host=None,
- state=None):
+ def host_power_action(self, context, instance_id=None, host=None,
+ action=None):
"""Reboots or shuts down the host."""
- return self.driver.set_host_powerstate(host, state)
+ 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,
diff --git a/nova/tests/test_hosts.py b/nova/tests/test_hosts.py
index d8f90a109..cd22571e6 100644
--- a/nova/tests/test_hosts.py
+++ b/nova/tests/test_hosts.py
@@ -48,8 +48,8 @@ def stub_set_host_enabled(context, host, enabled):
return status
-def stub_set_host_powerstate(context, host, state):
- return state
+def stub_host_power_action(context, host, action):
+ return action
class FakeRequest(object):
@@ -66,8 +66,8 @@ class HostTestCase(test.TestCase):
self.stubs.Set(scheduler_api, 'get_host_list', stub_get_host_list)
self.stubs.Set(self.controller.compute_api, 'set_host_enabled',
stub_set_host_enabled)
- self.stubs.Set(self.controller.compute_api, 'set_host_powerstate',
- stub_set_host_powerstate)
+ self.stubs.Set(self.controller.compute_api, 'host_power_action',
+ stub_host_power_action)
def test_list_hosts(self):
"""Verify that the compute hosts are returned."""
@@ -93,19 +93,18 @@ class HostTestCase(test.TestCase):
result_c2 = self.controller.update(self.req, "host_c2", body=en_body)
self.assertEqual(result_c2["status"], "disabled")
- def test_host_power_state(self):
- en_body = {"power_state": "reboot"}
- result_c1 = self.controller.update(self.req, "host_c1", body=en_body)
- self.assertEqual(result_c1["power_state"], "reboot")
- # Test invalid power_state
- en_body = {"power_state": "invalid"}
- self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
- self.req, "host_c1", body=en_body)
+ def test_host_startup(self):
+ self.assertRaises(webob.exc.HTTPBadRequest, self.controller.startup,
+ self.req, "host_c1")
- def test_bad_power_state_value(self):
- bad_body = {"power_state": "bad"}
- self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update,
- self.req, "host_c1", body=bad_body)
+ 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):
+ result = self.controller.reboot(self.req, "host_c1")
+ self.assertEqual(result["power_action"], "reboot")
def test_bad_status_value(self):
bad_body = {"status": "bad"}
diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py
index 5f3aec700..b0b557907 100644
--- a/nova/tests/test_xenapi.py
+++ b/nova/tests/test_xenapi.py
@@ -764,12 +764,18 @@ class XenAPIMigrateInstance(test.TestCase):
def test_finish_migrate(self):
instance = db.instance_create(self.context, self.values)
self.called = False
+ self.fake_vm_start_called = False
+
+ def fake_vm_start(*args, **kwargs):
+ self.fake_vm_start_called = True
def fake_vdi_resize(*args, **kwargs):
self.called = True
self.stubs.Set(stubs.FakeSessionForMigrationTests,
"VDI_resize_online", fake_vdi_resize)
+ self.stubs.Set(vmops.VMOps, '_start', fake_vm_start)
+
stubs.stubout_session(self.stubs, stubs.FakeSessionForMigrationTests)
stubs.stubout_loopingcall_start(self.stubs)
conn = xenapi_conn.get_connection(False)
@@ -791,6 +797,7 @@ class XenAPIMigrateInstance(test.TestCase):
dict(base_copy='hurr', cow='durr'),
network_info, resize_instance=True)
self.assertEqual(self.called, True)
+ self.assertEqual(self.fake_vm_start_called, True)
def test_finish_migrate_no_local_storage(self):
tiny_type_id = \
diff --git a/nova/virt/driver.py b/nova/virt/driver.py
index 30f14459a..052c6607e 100644
--- a/nova/virt/driver.py
+++ b/nova/virt/driver.py
@@ -282,7 +282,7 @@ class ComputeDriver(object):
# TODO(Vek): Need to pass context in for access to auth_token
raise NotImplementedError()
- def set_host_powerstate(self, host, state):
+ def host_power_action(self, host, action):
"""Reboots or shuts down the host."""
raise NotImplementedError()
diff --git a/nova/virt/fake.py b/nova/virt/fake.py
index 7b13f4fbe..db51c258b 100644
--- a/nova/virt/fake.py
+++ b/nova/virt/fake.py
@@ -512,7 +512,7 @@ class FakeConnection(driver.ComputeDriver):
"""Return fake Host Status of ram, disk, network."""
return self.host_status
- def set_host_powerstate(self, host, state):
+ def host_power_action(self, host, action):
"""Reboots or shuts down the host."""
pass
diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py
index 00c4d360b..f0efeb581 100644
--- a/nova/virt/hyperv.py
+++ b/nova/virt/hyperv.py
@@ -499,7 +499,7 @@ class HyperVConnection(driver.ComputeDriver):
"""See xenapi_conn.py implementation."""
pass
- def set_host_powerstate(self, host, state):
+ def host_power_action(self, host, action):
"""Reboots or shuts down the host."""
pass
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index f0b2014ac..14e02c7c4 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -1558,7 +1558,7 @@ class LibvirtConnection(driver.ComputeDriver):
"""See xenapi_conn.py implementation."""
pass
- def set_host_powerstate(self, host, state):
+ def host_power_action(self, host, action):
"""Reboots or shuts down the host."""
pass
diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py
index 90d083f10..5937d9585 100644
--- a/nova/virt/vmwareapi_conn.py
+++ b/nova/virt/vmwareapi_conn.py
@@ -191,7 +191,7 @@ class VMWareESXConnection(driver.ComputeDriver):
"""This method is supported only by libvirt."""
return
- def set_host_powerstate(self, host, state):
+ def host_power_action(self, host, action):
"""Reboots or shuts down the host."""
pass
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index 26fa8f279..844640b9e 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -122,7 +122,7 @@ class VMOps(object):
network_info)
if resize_instance:
self.resize_instance(instance, vdi_uuid)
- self._spawn(instance, vm_ref)
+ self._start(instance, vm_ref=vm_ref)
def _start(self, instance, vm_ref=None):
"""Power on a VM instance"""
@@ -1024,13 +1024,13 @@ class VMOps(object):
# TODO: implement this!
return 'http://fakeajaxconsole/fake_url'
- def set_host_powerstate(self, host, state):
+ def host_power_action(self, host, action):
"""Reboots or shuts down the host."""
- args = {"state": json.dumps(state)}
+ args = {"action": json.dumps(action)}
methods = {"reboot": "host_reboot", "shutdown": "host_shutdown"}
- json_resp = self._call_xenhost(methods[state], args)
+ json_resp = self._call_xenhost(methods[action], args)
resp = json.loads(json_resp)
- return resp["powerstate"]
+ return resp["power_action"]
def set_host_enabled(self, host, enabled):
"""Sets the specified host's ability to accept new instances."""
@@ -1038,7 +1038,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 fa5b78a2a..3452343c6 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -332,9 +332,9 @@ class XenAPIConnection(driver.ComputeDriver):
True, run the update first."""
return self.HostState.get_host_stats(refresh=refresh)
- def set_host_powerstate(self, host, state):
+ def host_power_action(self, host, action):
"""Reboots or shuts down the host."""
- return self._vmops.set_host_powerstate(host, state)
+ return self._vmops.host_power_action(host, action)
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 b48a303ee..a28f5abfb 100755
--- a/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
+++ b/plugins/xenserver/xenapi/etc/xapi.d/plugins/xenhost
@@ -104,6 +104,7 @@ def set_host_enabled(self, arg_dict):
return {"status": status}
+<<<<<<< TREE
def _write_config_dict(dct):
conf_file = file(config_file_path, "w")
json.dump(dct, conf_file)
@@ -163,7 +164,7 @@ def set_config(self, arg_dict):
_write_config_dict(conf)
-def _powerstate(state):
+def _power_action(action):
host_uuid = _get_host_uuid()
# Host must be disabled first
result = _run_command("xe host-disable")
@@ -175,23 +176,23 @@ def _powerstate(state):
raise pluginlib.PluginError(result)
cmds = {"reboot": "xe host-reboot", "startup": "xe host-power-on",
"shutdown": "xe host-shutdown"}
- result = _run_command(cmds[state])
+ result = _run_command(cmds[action])
# Should be empty string
if result:
raise pluginlib.PluginError(result)
- return {"powerstate": state}
+ return {"power_action": action}
@jsonify
def host_reboot(self, arg_dict):
"""Reboots the host."""
- return _powerstate("reboot")
+ return _power_action("reboot")
@jsonify
def host_shutdown(self, arg_dict):
"""Reboots the host."""
- return _powerstate("shutdown")
+ return _power_action("shutdown")
@jsonify
@@ -199,7 +200,7 @@ def host_start(self, arg_dict):
"""Starts the host. NOTE: Currently not feasible, since the host
runs on the same machine as Xen.
"""
- return _powerstate("startup")
+ return _power_action("startup")
@jsonify