
    d                       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Zd dl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 d dl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 d d
lmZ d dlmZm Z  d dl!m"Z" d dl#m$Z$m%Z%m&Z&m'Z'm(Z( d dl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3 d dl4m5Z5m6Z6 d dl7m8Z8 d dl9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZB d dlmCZC d dlDmEZE d dlFmGZG d dlHmIZImJZJmKZKmLZLmMZM dZNdZOeNdz   eOz   ZP ej                  ePdz   ej                        ZSdZTg dZU ej                  eNej                        ZV ej                  ePdz   ej                        ZWdZXdZYdZZd Z[d!Z\d"Z]d#Z^d$Z_d%Z` G d& d'ea      Zb G d( d)ea      Zcecj                  ecj                  gZf G d* d+ea      Zgd, Zhd- Zid. Zjd/ Zkd0 Zld1 Zm G d2 d3ea      Zn G d4 d5ea      Zod6 ZpdDd7Zq G d8 d9ea      Zr G d: d;ea      Zs G d< d=ea      Zt G d> d?ea      Zu G d@ dAea      Zv G dB dCe+      Zwy)E    N)LooseVersion)defaultdict)partial)conf)logger)fileutil)version)0get_agent_supported_features_list_for_extensionsSupportedFeatureNamesget_supported_feature_by_name)get_agent_supported_features_list_for_crp)CGroupConfigurator)get_propertiesset_properties)
ErrorState)	add_eventelapsed_millisecondsWALAEventOperationadd_periodicEVENTS_DIRECTORY)
ExtensionDownloadErrorExtensionErrorExtensionErrorCodesExtensionOperationErrorExtensionUpdateErrorProtocolErrorProtocolNotFoundErrorExtensionsGoalStateErrorGoalStateAggregateStatusCodesMultiConfigExtensionEnableError)ustris_file_not_found_error)GoalStateSource)	ExtensionStatusExtensionSubStatus	ExtensionExtHandlerStatusVMStatusGoalStateAggregateStatusExtensionStateExtensionRequestedStateExtensionSettings)textutil)ARCHIVE_DIRECTORY_NAME)FlexibleVersion)
AGENT_NAMECURRENT_VERSIONPY_VERSION_MAJORPY_VERSION_MICROPY_VERSION_MINORz^([^-]+)z(\d+(?:\.\d+)*)-z\.zip$Z   )ReadyNotReady
InstallingUnresponsive$z.zipNOT_RUNi   i   i (  z ... [TRUNCATED]      0c                       e Zd ZdZdZdZy)ExtHandlerStatusValuez)
    Statuses for Extension Handlers
    r7   r8   N)__name__
__module____qualname____doc__ready	not_ready     @/usr/lib/python3/dist-packages/azurelinuxagent/ga/exthandlers.pyrA   rA   Z   s     EIrI   rA   c                   (    e Zd ZdZdZdZdZdZg dZy)ExtensionStatusValuez!
    Statuses for Extensions
    transitioningwarningerrorsuccess)rM   rN   rO   rP   N)	rB   rC   rD   rE   rM   rN   rO   rP   STRINGSrH   rI   rJ   rL   rL   b   s"     $MGEG>GrI   rL   c                   (   e Zd ZdZdj	                  e      Zdj	                  e      Zdj	                  e      Zdj	                  e      Zdj	                  e      Z	dZ
dZd	j	                  e      Zd
j	                  e      Zdj	                  e      Zy)ExtCommandEnvVariableAZURE_GUEST_AGENTz{0}_DISABLE_CMD_EXIT_CODEz.{0}_DISABLE_CMD_EXIT_CODES_MULTIPLE_EXTENSIONSz{0}_UNINSTALL_CMD_EXIT_CODEz{0}_EXTENSION_PATHz{0}_EXTENSION_VERSIONConfigSequenceNumberConfigExtensionNamez{0}_UPDATING_FROM_VERSIONz{0}_WIRE_PROTOCOL_ADDRESSz {0}_EXTENSION_SUPPORTED_FEATURESN)rB   rC   rD   PrefixformatDisableReturnCode#DisableReturnCodeMultipleExtensionsUninstallReturnCodeExtensionPathExtensionVersionExtensionSeqNumberExtensionNameUpdatingFromVersionWireProtocolAddressExtensionSupportedFeaturesrH   rI   rJ   rS   rS   p   s     F3::6B*Z*a*abh*i'7>>vF(//7M.55f=/)M5<<VD5<<VD!C!J!J6!RrI   rS   c                 `    || vr*t        dj                  |      t         j                        y )Nz3Invalid status format by extension: Missing {0} keymsgcodeExtensionStatusErrorrX   StatusFileMalformed)objkeyfull_key_paths      rJ   validate_has_keyrm   ~   s5    
#~"'\'c'cdq'r(<(P(PR 	R rI   c                 d    | |vr,t        dj                  | ||      t         j                        y )Nz.Invalid value {0} in range {1} at the node {2}rd   rg   )valvalid_rangenames      rJ   validate_in_rangerr      s<    
+"'W'^'^_bdoqu'v(<(P(PR 	R rI   c                 ^    | y t        | dd       t        | dd       | j                  d      S )NlangzformattedMessage/langmessagezformattedMessage/message)rm   get)formatted_messages    rJ   parse_formatted_messagerx      s8     &0GH&	3MN  ++rI   c                 8   t        | dd       t        | d   t        j                  d       t	               }| j                  d      |_        | j                  d      |_        | j                  dd      |_        | j                  d      }t        |      |_
        |S )Nstatuszsubstatus/statusrq   rf   r   formattedMessage)rm   rr   rL   rQ   r%   rv   rq   rz   rf   rx   ru   )	substatusrz   rw   s      rJ   parse_ext_substatusr}      s    Y*<=i)+?+G+GI[\!F--'FKMM(+FM--*FK!&89,->?FNMrI   c                    |y t        |t              s8t        |      d d }t        dj	                  |      t        j
                        |sy |d   }t        |dd       |d   }t        |dd       |d   }|t        j                  vrt        j                  }|j                  d      }|| _        |j                  d      | _        || _        |j                  d	d      | _        |j                  d
      }t        |      | _        |j                  dg       }|g }|D ])  }|| j"                  j%                  t'        |             + y )Ni   z*The extension status must be an array: {0}rd   r   rz   zstatus/statusconfigurationAppliedTime	operationrf   r{   r|   )
isinstancelistr!   rh   rX   ri   rm   rL   rQ   rO   rv   r   r   rz   rf   rx   ru   substatusListappendr}   )	
ext_statusdatadata_stringstatus_datarz   applied_timerw   substatus_listr|   s	            rJ   parse_ext_statusr      sY   |dD!4j$'"'S'Z'Z[f'g  oC  oW  oW  X  	X 7DT8X.x.K[(O<"F)111%++??#=>L*6J'&??;7JJ!oofa0JO#(:;01BCJ __["5N# L	 $$++,?	,JKLrI   c                  f   t         j                  j                  t        j                         d      } t         j                  j                  |       syt        j                  t         j                  j                  | d            D ]%  }t         j                  j                  |      }t         j                  j                  t        j                         |d      }t         j                  j                  |      svdD ]  }t         j                  j                  | ||j                               }t         j                  j                  |d|z         }t         j                  j                  |      sut         j                  j                  |      r	 t        j                  ||        ( 	 t        j"                  |        y# t        $ r+}t        j                  d||t!        |             Y d}~d}~ww xY w# t        $ r*}t        j                  d| t!        |             Y d}~yd}~ww xY w)	a  
    Migrate handler state and status (if they exist) from an agent-owned directory into the
    handler-owned config directory

    Notes:
     - The v2.0.x branch wrote all handler-related state into the handler-owned config
       directory (e.g., /var/lib/waagent/Microsoft.Azure.Extensions.LinuxAsm-2.0.1/config).
     - The v2.1.x branch original moved that state into an agent-owned handler
       state directory (e.g., /var/lib/waagent/handler_state).
     - This move can cause v2.1.x agents to multiply invoke a handler's install command. It also makes
       clean-up more difficult since the agent must remove the state as well as the handler directory.
    handler_stateN*config)StateStatusHandlerz.Exception occurred migrating {0} {1} file: {2}z$Exception occurred removing {0}: {1})ospathjoinr   get_lib_dirisdirglobiglobbasenamelowerisfileshutilmove	Exceptionr   warnstrrmtree)handler_state_pathhandler_pathhandlerhandler_config_pathfile	from_pathto_pathes           rJ   migrate_handler_stater      s    d&6&6&8/J77==+,

277<<0BC#HI $''""<0 ggll4+;+;+=wQ77==,-+ $GGLL);WdjjlS	'',,':I<LM77>>),RWW^^G5L$Iw7$	$"X()  % $L# F	$ $$  X:<NPSTUPVWW
Xs0   G0G= 	G:!G55G:=	H0 H++H0c                       e Zd ZdZdZdZdZy)ExtHandlerStateNotInstalled	InstalledEnabledFailedUpgradeN)rB   rC   rD   r   r   r   r   rH   rI   rJ   r   r      s    !LIG#MrI   r   c                        e Zd ZdZdZdZdZdZy)GoalStateStatusa)  
    This is an Enum to define the State of the GoalState as a whole. This is reported as part of the
    'vmArtifactsAggregateStatus.goalStateAggregateStatus' in the status blob.
    Note: not to be confused with the State of the ExtHandler which reported as part of 'handlerAggregateStatus'
    SuccessFailed
InitializeTransitioningN)rB   rC   rD   rE   r   r   r   r   rH   rI   rJ   r   r      s    
 GF J#MrI   r   c                     t        |       S N)ExtHandlersHandler)protocols    rJ   get_exthandlers_handlerr     s    h''rI   c              #   2  K   t        j                         }t        j                  |      D ]g  }t        j                  j                  ||      }|t        |      r||v r5| r+t        j                  |      st        j                  |      rb||f i y wr   )
r   r   r   listdirr   r   anyr	   is_agent_packageis_agent_path)skip_agent_packageignore_nameslib_dirrq   r   s        rJ   list_agent_lib_directoryr     s      G

7# 	ww||GT*#L(9dl>R7#;#;D#AWEZEZ[_E`Dj	s   BBc                       e Zd Zd Zd Zd Zd Zd Zedd       Z	d Z
d	 Zed
        Zd Zd Zedd       Zd Zedd       Zd Zed        Zed        Zedd       ZddZd Zd Z	 	 ddZd Zd Zy)r   c                 L    || _         d | _        d | _        t               | _        y r   )r   ext_handlers(_ExtHandlersHandler__gs_aggregate_statusr   report_status_error_state)selfr   s     rJ   __init__zExtHandlersHandler.__init__  s%       &*")3&rI   c                     | j                   d uxrP | j                   j                  t        j                  k(  xr' | j                   j                  t
        j                  k(  S r   )r   rz   r   r   rf   r   $GoalStateUnsupportedRequiredFeaturesr   s    rJ   __last_gs_unsupportedz(ExtHandlersHandler.__last_gs_unsupported  sY     ))5 u))00O4J4JJu))..2O2t2tt	urI   c           	      2   	 | j                   j                         }|j                  }t        j                  |j
                        | _        | j                         sy t        j                  j                         }d }dj                  |j                  |j                  |j                  |j                  |j                  |j                         }t#        j$                  d       t#        j$                  |       t'        t(        j*                  |       	 | j-                  |j.                  |j                         | j1                          t9        |      }|2dj                  |j                  |      }t#        j$                  |       n2dj                  |j                  ||      }t#        j:                  |       t'        t(        j*                  |d u |d|       y # t2        $ r.}dj                  t5        j6                  |            }Y d }~d }~ww xY w# t9        |      }|2dj                  |j                  |      }t#        j$                  |       n2dj                  |j                  ||      }t#        j:                  |       t'        t(        j*                  |d u |d|       w xY w# t2        $ r`}d	j                  t5        j6                  |            }t#        j:                  |       t'        t(        j*                  d|d
       Y d }~y d }~ww xY w)NzlProcessExtensionsGoalState started [{0} channel: {1} source: {2} activity: {3} correlation {4} created: {5}] )opru   zError processing extensions:{0}z2ProcessExtensionsGoalState completed [{0} {1} ms]
