
    &`in              
          d dl Z d dlZd dlZd dlZd dlZd dlmZmZ d dlm	Z	m
Z
mZ d dlZd dlmZ d dlZd dlmc mZ d dlmZmZmZ d dlmZ d dlmZmZmZ d dlmZmZ d d	l m!Z!m"Z" d d
l#m$Z$ d dl%m&Z& d dl'm(Z( d dl)m*Z*m+Z+m,Z,m-Z-m.Z.  ej/        e0          Z1dZ2dZ3d Z4d Z5ddefdZ6	 dde7de
e7e	f         dee
e7e	f                  fdZ8 G d de(          Z9dS )    N)OrderedDictdefaultdict)AnyDictList)ServiceResource)"CLOUDWATCH_AGENT_INSTALLED_AMI_TAGCLOUDWATCH_AGENT_INSTALLED_TAGCloudwatchHelperbootstrap_aws)boto_exception_handlerclient_cacheresource_cache)cf
cli_logger)BOTO_CREATE_MAX_RETRIESBOTO_MAX_RETRIES)LogTimer)NodeLaunchException)NodeProvider)TAG_RAY_CLUSTER_NAMETAG_RAY_LAUNCH_CONFIGTAG_RAY_NODE_KINDTAG_RAY_NODE_NAMETAG_RAY_USER_NODE_TYPE   c                 H    t           | v r| t                    | d<   | t           = | S )z=Convert the Ray node name tag to the AWS-specific 'Name' tag.Namer   tagss    }/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/autoscaler/_private/aws/node_provider.pyto_aws_formatr$   ,   s,     D  -.V"#K    c                 4    d| v r| d         | t           <   | d= | S )z=Convert the AWS-specific 'Name' tag to the Ray node name tag.r   r    r!   s    r#   from_aws_formatr'   5   s(     ~~"&v,LKr%   returnc                 (    |pi }t          d| |fi |S )z3Make client, retrying requests up to `max_retries`.ec2)r   regionmax_retriesaws_credentialss      r#   make_ec2_resourcer/   >   s&    %+O%HHHHHr%   r,   r.   c                 ^   g }|pi }t          d| t          fi |}|                                }|                    t	          j        |d                              d|v rM|                    |d                   }|                    t	          j        |d                              d|v M|S )aq  Get all instance-types/resources available in the user's AWS region.
    Args:
        region: the region of the AWS provider. e.g., "us-west-2".
    Returns:
        final_instance_types: a list of instances. An example of one element in
        the list:
            {'InstanceType': 'm5a.xlarge', 'ProcessorInfo':
            {'SupportedArchitectures': ['x86_64'], 'SustainedClockSpeedInGhz':
            2.5},'VCpuInfo': {'DefaultVCpus': 4, 'DefaultCores': 2,
            'DefaultThreadsPerCore': 2, 'ValidCores': [2],
            'ValidThreadsPerCore': [1, 2]}, 'MemoryInfo': {'SizeInMiB': 16384},
            ...}

    r*   InstanceTypes	NextToken)r2   )r   r   describe_instance_typesextendcopydeepcopy)r,   r.   final_instance_typesr*   instance_typess        r#   list_ec2_instancesr9   D   s    " %+O
uf&6
J
J/
J
JC0022Nn_.M N NOOO

'
'44$[1 5 
 
 	##DM.2Q$R$RSSS	 
'
'  r%   c                   @   e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zdeeef         fdZedeeeef                  deeeef                  ddfd            Zd Zd Zd Zd Zd Zd Zed             Zedeeef         deeef         fd            ZdS )AWSNodeProvideri  c                    t          j        | ||           |                    dd          | _        |                    d          }t	          |d         t
          |          | _        t	          |d         d|          | _        i | _        t          t                    | _        d| _        t          j                    | _        | j                                         t          j                    | _        | j                                         t          j                    | _        t          j                    | _        t          j                    | _        i | _        d S )Ncache_stopped_nodesTr.   r,   r+   r   )r   __init__getr=   r/   r   r*   ec2_fail_fast	tag_cacher   dicttag_cache_pendingbatch_thread_count	threadingEventbatch_update_donesetready_for_new_batchLocktag_cache_lock
count_lock_reuse_node_lockcached_nodes)selfprovider_configcluster_namer.   s       r#   r>   zAWSNodeProvider.__init__f   s9   dO\BBB#2#6#67Ld#S#S )--.?@@$"8,(+
 
 

 /"8,+
 
 
 !,T!2!2"#!*!2!2""$$$#,?#4#4  $$&&&'n..#.** ) 0 0 r%   c                 `   t          |          }dddgdd                    t                    | j        gdg}|                                D ]1\  }}|                    d                    |          |gd           2t          d          5  t          | j        j	        
                    |                    }d d d            n# 1 swxY w Y   |D ]<}|j        | j        v rt          d |j        D                       | j        |j        <   =d	 |D             | _        d
 |D             S )Ninstance-state-namependingrunningr   Valuestag:{}z+Failed to fetch running instances from AWS.Filtersc                 ,    i | ]}|d          |d         S KeyValue .0xs     r#   
