
    &`if                     4   d dl Z 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	Z	d dl
Z
d dlZd dlmZ d dlmZ d dl
mZmZ d dlmZmZ d dlmZmZmZ d dlmZmZmZmZ  ej        e           Z!d	Z"d
Z#dZ$e$dz   e"z   Z%dZ&dd'                    e"          iZ(g dZ)dgZ*dZ+de,de-fdZ.de,fdZ/de,de0fdZ1de,de2fdZ3de,defdZ4d Z5d Z6de,de2fdZ7de,de2fdZ8d  Z9d3d!Z:d3d"Z;d3d#Z<d3d$Z=d% Z>d& Z?d' Z@d( ZAd) ZBd* ZCd+ ZDd, ZEd- ZFd. ZGd/ ZHd0 ZId1 ZJd2 ZKdS )4    N)partialreduce)service_account)Credentials)	discoveryerrors)TPUAcceleratorManagertpu)	MAX_POLLSPOLL_INTERVALGCPNodeType)check_legacy_fieldsgenerate_rsa_key_pairgenerate_ssh_key_namegenerate_ssh_key_pathsv1v2alphazray-autoscalerz-sa-z1{account_id}@{project_id}.iam.gserviceaccount.comdisplayNamez#Ray Autoscaler Service Account ({}))zroles/storage.objectAdminzroles/compute.adminzroles/iam.serviceAccountUserzroles/iam.roleViewerzroles/tpu.admin	_has_tpusaccelerator_configreturnc                     | d                                          }| d         }d |                    d          D             }t          d |          }|dk    rd}t          j        |          |z  }| d| S )	a  Convert a provided accelerator_config to accelerator_type.

    Args:
        accelerator_config: A dictionary defining the spec of a
            TPU accelerator. The dictionary should consist of
            the keys 'type', indicating the TPU chip type, and
            'topology', indicating the topology of the TPU.

    Returns:
        A string, accelerator_type, e.g. "v4-8".

    typetopologyc                 ,    g | ]}t          |          S  )int).0
chip_counts     v/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/autoscaler/_private/gcp/config.py
<listcomp>z2tpu_accelerator_config_to_type.<locals>.<listcomp>I   s    MMM:s:MMM    xc                     | |z  S Nr   )r#   ys     r    <lambda>z0tpu_accelerator_config_to_type.<locals>.<lambda>J   s
    AE r"   
v5lite_pod	v5litepod-)lowersplitr   r
   get_tpu_cores_per_chip)r   
generationr   chip_dimensions	num_chips	num_coress         r    tpu_accelerator_config_to_typer2   9   s     $F+1133J!*-HMM9L9LMMMO))?;;I
 \!! 
*:66BI&&9&&&r"   nodec                 T   d| v rd| v rt          d          d| v r1| d         }t          j        |          st          d| d          dS | d         }d|vsd|vrt          d|           | d         d         }| d         d         }t          j        d	          }t          j        d
          }|dk    r(|                    |          st          d| d          |dk    s|dk    rt          d| d          |                    |          st          d| d          dS )a  Validate the provided node with TPU support.

    If the config is malformed, users will run into an error but this function
    will raise the error at config parsing time. This only tests very simple assertions.

    Raises: `ValueError` in case the input is malformed.

    acceleratorTypeacceleratorConfigzHFor TPU usage, acceleratorType and acceleratorConfig cannot both be set.z@`acceleratorType` should match v(generation)-(cores/chips). Got .r   r   z5acceleratorConfig expects 'type' and 'topology'. Got z^V\d+[a-zA-Z]*$z^\d+x\d+(x\d+)?$
V5LITE_PODz%type should match V(generation). Got V2V3z6acceleratorConfig is not supported on V2/V3 TPUs. Got z-topology should be of form axbxc or axb. Got N)
ValueErrorr	   is_valid_tpu_accelerator_typerecompilematch)r3   accelerator_typer   r.   r   generation_patterntopology_patterns          r    _validate_tpu_configrC   W   s    D  %8D%@%@"
 
 	
 D   12$BCSTT 	+'+ + +  	 	 ""56+++zAS/S/S,), ,   -.v6
+,Z8Z(:;;:&9::%%.@.F.Fz.R.R%RZRRRSSSt!3!3VVVV    %%h// 	KKKK  	 	r"   c                    d}d| v rG| d         }t          |                    d          d                   }|t          j        |          z  }d| v r:| d         d         }d}|                    d          D ]}|t          |          z  }|S )Nr   r5   r*      r6   r   r#   )r   r,   r
   r-   )r3   chipsr@   coresr   dims         r    _get_num_tpu_chipsrI      s    ED   12$**3//23323CDDDd""+,Z8 >>#&& 	 	CSXXEELr"   c                     d}d| v r	| d         }nt          | d                   }t          |           t          j        |          k    S )N r5   r6   )r2   rI   r
   "get_num_tpu_visible_chips_per_host)r3   r@   s     r    _is_single_host_tpurM      s]    D   129$?R:STTd##s'M( (  r"   c                    d| vr(d| vr$d| vr t          dt          |            d          d| vrLd| v sd| v rDt          |            t          |           st                              d           t          j        S t          j        S )ak  Returns node type based on the keys in ``node``.

    This is a very simple check. If we have a ``machineType`` key,
    this is a Compute instance. If we don't have a ``machineType`` key,
    but we have ``acceleratorType``, this is a TPU. Otherwise, it's
    invalid and an exception is raised.

    This works for both node configs and API returned nodes.
    machineTyper5   r6   zInvalid node. For a Compute instance, 'machineType' is required.For a TPU instance, 'acceleratorType' OR 'acceleratorConfig' and no 'machineType' is required. Got r7   zTPU pod detected. Note that while the cluster launcher can create multiple TPU pods, proper autoscaling will not work as expected, as all hosts in a TPU pod need to execute the same program. Proceed with caution.)	r;   listrC   rM   loggerwarningr   TPUCOMPUTE)r3   s    r    get_node_typerU      s     	T!!T))t++?15d? ? ?
 
 	
 D  T!!%8D%@%@T""""4(( 	NN(   r"   c                    t                               d                    |                      t          t                    D ]}|                                                    | d                                                   }d|v rt          |d                   d|v r$|d         rt                               d            nt          j
        t                     |S )z9Poll for cloud resource manager operation until finished.z=wait_for_crm_operation: Waiting for operation {} to finish...namerW   errordonez'wait_for_crm_operation: Operation done.)rQ   infoformatranger   
operationsgetexecute	Exceptiontimesleepr   )	operationcrm_results       r    wait_for_crm_operationrh      s    
KK	006y0A0A  
 9 	" 	"!!%%9V+<%==EEGGfF7O,,,VvKKABBBE
=!!!!Mr"   c                    t                               d                    |d                              t          t                    D ]}|                                                    | |d                                                   }d|v rt          |d                   |d         dk    rt                               d            nt          j
        t                     |S )z1Poll for global compute operation until finished.zHwait_for_compute_global_operation: Waiting for operation {} to finish...rW   )projectrd   rY   statusDONEz2wait_for_compute_global_operation: Operation done.)rQ   r[   r\   r]   r   globalOperationsr_   r`   ra   rb   rc   r   )project_namerd   computerf   rg   s        r    !wait_for_compute_global_operationrp      s    