z2ProcessExtensionsGoalState failed [{0} {1} ms]
{2}F)r   
is_successru   	log_eventdurationzJProcessExtensionsInGoalState - Exception processing extension handlers:{0}r   r   ru   r   )r   get_goal_stateextensions_goal_statecopydeepcopy
extensionsr   _extension_processing_alloweddatetimeutcnowrX   idchannelsourceactivity_idcorrelation_idcreated_on_timestampr   infor   r   ExtensionProcessing2_ExtHandlersHandler__process_and_handle_extensionssvd_sequence_number_cleanup_outdated_handlersr   r-   format_exceptionr   rO   )	r   gsegs	utc_startrO   ru   r   r   re   s	            rJ   runzExtHandlersHandler.run%  s   %	q--/B**C !%cnn =D557 ))002IE E  L  LSZZ#BTBTVYVnVnpGKKOKK +??QV44S5L5LcffU//1 0	:=SZZ[^[a[acklGKK(SZZ[^[a[ackmrsGLL)/CCQVZ^Q^ip  }B  MU  V  `:AA(B[B[\]B^_` 0	:=SZZ[^[a[acklGKK(SZZ[^[a[ackmrsGLL)/CCQVZ^Q^ip  }B  MU  V 	q_ffgo  hA  hA  BG  hH  ICLL+??E[^jopp	qsX   AJ- B7J- 6G BJ- 	H&$H
H HH BJ**J- -	L6ALLc                     | j                   j                         j                  j                  }t	               }|D cg c]	  }||vs| c}S c c}w r   )r   r   r   required_featuresr   )r   r   supported_featuresfeatures       rJ   __get_unsupported_featuresz-ExtHandlersHandler.__get_unsupported_featuresM  sF     MM88:PPbbFH'8^GGK]<]^^^s   	AAc                    	 | j                         }t        |      rdj                  |dj                  |            }t	        j
                  |       t        t        j                  |t        j                  |      | _        t        t        j                  d|d       y | j                  |       t        t        j                   |t        j                   d      | _        y # t"        $ r}dj                  t%        j&                  |            }t        t        j                  |t        j(                  |      | _        t	        j
                  |       t        t        j*                  d|d       Y d }~y d }~ww xY w)Nz1Failing GS {0} as Unsupported features found: {1}z, )rz   seq_norf   ru   Fr   zGoalState executed successfullyz/Unexpected error when processing goal state:{0})-_ExtHandlersHandler__get_unsupported_featuresr   rX   r   r   r   r)   r   r   r   r   r   r   r   GoalStateUnsupportedFeatureshandle_ext_handlersr   r   r-   r   GoalStateUnknownFailurer   )r   r   goal_state_idunsupported_featuresre   rO   s         rJ   __process_and_handle_extensionsz2ExtHandlersHandler.__process_and_handle_extensionsR  sP   	'#'#B#B#D '(IPPQ^`d`i`ij~`  AC -E_McMclKh  LN  LNNQ.S* /LL%*"%$)+
 ((7-E_MdMd  nAKhKpKpNo.q*  		'CJJ8KdKdejKklC)AI_I_h{GdG|G|JM*OD& KK+??!&! %' '		's    BC# !AC# #	E<,BE77E<Nc                    t         j                  j                  |      rt        j                  t
        |       y | j                  d      }| d| }|||v ry t        |      }t        t        | |dz   d              |_
        t        ||      S )Nr5   r   rq      )r   r   r   rematchHANDLER_NAME_PATTERNrfindr&   r   r/   r	   ExtHandlerInstance)rq   r   r   skip_handlers	separatorhandler_nameehs          rJ   "get_ext_handler_instance_from_pathz5ExtHandlersHandler.get_ext_handler_instance_from_pathp  s    ww}}T"bhh/CT&J&RJJsO	Ai($)FL)i!mn)=>?
!"h//rI   c                 <   | j                         ry g }g }| j                  D cg c]  }|j                   }}t        d      D ]  \  }}	 t        j                  ||| j                  |      }||j                  |       >	 t        j                  j                  |      s_t        j                  j                  |dt        t                      rt        j                   t"        |      s|j                  |        |D ]<  }	 t        j$                  |       t'        j(                  dj+                  |             > |D ]  }
|
j3                          t        j                  j5                  t7        j8                         |
j;                         t        z         }t        j                  j                  |      sz	 t        j$                  |       t'        j(                  dj+                  |              y c c}w # t        $ r Y w xY w# t,        $ r:}	t'        j.                  dj+                  ||	j0                               Y d }	~	Kd }	~	ww xY w# t,        $ r:}	t'        j.                  dj+                  ||	j0                               Y d }	~	Pd }	~	ww xY w)	NT)r   )rq   r   r   r  r   z&Removed orphaned extension package {0}z*Failed to remove orphaned package {0}: {1}zRemoved extension package {0}z+Failed to remove extension package {0}: {1})(_ExtHandlersHandler__last_gs_unsupportedr   rq   r   r   r
  r   r   r   r   r   r   r   lenHANDLER_PKG_EXTr  r  _HANDLER_PKG_PATTERNremover   verboserX   OSErrorr   strerrorremove_ext_handlerr   r   r   get_full_name)r   handlerspkgsext_handlerext_handlers_in_gsitemr   handler_instancepkgr   r   s              rJ   r   z-ExtHandlersHandler._cleanup_outdated_handlers  s:   %%'BFBSBST;k..TT 3dK 	"JD$
#5#X#X^b^bbfbobogy $Y ${  $/OO$45 0 ww~~d#d1c/.B-B&CDxx 4d;D!#	"(  	bCb		#GNNsST	b   	gG&&('',,t//173H3H3J_3\]Cww~~c"gIIcNNN#B#I#I##NO	gI U"    bHOOPSUVU_U_`aab  gKK M T TUXZ[ZdZd effgsG   G=6H	9H9I	HH	I/II	J!/JJc                    t        j                         st        j                  d       yt        j                         rD| j
                  j                         j                  j                  rt        j                  d       yy)NzExtension handling is disabledFzExtension handling is on holdT)