<dictcomp>z8AWSNodeProvider.non_terminated_nodes.<locals>.<dictcomp>   s"    999!51W:999r%   c                     i | ]
}|j         |S r_   idra   nodes     r#   rc   z8AWSNodeProvider.non_terminated_nodes.<locals>.<dictcomp>   s    ===tTWd===r%   c                     g | ]	}|j         
S r_   re   rg   s     r#   
<listcomp>z8AWSNodeProvider.non_terminated_nodes.<locals>.<listcomp>   s    ***D***r%   )r$   formatr   rQ   itemsappendr   listr*   	instancesfilterrf   rA   r'   r"   rN   )rO   tag_filtersfilterskvnodesrh   s          r#   non_terminated_nodesz$AWSNodeProvider.non_terminated_nodes   s    $K00 .$i0 
 !(<==,- 	
  %%'' 	 	DAqNN$OOA.. c     $$QRR 	E 	E+2272CCDDE	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E 	E  	 	Dw$.((&599ty999' 'DN47## >=u===**E****s   .C		CCc                 N    |                      |          }|j        d         dk    S )Nr   rU   _get_cached_nodestaterO   node_idrh   s      r#   
is_runningzAWSNodeProvider.is_running   s'    $$W--z&!Y..r%   c                 N    |                      |          }|j        d         }|dvS )Nr   )rU   rT   rx   )rO   r|   rh   rz   s       r#   is_terminatedzAWSNodeProvider.is_terminated   s-    $$W--
6"222r%   c                     | j         5  | j        |         }| j                            |i           }t	          |fi |cd d d            S # 1 swxY w Y   d S N)rK   rA   rC   r?   rB   )rO   r|   d1d2s       r#   	node_tagszAWSNodeProvider.node_tags   s      	" 	"(B'++GR88B>>b>>	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	" 	"s   5A

AAc                 r    |                      |          }|j        |                     |          }|j        S r   )ry   public_ip_address	_get_noder{   s      r#   external_ipzAWSNodeProvider.external_ip   s8    $$W--!)>>'**D%%r%   c                 r    |                      |          }|j        |                     |          }|j        S r   )ry   private_ip_addressr   r{   s      r#   internal_ipzAWSNodeProvider.internal_ip   s8    $$W--"*>>'**D&&r%   c                 6   d}| j         5  | j        sMd}| j                                         | j                                         | j                                         | j        |                             |           d d d            n# 1 swxY w Y   |ret          j        t                     | j         5  | 
                                 | j                                         d d d            n# 1 swxY w Y   | j        5  | xj        dz  c_        d d d            n# 1 swxY w Y   | j                                         | j        5  | xj        dz  c_        | j        dk    r| j                                         d d d            d S # 1 swxY w Y   d S )NFTr   r   )rK   rC   rI   waitclearrG   updatetimesleepTAG_BATCH_DELAY_update_node_tagsrH   rL   rD   )rO   r|   r"   is_batching_threads       r#   set_node_tagszAWSNodeProvider.set_node_tags   s   "  	9 	9) /%)"(--///(..000&,,..."7+224888	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9  	-J'''$ - -&&(((&**,,,- - - - - - - - - - - - - - - _ 	) 	)##q(##	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)##%%%_ 	/ 	/##q(##&!++(,,...	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/sH   A5BBB8.C22C69C6D!!D%(D%5FFFc                 l   t          t                    }| j                                        D ]W\  }}|                                D ]}||                             |           | j        |                             |           Xt          t                    | _        |                     |           d S r   )	r   rn   rC   rl   rm   rA   r   rB   _create_tags)rO   batch_updatesr|   r"   rb   s        r#   r   z!AWSNodeProvider._update_node_tags   s    #D))!399;; 	1 	1MGTZZ\\ 1 1a ''0000N7#**40000!,T!2!2-(((((r%   c                 P   |                                 D ]\  \  }}}d                    |||          }t          d                    |                    5  |t          k    rd}| j        j        j                            |||dg           d d d            n# 1 swxY w Y   d S )NzSet tag {}={} on {}zAWSNodeProvider: {}r   r\   )	ResourcesTags)rl   rk   r   r   r*   metaclientcreate_tags)rO   r   rs   rt   node_idsms         r#   r   zAWSNodeProvider._create_tags   s     - 3 3 5 5 	 	FQH%,,Q8<<A/66q99::  )))A$00&"#a001 1                 	 	s   8BB	!B	r(   c                    t          t          t          j        |                                                              }i }| j        rCdddgdd                    t                    | j        gdd                    t                    |t                   gdd                    t                    |t                   gdg}t          |v r<|                    d                    t                    |t                   gd           | j        5  t          | j        j                            |                    d|         }d |D             }d	 |D             }|rt%          j        d
t%          j        |                     t%          j        d          5  |D ]l}t-          d |j        D                       | j        |j        <   |j        d         dk    r.t%          j        d|j                   |                                 m	 ddd           n# 1 swxY w Y   | j        j        j                            |           |D ]}	|                     |	|           |tA          |          z  }ddd           n# 1 swxY w Y   i }
|r| !                    |||          }
|}|"                    |
           |S )zCreates instances.

        Returns dict mapping instance id to ec2.Instance object for the created
        instances.
        rS   stoppedstoppingrV   rX   rY   Nc                     g | ]	}|j         
