You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2011/06/05 10:34:13 UTC

svn commit: r1132067 [4/9] - in /incubator/mesos/trunk: ec2/ third_party/boto-1.8d/ third_party/boto-1.8d/bin/ third_party/boto-1.8d/boto.egg-info/ third_party/boto-1.8d/boto/ third_party/boto-1.8d/boto/cloudfront/ third_party/boto-1.8d/boto/contrib/ t...

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/instance.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/instance.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/instance.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/instance.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/instance.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/instance.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/instance.py Sun Jun  5 08:34:02 2011
@@ -22,10 +22,12 @@
 """
 Represents an EC2 Instance
 """
-
+import boto
 from boto.ec2.ec2object import EC2Object
 from boto.resultset import ResultSet
 from boto.ec2.address import Address
+from boto.ec2.blockdevicemapping import BlockDeviceMapping
+from boto.ec2.image import ProductCodes
 import base64
 
 class Reservation(EC2Object):
@@ -76,15 +78,26 @@ class Instance(EC2Object):
         self.shutdown_state = None
         self.previous_state = None
         self.instance_type = None
+        self.instance_class = None
         self.launch_time = None
         self.image_id = None
         self.placement = None
         self.kernel = None
         self.ramdisk = None
-        self.product_codes = []
+        self.product_codes = ProductCodes()
         self.ami_launch_index = None
         self.monitored = False
+        self.instance_class = None
+        self.spot_instance_request_id = None
+        self.subnet_id = None
+        self.vpc_id = None
+        self.private_ip_address = None
+        self.ip_address = None
+        self.requester_id = None
         self._in_monitoring_element = False
+        self.persistent = False
+        self.root_device_name = None
+        self.block_device_mapping = None
 
     def __repr__(self):
         return 'Instance:%s' % self.id
@@ -92,6 +105,11 @@ class Instance(EC2Object):
     def startElement(self, name, attrs, connection):
         if name == 'monitoring':
             self._in_monitoring_element = True
+        elif name == 'blockDeviceMapping':
+            self.block_device_mapping = BlockDeviceMapping()
+            return self.block_device_mapping
+        elif name == 'productCodes':
+            return self.product_codes
         return None
 
     def endElement(self, name, value, connection):
@@ -115,9 +133,17 @@ class Instance(EC2Object):
         elif name == 'name':
             self.state = value
         elif name == 'code':
-            self.state_code = int(value)
+            try:
+                self.state_code = int(value)
+            except ValueError:
+                boto.log.warning('Error converting code (%s) to int' % value)
+                self.state_code = value
         elif name == 'instanceType':
             self.instance_type = value
+        elif name == 'instanceClass':
+            self.instance_class = value
+        elif name == 'rootDeviceName':
+            self.root_device_name = value
         elif name == 'launchTime':
             self.launch_time = value
         elif name == 'availabilityZone':
@@ -128,13 +154,30 @@ class Instance(EC2Object):
             self.kernel = value
         elif name == 'ramdiskId':
             self.ramdisk = value
-        elif name == 'productCode':
-            self.product_codes.append(value)
         elif name == 'state':
             if self._in_monitoring_element:
                 if value == 'enabled':
                     self.monitored = True
                 self._in_monitoring_element = False
+        elif name == 'instanceClass':
+            self.instance_class = value
+        elif name == 'spotInstanceRequestId':
+            self.spot_instance_request_id = value
+        elif name == 'subnetId':
+            self.subnet_id = value
+        elif name == 'vpcId':
+            self.vpc_id = value
+        elif name == 'privateIpAddress':
+            self.private_ip_address = value
+        elif name == 'ipAddress':
+            self.ip_address = value
+        elif name == 'requesterId':
+            self.requester_id = value
+        elif name == 'persistent':
+            if value == 'true':
+                self.persistent = True
+            else:
+                self.persistent = False
         else:
             setattr(self, name, value)
 
@@ -220,3 +263,18 @@ class ConsoleOutput:
             self.output = base64.b64decode(value)
         else:
             setattr(self, name, value)
+
+class InstanceAttribute(dict):
+
+    def __init__(self, parent=None):
+        dict.__init__(self)
+        self._current_value = None
+
+    def startElement(self, name, attrs, connection):
+        return None
+
+    def endElement(self, name, value, connection):
+        if name == 'value':
+            self._current_value = value
+        else:
+            self[name] = self._current_value

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/instanceinfo.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/instanceinfo.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/instanceinfo.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/instanceinfo.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/instanceinfo.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/keypair.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/keypair.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/keypair.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/keypair.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/keypair.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/keypair.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/keypair.py Sun Jun  5 08:34:02 2011
@@ -52,8 +52,8 @@ class KeyPair(EC2Object):
         """
         Delete the KeyPair.
         
-        @rtype: bool
-        @return: True if successful, otherwise False.
+        :rtype: bool
+        :return: True if successful, otherwise False.
         """
         return self.connection.delete_key_pair(self.name)
 
@@ -62,8 +62,8 @@ class KeyPair(EC2Object):
         Save the material (the unencrypted PEM encoded RSA private key)
         of a newly created KeyPair to a local file.
         
-        @type directory_path: string
-        @param directory_path: The fully qualified path to the directory
+        :type directory_path: string
+        :param directory_path: The fully qualified path to the directory
                                in which the keypair will be saved.  The
                                keypair file will be named using the name
                                of the keypair as the base name and .pem
@@ -72,8 +72,8 @@ class KeyPair(EC2Object):
                                exception will be raised and the old file
                                will not be overwritten.
         
-        @rtype: bool
-        @return: True if successful.
+        :rtype: bool
+        :return: True if successful.
         """
         if self.material:
             file_path = os.path.join(directory_path, '%s.pem' % self.name)
@@ -94,11 +94,11 @@ class KeyPair(EC2Object):
         you will need to save the material associated with the
         new key pair (use the save method) to a local file.
 
-        @type region: L{RegionInfo<boto.ec2.regioninfo.RegionInfo>}
-        @param region: The region to which this security group will be copied.
+        :type region: :class:`boto.ec2.regioninfo.RegionInfo`
+        :param region: The region to which this security group will be copied.
 
-        @rtype: L{KeyPair<boto.ec2.keypair.KeyPair>}
-        @return: The new key pair
+        :rtype: :class:`boto.ec2.keypair.KeyPair`
+        :return: The new key pair
         """
         if region.name == self.region:
             raise BotoClientError('Unable to copy to the same Region')