r   get_extensions_enabledr   r  get_enable_overprovisioningr   r   r   on_holdr   r   s    rJ   r   z0ExtHandlersHandler._extension_processing_allowed  sY    **,NN;<++-}}++-CCKK;<rI   c                 f    | \  }}||j                  |j                        S |j                         S r   )dependency_level_sort_keystate)tup	extensionr   s      rJ   __get_dependency_levelz)ExtHandlersHandler.__get_dependency_level  s6    "G 66w}}EE0022rI   c                 r   g }| j                   D ]  }t        |j                        r,|j                  |j                  D cg c]  }||f c}       Dt	        j
                  dj                  |j                               |j                  d |f        |j                  | j                         |S c c}w )Nz5No extension/run-time settings settings found for {0}rk   )r   r   settingsextendr   r   rX   rq   r   sort)_ExtHandlersHandler__get_dependency_level)r   all_extensionsr   exts       rJ   &__get_sorted_extensions_for_processingz9ExtHandlersHandler.__get_sorted_extensions_for_processing  s    (( 	7G7##$%%AQAQ&R#W~&RS SZZ[b[g[ghi%%tWo6	7 	 ; ;< 'Ss    B4
c           	      @   | j                   st        j                  d       y t        j                  j	                         t        j
                  t              z   }| j                         }t        |      r| j                  |d         nd}d }|D ]  \  }}t        || j                  |      }|{|j                  |      rV|j                         |j                  |d       |j                  |t         j"                  dt$        j&                  |       n|j                  |d       | j)                  |||      }	| j                  ||f      }
d|
cxk  r|k  sn |j+                  |      }	 |	st-        dj/                  |            | j1                  |||        y # t,        $ rl}t        j2                  d	j/                  |             t5        |      }t7        ||j8                  j:                  t$        j&                  d
|       Y d }~d }~ww xY w)Nz5No extension handlers found, not processing anything.)minutesr   r%  ru   rf   rz   rf   r   ru   zSSkipping processing of extensions since execution of dependent extension {0} failedz\Dependent extension {0} failed or timed out, will skip processing the rest of the extensionsF)rq   r	   r   r   ru   )r   r   r   r   r   	timedelta_DEFAULT_EXT_TIMEOUT_MINUTES9_ExtHandlersHandler__get_sorted_extensions_for_processingr   r,  r  r   should_perform_multi_config_opget_handler_statusset_handler_statuscreate_status_file_if_not_existrL   rO   r   r   handle_ext_handlerget_extension_full_namer   rX   wait_for_handler_completionr   r!   r   r  r	   )r   r   
wait_untilr-  max_dep_leveldepends_on_err_msgr%  r  	handler_iextension_success	dep_levelextension_full_namerO   s                rJ   r   z&ExtHandlersHandler.handle_ext_handlers  s     KKOP&&--/(2D2DMi2jj
DDFKN~K^33N24FGde!&4 4	:"I{*;QZ[I
 "- ;;IF 335=!44=OVX4Y==iPdPjPjqsHZHnHnFX > Z 009KRT0U !% 7 7	9m \33Y4LMII--&/&G&G	&R#:,'(}  )E  )E 3)5 6 6 44Y
V_4`S4	:V ! 	:KKv}}/12 *.e&#6&/&;&;&C&C!3!G!G).&8	: :	:s   40F((	H1A!HHc                    | j                  |      }|%t        j                  dj                  |             y	 d\  }}t        j                  j                         |k  rN| j                  |      \  }}|rn7t        j                  d       t        j                  j                         |k  rN|s>t        j                  j                         |kD  rdj                  ||      }t        |      |t        j                  k7  rdj                  ||      }t        |      y# t        $ r5}dj                  |t        j                  |            }t        |      d}~ww xY w)z
        Check the status of the extension being handled. Wait until it has a terminal state or times out.
        :raises: Exception if it is not handled successfully.
        Nz6No settings found for {0}, not waiting for it's status)FNr=   zoFailed to wait for Handler completion due to unknown error. Marking the dependent extension as failed: {0}, {1}zfDependent Extension {0} did not reach a terminal state within the allowed timeout. Last status was {1}z7Dependent Extension {0} did not succeed. Status was {1})r>  r   r   rX   r   r   is_ext_handling_completetimesleepr   r-   r   rL   rP   )rC  r@  r%  extension_nameext_completedrz   r   re   s           rJ   r?  z.ExtHandlersHandler.wait_for_handler_completion  sV    #::9E KKPWWXfgh	!$/!M6 ##**,
:(1(J(J9(U%v 

1	 ##**,
: !2!2!9!9!;j!Hz  B  B(CC. )111KRRSacijCC.  2  	! D  K  K 9 9! <>CC. 	!s   A3D 	E(0EEc           	         	 |j                   j                  rt        |j                   j                        |j                   j                  }|j                  ||      	 ||t        j                  k(  ri|j                   j                  }|j                   j                  }dj                  ||      }|j                  t        j                         t        |      |j                  j!                  d||       |t        j                  k(  r| j#                  ||       y|t        j$                  k(  r| j'                  ||       y|t        j(                  k(  r| j+                  ||       ydj                  |      }t        |      # t,        $ r}	|j/                  |      }
d	j                  |
t1        |	            }|j3                  |t4        j6                  |	j8                  |j:                  |
       t=        |
|j                   j                  |j:                  dd|       Y d}	~	yd}	~	wt        $ rH}	dj                  t1        |	            }| j?                  ||	t        j@                  ||       Y d}	~	yd}	~	wtB        $ r4}	| j?                  ||	|j:                  t1        |	      d|       Y d}	~	yd}	~	wtD        $ rH}	dj                  t1        |	            }| j?                  ||	t        j                  ||       Y d}	~	yd}	~	wt        $ r3}	| j?                  ||	|j:                  t1        |	      |       Y d}	~	yd}	~	wtF        $ r:}	d|	_        | j?                  ||	|j:                  t1        |	      |       Y d}	~	yd}	~	ww xY w)ay  
        Execute the requested command for the handler and return if success
        :param ext_handler_i: The ExtHandlerInstance object to execute the command on
        :param extension: The extension settings on which to run the command on
        :param goal_state_id: ID of the current GoalState
        :return: True if the operation was successful, False if not
        )target_stater%  Nz8Unable to find version {0} in manifest for extension {1})re   zTarget handler state: {0} [{1}]r3  zUnknown ext handler state:{0}Tz/Error processing MultiConfig extension {0}: {1}r5  Frq   r	   r   r   r   ru   z[Ran into config errors: {0}. 
Please retry again as another operation with updated settings)	report_opru   r%  )reportr%  z!Failed to download artifacts: {0}r2  )$r  is_invalid_settingr   invalid_setting_reasonr#  decide_versionr+   r   r	   rq   rX   set_operationr   Downloadr   r   r   handle_enableDisabledhandle_disable	Uninstallhandle_uninstallr    r>  r!   r<  rL   rO   rf   r   r   9_ExtHandlersHandler__handle_and_report_ext_handler_errorsInvalidExtensionConfigr   r   r   )r   ext_handler_ir%  r   r   handler_versionrq   err_msgru   rO   ext_namere   s               rJ   r=  z%ExtHandlersHandler.handle_ext_handler>  s   ?	M((;;.}/H/H/_/_``)55;;M ++6? , ADHIMZ^u^}^}M}"/";";"C"C$0055T[[\kmqr++,>,G,GH$11   %%&GXef 7 ? ??""=)<  "9"B"BB##M9=  "9"C"CC%%my%I
  ;AA-P$W-- / 		I$<<YGHGNNxY]^cYdeG 99)L`LfLfmrmwmwDQD[D[el : n8]-F-F-N-NS`SjSj!&$I I2 / ( 	^t{{UG77uBTBkBk@GS\ 8 ^ ^& ! $ 	[77umNeNegklqgr?DPY 8 [ [  & 	Z5<<T%[IC77uXjXsXs@Cy 8 Z Z   	M77umNeNegklqgrBK 8 M M   	MEJ77umNeNegklqgrBK 8 M M 	Msg   DF	  %F	 &F	 -F	 		NBH**N6>I99N*J44N >LN)L==N	0M>>Nc                 2   | j                  ||j                         | j                  |      r.| j                  |t        j
                  |j                  ||       |r9| j                  |      }| j                  j                  }t        |||dd|       y y )Nr4  r5  FTrO  )
r;  rf   r9  r<  rL   rO   r>  r  r	   r   )r^  rO   rP  ru   rQ  r%  rq   r_  s           rJ   &__handle_and_report_ext_handler_errorsz9ExtHandlersHandler.__handle_and_report_ext_handler_errors  s     	((uzz(J 77	B99)L`LfLfmrmwmwDMW^ : `  88CD+77??O4YSXdh%' rI   c                    d}|j                         }|j                         }|j                  j                  d|j	                                |t
        j                  k(  s|t
        j                  k(  rP| j                  ||       ||j                  |       nJ|j                  |      r9t        j                  |||      }n!|j                          |j                  |       | j                  |||       y)z
             1- Ensure the handler is installed
             2- Check if extension is enabled or disabled and then process accordingly
        Nz&[Enable] current handler state is: {0}r3  )get_installed_ext_handlerget_handler_stater   r   r   r   r   r   &_ExtHandlersHandler__setup_new_handlerinstall
version_ner   ._update_extension_handler_and_return_if_failedensure_consistent_data_for_mcupdate_settings%_ExtHandlersHandler__handle_extension)r   r^  r%  uninstall_exit_codeold_ext_handler_icurrent_handler_states         rJ   rW  z ExtHandlersHandler.handle_enable  s    
 #)CCE - ? ? A!!"JLaLgLgLij !O$@$@@DY]l]z]zDz$$]I> (%%	%:))*;< '9&g&g%}i'A# 779)))4y:MNrI   c                     | j                  t        j                         | j                          | j	                          | j                  |       y r   )set_handler_stater   r   download
initializerl  )r^  r%  s     rJ   __setup_new_handlerz&ExtHandlersHandler.__setup_new_handler  s<    ''(D(DE   "%%i0rI   c                    || j                          y | j                  j                  d|j                         |j                  t        j
                  k(  r| j                  ||       y |j                  t        j                  k(  rR| j                  |      t        j                  k7  r| j                  |d       y | j                  j                  d       y t        dj                  |j                  |j                              )NzRequested extension state: {0})rn  T)ignore_errorz.Extension already disabled, not doing anythingz.Unknown requested state for Extension {0}: {1})enabler   r   r#  r*   r   rX  get_extension_statedisabler   rX   rq   )r^  r%  rn  s      rJ   __handle_extensionz%ExtHandlersHandler.__handle_extension  s       " 	!!"BIOOT??n444  @S T__ 7 7700;~?V?VV %%id%C$$))*Z[*@GG	XaXgXghj jrI   c                      fd}t        d       } j                         t        j                  k(  r j                  sJt         j                        s5 |t         j                  d             | j                  j                  <    j                  D ]-  } |t         j                  |            ||j                  <   / j                          j                         r)j                  | j                  j                  |       n+j                  j                  } j                  ||||        |t         j                   |            } j#                          j%                  ||       |S )Nc                 d   d}d}	 j                         j                         } |         |S # t        $ rx}t        |      d|}j	                  |d       |st        |      |j                  }t        |t              r|j                  }t        j                  d       Y d}~|S d}~ww xY w)aS  
            Created a common wrapper to execute all commands that need to be executed from the old handler
            so that it can have a common exception handling mechanism
            :param func: The command to be executed on the old handler
            :return: True if command execution succeeds and False if it fails
            Fr   z; ContinueOnUpdate: ru   r   z>Continue on Update failure flag is set, proceeding with updateN)load_manifestis_continue_on_update_failurer   r!   report_eventr   rf   r   r   	exit_coder   r   )funccontinue_on_update_failurer  r   re   r^  ro  s        rJ   2execute_old_handler_command_and_return_if_succeedsz}ExtHandlersHandler._update_extension_handler_and_return_if_failed.<locals>.execute_old_handler_command_and_return_if_succeeds  s     */&I^-:-H-H-J-h-h-j*  " ^ 59G=WX!..su.M1.s33FF	a!89 !I\]]^s   %. 	B/A-B**B/c                      t         S r   )r<   rH   rI   rJ   <lambda>zSExtHandlersHandler._update_extension_handler_and_return_if_failed.<locals>.<lambda>  s     rI   r3  )r  )disable_exit_codesupdating_from_versionr%  )r_  r  r  r%  rn  r%  )r   rf  r   r   supports_multi_configr   r   r   rz  r  rq   enabled_extensionscopy_status_files
version_gtupdater	   	uninstallr  update_with_install)ro  r^  r%  r  r  old_extr  rn  s   ``      rJ   rj  zAExtHandlersHandler._update_extension_handler_and_return_if_failed  sy   	6 )9..0O4K4KK %::3GXGcGcCd:l !2!:!:dK;M #%11668 -?? P3e !2!:!:gN4P"7<<0P 	''(9:##$56  4F7H7T7T7\7\+4 ! 6 %2$=$=$E$E!$$5J8Jbw/8 % : Q*44	JL,,.))>Q]f)g""rI   c                     |j                         }|j                  j                  d|j                                |t        j
                  k(  r|j                  |       yy)z
            Disable is a legacy behavior, CRP doesn't support it, its only for XML based extensions.
            In case we get a disable request, just disable that extension.
        z'[Disable] current handler state is: {0}N)rf  r   r   r   r   r   rz  )r   r^  r%  r   s       rJ   rY  z!ExtHandlersHandler.handle_disable  sS    
 &779!!"K]M`M`MbcO333!!), 4rI   c                    |j                         }|j                  j                  d|j                                |t        j
                  k7  ry|t        j                  k(  rS|j                  s%t        |j                        s|j                          |j                  D ]  }|j                  |        	 |j                  |       |j!                          y# t        $ r&}|j                  t        |      d       Y d}~;d}~ww xY w)a	  
        To Uninstall the handler, first ensure all extensions are disabled
            1- Disable all enabled extensions first if Handler is Enabled and then Disable the handler
                (disabled extensions wont have any extensions dependent on them so we can just go
                ahead and remove all of them at once if HandlerState==Uninstall.
                CRP will only set the HandlerState to Uninstall if all its extensions are set to be disabled)
            2- Finally uninstall the handler
        z)[Uninstall] current handler state is: {0}r3  Fr~  N)rf  r   r   r   r   r   r   r  r   r   rz  r  r  r   r  r!   r  )r   r^  r%  r   enabled_extr   s         rJ   r[  z#ExtHandlersHandler.handle_uninstall$  s     &779!!"M}ObObOdeO888 7 77 %::3}G_G_C`!))+ $1#C#C 7K!))+67N'')'< 	((* " N**47u*MMNs   5C 	D!DDc           
      ^   g }t        dt        t        g      D ]H  \  }}	 t        j	                  ||| j
                        }||j                  }t               }t        j                  t        j                  j                  |j                         d            D ]B  }t        j                  d|      }	|	|j!                  |	j#                  d             d|_        D t'        |      s|j!                  |j(                         |D ]D  }