S r_   re   ra   ns     r#   rj   z/AWSNodeProvider.create_node.<locals>.<listcomp>)  s    !<!<!<1!$!<!<!<r%   c                     i | ]
}|j         |S r_   re   r   s     r#   rc   z/AWSNodeProvider.create_node.<locals>.<dictcomp>*  s    $B$B$BQT1$B$B$Br%   zsReusing nodes {}. To disable reuse, set `cache_stopped_nodes: False` under `provider` in the cluster configuration.zStopping instances to reusec                 ,    i | ]}|d          |d         S r\   r_   r`   s     r#   rc   z/AWSNodeProvider.create_node.<locals>.<dictcomp>8  s"     I I I!51W: I I Ir%   r   zWaiting for instance {} to stopInstanceIds)#r   sortedr5   r6   rl   r=   rk   r   rQ   r   r   r   rm   rM   rn   r*   ro   rp   r   printrender_listgroupr'   r"   rA   rf   rz   wait_until_stoppedr   r   start_instancesr   len_create_noder   )rO   node_configr"   countreused_nodes_dictrr   reuse_nodesreuse_node_idsrh   r|   created_nodes_dictall_created_nodess               r#   create_nodezAWSNodeProvider.create_node   s    6$-"5"5";";"="=>>??# :	1
 2(*5 
 %OO,@AA#01 
 %OO,=>>#$567 
 %OO,ABB#$9:; G& &-- (0F G G#'(>#?"@    & 1 1"48#5#<#<W#<#M#MNNvPUvV!<!<!<!<!<$B$Bk$B$B$B! 1$I #.~>>   $)*GHH 	: 	:$/ : :D6E I Ity I I I7 7DN473  $z&1Z?? * 0$Etw!" !" !" !% 7 7 9 9 9:	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: HM(88^8TTT#1 : :**7D9999S000E91 1 1 1 1 1 1 1 1 1 1 1 1 1 1<   	M!%!2!2;e!L!L-  !3444  s9   BJA0HJH	J!H	"AJJ
J	tag_specsuser_tag_specsNc                     |D ]m}|d         dk    rY|d         D ]O}d}| d         d         D ]#}|d         |d         k    rd}|d         |d<    n$|s| d         dxx         |gz  cc<   Pg| |gz  } nd	S )
aZ  
        Merges user-provided node config tag specifications into a base
        list of node provider tag specifications. The base list of
        node provider tag specs is modified in-place.

        This allows users to add tags and override values of existing
        tags with their own, and only applies to the resource type
        "instance". All other resource types are appended to the list of
        tag specs.

        Args:
            tag_specs (List[Dict[str, Any]]): base node provider tag specs
            user_tag_specs (List[Dict[str, Any]]): user's node config tag specs
        ResourceTypeinstancer   Fr   r]   Tr^   Nr_   )r   r   user_tag_specuser_tagexiststags         r#   _merge_tag_specsz AWSNodeProvider._merge_tag_specsM  s    & , 	- 	-M^,