KK	006y7H0I0I  
 9 " "$$&&S$#F+    WYY 	 fF7O,,,(v%%KKLMMME
=!!!!Mr"   configc                 |    d | d                                          D             }t          d |D                       S )z&Check if any nodes in config are TPUs.c                     g | ]
}|d          S node_configr   r   	node_types     r    r!   z-_has_tpus_in_node_configs.<locals>.<listcomp>   -        	-   r"   available_node_typesc              3   P   K   | ]!}t          |          t          j        k    V  "d S r%   )rU   r   rS   )r   r3   s     r    	<genexpr>z,_has_tpus_in_node_configs.<locals>.<genexpr>   s1      OO$}T""ko5OOOOOOr"   )valuesanyrq   node_configss     r    _has_tpus_in_node_configsr      sQ      67>>@@  L OO,OOOOOOr"   c                     d | d                                          D             }t          || d                            t          j        k    S )z Check if the head node is a TPU.c                 &    i | ]\  }}||d          S rt   r   )r   node_idrw   s      r    
<dictcomp>z'_is_head_node_a_tpu.<locals>.<dictcomp>  s3       GY 	=)  r"   ry   head_node_type)itemsrU   r   rS   r~   s     r    _is_head_node_a_tpur     sT     "()?"@"F"F"H"H  L f-=&>?@@KOSSr"   c                     t          j        | j        t          j                              }t          j        j        |g|R i |S )N)http)google_auth_httplib2AuthorizedHttpcredentialshttplib2Httpgoogleapiclientr   HttpRequest)r   argskwargsnew_https       r    build_requestr   
  sM    #2x}  H +HFtFFFvFFFr"   c                 >    t          j        dd| t          d          S )Ncloudresourcemanagerr   Fr   requestBuildercache_discoveryr   buildr   gcp_credentialss    r    _create_crmr     s*    ?#$   r"   c                 >    t          j        dd| t          d          S )Niamr   Fr   r   r   s    r    _create_iamr     s*    ?#$   r"   c                 >    t          j        dd| t          d          S )Nro   r   Fr   r   r   s    r    _create_computer   %  s*    ?#$   r"   c                 J    t          j        dt          | t          dd          S )Nr
   Fz*https://tpu.googleapis.com/$discovery/rest)r   r   r   discoveryServiceUrl)r   r   TPU_VERSIONr   r   s    r    _create_tpur   /  s-    ?#$H   r"   c                    |                      d          }|ot                              d           |                      t          d          rt	                      nd}t                      t                      t                      |fS d|v s
