OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/ |
| 2 # Copyright (c) 2010, Eucalyptus Systems, Inc. |
| 3 # |
| 4 # Permission is hereby granted, free of charge, to any person obtaining a |
| 5 # copy of this software and associated documentation files (the |
| 6 # "Software"), to deal in the Software without restriction, including |
| 7 # without limitation the rights to use, copy, modify, merge, publish, dis- |
| 8 # tribute, sublicense, and/or sell copies of the Software, and to permit |
| 9 # persons to whom the Software is furnished to do so, subject to the fol- |
| 10 # lowing conditions: |
| 11 # |
| 12 # The above copyright notice and this permission notice shall be included |
| 13 # in all copies or substantial portions of the Software. |
| 14 # |
| 15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- |
| 17 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT |
| 18 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 21 # IN THE SOFTWARE. |
| 22 |
| 23 from boto.ec2.ec2object import EC2Object, TaggedEC2Object |
| 24 from boto.ec2.blockdevicemapping import BlockDeviceMapping |
| 25 |
| 26 class ProductCodes(list): |
| 27 |
| 28 def startElement(self, name, attrs, connection): |
| 29 pass |
| 30 |
| 31 def endElement(self, name, value, connection): |
| 32 if name == 'productCode': |
| 33 self.append(value) |
| 34 |
| 35 class Image(TaggedEC2Object): |
| 36 """ |
| 37 Represents an EC2 Image |
| 38 """ |
| 39 |
| 40 def __init__(self, connection=None): |
| 41 TaggedEC2Object.__init__(self, connection) |
| 42 self.id = None |
| 43 self.location = None |
| 44 self.state = None |
| 45 self.ownerId = None # for backwards compatibility |
| 46 self.owner_id = None |
| 47 self.owner_alias = None |
| 48 self.is_public = False |
| 49 self.architecture = None |
| 50 self.platform = None |
| 51 self.type = None |
| 52 self.kernel_id = None |
| 53 self.ramdisk_id = None |
| 54 self.name = None |
| 55 self.description = None |
| 56 self.product_codes = ProductCodes() |
| 57 self.block_device_mapping = None |
| 58 self.root_device_type = None |
| 59 self.root_device_name = None |
| 60 self.virtualization_type = None |
| 61 self.hypervisor = None |
| 62 self.instance_lifecycle = None |
| 63 |
| 64 def __repr__(self): |
| 65 return 'Image:%s' % self.id |
| 66 |
| 67 def startElement(self, name, attrs, connection): |
| 68 retval = TaggedEC2Object.startElement(self, name, attrs, connection) |
| 69 if retval is not None: |
| 70 return retval |
| 71 if name == 'blockDeviceMapping': |
| 72 self.block_device_mapping = BlockDeviceMapping() |
| 73 return self.block_device_mapping |
| 74 elif name == 'productCodes': |
| 75 return self.product_codes |
| 76 else: |
| 77 return None |
| 78 |
| 79 def endElement(self, name, value, connection): |
| 80 if name == 'imageId': |
| 81 self.id = value |
| 82 elif name == 'imageLocation': |
| 83 self.location = value |
| 84 elif name == 'imageState': |
| 85 self.state = value |
| 86 elif name == 'imageOwnerId': |
| 87 self.ownerId = value # for backwards compatibility |
| 88 self.owner_id = value |
| 89 elif name == 'isPublic': |
| 90 if value == 'false': |
| 91 self.is_public = False |
| 92 elif value == 'true': |
| 93 self.is_public = True |
| 94 else: |
| 95 raise Exception( |
| 96 'Unexpected value of isPublic %s for image %s'%( |
| 97 value, |
| 98 self.id |
| 99 ) |
| 100 ) |
| 101 elif name == 'architecture': |
| 102 self.architecture = value |
| 103 elif name == 'imageType': |
| 104 self.type = value |
| 105 elif name == 'kernelId': |
| 106 self.kernel_id = value |
| 107 elif name == 'ramdiskId': |
| 108 self.ramdisk_id = value |
| 109 elif name == 'imageOwnerAlias': |
| 110 self.owner_alias = value |
| 111 elif name == 'platform': |
| 112 self.platform = value |
| 113 elif name == 'name': |
| 114 self.name = value |
| 115 elif name == 'description': |
| 116 self.description = value |
| 117 elif name == 'rootDeviceType': |
| 118 self.root_device_type = value |
| 119 elif name == 'rootDeviceName': |
| 120 self.root_device_name = value |
| 121 elif name == 'virtualizationType': |
| 122 self.virtualization_type = value |
| 123 elif name == 'hypervisor': |
| 124 self.hypervisor = value |
| 125 elif name == 'instanceLifecycle': |
| 126 self.instance_lifecycle = value |
| 127 else: |
| 128 setattr(self, name, value) |
| 129 |
| 130 def _update(self, updated): |
| 131 self.__dict__.update(updated.__dict__) |
| 132 |
| 133 def update(self, validate=False): |
| 134 """ |
| 135 Update the image's state information by making a call to fetch |
| 136 the current image attributes from the service. |
| 137 |
| 138 :type validate: bool |
| 139 :param validate: By default, if EC2 returns no data about the |
| 140 image the update method returns quietly. If |
| 141 the validate param is True, however, it will |
| 142 raise a ValueError exception if no data is |
| 143 returned from EC2. |
| 144 """ |
| 145 rs = self.connection.get_all_images([self.id]) |
| 146 if len(rs) > 0: |
| 147 img = rs[0] |
| 148 if img.id == self.id: |
| 149 self._update(img) |
| 150 elif validate: |
| 151 raise ValueError('%s is not a valid Image ID' % self.id) |
| 152 return self.state |
| 153 |
| 154 def run(self, min_count=1, max_count=1, key_name=None, |
| 155 security_groups=None, user_data=None, |
| 156 addressing_type=None, instance_type='m1.small', placement=None, |
| 157 kernel_id=None, ramdisk_id=None, |
| 158 monitoring_enabled=False, subnet_id=None, |
| 159 block_device_map=None, |
| 160 disable_api_termination=False, |
| 161 instance_initiated_shutdown_behavior=None, |
| 162 private_ip_address=None, |
| 163 placement_group=None, security_group_ids=None, |
| 164 additional_info=None, instance_profile_name=None, |
| 165 instance_profile_arn=None, tenancy=None): |
| 166 |
| 167 """ |
| 168 Runs this instance. |
| 169 |
| 170 :type min_count: int |
| 171 :param min_count: The minimum number of instances to start |
| 172 |
| 173 :type max_count: int |
| 174 :param max_count: The maximum number of instances to start |
| 175 |
| 176 :type key_name: string |
| 177 :param key_name: The name of the keypair to run this instance with. |
| 178 |
| 179 :type security_groups: |
| 180 :param security_groups: |
| 181 |
| 182 :type user_data: |
| 183 :param user_data: |
| 184 |
| 185 :type addressing_type: |
| 186 :param daddressing_type: |
| 187 |
| 188 :type instance_type: string |
| 189 :param instance_type: The type of instance to run. Current choices are: |
| 190 m1.small | m1.large | m1.xlarge | c1.medium | |
| 191 c1.xlarge | m2.xlarge | m2.2xlarge | |
| 192 m2.4xlarge | cc1.4xlarge |
| 193 |
| 194 :type placement: string |
| 195 :param placement: The availability zone in which to launch the instances |
| 196 |
| 197 :type kernel_id: string |
| 198 :param kernel_id: The ID of the kernel with which to launch the instance
s |
| 199 |
| 200 :type ramdisk_id: string |
| 201 :param ramdisk_id: The ID of the RAM disk with which to launch the insta
nces |
| 202 |
| 203 :type monitoring_enabled: bool |
| 204 :param monitoring_enabled: Enable CloudWatch monitoring on the instance. |
| 205 |
| 206 :type subnet_id: string |
| 207 :param subnet_id: The subnet ID within which to launch the instances for
VPC. |
| 208 |
| 209 :type private_ip_address: string |
| 210 :param private_ip_address: If you're using VPC, you can optionally use |
| 211 this parameter to assign the instance a |
| 212 specific available IP address from the |
| 213 subnet (e.g., 10.0.0.25). |
| 214 |
| 215 :type block_device_map: :class:`boto.ec2.blockdevicemapping.BlockDeviceM
apping` |
| 216 :param block_device_map: A BlockDeviceMapping data structure |
| 217 describing the EBS volumes associated |
| 218 with the Image. |
| 219 |
| 220 :type disable_api_termination: bool |
| 221 :param disable_api_termination: If True, the instances will be locked |
| 222 and will not be able to be terminated |
| 223 via the API. |
| 224 |
| 225 :type instance_initiated_shutdown_behavior: string |
| 226 :param instance_initiated_shutdown_behavior: Specifies whether the insta
nce |
| 227 stops or terminates on inst
ance-initiated |
| 228 shutdown. Valid values are: |
| 229 stop | terminate |
| 230 |
| 231 :type placement_group: string |
| 232 :param placement_group: If specified, this is the name of the placement |
| 233 group in which the instance(s) will be launched. |
| 234 |
| 235 :type additional_info: string |
| 236 :param additional_info: Specifies additional information to make |
| 237 available to the instance(s) |
| 238 |
| 239 :type security_group_ids: |
| 240 :param security_group_ids: |
| 241 |
| 242 :type instance_profile_name: string |
| 243 :param instance_profile_name: The name of an IAM instance profile to use
. |
| 244 |
| 245 :type instance_profile_arn: string |
| 246 :param instance_profile_arn: The ARN of an IAM instance profile to use. |
| 247 |
| 248 :type tenancy: string |
| 249 :param tenancy: The tenancy of the instance you want to launch. An |
| 250 instance with a tenancy of 'dedicated' runs on |
| 251 single-tenant hardware and can only be launched into a |
| 252 VPC. Valid values are: "default" or "dedicated". |
| 253 NOTE: To use dedicated tenancy you MUST specify a VPC |
| 254 subnet-ID as well. |
| 255 |
| 256 :rtype: Reservation |
| 257 :return: The :class:`boto.ec2.instance.Reservation` associated with the
request for machines |
| 258 |
| 259 """ |
| 260 |
| 261 return self.connection.run_instances(self.id, min_count, max_count, |
| 262 key_name, security_groups, |
| 263 user_data, addressing_type, |
| 264 instance_type, placement, |
| 265 kernel_id, ramdisk_id, |
| 266 monitoring_enabled, subnet_id, |
| 267 block_device_map, disable_api_termi
nation, |
| 268 instance_initiated_shutdown_behavio
r, |
| 269 private_ip_address, placement_group
, |
| 270 security_group_ids=security_group_i
ds, |
| 271 additional_info=additional_info, |
| 272 instance_profile_name=instance_prof
ile_name, |
| 273 instance_profile_arn=instance_profi
le_arn, |
| 274 tenancy=tenancy) |
| 275 |
| 276 def deregister(self, delete_snapshot=False): |
| 277 return self.connection.deregister_image(self.id, delete_snapshot) |
| 278 |
| 279 def get_launch_permissions(self): |
| 280 img_attrs = self.connection.get_image_attribute(self.id, |
| 281 'launchPermission') |
| 282 return img_attrs.attrs |
| 283 |
| 284 def set_launch_permissions(self, user_ids=None, group_names=None): |
| 285 return self.connection.modify_image_attribute(self.id, |
| 286 'launchPermission', |
| 287 'add', |
| 288 user_ids, |
| 289 group_names) |
| 290 |
| 291 def remove_launch_permissions(self, user_ids=None, group_names=None): |
| 292 return self.connection.modify_image_attribute(self.id, |
| 293 'launchPermission', |
| 294 'remove', |
| 295 user_ids, |
| 296 group_names) |
| 297 |
| 298 def reset_launch_attributes(self): |
| 299 return self.connection.reset_image_attribute(self.id, |
| 300 'launchPermission') |
| 301 |
| 302 def get_kernel(self): |
| 303 img_attrs =self.connection.get_image_attribute(self.id, 'kernel') |
| 304 return img_attrs.kernel |
| 305 |
| 306 def get_ramdisk(self): |
| 307 img_attrs = self.connection.get_image_attribute(self.id, 'ramdisk') |
| 308 return img_attrs.ramdisk |
| 309 |
| 310 class ImageAttribute: |
| 311 |
| 312 def __init__(self, parent=None): |
| 313 self.name = None |
| 314 self.kernel = None |
| 315 self.ramdisk = None |
| 316 self.attrs = {} |
| 317 |
| 318 def startElement(self, name, attrs, connection): |
| 319 if name == 'blockDeviceMapping': |
| 320 self.attrs['block_device_mapping'] = BlockDeviceMapping() |
| 321 return self.attrs['block_device_mapping'] |
| 322 else: |
| 323 return None |
| 324 |
| 325 def endElement(self, name, value, connection): |
| 326 if name == 'launchPermission': |
| 327 self.name = 'launch_permission' |
| 328 elif name == 'group': |
| 329 if 'groups' in self.attrs: |
| 330 self.attrs['groups'].append(value) |
| 331 else: |
| 332 self.attrs['groups'] = [value] |
| 333 elif name == 'userId': |
| 334 if 'user_ids' in self.attrs: |
| 335 self.attrs['user_ids'].append(value) |
| 336 else: |
| 337 self.attrs['user_ids'] = [value] |
| 338 elif name == 'productCode': |
| 339 if 'product_codes' in self.attrs: |
| 340 self.attrs['product_codes'].append(value) |
| 341 else: |
| 342 self.attrs['product_codes'] = [value] |
| 343 elif name == 'imageId': |
| 344 self.image_id = value |
| 345 elif name == 'kernel': |
| 346 self.kernel = value |
| 347 elif name == 'ramdisk': |
| 348 self.ramdisk = value |
| 349 else: |
| 350 setattr(self, name, value) |
OLD | NEW |