diff --git a/contrib/ci/lambda_functions/ci.py b/contrib/ci/lambda_functions/ci.py --- a/contrib/ci/lambda_functions/ci.py +++ b/contrib/ci/lambda_functions/ci.py @@ -116,6 +116,7 @@ state = event['detail']['state'] print('received %s for %s' % (state, instance_id)) + ec2_client = boto3.client('ec2') ec2 = boto3.resource('ec2') dynamodb = boto3.resource('dynamodb') @@ -132,7 +133,7 @@ job_table = dynamodb.Table(os.environ['DYNAMODB_JOB_TABLE']) - react_to_instance_state_change(job_table, instance, state) + react_to_instance_state_change(ec2_client, job_table, instance, state) def handle_try_server_upload(event, context): @@ -644,7 +645,7 @@ ) -def react_to_instance_state_change(job_table, instance, state): +def react_to_instance_state_change(ec2, job_table, instance, state): """React to a CI worker instance state change.""" now = decimal.Decimal(time.time()) @@ -689,17 +690,32 @@ # New instance/job seen. Record that. if state == 'pending': print('recording running state for job %s' % job_id) + + # Try to record the cost to running this instance. + hourly_cost = None + + if instance.spot_instance_request_id: + spot_instance_requests = ec2.describe_spot_instance_requests( + SpotInstanceRequestIds=[instance.spot_instance_request_id], + )['SpotInstanceRequests'] + + if spot_instance_requests: + hourly_cost = decimal.Decimal( + spot_instance_requests[0]['ActualBlockHourlyPrice']) + job_table.update_item( Key={'job_id': job_id}, UpdateExpression=( 'set execution_state = :state, ' 'instance_id = :instance_id, ' + 'instance_hourly_cost = :hourly_cost, ' 'start_time = :start_time, ' 'exit_clean = :exit_clean' ), ExpressionAttributeValues={ ':state': 'running', ':instance_id': instance.instance_id, + ':hourly_cost': hourly_cost, ':start_time': now, ':exit_clean': False, }, diff --git a/contrib/ci/lambda_functions/web.py b/contrib/ci/lambda_functions/web.py --- a/contrib/ci/lambda_functions/web.py +++ b/contrib/ci/lambda_functions/web.py @@ -115,6 +115,7 @@ '