J d            d|v s
J d            |d         }|d         }|d	k    r]	 t          j	        |          }n'# t          j
        j        $ r t          d
          w xY wt          j                            |          }n|dk    rt!          |          }|                      t          d          rt	          |          nd}t          |          t          |          t          |          |fS )z
    Attempt to fetch and parse the JSON GCP credentials from the provider
    config yaml file.

    tpu resource (the last element of the tuple) will be None if
    `_has_tpus` in provider config is not set or False.
    r   Nztgcp_credentials not found in cluster yaml file. Falling back to GOOGLE_APPLICATION_CREDENTIALS environment variable.Fr   z8gcp_credentials cluster yaml field missing 'type' field.r   z?gcp_credentials cluster yaml field missing 'credentials' field.r   zDgcp_credentials found in cluster yaml file but formatted improperly.credentials_token)r_   rQ   debugHAS_TPU_PROVIDER_FIELDr   r   r   r   jsonloadsdecoderJSONDecodeErrorRuntimeErrorr   r   from_service_account_infoOAuthCredentials)provider_configr   tpu_resource	cred_typecredentials_fieldservice_account_infor   s          r    &construct_clients_from_provider_configr   :  s    &))*;<<O$	
 	
 	
 ""#95AAKMMM 	 }}kmm_->->LL 	/!!!A 	"!! 	(((H 	)((  'I'6%%%	#':.?#@#@  |+ 	 	 	(  	
 &1KK 
 
 
)	)	)&'899 5u==	K     	K  K  $$	 s   :C $C3c                 J   t          j        |           } t          |            i | d<   t          |           rd| d         t          <   t          | d                   \  }}}}t          | |          } t          | ||          } t          | |          } t          | |          } | S )N	head_nodeTprovider)
copydeepcopyr   r   r   r   _configure_project_configure_iam_role_configure_key_pair_configure_subnet)rq   re   r   ro   r
   s        r    bootstrap_gcpr   {  s    ]6""FF; !(( :59z12CF:DVWWCgs,,F c22F 11Fvw//FMr"   c                    t          j        |           } | d                             d          }| d         d         
J d            t          ||          }| t	          ||           t          ||          }|
J d            |d         dk    s#J d                    |d                               |d	         | d         d<   | S )
zSetup a Google Cloud Platform Project.

    Google Compute Platform organizes all the resources, such as storage
    buckets, users, and instances under projects. This is different from
    aws ec2 where everything is global.
    r   
