def _get_instances(self, dc_idx):

        test_id = self.params.get('test_id', default=None)
        if not test_id:
            raise ValueError(
                "test_id should be configured for using reuse_cluster")

        ec2 = ec2_client.EC2Client(region_name=self.region_names[dc_idx],
                                   spot_max_price_percentage=self.params.get(
                                       'spot_max_price', default=0.60))
        instances = list_instances_aws(tags_dict={
            'TestId': test_id,
            'NodeType': self.node_type
        },
                                       region_name=self.region_names[dc_idx])

        def sort_by_index(item):
            for tag in item['Tags']:
                if tag['Key'] == 'NodeIndex':
                    return tag['Value']
            else:
                return '0'

        instances = sorted(instances, key=sort_by_index)
        return [
            ec2.get_instance(instance['InstanceId']) for instance in instances
        ]
예제 #2
0
    def _create_spot_instances(self,
                               count,
                               interfaces,
                               ec2_user_data='',
                               dc_idx=0):
        ec2 = ec2_client.EC2Client(region_name=self.region_names[dc_idx])
        subnet_info = ec2.get_subnet_info(self._ec2_subnet_id[dc_idx])
        spot_params = dict(
            instance_type=self._ec2_instance_type,
            image_id=self._ec2_ami_id[dc_idx],
            region_name=subnet_info['AvailabilityZone'],
            network_if=interfaces,
            key_pair=self._credentials[dc_idx].key_pair_name,
            user_data=ec2_user_data,
            count=count,
            block_device_mappings=self._ec2_block_device_mappings)
        if self.instance_provision == INSTANCE_PROVISION_SPOT_DURATION:
            # duration value must be a multiple of 60
            spot_params.update(
                {'duration': cluster.TEST_DURATION / 60 * 60 + 60})

        limit = SPOT_FLEET_LIMIT if self.instance_provision == INSTANCE_PROVISION_SPOT_FLEET else SPOT_CNT_LIMIT
        request_cnt = 1
        tail_cnt = 0
        if count > limit:
            # pass common reservationid
            spot_params['user_data'] += (' --customreservation %s' %
                                         str(uuid.uuid4())[:18])
            self.log.debug("User_data to spot instances: '%s'",
                           spot_params['user_data'])
            request_cnt = count / limit
            spot_params['count'] = limit
            tail_cnt = count % limit
            if tail_cnt:
                request_cnt += 1
        instances = []
        for i in range(request_cnt):
            if tail_cnt and i == request_cnt - 1:
                spot_params['count'] = tail_cnt
            try:
                if self.instance_provision == INSTANCE_PROVISION_SPOT_FLEET and count > 1:
                    instances_i = ec2.create_spot_fleet(**spot_params)
                else:
                    instances_i = ec2.create_spot_instances(**spot_params)
                instances.extend(instances_i)
            except ClientError as cl_ex:
                if ec2_client.MAX_SPOT_EXCEEDED_ERROR in cl_ex.message:
                    self.log.debug(
                        'Cannot create spot instance(-s): %s.'
                        'Creating on demand instance(-s) instead.', cl_ex)
                    instances_i = self._create_on_demand_instances(
                        count, interfaces, ec2_user_data, dc_idx)
                    instances.extend(instances_i)
                else:
                    raise

        return instances
예제 #3
0
 def _get_instances(self):
     ec2 = ec2_client.EC2Client(region_name=self.region_names[0])
     return [ec2.get_instance_by_private_ip(ip) for ip in self._node_private_ips]