From d2eb04cea6b7f0a669758fc1fba32e77a008a7eb Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 21 Dec 2010 11:42:25 -0600 Subject: PEP8 cleanup --- nova/virt/xenapi/vmops.py | 16 ++++++++-------- nova/virt/xenapi_conn.py | 30 +++++++++++++++--------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index a18eacf07..bedf131df 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -44,12 +44,12 @@ class VMOps(object): VMHelper.late_import() def list_instances(self): - """ List VM instances """ + """List VM instances""" return [self._session.get_xenapi().VM.get_name_label(vm) \ for vm in self._session.get_xenapi().VM.get_all()] def spawn(self, instance): - """ Create VM instance """ + """Create VM instance""" vm = VMHelper.lookup(self._session, instance.name) if vm is not None: raise Exception('Attempted to create non-unique name %s' % @@ -81,7 +81,7 @@ class VMOps(object): vm_ref) def reboot(self, instance): - """ Reboot VM instance """ + """Reboot VM instance""" instance_name = instance.name vm = VMHelper.lookup(self._session, instance_name) if vm is None: @@ -90,7 +90,7 @@ class VMOps(object): self._session.wait_for_task(task) def destroy(self, instance): - """ Destroy VM instance """ + """Destroy VM instance""" vm = VMHelper.lookup(self._session, instance.name) if vm is None: # Don't complain, just return. This lets us clean up instances @@ -127,7 +127,7 @@ class VMOps(object): callback(ret) def pause(self, instance, callback): - """ Pause VM instance """ + """Pause VM instance""" instance_name = instance.name vm = VMHelper.lookup(self._session, instance_name) if vm is None: @@ -136,7 +136,7 @@ class VMOps(object): self._wait_with_callback(task, callback) def unpause(self, instance, callback): - """ Unpause VM instance """ + """Unpause VM instance""" instance_name = instance.name vm = VMHelper.lookup(self._session, instance_name) if vm is None: @@ -145,7 +145,7 @@ class VMOps(object): self._wait_with_callback(task, callback) def get_info(self, instance_id): - """ Return data about VM instance """ + """Return data about VM instance""" vm = VMHelper.lookup_blocking(self._session, instance_id) if vm is None: raise Exception('instance not present %s' % instance_id) @@ -161,6 +161,6 @@ class VMOps(object): return VMHelper.compile_diagnostics(self._session, rec) def get_console_output(self, instance): - """ Return snapshot of console """ + """Return snapshot of console""" # TODO: implement this to fix pylint! return 'FAKE CONSOLE OUTPUT of instance' diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 21ed2cd65..3a9084d89 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -101,7 +101,7 @@ def get_connection(_): class XenAPIConnection(object): - """ A connection to XenServer or Xen Cloud Platform """ + """A connection to XenServer or Xen Cloud Platform""" def __init__(self, url, user, pw): session = XenAPISession(url, user, pw) @@ -109,31 +109,31 @@ class XenAPIConnection(object): self._volumeops = VolumeOps(session) def list_instances(self): - """ List VM instances """ + """List VM instances""" return self._vmops.list_instances() def spawn(self, instance): - """ Create VM instance """ + """Create VM instance""" self._vmops.spawn(instance) def reboot(self, instance): - """ Reboot VM instance """ + """Reboot VM instance""" self._vmops.reboot(instance) def destroy(self, instance): - """ Destroy VM instance """ + """Destroy VM instance""" self._vmops.destroy(instance) def pause(self, instance, callback): - """ Pause VM instance """ + """Pause VM instance""" self._vmops.pause(instance, callback) def unpause(self, instance, callback): - """ Unpause paused VM instance """ + """Unpause paused VM instance""" self._vmops.unpause(instance, callback) def get_info(self, instance_id): - """ Return data about VM instance """ + """Return data about VM instance""" return self._vmops.get_info(instance_id) def get_diagnostics(self, instance_id): @@ -141,33 +141,33 @@ class XenAPIConnection(object): return self._vmops.get_diagnostics(instance_id) def get_console_output(self, instance): - """ Return snapshot of console """ + """Return snapshot of console""" return self._vmops.get_console_output(instance) def attach_volume(self, instance_name, device_path, mountpoint): - """ Attach volume storage to VM instance """ + """Attach volume storage to VM instance""" return self._volumeops.attach_volume(instance_name, device_path, mountpoint) def detach_volume(self, instance_name, mountpoint): - """ Detach volume storage to VM instance """ + """Detach volume storage to VM instance""" return self._volumeops.detach_volume(instance_name, mountpoint) class XenAPISession(object): - """ The session to invoke XenAPI SDK calls """ + """The session to invoke XenAPI SDK calls""" def __init__(self, url, user, pw): self._session = XenAPI.Session(url) self._session.login_with_password(user, pw) def get_xenapi(self): - """ Return the xenapi object """ + """Return the xenapi object""" return self._session.xenapi def get_xenapi_host(self): - """ Return the xenapi host """ + """Return the xenapi host""" return self._session.xenapi.session.get_this_host(self._session.handle) def call_xenapi(self, method, *args): @@ -218,7 +218,7 @@ class XenAPISession(object): def _unwrap_plugin_exceptions(func, *args, **kwargs): - """ Parse exception details """ + """Parse exception details""" try: return func(*args, **kwargs) except XenAPI.Failure, exc: -- cgit From b3fce81e384aec46c0963db1f144cc58d02340a4 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 21 Dec 2010 14:13:18 -0600 Subject: Log all XenAPI actions --- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 12 ++++++++++++ nova/db/sqlalchemy/models.py | 1 - nova/virt/xenapi/vmops.py | 16 ++++++++-------- nova/virt/xenapi_conn.py | 33 +++++++++++++++++++++++---------- 5 files changed, 48 insertions(+), 19 deletions(-) diff --git a/nova/db/api.py b/nova/db/api.py index 8f9dc2443..4e15596d9 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -334,6 +334,11 @@ def instance_add_security_group(context, instance_id, security_group_id): security_group_id) +def instance_action_create(context, values): + """Create an instance action from the values dictionary.""" + return IMPL.instance_action_create(context, values) + + ################### diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 935063609..63b367d2e 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -749,6 +749,18 @@ def instance_add_security_group(context, instance_id, security_group_id): instance_ref.save(session=session) +@require_context +def instance_action_create(context, values): + """Create an instance action and the action results""" + action_ref = models.InstanceActions() + action_ref.update(values) + + session = get_session() + with session.begin(): + action_ref.save(session=session) + return action_ref + + ################### diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index 96d981571..eac6a304e 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -248,7 +248,6 @@ class InstanceActions(BASE, NovaBase): instance_id = Column(Integer, ForeignKey('instances.id')) action = Column(String(255)) - result = Column(Boolean) error = Column(Text) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index bedf131df..5b9495b67 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -87,7 +87,7 @@ class VMOps(object): if vm is None: raise Exception('instance not present %s' % instance_name) task = self._session.call_xenapi('Async.VM.clean_reboot', vm) - self._session.wait_for_task(task) + self._session.wait_for_task(instance.id, task) def destroy(self, instance): """Destroy VM instance""" @@ -101,7 +101,7 @@ class VMOps(object): try: task = self._session.call_xenapi('Async.VM.hard_shutdown', vm) - self._session.wait_for_task(task) + self._session.wait_for_task(instance.id, task) except XenAPI.Failure, exc: logging.warn(exc) # Disk clean-up @@ -109,19 +109,19 @@ class VMOps(object): for vdi in vdis: try: task = self._session.call_xenapi('Async.VDI.destroy', vdi) - self._session.wait_for_task(task) + self._session.wait_for_task(instance.id, task) except XenAPI.Failure, exc: logging.warn(exc) try: task = self._session.call_xenapi('Async.VM.destroy', vm) - self._session.wait_for_task(task) + self._session.wait_for_task(instance.id, task) except XenAPI.Failure, exc: logging.warn(exc) - def _wait_with_callback(self, task, callback): + def _wait_with_callback(self, instance_id, task, callback): ret = None try: - ret = self._session.wait_for_task(task) + ret = self._session.wait_for_task(instance_id, task) except XenAPI.Failure, exc: logging.warn(exc) callback(ret) @@ -133,7 +133,7 @@ class VMOps(object): if vm is None: raise Exception('instance not present %s' % instance_name) task = self._session.call_xenapi('Async.VM.pause', vm) - self._wait_with_callback(task, callback) + self._wait_with_callback(instance.id, task, callback) def unpause(self, instance, callback): """Unpause VM instance""" @@ -142,7 +142,7 @@ class VMOps(object): if vm is None: raise Exception('instance not present %s' % instance_name) task = self._session.call_xenapi('Async.VM.unpause', vm) - self._wait_with_callback(task, callback) + self._wait_with_callback(instance.id, task, callback) def get_info(self, instance_id): """Return data about VM instance""" diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 3a9084d89..33a55d7b2 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -54,6 +54,8 @@ import xmlrpclib from eventlet import event from eventlet import tpool +from nova import context +from nova import db from nova import utils from nova import flags from nova.virt.xenapi.vmops import VMOps @@ -183,35 +185,46 @@ class XenAPISession(object): self._session.xenapi.Async.host.call_plugin, self.get_xenapi_host(), plugin, fn, args) - def wait_for_task(self, task): + def wait_for_task(self, instance_id, task): """Return a Deferred that will give the result of the given task. The task is polled until it completes.""" done = event.Event() - loop = utils.LoopingCall(self._poll_task, task, done) + loop = utils.LoopingCall(self._poll_task, instance_id, task, done) loop.start(FLAGS.xenapi_task_poll_interval, now=True) rv = done.wait() loop.stop() return rv - def _poll_task(self, task, done): + def _poll_task(self, instance_id, task, done): """Poll the given XenAPI task, and fire the given Deferred if we get a result.""" try: - #logging.debug('Polling task %s...', task) + name = self._session.xenapi.task.get_name_label(task) status = self._session.xenapi.task.get_status(task) - if status == 'pending': + action = dict( + instance_id=int(instance_id), + action=name, + error=None) + if status == "pending": return - elif status == 'success': + elif status == "success": result = self._session.xenapi.task.get_result(task) - logging.info('Task %s status: success. %s', task, result) + logging.info("Task [%s] %s status: success %s" % ( + name, + task, + result)) done.send(_parse_xmlrpc_value(result)) else: error_info = self._session.xenapi.task.get_error_info(task) - logging.warn('Task %s status: %s. %s', task, status, - error_info) + action["error"] = str(error_info) + logging.warn("Task [%s] %s status: %s %s" % ( + name, + task, + status, + error_info)) done.send_exception(XenAPI.Failure(error_info)) - #logging.debug('Polling task %s done.', task) + db.instance_action_create(context.get_admin_context(), action) except XenAPI.Failure, exc: logging.warn(exc) done.send_exception(*sys.exc_info()) -- cgit From 7da5fdf45add8e5c049321c5553f98229446e6b9 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 21 Dec 2010 14:28:20 -0600 Subject: PEP8 cleanup --- nova/db/sqlalchemy/api.py | 2 +- nova/tests/virt_unittest.py | 46 +++++++++++++++++++++++---------------------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 63b367d2e..f409560cf 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -751,7 +751,7 @@ def instance_add_security_group(context, instance_id, security_group_id): @require_context def instance_action_create(context, values): - """Create an instance action and the action results""" + """Create an instance action from the values dictionary.""" action_ref = models.InstanceActions() action_ref.update(values) diff --git a/nova/tests/virt_unittest.py b/nova/tests/virt_unittest.py index 9bbba4ba9..0cf016380 100644 --- a/nova/tests/virt_unittest.py +++ b/nova/tests/virt_unittest.py @@ -129,43 +129,45 @@ class LibvirtConnTestCase(test.TestCase): check_list.append(check) else: if expect_kernel: - check = (lambda t: t.find('./os/kernel').text.split('/' - )[1], 'kernel') + check = (lambda t: t.find('./os/kernel').text.split( + '/')[1], 'kernel') else: check = (lambda t: t.find('./os/kernel'), None) check_list.append(check) if expect_ramdisk: - check = (lambda t: t.find('./os/initrd').text.split('/' - )[1], 'ramdisk') + check = (lambda t: t.find('./os/initrd').text.split( + '/')[1], 'ramdisk') else: check = (lambda t: t.find('./os/initrd'), None) check_list.append(check) common_checks = [ (lambda t: t.find('.').tag, 'domain'), - (lambda t: t.find('./devices/interface/filterref/parameter' - ).get('name'), 'IP'), - (lambda t: t.find('./devices/interface/filterref/parameter' - ).get('value'), '10.11.12.13'), - (lambda t: t.findall('./devices/interface/filterref/parameter' - )[1].get('name'), 'DHCPSERVER'), - (lambda t: t.findall('./devices/interface/filterref/parameter' - )[1].get('value'), '10.0.0.1'), - (lambda t: t.find('./devices/serial/source').get('path' - ).split('/')[1], 'console.log'), + (lambda t: t.find( + './devices/interface/filterref/parameter').get('name'), 'IP'), + (lambda t: t.find( + './devices/interface/filterref/parameter').get( + 'value'), '10.11.12.13'), + (lambda t: t.findall( + './devices/interface/filterref/parameter')[1].get( + 'name'), 'DHCPSERVER'), + (lambda t: t.findall( + './devices/interface/filterref/parameter')[1].get( + 'value'), '10.0.0.1'), + (lambda t: t.find('./devices/serial/source').get( + 'path').split('/')[1], 'console.log'), (lambda t: t.find('./memory').text, '2097152')] if rescue: - common_checks += [(lambda t: t.findall('./devices/disk/source' - )[0].get('file').split('/')[1], - 'rescue-disk'), - (lambda t: t.findall('./devices/disk/source' - )[1].get('file').split('/')[1], - 'disk')] + common_checks += [(lambda t: t.findall( + './devices/disk/source')[0].get('file').split('/')[1], + 'rescue-disk'), (lambda t: t.findall( + './devices/disk/source')[1].get( + 'file').split('/')[1], 'disk')] else: - common_checks += [(lambda t: t.findall('./devices/disk/source' - )[0].get('file').split('/')[1], + common_checks += [(lambda t: t.findall( + './devices/disk/source')[0].get('file').split('/')[1], 'disk')] for (libvirt_type, (expected_uri, checks)) in type_uri_map.iteritems(): -- cgit From 555bea30cddfd32c42b6d7453b5afd2e7fcfb7f2 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 21 Dec 2010 15:46:44 -0600 Subject: Filter templates and dom0 from list_instances() --- nova/virt/xenapi/vmops.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 5b9495b67..3b00ce8bf 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -45,8 +45,12 @@ class VMOps(object): def list_instances(self): """List VM instances""" - return [self._session.get_xenapi().VM.get_name_label(vm) \ - for vm in self._session.get_xenapi().VM.get_all()] + vms = [] + for vm in self._session.get_xenapi().VM.get_all(): + rec = self._session.get_xenapi().VM.get_record(vm) + if not rec["is_a_template"] and not rec["is_control_domain"]: + vms.append(rec["name_label"]) + return vms def spawn(self, instance): """Create VM instance""" -- cgit From 3b05f5b5b46dd58a891f2e4c7a15231ea44a3e46 Mon Sep 17 00:00:00 2001 From: Josh Kearney Date: Tue, 21 Dec 2010 15:56:12 -0600 Subject: Style correction --- nova/tests/virt_unittest.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nova/tests/virt_unittest.py b/nova/tests/virt_unittest.py index 0cf016380..cb35db1e1 100644 --- a/nova/tests/virt_unittest.py +++ b/nova/tests/virt_unittest.py @@ -160,11 +160,11 @@ class LibvirtConnTestCase(test.TestCase): (lambda t: t.find('./memory').text, '2097152')] if rescue: - common_checks += [(lambda t: t.findall( - './devices/disk/source')[0].get('file').split('/')[1], - 'rescue-disk'), (lambda t: t.findall( - './devices/disk/source')[1].get( - 'file').split('/')[1], 'disk')] + common_checks += [ + (lambda t: t.findall('./devices/disk/source')[0].get( + 'file').split('/')[1], 'rescue-disk'), + (lambda t: t.findall('./devices/disk/source')[1].get( + 'file').split('/')[1], 'disk')] else: common_checks += [(lambda t: t.findall( './devices/disk/source')[0].get('file').split('/')[1], -- cgit From 56856ac1103ec9f3ba0f2da81832a59e7e773256 Mon Sep 17 00:00:00 2001 From: "jaypipes@gmail.com" <> Date: Wed, 22 Dec 2010 11:12:20 -0500 Subject: Fix doc building endpoint for gettext. --- doc/ext/nova_autodoc.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/ext/nova_autodoc.py b/doc/ext/nova_autodoc.py index 39aa2c2cf..5429bb656 100644 --- a/doc/ext/nova_autodoc.py +++ b/doc/ext/nova_autodoc.py @@ -1,5 +1,8 @@ +import gettext import os +gettext.install('nova') + from nova import utils def setup(app): -- cgit