소스 검색

Refactored - added support for objects with lifecycles.

nuwan_ag 10 년 전
부모
커밋
4b55b1a977

+ 43 - 47
cloudbridge/providers/base.py

@@ -8,12 +8,12 @@ import time
 from cloudbridge.providers.interfaces import CloudProvider
 from cloudbridge.providers.interfaces import CloudProvider
 from cloudbridge.providers.interfaces import Instance
 from cloudbridge.providers.interfaces import Instance
 from cloudbridge.providers.interfaces import InstanceState
 from cloudbridge.providers.interfaces import InstanceState
-from cloudbridge.providers.interfaces import InstanceWaitException
 from cloudbridge.providers.interfaces import KeyPair
 from cloudbridge.providers.interfaces import KeyPair
 from cloudbridge.providers.interfaces import MachineImage
 from cloudbridge.providers.interfaces import MachineImage
 from cloudbridge.providers.interfaces import MachineImageState
 from cloudbridge.providers.interfaces import MachineImageState
-from cloudbridge.providers.interfaces import MachineImageWaitException
+from cloudbridge.providers.interfaces import ObjectLifeCycleMixin
 from cloudbridge.providers.interfaces import SecurityGroup
 from cloudbridge.providers.interfaces import SecurityGroup
+from cloudbridge.providers.interfaces import WaitStateException
 
 
 
 
 log = logging.getLogger(__name__)
 log = logging.getLogger(__name__)
@@ -62,18 +62,29 @@ class BaseCloudProvider(CloudProvider):
             return self.config.get(key, default_value)
             return self.config.get(key, default_value)
         else:
         else:
             return getattr(self.config, key) if hasattr(
             return getattr(self.config, key) if hasattr(
-                self.config, key) and getattr(self.config, key) else default_value
-
-
-class BaseInstance(Instance):
-
+                self.config, key) and getattr(self.config, key) else \
+                default_value
+
+
+class BaseObjectLifeCycleMixin(ObjectLifeCycleMixin):
+    """
+    A base implementation of an ObjectLifeCycleMixin.
+    This base implementation has an implementation of wait_till_ready
+    which refreshes the object's state till the desired ready states
+    are reached. Subclasses must implement two new properties - ready_states
+    and terminal_states, which return a list of states to wait for.
+    """
     @property
     @property
     def ready_states(self):
     def ready_states(self):
-        return [InstanceState.RUNNING]
+        raise NotImplementedError(
+            "ready_states not implemented by this object. Subclasses must"
+            " implement this method and return a valid set of ready states")
 
 
     @property
     @property
     def terminal_states(self):
     def terminal_states(self):
-        return [InstanceState.TERMINATED, InstanceState.ERROR]
+        raise NotImplementedError(
+            "terminal_states not implemented by this object. Subclasses must"
+            " implement this method and return a valid set of terminal states")
 
 
     def wait_till_ready(self, timeout=600, interval=5):
     def wait_till_ready(self, timeout=600, interval=5):
         assert timeout > 0
         assert timeout > 0
@@ -81,62 +92,47 @@ class BaseInstance(Instance):
         assert interval > 0
         assert interval > 0
 
 
         for time_left in range(timeout, 0, -interval):
         for time_left in range(timeout, 0, -interval):
-            state = self.instance_state
-            if state in self.ready_states:
+            if self.state in self.ready_states:
                 return True
                 return True
-            elif state in self.terminal_states:
-                raise InstanceWaitException(
-                    "Instance is in state: {0} which is a terminal state and cannot be waited on.".format(state))
+            elif self.state in self.terminal_states:
+                raise WaitStateException(
+                    "Object: {0} is in state: {1} which is a terminal state"
+                    " and cannot be waited on.".format(self, self.state))
             else:
             else:
                 log.debug(
                 log.debug(
-                    "Instance is in state '{0}'. Waiting another {1} seconds to reach state a ready state...".format(
-                        state,
+                    "Object {0} is in state: {1}. Waiting another {2} seconds"
+                    " to reach state a ready state...".format(
+                        self,
+                        self.state,
                         time_left))
                         time_left))
                 time.sleep(interval)
                 time.sleep(interval)
             self.refresh()
             self.refresh()
 
 
