Exemplo n.º 1
0
def test_launch_config_add_with_block_device_mapping(sys, user_input):
    sys.argv = [
        'autoscaler_launch_config',
        'add',
        'web',
    ]

    # "image_id", "key_name", "security_groups", "user_data", "instance_type",
    # "kernel_id", "ramdisk_id", "block_device_mappings", "instance_monitoring",
    # "instance_profile_name", "spot_price", "ebs_optimized", "associate_public_ip_address"
    user_input.side_effect = [
        'ami-1234abcd',
        'the_key',
        "default,web",
        "echo 'web' > /etc/config",
        "m1.small",
        "",
        "",
        "/dev/xvda=:100,/dev/xvdb=:200,/dev/xvdc=snap-1234abcd:10",
        "yes",
        "arn:aws:iam::123456789012:instance-profile/tester",
        "0.2",
        "yes",
        "",
    ]

    # Simulate CLI call
    launch_config()

    # Build a fake block device mapping
    bdm = BlockDeviceMapping()
    bdm['/dev/xvda'] = BlockDeviceType(volume_id='/dev/xvda', size=100)
    bdm['/dev/xvdb'] = BlockDeviceType(volume_id='/dev/xvdb', size=200)
    bdm['/dev/xvdc'] = BlockDeviceType(volume_id='/dev/xvdc',
                                       snapshot_id="snap-1234abcd",
                                       size=10)

    conn = boto.connect_autoscale(use_block_device_types=True)
    configs = conn.get_all_launch_configurations()
    configs.should.have.length_of(1)
    config = configs[0]
    config.name.should.equal("web")
    config.image_id.should.equal("ami-1234abcd")
    config.key_name.should.equal("the_key")
    set(config.security_groups).should.equal(set(["web", "default"]))
    config.user_data.should.equal("echo 'web' > /etc/config")
    config.instance_type.should.equal("m1.small")
    config.kernel_id.should.equal("")
    config.ramdisk_id.should.equal("")
    config.instance_monitoring.enabled.should.equal('true')
    config.spot_price.should.equal(0.2)
    config.ebs_optimized.should.equal(True)
    config.associate_public_ip_address.should.equal(False)
    config.block_device_mappings.keys().should.equal(bdm.keys())
    config.block_device_mappings['/dev/xvda'].size.should.equal(100)
    config.block_device_mappings['/dev/xvdb'].size.should.equal(200)
    config.block_device_mappings['/dev/xvdc'].size.should.equal(10)
    config.block_device_mappings['/dev/xvdc'].snapshot_id.should.equal(
        "snap-1234abcd")