Added: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/launchspecification.py
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/launchspecification.py?rev=1132067&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/launchspecification.py (added)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/launchspecification.py Sun Jun  5 08:34:02 2011
@@ -0,0 +1,96 @@
+# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish, dis-
+# tribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the fol-
+# lowing conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+"""
+Represents a launch specification for Spot instances.
+"""
+
+from boto.ec2.ec2object import EC2Object
+from boto.resultset import ResultSet
+from boto.ec2.blockdevicemapping import BlockDeviceMapping
+from boto.ec2.instance import Group
+
+class GroupList(list):
+
+    def startElement(self, name, attrs, connection):
+        pass
+
+    def endElement(self, name, value, connection):
+        if name == 'groupId':
+            self.append(value)
+            
+class LaunchSpecification(EC2Object):
+    
+    def __init__(self, connection=None):
+        EC2Object.__init__(self, connection)
+        self.key_name = None
+        self.instance_type = None
+        self.image_id = None
+        self.groups = []
+        self.placement = None
+        self.kernel = None
+        self.ramdisk = None
+        self.monitored = False
+        self.subnet_id = None
+        self._in_monitoring_element = False
+        self.block_device_mapping = None
+
+    def __repr__(self):
+        return 'LaunchSpecification(%s)' % self.image_id
+
+    def startElement(self, name, attrs, connection):
+        if name == 'groupSet':
+            self.groups = ResultSet([('item', Group)])
+            return self.groups
+        elif name == 'monitoring':
+            self._in_monitoring_element = True
+        elif name == 'blockDeviceMapping':
+            self.block_device_mapping = BlockDeviceMapping()
+            return self.block_device_mapping
+        else:
+            return None
+
+    def endElement(self, name, value, connection):
+        if name == 'imageId':
+            self.image_id = value
+        elif name == 'keyName':
+            self.key_name = value
+        elif name == 'instanceType':
+            self.instance_type = value
+        elif name == 'availabilityZone':
+            self.placement = value
+        elif name == 'placement':
+            pass
+        elif name == 'kernelId':
+            self.kernel = value
+        elif name == 'ramdiskId':
+            self.ramdisk = value
+        elif name == 'subnetId':
+            self.subnet_id = value
+        elif name == 'state':
+            if self._in_monitoring_element:
+                if value == 'enabled':
+                    self.monitored = True
+                self._in_monitoring_element = False
+        else:
+            setattr(self, name, value)
+
+

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/regioninfo.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/regioninfo.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/regioninfo.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/regioninfo.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/regioninfo.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/regioninfo.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/regioninfo.py Sun Jun  5 08:34:02 2011
@@ -51,8 +51,8 @@ class RegionInfo(object):
         object's constructor as keyword arguments and they will be
         passed along to the EC2Connection object.
         
-        @rtype: L{EC2Connection<boto.ec2.connection.EC2Connection}
-        @return: The connection to this regions endpoint
+        :rtype: :class:`boto.ec2.connection.EC2Connection`
+        :return: The connection to this regions endpoint
         """
         from boto.ec2.connection import EC2Connection
         return EC2Connection(region=self, **kw_params)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/reservedinstance.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/reservedinstance.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/reservedinstance.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/reservedinstance.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/reservedinstance.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/securitygroup.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/securitygroup.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/securitygroup.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/securitygroup.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/securitygroup.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/securitygroup.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/securitygroup.py Sun Jun  5 08:34:02 2011
@@ -108,24 +108,24 @@ class SecurityGroup(EC2Object):
         and cidr_ip.  In other words, either you are authorizing another
         group or you are authorizing some ip-based rule.
         
-        @type ip_protocol: string
-        @param ip_protocol: Either tcp | udp | icmp
+        :type ip_protocol: string
+        :param ip_protocol: Either tcp | udp | icmp
 
-        @type from_port: int
-        @param from_port: The beginning port number you are enabling
+        :type from_port: int
+        :param from_port: The beginning port number you are enabling
 
-        @type to_port: int
-        @param to_port: The ending port number you are enabling
+        :type to_port: int
+        :param to_port: The ending port number you are enabling
 
-        @type to_port: string
-        @param to_port: The CIDR block you are providing access to.
+        :type to_port: string
+        :param to_port: The CIDR block you are providing access to.
                         See http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
 
-        @type src_group: L{SecurityGroup<boto.ec2.securitygroup.SecurityGroup>} or
-                         L{GroupOrCIDR<boto.ec2.securitygroup.GroupOrCIDR}
+        :type src_group: :class:`boto.ec2.securitygroup.SecurityGroup` or
+                         :class:`boto.ec2.securitygroup.GroupOrCIDR`
                          
-        @rtype: bool
-        @return: True if successful.
+        :rtype: bool
+        :return: True if successful.
         """
         if src_group:
             from_port = None
@@ -180,15 +180,15 @@ class SecurityGroup(EC2Object):
         and will not stay in sync automatically after the copy
         operation.
 
-        @type region: L{RegionInfo<boto.ec2.regioninfo.RegionInfo>}
-        @param region: The region to which this security group will be copied.
+        :type region: :class:`boto.ec2.regioninfo.RegionInfo`
+        :param region: The region to which this security group will be copied.
 
-        @type name: string
-        @param name: The name of the copy.  If not supplied, the copy
+        :type name: string
+        :param name: The name of the copy.  If not supplied, the copy
                      will have the same name as this security group.
         
-        @rtype: L{SecurityGroup<boto.ec2.securitygroup.SecurityGroup>}
-        @return: The new security group.
+        :rtype: :class:`boto.ec2.securitygroup.SecurityGroup`
+        :return: The new security group.
         """
         if region.name == self.region:
             raise BotoClientError('Unable to copy to the same Region')