-        raise InstanceWaitException(
-            "Waited too long for instance to become ready. Instance Id: %s is in state: %s".format(
-                self.instance_id,
-                self.name,
-                self.instance_state))
+        raise WaitStateException("Waited too long for object: {0} to become"
+                                 " ready. It's still  in state: {1}".format(
+                                     self, self.state))
 
 
 
 
-class BaseMachineImage(MachineImage):
+class BaseInstance(BaseObjectLifeCycleMixin, Instance):
 
 
     @property
     @property
     def ready_states(self):
     def ready_states(self):
-        return [MachineImageState.AVAILABLE]
+        return [InstanceState.RUNNING]
 
 
     @property
     @property
     def terminal_states(self):
     def terminal_states(self):
-        return [MachineImageState.ERROR]
+        return [InstanceState.TERMINATED, InstanceState.ERROR]
 
 
-    def wait_till_ready(self, timeout=600, interval=5):
-        assert timeout > 0
-        assert timeout > interval
-        assert interval > 0
 
 
-        for time_left in range(timeout, 0, -interval):
-            state = self.image_state
-            if state in self.ready_states:
-                return True
-            elif state in self.terminal_states:
-                raise MachineImageWaitException(
-                    "Image is in state: {0} which is a terminal state and cannot be waited on.".format(state))
-            else:
-                log.debug(
-                    "Image is in state '{0}'. Waiting another {1} seconds to reach a ready state...".format(
-                        state,
-                        time_left))
-                time.sleep(interval)
-            self.refresh()
+class BaseMachineImage(BaseObjectLifeCycleMixin, MachineImage):
 
 
-        raise MachineImageWaitException(
-            "Waited too long for image to become ready. Image: {0}({1}) is still in state: {2}".format(
-                self.name,
-                self.image_id,
-                self.image_state))
+    @property
+    def ready_states(self):
+        return [MachineImageState.AVAILABLE]
+
+    @property
+    def terminal_states(self):
+        return [MachineImageState.ERROR]
 
 
 
 
 class BaseKeyPair(KeyPair):
 class BaseKeyPair(KeyPair):

+ 4 - 2
cloudbridge/providers/ec2/services.py

@@ -80,8 +80,10 @@ class EC2ComputeService(ComputeService):
     def __init__(self, provider):
     def __init__(self, provider):
         self.provider = provider
         self.provider = provider
 
 
-    def create_instance(self, name, image, instance_type, zone=None, keypair=None, security_groups=None,
-                        user_data=None, block_device_mapping=None, network_interfaces=None, **kwargs):
+    def create_instance(self, name, image, instance_type, zone=None,
+                        keypair=None, security_groups=None, user_data=None,
+                        block_device_mapping=None, network_interfaces=None,
+                        **kwargs):
         """
         """
         Creates a new virtual machine instance.
         Creates a new virtual machine instance.
         """
         """

+ 8 - 5
cloudbridge/providers/ec2/types.py

@@ -63,7 +63,7 @@ class EC2MachineImage(BaseMachineImage):
         self._ec2_image.deregister()
         self._ec2_image.deregister()
 
 
     @property
     @property
-    def image_state(self):
+    def state(self):
         return EC2MachineImage.IMAGE_STATE_MAP.get(
         return EC2MachineImage.IMAGE_STATE_MAP.get(
             self._ec2_image.state, MachineImageState.UNKNOWN)
             self._ec2_image.state, MachineImageState.UNKNOWN)
 
 
@@ -72,7 +72,8 @@ class EC2MachineImage(BaseMachineImage):
         Refreshes the state of this instance by re-querying the cloud provider
         Refreshes the state of this instance by re-querying the cloud provider
         for its latest state.
         for its latest state.
         """
         """
-        self._ec2_image = self.provider.images.get_image(self.image_id)._ec2_image
+        self._ec2_image = self.provider.images.get_image(
+            self.image_id)._ec2_image
 
 
 
 
 class EC2InstanceType(InstanceType):
 class EC2InstanceType(InstanceType):
@@ -94,7 +95,8 @@ class EC2InstanceType(InstanceType):
 
 
 class EC2Instance(BaseInstance):
 class EC2Instance(BaseInstance):
 
 
