예제 #1
0
    def _get_instances(self, dc_idx):

        test_id = cluster.Setup.test_id()
        if not test_id:
            raise ValueError(
                "test_id should be configured for using reuse_cluster")

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

        def sort_by_index(item):
            for tag in item['Tags']:
                if tag['Key'] == 'NodeIndex':
                    return tag['Value']
            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):  # pylint: disable=too-many-arguments
        # pylint: disable=too-many-locals
        ec2 = ec2_client.EC2ClientWarpper(
            region_name=self.region_names[dc_idx],
            spot_max_price_percentage=self.params.get('spot_max_price',
                                                      default=0.60))
        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,
            aws_instance_profile=self.params.get('aws_instance_profile_name'))
        if self.instance_provision == INSTANCE_PROVISION_SPOT_DURATION:
            # duration value must be a multiple of 60
            spot_params.update(
                {'duration': round(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:
            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 str(cl_ex):
                    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 _create_spot_instances(self, count, interfaces, ec2_user_data='', dc_idx=0):  # pylint: disable=too-many-arguments
        # pylint: disable=too-many-locals
        ec2 = ec2_client.EC2ClientWarpper(region_name=self.region_names[dc_idx],
                                          spot_max_price_percentage=self.params.get('spot_max_price'))
        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,
                           aws_instance_profile=self.params.get('aws_instance_profile_name'))
        if self.instance_provision == INSTANCE_PROVISION_SPOT_DURATION:
            # duration value must be a multiple of 60
            spot_params.update({'duration': self.calculate_spot_duration_for_test()})

        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:
            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

            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)

        return instances