def register(snapshot_id, region, size=None, arch=None, name=None, desc=None): conn = utils.connect(region) log.debug('getting snapshot - %s', snapshot_id) snapshot = conn.get_all_snapshots(snapshot_ids=[snapshot_id])[0] size = size if size else snapshot.volume_size name = name if name else snapshot.description desc = desc if desc else utils.parse_imagename(name)['url'] arch = arch if arch else utils.parse_imagename(name)['architecture'] kernel_id = utils.get_kernel(region, arch) arch_ec2 = "x86_64" if arch == "amd64" else arch log.debug('creating block_device_map') rootfs = BlockDeviceType() rootfs.delete_on_termination = True rootfs.size = size rootfs.snapshot_id = snapshot_id ephemeral = BlockDeviceType() ephemeral.ephemeral_name = 'ephemeral0' block_device_map = BlockDeviceMapping() block_device_map['/dev/sda1'] = rootfs block_device_map['/dev/sda2'] = ephemeral log.debug('registering image - %s', name) ami_id = conn.register_image(name=name, description=desc, architecture=arch_ec2, kernel_id=kernel_id, root_device_name="/dev/sda1", block_device_map=block_device_map) log.info('registered image - %s %s %s', ami_id, name, region) return ami_id
def test_run_instances_block_device_mapping(self): # Same as the test in ``unit/ec2/autoscale/test_group.py:TestLaunchConfiguration``, # but with modified request parameters (due to a mismatch between EC2 & # Autoscaling). self.set_http_response(status_code=200) dev_sdf = BlockDeviceType(snapshot_id='snap-12345') dev_sdg = BlockDeviceType(snapshot_id='snap-12346') bdm = BlockDeviceMapping() bdm['/dev/sdf'] = dev_sdf bdm['/dev/sdg'] = dev_sdg response = self.service_connection.run_instances( image_id='123456', instance_type='m1.large', security_groups=['group1', 'group2'], block_device_map=bdm ) self.assert_request_parameters({ 'Action': 'RunInstances', 'BlockDeviceMapping.1.DeviceName': '/dev/sdf', 'BlockDeviceMapping.1.Ebs.DeleteOnTermination': 'false', 'BlockDeviceMapping.1.Ebs.SnapshotId': 'snap-12345', 'BlockDeviceMapping.2.DeviceName': '/dev/sdg', 'BlockDeviceMapping.2.Ebs.DeleteOnTermination': 'false', 'BlockDeviceMapping.2.Ebs.SnapshotId': 'snap-12346', 'ImageId': '123456', 'InstanceType': 'm1.large', 'MaxCount': 1, 'MinCount': 1, 'SecurityGroup.1': 'group1', 'SecurityGroup.2': 'group2', }, ignore_params_values=[ 'Version', 'AWSAccessKeyId', 'SignatureMethod', 'SignatureVersion', 'Timestamp' ])
def create_instance(connection, instance_name, config, key_name): bdm = None if 'device_map' in config: bdm = BlockDeviceMapping() for device, device_info in config['device_map'].items(): bdm[device] = BlockDeviceType(size=device_info['size'], delete_on_termination=True) if 'user_data_file' in config: log.debug("reading user_data from '%s'" % config['user_data_file']) user_data = open(config['user_data_file']).read() # assert that there are no values in need of formatting user_data = user_data.format() else: user_data = None subnet_id = random.choice(config.get('subnet_ids')) interface = NetworkInterfaceSpecification( subnet_id=subnet_id, delete_on_termination=True, groups=config.get('security_group_ids', []), associate_public_ip_address=config.get("use_public_ip")) interfaces = NetworkInterfaceCollection(interface) reservation = connection.run_instances( image_id=config['ami'], key_name=key_name, instance_type=config['instance_type'], block_device_map=bdm, client_token=str(uuid.uuid4())[:16], disable_api_termination=bool(config.get('disable_api_termination')), user_data=user_data, instance_profile_name=config.get('instance_profile_name'), network_interfaces=interfaces, ) instance = reservation.instances[0] instance.add_tag('Name', instance_name) log.info("instance %s created, waiting to come up", instance) # Wait for the instance to come up wait_for_status(instance, 'state', 'running', 'update') log.info("instance %s is running; waiting for shutdown", instance) wait_for_status(instance, 'state', 'stopped', 'update') log.info("clearing userData") instance.modify_attribute("userData", None) return instance
def clone_instance(instance): new_bdm = None ec2 = instance.connection if instance.block_device_mapping: root_device_name = instance.get_attribute( 'rootDeviceName')['rootDeviceName'] user_data = instance.get_attribute('userData')['userData'] # user_data comes back base64 encoded. Need to decode it so it # can get re-encoded by run_instance ! user_data = base64.b64decode(user_data) new_bdm = BlockDeviceMapping() for dev in instance.block_device_mapping: # if this entry is about the root device, skip it if dev != root_device_name: bdt = instance.block_device_mapping[dev] if bdt.volume_id: volume = ec2.get_all_volumes([bdt.volume_id])[0] snaps = volume.snapshots() if len(snaps) == 0: print 'No snapshots available for %s' % volume.id else: # sort the list of snapshots, newest is at the end now snaps.sort(key=lambda snap: snap.start_time) latest_snap = snaps[-1] new_bdt = BlockDeviceType() new_bdt.snapshot_id = latest_snap.id new_bdm[dev] = new_bdt return ec2.run_instances(instance.image_id, key_name=instance.key_name, security_groups=[g.name for g in instance.groups], user_data=user_data, instance_type=instance.instance_type, kernel_id=instance.kernel, ramdisk_id=instance.ramdisk, monitoring_enabled=instance.monitored, placement=instance.placement, block_device_map=new_bdm).instances[0]
def _get_bmap(self, params): bmap = BlockDeviceMapping() for device in params['bmap']: if not 'name' in device.keys(): self.logger.debug('bad device ' + str(device)) continue dev = BlockDeviceType() if 'size' in device.keys(): dev.size = device['size'] if 'delete_on_termination' in device.keys(): dev.delete_on_termination = device['delete_on_termination'] if 'ephemeral_name' in device.keys(): dev.ephemeral_name = device['ephemeral_name'] bmap[device['name']] = dev return bmap
def _parse_block_device_mappings(self): block_device_map = BlockDeviceMapping() for mapping in self.block_device_mapping_dict: block_type = BlockDeviceType() mount_point = mapping.get('device_name') if 'ephemeral' in mapping.get('virtual_name', ''): block_type.ephemeral_name = mapping.get('virtual_name') else: block_type.volume_type = mapping.get('ebs._volume_type') block_type.snapshot_id = mapping.get('ebs._snapshot_id') block_type.delete_on_termination = mapping.get('ebs._delete_on_termination') block_type.size = mapping.get('ebs._volume_size') block_type.iops = mapping.get('ebs._iops') block_device_map[mount_point] = block_type return block_device_map
def create_image(module, ec2): """ Creates new AMI module : AnsibleModule object ec2: authenticated ec2 connection object """ instance_id = module.params.get('instance_id') name = module.params.get('name') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) description = module.params.get('description') no_reboot = module.params.get('no_reboot') device_mapping = module.params.get('device_mapping') tags = module.params.get('tags') launch_permissions = module.params.get('launch_permissions') try: params = { 'instance_id': instance_id, 'name': name, 'description': description, 'no_reboot': no_reboot } images = ec2.get_all_images(filters={'name': name}) if images and images[0]: module.exit_json(msg="AMI name already present", image_id=images[0].id, state=images[0].state, changed=False) if device_mapping: bdm = BlockDeviceMapping() for device in device_mapping: if 'device_name' not in device: module.fail_json(msg='Device name must be set for volume') device_name = device['device_name'] del device['device_name'] bd = BlockDeviceType(**device) bdm[device_name] = bd params['block_device_mapping'] = bdm image_id = ec2.create_image(**params) except boto.exception.BotoServerError, e: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message))
def start_instances(ec2cxn, instance_count, image_id, use_ephemeral=False, instance_type="c1.xlarge"): print "Attempting to start ", instance_count, " instances of image: ", image_id if use_ephemeral: dev_map = BlockDeviceMapping() sdb1 = BlockDeviceType() sdb1.ephemeral_name = 'ephemeral0' dev_map['/dev/sdb1'] = sdb1 reservation = ec2cxn.run_instances(image_id, min_count=1, max_count=instance_count, block_device_map=dev_map, security_groups=SECURITY_GROUPS, key_name="capk", instance_type=instance_type) else: reservation = ec2cxn.run_instances(image_id, min_count=1, max_count=instance_count, security_groups=SECURITY_GROUPS, key_name="capk", instance_type=instance_type) instances = reservation.instances # never leave instances running at the end of the script def kill_instances(): for instance in instances: instance.update() if instance.state != 'terminated': print "Killing ", instance instance.terminate() atexit.register(kill_instances) print "Started ", instance_count, " instances" for i in instances: print " =>", i.id if len(instances) != instance_count: print "Expected %d instances, got %d" % (instance_count, len(instances)) return instances
def _process_block_device_mappings(self, launch_config, zone=None): """ Processes block device mapping information and returns a Boto BlockDeviceMapping object. If new volumes are requested (source is None and destination is VOLUME), they will be created and the relevant volume ids included in the mapping. """ bdm = BlockDeviceMapping() # Assign letters from f onwards # http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html next_letter = iter(list(string.ascii_lowercase[6:])) # assign ephemeral devices from 0 onwards ephemeral_counter = 0 for device in launch_config.block_devices: bd_type = BlockDeviceType() if device.is_volume: if device.is_root: bdm['/dev/sda1'] = bd_type else: bdm['sd' + next(next_letter)] = bd_type if isinstance(device.source, Snapshot): bd_type.snapshot_id = device.source.id elif isinstance(device.source, Volume): bd_type.volume_id = device.source.id elif isinstance(device.source, MachineImage): # Not supported pass else: # source is None, but destination is volume, therefore # create a blank volume. If the Zone is None, this # could fail since the volume and instance may be created # in two different zones. if not zone: raise InvalidConfigurationException( "A zone must be specified when launching with a" " new blank volume block device mapping.") new_vol = self.provider.block_store.volumes.create( '', device.size, zone) bd_type.volume_id = new_vol.id bd_type.delete_on_terminate = device.delete_on_terminate if device.size: bd_type.size = device.size else: # device is ephemeral bd_type.ephemeral_name = 'ephemeral%s' % ephemeral_counter return bdm
def _parse_block_device_mappings(self): block_device_map = BlockDeviceMapping() for mapping in self.block_device_mapping_dict: block_type = BlockDeviceType() mount_point = mapping.get("device_name") if "ephemeral" in mapping.get("virtual_name", ""): block_type.ephemeral_name = mapping.get("virtual_name") else: block_type.volume_type = mapping.get("ebs._volume_type") block_type.snapshot_id = mapping.get("ebs._snapshot_id") block_type.delete_on_termination = mapping.get( "ebs._delete_on_termination") block_type.size = mapping.get("ebs._volume_size") block_type.iops = mapping.get("ebs._iops") block_device_map[mount_point] = block_type return block_device_map
def _get_block_device_mapping(device_name, size): """ Returns a block device mapping object for the specified device and size. Block Device Mapping is used to associate a device on the VM with an EBS Volume. parameters: device_name -- The name of the device in the VM, such as /dev/sda1, /dev/sdb1. etc size -- The amount of space to allocate for the EBS drive. """ block_device = BlockDeviceType() block_device.size = size bdm = BlockDeviceMapping() bdm[device_name] = block_device return bdm
def capture(self): volume = self.ec2.get_all_volumes( filters={ 'attachment.instance-id': self.instance.id, 'attachment.device': self.root_device, })[0] snapshot = self.ec2.create_snapshot(volume.id) sys.stdout.write("waiting for snapshot to complete ..") while snapshot.status != 'completed': sys.stdout.write(".") sys.stdout.flush() time.sleep(5) snapshot.update() sys.stdout.write("\n") # create EBS mapping device = BlockDeviceType() device.snapshot_id = snapshot.id mapping = BlockDeviceMapping() mapping['/dev/sda'] = device self.get_instance_kernel() image = self.ec2.register_image(name=self.name, description=self.name, architecture=self.arch, kernel_id=self.instance_kernel.id, root_device_name='/dev/sda', block_device_map=mapping) if self.settings["target/permission"] == "public": self.ec2.modify_image_attribute(image, groups='all') with open(self.settings["path/mirror/target"], "w") as fd: cmd = [ "ec2-run-instances", "--region", self.region, "--instance-type", "t1.micro", image, ] fd.write(" ".join(cmd)) fd.write("\n")
def run(cls, info): registration_params = { 'name': info._ec2['ami_name'], 'description': info._ec2['ami_description'] } registration_params['architecture'] = { 'i386': 'i386', 'amd64': 'x86_64' }.get(info.manifest.system['architecture']) if info.manifest.volume['backing'] == 's3': registration_params['image_location'] = info._ec2[ 'manifest_location'] else: root_dev_name = { 'pvm': '/dev/sda', 'hvm': '/dev/xvda' }.get(info.manifest.provider['virtualization']) registration_params['root_device_name'] = root_dev_name from boto.ec2.blockdevicemapping import BlockDeviceType from boto.ec2.blockdevicemapping import BlockDeviceMapping block_device = BlockDeviceType( snapshot_id=info._ec2['snapshot'].id, delete_on_termination=True, size=info.volume.size.bytes.get_qty_in('GiB'), volume_type='gp2') registration_params['block_device_map'] = BlockDeviceMapping() registration_params['block_device_map'][ root_dev_name] = block_device if info.manifest.provider['virtualization'] == 'hvm': registration_params['virtualization_type'] = 'hvm' else: registration_params['virtualization_type'] = 'paravirtual' akis_path = os.path.join(os.path.dirname(__file__), 'ami-akis.yml') from bootstrapvz.common.tools import config_get registration_params['kernel_id'] = config_get( akis_path, [info._ec2['region'], info.manifest.system['architecture']]) if info.manifest.provider.get('enhanced_networking', None) == 'simple': registration_params['sriov_net_support'] = 'simple' info._ec2['image'] = info._ec2['connection'].register_image( **registration_params)
def create_image(module, ec2): """ Creates new AMI module : AnsibleModule object ec2: authenticated ec2 connection object """ instance_id = module.params.get('instance_id') name = module.params.get('name') wait = module.params.get('wait') wait_timeout = int(module.params.get('wait_timeout')) description = module.params.get('description') no_reboot = module.params.get('no_reboot') device_mapping = module.params.get('device_mapping') tags = module.params.get('tags') try: params = {'instance_id': instance_id, 'name': name, 'description': description, 'no_reboot': no_reboot} if device_mapping: bdm = BlockDeviceMapping() for device in device_mapping: if 'device_name' not in device: module.fail_json(msg = 'Device name must be set for volume') device_name = device['device_name'] del device['device_name'] bd = BlockDeviceType(**device) bdm[device_name] = bd params['block_device_mapping'] = bdm image_id = ec2.create_image(**params) except boto.exception.BotoServerError, e: if e.error_code == 'InvalidAMIName.Duplicate': images = ec2.get_all_images() for img in images: if img.name == name: module.exit_json(msg="AMI name already present", image_id=img.id, state=img.state, changed=False) sys.exit(0) else: module.fail_json(msg="Error in retrieving duplicate AMI details") else: module.fail_json(msg="%s: %s" % (e.error_code, e.error_message))
def get_block_device(instance_type, ebs_vol_size): block_map = BlockDeviceMapping() if ebs_vol_size > 0: device = EBSBlockDeviceType() device.size = ebs_vol_size device.delete_on_termination = True block_map["/dev/sdv"] = device for i in range(get_num_disks(instance_type)): dev = BlockDeviceType() dev.ephemeral_name = 'ephemeral%d' % i # The first ephemeral drive is /dev/sdb. name = '/dev/sd' + string.ascii_letters[i + 1] block_map[name] = dev return block_map
def run_instance(self, image_id, security_group_ids=None, instance_type='c3.xlarge', placement=None, block_device_map=None, subnet_id=None, user_data=None, ebs_optimized=True, instance_profile_name=None): instance = Instance() instance.id = new_id() instance.image_id = image_id instance.root_device_name = '/dev/sda1' instance._state.code = 0 instance._state.name = 'pending' # Create volumes based on block device data from the image. image = self.get_image(image_id) instance_bdm = BlockDeviceMapping() for device_name, bdm in image.block_device_mapping.iteritems(): # Create a new volume and attach it to the instance. volume = Volume() volume.size = 8 volume.id = new_id() self.volumes[volume.id] = volume bdt = BlockDeviceType(volume_id=volume.id, size=8) instance_bdm[device_name] = bdt instance.block_device_mapping = instance_bdm self.instances[instance.id] = instance if self.run_instance_callback: args = RunInstanceArgs() args.image_id = image_id args.instance_type = instance_type args.ebs_optimized = ebs_optimized args.security_group_ids = security_group_ids args.subnet_id = subnet_id args.user_data = user_data args.instance = instance self.run_instance_callback(args) return instance
def create_root_block_device(self): # if the root volume size is not the same as the AMI default value: if self.root_volume_size is not None: # sda rather than xvda (for Windows) dev_sda1 = BlockDeviceType() dev_sda1.size = self.root_volume_size dev_sda1.delete_on_termination = True volume = BlockDeviceMapping() # Check the OS type, if its windows we use sda, linux: xvda images = self.ec2.get_all_images(image_ids=[self.node_obj.ami]) image = images[0] if image.platform is None: volume['/dev/xvda'] = dev_sda1 else: volume['/dev/sda1'] = dev_sda1 self.volumes = volume
def test_detect_double_encryption(self): """ Test that we disallow encryption of an already encrypted AMI. """ aws_svc = test_aws_service.DummyAWSService() # Register guest image bdm = BlockDeviceMapping() bdm['/dev/sda1'] = BlockDeviceType() id = aws_svc.register_image(kernel_id=None, name='Guest image', block_device_map=bdm) guest_image = aws_svc.get_image(id) # Make the guest image look like it was already encrypted and # make sure that validation fails. guest_image.tags[encrypt_ami.TAG_ENCRYPTOR] = 'ami-' + new_id() with self.assertRaises(ValidationError): brkt_cli.aws._validate_guest_ami(aws_svc, id)
def get_block_device_map(source_image): block_device_map = BlockDeviceMapping() for item in source_image.block_device_mapping: source_snapshot_id = source_image.block_device_mapping[ item].snapshot_id target_snapshot_size = source_image.block_device_mapping[item].size delete_on_termination = source_image.block_device_mapping[ item].delete_on_termination volume_type = source_image.block_device_mapping[item].volume_type device_name = str(item) block_device_map[device_name] = BlockDeviceType( snapshot_id=source_snapshot_id, size=target_snapshot_size, volume_type=volume_type, delete_on_termination=delete_on_termination) return block_device_map
def create_block_device(module, volume): # Not aware of a way to determine this programatically # http://aws.amazon.com/about-aws/whats-new/2013/10/09/ebs-provisioned-iops-maximum-iops-gb-ratio-increased-to-30-1/ MAX_IOPS_TO_SIZE_RATIO = 30 if 'snapshot' not in volume and 'ephemeral' not in volume: if 'volume_size' not in volume: module.fail_json(msg='Size must be specified when creating a new volume or modifying the root volume') if 'snapshot' in volume: if 'device_type' in volume and volume.get('device_type') == 'io1' and 'iops' not in volume: module.fail_json(msg='io1 volumes must have an iops value set') if 'ephemeral' in volume: if 'snapshot' in volume: module.fail_json(msg='Cannot set both ephemeral and snapshot') return BlockDeviceType(snapshot_id=volume.get('snapshot'), ephemeral_name=volume.get('ephemeral'), size=volume.get('volume_size'), volume_type=volume.get('device_type'), delete_on_termination=volume.get('delete_on_termination', False), iops=volume.get('iops'))
def copy_snapshots_by_ami(conn, source_image, region): block_device_map = BlockDeviceMapping() for item in source_image.block_device_mapping: source_snapshot_id = source_image.block_device_mapping[ item].snapshot_id target_snapshot_size = source_image.block_device_mapping[item].size delete_on_termination = source_image.block_device_mapping[ item].delete_on_termination volume_type = source_image.block_device_mapping[item].volume_type target_snapshot_id = copy_snapshot(conn, region, source_snapshot_id) print 'New snapshot created: {}'.format(target_snapshot_id) device_name = str(item) block_device_map[device_name] = BlockDeviceType( snapshot_id=target_snapshot_id, size=target_snapshot_size, volume_type=volume_type, delete_on_termination=delete_on_termination) return block_device_map
def start_remote(self): self.get_bootstrap_kernel() self.get_bootstrap_image() # create EBS volume for /mnt/gentoo device = BlockDeviceType() device.size = self.settings["ec2/instance/device/size"] device.delete_on_termination = True mapping = BlockDeviceMapping() self.root_device = "/dev/" + self.settings["ec2/instance/device/name"] mapping[self.root_device] = device # start bootstrapping instance reservation = self.ec2.run_instances( self.bootstrap_image.id, kernel_id=self.bootstrap_kernel.id, instance_type=self.settings["ec2/instance/type"], security_groups=[self.name], key_name=self.name, block_device_map=mapping) self.instance = reservation.instances[0] sys.stdout.write("waiting for instance to come up ..") while self.instance.update() != 'running': sys.stdout.write(".") sys.stdout.flush() time.sleep(5) sys.stdout.write("\n") time.sleep(120) self.ssh_uri = "ec2-user@" + self.instance.public_dns_name self.remote_upload_path = "/tmp" # enable sudo without a tty cmd = "sudo sed -i -e '/requiretty/d' /etc/sudoers" cmd = ["ssh", "-t"] + self.ssh_options() + [self.ssh_uri, cmd] ssh = subprocess.Popen(cmd) ssh.wait() self.run_script_at_remote("steps/remote/postboot")
def run(cls, info): registration_params = { 'name': info.ami_name, 'description': info.ami_description } registration_params['architecture'] = { 'i386': 'i386', 'amd64': 'x86_64' }.get(info.manifest.system['architecture']) if info.manifest.volume['backing'] == 's3': registration_params[ 'image_location'] = info.manifest.manifest_location else: root_dev_name = { 'pvm': '/dev/sda', 'hvm': '/dev/xvda' }.get(info.manifest.data['virtualization']) registration_params['root_device_name'] = root_dev_name from boto.ec2.blockdevicemapping import BlockDeviceType from boto.ec2.blockdevicemapping import BlockDeviceMapping block_device = BlockDeviceType( snapshot_id=info.snapshot.id, delete_on_termination=True, size=info.volume.size.get_qty_in('GiB')) registration_params['block_device_map'] = BlockDeviceMapping() registration_params['block_device_map'][ root_dev_name] = block_device if info.manifest.data['virtualization'] == 'hvm': registration_params['virtualization_type'] = 'hvm' else: registration_params['virtualization_type'] = 'paravirtual' akis_path = os.path.join(os.path.dirname(__file__), 'ami-akis.json') from common.tools import config_get registration_params['kernel_id'] = config_get( akis_path, [info.host['region'], info.manifest.system['architecture']]) info.image = info.connection.register_image(**registration_params)
def volume_to_ami(volume, ami_name, arch, virtualization_type, root_device_name, tags, kernel_id=None): log.info('Creating a snapshot') snap = volume.create_snapshot(ami_name) wait_for_status(snap, "status", "completed", "update") snap.add_tag("Name", ami_name) bdm = BlockDeviceMapping() bdm[root_device_name] = BlockDeviceType(snapshot_id=snap.id) log.info('Creating AMI') ami_id = volume.connection.register_image( ami_name, ami_name, architecture=arch, kernel_id=kernel_id, root_device_name=root_device_name, block_device_map=bdm, virtualization_type=virtualization_type, ) log.info('Waiting...') while True: try: ami = volume.connection.get_image(ami_id) ami.add_tag('Name', ami_name) ami.add_tag('moz-created', int(time.time())) for tag, value in tags.iteritems(): ami.add_tag(tag, value) log.info('AMI created') log.info('ID: {id}, name: {name}'.format(id=ami.id, name=ami.name)) break except: # noqa: E722 log.info('Wating for AMI') time.sleep(10) wait_for_status(ami, "state", "available", "update") return ami
def create_block_device(module, ec2, volume): # Not aware of a way to determine this programatically # http://aws.amazon.com/about-aws/whats-new/2013/10/09/ebs-provisioned-iops-maximum-iops-gb-ratio-increased-to-30-1/ MAX_IOPS_TO_SIZE_RATIO = 30 if 'snapshot' not in volume and 'ephemeral' not in volume: if 'volume_size' not in volume: module.fail_json( msg= 'Size must be specified when creating a new volume or modifying the root volume' ) if 'snapshot' in volume: if 'device_type' in volume and volume.get( 'device_type') == 'io1' and 'iops' not in volume: module.fail_json(msg='io1 volumes must have an iops value set') if 'iops' in volume: snapshot = ec2.get_all_snapshots( snapshot_ids=[volume['snapshot']])[0] size = volume.get('volume_size', snapshot.volume_size) if int(volume['iops']) > MAX_IOPS_TO_SIZE_RATIO * size: module.fail_json( msg='IOPS must be at most %d times greater than size' % MAX_IOPS_TO_SIZE_RATIO) if 'encrypted' in volume: module.fail_json( msg= 'You can not set encyrption when creating a volume from a snapshot' ) if 'ephemeral' in volume: if 'snapshot' in volume: module.fail_json(msg='Cannot set both ephemeral and snapshot') return BlockDeviceType(snapshot_id=volume.get('snapshot'), ephemeral_name=volume.get('ephemeral'), size=volume.get('volume_size'), volume_type=volume.get('device_type'), delete_on_termination=volume.get( 'delete_on_termination', False), iops=volume.get('iops'), encrypted=volume.get('encrypted', None))
def parse_block_device_args(self, block_device_maps_args): block_device_map = BlockDeviceMapping() for block_device_map_arg in block_device_maps_args: parts = block_device_map_arg.split('=') if len(parts) > 1: device_name = parts[0] block_dev_type = BlockDeviceType() value_parts = parts[1].split(':') if value_parts[0].startswith('snap'): block_dev_type.snapshot_id = value_parts[0] else: if value_parts[0].startswith('ephemeral'): block_dev_type.ephemeral_name = value_parts[0] if len(value_parts) > 1: try: block_dev_type.size = int(value_parts[1]) except ValueError: pass if len(value_parts) > 2: if value_parts[2] == 'true': block_dev_type.delete_on_termination = True block_device_map[device_name] = block_dev_type return block_device_map
def get_block_device_map(bdmapping_json=None): """Parse block_device_mapping JSON and return a configured BlockDeviceMapping object Mapping JSON structure... {"/dev/sda": {"snapshot_id": "snap-23E93E09", "volume_type": null, "delete_on_termination": true, "size": 1} } """ if bdmapping_json: mapping = json.loads(bdmapping_json) if mapping: bdm = BlockDeviceMapping() for key, val in mapping.items(): device = BlockDeviceType() if val.get('virtual_name') is not None and val.get('virtual_name').startswith('ephemeral'): device.ephemeral_name = val.get('virtual_name') else: device.volume_type = 'standard' device.snapshot_id = val.get('snapshot_id') or None device.size = val.get('size') device.delete_on_termination = val.get('delete_on_termination', False) bdm[key] = device return bdm return None return None
def snapshots_register(self): snapshot_id = self.request.params.get('snapshot_id') snapshot = self.get_snapshot( snapshot_id) if snapshot_id != 'new' else None name = self.request.params.get('name') description = self.request.params.get('description') dot = self.request.params.get('dot') reg_as_windows = self.request.params.get('reg_as_windows') root_vol = BlockDeviceType(snapshot_id=snapshot_id) root_vol.delete_on_termination = dot bdm = BlockDeviceMapping() root_device_name = '/dev/sda' if self.cloud_type == 'euca' else '/dev/sda1' bdm[root_device_name] = root_vol location = self.get_redirect_location('snapshots') if snapshot and self.register_form.validate(): with boto_error_handler(self.request, location): self.log_request( _(u"Registering snapshot {0} as image {1}").format( snapshot_id, name)) image_id = snapshot.connection.register_image( name=name, description=description, root_device_name=root_device_name, kernel_id=('windows' if reg_as_windows else None), block_device_map=bdm) prefix = _(u'Successfully registered snapshot') msg = u'{prefix} {id}'.format(prefix=prefix, id=snapshot_id) # Clear images cache self.invalidate_images_cache() location = self.request.route_path('image_view', id=image_id) self.request.session.flash(msg, queue=Notification.SUCCESS) return HTTPFound(location=location) else: # TODO: need validation error! msg = _(u'Unable to register snapshot') self.request.session.flash(msg, queue=Notification.ERROR) return HTTPFound(location=location)
def create_block_device(module, ec2, volume): # Not aware of a way to determine this programatically # http://aws.amazon.com/about-aws/whats-new/2013/10/09/ebs-provisioned-iops-maximum-iops-gb-ratio-increased-to-30-1/ MAX_IOPS_TO_SIZE_RATIO = 30 # device_type has been used historically to represent volume_type, # however ec2_vol uses volume_type, as does the BlockDeviceType, so # we add handling for either/or but not both if all(key in volume for key in ['device_type','volume_type']): module.fail_json(msg = 'device_type is a deprecated name for volume_type. Do not use both device_type and volume_type') # get whichever one is set, or NoneType if neither are set volume_type = volume.get('device_type') or volume.get('volume_type') if 'snapshot' not in volume and 'ephemeral' not in volume: if 'volume_size' not in volume: module.fail_json(msg = 'Size must be specified when creating a new volume or modifying the root volume') if 'snapshot' in volume: if volume_type == 'io1' and 'iops' not in volume: module.fail_json(msg = 'io1 volumes must have an iops value set') if 'iops' in volume: snapshot = ec2.get_all_snapshots(snapshot_ids=[volume['snapshot']])[0] size = volume.get('volume_size', snapshot.volume_size) if int(volume['iops']) > MAX_IOPS_TO_SIZE_RATIO * size: module.fail_json(msg = 'IOPS must be at most %d times greater than size' % MAX_IOPS_TO_SIZE_RATIO) if 'encrypted' in volume: module.fail_json(msg = 'You can not set encyrption when creating a volume from a snapshot') if 'ephemeral' in volume: if 'snapshot' in volume: module.fail_json(msg = 'Cannot set both ephemeral and snapshot') return BlockDeviceType(snapshot_id=volume.get('snapshot'), ephemeral_name=volume.get('ephemeral'), size=volume.get('volume_size'), volume_type=volume_type, delete_on_termination=volume.get('delete_on_termination', False), iops=volume.get('iops'), encrypted=volume.get('encrypted', None))
def fire_up_instance(self): self.conn = boto.ec2.connect_to_region( self.config["region"], aws_access_key_id=self.config.get("aws_key", None), aws_secret_access_key=self.config.get("aws_secret_key", None)) mapping = BlockDeviceMapping() for device, eph_name in self.config["ephemeral_map"].iteritems(): mapping[device] = BlockDeviceType(ephemeral_name=eph_name) reservation = self.conn.run_instances( self.config["image"], key_name=self.config["key_name"], instance_type=self.config["instance_type"], security_groups=self.config["security_groups"], block_device_map=mapping, user_data=self.user_data, instance_profile_name=self.config["iam_role"], instance_initiated_shutdown_behavior=self.config["shutdown"]) instance = reservation.instances[0] name_string = "{0}-{1}-{2}".format(self.config["owner"], self.config["tags"]["App"], self.config["tags"]["Type"]) owner_tags = {"Name": name_string, "Owner": self.config["owner"]} self.conn.create_tags([instance.id], owner_tags) self.conn.create_tags([instance.id], self.config["tags"]) while instance.state == 'pending': print "Instance is pending -- Waiting 10s for instance", \ instance.id, "to start up..." time.sleep(10) instance.update() print("Instance {0} is {1}".format(instance.id, instance.state)) print("ubuntu@{0}".format(instance.public_dns_name))