Added: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/snapshot.py
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/snapshot.py?rev=1132067&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/snapshot.py (added)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/snapshot.py Sun Jun  5 08:34:02 2011
@@ -0,0 +1,124 @@
+# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish, dis-
+# tribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the fol-
+# lowing conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+"""
+Represents an EC2 Elastic IP Snapshot
+"""
+from boto.ec2.ec2object import EC2Object
+
+class Snapshot(EC2Object):
+    
+    def __init__(self, connection=None):
+        EC2Object.__init__(self, connection)
+        self.id = None
+        self.volume_id = None
+        self.status = None
+        self.progress = None
+        self.start_time = None
+        self.owner_id = None
+        self.volume_size = None
+        self.description = None
+
+    def __repr__(self):
+        return 'Snapshot:%s' % self.id
+
+    def endElement(self, name, value, connection):
+        if name == 'snapshotId':
+            self.id = value
+        elif name == 'volumeId':
+            self.volume_id = value
+        elif name == 'status':
+            self.status = value
+        elif name == 'startTime':
+            self.start_time = value
+        elif name == 'ownerId':
+            self.owner_id = value
+        elif name == 'volumeSize':
+            self.volume_size = int(value)
+        elif name == 'description':
+            self.description = value
+        else:
+            setattr(self, name, value)
+
+    def _update(self, updated):
+        self.progress = updated.progress
+        self.status = updated.status
+
+    def update(self):
+        rs = self.connection.get_all_snapshots([self.id])
+        if len(rs) > 0:
+            self._update(rs[0])
+        return self.progress
+    
+    def delete(self):
+        return self.connection.delete_snapshot(self.id)
+
+    def get_permissions(self):
+        attrs = self.connection.get_snapshot_attribute(self.id,
+                                                       attribute='createVolumePermission')
+        return attrs.attrs
+
+    def share(self, user_ids=None, groups=None):
+        return self.connection.modify_snapshot_attribute(self.id,
+                                                         'createVolumePermission',
+                                                         'add',
+                                                         user_ids,
+                                                         groups)
+
+    def unshare(self, user_ids=None, groups=None):
+        return self.connection.modify_snapshot_attribute(self.id,
+                                                         'createVolumePermission',
+                                                         'remove',
+                                                         user_ids,
+                                                         groups)
+
+    def reset_permissions(self):
+        return self.connection.reset_snapshot_attribute(self.id, 'createVolumePermission')
+
+class SnapshotAttribute:
+
+    def __init__(self, parent=None):
+        self.snapshot_id = None
+        self.attrs = {}
+
+    def startElement(self, name, attrs, connection):
+        return None
+
+    def endElement(self, name, value, connection):
+        if name == 'createVolumePermission':
+            self.name = 'create_volume_permission'
+        elif name == 'group':
+            if self.attrs.has_key('groups'):
+                self.attrs['groups'].append(value)
+            else:
+                self.attrs['groups'] = [value]
+        elif name == 'userId':
+            if self.attrs.has_key('user_ids'):
+                self.attrs['user_ids'].append(value)
+            else:
+                self.attrs['user_ids'] = [value]
+        elif name == 'snapshotId':
+            self.snapshot_id = value
+        else:
+            setattr(self, name, value)
+
+
+            

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotdatafeedsubscription.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/elb/instancestate.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotdatafeedsubscription.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotdatafeedsubscription.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/elb/instancestate.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/elb/instancestate.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotdatafeedsubscription.py Sun Jun  5 08:34:02 2011
@@ -19,36 +19,45 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 # IN THE SOFTWARE.
 
-class InstanceState(object):
-    """
-    Represents the state of an EC2 Load Balancer Instance
-    """
-
-    def __init__(self, load_balancer=None, description=None,
-                 state=None, instance_id=None, reason_code=None):
-        self.load_balancer = load_balancer
-        self.description = description
+"""
+Represents an EC2 Spot Instance Datafeed Subscription
+"""
+from boto.ec2.ec2object import EC2Object
+from boto.ec2.spotinstancerequest import SpotInstanceStateFault
+
+class SpotDatafeedSubscription(EC2Object):
+    
+    def __init__(self, connection=None, owner_id=None,
+                 bucket=None, prefix=None, state=None,fault=None):
+        EC2Object.__init__(self, connection)
+        self.owner_id = owner_id
+        self.bucket = bucket
+        self.prefix = prefix
         self.state = state
-        self.instance_id = instance_id
-        self.reason_code = reason_code
+        self.fault = fault
 
     def __repr__(self):
-        return 'InstanceState:(%s,%s)' % (self.instance_id, self.state)
+        return 'SpotDatafeedSubscription:%s' % self.bucket
 
     def startElement(self, name, attrs, connection):
-        return None
-
+        if name == 'fault':
+            self.fault = SpotInstanceStateFault()
+            return self.fault
+        else:
+            return None
+        
     def endElement(self, name, value, connection):
-        if name == 'Description':
-            self.description = value
-        elif name == 'State':
+        if name == 'ownerId':
+            self.owner_id = value
+        elif name == 'bucket':
+            self.bucket = value
+        elif name == 'prefix':
+            self.prefix = value
+        elif name == 'state':
             self.state = value
-        elif name == 'InstanceId':
-            self.instance_id = value
-        elif name == 'ReasonCode':
-            self.reason_code = value
         else:
             setattr(self, name, value)
 
-
+    def delete(self):
+        return self.connection.delete_spot_datafeed_subscription()
 

Added: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotinstancerequest.py
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotinstancerequest.py?rev=1132067&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotinstancerequest.py (added)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotinstancerequest.py Sun Jun  5 08:34:02 2011
@@ -0,0 +1,106 @@
+# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish, dis-
+# tribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the fol-
+# lowing conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+"""
+Represents an EC2 Spot Instance Request
+"""
+
+from boto.ec2.ec2object import EC2Object
+from boto.ec2.launchspecification import LaunchSpecification
+
+class SpotInstanceStateFault(object):
+
+    def __init__(self, code=None, message=None):
+        self.code = code
+        self.message = message
+
+    def __repr__(self):
+        return '(%s, %s)' % (self.code, self.message)
+
+    def startElement(self, name, attrs, connection):
+        return None
+
+    def endElement(self, name, value, connection):
+        if name == 'code':
+            self.code = code
+        elif name == 'message':
+            self.message = message
+        setattr(self, name, value)
+
+class SpotInstanceRequest(EC2Object):
+    
+    def __init__(self, connection=None):
+        EC2Object.__init__(self, connection)
+        self.id = None
+        self.price = None
+        self.type = None
+        self.state = None
+        self.fault = None
+        self.valid_from = None
+        self.valid_until = None
+        self.launch_group = None
+        self.product_description = None
+        self.availability_zone_group = None
+        self.create_time = None
+        self.launch_specification = None
+
+    def __repr__(self):
+        return 'SpotInstanceRequest:%s' % self.id
+
+    def startElement(self, name, attrs, connection):
+        if name == 'launchSpecification':
+            self.launch_specification = LaunchSpecification(connection)
+            return self.launch_specification
+        elif name == 'fault':
+            self.fault = SpotInstanceStateFault()
+            return self.fault
+        else:
+            return None
+
+    def endElement(self, name, value, connection):
+        if name == 'spotInstanceRequestId':
+            self.id = value
+        elif name == 'spotPrice':
+            self.price = float(value)
+        elif name == 'type':
+            self.type = value
+        elif name == 'state':
+            self.state = value
+        elif name == 'productDescription':
+            self.product_description = value
+        elif name == 'validFrom':
+            self.valid_from = value
+        elif name == 'validUntil':
+            self.valid_until = value
+        elif name == 'launchGroup':
+            self.launch_group = value
+        elif name == 'availabilityZoneGroup':
+            self.availability_zone_group = value
+        elif name == 'createTime':
+            self.create_time = value
+        else:
+            setattr(self, name, value)
+
+    def cancel(self):
+        self.connection.cancel_spot_instance_requests([self.id])
+
+
+    

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotpricehistory.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/zone.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotpricehistory.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotpricehistory.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/zone.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/zone.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/spotpricehistory.py Sun Jun  5 08:34:02 2011
@@ -1,4 +1,4 @@
-# Copyright (c) 2006-2008 Mitch Garnaat http://garnaat.org/
+# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the
@@ -20,28 +20,33 @@
 # IN THE SOFTWARE.
 
 """