-    # ref: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-lifecycle.html
+    # ref:
+    # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-lifecycle.html
     INSTANCE_STATE_MAP = {
     INSTANCE_STATE_MAP = {
         'pending': InstanceState.PENDING,
         'pending': InstanceState.PENDING,
         'running': InstanceState.RUNNING,
         'running': InstanceState.RUNNING,
@@ -190,7 +192,8 @@ class EC2Instance(BaseInstance):
         """
         """
         Get the security group IDs associated with this instance.
         Get the security group IDs associated with this instance.
         """
         """
-        return [BaseSecurityGroup(group.name) for group in self._ec2_instance.groups]
+        return [BaseSecurityGroup(group.name)
+                for group in self._ec2_instance.groups]
 
 
     @property
     @property
     def key_pair_name(self):
     def key_pair_name(self):
@@ -208,7 +211,7 @@ class EC2Instance(BaseInstance):
         return EC2MachineImage(self.provider, image)
         return EC2MachineImage(self.provider, image)
 
 
     @property
     @property
-    def instance_state(self):
+    def state(self):
         return EC2Instance.INSTANCE_STATE_MAP.get(
         return EC2Instance.INSTANCE_STATE_MAP.get(
             self._ec2_instance.state, InstanceState.UNKNOWN)
             self._ec2_instance.state, InstanceState.UNKNOWN)
 
 

+ 2 - 14
cloudbridge/providers/interfaces/__init__.py

@@ -1,15 +1,7 @@
 """
 """
 Public interface exports
 Public interface exports
 """
 """
-
-"""
-Core implementation of a cloud provider
-"""
 from .impl import CloudProvider
 from .impl import CloudProvider
-
-"""
-Optional services offered by a cloud provider
-"""
 from .services import ComputeService
 from .services import ComputeService
 from .services import ImageService
 from .services import ImageService
 from .services import InstanceTypesService
 from .services import InstanceTypesService
@@ -17,21 +9,17 @@ from .services import ObjectStoreService
 from .services import ProviderService
 from .services import ProviderService
 from .services import SecurityService
 from .services import SecurityService
 from .services import VolumeService
 from .services import VolumeService
-
-"""
-Data objects returned by cloud provider services
-"""
 from .types import CloudProviderServiceType
 from .types import CloudProviderServiceType
 from .types import Instance
 from .types import Instance
 from .types import InstanceState
 from .types import InstanceState
 from .types import InstanceType
 from .types import InstanceType
-from .types import InstanceWaitException
 from .types import KeyPair
 from .types import KeyPair
 from .types import MachineImage
 from .types import MachineImage
 from .types import MachineImageState
 from .types import MachineImageState
-from .types import MachineImageWaitException
+from .types import ObjectLifeCycleMixin
 from .types import PlacementZone
 from .types import PlacementZone
 from .types import Region
 from .types import Region
 from .types import SecurityGroup
 from .types import SecurityGroup
 from .types import Snapshot
 from .types import Snapshot
 from .types import Volume
 from .types import Volume
+from .types import WaitStateException

+ 2 - 2
cloudbridge/providers/interfaces/impl.py

@@ -11,8 +11,8 @@ class CloudProvider(object):
 
 
     def __init__(self, config):
     def __init__(self, config):
         """
         """
-        Create a new provider implementation given a dictionary of configuration
-        attributes.
+        Create a new provider implementation given a dictionary of
+        configuration attributes.
 
 
         :type config: an object with required fields
         :type config: an object with required fields
         :param config: This can be a Bunch or any other object whose fields can
         :param config: This can be a Bunch or any other object whose fields can

+ 10 - 5
cloudbridge/providers/interfaces/services.py

@@ -76,8 +76,10 @@ class ComputeService(ProviderService):
         raise NotImplementedError(
         raise NotImplementedError(
             'list_regions not implemented by this provider')
             'list_regions not implemented by this provider')
 
 
-    def create_instance(self, name, image, instance_type, zone=None, keypair=None, security_groups=None,
-                        user_data=None, block_device_mapping=None, network_interfaces=None, **kwargs):
+    def create_instance(self, name, image, instance_type, zone=None,
+                        keypair=None, security_groups=None, user_data=None,
+                        block_device_mapping=None, network_interfaces=None,
+                        **kwargs):
         """
         """
         Creates a new virtual machine instance.
         Creates a new virtual machine instance.
 
 
@@ -85,7 +87,8 @@ class ComputeService(ProviderService):
         :param name: The name of the virtual machine instance
         :param name: The name of the virtual machine instance
 
 
         :type  image: ``MachineImage`` or ``str``
         :type  image: ``MachineImage`` or ``str``
-        :param image: The MachineImage object or id to boot the virtual machine with
+        :param image: The MachineImage object or id to boot the virtual machine
+        with
 
 
         :type  instance_type: ``InstanceType`` or ``str``
         :type  instance_type: ``InstanceType`` or ``str``
         :param instance_type: The InstanceType or name, specifying the size of
         :param instance_type: The InstanceType or name, specifying the size of
@@ -95,7 +98,8 @@ class ComputeService(ProviderService):
         :param zone: The Zone or its name, where the instance should be placed.
         :param zone: The Zone or its name, where the instance should be placed.
 
 
         :type  keypair: ``KeyPair`` or ``str``
         :type  keypair: ``KeyPair`` or ``str``
-        :param keypair: The KeyPair object or its name, to set for the instance.
+        :param keypair: The KeyPair object or its name, to set for the
+        instance.
 
 
         :type  security_groups: A ``list`` of ``SecurityGroup`` objects or a
         :type  security_groups: A ``list`` of ``SecurityGroup`` objects or a
                                 list of ``str`` names
                                 list of ``str`` names
@@ -341,4 +345,5 @@ class InstanceTypesService(object):
         :return: an Instance object
         :return: an Instance object
         """
         """
         raise NotImplementedError(
         raise NotImplementedError(
-            'InstanceTypesService.find_instance not implemented by this provider')
+            'InstanceTypesService.find_instance not implemented by this'
+            'provider')

+ 66 - 80
cloudbridge/providers/interfaces/types.py

@@ -23,16 +23,74 @@ class CloudProviderServiceType(object):
     OBJECTSTORE = 'object_store'
     OBJECTSTORE = 'object_store'
 
 
 
 
-class InstanceWaitException(Exception):
+class WaitStateException(Exception):
 
 
     """
     """
-    Marker interface for instance wait exceptions.
-    Thrown when a timeout or errors occurs waiting for an instance to reach
-    state RUNNING.
+    Marker interface for object wait exceptions.
+    Thrown when a timeout or errors occurs waiting for an object does not reach
+    the expected state within a specified time limit.
     """
     """
     pass
     pass
 
 
 
 
+class ObjectLifeCycleMixin(object):
+
+    """
+    A mixin for an object with a defined life-cycle, such as an Instance,
+    Volume, Image or Snapshot. An object that supports ObjectLifeCycleMixin
+    will always have a state, defining which point in its lifecycle it is
+    currently at.
+
+    It also defines a wait_till_ready operation, which indicates that the
+    object is in a state in its lifecycle where it is ready to be used by an
+    end-user.
+
+    A refresh operation allows the object to synchronise its state with the
+    service provider.
+    """
+    @property
+    def state(self):
+        """
+        Get the current state of this object.
+
+        :rtype: ``str``
+        :return: The current state as a string
+        """
+        raise NotImplementedError(
+            'LifeCycleObject.state not implemented by this service')
+
+    def refresh(self):
+        """
+        Refreshs this object's state and synchronize it with the underlying
+        service provider.
+        """
+        raise NotImplementedError(
+            'LifeCycleObject.refresh not implemented by this service')
+
+    def wait_till_ready(self, timeout, interval):
+        """
+        Wait till the current object is in a ready state, which is any
+        state where the end-user can successfully interact with the object.
+        Will throw a WaitStateException if the object is not ready within
+        the specified timeout.
+
+        :type timeout: int
+        :param timeout: The maximum length of time (in seconds) to wait for the
+        object to become ready.
+
+        :type interval: int
+        :param interval: How frequently to poll the object's ready state (in
+        seconds)
+
+        :rtype: ``True``
+        :return: Returns True if successful. A WaitStateException exception may
+        be thrown by the underlying service if the object cannot get into a
+        ready state (e.g. If the object is in an error state)
+        """
+        raise NotImplementedError(
+            'LifeCycleObject.wait_till_ready not implemented by this service')
+
+
 class InstanceState(object):
 class InstanceState(object):
 
 
     """
     """
@@ -58,7 +116,7 @@ class InstanceState(object):
     ERROR = "error"
     ERROR = "error"
 
 
 
 
-class Instance(object):
+class Instance(ObjectLifeCycleMixin):
 
 
     def instance_id(self):
     def instance_id(self):
         """
         """
@@ -110,16 +168,6 @@ class Instance(object):
         raise NotImplementedError(
         raise NotImplementedError(
             'Instance.instance_type not implemented by this provider')
             'Instance.instance_type not implemented by this provider')
 
 
-    def instance_state(self):
-        """
-        Get the current state of this instance.
-
-        :rtype: ``InstanceType``
-        :return: The instance state such as RUNNING, PENDING, TERMINATED etc.
-        """
-        raise NotImplementedError(
-            'Instance.instance_state not implemented by this provider')
-
     def reboot(self):
     def reboot(self):
         """
         """
         Reboot this instance (using the cloud middleware API).
         Reboot this instance (using the cloud middleware API).
@@ -191,24 +239,6 @@ class Instance(object):
         raise NotImplementedError(
         raise NotImplementedError(
             'Instance.key_pair_name not implemented by this provider')
             'Instance.key_pair_name not implemented by this provider')
 
 
-    def wait_till_ready(self, timeout=600, interval=5):
-        """
-        Wait until the instance is running or the timeout elapses.
-        Throws an exception if the instance reaches an error state.
-
-        :type timeout: int
-        :param timeout: Maximum timeout to wait before giving up
-
-        :type interval: int
-        :param interval: How frequently to poll instance state
-
-        :rtype: :bool
-        :return: True if instance is ready. False if the instance is
-        not ready within the specified timeout.
-        """
-        raise NotImplementedError(
-            'Instance.wait_till_ready not implemented by this provider')
-
     def create_image(self, name):
     def create_image(self, name):
         """
         """
         Create a new image based on this instance.
         Create a new image based on this instance.
@@ -218,24 +248,6 @@ class Instance(object):
         raise NotImplementedError(
         raise NotImplementedError(
             'Instance.create_image not implemented by this provider')
             'Instance.create_image not implemented by this provider')
 
 
-    def refresh(self):
-        """
-        Refreshes the state of this instance by re-querying the cloud provider
-        for its latest state.
-        """
-        raise NotImplementedError(
-            'Instance.refresh not implemented by this provider')
-
-
-class MachineImageWaitException(Exception):
-
-    """
-    Marker interface for image wait exceptions.
-    Thrown when a timeout or errors occurs waiting for an image to reach
-    state RUNNING.
-    """
-    pass
-
 
 
 class MachineImageState(object):
 class MachineImageState(object):
 
 
@@ -254,7 +266,7 @@ class MachineImageState(object):
     ERROR = "error"
     ERROR = "error"
 
 
 
 
-class MachineImage(object):
+class MachineImage(ObjectLifeCycleMixin):
 
 
     @property
     @property
     def image_id(self):
     def image_id(self):
@@ -299,34 +311,8 @@ class MachineImage(object):
         raise NotImplementedError(
         raise NotImplementedError(
             'MachineImage.delete not implemented by this provider')
             'MachineImage.delete not implemented by this provider')
 
 
-    def wait_till_ready(self, timeout=600, interval=5):
-        """
-        Wait until the image is running or the timeout elapses.
-        Throws an exception if the image reaches an error state.
-
-        :type timeout: int
-        :param timeout: Maximum timeout to wait before giving up
-
-        :type interval: int
-        :param interval: How frequently to poll image state
-
-        :rtype: :bool
-        :return: True if image is ready. False if the image is
-        not ready within the specified timeout.
-        """
-        raise NotImplementedError(
-            'Image.wait_till_ready not implemented by this provider')
-
-    def refresh(self):
-        """
-        Refreshes the state of this image by re-querying the cloud provider
-        for its latest state.
-        """
-        raise NotImplementedError(
-            'Image.refresh not implemented by this provider')
-
 
 
-class Volume(object):
+class Volume(ObjectLifeCycleMixin):
 
 
     def attach(self, instance_id, device):
     def attach(self, instance_id, device):
         """
         """
@@ -391,7 +377,7 @@ class Volume(object):
             'delete not implemented by this provider')
             'delete not implemented by this provider')
 
 
 
 