project_idNz'project_id' must be set in the 'provider' section of the autoscaler config. Notice that the project id must be globally unique.zFailed to create projectlifecycleStateACTIVEz)Project status needs to be ACTIVE, got {}	projectId)r   r   r_   _get_project_create_projectr\   )rq   re   r   rj   s       r    r   r     s     ]6""F
#''55J*l+77	G 877 :s++G
C(((z3// : !X---299'BR:STT 	.-- (/{';F:|$Mr"   c                     t          j        |           } t                              t          | d         d                   }t          || |          }|Nt                              d                    t                               t          t          t          | |          }|
J d            | d         
                    t          d          rt          t          z   }nt          }t          |||           |d         d	gd
g| d         d<   | S )a  Setup a gcp service account with IAM roles.

    Creates a gcp service acconut and binds IAM roles which allow it to control
    control storage/compute services. Specifically, the head node needs to have
    an IAM role that allows it to create further gce instances and store items
    in google cloud storage.

    TODO: Allow the name/id of the service account to be configured
    r   r   )
account_idr   Nz4_configure_iam_role: Creating new service account {}z Failed to create service accountFemailz.https://www.googleapis.com/auth/cloud-platform)r   scopesr   serviceAccounts)r   r   SERVICE_ACCOUNT_EMAIL_TEMPLATEr\   DEFAULT_SERVICE_ACCOUNT_ID_get_service_accountrQ   r[   _create_service_accountDEFAULT_SERVICE_ACCOUNT_CONFIGr_   r   DEFAULT_SERVICE_ACCOUNT_ROLESTPU_SERVICE_ACCOUNT_ROLES_add_iam_policy_binding)rq   re   r   r   r   roless         r    r   r     s*    ]6""F*11-*%l3 2  E +5&#>>O..4f5O.P.P	
 	
 	

 2&(FPS
 
 &&(J&&&j4e<< .-0II-OUC888 %W-
 HH	
 	
	.F;)* Mr"   c           	      *   t          j        |           } d| d         v r| S | d         d         }|                                                    | d         d                                                   }t          d |d                             d	g           D             i                               d
d          }|r|                    d          ng }d}t          d          D ]}t          d|| d         d         | d         d         |          }t          |          \  }	}
|D ]Z}|                    d          }t          |          dk    r+|d         |k    r#t          j                            |
          rd} n[t          j        t          j                            d          d           |s>t          j                            |
          st                               d                    |                     t'                      \  }}t)          ||||           t          j                            |
          }t          j        |d           t-          |
dt/          t          j        d                    5 }|                    |           ddd           n# 1 swxY w Y   t-          |	d          5 }|                    |           ddd           n# 1 swxY w Y   d} n|r n|sJ d                    ||
                      t          j                            |
          sJ d                    |
|                      t                               d                    |
                     |
