From 20113ae3dcb4b7cd914a0e0862240b08bb855735 Mon Sep 17 00:00:00 2001 From: sateesh Date: Tue, 22 Feb 2011 21:14:58 +0530 Subject: Updated import statements according to HACKING guidelines. Added docstrings to each document. Verified pep8 over all files. Replaced some constants by enums accordingly. Still little bit more left in vm_util.py and vim_util.py files. --- nova/virt/vmwareapi/__init__.py | 16 +++++++++++++ nova/virt/vmwareapi/io_util.py | 21 ++++++++++++----- nova/virt/vmwareapi/read_write_util.py | 14 ++++++++++-- nova/virt/vmwareapi/vim.py | 8 ++++++- nova/virt/vmwareapi/vim_util.py | 2 ++ nova/virt/vmwareapi/vm_util.py | 5 +++++ nova/virt/vmwareapi/vmops.py | 9 +++++--- nova/virt/vmwareapi/vmware_images.py | 21 ++++++++++------- nova/virt/vmwareapi_conn.py | 41 +++++++++++++++++++++++++++++----- 9 files changed, 112 insertions(+), 25 deletions(-) diff --git a/nova/virt/vmwareapi/__init__.py b/nova/virt/vmwareapi/__init__.py index e9c06d96a..52e3ddf4d 100644 --- a/nova/virt/vmwareapi/__init__.py +++ b/nova/virt/vmwareapi/__init__.py @@ -14,3 +14,19 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. + +""" +:mod:`vmwareapi` -- Nova support for VMware ESX/ESXi Server through vSphere API +=============================================================================== +""" + + +class HelperBase(object): + """ + The base for helper classes. This adds the VMwareAPI class attribute + """ + + VMwareAPI = None + + def __init__(self): + return diff --git a/nova/virt/vmwareapi/io_util.py b/nova/virt/vmwareapi/io_util.py index 48ea4debf..3b3cbee33 100644 --- a/nova/virt/vmwareapi/io_util.py +++ b/nova/virt/vmwareapi/io_util.py @@ -16,15 +16,24 @@ # under the License. """ - Reads a chunk from input file and writes the same to the output file till - it reaches the transferable size. +Helper classes for multi-threaded I/O (read/write) in the basis of chunks. + +The class ThreadSafePipe queues the chunk data. + +The class IOThread reads chunks from input file and pipes it to output file +till it reaches the transferable size + """ -from Queue import Queue, Full, Empty +from Queue import Empty +from Queue import Full +from Queue import Queue from threading import Thread import time import traceback +THREAD_SLEEP_TIME = .01 + class ThreadSafePipe(Queue): """ @@ -122,12 +131,12 @@ class IOThread(Thread): # no more data in read break #Restrict tight loop - time.sleep(.01) + time.sleep(THREAD_SLEEP_TIME) except Full: # Pipe full while writing to pipe - safe to retry since #chunk is preserved #Restrict tight loop - time.sleep(.01) + time.sleep(THREAD_SLEEP_TIME) if isinstance(self.output_file, ThreadSafePipe): # If this is the reader thread, send eof signal self.output_file.set_eof(True) @@ -137,7 +146,7 @@ class IOThread(Thread): raise IOError("Not enough data (%d of %d bytes)" \ % (self.read_size, self.transfer_size)) - except: + except Exception: self._error = True self._exception = str(traceback.format_exc()) self._done = True diff --git a/nova/virt/vmwareapi/read_write_util.py b/nova/virt/vmwareapi/read_write_util.py index c3eeb0566..fcd95308a 100644 --- a/nova/virt/vmwareapi/read_write_util.py +++ b/nova/virt/vmwareapi/read_write_util.py @@ -15,6 +15,16 @@ # License for the specific language governing permissions and limitations # under the License. +""" Image file handlers + +Collection of classes to handle image upload/download to/from Image service +(like Glance image storage and retrieval service) from/to ESX/ESXi server. + +Also a class is available that acts as Fake image service. It uses local +file system for storage. + +""" + import httplib import json import logging @@ -84,7 +94,7 @@ class ImageServiceFile: """ try: self.file_handle.close() - except: + except Exception: pass def get_image_properties(self): @@ -267,7 +277,7 @@ class VMwareHTTPFile(object): """ try: self.file_handle.close() - except: + except Exception: pass def __del__(self): diff --git a/nova/virt/vmwareapi/vim.py b/nova/virt/vmwareapi/vim.py index 03439a049..3007535dd 100644 --- a/nova/virt/vmwareapi/vim.py +++ b/nova/virt/vmwareapi/vim.py @@ -15,9 +15,15 @@ # License for the specific language governing permissions and limitations # under the License. -import ZSI +""" +Class facilitating SOAP calls to ESX/ESXi server + +""" + import httplib +import ZSI + from nova.virt.vmwareapi import VimService_services RESP_NOT_XML_ERROR = 'Response is "text/html", not "text/xml' diff --git a/nova/virt/vmwareapi/vim_util.py b/nova/virt/vmwareapi/vim_util.py index 8596a1004..d38d8b949 100644 --- a/nova/virt/vmwareapi/vim_util.py +++ b/nova/virt/vmwareapi/vim_util.py @@ -17,7 +17,9 @@ """ The VMware API utility module + """ + from nova.virt.vmwareapi.VimService_services_types import ns0 MAX_CLONE_RETRIES = 1 diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index 603537278..b1202f2b1 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -15,6 +15,11 @@ # License for the specific language governing permissions and limitations # under the License. +""" +Utility functions to handle virtual disks, virtual network adapters, VMs etc. + +""" + from nova.virt.vmwareapi.VimService_services_types import ns0 diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 23247a54e..4eda4ef0e 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -15,6 +15,10 @@ # License for the specific language governing permissions and limitations # under the License. +""" +Class for VM tasks like spawn, snapshot, suspend, resume etc. + +""" import logging import os import time @@ -23,7 +27,6 @@ import uuid from nova import db from nova import context from nova.compute import power_state - from nova.virt.vmwareapi import vim_util from nova.virt.vmwareapi import vm_util from nova.virt.vmwareapi import vmware_images @@ -102,8 +105,8 @@ class VMWareVMOps(object): 'but that already exists on the host' % instance.name) bridge = db.network_get_by_instance(context.get_admin_context(), instance['id'])['bridge'] - #TODO: Shouldn't we consider any public network in case the network - #name supplied isn't there + #TODO(sateesh): Shouldn't we consider any public network in case + #the network name supplied isn't there network_ref = \ self._get_network_with_the_name(bridge) if network_ref is None: diff --git a/nova/virt/vmwareapi/vmware_images.py b/nova/virt/vmwareapi/vmware_images.py index aa3b263cd..d3b1dc446 100644 --- a/nova/virt/vmwareapi/vmware_images.py +++ b/nova/virt/vmwareapi/vmware_images.py @@ -15,12 +15,16 @@ # License for the specific language governing permissions and limitations # under the License. -import time -import os +""" +Utility functions to handle vm images. Also include fake image handlers. + +""" + import logging +import os +import time from nova import flags - from nova.virt.vmwareapi import read_write_util from nova.virt.vmwareapi import io_util @@ -31,6 +35,7 @@ READ_CHUNKSIZE = 2 * 1024 * 1024 WRITE_CHUNKSIZE = 2 * 1024 * 1024 LOG = logging.getLogger("nova.virt.vmwareapi.vmware_images") +TEST_IMAGE_PATH = "/tmp/vmware-test-images" def start_transfer(read_file_handle, write_file_handle, data_size): @@ -148,7 +153,7 @@ def _get_fake_image(image, instance, **kwargs): """ LOG.debug("Downloading image %s from fake image service" % image) image = str(image) - file_path = os.path.join("/tmp/vmware-test-images", image, image) + file_path = os.path.join(TEST_IMAGE_PATH, image, image) file_path = os.path.abspath(file_path) read_file_handle = read_write_util.FakeFileRead(file_path) file_size = read_file_handle.get_size() @@ -215,9 +220,9 @@ def _put_fake_image(image, instance, **kwargs): kwargs.get("file_path")) file_size = read_file_handle.get_size() image = str(image) - image_dir_path = os.path.join("/tmp/vmware-test-images", image) - if not os.path.exists("/tmp/vmware-test-images"): - os.mkdir("/tmp/vmware-test-images") + image_dir_path = os.path.join(TEST_IMAGE_PATH, image) + if not os.path.exists(TEST_IMAGE_PATH): + os.mkdir(TEST_IMAGE_PATH) os.mkdir(image_dir_path) else: if not os.path.exists(image_dir_path): @@ -247,7 +252,7 @@ def get_vmdk_size_and_properties(image, instance): raise NotImplementedError elif FLAGS.image_service == "nova.FakeImageService": image = str(image) - file_path = os.path.join("/tmp/vmware-test-images", image, image) + file_path = os.path.join(TEST_IMAGE_PATH, image, image) file_path = os.path.abspath(file_path) read_file_handle = read_write_util.FakeFileRead(file_path) size = read_file_handle.get_size() diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index d53a1c129..421efe91c 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -15,6 +15,23 @@ # License for the specific language governing permissions and limitations # under the License. +""" +Connection class for VMware Infrastructure API in VMware ESX/ESXi platform + +Encapsulates the session management activties and acts as interface for VI API. +The connection class sets up a session with the ESX/ESXi compute provider host +and handles all the calls made to the host. + +**Related Flags** + +:vmwareapi_host_ip: IP of VMware ESX/ESXi compute provider host +:vmwareapi_host_username: ESX/ESXi server user to be used for API session +:vmwareapi_host_password: Password for the user "vmwareapi_host_username" +:vmwareapi_task_poll_interval: The interval used for polling of remote tasks +:vmwareapi_api_retry_count: Max number of retry attempts upon API failures + +""" + import logging import time import urlparse @@ -58,6 +75,19 @@ flags.DEFINE_float('vmwareapi_api_retry_count', TIME_BETWEEN_API_CALL_RETRIES = 2.0 +class TaskState: + """ + Enumeration class for different states of task + 0 - Task completed successfully + 1 - Task is in queued state + 2 - Task is in running state + """ + + TASK_SUCCESS = 0 + TASK_QUEUED = 1 + TASK_RUNNING = 2 + + class Failure(Exception): """ Base Exception class for handling task failures @@ -278,7 +308,7 @@ class VMWareAPISession(object): # ESX host try: self.vim.Logout(self.vim.get_service_content().SessionManager) - except: + except Exception: pass def _call_method(self, module, method, *args, **kwargs): @@ -363,17 +393,18 @@ class VMWareAPISession(object): instance_id=int(instance_id), action=task_name[0:255], error=None) - if task_info.State in ['queued', 'running']: + if task_info.State in [TaskState.TASK_QUEUED, + TaskState.TASK_RUNNING]: return - elif task_info.State == 'success': + elif task_info.State == TaskState.TASK_SUCCESS: LOG.info("Task [%s] %s status: success " % ( task_name, str(task_ref))) - done.send("success") + done.send(TaskState.TASK_SUCCESS) else: error_info = str(task_info.Error.LocalizedMessage) action["error"] = error_info - LOG.warn("Task [%s] %s status: error %s" % ( + LOG.warn("Task [%s] %s status: error [%s]" % ( task_name, str(task_ref), error_info)) -- cgit