-class Snapshot(object):
+class Snapshot(ObjectLifeCycleMixin):
 
 
     def create_volume(self, placement, size=None, volume_type=None, iops=None):
     def create_volume(self, placement, size=None, volume_type=None, iops=None):
         """
         """

+ 1 - 1
cloudbridge/providers/openstack/__init__.py

@@ -4,4 +4,4 @@ Exports from this provider
 
 
 from .impl import OpenStackCloudProviderV1
 from .impl import OpenStackCloudProviderV1
 from .types import OpenStackInstance
 from .types import OpenStackInstance
-from .types import OpenStackInstanceType
+from .types import OpenStackInstanceType

+ 22 - 12
cloudbridge/providers/openstack/impl.py

@@ -1,5 +1,6 @@
 """
 """
-Provider implementation based on openstack python client for OpenStack compatible clouds.
+Provider implementation based on openstack python client for OpenStack
+compatible clouds.
 """
 """
 
 
 import os
 import os
@@ -23,11 +24,14 @@ class OpenStackCloudProviderV1(BaseCloudProvider):
 
 
         self.api_version = self._get_config_value(
         self.api_version = self._get_config_value(
             'api_version', os.environ.get('OS_COMPUTE_API_VERSION', 2))
             'api_version', os.environ.get('OS_COMPUTE_API_VERSION', 2))