| d         d<   | S ) a  Configure SSH access, using an existing key pair if possible.

    Creates a project-wide ssh key that can be used to access all the instances
    unless explicitly prohibited by instance config.

    The ssh-keys created by ray are of format:

      [USERNAME]:ssh-rsa [KEY_VALUE] [USERNAME]

    where:

      [USERNAME] is the user for the SSH key, specified in the config.
      [KEY_VALUE] is the public SSH key value.
    ssh_private_keyauthssh_userr   r   )rj   c              3   2   K   | ]}|d          dk    |V  dS keyssh-keysNr   )r   items     r    r{   z&_configure_key_pair.<locals>.<genexpr>  s=       	
 	
E{j(( ((((	
 	
r"   commonInstanceMetadatar   valuerK   
F
   gcpregion       Tz~/.ssh)exist_okz-_configure_key_pair: Creating new key pair {}wi  )mode)openerNz(SSH keypair for user {} not found for {}z)Private key file {} not found for user {}zA_configure_key_pair: Private key not specified in config, using{})r   r   projectsr_   r`   nextr,   r]   r   r   lenospathexistsmakedirs
expanduserrQ   r[   r\   r   _create_project_ssh_key_pairdirnameopenr   write)rq   ro   r   rj   ssh_keys_strssh_keys	key_foundikey_namepublic_key_pathprivate_key_pathssh_key	key_parts
public_keyprivate_keyprivate_key_dirfs                    r    r   r     sU    ]6""FF6N**f~j)H  $$VJ-?-M$NNVVXXG 	
 	
 89==grJJ	
 	
 	

 	  
c'2  ,8?|!!$'''RH I2YY 7 7(:x(:|,
 
 -C8,L,L)) 	 	Gc**I9~~""|x''BGNN;K,L,L' 	 	BG&&x004@@@@  	0@!A!A 	KK?FFxPP   '<&=&=#J(*hPPP !goo.>??OK$7777
  rwU333   % $$$% % % % % % % % % % % % % % % os++ $q
###$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ IE 	E	   @GG"   9 7>>  V V299:JHUUV V  KK	V$%%   )9F6N$%Ms$   
J,,J0	3J0	K))K-	0K-	c                    t          j        |           } d | d                                         D             }t          d |D                       r| S t	          | |          }|st          d          |d         }|d         ddd	gd
g}|D ]Y}d|vrt          j        |          |d<   d|vr8t          j        |          d         |d<   |d                             d           Z| S )z8Pick a reasonable subnet if not specified by the config.c                     g | ]
}|d          S rt   r   rv   s     r    r!   z%_configure_subnet.<locals>.<listcomp>X  rx   r"   ry   c              3   &   K   | ]}d |v pd|v V  dS )networkInterfacesnetworkConfigNr   )r   ru   s     r    r{   z$_configure_subnet.<locals>.<genexpr>`  sE         	{*Lo.L     r"   z Should be able to create subnet.r   selfLinkzExternal NATONE_TO_ONE_NAT)rW   r   )
subnetworkaccessConfigsr
  r  r  )r   r   r|   all_list_subnetsNotImplementedErrorpop)rq   ro   r   subnetsdefault_subnetdefault_interfacesru   s          r    r   r   T  sU   ]6""F  67>>@@  L   '      FG,,G F!"DEEE
 QZN )4 +, 	
 	

 $ 	> 	> k11/3}=O/P/PK+,+--+/=9K+L+LQ+OK((,,_===Mr"   c                     |                                                     | d         d         | d         d                                                   }|d         S )Nr   r   r   )rj   r   r   )subnetworksrP   r`   )rq   ro   responses      r    r  r    s\    	:&|4*%h/ 
 

 

 
  Gr"   c                     |                                                     | d         d         | d         d         |                                          }|S )Nr   r   r   )rj   r   r  )r  r_   r`   )rq   	subnet_idro   subnets       r    _get_subnetr    sY    	:&|4*%h/  
 

 


 
  Mr"   c                     	 |                                                     |                                           }n/# t          j        $ r}|j        j        dk    r d }Y d }~nd }~ww xY w|S )N)r   i  )r   r_   r`   r   	HttpErrorresprk   )r   re   rj   es       r    r   r     s}    ,,..$$z$::BBDD   6=C
 Ns   := A)A$$A)c                     |                                                     | | d                                          }t          ||          }|S )N)r   rW   )body)r   creater`   rh   )r   re   rd   rg   s       r    r   r     sH    	:zBB	C	C	  $Is33FMr"   c                 J   |d         d         }d                     ||           }	 |                                                                                    |                                          }n/# t
          j        $ r}|j        j        dk    r d }Y d }~nd }~ww xY w|S )Nr   r   z/projects/{project_id}/serviceAccounts/{account})r   accountrX   i  )	r\   r   r   r_   r`   r   r  r   rk   )r&  rq   r   r   	full_namer   r!  s          r    r   r     s    
