summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@yahoo.com>2010-09-11 00:21:58 -0700
committerVishvananda Ishaya <vishvananda@yahoo.com>2010-09-11 00:21:58 -0700
commitd41ebe02faadc620a5c38490f46dbf5b23b6a20f (patch)
tree899091006aaec84bb8fc8cb5b5ffee090ec262ba
parent9003fe35cfd2a6daa49d717bf256f2229171f7c6 (diff)
parent433d83a7e487b41ba4caa7aa5addfc7365975f0b (diff)
downloadnova-d41ebe02faadc620a5c38490f46dbf5b23b6a20f.tar.gz
nova-d41ebe02faadc620a5c38490f46dbf5b23b6a20f.tar.xz
nova-d41ebe02faadc620a5c38490f46dbf5b23b6a20f.zip
merged trunk
-rwxr-xr-xbin/nova-manage55
-rw-r--r--nova/tests/cloud_unittest.py3
-rw-r--r--nova/virt/xenapi.py40
3 files changed, 82 insertions, 16 deletions
diff --git a/bin/nova-manage b/bin/nova-manage
index 56191252a..325245ac4 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -17,6 +17,37 @@
# License for the specific language governing permissions and limitations
# under the License.
+# Interactive shell based on Django:
+#
+# Copyright (c) 2005, the Lawrence Journal-World
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# 3. Neither the name of Django nor the names of its contributors may be used
+# to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
"""
CLI interface for nova management.
Connects to the running ADMIN api in the api daemon.
@@ -103,6 +134,29 @@ class VpnCommands(object):
self.pipe.launch_vpn_instance(project_id)
+class ShellCommands(object):
+ def run(self):
+ "Runs a Python interactive interpreter. Tries to use IPython, if it's available."
+ try:
+ import IPython
+ # Explicitly pass an empty list as arguments, because otherwise IPython
+ # would use sys.argv from this script.
+ shell = IPython.Shell.IPShell(argv=[])
+ shell.mainloop()
+ except ImportError:
+ import code
+ try: # Try activating rlcompleter, because it's handy.
+ import readline
+ except ImportError:
+ pass
+ else:
+ # We don't have to wrap the following import in a 'try', because
+ # we already know 'readline' was imported successfully.
+ import rlcompleter
+ readline.parse_and_bind("tab:complete")
+ code.interact()
+
+
class RoleCommands(object):
"""Class for managing roles."""
@@ -256,6 +310,7 @@ CATEGORIES = [
('user', UserCommands),
('project', ProjectCommands),
('role', RoleCommands),
+ ('shell', ShellCommands),
('vpn', VpnCommands),
('floating', FloatingIpCommands)
]
diff --git a/nova/tests/cloud_unittest.py b/nova/tests/cloud_unittest.py
index 29947e03c..c36d5a34f 100644
--- a/nova/tests/cloud_unittest.py
+++ b/nova/tests/cloud_unittest.py
@@ -29,6 +29,7 @@ from nova import rpc
from nova import test
from nova import utils
from nova.auth import manager
+from nova.compute import power_state
from nova.endpoint import api
from nova.endpoint import cloud
@@ -94,7 +95,7 @@ class CloudTestCase(test.BaseTestCase):
rv = yield defer.succeed(time.sleep(1))
info = self.cloud._get_instance(instance['instance_id'])
logging.debug(info['state'])
- if info['state'] == node.Instance.RUNNING:
+ if info['state'] == power_state.RUNNING:
break
self.assert_(rv)
diff --git a/nova/virt/xenapi.py b/nova/virt/xenapi.py
index b44ac383a..1c6de4403 100644
--- a/nova/virt/xenapi.py
+++ b/nova/virt/xenapi.py
@@ -274,9 +274,19 @@ class XenAPIConnection(object):
def destroy(self, instance):
vm = yield self._lookup(instance.name)
if vm is None:
- raise Exception('instance not present %s' % instance.name)
- task = yield self._call_xenapi('Async.VM.destroy', vm)
- yield self._wait_for_task(task)
+ # Don't complain, just return. This lets us clean up instances
+ # that have already disappeared from the underlying platform.
+ defer.returnValue(None)
+ try:
+ task = yield self._call_xenapi('Async.VM.hard_shutdown', vm)
+ 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)
+ except Exception, exc:
+ logging.warn(exc)
def get_info(self, instance_id):
vm = self._lookup_blocking(instance_id)
@@ -330,9 +340,9 @@ class XenAPIConnection(object):
error_info)
deferred.errback(XenAPI.Failure(error_info))
#logging.debug('Polling task %s done.', task)
- except Exception, exn:
- logging.warn(exn)
- deferred.errback(exn)
+ except Exception, exc:
+ logging.warn(exc)
+ deferred.errback(exc)
@utils.deferredToThread
def _call_xenapi(self, method, *args):
@@ -358,21 +368,21 @@ class XenAPIConnection(object):
def _unwrap_plugin_exceptions(func, *args, **kwargs):
try:
return func(*args, **kwargs)
- except XenAPI.Failure, exn:
- logging.debug("Got exception: %s", exn)
- if (len(exn.details) == 4 and
- exn.details[0] == 'XENAPI_PLUGIN_EXCEPTION' and
- exn.details[2] == 'Failure'):
+ except XenAPI.Failure, exc:
+ logging.debug("Got exception: %s", exc)
+ if (len(exc.details) == 4 and
+ exc.details[0] == 'XENAPI_PLUGIN_EXCEPTION' and
+ exc.details[2] == 'Failure'):
params = None
try:
- params = eval(exn.details[3])
+ params = eval(exc.details[3])
except:
- raise exn
+ raise exc
raise XenAPI.Failure(params)
else:
raise
- except xmlrpclib.ProtocolError, exn:
- logging.debug("Got exception: %s", exn)
+ except xmlrpclib.ProtocolError, exc:
+ logging.debug("Got exception: %s", exc)
raise