-Represents an EC2 Availability Zone
+Represents an EC2 Spot Instance Request
 """
+
 from boto.ec2.ec2object import EC2Object
 
-class Zone(EC2Object):
+class SpotPriceHistory(EC2Object):
     
     def __init__(self, connection=None):
         EC2Object.__init__(self, connection)
-        self.name = None
-        self.state = None
+        self.price = 0.0
+        self.instance_type = None
+        self.product_description = None
+        self.timestamp = None
 
     def __repr__(self):
-        return 'Zone:%s' % self.name
+        return 'SpotPriceHistory(%s):%2f' % (self.instance_type, self.price)
 
     def endElement(self, name, value, connection):
-        if name == 'zoneName':
-            self.name = value
-        elif name == 'zoneState':
-            self.state = value
+        if name == 'instanceType':
+            self.instance_type = value
+        elif name == 'spotPrice':
+            self.price = float(value)
+        elif name == 'productDescription':
+            self.product_description = value
+        elif name == 'timestamp':
+            self.timestamp = value
         else:
             setattr(self, name, value)
 
 
-
-

Added: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/volume.py
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/volume.py?rev=1132067&view=auto
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/volume.py (added)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/volume.py Sun Jun  5 08:34:02 2011
@@ -0,0 +1,229 @@
+# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish, dis-
+# tribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the fol-
+# lowing conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
+# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+"""
+Represents an EC2 Elastic IP Volume
+"""
+from boto.ec2.ec2object import EC2Object
+
+class Volume(EC2Object):
+    
+    def __init__(self, connection=None):
+        EC2Object.__init__(self, connection)
+        self.id = None
+        self.create_time = None
+        self.status = None
+        self.size = None
+        self.snapshot_id = None
+        self.attach_data = None
+        self.zone = None
+
+    def __repr__(self):
+        return 'Volume:%s' % self.id
+
+    def startElement(self, name, attrs, connection):
+        if name == 'attachmentSet':
+            self.attach_data = AttachmentSet()
+            return self.attach_data
+        else:
+            return None
+
+    def endElement(self, name, value, connection):
+        if name == 'volumeId':
+            self.id = value
+        elif name == 'createTime':
+            self.create_time = value
+        elif name == 'status':
+            if value != '':
+                self.status = value
+        elif name == 'size':
+            self.size = int(value)
+        elif name == 'snapshotId':
+            self.snapshot_id = value
+        elif name == 'availabilityZone':
+            self.zone = value
+        else:
+            setattr(self, name, value)
+
+    def _update(self, updated):
+        self.updated = updated
+        if hasattr(updated, 'create_time'):
+            self.create_time = updated.create_time
+        if hasattr(updated, 'status'):
+            self.status = updated.status
+        else:
+            self.status = None
+        if hasattr(updated, 'size'):
+            self.size = updated.size
+        if hasattr(updated, 'snapshot_id'):
+            self.snapshot_id = updated.snapshot_id
+        if hasattr(updated, 'attach_data'):
+            self.attach_data = updated.attach_data
+        if hasattr(updated, 'zone'):
+            self.zone = updated.zone
+
+    def update(self):
+        rs = self.connection.get_all_volumes([self.id])
+        if len(rs) > 0:
+            self._update(rs[0])
+        return self.status
+
+    def delete(self):
+        """
+        Delete this EBS volume.
+
+        :rtype: bool
+        :return: True if successful
+        """
+        return self.connection.delete_volume(self.id)
+
+    def attach(self, instance_id, device):
+        """
+        Attach this EBS volume to an EC2 instance.
+
+        :type instance_id: str
+        :param instance_id: The ID of the EC2 instance to which it will
+                            be attached.
+
+        :type device: str
+        :param device: The device on the instance through which the
+                       volume will be exposted (e.g. /dev/sdh)
+
+        :rtype: bool
+        :return: True if successful
+        """
+        return self.connection.attach_volume(self.id, instance_id, device)
+
+    def detach(self, force=False):
+        """
+        Detach this EBS volume from an EC2 instance.
+
+        :type force: bool
+        :param force: Forces detachment if the previous detachment attempt did
+                      not occur cleanly.  This option can lead to data loss or
+                      a corrupted file system. Use this option only as a last
+                      resort to detach a volume from a failed instance. The
+                      instance will not have an opportunity to flush file system
+                      caches nor file system meta data. If you use this option,
+                      you must perform file system check and repair procedures.
+
+        :rtype: bool
+        :return: True if successful
+        """
+        instance_id = None
+        if self.attach_data:
+            instance_id = self.attach_data.instance_id
+        device = None
+        if self.attach_data:
+            device = self.attach_data.device
+        return self.connection.detach_volume(self.id, instance_id, device, force)
+
+    def create_snapshot(self, description=None):
+        """
+        Create a snapshot of this EBS Volume.
+
+        :type description: str
+        :param description: A description of the snapshot.  Limited to 256 characters.
+        
+        :rtype: bool
+        :return: True if successful
+        """
+        return self.connection.create_snapshot(self.id, description)
+
+    def volume_state(self):
+        """
+        Returns the state of the volume.  Same value as the status attribute.
+        """
+        return self.status
+
+    def attachment_state(self):
+        """
+        Get the attachmentSet information for the volume.  This info is stored
+        in a dictionary object and contains at least the following info:
+
+        - volumeId
+        - instanceId
+        - device
+        - status
+        - attachTime
+        """
+        state = None
+        if self.attach_data:
+            state = self.attach_data.status
+        return state
+
+    def snapshots(self, owner=None, restorable_by=None):
+        """
+        Get all snapshots related to this volume.  Note that this requires
+        that all available snapshots for the account be retrieved from EC2
+        first and then the list is filtered client-side to contain only
+        those for this volume.
+
+        :type owner: str
+        :param owner: If present, only the snapshots owned by the specified user
+                      will be returned.  Valid values are:
+                      self | amazon | AWS Account ID
+
+        :type restorable_by: str
+        :param restorable_by: If present, only the snapshots that are restorable
+                              by the specified account id will be returned.
+
+        :rtype: list of L{boto.ec2.snapshot.Snapshot}
+        :return: The requested Snapshot objects
+        
+        """
+        rs = self.connection.get_all_snapshots(owner=owner,
+                                               restorable_by=restorable_by)
+        mine = []
+        for snap in rs:
+            if snap.volume_id == self.id:
+                mine.append(snap)
+        return mine
+
+class AttachmentSet(object):
+    
+    def __init__(self):
+        self.id = None
+        self.instance_id = None
+        self.status = None
+        self.attach_time = None
+        self.device = None
+
+    def __repr__(self):
+        return 'AttachmentSet:%s' % self.id
+
+    def startElement(self, name, attrs, connection):
+        pass
+    
+    def endElement(self, name, value, connection):
+        if name == 'volumeId':
+            self.id = value
+        elif name == 'instanceId':
+            self.instance_id = value
+        elif name == 'status':
+            self.status = value
+        elif name == 'attachTime':
+            self.attach_time = value
+        elif name == 'device':
+            self.device = value
+        else:
+            setattr(self, name, value)
+

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/zone.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/zone.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/zone.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/ec2/zone.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/ec2/zone.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/exception.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/exception.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/exception.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/exception.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/exception.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/exception.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/exception.py Sun Jun  5 08:34:02 2011
@@ -28,7 +28,7 @@ from boto.resultset import ResultSet
 
 import xml.sax
 
-class BotoClientError(Exception):
+class BotoClientError(StandardError):
     """
     General Boto Client error (error accessing AWS)
     """
@@ -42,7 +42,7 @@ class BotoClientError(Exception):
     def __str__(self):
         return 'S3Error: %s' % self.reason
 
-class SDBPersistenceError(Exception):
+class SDBPersistenceError(StandardError):
 
     pass
 
@@ -52,7 +52,7 @@ class S3PermissionsError(BotoClientError
     """
     pass
     
-class BotoServerError(Exception):
+class BotoServerError(StandardError):
     
     def __init__(self, status, reason, body=None):
         self.status = status
@@ -175,6 +175,20 @@ class SQSError(BotoServerError):
         for p in ('detail', 'type'):
             setattr(self, p, None)
 
+class SQSDecodeError(BotoClientError):
+    """
+    Error when decoding an SQS message.
+    """
+    def __init__(self, reason, message):
+        self.reason = reason
+        self.message = message
+
+    def __repr__(self):
+        return 'SQSDecodeError: %s' % self.reason
+
+    def __str__(self):
+        return 'SQSDecodeError: %s' % self.reason
+    
 class S3ResponseError(BotoServerError):
     """
     Error in response from S3.

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/fps/__init__.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/fps/__init__.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/fps/__init__.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/fps/__init__.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/fps/__init__.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/fps/connection.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/fps/connection.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/fps/connection.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/fps/connection.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/fps/connection.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/fps/connection.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/fps/connection.py Sun Jun  5 08:34:02 2011
@@ -48,7 +48,9 @@ class FPSConnection(AWSQueryConnection):
 		"""
 		InstallPaymentInstruction
 		instruction: The PaymentInstruction to send, for example: 
+		
 			MyRole=='Caller' orSay 'Roles do not match';