t+        |
      }|j-                  |      \  }}||_        |j0                  j3                  |       F |j3                  |       K |S # t4        $ r;}|r.t7        j8                  dj;                  |t=        |                   Y d }~d }~ww xY w)	NT)r   r   )rq   r   r   z*.*.settingsz(?P<extname>\w+)\.\d+\.settingsextnamer   z1Can't fetch ExtHandler from path: {0}; Error: {1})r   r   r.   r   r
  r   r  setr   r   r   r   r   get_conf_dirr  searchaddgroupr  r   rq   r,   get_status_file_pathsequenceNumberr)  r   r   r   r   rX   r!   )r   goal_state_changedhandlers_to_reportr  r   r  r  extensions_namessettings_pathr  ra  r.  r   _rO   s                  rJ   __get_handlers_on_file_systemz0ExtHandlersHandler.__get_handlers_on_file_systemC  s   2dAQSi@jl %	oJD$#o#5#X#X^b^bbfbobo $Y $q  $/"2">">K
 (+u$ *.BGGLLAQA^A^A`bp4q)r E "		*OQ^ _ ,,00Y1GH@DK=	E /0(,,[-=-=>$4 9/X>$4$I$I#$N	-3*#,,33C89 '--k:C%	oN "!  o%KK S Z Z[_aefkal mnos   BE(:B)E((	F,10F''F,c           	         	 t        dd| j                  |      }|j                  j                  |       g }| j	                         r| j                  |      }n(| j	                         s| j                  | j                  }|D ]  }	 | j                  |||        t        j                  d       	 | j                  j!                  |       t        j                  d       | j"                  j%                          | j"                  j3                         redj+                  | j"                  j4                        }t        t.        t0        t        j6                  d|
       | j"                  j%                          |S # t        $ r0}t        t        j                  dt        |             Y d}~.d}~ww xY w# t&        $ rK}| j"                  j)                          d	j+                  |      }t        j                  |       Y d}~d}~wt,        $ r\}| j"                  j)                          d	j+                  |      }t        t.        t0        t        j                  d|
       Y d}~od}~ww xY w# t8        $ ri}dj+                  t;        j<                  |            }	t        j>                  |	       t        t.        t0        t        j@                  d|	
       Y d}~yd}~ww xY w)z
        Go through handler_state dir, collect and report status.
        Returns the status it reported, or None if an error occurred.
        r7   zGuest Agent is running)rz   ru   gs_aggregate_statusvm_agent_update_statusNF)r   r   ru   zReport vm agent statusz-Completed vm agent status report successfullyz%Failed to report vm agent status: {0})r	   r   r   ru   z2Failed to report vm agent status for more than {0}zFailed to report status: {0})!r(   r   vmAgentset_supports_fast_trackr  0_ExtHandlersHandler__get_handlers_on_file_systemr   report_ext_handler_statusr   r   r   r   r!   r   r  r   report_vm_statusr   resetr   incrrX   r   r0   r1   is_triggeredmin_timedeltaReportStatusExtendedr   r-   r   r   ReportStatus)
r   r  r  vm_agent_supports_fast_track	vm_statusr  r  rO   ru   re   s
             rJ   report_ext_handlers_statusz-ExtHandlersHandler.report_ext_handlers_statuso  sy   =	 9Q595O5O8NPI 556RS!# ))+%)%G%GHZ%[" //1d6G6G6S%)%6%6"1 pp229kK]^p NN34+..y9NO..446 --::<NVD::HHI  *"1/DD%*")	+ ..446C & p!3!G!GTYcghmcnoop ) (..335AHHOw''  +..335AHHO*"1/CC%*")	+ ++.  	1889R9RSX9YZCKKj-+88!&!	#
 	s   BI4 E>I4 3A
F: =B I4 >	F7%F2,I4 2F77I4 :	I1A H	I4 	I1AI,&I4 ,I11I4 4	K&=AK!!K&c                 B   | j                   j                         }|d}i }t        |      }|j                  di       j                  d      }|D ]7  }|j                  d      |j                  d      ||j                  d      <   9 t	        j
                  t        t        t        j                               dj                  t        t        t              t               j                         D cg c]  \  }}|	 c}}|d      }	dj                  ||	      S c c}}w )	Nr   r  extensionHandlersrq   r  zPython: {0}.{1}.{2})	agentNamedaemonVersionpythonVersionextensionSupportedFeaturessupportsMultiConfigz{{
    "__comment__": "The __status__ property is the actual status reported to CRP",
    "__status__": {0},
    "__debug__": {1}
}}
)r   get_status_blob_datar   rv   jsondumpsr0   r   r	   get_daemon_versionrX   r2   r4   r3   r
   items)
r   r  status_blob_textsupport_multi_configvm_status_datavm_handler_statuseshandler_statusrq   r  
debug_texts
             rJ   "get_ext_handlers_status_debug_infoz5ExtHandlersHandler.get_ext_handlers_status_debug_info  s   ====?#!!'	2,00B?CCDWX1 	oN!!&)5CQCUCUVmCn$^%7%7%?@	o ZZ# !;!;!=>299:JL\^no?o?q?w?w?y*zGD!4*z#7!
 

 FZ(	)	 +{s   2Dc                 ,   t        || j                        }|j                         }|M|j                  t        j
                  k7  r/dj                  |j                        }|j                  |||       y |j                         }g }|t        j                  k7  s|j                  rq|t        j                  k7  rL	 |j                         }	|	9|	j                  d      |_        d|	v rt!        |	j                  d            |_        |j-                  ||      }t/        |      s|j1                  |       |j2                  j4                  j7                  |       y # t$        $ r0}
|j'                  t)        |
      |
j*                         Y d }
~
d }
~
ww xY w)Nz?No handler status found for {0}. Not reporting anything for it.)log_msg	event_msgrz   r{   r4  )r  r   r:  r#  r+   rZ  rX   rq   "report_error_on_incarnation_changerf  r   r   r  collect_heartbeatrv   rz   rx   ru   r   r;  r!   rf   get_extension_handler_statusesr   r   r  r  r*  )r   r  r  r  r^  r  re   r   ext_handler_statuses	heartbeatr   s              rJ   r  z,ExtHandlersHandler.report_ext_handler_status  st   *;F&99; !   $;$E$EEW^^_j_o_op@@AS]`lo@p%779! O888K<]<]  < <<S - ? ? AI ,09h0G--:5LY]][mMn5oN2 $1#O#OP^`r#s  '( ''7++223GH & S!44T!W1664RRSs   ;AE 	F#&FFr   TN)FNF)rB   rC   rD   r   r  r   r   r   staticmethodr
  r   r   r,  r8  r   r?  r=  r\  rW  rg  rm  rj  rY  r[  r  r  r  r  rH   rI   rJ   r   r     s    6u&qP_
'< 0 03gj
 3 3@:D $! $!LJX ' '(O8 1 1 j j0 <# <#|-+>*"X [_@ECJ)6(IrI   r   c                      e Zd ZdLdZed        Zed        Zed        ZdMdZd Z	e
d        ZdNd	ZdLd
Zd Zd Zd Zd Zd Zd ZdOdZd Zd Zd Zd Zd Zd ZdNdZd Zd ZdMdZdPdZdNdZ dMd Z!d! Z"dQd"Z#dNd#Z$d$ Z%dMd%Z&d& Z'd' Z(d( Z)de*jV                  fd)Z,d* Z-d+ Z.e
d,        Z/dd-e0jb                  ddfd.Z2d/ Z3d0 Z4d1 Z5d2 Z6dMd3Z7d4 Z8d5 Z9d6 Z:dMd7Z;d8 Z<dMd9Z=d: Z>e?j                  ddfd;ZAd< ZBd= ZCdMd>ZDd? ZEd@ ZFdA ZGdB ZHdC ZIdD ZJdE ZKdF ZLe
dG        ZMe
dH        ZNe
dI        ZOdRdJZPe
eQfdK       ZRy)Sr  Nc                 ~    || _         || _        d | _        d | _        d | _        d | _        | j                  ||       y )N)r%  execution_log_max_size)r  r   r   r  pkg_filer   
set_logger)r   r  r   r  r%  s        rJ   r   zExtHandlerInstance.__init__  s>    & )DZ[rI   c                 .    | j                   j                  S r   )r  r  r   s    rJ   r  z(ExtHandlerInstance.supports_multi_config  s    555rI   c                 .    | j                   j                  S r   )r  r)  r   s    rJ   r   zExtHandlerInstance.extensions	  s    (((rI   c                     | j                   r=| j                  D cg c]'  }| j                  |      t        j                  k(  s&|) c}S | j                  S c c}w )z
        In case of Single config, just return all the extensions of the handler
        (expectation being that there'll only be a single extension per handler).
        We will not be maintaining extension level state for Single config Handlers
        )r  r   ry  r*   r   )r   r.  s     rJ   r  z%ExtHandlerInstance.enabled_extensions  sK     %%#'??nCd6N6Ns6SWeWmWm6mCnn os   'AAc                     | j                  |      r0dj                  | j                  j                  |j                        S | j                  j                  S )z
        Get the full name of the extension <HandlerName>.<ExtensionName>.
        :param extension: The requested extension
        :return: <HandlerName> if MultiConfig not supported or extension == None, else <HandlerName>.<ExtensionName>
        z{0}.{1})r9  rX   r  rq   r   r%  s     rJ   r>  z*ExtHandlerInstance.get_extension_full_name  sG     ..y9##D$4$4$9$99>>JJ$$$rI   c                 J   	 t        j                  | j                         d       | j                  |      sdndj	                  |j
                        }t        j                  j                  | j                         |      }| j                  ||| j                  |             | j                  j                  t        j                  j                  t        j                  j                   |       y # t"        $ r&}| j                  j%                  d|       Y d }~y d }~ww xY w)Ni  modezCommandExecution.logzCommandExecution_{0}.logz'Failed to create extension log dir: {0})r   mkdirget_log_dirr9  rX   rq   r   r   r   '_ExtHandlerInstance__truncate_file_headr>  r   add_appenderAppenderTypeFILELogLevelINFOIOErrorrO   )r   r%  r  log_file_namelog_filer   s         rJ   __set_command_execution_logz.ExtHandlerInstance.__set_command_execution_log#  s    
	_NN4++-E: ;?:]:];2 : A A).. Q  ww||D$4$4$6FH%%h0FHdHdenHopKK$$V%8%8%=%=v?S?SU]^  	MKKH!LL	Ms   %C3 3	D"<DD"c           	         	 t        j                  |       j                  |k  ry t        | d      5 }|j	                  d|z  d       |j                         }t        | dz   d      5 }t        j                  ||       d d d        d d d        t        j                  | dz   |        y # 1 sw Y   +xY w# 1 sw Y   /xY w# t        t        f$ r}t        |      rY d }~y t        j                  d| |t        |             | | dz   fD ]m  }	 t        j                  |       # t        t        f$ rC}t        |      rt        j                   d|       nt        j"                  d||       Y d }~gd }~ww xY w Y d }~y d }~ww xY w)	Nrbr2  r>   z.tmpwbzXException occurred while attempting to truncate {0} for extension {1}. Exception is: {2}zFile '{0}' does not exist.z=Exception occurred while attempting to remove file '{0}': {1})r   statst_sizeopenseekreadliner   copyfileobjrenamer  r  r"   r   rO   r!   r  r   r   )	filenamemax_sizerK  existing_filer  tmp_filer   fcleanup_exceptions	            rJ   __truncate_file_headz'ExtHandlerInstance.__truncate_file_head0  sb    	7wwx ((H4h% @""2=!4!**,(V+T2 @h&&}h?@	@ IIh'2@ @	@ @ ! 	7&q) LLj.$q'3 6 12 77IIaL) 7./@A$@!D$cef$57	77	7s{   "B? B? 5B3&B'=B3!B? 'B0	,B33B<8B? ?F E;+E;
D E; E2/9E-(E;-E22E;;F c                 f   | j                   j                  d       	 | j                  j                         j	                  | j
                  j                  | j
                  j                        }|j                  }t        t!        | j
                  j"                              }| j%                         }||n
t        |      }d }	d }
|j&                  j)                  d        |j&                  D ]2  }t        |j"                        }||k(  r|}
|j+                  |      s1|}	4 |t,        j.                  t,        j0                  fv ri|
Adj3                  || j
                  j                        }| j                   j5                  |       |
| _        |t!        |      nd | j
                  _        n7|	| _        | j6                  $t!        |	j"                        | j
                  _        | j6                  0| j                   j                  d| j6                  j"                         |j+                  t        | j
                  j"                              s| j9                  |       | j6                  S # t        $ r}t        d|      d }~wt        $ r! | j                  t        j                          w xY w)NzDecide which version to usezFailed to get ext handler pkgsc                 ,    t        | j                        S r   )r/   r	   )ps    rJ   r  z3ExtHandlerInstance.decide_version.<locals>.<lambda>j  s    _QYY-G rI   r(  zXFailed to find installed version: {0} of Handler: {1}  in handler manifest to uninstall.zUse version: {0}r3  )r   r  r   r   fetch_extension_manifestr  rq   manifest_urispkg_listr   r   r   rU  r   rV  r/   r   r	   get_installed_versionversionsr+  matchesr+   rZ  rX  rX   r   r  r  )r   rN  r%  manifestr  r   requested_versioninstalled_version_stringinstalled_versionselected_pkginstalled_pkgr  pkg_versionre   s                 rJ   rT  z!ExtHandlerInstance.decide_versionT  sd   9:	}}335NNtO_O_OdOdfjfvfv  gE  gE  FH((H ,C0@0@0H0H,IJ#'#=#=#? 1I1Q-Wfg  XA #GH$$ 	#C)#++6K// # ((5"	# 3==?V?_?_``$pww%t'7'7'<'<>  %$DH$0 (++<'=6: $ $DHxx#+.|/C/C+D  (88KK 2DHH4D4DE !((9I9I9Q9Q)RSOOiO0xxc  	F !A1EE% 	1::;	s   AI. .	J07J-J0c                     dj                  | j                  |            }t        j                  t        j                  |      | _        | j                  ||       y )Nz[{0}])rX   r  r   LoggerDEFAULT_LOGGER._ExtHandlerInstance__set_command_execution_log)r   r  r%  prefixs       rJ   r  zExtHandlerInstance.set_logger  sD     2 29 =>mmF$9$96B((4JKrI   c                     | j                   j                  }|j                   j                  }t        |      t        |      kD  S r   r  r	   r/   r   otherself_versionother_versions       rJ   r  zExtHandlerInstance.version_gt  s9    ''//))11|,}/MMMrI   c                     | j                   j                  }|j                   j                  }t        |      t        |      k7  S r   r  r  s       rJ   ri  zExtHandlerInstance.version_ne  s9    ''//))11|,0NNNrI   c                     | j                         }|y t        j                  | j                        }||_        t        || j                        S r   )r  r   r   r  r	   r  r   )r   latest_versioninstalled_handlers      rJ   re  z,ExtHandlerInstance.get_installed_ext_handler  sI    335! MM$*:*:;$2!!"3T]]CCrI   c                    d }t        j                  t        j                  j	                  t        j                         | j                  j                  dz               D ]   }t        j                  j                  |      s$|j                  d      }t        ||dz   d        }t        j                  j	                  |dd      }t        j                  j                  |      rLt        j                  |      t        j                   k(  s&t        j                  |      t        j"                  k(  r%t%        j&                  dj)                  |             |||k  s|} |t+        |      S d S )Nz-*r5   r   r   HandlerStatez8Ignoring version of uninstalled or failed extension: {0})r   r   r   r   r   r   r   r  rq   r   r  r/   existsr   	read_filer   r   r   r   r  rX   r   )r   r  r   r  version_from_path
state_paths         rJ   r  z(ExtHandlerInstance.get_installed_version  s   JJrww||D,<,<,>@P@P@U@UX\@\]^ 	3D77==&

3I /Y]^0D EdHnEJ77>>*-1C1CJ1OSbSoSo1o))*59V9VVY``aefg%:K)K!2	3  '5&@s>"JdJrI   c                    | j                   j                  d       |j                         }| j                         }t        j                  j                  |d      }t        j                  j                  |      r.t        j                  d||       t        j                  ||       nt        j                  d|       |j                         }| j                         }t        j                  j                  |      rqt        j                  |      D ]X  }t        j                  j                  ||      }t        j                  j                  |      sCt        j                  ||       Z y y )Nz(Copy status files from old plugin to newmrseqzMigrating {0} to {1}.z+{0} does not exist, no migration is needed.)r   r   get_base_dirr   r   r   r   r   copy2get_status_dirr   r   )r   ro  old_ext_dirnew_ext_dirold_ext_mrseq_fileold_ext_status_dirnew_ext_status_dirstatus_files           rJ   r  z$ExtHandlerInstance.copy_status_files  s   CD'446'')WW\\+w?77>>,-KK/1C[QLL+[9KKEGYZ.==?!00277==+,!zz*<= B ggll+={K77>>+.LL.@AB -rI   c                     || _         y r   )r   )r   r   s     rJ   rU  z ExtHandlerInstance.set_operation  s	    rI   r   r   c           	          | j                   j                  }|| j                   j                  n|}t        |||| j                  |||       y )N)rq   r	   ru   r   r   r   r   )r  r	   rq   r   r   )r   rq   ru   r   r   r   ext_handler_versions          rJ   r  zExtHandlerInstance.report_event  sI    "..66(,t$$$t%8'^^
XYb	drI   c                    | j                   j                  d|       	 t        j                  |      j	                  |       y# t
        $ rr}t        j                  dt        |             t        j                  |       t        j                  j                  |      rt        j                  |       Y d }~yd }~ww xY w)Nz Unzipping extension package: {0}z,Error while unzipping extension package: {0}FT)r   r   zipfileZipFile