:: -f 5 ; ;H"F(|F3 " "#E?c%j88%)F+3G+<CL!E 9 " ;!!V,,,
:,,,; m_,			- 	-r%   c                 @   i }t          |          }|                                }t          | j        dg}|                                D ]\  }}|                    ||d           t          j        | j        d          r5| 	                    |          }	|	r|
                    t          ddg           d|dg}
|                    dg           }t                              |
|           |                    d          }|                    d||
d	           d
}i }t#          t$          t'          |                    }t)          d|dz             D ]}	 d|v r1|d         }|                    dd            t+          |          |d<   n"||t'          |          z           }||d<   ||d<    | j        j        di |}d |D             }t1          j        d||          5  |D ]P}d}|j        r|j        d         p|}t1          j        d|j        t;          |j        d         |                     Q	 d d d            n# 1 swxY w Y    n# t>          j         j!        $ r}|dz  }||k    r	 tE          |j#        d         d         |j#        d         d         tI          j%                              }n+# tL          $ r tN          (                    d|           Y nw xY wt1          j)        d|           nt1          j(        d|           Y d }~d }~ww xY w|S ) Nr\   agentTruer   )r   r   TagSpecifications	SubnetIdsr   )MinCountMaxCountr   r   NetworkInterfacesSecurityGroupIdsnetwork_interfacesSubnetId	subnet_idc                     i | ]
}|j         |S r_   re   r   s     r#   rc   z0AWSNodeProvider._create_node.<locals>.<dictcomp>  s    %?%?%?!adA%?%?%?r%   zLaunched {} nodes)_tagsrT   MessagezLaunched instance {}r   )rz   infoErrorCode)categorydescriptionsrc_exc_infozCouldn't parse exception.z2Failed to launch instances. Max attempts exceeded.)excz3create_instances: Attempt failed with {}, retrying.r_   )*r$   r5   r   rQ   rl   rm   r   cloudwatch_config_existsrP   _check_ami_cwa_installationr4   r
   r?   r;   r   popr   maxr   r   rangestrr@   create_instancesr   r   state_reasonr   instance_idrB   rz   botocore