+		
 		token_type: Defaults to "Unrestricted"
 		transaction_id: Defaults to a new ID
 		"""

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/handler.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/handler.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/handler.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/handler.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/handler.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/__init__.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/__init__.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/__init__.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/__init__.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/__init__.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/cmdshell.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/cmdshell.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/cmdshell.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/cmdshell.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/cmdshell.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/cmdshell.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/cmdshell.py Sun Jun  5 08:34:02 2011
@@ -75,6 +75,9 @@ class SSHClient(object):
         sftp_client = self._ssh_client.open_sftp()
         return sftp_client.listdir(path)
 
+    def open_sftp(self):
+        return self._ssh_client.open_sftp()
+
     def isdir(self, path):
         status = self.run('[ -d %s ] || echo "FALSE"' % path)
         if status[1].startswith('FALSE'):

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/propget.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/propget.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/propget.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/propget.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/propget.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/server.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/server.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/server.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/server.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/server.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/server.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/server.py Sun Jun  5 08:34:02 2011
@@ -25,114 +25,68 @@ High-level abstraction of an EC2 server
 from __future__ import with_statement
 import boto.ec2
 from boto.mashups.iobject import IObject
-from boto.pyami.config import BotoConfigPath
-from boto.sdb.db.model import Model, ModelMeta
+from boto.pyami.config import BotoConfigPath, Config
+from boto.sdb.db.model import Model
 from boto.sdb.db.property import *
 from boto.manage import propget
-import cmdshell
-import os, time
-import StringIO
+from boto.ec2.zone import Zone
+from boto.ec2.keypair import KeyPair
+import os, time, StringIO
 from contextlib import closing
+from boto.exception import EC2ResponseError
 
-class ServerMeta(ModelMeta):
-
-    def __init__(cls, name, bases, dict):
-        super(ServerMeta, cls).__init__(name, bases, dict)
-        installers = []
-        for base in bases:
-            l = []
-            for key in base.__dict__:
-                val = base.__dict__[key]
-                if isinstance(val, Installer):
-                    print 'Found %s_%s in %s' % (val.name, val.seq_no, base.__name__)
-                    l.append(val)
-            l.sort()
-            installers.extend(l)
-        for i in installers:
-            print i.name
-        
-class Installer(object):
-
-    def __init__ (self, seq_no, fn):
-        self.instance_id = boto.config.get('Instance', 'instance-id', None)
-        self.name = fn.__name__
-        self.seq_no = seq_no
-        self.fn = fn
-
-    def __call__ (self, *args, **kws):
-        if self.instance_id == self.obj.instance_id:
-            ret_val = self.fn(self.obj, *args, **kws)
-            return ret_val
-        else:
-            raise NotImplementedError, '%s is only available on the EC2 instance' % self.fn.__name__
-
-    def __cmp__(self, other):
-        return cmp(self.seq_no, other.seq_no)
-
-    def __get__(descr, inst, instCls=None):
-        descr.obj = inst
-        return descr
-
-def installer(seq_no):
-    ret_val = lambda func: Installer(seq_no, func)
-    return ret_val
-
-InstanceTypes = ['m1.small', 'm1.large', 'm1.xlarge', 'c1.medium', 'c1.xlarge']
+InstanceTypes = ['m1.small', 'm1.large', 'm1.xlarge',
+                 'c1.medium', 'c1.xlarge',
+                 'm2.2xlarge', 'm2.4xlarge']
 
 class Bundler(object):
 
-    def __init__(self, server):
+    def __init__(self, server, uname='root'):
+        from boto.manage.cmdshell import SSHClient
         self.server = server
-        self.ssh_client = SSHClient(server)
+        self.uname = uname
+        self.ssh_client = SSHClient(server, uname=uname)
 
-    def bundle_image(self, prefix, key_file, cert_file, size, ssh_key):
-        print 'bundling image...'
+    def copy_x509(self, key_file, cert_file):
         print '\tcopying cert and pk over to /mnt directory on server'
         sftp_client = self.ssh_client.open_sftp()
         path, name = os.path.split(key_file)
-        remote_key_file = '/mnt/%s' % name
-        self.put_file(key_file, remote_key_file)
+        self.remote_key_file = '/mnt/%s' % name
+        self.ssh_client.put_file(key_file, self.remote_key_file)
         path, name = os.path.split(cert_file)
-        remote_cert_file = '/mnt/%s' % name
-        self.put_file(cert_file, remote_cert_file)
-        print '\tdeleting %s' % BotoConfigPath
-        # delete the metadata.ini file if it exists
-        try:
-            sftp_client.remove(BotoConfigPath)
-        except:
-            pass
-        command = 'ec2-bundle-vol '
-        command += '-c %s -k %s ' % (remote_cert_file, remote_key_file)
-        command += '-u %s ' % self._reservation.owner_id
+        self.remote_cert_file = '/mnt/%s' % name
+        self.ssh_client.put_file(cert_file, self.remote_cert_file)
+        print '...complete!'
+
+    def bundle_image(self, prefix, size, ssh_key):
+        command = ""
+        if self.uname != 'root':
+            command = "sudo "
+        command += 'ec2-bundle-vol '
+        command += '-c %s -k %s ' % (self.remote_cert_file, self.remote_key_file)
+        command += '-u %s ' % self.server._reservation.owner_id
         command += '-p %s ' % prefix
         command += '-s %d ' % size
         command += '-d /mnt '
-        if self.instance.instance_type == 'm1.small' or self.instance_type == 'c1.medium':
+        if self.server.instance_type == 'm1.small' or self.server.instance_type == 'c1.medium':
             command += '-r i386'
         else:
             command += '-r x86_64'
-        print '\t%s' % command
-        t = ssh_client.exec_command(command)
-        response = t[1].read()
-        print '\t%s' % response
-        print '\t%s' % t[2].read()
-        print '...complete!'
+        return command
 
     def upload_bundle(self, bucket, prefix, ssh_key):
-        print 'uploading bundle...'
-        command = 'ec2-upload-bundle '
+        command = ""
+        if self.uname != 'root':
+            command = "sudo "
+        command += 'ec2-upload-bundle '
         command += '-m /mnt/%s.manifest.xml ' % prefix
         command += '-b %s ' % bucket
         command += '-a %s ' % self.server.ec2.aws_access_key_id
         command += '-s %s ' % self.server.ec2.aws_secret_access_key
-        print '\t%s' % command
-        t = self.ssh_client.exec_command(command)
-        response = t[1].read()
-        print '\t%s' % response
-        print '\t%s' % t[2].read()
-        print '...complete!'
+        return command
 
-    def bundle(self, bucket=None, prefix=None, key_file=None, cert_file=None, size=None, ssh_key=None):
+    def bundle(self, bucket=None, prefix=None, key_file=None, cert_file=None,
+               size=None, ssh_key=None, fp=None, clear_history=True):
         iobject = IObject()
         if not bucket:
             bucket = iobject.get_string('Name of S3 bucket')
@@ -145,9 +99,27 @@ class Bundler(object):
         if not size:
             size = iobject.get_int('Size (in MB) of bundled image')
         if not ssh_key:
-            ssh_key = iobject.get_filename('Path to SSH Private Key')
-        self.bundle_image(prefix, key_file, cert_file, size, ssh_key)
-        self.upload_bundle(bucket, prefix, ssh_key)
+            ssh_key = self.server.get_ssh_key_file()
+        self.copy_x509(key_file, cert_file)
+        if not fp:
+            fp = StringIO.StringIO()
+        fp.write('mv %s /mnt/boto.cfg; ' % BotoConfigPath)
+        fp.write('mv /root/.ssh/authorized_keys /mnt/authorized_keys; ')
+        if clear_history:
+            fp.write('history -c; ')
+        fp.write(self.bundle_image(prefix, size, ssh_key))
+        fp.write('; ')
+        fp.write(self.upload_bundle(bucket, prefix, ssh_key))
+        fp.write('; ')
+        fp.write('mv /mnt/boto.cfg %s; ' % BotoConfigPath)
+        fp.write('mv /mnt/authorized_keys /root/.ssh/authorized_keys\n')
+        command = fp.getvalue()
+        print 'running the following command on the remote server:'
+        print command
+        t = self.ssh_client.run(command)
+        print '\t%s' % t[0]
+        print '\t%s' % t[1]
+        print '...complete!'
         print 'registering image...'
         self.image_id = self.server.ec2.register_image('%s/%s.manifest.xml' % (bucket, prefix))
         return self.image_id
@@ -163,7 +135,11 @@ class CommandLineGetter(object):
         return my_amis
     
     def get_region(self, params):
-        if not params.get('region', None):
+        region = params.get('region', None)
+        if isinstance(region, str) or isinstance(region, unicode):
+            region = boto.ec2.get_region(region)
+            params['region'] = region
+        if not region:
             prop = self.cls.find_property('region_name')
             params['region'] = propget.get(prop, choices=boto.ec2.regions)
 
@@ -195,22 +171,43 @@ class CommandLineGetter(object):
             params['zone'] = propget.get(prop)
             
     def get_ami_id(self, params):
+        ami = params.get('ami', None)
+        if isinstance(ami, str) or isinstance(ami, unicode):
+            ami_list = self.get_ami_list()
+            for l,a in ami_list:
+                if a.id == ami:
+                    ami = a
+                    params['ami'] = a
         if not params.get('ami', None):
             prop = StringProperty(name='ami', verbose_name='AMI',
                                   choices=self.get_ami_list)
             params['ami'] = propget.get(prop)
 
     def get_group(self, params):
-        if not params.get('groups', None):
-            prop = StringProperty(name='groups', verbose_name='EC2 Security Group',
+        group = params.get('group', None)
+        if isinstance(group, str) or isinstance(group, unicode):
+            group_list = self.ec2.get_all_security_groups()
+            for g in group_list:
+                if g.name == group:
+                    group = g
+                    params['group'] = g
+        if not group:
+            prop = StringProperty(name='group', verbose_name='EC2 Security Group',
                                   choices=self.ec2.get_all_security_groups)
-            params['groups'] = [propget.get(prop)]
+            params['group'] = propget.get(prop)
 
     def get_key(self, params):
-        if not params.get('keypair', None):
+        keypair = params.get('keypair', None)
+        if isinstance(keypair, str) or isinstance(keypair, unicode):
+            key_list = self.ec2.get_all_key_pairs()
+            for k in key_list:
+                if k.name == keypair:
+                    keypair = k.name
+                    params['keypair'] = k.name
+        if not keypair:
             prop = StringProperty(name='keypair', verbose_name='EC2 KeyPair',
                                   choices=self.ec2.get_all_key_pairs)
-            params['keypair'] = propget.get(prop)
+            params['keypair'] = propget.get(prop).name
 
     def get(self, cls, params):
         self.cls = cls
@@ -227,8 +224,6 @@ class CommandLineGetter(object):
 
 class Server(Model):
 
-    __metaclass__ = ServerMeta
-    
     #
     # The properties of this object consists of real properties for data that
     # is not already stored in EC2 somewhere (e.g. name, description) plus
@@ -245,54 +240,100 @@ class Server(Model):
     zone = CalculatedProperty(verbose_name="Availability Zone Name", calculated_type=str, use_method=True)
     hostname = CalculatedProperty(verbose_name="Public DNS Name", calculated_type=str, use_method=True)
     private_hostname = CalculatedProperty(verbose_name="Private DNS Name", calculated_type=str, use_method=True)
-    groups = CalculatedProperty(verbose_name="Security Group Name", calculated_type=list, use_method=True)
+    groups = CalculatedProperty(verbose_name="Security Groups", calculated_type=list, use_method=True)
+    security_group = CalculatedProperty(verbose_name="Primary Security Group Name", calculated_type=str, use_method=True)
     key_name = CalculatedProperty(verbose_name="Key Name", calculated_type=str, use_method=True)
     instance_type = CalculatedProperty(verbose_name="Instance Type", calculated_type=str, use_method=True)
     status = CalculatedProperty(verbose_name="Current Status", calculated_type=str, use_method=True)
     launch_time = CalculatedProperty(verbose_name="Server Launch Time", calculated_type=str, use_method=True)
-    console_output = CalculatedProperty(verbose_name="Console Output", calculated_type=str, use_method=True)
+    console_output = CalculatedProperty(verbose_name="Console Output", calculated_type=file, use_method=True)
 
     packages = []
     plugins = []
 
     @classmethod
-    def make_config(cls, aws_access_key_id, aws_secret_access_key):
-        cfg = StringIO.StringIO()
-        cfg.write('[Credentials]\n')
-        cfg.write('aws_access_key_id = %s\n' % aws_access_key_id)
-        cfg.write('aws_secret_access_key = %s\n\n' % aws_secret_access_key)
-        cfg.write('[DB_Server]\n')
-        cfg.write('db_type = SimpleDB\n')
-        cfg.write('db_name = %s\n' % cls._manager.domain.name)
-        return cfg.getvalue()
+    def add_credentials(cls, cfg, aws_access_key_id, aws_secret_access_key):
+        if not cfg.has_section('Credentials'):
+            cfg.add_section('Credentials')
+        cfg.set('Credentials', 'aws_access_key_id', aws_access_key_id)
+        cfg.set('Credentials', 'aws_secret_access_key', aws_secret_access_key)
+        if not cfg.has_section('DB_Server'):
+            cfg.add_section('DB_Server')
+        cfg.set('DB_Server', 'db_type', 'SimpleDB')
+        cfg.set('DB_Server', 'db_name', cls._manager.domain.name)
+
+    '''
+    Create a new instance based on the specified configuration file or the specified
+    configuration and the passed in parameters.
+    
+    If the config_file argument is not None, the configuration is read from there. 
+    Otherwise, the cfg argument is used.
 
+    The config file may include other config files with a #import reference. The included
+    config files must reside in the same directory as the specified file. 
+    
+    The logical_volume argument, if supplied, will be used to get the current physical 
+    volume ID and use that as an override of the value specified in the config file. This 
+    may be useful for debugging purposes when you want to debug with a production config 
+    file but a test Volume. 
+    
+    The dictionary argument may be used to override any EC2 configuration values in the 
+    config file. 
+    '''
     @classmethod
-    def create(cls, **params):
+    def create(cls, config_file=None, logical_volume = None, cfg = None, **params):
+        if config_file:
+            cfg = Config(path=config_file)
+        if cfg.has_section('EC2'):
+            # include any EC2 configuration values that aren't specified in params:
+            for option in cfg.options('EC2'):
+                if option not in params:
+                    params[option] = cfg.get('EC2', option)
         getter = CommandLineGetter()
         getter.get(cls, params)
         region = params.get('region')
         ec2 = region.connect()
-        cfg = cls.make_config(ec2.aws_access_key_id, ec2.aws_secret_access_key)
+        cls.add_credentials(cfg, ec2.aws_access_key_id, ec2.aws_secret_access_key)
         ami = params.get('ami')
         kp = params.get('keypair')
-        groups = [g.name for g in params.get('groups')]
+        group = params.get('group')
         zone = params.get('zone')
+        # deal with possibly passed in logical volume:
+        if logical_volume != None:
+           cfg.set('EBS', 'logical_volume_name', logical_volume.name) 
+        cfg_fp = StringIO.StringIO()
+        cfg.write(cfg_fp)
+        # deal with the possibility that zone and/or keypair are strings read from the config file:
+        if isinstance(zone, Zone):
+            zone = zone.name
+        if isinstance(kp, KeyPair):
+            kp = kp.name
         reservation = ami.run(min_count=1,
                               max_count=params.get('quantity', 1),
-                              key_name=kp.name,
-                              security_groups=groups,
+                              key_name=kp,
+                              security_groups=[group],
                               instance_type=params.get('instance_type'),
-                              placement = zone.name,
-                              user_data = cfg)
+                              placement = zone,
+                              user_data = cfg_fp.getvalue())
         l = []
         i = 0
-        for instance in reservation.instances:
+        elastic_ip = params.get('elastic_ip')
+        instances = reservation.instances
+        if elastic_ip != None and instances.__len__() > 0:
+            instance = instances[0]
+            while instance.update() != 'running':
+                time.sleep(1)
+            instance.use_ip(elastic_ip)
+            print 'set the elastic IP of the first instance to %s' % elastic_ip
+        for instance in instances:
             s = cls()
             s.ec2 = ec2
             s.name = params.get('name') + '' if i==0 else str(i)
             s.description = params.get('description')
             s.region_name = region.name
             s.instance_id = instance.id
+            if elastic_ip and i == 0:
+                s.elastic_ip = elastic_ip
             s.put()
             l.append(s)
             i += 1
@@ -322,6 +363,7 @@ class Server(Model):
                 return s
         return None
 
+    @classmethod
     def create_from_current_instances(cls):
         servers = []
         regions = boto.ec2.regions()
@@ -362,12 +404,15 @@ class Server(Model):
                     if region.name == self.region_name:
                         self.ec2 = region.connect()
                         if self.instance_id and not self._instance:
-                            rs = self.ec2.get_all_instances([self.instance_id])
-                            if len(rs) >= 1:
-                                for instance in rs[0].instances:
-                                    if instance.id == self.instance_id:
-                                        self._reservation = rs[0]
-                                        self._instance = instance
+                            try:
+                                rs = self.ec2.get_all_instances([self.instance_id])
+                                if len(rs) >= 1:
+                                    for instance in rs[0].instances:
+                                        if instance.id == self.instance_id:
+                                            self._reservation = rs[0]
+                                            self._instance = instance
+                            except EC2ResponseError:
+                                pass
                             
     def _status(self):
         status = ''
@@ -388,6 +433,12 @@ class Server(Model):
             hostname = self._instance.private_dns_name
         return hostname
 
+    def _instance_type(self):
+        it = ''
+        if self._instance:
+            it = self._instance.instance_type
+        return it
+
     def _launch_time(self):
         lt = ''
         if self._instance:
@@ -406,6 +457,12 @@ class Server(Model):
             gn = self._reservation.groups
         return gn
 
+    def _security_group(self):
+        groups = self._groups()
+        if len(groups) >= 1:
+            return groups[0].id
+        return ""
+
     def _zone(self):
         zone = None
         if self._instance:
@@ -456,6 +513,7 @@ class Server(Model):
 
     def get_cmdshell(self):
         if not self._cmdshell:
+            import cmdshell
             self.get_ssh_key_file()
             self._cmdshell = cmdshell.start(self)
         return self._cmdshell
@@ -468,22 +526,17 @@ class Server(Model):
             status = cmd.run(command)
         return status
 
-    def get_bundler(self, key_file=None):
-        self.get_ssh_key_file()
-        return SSHClient(self)
+    def get_bundler(self, uname='root'):
+        ssh_key_file = self.get_ssh_key_file()
+        return Bundler(self, uname)
+
+    def get_ssh_client(self, uname='root'):
+        from boto.manage.cmdshell import SSHClient
+        ssh_key_file = self.get_ssh_key_file()
+        return SSHClient(self, uname=uname)
 
     def install(self, pkg):
         return self.run('apt-get -y install %s' % pkg)
 
-class MySQLServer(Server):
-
-    root_password = StringProperty(verbose_name="Root Password")
-
-    def test(self):
-        print 'MySQLServer.test'
-
-    @installer('001')
-    def test_mysql(self):
-        print 'MySQLServer.test_mysql'
 
     

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/task.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/task.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/task.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/task.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/task.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/task.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/task.py Sun Jun  5 08:34:02 2011
@@ -81,6 +81,8 @@ class Task(Model):
         if self.daily and not self.last_executed:
             if int(self.hour) == self.now.hour:
                 return 0
+            else:
+                return max((int(self.hour) - self.now.hour),0)*60*60
 
         delta = self.now - self.last_executed
         if self.hourly:

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/test_manage.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/test_manage.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/test_manage.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/test_manage.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/test_manage.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/volume.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/volume.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/volume.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/volume.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/volume.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/manage/volume.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/manage/volume.py Sun Jun  5 08:34:02 2011
@@ -76,6 +76,7 @@ class Volume(Model):
 
     name = StringProperty(required=True, unique=True, verbose_name='Name')
     region_name = StringProperty(required=True, verbose_name='EC2 Region')
+    zone_name = StringProperty(required=True, verbose_name='EC2 Zone')
     mount_point = StringProperty(verbose_name='Mount Point')
     device = StringProperty(verbose_name="Device Name", default='/dev/sdp')
     volume_id = StringProperty(required=True)
@@ -105,6 +106,7 @@ class Volume(Model):
         v.mount_point = params.get('mount_point')
         v.device = params.get('device')
         v.region_name = region.name
+        v.zone_name = zone.name
         v.put()
         return v
 
@@ -119,8 +121,33 @@ class Volume(Model):
             vol.volume_id = v.id
             vol.name = name
             vol.region_name = v.region.name
+            vol.zone_name = v.zone
             vol.put()
         return vol
+
+    def create_from_latest_snapshot(self, name, size=None):
+        snapshot = self.get_snapshots()[-1]
+        return self.create_from_snapshot(name, snapshot, size)
+
+    def create_from_snapshot(self, name, snapshot, size=None):
+        if size < self.size:
+            size = self.size
+        ec2 = self.get_ec2_connection()
+        if self.zone_name == None or self.zone_name == '':
+            # deal with the migration case where the zone is not set in the logical volume:
+            current_volume = ec2.get_all_volumes([self.volume_id])[0]
+            self.zone_name = current_volume.zone
+        ebs_volume = ec2.create_volume(size, self.zone_name, snapshot)
+        v = Volume()
+        v.ec2 = self.ec2
+        v.volume_id = ebs_volume.id
+        v.name = name
+        v.mount_point = self.mount_point
+        v.device = self.device
+        v.region_name = self.region_name
+        v.zone_name = self.zone_name
+        v.put()
+        return v
     
     def get_ec2_connection(self):
         if self.server:
@@ -271,9 +298,11 @@ class Volume(Model):
         # if this volume is attached to a server
         # we need to freeze the XFS file system
         try:
-            status = self.freeze(keep_alive=True)
-            print status[1]
-            snapshot = self.server.ec2.create_snapshot(self.volume_id)
+            self.freeze()
+            if self.server == None:
+                snapshot = self.get_ec2_connection().create_snapshot(self.volume_id)
+            else:
+                snapshot = self.server.ec2.create_snapshot(self.volume_id)
             boto.log.info('Snapshot of Volume %s created: %s' %  (self.name, snapshot))
         except Exception, e:
             boto.log.info('Snapshot error')

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/__init__.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/__init__.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/__init__.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/__init__.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/__init__.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/lqs.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/lqs.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/lqs.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/lqs.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/lqs.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/partitiondb.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/partitiondb.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/partitiondb.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/partitiondb.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/partitiondb.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/partitiondb.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/partitiondb.py Sun Jun  5 08:34:02 2011
@@ -53,8 +53,8 @@ class Version(SDBObject):
         """
         Return an iterator containing all Partition objects related to this Version.
 