extractallr   r!   r   r  r   r  r   r   )r   source_filetarget_directory	exceptions       rJ   _unzip_extension_packagez+ExtHandlerInstance._unzip_extension_package  s    ;[I	OOK(334DE   	KKFYXIIk"ww~~././	s   $A 	B>A(B99B>c                    t         j                   j                         }| j                  t        j                         | j
                  8| j
                  j                  "t        | j
                  j                        dk(  rt        d      t        j                  j                  t        j                         | j                               }d}t        j                  j                  |      rZ| j                   j#                  d|       | j%                  || j'                               rd}n| j                   j#                  d       |s| j(                  j+                         j,                  j.                  t0        j2                  k(  }| j(                  j4                  j7                  d| j
                  j                  || j'                         |       | j9                  d	t;        |      
       || _        y )Nr   zNo package uri foundFz%Using existing extension package: {0}Tz:The existing extension package is invalid, will ignore it.zextension package)use_verify_headerzDownload succeeded)ru   r   )r   r   rU  r   rV  r  urisr  r   r   r   r   r   r   "get_extension_package_zipfile_namer  r   r   r7  r$  r   r   r   r   r#   	FastTrackclientdownload_zip_packager  r   r  )r   	begin_utcpackage_filepackage_existsis_fast_track_goal_states        rJ   rs  zExtHandlerInstance.download  sr   %%,,.	-66788txx}}4DHHMM8Ja8O()?@@ww||D$4$4$68_8_8ab77>>,'KKDlS,,\4;L;L;NO!%  !]^'+}}'C'C'E'['['b'bfuff'$MM  556I488==Zfhlhyhyh{  Ph5  i&:EYZcEde$rI   c                     | j                   rM| j                         j                         s.t        dj	                  | j
                  j                              y y )Nz]Handler {0} does not support MultiConfig but CRP expects it, failing due to inconsistent data)r  r  supports_multiple_extensionsr   rX   r  rq   r   s    rJ   rk  z0ExtHandlerInstance.ensure_consistent_data_for_mc  sT    
 %%d.@.@.B._._.a*ovv$$))+, , /b%rI   c                 &   | j                   j                  dj                  | j                                      t	        j
                  | j                               D ]F  }t	        j                  |t        j                  |      j                  t        j                  z         H t	        j                  | j                         d      }|t        d      	 t	        j                  |d      }t	        j                  | j!                         |       | j)                          	 | j+                         }t	        j,                  |d	       | j/                         }t	        j,                  |d	       t1        t2        j4                        j6                  r%t	        j,                  | j9                         d	       | j;                          | j=                          y # t"        $ rB}t	        j$                  || j                         | j&                  g       t        d|      d }~ww xY w# t"        $ r_}t	        j$                  || j                         | j&                  g       t        d
j                  | j                               |      d }~ww xY w)NzInitializing extension {0}HandlerManifest.jsonzHandlerManifest.json not foundT)
remove_bompathsz#Failed to save HandlerManifest.json  r  z$Failed to initialize extension '{0}')r   r   rX   r  r   get_all_filesr$  chmodr   r  st_modeS_IXUSRsearch_filer   r  
write_fileget_manifest_filer  clean_ioerrorr  rk  r&  r  r  r   r   ExtensionTelemetryPipelineis_supportedget_extension_events_dircreate_handler_envset_extension_resource_limits)r   r   man_filemanr   
status_dirconf_dirs          rJ   rt  zExtHandlerInstance.initialize  s   5<<T=O=O=QRS **4+<+<+>? 	GDNN4!6!6!EF	G ''(9(9(;=ST()IJJ	T$$X$?C 6 6 8#>
 	**,	r,,.JNN:E2((*HNN8%0,-B-]-]^kkt<<>UK 	!**,1  	T""1T->->-@$--,PQ()OQRSS	T"  	r""1T->->-@$--,PQ()P)W)WX\XjXjXl)mopqq	rs2   ;G #BH( 	H%#=H  H%(	J1AJJc                    | j                         }| j                         }|j                  || j                  j                        }t        j                         j                  ||j                               set        j                         j                  ||j                                t        j                         j                  |j                                y y )N)	cpu_quota)rK  r]  )r  r  get_resource_limitsr  r	   r   get_instance,is_extension_resource_limits_setup_completedget_extension_slice_cpu_quotasetup_extension_slice'set_extension_services_cpu_memory_quotaget_service_list)r   rK  rY  resource_limitss       rJ   rW  z0ExtHandlerInstance.set_extension_resource_limits0  s    ++-  "11.$BRBRBZBZ[!..0]]^lhw  iV  iV  iX ^ Y++-CC-9f9f9h D j++-UUVeVvVvVxy	YrI   c           	         | j                  |      \  }}|2t        j                  j                  |      st        j                  j                         j                  d      }d|| j                  |      |||d|dddg}	t        j                  j                  t        j                  j                  |            s4t        j                  t        j                  j                  |      d       | j                  j                  d	j                  ||             t        j                  |t        j                   |	             y y y )
Nz%Y-%m-%dT%H:%M:%SZ      ?zen-US)rt   ru   )rq   r   rz   rf   r{   )r	   timestampUTCrz   rJ  r  z7Creating a placeholder status file {0} with status: {1})r  r   r   r  r   r   strftimer>  dirnamer   r  r   r   rX   rP  r  r  )
r   r%  rz   rf   r   ru   r  status_pathnowstatus_contentss
             rJ   r<  z2ExtHandlerInstance.create_status_file_if_not_exist;  s   229=;"277>>++F##**,556JKC  #$' $ < <Y G%."( $$+'.-	O$ 77>>"''//+">?rww{;%HKKV]]^ikqrsTZZ-HI/ ,G"rI   c                    	 | j                  ||       | j	                  t
        j                         | j                  t        j                  d       y # t        $ r"}| j                  |      rt        |       d }~ww xY w)NzPlugin enabledrz   ru   )
_enable_extensionr   r9  r    rr  r   r   r;  rA   rF   )r   r%  rn  rO   s       rJ   rx  zExtHandlerInstance.enableV  sw    	""9.AB 	667'<'B'BL\]  	229=5e<<	s   A 	B A;;B c                 &    | j                   xr |d uS r   )r  r  s     rJ   r9  z1ExtHandlerInstance.should_perform_multi_config_opa  s    ))Cit.CCrI   c                    |t        |      nt        }t        j                  |i}| j	                          | j                  t        j                         | j                         }|j                         }| j                  j                  dj                  |             | j                  |ddt        j                  ||       | j!                  |      r | j#                  |t$        j&                         |j)                  | j+                         | j,                  j.                        }t1        j2                         j5                  |j7                                y )NzEnable extension: [{0}]rx  ,  cmd_nametimeoutextension_error_codeenvr%  )r   r<   rS   r[   rW  rU  r   Enabler  get_enable_commandr   r   rX   launch_commandr   PluginEnableProcessingFailedr9  (_ExtHandlerInstance__set_extension_stater*   r   r^  r  r  r	   r   r_  )start_tracking_extension_services_cgroupsrd  )r   r%  rn  rx  rY  
enable_cmdre  s          rJ   rp  z$ExtHandlerInstance._enable_extensiond  s"   :M:Yc"56_f "557J
 	**,-445  "++-
299*EFJ31D1a1agj&/ 	 	1 ..y9&&y.2H2HI 11$2D2D2FHXHXH`H`a'')SS,,.	0rI   c                    | j                  t        j                         | j                         }|j	                         }| j
                  j                  dj                  |             | j                  |ddt        j                  |       y )NzDisable extension: [{0}]rz    )ru  rv  rw  r%  )rU  r   Disabler  get_disable_commandr   r   rX   r{  r   PluginDisableProcessingFailed)r   r%  rY  disable_cmds       rJ   _disable_extensionz%ExtHandlerInstance._disable_extension~  sv    -556  "--/3::;GHK)S1D1b1b&/ 	 	1rI   c                    	 | j                  |       | j                  |      r| j                  |       | j                  rt        | j                        sA| j                  t        j                         | j!                  t"        j$                  d       y y # t        $ rf}|s dj                  t        |            }| j                  j                  |       | j                  | j                  |      |dd       Y d }~d }~ww xY w)Nz6[Ignored Error] Ran into error disabling extension:{0}Frq   ru   r   r   zPlugin disabledro  )r  r   rX   r!   r   r   r  r>  r9  1_ExtHandlerInstance__remove_extension_state_filesr  r   r  rr  r   r   r;  rA   rG   )r   r%  rw  rO   re   s        rJ   rz  zExtHandlerInstance.disable  s    		/##I. ..y9//	: ))T5L5L1M""?#<#<=##+@+J+JTe#f 2N  	/JQQRVW\R]^CKKS!4#?#?	#JTWdi(-  / /	/s   B 	D!ADDc                    |t        |      nt        }t        j                  |i}| j	                         }|j                         }| j                  j                  dj                  |             | j                  t        j                         | j                  |dd|t        j                  |       | j                  t         j"                         | j%                  t&        j(                  d       y )NzInstall extension [{0}]rh  r  )ru  rv  r%  rw  rx  z Plugin installed but not enabledro  )r   r<   rS   r[   r  get_install_commandr   r   rX   rU  r   Installr{  r   PluginInstallProcessingFailedrr  r   r   r;  rA   rG   )r   rn  r%  rx  rY  install_cmds         rJ   rh  zExtHandlerInstance.install  s     ;N:Yc"56_f$88:MN  "--/299+FG-556K)ST]1D1b1bhk 	 	m889'<'F'FPrsrI   c                 *   | j                  t        j                         | j                         }|j	                  | j                         | j                  j                        }t        j                         j                  |j                                t        j                         j                  |j                                |j                         }| j                  j                  dj!                  |             | j#                  |d|       y )NzUninstall extension [{0}]r  )ru  r%  )rU  r   	UnInstallr  r^  r  r  r	   r   r_  (stop_tracking_extension_services_cgroupsrd  'remove_extension_services_drop_in_filesget_uninstall_commandr   r   rX   r{  )r   r%  rY  re  uninstall_cmds        rJ   r  zExtHandlerInstance.uninstall  s     	-778  " 11$2D2D2FHXHXH`H`a'')RR,,.	0'')QQ,,.	0 1134;;MJKMK9UrI   c                 n   	 t         j                  j                  t        j                         | j                               }t         j                  j                  |      r1t        j                  |       | j                  j                  d|       | j                         }t         j                  j                  |      r6| j                  j                  d|       d }t        j                  ||       | j                  j                  dj                  | j!                                      t#        j$                         j'                  | j!                                y # t(        $ rI}dj                  |      }| j+                  |d	       | j                  j-                  |       Y d }~y d }~ww xY w)