#L1JAHHw I  I,,..88::>>I>NNVVXX   6=C
 s   AA4 4B BB c                     |d         d         }|                                                                                     d                    |          | |d                                          }|S )Nr   r   zprojects/{project_id})r   )	accountIdserviceAccount)rW   r#  )r   r   r$  r\   r`   )r   account_configrq   r   r   r   s         r    r   r     sy    
#L1J 					(//:/FF'"0  
 

 

 
  r"   c                    | d         }| d         }d|z   }|                                                     |dddii                                          }d}|D ]g}d	}	|d
         D ]7}
|
d         |k    r)||
d         vr|
d                             |           d	}d}	8|	s!d	}|d
                             |g|d           h|rdS |                                                     |d|i                                          }|S )z*Add new IAM roles for the service account.r   r   zserviceAccount:optionsrequestedPolicyVersionr   )resourcer#  TFbindingsrolemembers)r2  r1  Npolicy)r   getIamPolicyr`   appendsetIamPolicy)r   r   re   r   r   	member_idr3  already_configuredr1  role_existsbindingrg   s               r    r   r     si    -JG$E!E)I 		y3KQ2O&P 
 

 

 
    j) 	# 	#Gv$&&GI$666I&--i888).&" 	!&:%% ){       	 		& 
 

 

 
  Mr"   c                    |                     d          }t          |          dk    s
J |            |d         dk    s
J |            d                    ||d                   }| d         }|                    d	g           }t	          d
 t          |          D             d          }||                    d|d           n ||         }	|	dxx         d|z   z  cc<   |	||<   ||d	<   |                                                    | d         |          	                                }
t          | d         |
|          }|S )z6Inserts an ssh-key into project commonInstanceMetadatar   r   r   zssh-rsaz){ssh_user}:ssh-rsa {key_value} {ssh_user}rE   )r   	key_valuer   r   c              3   8   K   | ]\  }}|d          dk    |V  dS r   r   )r   r   r   s      r    r{   z/_create_project_ssh_key_pair.<locals>.<genexpr>#  s4      HHwq$d5kZ.G.G.G.G.G.GHHr"   Nr   )r   r   r   r   rW   )rj   r#  )r,   r   r\   r_   r   	enumerater5  r   setCommonInstanceMetadatar`   rp   )rj   r  r   ro   r  new_ssh_metacommon_instance_metadatar   
ssh_keys_ir   rd   r  s               r    r   r     s      %%I y>>Q	Q<9$$$i$$$>EEYq\ F  L  ''?@$(("55EHH)E**HHH$ J Z,??@@@@$TL00$j(-W% 		"	"FO*B 
# 

 

 
  1)WUUHOr"   r%   )Lr   r   loggingr   r=   rb   	functoolsr   r   r   r   r   google.oauth2r   google.oauth2.credentialsr   r   r   r   ray._private.acceleratorsr	   r
    ray.autoscaler._private.gcp.noder   r   r   ray.autoscaler._private.utilr   r   r   r   	getLogger__name__rQ   VERSIONr   RAYr   r   r\   r   r   r   r   dictstrr2   rC   r   rI   boolrM   rU   rh   rp   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r   r   r   r   r   r   r"   r    <module>rQ     s      				 				  % % % % % % % %          ) ) ) ) ) ) E E E E E E - - - - - - - - @ @ @ @ @ @ @ @ R R R R R R R R R R            
	8	$	$
 6\G3 !T 8??HH" ! ! !  //  % 't ' ' ' ' '<+t + + + +\T c    "d t    # # # # # #L  *  8Pd Pt P P P PT T T T T TG G G            > > >B  *  >0 0 0fo o od3 3 3l
 
 
    	 	 	    &1 1 1h' ' ' ' 'r"   