-        @rtype: iterator of L{Partitions<boto.mapreduce.partitiondb.Partition>}
-        @return: The Partitions in this Version
+        :rtype: iterator of :class:`boto.mapreduce.partitiondb.Partition`
+        :return: The Partitions in this Version
         """
         return self.get_related_objects('version', Partition)
 
@@ -62,11 +62,11 @@ class Version(SDBObject):
         """
         Add a new Partition to this Version.
 
-        @type name: string
-        @param name: The name of the new Partition (optional)
+        :type name: string
+        :param name: The name of the new Partition (optional)
 
-        @rtype: L{Partition<boto.mapreduce.partitiondb.Partition>}
-        @return: The new Partition object
+        :rtype: :class:`boto.mapreduce.partitiondb.Partition`
+        :return: The new Partition object
         """
         p = Partition(manager=self.manager, name=name)
         p.version = self
@@ -99,8 +99,8 @@ class PartitionDB(SDBObject):
         Add a new Version to this PartitionDB.  The newly added version becomes the
         current version.
 
-        @rtype: L{Version<boto.mapreduce.partitiondb.Version>}
-        @return: The newly created Version object.
+        :rtype: :class:`boto.mapreduce.partitiondb.Version`
+        :return: The newly created Version object.
         """
         v = Version()
         v.pdb = self