Exemplo n.º 2
0
def do_build(ctxt, **kwargs):
    conn = ctxt.cnx_ec2
    if 'template' in kwargs and kwargs['template']:
        template_file_name = kwargs['template']
        kwargs = parse_template(ctxt, template_file_name, kwargs)
    del kwargs['template']

    defaultrun = {'instance_type': 'm1.large', 'key_name': ctxt.key_name }
    for key in defaultrun:
        if key not in kwargs or kwargs[key] == None:
            kwargs[key] = defaultrun[key]
                        
    (remote_user, kwargs) = get_remote_user(ctxt, **kwargs)
    (key_file, kwargs) = get_key_file(ctxt, **kwargs)

    (tags,kwargs) = do_tags(**kwargs)

    do_run_scripts =  kwargs.pop('run')

    ###########
    # Check VM naming
    ###########
    if 'Name' not in tags and kwargs['hostname'] is not None:
        tags['Name'] = kwargs['hostname']
    if 'Name' not in tags:
        yield "instance name is mandatory"
        return
    
    try:
        oslib.ec2_objects.Instance(ctxt, name=tags['Name']).get()
        # if get succed, the name already exist, else get throws an exception
        yield "duplicate name %s" % tags['Name']
        return 
    except:
        pass
        
    user_data_properties = {}
    
    image = kwargs.pop('image_id', None)

    ###########
    # Check device mapping
    ###########
    volumes = BlockDeviceMapping(conn)
    first_volume = 'f'
    l = first_volume

    ebs_optimized = False
    for volume_info in kwargs.pop('volume_size', []):
        # yaml is not typed, volume_info can be a string or a number
        if isinstance(volume_info, basestring):
            options = volume_info.split(',')
            size = int(oslib.parse_size(options[0], 'G', default_suffix='G'))
        else:
            options = []
            size = int(volume_info)
        vol_kwargs = {"connection":conn, "size": size}
        if len(options) > 1:
            for opt in options[1:]:
                parsed = opt.split('=')
                key = parsed[0]
                if len(parsed) == 2:
                    value = parsed[1]
                elif len(parsed) == 1:
                    value = True
                else:
                    raise OSLibError("can't parse volume argument %s", opt)
                if key == 'iops':
                    ebs_optimized = True
                    vol_kwargs['volume_type'] = 'io1'
                vol_kwargs[key] = value
        volumes["/dev/sd%s"%l] = BlockDeviceType(**vol_kwargs)
        l = chr( ord(l[0]) + 1)
    kwargs['ebs_optimized'] = ebs_optimized

    # if drive letter is not f, some volumes definition was found
    if l != first_volume:
        kwargs['block_device_map'] = volumes
        user_data_properties['volumes'] = ' '.join(volumes.keys())

    # after user_data_properties['volumes'] otherwise they will be lvm'ed
    for snapshot_id in kwargs.pop('snap_id', []):
        volumes["/dev/sd%s"%l] = BlockDeviceType(connection=conn, snapshot_id=snapshot_id)
        l = chr( ord(l[0]) + 1)
    
    kwargs = build_user_data(user_data_properties, **kwargs)

    ###########
    # Check elastic IP
    ###########
    if kwargs['elastic_ip']:
        eip = True
    else:
        eip = False
    del kwargs['elastic_ip']

    for k in kwargs.keys()[:]:
        value = kwargs[k]
        if kwargs[k] == None:
            del(kwargs[k])
        elif value.__class__ == [].__class__ and len(value) == 0:
            del(kwargs[k])
    
    if 'private_ip_address' in kwargs and kwargs['private_ip_address']:
        netif_specification = NetworkInterfaceCollection()
        netif_kwargs = {}
        if kwargs['private_ip_address']:
            netif_kwargs['private_ip_address'] = kwargs['private_ip_address']
            del kwargs['private_ip_address']
        if 'associate_public_ip_address' in kwargs and kwargs['associate_public_ip_address']:
            netif_kwargs['associate_public_ip_address'] = kwargs['associate_public_ip_address']
            del kwargs['associate_public_ip_address']
        if 'security_groups' in kwargs and kwargs['security_groups']:
            netif_kwargs['groups'] = kwargs['security_groups']
            del kwargs['security_groups']
        
        netif_kwargs['subnet_id'] = kwargs['subnet_id']
        del kwargs['subnet_id']
        print netif_kwargs
        spec = NetworkInterfaceSpecification(**netif_kwargs)
        netif_specification.append(spec)   
        kwargs['network_interfaces'] = netif_specification

    reservation = conn.run_instances(image, **kwargs)
    instance = reservation.instances[0]
    # Quick hack to keep the selected remote user
    instance.remote_user = remote_user
    
    if len(tags) > 0:
        conn.create_tags([ instance.id ], tags)
        
    if instance.interfaces and len(instance.interfaces) > 0:
        for interface in instance.interfaces:
            conn.create_tags([ interface.id ], {'creator': tags['creator']})

    while instance.state != 'running' and instance.state != 'terminated':
        instance.update(True)
        yield (".")
        time.sleep(1)
    yield ("\n")
    
    if eip:
        ip = conn.allocate_address().public_ip
        conn.associate_address(instance_id = instance.id, public_ip=ip)
        conn.create_tags([instance.id], {"EIP": ip})

    #Update tag for this instance's volumes
    for device in instance.block_device_mapping:
        device_type = instance.block_device_mapping[device]
        (vol_tags, vol_kwargs) = do_tags(name='%s/%s' % (tags['Name'], device.replace('/dev/','')))
        conn.create_tags([ device_type.volume_id ], vol_tags)
    instance.update(True)

    windows_instance = instance.platform == 'Windows'

    if do_run_scripts and not windows_instance:
        while instance.state != 'terminated':
            try:
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.settimeout(1.0)
                s.connect((instance.public_dns_name, 22))
                s.close()
                break
            except socket.error, msg:
                yield (".")
                s.close()
                time.sleep(1)
        yield ("\n")
        instance.key_file = key_file

        remote_setup(instance, remote_user, key_file)
Exemplo n.º 3
0
    userdata['source'] = src_inst.public_dns_name

    # Start the destination instance
    info('Starting EC2 destination instance')
    dst_inst = ec2dst.run_instance_wait(amazon_linux_ebs_64[args.dst_region],
            key_name = args.dst_keypair,
            security_groups = [args.name],
            user_data = dst_data % userdata,
            instance_type = args.inst_type,
            block_device_map = dst_inst_bdm,
            instance_initiated_shutdown_behavior = 'terminate')
    
    # Clean up created volumes
    dst_inst_bdm = dst_inst.block_device_mapping
    vol_ids = []
    for b in dst_inst_bdm.keys():
        if dst_inst_bdm[b].volume_id and b != '/dev/sda1':
            vol_ids.append(dst_inst_bdm[b].volume_id)
    vols = ec2dst.get_all_volumes(vol_ids)
    for v in vols:
        cleanup.add(v, 'delete', 'Deleting destination volume')

    cleanup.add(dst_inst, 'terminate_wait', 'Terminating destination instance')
    
    info('Tagging EC2 destination instance')
    ec2dst.create_tags([dst_inst.id], {'Name': args.name})

    # Set up security groups for Tsunami
    info('Allowing TCP access to source instance for tsunamid')
    src_sg.authorize('tcp', 46224, 46224, dst_inst.ip_address + '/32')
    src_sg.authorize('tcp', 46224, 46224, dst_inst.private_ip_address + '/32')