Nz%Deleted the extension zip at path {0}z'Remove extension handler directory: {0}c                 R    |\  } }} t        |t              r|j                  dk7  r|y )Nr>   )r   r  errno)r  __exc_infor6  s       rJ   on_rmtree_errorz>ExtHandlerInstance.remove_ext_handler.<locals>.on_rmtree_error  s.    &.OAy!%i9Y__PQ=Q' >RrI   )onerrorzRemove the extension slice: {0})rK  z1Failed to remove extension handler directory: {0}Fr~  )r   r   r   r   r   r;  r  r  r   r  r$  r   r   r   r   rX   r  r   r_  remove_extension_slicer  r  r   )r   zip_filenamebase_dirr  r   ru   s         rJ   r  z%ExtHandlerInstance.remove_ext_handler  sA   	&77<<(8(8(:D<c<c<efLww~~l+		,'##$K\Z((*Hww}}X&  !JHU(
 h@KK>EEdFXFXFZ[\++-DD#113 E 5  	&IPPQRSGg%@KKW%%	&s   EE" "	F4+?F//F4c           	      ^   || j                   j                  }d|t        j                  |i}| j                  s@t        |j                  | j                   j                              |t        j                  <   nyg }| j                  D ]B  }|j                  |j                  t        |j                  |j                              d       D t        j                  |      |t        j                  <   	 | j                  t        j                          | j#                         }|j%                         }	| j&                  j)                  dj+                  |	             | j-                  |	ddt.        j0                  ||       y # t2        $ r! | j5                  t6        j8                          w xY w)NVERSION)extensionNameexitCodezUpdate extension [{0}]r  r  rt  )r  r	   rS   r`   r  r!   rv   rq   rY   r   r   r  r  rZ   rU  r   Updater  get_update_commandr   r   rX   r{  r   PluginUpdateProcessingFailedr   rr  r   r   )
r   r_  r  r  r%  rx  disable_codesr.  rY  
update_cmds
             rJ   r  zExtHandlerInstance.update  s|    ""..66O !557L

 ));?@R@V@VW[WgWgWlWl@m;nC%778M $$%(XX $%7%;%;CHH%E F& 
 NRZZXeMfC%IIJ	1889$$&C//1JKK5<<ZHI
X(+5H5e5e$'9   >  	""?#@#@A	s   3BF *F,c                     | j                         }|j                         r| j                  ||       n| j                  j	                  d       | j                  t        j                         y )Nr  z7UpdateWithInstall not set. Skip install during upgrade.)r  is_update_with_installrh  r   r   rr  r   r   )r   rn  r%  rY  s       rJ   r  z&ExtHandlerInstance.update_with_install  sX      "%%'LL-@ILVKK < =889rI   c                 (   d}| j                   r||j                  |S 	 d}| j                         }t        j                  |      D ]  }t        j
                  j                  ||      }t        j
                  j                  |      sC	 t        j                  d|      }|o|j                  d      }| j                   r|j                  |k7  rt        |j                  d            }	t        j
                  j                  |      }
|
|kD  r|	}|
} 	 |S # t        t        t        f$ r  | j                   j#                  d|       Y w xY w# t$        $ r:}t!        j"                  dj'                  t)        |                   d}Y d}~|S d}~ww xY w)	a0  
        The sequence number is not guaranteed to always be strictly increasing. To ensure we always get the latest one,
        fetching the sequence number from config file that was last modified (and not necessarily the largest).
        :return: Last modified Sequence number or -1 on errors
        r2  Nr   z/((?P<ext_name>\w+)\.)*(?P<seq_no>\d+)\.settingsra  r   zFailed to parse file name: {0}z5Error fetching sequence number from config files: {0})r  rq   r  r   r   r   r   r   r  r  r  intgetmtime
ValueError
IndexError	TypeErrorr   r  r   rX   r!   )r   r%  r   largest_modified_timer[  r  	item_pathr  ra  curr_seq_nocurr_modified_timerO   s               rJ   +_get_last_modified_seq_no_from_config_filesz>ExtHandlerInstance._get_last_modified_seq_no_from_config_files
  so    %%9+<	@VM	$%!((*H

8, GGLL48	ww~~i0 II&[]fgE(#(;;z#:55)..H:T$&)%++h*?&@-/WW-=-=i-H*-0EE%0F4F1!0  #J	: KK''(H$O  	NNRYYZ^_dZefgF		sJ   A*E ADE ADE 0EE 
EE 	F/FFc                 x   d}d}|"|j                   	 t        |j                         }|| j                  |      }||dkD  r| j                  |      rW|U|j                  It        j                  j                  | j                         dj                  |j                  |            }nI| j                  s=t        j                  j                  | j                         d      j                  |      }|||fS d|fS # t        $ r2 t        j                  dj                  |j                                Y w xY w)a\  
        We should technically only fetch the sequence number from GoalState and not rely on the filesystem at all,
        But there are certain scenarios where we need to fetch the latest sequence number from the filesystem
        (For example when we need to report the status for extensions of previous GS if the current GS is Unsupported).
        Always prioritizing sequence number from extensions but falling back to filesystem
        :param extension: Extension for which the sequence number is required
        :return: Sequence number for the extension, Status file path or -1, None
        Nz1Sequence number [{0}] does not appear to be validr2  z{0}.{1}.statusz
{0}.status)r  r  r  r   rO   rX   r  r9  rq   r   r   r   r&  r  )r   r%  r   r   s       rJ   r  z'ExtHandlerInstance.get_status_file_path3  s*     Y%=%=%IsY556 > EEiPF&2+229=)BW\e\j\j\vww||D$7$7$9;K;R;RS\SaSaci;jk//ww||D$7$7$9<HOOPVW+vT99T99  sPWWXaXpXpqrss   C> >7D98D9c           
         | j                   j                  dj                  | j                  |                   | j	                  |      \  }}|dk(  s|y d }d }t        |j                  |      }	 | j                  |      \  }}	 t?        ||       tA        |      tB        kD  rJt        dj                  | j!                  |      ||tA        |      tB              t        jD                        	 |S # t        $ r}d}t        j                  |_        |j                  t        j                  k(  rAt        j                  |_        dj                  | j!                  |      |t#        |            }n|j                  t        j$                  k(  rAt        j&                  |_        dj                  | j!                  |      |t#        |            }nq|j                  t        j(                  k(  rTdj                  | j                  |      t#        |            }t        j*                  |_        t        j,                  |_        t        j.                  t         j0                  d|z          t3        t         j0                  | j                  |      | j4                  j6                  t8        j:                  d	|d	
       ||_        |cY d }~S d }~ww xY w# t        $ r}dj                  | j!                  |      ||t#        |            }t        j.                  t         jF                  d|z          t3        t         j0                  | j                  |      | j4                  j6                  t8        j:                  d	|d	
       |j                  t        jD                  k(  rJ| jI                  |j<                  tJ              \  |_        }	| jM                  |jN                  |	      |_'        nv|j                  t        jP                  k(  rYdj                  | j!                  |      t#        |            |_        t        j&                  |_        t        j                  |_        Y d }~|S d }~ww xY w)Nz Collect extension status for {0}r2  )rq   r   r   z`We couldn't read any status for {0} extension, for the sequence number {1}. It failed due to {2}zThe status reported by the extension {0}(Sequence number {1}), was in an incorrect format and the agent could not parse it correctly. Failed due to {2}zhThis status is being reported by the Guest Agent since no status file was reported by extension {0}: {1}z[PERIODIC] F)deltarq   r	   r   r   ru   r   zFor Extension Handler {0} for the sequence number {1}, the status file {2} of size {3} bytes is too big. Max Limit allowed is {4} bytesrd   zpFor Extension Handler {0} for the sequence number {1}, the status file {2}. Encountered the following error: {3}zYCould not get a valid status from the extension {0}. Encountered the following error: {1}))r   r  rX   r>  r  r$   rq   _read_status_filerh   rL   rO   rz   rf   CouldNotReadStatusFiler   PluginUnknownFailurer  r!   InvalidJsonFilePluginSettingsStatusInvalidFileNotExistsPluginSuccessrM   periodic_warnEVERY_HALF_HOURr   r  r	   r   StatusProcessingru   r   r  _MAX_STATUS_FILE_SIZE_IN_BYTESMaxSizeExceeded	EVERY_DAY_truncate_message_MAX_STATUS_MESSAGE_LENGTH_process_substatus_listr   ri   )
r   r.  r   ext_status_filer   data_strr   r   re   
field_sizes
             rJ   collect_ext_statusz%ExtHandlerInstance.collect_ext_statusQ  s   >EEdFbFbcfFghi"&";";C"@ R<3;$#((6B
$	!33ODNHdN	?Z.8}==* 0w,2F43E3Ec3JF3BCMSq-s0D0T0T	V V >2 C $ "	C 4 : :Jvv-DDD"5"J"J
!!'(:(:3(?a!Q /???"5"Q"Q
hvd005vtAwG  /===77=vd>Z>Z[^>_aefgah7i 
 #6"C"C
$8$F$F
!   !7!7#9MNv55D<X<XY\<]!%!1!1!9!9.??E[^#(*
 "%JE"	\ $ 	?::@&ASASTWAXZ`APRVWXRY;[    !1!1>C3GHv55D<X<XY\<]!%!1!1!9!9.??E[^joq vv-===151G1G
HZHZ\v1w.
"J+/+G+G
H`H`bl+m
(/CCC&<<BF4CUCUVYCZ\`ab\c<d ""5"Q"Q
$8$>$>
!'	?s9   2C2 A(K 2
K<GK KK
Q$FQQ$c                     | j                  |      \  }}|dk  s|y t        j                  j                  |      st        j
                  }|S | j                  |      }||j                  nd }|S )Nr   )r  r   r   r  rL   rN   r  rz   )r   r.  r   r  rz   r   s         rJ   get_ext_handling_statusz*ExtHandlerInstance.get_ext_handling_status  su    "&";";C"@ A:0 ww~~o.)11F
  005J*4*@Z&&dFrI   c                 J    | j                  |      }|y|t        vrd|fS d|fS )Nr  FT)r  _EXTENSION_TERMINAL_STATUSES)r   r.  rz   s      rJ   rH  z+ExtHandlerInstance.is_ext_handling_complete  s=    --c2 > 55&=  V|rI   c                     |rJt        j                  |       t        | j                  |      | j                  j
                  ||dd       y t        j                  |       y )NF)rq   r	   r   ru   r   r   )r   r   r   r>  r  r	   r  )r   r  r  r  r%  r   s         rJ   r  z5ExtHandlerInstance.report_error_on_incarnation_change  sN     KK 477	BDL\L\LdLdY5ES NN7#rI   c                 t   g }| j                   D ]  }| j                  |      r@|j                  t        j                  k(  r#| j                  |      t        j                  k(  rT	 t               }t        d|t        |             	 | j!                  |      }|||_        |j%                  |        |S # t        $ ru}dj                  | j                               }| j                  ||dj                  |t        j                  |                   | j                  |d       Y d}~ |S d}~ww xY w# t&        $ r}dj                  | j                  |            }| j                  ||dj                  |t        j                  |            |	       | j                  |      s-| j                  t)        |      |j*                         Y d}~ |S t-        |j.                  |j0                  t2        j4                  t6        j8                  |
      }||_        |j%                  |       Y d}~#d}~ww xY w)aM  
        Get the list of ExtHandlerStatus objects corresponding to each extension in the Handler. Each object might have
        its own status for the Extension status but the Handler status would be the same for each extension in a Handle
        :return: List of ExtHandlerStatus objects for each extension in the Handler
        r'   zLSomething went wrong when trying to get a copy of the Handler status for {0}z{0}.
Stack Trace: {1})r  r  r2  r4  Nz<Unknown error when trying to fetch status from extension {0})r  r  r%  )rq   r   rf   rz   ru   )r   r9  r#  r*   rX  ry  r'   r   r   r   rX   r>  r  r-   r   r;  r  extension_statusr   r   r!   rf   r$   rq   r  r   r  rL   rO   )	r   r  r  r  r.  ext_handler_statusrO   re   r   s	            rJ   r  z1ExtHandlerInstance.get_extension_handler_statuses  s=     "?? 1	@C 2237II!8!88T=U=UVY=Z^l^u^u=u%5%7"13E~VdGef@!44S9
):D&7$++,>?91	@f $#O  	dkk0024778JVY@X@_@_UXZbZsZstyZzA| 8 }
 ''"'=< $#O	" " @T[[0057778JVY@X@_@_UXZbZsZstyZzA|BE 8 G ::3?++DKejj+Q $# -#((3CUCU2E2Z2Z4H4N4NX[]
 7A"3$++,>??)@s9   $ B4+D54	D2=A)D--D25	H7>BH2AH22H7c                 Z   | j                         }|j                         sy t        j                  j	                  t        j                         | j                               }t        j                  j                  |      st        d      | j                  |      sddddS 	 t        j                  |      }t        j                  |      d   d   }|S # t        $ r}t        dj!                  |            d }~wt"        t$        f$ r}t        d	j!                  |            d }~ww xY w)
NzFailed to get heart beat filer:   r2  z%Extension heartbeat is not responsive)rz   rf   ru   r   r  z Failed to get heartbeat file:{0}zMalformed heartbeat file: {0})r  is_report_heartbeatr   r   r   r   r   get_heartbeat_filer   r   is_responsiver   r  r  loadsr  rX   r  KeyError)r   rY  heartbeat_fileheartbeat_jsonr  r   s         rJ   r  z$ExtHandlerInstance.collect_heartbeat
  s     "&&(d&6&6&8&*&=&=&?A ww~~n- !@AA!!.1(B 
	L%//?N

>215kBI
 	  	O !C!J!J1!MNNH% 	L !@!G!G!JKK	Ls$   $0C 	D*C99D*D%%D*c                     t        t        j                         t        j                  |       j                  z
        }|dk  S )z
        Was heartbeat_file updated within the last ten (10) minutes?

        :param heartbeat_file: str
        :return: bool
        iX  )r  rI  r   r  st_mtime)r  last_updates     rJ   r  z ExtHandlerInstance.is_responsive"  s3     $))+(?(H(HHIc!!rI   rs  c                 t   t         j                   j                         }| j                  j                  d|       | j	                         }t        j                  |d      5 }	t        j                  |d      5 }
|i }|j                  t        j                  |t        j                  t        | j                  j                        t        j                  | j                  j!                         t        j"                  |t        |j$                        nt&        i       | j)                  |      r|j*                  |t        j,                  <   g }t/               j1                         D ]-  \  }}|j3                  |j*                  |j                  d       / |r&t5        j6                  |      |t        j8                  <   | j;                  |      }	 t<        j>                  jA                  ||jC                  t<        j>                  jD                              }djG                  |t5        j6                  |            }| j                  jI                  |       | jK                  ||d       |j                  t<        jL                         tO        jP                         jS                  | jU                  |      |||d|||	|
|	
      }t]        |      }djG                  |djA                  |j_                  d      D cg c]
  }|dk7  s	| c}            }| j                  jI                  |       | jK                  |||d       |cd d d        cd d d        S # tV        $ r,}tY        d
jG                  |jZ                        |      d }~ww xY wc c}w # 1 sw Y   nxY w	 d d d        y # 1 sw Y   y xY w)NzLaunch command: [{0}]zw+b)dirr  )KeyValuez6Executing command: {0} with environment variables: {1}F)rq   ru   r   T)
rK  commandru  rv  shellcwdrx  stdoutstderr
error_codezFailed to launch '{0}': {1}rf   zCommand: {0}
{1}
r   )rq   ru   r   r   )0r   r   r   r  r$  tempfileTemporaryFiler  rS   r\   r]   r   r  r	   ra   r   get_endpointr^   r  _DEFAULT_SEQ_NOr9  rq   r_   r
   r  r   r  r  rb   r>  r   r   r   lstripseprX   r   r  environr   r_  start_extension_commandr  r  r   r  r   split)r   cmdru  rv  rw  rx  r%  r?  r  r  r  r   r  r   ra  command_full_pathr  process_outputr   r   lines                        rJ   r{  z!ExtHandlerInstance.launch_command-  sV   %%,,.	3S9$$&##u= A	&''H5A @&V;C 

)77)::C@P@P@X@X<Y)==t}}?Y?Y?[ *<<5>5J ?B!00?2P_	 	 66yA?H~~C-;;<%'""R"T"Z"Z"\ JAw&--#*<<%,__ &LPJJWiLjC-HHI77	BD )+Xszz"''++?V(W%V]]^o^b^h^hil^moGKK$$W-%%8WPU%V JJrzz*%7%D%D%F%^%^'+'9'9)'D 1!) '"$%%#7 &_ 
&9N  0	:-44S$))&4&:&:4&@OdDBJTO;Q R  )!!x8_d!e%A@& @&A	& A	&n  D()F)M)MN_abakak)l.BD DD Py@& @& @&A	& A	& A	&s\   "N.:ENC6M5N=
NN<N	N.	N$'NNNN!	N..N7c                    | j                         }	 t        j                  t        j                  |            }t        |d         S # t
        t        f$ r:}t        dj                  ||j                        t        j                        d }~wt        $ r+ t        dj                  |      t        j                        w xY w)Nz'Failed to load manifest file ({0}): {1}r  zMalformed manifest file ({0}).r   )rQ  r  r  r   r  r  r  r   rX   r  r   PluginHandlerManifestNotFoundr  )PluginHandlerManifestDeserializationErrorHandlerManifest)r   rX  r   r   s       rJ   r  z ExtHandlerInstance.load_manifestw  s    ))+	e::h00:;D tAw'' ! 	Y !J!Q!QRZ\]\f\f!g&9&W&WY Y 	e !A!H!H!R&9&c&ce e	es   (A C5B7Cc                     t         j                  j                  | j                         |      }	 t	        j
                  ||       y # t        $ r)}t	        j                  ||g       t        d|      d }~ww xY w)NrH  zFailed to update settings file)	r   r   r   r  r   rP  r  rR  r   )r   settings_filer)  r   s       rJ   update_settings_filez'ExtHandlerInstance.update_settings_file  sj    T%6%6%8-H	Gx8 	G""1*7: !BAFF	Gs   A 	A9$A44A9c                 N   | j                   t        | j                         dk(  s|A| j                  j                  d       | j	                  dj                  t              d       y |j                  |j                  |j                  d}dd|igi}| j                  |      r&dj                  |j                  |j                        ndj                  |j                        }| j                  j                  d	|       | j	                  |t        j                  |             y )
Nr   z1Extension has no settings, write empty 0.settingsz{0}.settingsr   )publicSettingsprotectedSettingsprotectedSettingsCertThumbprintruntimeSettingshandlerSettingsz{0}.{1}.settingszUpdate settings file: {0})r   r  r   r   r  rX   r  r   r  certificateThumbprintr9  rq   r  r  r  )r   r%  r)  ext_settingsr  s        rJ   rl  z"ExtHandlerInstance.update_settings  s	   ??"c$//&:a&?9CT KKPQ%%n&;&;O&LbQ (66!*!<!</8/N/N
 !8!  
 //	: +11)..)BZBZ[@N@U@UV_VnVn@o 	 	4mD!!-L1IJrI   c           	      x   t         j                  | j                         t         j                  | j	                         t         j
                  | j                         t         j                  | j                         i}t        t        j                        j                  rB| j                         |t         j                  <   | j                         |t         j                  <   t         j                   | j"                  j                   t         j$                  t         j&                  t         j(                  |ig}	 t+        j,                  | j/                         t1        j2                  |             y # t4        $ rB}t+        j6                  || j9                         | j:                  g       t=        d|      d }~ww xY w)NrH  z"Failed to save handler environment)HandlerEnvironment	logFolderr  configFolderr  statusFolderr&  heartbeatFiler  r   r   rS  rT  rU  eventsFoldereventsFolder_previewrq   r  r	   schemaVersionhandlerEnvironmentr   rP  get_env_filer  r  r  rR  r$  r  r   )r   handler_envrx  r   s       rJ   rV  z%ExtHandlerInstance.create_handler_env  sT   ",,d.>.>.@"//1B1B1D"//1D1D1F"00$2I2I2K	 ))>)Y)YZgg;?;X;X;ZK*778CGC`C`CbK*??@ ##T%5%5%:%:&&(:(H(H11;
 
	S 1 1 3TZZ_E 	S""1*.*;*;*=t}})MO()NPQRR	Ss   67E. .	F97=F44F9c                 \    | j                  |      rdj                  |j                        S y)Nz{0}.HandlerStater  )r9  rX   rq   r  s     rJ   __get_handler_state_file_namez0ExtHandlerInstance.__get_handler_state_file_name  s(    ..y9%,,Y^^<<rI   c                 F    | j                  | j                         |       y N)rq   value_ExtHandlerInstance__set_state0_ExtHandlerInstance__get_handler_state_file_name)r   r   s     rJ   rr  z$ExtHandlerInstance.set_handler_state  s    d@@B-XrI   c                 `    | j                  | j                         t        j                        S N)rq   default)_ExtHandlerInstance__get_stater  r   r   r   s    rJ   rf  z$ExtHandlerInstance.get_handler_state  s(    T%G%G%ISbSoSopprI   c                 H    | j                  | j                  |      |       y r  r  )r   r%  extension_states      rJ   __set_extension_statez(ExtHandlerInstance.__set_extension_state  s!    d@@KSbcrI   c                 b    | j                  | j                  |      t        j                        S r  )r  r  r*   rX  r  s     rJ   ry  z&ExtHandlerInstance.get_extension_state  s*    T%G%G	%R\j\s\sttrI   c                    | j                         }t        j                  j                  ||      }	 t        j                  j	                  |      st        j                  |d       t        j                  ||       y # t        $ r>}t        j                  ||g       | j                  j                  d|       Y d }~y d }~ww xY w)NrJ  r  rH  zFailed to set state: {0})r  r   r   r   r  r   r  rP  r  rR  r   rO   )r   rq   r  	state_dir
state_filer   s         rJ   __set_statezExtHandlerInstance.__set_state  s    %%'	WW\\)T2
	=77>>),yu5
E2 	=""1ZL9KK8!<<	=s   AA? ?	C4CCc                 8   | j                         }t        j                  j                  ||      }t        j                  j	                  |      s|S 	 t        j                  |      S # t        $ r(}| j                  j                  d|       |cY d }~S d }~ww xY w)NzFailed to get state: {0})
r  r   r   r   r   r   r  r  r   rO   )r   rq   r  r$  r%  r   s         rJ   __get_statezExtHandlerInstance.__get_state  sy    %%'	WW\\)T2
ww~~j)N	%%j11 	KK8!<N	s   A( (	B1BBBc                 
   | j                   j                  dj                  |j                               	 t        j
                  j                  | j                         dj                  |j                              t        j
                  j                  | j                         dj                  |j                              t        j
                  j                  | j                         | j                  |            g}t        j                  |  y # t        $ rf}| j                  |      }dj                  |t        |            }| j                  ||dd       | j                   j!                  |       Y d }~y d }~ww xY w)Nz1Removing states files for disabled extension: {0}z{0}.*.settingsz{0}.*.statusz3Failed to remove extension state files for {0}: {1}Fr  )r   r   rX   rq   r   r   r   r  r&  r  r   rm_filesr   r>  r!   r  r   )r   r%  files_to_deleterO   rK  ru   s         rJ   __remove_extension_state_filesz1ExtHandlerInstance.__remove_extension_state_files  s(   LSST]TbTbcd	& T..02B2I2I)..2YZT002N4I4I)..4YZT..0$2T2TU^2_`O / 	&!99)DNKRRSacghmcnoG>7u`efKKW%%		&s   CD 	FAE==Fc                    | j                         }t               }| j                  j                  |_        t	        | j                  j
                        |_        ||_        ||_        ||_        | j                  j                  |_	        t        j                  j                  |d      }	 t        j                  t        |            }|Mt        j                  j!                  |      st#        j$                  |d       t#        j&                  ||       y | j(                  j+                  dj-                  | j                  j                  | j                  j
                               y # t.        t0        t2        f$ rQ}t#        j4                  ||g       | j(                  j+                  dt7        j8                  |             Y d }~y d }~ww xY w)NHandlerStatusrJ  r  zDFailed to create JSON document of handler status for {0} version {1}rH  z"Failed to save handler status: {0})r  r'   r  rq   r   r	   ru   rf   rz   r  r   r   r   r  r  r   r  r   r  rP  r   rO   rX   r  r  r   rR  r-   r   )	r   rz   ru   rf   r$  r  r,  handler_status_jsonrO   s	            rJ   r;  z%ExtHandlerInstance.set_handler_status  sb   %%'	)+"..33!$T%5%5%=%=!>!(" &/3/?/?/U/U,ggll9o>	f"&**^N-K"L".ww~~i0NN959##K1DE!!"h"o"o$$))4+;+;+C+C#E F]3 	f""5>KKBHD]D]^cDdee	fs!   +A,E, AE, ,G AGGc           	      x   | j                         }t        j                  j                  |d      }t        j                  j	                  |      sy d}	 t        j                  |      }t        j                  |      }t               }t        d||       |S # t        t        f$ r&}| j                  j                  d|       Y d }~y d }~wt        $ rf}dj!                  t#        |      |      j%                  dd      }t'        t        j(                  t*        t,        t.        j0                  d|	        d }~ww xY w)
Nr.  r   r'   z!Failed to get handler status: {0}zAFailed to get handler status message: {0}.
 Contents of file: {1}"'F)r  rq   r	   r   r   ru   )r  r   r   r   r   r   r  r  r  r'   r   r  r  r   rO   r   rX   r!   replacer   