@@ -115,8 +115,8 @@ class PartitionDB(SDBObject):
         Note that this method does not delete the Version object or any Partitions related to the
         Version object.
 
-        @rtype: L{Version<boto.mapreduce.partitiondb.Version>}
-        @return: The previous current Version object.
+        :rtype: :class:`boto.mapreduce.partitiondb.Version`
+        :return: The previous current Version object.
         """
         v = self.current_version()
         if v:
@@ -127,8 +127,8 @@ class PartitionDB(SDBObject):
         """
         Get the currently active Version of this PartitionDB object.
 
-        @rtype: L{Version<boto.mapreduce.partitiondb.Version>}
-        @return: The current Version object or None if there are no Versions associated
+        :rtype: :class:`boto.mapreduce.partitiondb.Version`
+        :return: The current Version object or None if there are no Versions associated
                  with this PartitionDB object.
         """
         if self.versions:

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_delete (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/pdb_delete)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_delete?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_delete&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/pdb_delete&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_describe (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/pdb_describe)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_describe?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_describe&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/pdb_describe&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_revert (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/pdb_revert)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_revert?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_revert&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/pdb_revert&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_upload (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/pdb_upload)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_upload?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/pdb_upload&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/pdb_upload&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/queuetools.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/queuetools.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/queuetools.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mapreduce/queuetools.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mapreduce/queuetools.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/__init__.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/__init__.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/__init__.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/__init__.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/__init__.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/interactive.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/interactive.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/interactive.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/interactive.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/interactive.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/iobject.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/iobject.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/iobject.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/iobject.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/iobject.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/iobject.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/iobject.py Sun Jun  5 08:34:02 2011
@@ -46,10 +46,16 @@ class IObject(object):
                     n += 1
                 else:
                     obj, id, desc = item
-                    if desc.find(search_str) >= 0:
-                        print '[%d] %s - %s' % (n, id, desc)
-                        choices.append(obj)
-                        n += 1
+                    if desc:
+                        if desc.find(search_str) >= 0:
+                            print '[%d] %s - %s' % (n, id, desc)
+                            choices.append(obj)
+                            n += 1
+                    else:
+                        if id.find(search_str) >= 0:
+                            print '[%d] %s' % (n, id)
+                            choices.append(obj)
+                            n += 1
             if choices:
                 val = raw_input('%s[1-%d]: ' % (prompt, len(choices)))
                 if val.startswith('/'):

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/order.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/order.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/order.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/order.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/order.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/server.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/server.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/server.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/server.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/server.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/mashups/server.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/mashups/server.py Sun Jun  5 08:34:02 2011
@@ -351,11 +351,11 @@ class Server(Model):
         """
         Attach an EBS volume to this server
 