-        self.username = self._get_config_value('username', os.environ.get('OS_USERNAME', None))
-        self.password = self._get_config_value('password', os.environ.get('OS_PASSWORD', None))
+        self.username = self._get_config_value(
+            'username', os.environ.get('OS_USERNAME', None))
+        self.password = self._get_config_value(
+            'password', os.environ.get('OS_PASSWORD', None))
         self.tenant_name = self._get_config_value(
         self.tenant_name = self._get_config_value(
             'tenant_name', os.environ.get('OS_TENANT_NAME', None))
             'tenant_name', os.environ.get('OS_TENANT_NAME', None))
-        self.auth_url = self._get_config_value('auth_url', os.environ.get('OS_AUTH_URL', None))
+        self.auth_url = self._get_config_value(
+            'auth_url', os.environ.get('OS_AUTH_URL', None))
 
 
         self.nova = self._connect_nova()
         self.nova = self._connect_nova()
         self.keystone = self._connect_keystone()
         self.keystone = self._connect_keystone()
@@ -43,18 +47,24 @@ class OpenStackCloudProviderV1(BaseCloudProvider):
         Get an openstack client object for the given cloud.
         Get an openstack client object for the given cloud.
         """
         """
         return nova_client.Client(
         return nova_client.Client(
-            self.api_version, self.username, self.password, self.tenant_name, self.auth_url)
+            self.api_version, self.username, self.password, self.tenant_name,
+            self.auth_url)
 
 
     def _connect_keystone(self):
     def _connect_keystone(self):
         """
         """
         Get an openstack client object for the given cloud.
         Get an openstack client object for the given cloud.
         """
         """
