Skip to content

Commit

Permalink
Adding support for EC2 Compute Cluster. Fixes issue 419.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mitch Garnaat committed Jul 21, 2010
2 parents 687bb32 + 1c8a28b commit 3212173
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 12 deletions.
77 changes: 70 additions & 7 deletions boto/ec2/connection.py
@@ -1,4 +1,4 @@
# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
# Copyright (c) 2006-2010 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
Expand Down Expand Up @@ -46,13 +46,14 @@
from boto.ec2.spotpricehistory import SpotPriceHistory
from boto.ec2.spotdatafeedsubscription import SpotDatafeedSubscription
from boto.ec2.bundleinstance import BundleInstanceTask
from boto.ec2.placementgroup import PlacementGroup
from boto.exception import EC2ResponseError

#boto.set_stream_logger('ec2')

class EC2Connection(AWSQueryConnection):

APIVersion = boto.config.get('Boto', 'ec2_version', '2009-11-30')
APIVersion = boto.config.get('Boto', 'ec2_version', '2010-06-15')
DefaultRegionName = boto.config.get('Boto', 'ec2_region_name', 'us-east-1')
DefaultRegionEndpoint = boto.config.get('Boto', 'ec2_region_endpoint',
'ec2.amazonaws.com')
Expand All @@ -69,7 +70,7 @@ def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
B{Note:} The host argument is overridden by the host specified in the boto configuration file.
"""
if not region:
region = RegionInfo(self, self.DefaultRegionName, self.DefaultRegionEndpoint, EC2Connection)
region = RegionInfo(self, self.DefaultRegionName, self.DefaultRegionEndpoint)
self.region = region
AWSQueryConnection.__init__(self, aws_access_key_id,
aws_secret_access_key,
Expand Down Expand Up @@ -383,7 +384,8 @@ def run_instances(self, image_id, min_count=1, max_count=1,
block_device_map=None,
disable_api_termination=False,
instance_initiated_shutdown_behavior=None,
private_ip_address=None):
private_ip_address=None,
placement_group=None):
"""
Runs an image on EC2.
Expand All @@ -406,7 +408,10 @@ def run_instances(self, image_id, min_count=1, max_count=1,
:param user_data: The user data passed to the launched instances
:type instance_type: string
:param instance_type: The type of instance to run (m1.small, m1.large, m1.xlarge)
:param instance_type: The type of instance to run. Current choices are:
m1.small | m1.large | m1.xlarge | c1.medium |
c1.xlarge | m2.xlarge | m2.2xlarge |
m2.4xlarge | cc1.4xlarge
:type placement: string
:param placement: The availability zone in which to launch the instances
Expand Down Expand Up @@ -435,8 +440,9 @@ def run_instances(self, image_id, min_count=1, max_count=1,
with the Image.
:type disable_api_termination: bool
:param disable_api_termination: If True, the instances will be locked and will
not be able to be terminated via the API.
:param disable_api_termination: If True, the instances will be locked
and will not be able to be terminated
via the API.
:type instance_initiated_shutdown_behavior: string
:param instance_initiated_shutdown_behavior: Specifies whether the instance's
Expand All @@ -446,6 +452,10 @@ def run_instances(self, image_id, min_count=1, max_count=1,
owner. Valid values are:
stop | terminate
:type placement_group: string
:param placement_group: If specified, this is the name of the placement
group in which the instance(s) will be launched.
:rtype: Reservation
:return: The :class:`boto.ec2.instance.Reservation` associated with the request for machines
"""
Expand All @@ -470,6 +480,8 @@ def run_instances(self, image_id, min_count=1, max_count=1,
params['InstanceType'] = instance_type
if placement:
params['Placement.AvailabilityZone'] = placement
if placement_group:
params['Placement.GroupName'] = placement_group
if kernel_id:
params['KernelId'] = kernel_id
if ramdisk_id:
Expand Down Expand Up @@ -1626,3 +1638,54 @@ def get_password_data(self, instance_id):
rs = self.get_object('GetPasswordData', params, ResultSet)
return rs.passwordData

#
# Cluster Placement Groups
#

def get_all_placement_groups(self, groupnames=None):
"""
Get all placement groups associated with your account in a region.
:type groupnames: list
:param groupnames: A list of the names of placement groups to retrieve.
If not provided, all placement groups will be returned.
:rtype: list
:return: A list of :class:`boto.ec2.placementgroup.PlacementGroup`
"""
params = {}
if groupnames:
self.build_list_params(params, groupnames, 'GroupName')
return self.get_list('DescribePlacementGroups', params, [('item', PlacementGroup)])

def create_placement_group(self, name, strategy='cluster'):
"""
Create a new placement group for your account.
This will create the placement group within the region you
are currently connected to.
:type name: string
:param name: The name of the new placement group
:type strategy: string
:param strategy: The placement strategy of the new placement group.
Currently, the only acceptable value is "cluster".
:rtype: :class:`boto.ec2.placementgroup.PlacementGroup`
:return: The newly created :class:`boto.ec2.keypair.KeyPair`.
"""
params = {'GroupName':name, 'Strategy':strategy}
group = self.get_status('CreatePlacementGroup', params)
return group

def delete_placement_group(self, name):
"""
Delete a placement group from your account.
:type key_name: string
:param key_name: The name of the keypair to delete
"""
params = {'GroupName':name}
return self.get_status('DeletePlacementGroup', params)


43 changes: 38 additions & 5 deletions boto/ec2/image.py
Expand Up @@ -117,7 +117,11 @@ def run(self, min_count=1, max_count=1, key_name=None,
addressing_type=None, instance_type='m1.small', placement=None,
kernel_id=None, ramdisk_id=None,
monitoring_enabled=False, subnet_id=None,
block_device_map=None):
block_device_map=None,
disable_api_termination=False,
instance_initiated_shutdown_behavior=None,
private_ip_address=None,
placement_group=None):
"""
Runs this instance.
Expand All @@ -140,10 +144,13 @@ def run(self, min_count=1, max_count=1, key_name=None,
:param daddressing_type:
:type instance_type: string
:param instance_type: The type of instance to run (m1.small, m1.large, m1.xlarge)
:param instance_type: The type of instance to run. Current choices are:
m1.small | m1.large | m1.xlarge | c1.medium |
c1.xlarge | m2.xlarge | m2.2xlarge |
m2.4xlarge | cc1.4xlarge
:type placement:
:param placement:
:type placement: string
:param placement: The availability zone in which to launch the instances
:type kernel_id: string
:param kernel_id: The ID of the kernel with which to launch the instances
Expand All @@ -157,11 +164,34 @@ def run(self, min_count=1, max_count=1, key_name=None,
:type subnet_id: string
:param subnet_id: The subnet ID within which to launch the instances for VPC.
:type private_ip_address: string
:param private_ip_address: If you're using VPC, you can optionally use
this parameter to assign the instance a
specific available IP address from the
subnet (e.g., 10.0.0.25).
:type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceMapping`
:param block_device_map: A BlockDeviceMapping data structure
describing the EBS volumes associated
with the Image.
:type disable_api_termination: bool
:param disable_api_termination: If True, the instances will be locked
and will not be able to be terminated
via the API.
:type instance_initiated_shutdown_behavior: string
:param instance_initiated_shutdown_behavior: Specifies whether the instance's
EBS volues are stopped (i.e. detached)
or terminated (i.e. deleted) when
the instance is shutdown by the
owner. Valid values are:
stop | terminate
:type placement_group: string
:param placement_group: If specified, this is the name of the placement
group in which the instance(s) will be launched.
:rtype: Reservation
:return: The :class:`boto.ec2.instance.Reservation` associated with the request for machines
"""
Expand All @@ -171,7 +201,10 @@ def run(self, min_count=1, max_count=1, key_name=None,
instance_type, placement,
kernel_id, ramdisk_id,
monitoring_enabled, subnet_id,
block_device_map)
block_device_map, disable_api_termination,
instance_initiated_shutdown_behavior,
private_ip_address,
placement_group)

def deregister(self):
return self.connection.deregister_image(self.id)
Expand Down
4 changes: 4 additions & 0 deletions boto/ec2/instance.py
Expand Up @@ -100,6 +100,7 @@ def __init__(self, connection=None):
self.root_device_type = None
self.block_device_mapping = None
self.state_reason = None
self.group_name = None

def __repr__(self):
return 'Instance:%s' % self.id
Expand Down Expand Up @@ -185,6 +186,9 @@ def endElement(self, name, value, connection):
self.persistent = True
else:
self.persistent = False
elif name == 'groupName':
if self._in_monitoring_element:
self.group_name = value
else:
setattr(self, name, value)

Expand Down
51 changes: 51 additions & 0 deletions boto/ec2/placementgroup.py
@@ -0,0 +1,51 @@
# Copyright (c) 2010 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 Placement Group
"""
from boto.ec2.ec2object import EC2Object
from boto.exception import BotoClientError

class PlacementGroup(EC2Object):

def __init__(self, connection=None, name=None, strategy=None, state=None):
EC2Object.__init__(self, connection)
self.name = name
self.strategy = strategy
self.state = state

def __repr__(self):
return 'PlacementGroup:%s' % self.name

def endElement(self, name, value, connection):
if name == 'groupName':
self.name = value
elif name == 'strategy':
self.strategy = value
elif name == 'state':
self.state = value
else:
setattr(self, name, value)

def delete(self):
return self.connection.delete_placement_group(self.name)


0 comments on commit 3212173

Please sign in to comment.