-        @param volume: EBS Volume to attach
-        @type volume: boto.ec2.volume.Volume
+        :param volume: EBS Volume to attach
+        :type volume: boto.ec2.volume.Volume
 
-        @param device: Device to attach to (default to /dev/sdp)
-        @type device: string
+        :param device: Device to attach to (default to /dev/sdp)
+        :type device: string
         """
         if hasattr(volume, "id"):
             volume_id = volume.id
@@ -367,8 +367,8 @@ class Server(Model):
         """
         Detach an EBS volume from this server
 
-        @param volume: EBS Volume to detach
-        @type volume: boto.ec2.volume.Volume
+        :param volume: EBS Volume to detach
+        :type volume: boto.ec2.volume.Volume
         """
         if hasattr(volume, "id"):
             volume_id = volume.id

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mturk/__init__.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mturk/__init__.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mturk/__init__.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mturk/__init__.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mturk/__init__.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
    (empty)

Copied: incubator/mesos/trunk/third_party/boto-1.9b/boto/mturk/connection.py (from r1132066, incubator/mesos/trunk/third_party/boto-1.8d/boto/mturk/connection.py)
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/boto-1.9b/boto/mturk/connection.py?p2=incubator/mesos/trunk/third_party/boto-1.9b/boto/mturk/connection.py&p1=incubator/mesos/trunk/third_party/boto-1.8d/boto/mturk/connection.py&r1=1132066&r2=1132067&rev=1132067&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/boto-1.8d/boto/mturk/connection.py (original)
+++ incubator/mesos/trunk/third_party/boto-1.9b/boto/mturk/connection.py Sun Jun  5 08:34:02 2011
@@ -176,7 +176,7 @@ class MTurkConnection(AWSQueryConnection
             self.build_list_params(params, response_groups, 'ResponseGroup')
                 
         # Submit
-        return self._process_request('CreateHIT', params, [('Reward', Price),])
+        return self._process_request('CreateHIT', params, [('HIT', HIT),])
 
     def get_reviewable_hits(self, hit_type=None, status='Reviewable',
                             sort_by='Expiration', sort_direction='Ascending', 
@@ -312,6 +312,21 @@ class MTurkConnection(AWSQueryConnection
         params = {'HITId' : hit_id,}
         return self._process_request('DisposeHIT', params)
 
+    def expire_hit(self, hit_id):
+
+        """
+        Expire a HIT that is no longer needed.
+
+	The effect is identical to the HIT expiring on its own. The HIT no longer appears on the 
+	Mechanical Turk web site, and no new Workers are allowed to accept the HIT. Workers who 
+	have accepted the HIT prior to expiration are allowed to complete it or return it, or 
+	allow the assignment duration to elapse (abandon the HIT). Once all remaining assignments 
+	have been submitted, the expired HIT becomes "reviewable", and will be returned by a call 
+	to GetReviewableHITs.
+        """
+        params = {'HITId' : hit_id,}
+        return self._process_request('ForceExpireHIT', params)
+
     def extend_hit(self, hit_id, assignments_increment=None, expiration_increment=None):
         """
         Increase the maximum number of assignments, or extend the expiration date, of an existing HIT.
@@ -374,7 +389,7 @@ class MTurkConnection(AWSQueryConnection
         """
         body = response.read()
         #print body
-        if response.status == 200:
+        if '<Errors>' not in body:
             rs = ResultSet(marker_elems)
             h = handler.XmlHandler(rs, self)
             xml.sax.parseString(body, h)
@@ -463,7 +478,7 @@ class Assignment(BaseAutoResultElement):
         if name == 'Answer':
             answer_rs = ResultSet([('Answer', QuestionFormAnswer),])
             h = handler.XmlHandler(answer_rs, connection)
-            value = self.get_utf8_value(value)
+            value = self.connection.get_utf8_value(value)
             xml.sax.parseString(value, h)
             self.answers.append(answer_rs)
         else: