2727)
2828from .ssh import generate_ssh_key_pair
2929from .services import SecurityGroupRule
30- from .util import duration_to_expiration
3130
3231logger = logging .getLogger ('flintrock.ec2' )
3332
@@ -275,7 +274,6 @@ def add_slaves(
275274 identity_file : str ,
276275 num_slaves : int ,
277276 spot_price : float ,
278- spot_request_duration : str ,
279277 min_root_ebs_size_gb : int ,
280278 tags : list ,
281279 assume_yes : bool ,
@@ -321,7 +319,6 @@ def add_slaves(
321319 num_instances = num_slaves ,
322320 region = self .region ,
323321 spot_price = spot_price ,
324- spot_request_valid_until = duration_to_expiration (spot_request_duration ),
325322 ami = self .master_instance .image_id ,
326323 assume_yes = assume_yes ,
327324 key_name = self .master_instance .key_name ,
@@ -704,7 +701,6 @@ def _create_instances(
704701 num_instances ,
705702 region ,
706703 spot_price ,
707- spot_request_valid_until ,
708704 ami ,
709705 assume_yes ,
710706 key_name ,
@@ -724,7 +720,6 @@ def _create_instances(
724720 ec2 = boto3 .resource (service_name = 'ec2' , region_name = region )
725721
726722 cluster_instances = []
727- spot_requests = []
728723 common_launch_specs = {
729724 'ImageId' : ami ,
730725 'KeyName' : key_name ,
@@ -733,7 +728,6 @@ def _create_instances(
733728 'Placement' : {
734729 'AvailabilityZone' : availability_zone ,
735730 'Tenancy' : tenancy ,
736- 'GroupName' : placement_group ,
737731 },
738732 'SecurityGroupIds' : security_group_ids ,
739733 'SubnetId' : subnet_id ,
@@ -748,80 +742,36 @@ def _create_instances(
748742 ],
749743 }
750744
745+ if spot_price :
746+ common_launch_specs .update ({
747+ 'InstanceMarketOptions' : {
748+ 'MarketType' : 'spot' ,
749+ 'SpotOptions' : {
750+ 'SpotInstanceType' : 'one-time' ,
751+ 'MaxPrice' : str (spot_price ),
752+ 'InstanceInterruptionBehavior' : 'terminate' ,
753+ },
754+ }
755+ })
756+ else :
757+ common_launch_specs .update ({
758+ 'InstanceInitiatedShutdownBehavior' : instance_initiated_shutdown_behavior ,
759+ })
760+ # This can't be part of the previous update because we need a deep merge.
761+ common_launch_specs ['Placement' ].update ({
762+ 'GroupName' : placement_group ,
763+ })
764+
751765 try :
752- if spot_price :
753- user_data = base64 .b64encode (user_data .encode ('utf-8' )).decode ()
754- logger .info ("Requesting {c} spot instances at a max price of ${p}..." .format (
755- c = num_instances , p = spot_price ))
756- client = ec2 .meta .client
757- spot_requests = client .request_spot_instances (
758- SpotPrice = str (spot_price ),
759- InstanceCount = num_instances ,
760- ValidUntil = spot_request_valid_until ,
761- LaunchSpecification = common_launch_specs ,
762- )['SpotInstanceRequests' ]
763-
764- request_ids = [r ['SpotInstanceRequestId' ] for r in spot_requests ]
765- pending_request_ids = request_ids
766-
767- while pending_request_ids :
768- logger .info ("{grant} of {req} instances granted. Waiting..." .format (
769- grant = num_instances - len (pending_request_ids ),
770- req = num_instances ))
771- time .sleep (30 )
772- spot_requests = client .describe_spot_instance_requests (
773- SpotInstanceRequestIds = request_ids )['SpotInstanceRequests' ]
774-
775- failed_requests = [r for r in spot_requests if r ['State' ] == 'failed' ]
776- if failed_requests :
777- failure_reasons = {r ['Status' ]['Code' ] for r in failed_requests }
778- raise Error (
779- "The spot request failed for the following reason{s}: {reasons}"
780- .format (
781- s = '' if len (failure_reasons ) == 1 else 's' ,
782- reasons = ', ' .join (failure_reasons )))
783-
784- pending_request_ids = [
785- r ['SpotInstanceRequestId' ] for r in spot_requests
786- if r ['State' ] == 'open' ]
787-
788- logger .info ("All {c} instances granted." .format (c = num_instances ))
789-
790- cluster_instances = list (
791- ec2 .instances .filter (
792- Filters = [
793- {'Name' : 'instance-id' , 'Values' : [r ['InstanceId' ] for r in spot_requests ]}
794- ]))
795- else :
796- cluster_instances = ec2 .create_instances (
797- MinCount = num_instances ,
798- MaxCount = num_instances ,
799- # Shutdown Behavior is specific to on-demand instances.
800- InstanceInitiatedShutdownBehavior = instance_initiated_shutdown_behavior ,
801- ** common_launch_specs ,
802- )
766+ cluster_instances = ec2 .create_instances (
767+ MinCount = num_instances ,
768+ MaxCount = num_instances ,
769+ ** common_launch_specs ,
770+ )
803771 return cluster_instances
804772 except (Exception , KeyboardInterrupt ) as e :
805773 if not isinstance (e , KeyboardInterrupt ):
806774 print (e , file = sys .stderr )
807- if spot_requests :
808- request_ids = [r ['SpotInstanceRequestId' ] for r in spot_requests ]
809- if any ([r ['State' ] != 'active' for r in spot_requests ]):
810- print ("Canceling spot instance requests..." , file = sys .stderr )
811- client .cancel_spot_instance_requests (
812- SpotInstanceRequestIds = request_ids )
813- # Make sure we have the latest information on any launched spot instances.
814- spot_requests = client .describe_spot_instance_requests (
815- SpotInstanceRequestIds = request_ids )['SpotInstanceRequests' ]
816- instance_ids = [
817- r ['InstanceId' ] for r in spot_requests
818- if 'InstanceId' in r ]
819- if instance_ids :
820- cluster_instances = list (
821- ec2 .instances .filter (
822- Filters = [
823- {'Name' : 'instance-id' , 'Values' : instance_ids }
824- ]))
825775 raise InterruptedEC2Operation (instances = cluster_instances ) from e
826776
827777
@@ -842,7 +792,6 @@ def launch(
842792 user ,
843793 security_groups ,
844794 spot_price = None ,
845- spot_request_duration = None ,
846795 min_root_ebs_size_gb ,
847796 vpc_id ,
848797 subnet_id ,
@@ -916,7 +865,6 @@ def launch(
916865 common_instance_spec = {
917866 'region' : region ,
918867 'spot_price' : spot_price ,
919- 'spot_request_valid_until' : duration_to_expiration (spot_request_duration ),
920868 'ami' : ami ,
921869 'assume_yes' : assume_yes ,
922870 'key_name' : key_name ,
0 commit comments