EVERY_HOURr0   r1   r   r   )r   r$  r,  handler_status_contentsr   r  rO   	error_msgs           rJ   r:  z%ExtHandlerInstance.get_handler_status  s   %%'	ggll9o>ww~~k*"$	&.&8&8&E#::56D-/N-~tD!!$ 	JKKA5II   
	\ccU466=gc46H '''%99 !# 
	s&   AB D9&CD9A!D44D9c                     dj                  | j                  j                  | j                  j                  t              S )Nz{0}__{1}{2})rX   r  rq   r	   r  r   s    rJ   r;  z5ExtHandlerInstance.get_extension_package_zipfile_name/  s5    ##D$4$4$9$9$($4$4$<$<$35 	5rI   c                 l    dj                  | j                  |      | j                  j                        S )z
        :return: <HandlerName>-<HandlerVersion> if extension is None or Handler does not support Multi Config,
        else then return -  <HandlerName>.<ExtensionName>-<HandlerVersion>
        z{0}-{1})rX   r>  r  r	   r  s     rJ   r  z ExtHandlerInstance.get_full_name4  s.    
  < <Y GIYIYIaIabbrI   c                     t         j                  j                  t        j                         | j                               S r   )r   r   r   r   r   r  r   s    rJ   r$  zExtHandlerInstance.get_base_dir;  s)    ww||D,,.0B0B0DEErI   c                 ^    t         j                  j                  | j                         d      S )Nrz   r   r   r   r$  r   s    rJ   r&  z!ExtHandlerInstance.get_status_dir>       ww||D--/::rI   c                 ^    t         j                  j                  | j                         d      S )Nr   r;  r   s    rJ   r  zExtHandlerInstance.get_conf_dirA  r<  rI   c                 f    t         j                  j                  | j                         t              S r   )r   r   r   r  r   r   s    rJ   rU  z+ExtHandlerInstance.get_extension_events_dirD  s!    ww||D,,.0@AArI   c                 ^    t         j                  j                  | j                         d      S )Nzheartbeat.logr;  r   s    rJ   r  z%ExtHandlerInstance.get_heartbeat_fileG  s     ww||D--/AArI   c                 ^    t         j                  j                  | j                         d      S )NrF  r;  r   s    rJ   rQ  z$ExtHandlerInstance.get_manifest_fileJ  s!    ww||D--/1GHHrI   c                 z    t         j                  j                  | j                         t        j
                        S r   )r   r   r   r$  r  fileNamer   s    rJ   r  zExtHandlerInstance.get_env_fileM  s'    ww||D--/1C1L1LMMrI   c                     t         j                  j                  t        j                         | j
                  j                        S r   )r   r   r   r   get_ext_log_dirr  rq   r   s    rJ   r  zExtHandlerInstance.get_log_dirP  s,    ww||D002D4D4D4I4IJJrI   c                    t        j                         }t        j                  d|z   |       Rt        j                  j                         t        j                  j                  t        j                         d      k  ryy)Nz\Az%Y-%m-%dTF)r   !get_cgroup_monitor_extension_namer  r  r   r   strptimeget_cgroup_monitor_expiry_time)rK  cgroup_monitor_extension_names     rJ   is_azuremonitorlinuxagentz,ExtHandlerInstance.is_azuremonitorlinuxagentS  sb    (,(N(N(P%88E99>JV!!((*X->->-G-GHkHkHmoy-zzrI   c                     d}	 	 t         j                  |       S # t        $ r |dz  }|t        k\  r Y nw xY wt	        j
                  t               N)Nr   r   )r   _read_and_parse_json_status_filer   _NUM_OF_STATUS_FILE_RETRIESrI  rJ  _STATUS_FILE_RETRY_DELAY)r  	err_counts     rJ   r  z$ExtHandlerInstance._read_status_file[  s]    	)JJ?[[ Q	 ;; < JJ/0 s    55c           	         t         j                  j                  |       s*t        dj	                  |       t        j
                        	 t        j                  |       }	 t        j                  |      }||fS # t        $ r*}t        t        |      |t        j                        d }~ww xY w# t        t        f$ rF}t        dj	                  t        |      t        |      d d       |t        j                        d }~ww xY w)NzStatus file {0} does not existrd   )re   innerrf   z+{0} 
 First 2000 Bytes of status file:
 {1}i  )r   r   r  rh   rX   r  r   r  r  r!   r  r  r  r  r  r  )r  r  r   r   s       rJ   rL  z3ExtHandlerInstance._read_and_parse_json_status_fileg  s    ww~~o.&+K+R+RSb+c,@,N,NP P	Y))/:H	R::h'D
 ~  	Y&47!,@,W,WY Y	Y
 I& 	R&+Z+a+abfghbikopxkyz{  lA  ,B-.,@,P,PR R	Rs1   A: !B0 :	B-%B((B-0D?AD  Dc                    g }|D ]y  }| j                  |j                  t              \  |_        }||z  }| j                  |j                  t              \  |_        }||z  }|t        k  r|j                  |       x |S  |S r   )r  rq   _MAX_SUBSTATUS_FIELD_LENGTHru   r  r   )r   r   current_status_sizeprocessed_substatusr|   r  s         rJ   r  z*ExtHandlerInstance._process_substatus_listz  s      ( 
	I)-)?)?	Pk)l&INJ:-,0,B,B9CTCTVq,r)Iz:-"&DD#**95""
	 #"rI   c                 Z    | y t        |       |k  r| n| d | t        z   }|t        |      fS r   )r  _TRUNCATED_SUFFIX)fieldtruncate_sizetruncated_fields      rJ   r  z$ExtHandlerInstance._truncate_message  s9    ='*5zM'Aeu^mG\_pGpO"C$888rI   )i   Nr   )NN)Nr   Tr   T)NF)NNNN)r   )SrB   rC   rD   r   propertyr  r   r  r>  r  r  r  rT  r  r  ri  re  r  r  rU  r  r7  rs  rk  rt  rW  r<  rx  r9  rp  r  rz  rh  r  r  r  r  r  r  r  r  rH  r   r  r  r  r  r  r   PluginProcessingErrorr{  r  r  rl  rV  r  rr  rf  r}  ry  r  r  r  rA   rG   r;  r:  r;  r  r$  r&  r  rU  r  rQ  r  r  rJ  r  rL  r  rS  r  rH   rI   rJ   r  r    sN   \ 6 6 ) )  	%_ !7 !7F6pL
N
O
DK*B*d
%2,(-T	zJ6	^D041g,t V$&8$L:'R:<Pd" dh.@.M.M	$;$z0 " " ,0SfS|S|4H&T(GK2S2
Yqdu	=
&$ )>(G(GQSZ[ f2:5
cF;;BBINK   	1 	1  $#$ /J 9 9rI   r  c                   8    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y)r  rg  zHandlerEnvironment.jsonr  r	  r
  r  r  r  r  rq   r	   N)rB   rC   rD   r  rB  r  r	  r
  r  r  r  r  rq   r	   rH   rI   rJ   r  r    s;    M(H-I!L!L#M1!LDGrI   r  c                   Z    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 Zd Zy)r  c                 6    ||d   t        d      || _        y )NhandlerManifestzMalformed manifest file.)r   r   r   r   s     rJ   r   zHandlerManifest.__init__  s%    <4 12: !;<<	rI   c                      | j                   d   S )Nrq   r   r   s    rJ   get_namezHandlerManifest.get_name  s    yy  rI   c                      | j                   d   S )Nr	   rc  r   s    rJ   get_versionzHandlerManifest.get_version  s    yy##rI   c                 &    | j                   d   d   S )Nr`  installCommandrc  r   s    rJ   r  z#HandlerManifest.get_install_command      yy*+,<==rI   c                 &    | j                   d   d   S )Nr`  uninstallCommandrc  r   s    rJ   r  z%HandlerManifest.get_uninstall_command  s    yy*+,>??rI   c                 &    | j                   d   d   S )Nr`  updateCommandrc  r   s    rJ   r  z"HandlerManifest.get_update_command      yy*+O<<rI   c                 &    | j                   d   d   S )Nr`  enableCommandrc  r   s    rJ   rz  z"HandlerManifest.get_enable_command  rn  rI   c                 &    | j                   d   d   S )Nr`  disableCommandrc  r   s    rJ   r  z#HandlerManifest.get_disable_command  ri  rI   c                 @    | j                   d   j                  dd      S )Nr`  reportHeartbeatFr   rv   r   s    rJ   r  z#HandlerManifest.is_report_heartbeat  s     yy*+//0A5IIrI   c                 j    | j                   d   j                  d      }|y|j                         dk(  S )Nr`  
updateModeTupdatewithinstall)r   rv   r   )r   update_modes     rJ   r  z&HandlerManifest.is_update_with_install  s:    ii 1266|D  "&999rI   c                 @    | j                   d   j                  dd      S )Nr`  continueOnUpdateFailureFru  r   s    rJ   r  z-HandlerManifest.is_continue_on_update_failure  s     yy*+//0I5QQrI   c                 @    | j                   d   j                  dd      S )Nr`  supportsMultipleExtensionsFru  r   s    rJ   rD  z,HandlerManifest.supports_multiple_extensions  s     yy*+//0LeTTrI   c                 4   t         j                  |      r_t        |      t        d      k  r$ddddigii}t        |j	                  dd            S ddddigii}t        |j	                  dd            S t        | j
                  j	                  dd            S )z
        Placeholder values for testing and monitoring the monitor extension resource usage.
        This is not effective after nov 30th.
        z1.12resourceLimitsservicesrq   zmdsd.serviceNzazuremonitoragent.service)r  rJ  r   ResourceLimitsrv   r   )r   rK  str_versiontest_mans       rJ   r^  z#HandlerManifest.get_resource_limits  s    
 77GK(<+??$" &%' &hll3CT&JKK %" &(C%' &hll3CT&JKKdiimm,<dCDDrI   N)rB   rC   rD   r   rd  rf  r  r  r  rz  r  r  r  r  rD  r^  rH   rI   rJ   r  r    sH    
!$>@==>J:RUErI   r  c                   $    e Zd Zd Zd Zd Zd Zy)r  c                     || _         y r   rc  ra  s     rJ   r   zResourceLimits.__init__  s	    	rI   c                 T    | j                   | j                   j                  dd       S y )NcpuQuotaPercentageru  r   s    rJ   ra  z,ResourceLimits.get_extension_slice_cpu_quota  s%    99 99==!5t<<rI   c                 T    | j                   | j                   j                  dd       S y )NmemoryQuotaInMBru  r   s    rJ    get_extension_slice_memory_quotaz/ResourceLimits.get_extension_slice_memory_quota  s%    99 99==!2D99rI   c                 T    | j                   | j                   j                  dd       S y )Nr  ru  r   s    rJ   rd  zResourceLimits.get_service_list  s$    99 99==T22rI   N)rB   rC   rD   r   ra  r  rd  rH   rI   rJ   r  r    s    

rI   r  c                   8     e Zd ZdZdZdZdZdZdZd fd	Z	 xZ
S )	rh   z>
    When extension failed to provide a valid status file
    r   r>         r=   c                 0    t         t        |   |||       y r   )superrh   r   )r   re   rQ  rf   	__class__s       rJ   r   zExtensionStatusError.__init__	  s    "D23tDrI   )NNr2  )rB   rC   rD   rE   r  r  ri   r  r  r   __classcell__)r  s   @rJ   rh   rh   	  s1     OOME ErI   rh   r  )xr   r   r   r  r   r  r   r  r  rI  r1  distutils.versionr   collectionsr   	functoolsr   azurelinuxagent.commonr   r   azurelinuxagent.common.utilsr   r	   .azurelinuxagent.common.agent_supported_featurer
   r   r   r   )azurelinuxagent.common.cgroupconfiguratorr   #azurelinuxagent.common.datacontractr   r   !azurelinuxagent.common.errorstater   azurelinuxagent.common.eventr   r   r   r   r    azurelinuxagent.common.exceptionr   r   r   r   r   r   r   r   r   r    azurelinuxagent.common.futurer!   r"   5azurelinuxagent.common.protocol.extensions_goal_stater#   'azurelinuxagent.common.protocol.restapir$   r%   r&   r'   r(   r)   r*   r+   r,   r-   $azurelinuxagent.common.utils.archiver.   -azurelinuxagent.common.utils.flexible_versionr/   azurelinuxagent.common.versionr0   r1   r2   r3   r4   _HANDLER_NAME_PATTERN_HANDLER_VERSION_PATTERN_HANDLER_PATTERNcompile
IGNORECASEr  r7  _VALID_HANDLER_STATUSr  HANDLER_COMPLETE_NAME_PATTERNr  r<   r  r  rS  rW  rM  rN  r  objectrA   rL   rO   rP   r  rS   rm   rr   rx   r}   r   r   r   r   r   r   r   r  r  r  r  rh   rH   rI   rJ   <module>r     s2  &     	 	      * #  ' ) 1 *d d H N 8# #C C C H Qc c c 1 G I9 9 $ - (4/2JJ !rzz"2Y">N ! K !rzz"7G  *

+;d+BBMM R   ",  " ' '      F ?6 ? !5 : :<P<X<XY SF SRR,
!LH&R$f $$f $(dI dINX9 X9v$ GEf GETV (E> ErI   