-        auth = Password(self.auth_url, username=self.username, password=self.password,
-                        tenant_name=self.tenant_name)
-        # Wow, the internal keystoneV2 implementation is terribly buggy. It needs both a separate Session object
-        # and the username, password again for things to work correctly. Plus, a manual call to authenticate() is
-        # also required if the service  catalogue needs to be queried
-        keystone = keystone_client.Client(session=session.Session(auth=auth), auth_url=self.auth_url, username=self.username,
-                                          password=self.password, tenant_name=self.tenant_name)
+        auth = Password(self.auth_url, username=self.username,
+                        password=self.password, tenant_name=self.tenant_name)
+        # Wow, the internal keystoneV2 implementation is terribly buggy. It
+        # needs both a separate Session object and the username, password again
+        # for things to work correctly. Plus, a manual call to authenticate()
+        # is also required if the service  catalogue needs to be queried
+        keystone = keystone_client.Client(
+            session=session.Session(auth=auth),
+            auth_url=self.auth_url,
+            username=self.username,
+            password=self.password,
+            tenant_name=self.tenant_name)
         keystone.authenticate()
         keystone.authenticate()
         return keystone
         return keystone

+ 17 - 14
cloudbridge/providers/openstack/services.py

@@ -97,15 +97,17 @@ class OpenStackComputeService(ComputeService):
         self.provider = provider
         self.provider = provider
         self.instance_types = OpenStackInstanceTypesService(self.provider)
         self.instance_types = OpenStackInstanceTypesService(self.provider)
 
 