exceptionsClientErrorr   responsesysexc_info	Exceptionloggerwarningabort)rO   r   r"   r   r   conf	tag_pairsrs   rt   cwa_installedr   r   
subnet_ids
subnet_idxcli_logger_tags	max_triesattemptnet_ifsr   createdr   r   r   s                          r#   r   zAWSNodeProvider._create_noden  sR   T""!! ,* 
	 JJLL 	 	DAq     4T5I7SS 
	 <<[IIM    $B%+    !+! 
	 "5r::((NCCC XXk**
 	IVVWWW 
 /ZAA	Q	A.. E	 E	GD&$.."#67G HH/666<?LLO$899 *:J+G HI'0D$3<OK0=$,=EEEE%?%?w%?%?%?"  %'o     %,   (1#0  ( 5i @ PL ) #(2$0"&&.nV&<%1# # #                  4 &2    a
i''1%(\'%:6%B(+W(=i(H),  
 %    'BCHHH $L    
 &Ms  -4 "!sc   BI%AI:II
	
II
	IL'L3AJ98L9%K!L K!!/LLc                 t   |                      |          }| j        r|j        r@t          j        dt          j        d          z   |           |                                 d S t          j        dt          j        d          z   |           |                                 d S |                                 d S )NzTerminating instance {} ,(cannot stop spot instances, only terminate)zStopping instance {} f(to terminate instead, set `cache_stopped_nodes: False` under `provider` in the cluster configuration))	ry   r=   spot_instance_request_idr   r   r   dimmed	terminatestopr{   s      r#   terminate_nodezAWSNodeProvider.terminate_node  s    $$W--# 	,  .i NOOP  
       +iI     		NNr%   c                 :   | j         j        j                            |d         g          }d}|                    d          }|rUt          |          dk    sJ dt          |           d            |d                             d	d
          }t          |v rd}|S )NImageId)ImageIdsFImagesr   z9Expected to find only 1 AMI with the given ID, but found .r   r    T)r*   r   r   describe_imagesr?   r   r	   )rO   configr   r   images
image_names         r#   r   z+AWSNodeProvider._check_ami_cwa_installation	  s    8='77&BSAT7UUh'' 	%v;;!###, [[, , , $##  vr22J1Z?? $r%   c                    |sd S | j         j        j        j        }| j         j        j        j        }|g |g i}| j        rg }g }|D ])}|                     |          j        r||gz  }#||gz  }*|r<t          j	        dt          j        d          z   t          j        |                     |r<t          j	        dt          j        d          z   t          j        |                     |||<   |||<   n|||<   | j        | j        nt          |          }|                                D ]=\  }	}
t!          dt          |
          |          D ]} |	|
|||z                       >d S )NzStopping instances {} r   zTerminating instances {} r   r   r   )r*   r   r   terminate_instancesstop_instancesr=   ry   r   r   r   r   r   r   max_terminate_nodesr   rl   r   )rO   r   terminate_instances_funcstop_instances_funcnodes_to_terminatespot_idson_demand_idsr|   r  terminate_funcru   starts               r#   terminate_nodeszAWSNodeProvider.terminate_nodes  s    	F#'8=#7#K "hm2A 7<OQST#  	DHM# / /((11J /	)HH!gY.MM 
 ,iI  *=99     /i NOOP*844   7D23;C788;C78 '3 $$X 	 &8%=%=%?%? 	W 	W!NEq#e**.ABB W W5AT9T1T+UVVVVVW	W 	Wr%   c           	         |                      i            || j        v r| j        |         S t          t          t          d                    D ]}t          | j        j                            |g                    }t          |          dk    r
|d         c S t          j        d|t          |          t          |dz   t                     t          j        t                     t          d                    |                    )z7Refresh and get info for this node, updating the cache.r   r   r   zAttempt to fetch EC2 instances that have instance ID {}. Got {} matching EC2 instances. Will retry after {} second. This is retry number {}, and the maximum number of retries is {}.zInvalid instance id {})rv   rN   r   r   r   rn   r*   ro   rp   r   r   r   LIST_RETRY_DELAY_SECr   r   AssertionErrorrk   )rO   r|   attemptsmatchess       r#   r   zAWSNodeProvider._get_nodeR  s   !!"%%%d'''$W-- c"2A6677 	- 	-H48-44'4KKLLG7||q  qz!!! HG$1    J+,,,,5<<WEEFFFr%   c                 X    || j         v r| j         |         S |                     |          S )z>Return node info from cache if possible, otherwise fetches it.)rN   r   )rO   r|   s     r#   ry   z AWSNodeProvider._get_cached_noden  s0    d'''$W--~~g&&&r%   c                      t          |           S r   r   )cluster_configs    r#   bootstrap_configz AWSNodeProvider.bootstrap_configu  s    ^,,,r%   r  c                 >   d| vr| S t          j        |           } t          | d         d         | d                             d                    }d |D             }| d         }| d         }|D ]}||         d         d         }||v rl||         d	         d
         }d|i}||k    rO||         d         d         }	t	          |	          dz  dz  }	dt
          j        z
  }
t	          |	|
z            }||d<   t          j        j	        
                                D ]Q}|                    ||          }|                    ||          }|r!|||                                <   |rd|d| <   R|                    ||                             di                      |||                             di           k    r9|||         d<   t                              d                    ||                     t%          d|z   dz   | d         d         z   dz             | S )z=Fills out missing "resources" field for available_node_types.available_node_typesproviderr,   r.   c                      i | ]}|d          |S )InstanceTyper_   )ra   r   s     r#   rc   zJAWSNodeProvider.fillout_available_node_types_resources.<locals>.<dictcomp>  s,     
 
 
3;H^$h
 
 
r%   head_node_typer   r#  VCpuInfoDefaultVCpusCPU
MemoryInfo	SizeInMiBi   r   memoryzaccelerator_type:	resourcesz#Updating the resources of {} to {}.zInstance type z! is not available in AWS region: r  )r5   r6   r9   r?   intray_constants&DEFAULT_OBJECT_STORE_MEMORY_PROPORTIONray_privateacceleratorsget_all_accelerator_managers!get_ec2_instance_num_accelerators!get_ec2_instance_accelerator_typeget_resource_namer   r   debugrk   
ValueError)r  instances_listinstances_dictr   r$  	node_typeinstance_typecpusautodetected_resourcesmemory_totalpropmemory_resourcesaccelerator_managernum_acceleratorsaccelerator_types                  r#   &fillout_available_node_types_resourcesz6AWSNodeProvider.fillout_available_node_types_resourcesy  s   
 "77!!~66+:&x0:&**+<==
 

 
?M
 
 
  ..DE'(89- =	 =	I0;MJM ..%m4Z@P*/&..#1-#@#N#$L $'|#4#4t#;d#BL}SSD'*<$+>'?'?$7G*84 \.KKMM" "' ,MM)>  % ,MM)>  %
 ( " - //AACC , " !" 3 F4D F F '--(377RHH   *-A)-L-P-P. .  
 / )3# LL=DD%'=    !$#$9: %Z0:; 	   r%   )__name__
__module____qualname__r  r>   rv   r}   r   r   r   r   r   r   r   r   r   r   r   staticmethodr   r   r   r   r   r  r   ry   r  rD  r_   r%   r#   r;   r;   c   s       ! ! !F#+ #+ #+J/ / /3 3 3
" " "& & &' ' '/ / /4
) 
) 
)	 	 	M!tCH~ M! M! M! M!^ -S#X'-9=d38n9M-	- - - \-@{" {" {"z  <  9W 9W 9WvG G G8' ' ' - - \- OS#XO	c3hO O O \O O Or%   r;   r   ):r5   loggingr   rE   r   collectionsr   r   typingr   r   r   r   boto3.resources.baser   r/  ray._private.ray_constantsr0  r-  8ray.autoscaler._private.aws.cloudwatch.cloudwatch_helperr	   r
   r   "ray.autoscaler._private.aws.configr   !ray.autoscaler._private.aws.utilsr   r   r   "ray.autoscaler._private.cli_loggerr   r   !ray.autoscaler._private.constantsr   r   !ray.autoscaler._private.log_timerr   $ray.autoscaler.node_launch_exceptionr   ray.autoscaler.node_providerr   ray.autoscaler.tagsr   r   r   r   r   	getLoggerrE  r   r   r  r$   r'   r/   r   r9   r;   r_   r%   r#   <module>rX     s     



      0 0 0 0 0 0 0 0 " " " " " " " " " "  0 0 0 0 0 0 



 2 2 2 2 2 2 2 2 2         
 = < < < < <         
 > = = = = = = = W W W W W W W W 6 6 6 6 6 6 D D D D D D 5 5 5 5 5 5              
	8	$	$     I IO I I I I 48    "&sCx. 	$sCx.       >f	 f	 f	 f	 f	l f	 f	 f	 f	 f	r%   