-    def create_instance(self, name, image, instance_type, zone=None, keypair=None, security_groups=None,
-                        user_data=None, block_device_mapping=None, network_interfaces=None, **kwargs):
+    def create_instance(self, name, image, instance_type, zone=None,
+                        keypair=None, security_groups=None, user_data=None,
+                        block_device_mapping=None, network_interfaces=None,
+                        **kwargs):
         """
         """
         Creates a new virtual machine instance.
         Creates a new virtual machine instance.
         """
         """
         image_id = image.image_id if isinstance(image, MachineImage) else image
         image_id = image.image_id if isinstance(image, MachineImage) else image
-        instance_size = instance_type.name if isinstance(
-            instance_type,
-            InstanceType) else self.instance_types.find_by_name(instance_type).id
+        instance_size = instance_type.name if \
+            isinstance(instance_type, InstanceType) else \
+            self.instance_types.find_by_name(instance_type).id
         zone_name = zone.name if isinstance(zone, PlacementZone) else zone
         zone_name = zone.name if isinstance(zone, PlacementZone) else zone
         keypair_name = keypair.name if isinstance(
         keypair_name = keypair.name if isinstance(
             keypair,
             keypair,
@@ -119,15 +121,16 @@ class OpenStackComputeService(ComputeService):
         else:
         else:
             security_groups_list = None
             security_groups_list = None
 
 
-        os_instance = self.provider.nova.servers.create(name, image_id,
-                                                        instance_size,
-                                                        min_count=1,
-                                                        max_count=1,
-                                                        availability_zone=zone_name,
-                                                        key_name=keypair_name,
-                                                        security_groups=security_groups_list,
-                                                        userdata=user_data
-                                                        )
+        os_instance = self.provider.nova.servers.create(
+            name,
+            image_id,
+            instance_size,
+            min_count=1,
+            max_count=1,
+            availability_zone=zone_name,
+            key_name=keypair_name,
+            security_groups=security_groups_list,
+            userdata=user_data)
         return OpenStackInstance(self.provider, os_instance)
         return OpenStackInstance(self.provider, os_instance)
 
 
     def list_instances(self):
     def list_instances(self):

+ 8 - 5
cloudbridge/providers/openstack/types.py

@@ -68,7 +68,7 @@ class OpenStackMachineImage(BaseMachineImage):
         self._os_image.delete()
         self._os_image.delete()
 
 
     @property
     @property
-    def image_state(self):
+    def state(self):
         return OpenStackMachineImage.IMAGE_STATE_MAP.get(
         return OpenStackMachineImage.IMAGE_STATE_MAP.get(
             self._os_image.status, MachineImageState.UNKNOWN)
             self._os_image.status, MachineImageState.UNKNOWN)
 
 
@@ -207,7 +207,8 @@ class OpenStackInstance(BaseInstance):
         """
         """
         Get the security group IDs associated with this instance.
         Get the security group IDs associated with this instance.
         """
         """
-        return [BaseSecurityGroup(group.name) for group in self._os_instance.security_groups]
+        return [BaseSecurityGroup(group.name)
+                for group in self._os_instance.security_groups]
 
 
     @property
     @property
     def key_pair_name(self):
     def key_pair_name(self):
@@ -221,10 +222,11 @@ class OpenStackInstance(BaseInstance):
         Create a new image based on this instance.
         Create a new image based on this instance.
         """
         """
         image_id = self._os_instance.create_image(name)
         image_id = self._os_instance.create_image(name)
-        return OpenStackMachineImage(self.provider, self.provider.images.get_image(image_id))
+        return OpenStackMachineImage(
+            self.provider, self.provider.images.get_image(image_id))
 
 
     @property
     @property
-    def instance_state(self):
+    def state(self):
         return OpenStackInstance.INSTANCE_STATE_MAP.get(
         return OpenStackInstance.INSTANCE_STATE_MAP.get(
             self._os_instance.status, InstanceState.UNKNOWN)
             self._os_instance.status, InstanceState.UNKNOWN)
 
 
@@ -233,7 +235,8 @@ class OpenStackInstance(BaseInstance):
         Refreshes the state of this instance by re-querying the cloud provider
         Refreshes the state of this instance by re-querying the cloud provider
         for its latest state.
         for its latest state.
         """
         """
-        self._os_instance = self.provider.compute.get_instance(self.instance_id)._os_instance
+        self._os_instance = self.provider.compute.get_instance(
+            self.instance_id)._os_instance
 
 
 
 
 class OpenStackRegion(Region):
 class OpenStackRegion(Region):