
    p
f                        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
mZmZ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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" d dl#m$Z$ d dl%m&Z&m'Z' dZ(dZ)edz   Z*e(dz   e*z   Z+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6dZ7dZ8dZ9 G d  d!e:      Z;d" Z<d# Z= G d$ d%e:      Z>y)&    N)conf)logger)	CpuCgroupAGENT_NAME_TELEMETRYMetricsCounterMemoryCgroup)
CGroupsApiSystemdCgroupsApiSystemdRunErrorEXTENSION_SLICE_PREFIX)CGroupsTelemetry)ExtensionErrorCodesCGroupsExceptionAgentMemoryExceededException)ustr)
get_osutilsystemd)
get_distro)	shellutilfileutil)handle_process_completion)	add_eventWALAEventOperationzazure.slicezh
[Unit]
Description=Slice for Azure VM Agent and Extensions
DefaultDependencies=no
Before=slices.target
z.slice/z
[Unit]
Description=Slice for Azure VM Extensions
DefaultDependencies=no
Before=slices.target
[Slice]
CPUAccounting=yes
MemoryAccounting=yes
z
[Unit]
Description=Slice for Azure VM extension {extension_name}
DefaultDependencies=no
Before=slices.target
[Slice]
CPUAccounting=yes
CPUQuota={cpu_quota}
MemoryAccounting=yes
z%azure-walinuxagent-logcollector.slicez
[Unit]
Description=Slice for Azure VM Agent Periodic Log Collector
DefaultDependencies=no
Before=slices.target
[Slice]
CPUAccounting=yes
CPUQuota={cpu_quota}
MemoryAccounting=yes
z5%i  z10-Slice.confzh
# This drop-in unit file was created by the Azure VM Agent.
# Do not edit.
[Service]
Slice=azure.slice
z11-CPUAccounting.confzh
# This drop-in unit file was created by the Azure VM Agent.
# Do not edit.
[Service]
CPUAccounting=yes
z12-CPUQuota.confzc
# This drop-in unit file was created by the Azure VM Agent.
# Do not edit.
[Service]
CPUQuota={0}
z13-MemoryAccounting.confzk
# This drop-in unit file was created by the Azure VM Agent.
# Do not edit.
[Service]
MemoryAccounting=yes
c                       e Zd ZdZdZdZy)DisableCgroupsallagent
extensionsN)__name__
__module____qualname__ALLAGENT
EXTENSIONS     K/usr/lib/python3/dist-packages/azurelinuxagent/common/cgroupconfigurator.pyr   r   o   s    
CEJr'   r   c                      | j                   | }t        j                  d|z          t        t        j
                  |       y )Nz[CGI] opmessageformatr   infor   r   CGroupsInfoformat_stringargsr,   s      r(   _log_cgroup_infor4   u   s6    "m""D)G
KK7"##//Ar'   c                      | j                   | }t        j                  d|z          t        t        j
                  |dd       y )Nz[CGW] Fr+   r,   
is_success	log_eventr-   r1   s      r(   _log_cgroup_warningr9   {   s;    "m""D)G
KK7"##//U^cdr'   c                   :    e Zd ZdZ G d de      ZdZed        Zy)CGroupConfiguratora
  
    This class implements the high-level operations on CGroups (e.g. initialization, creation, etc)

    NOTE: with the exception of start_extension_command, none of the methods in this class
    raise exceptions (cgroup operations should not block extensions)
    c                      e Zd Zd Zd Zed        Zed        Zd Zd Z	ed        Z
ed        Zed	        Zed
        Zed        Zed        Zd1dZd Zd Zd Zd Zd Zd Zd Zed        Zed        Zed        Zd Zd Zed        Zed        Zed        Zed        Z ed        Z!ed         Z"ed!        Z#d" Z$ed#        Z%d$ Z&d% Z'd& Z(e)jT                  fd'Z+d( Z,d) Z-d* Z.d+ Z/d, Z0d- Z1d. Z2d/ Z3ed0        Z4y)2CGroupConfigurator._Implc                     d| _         d| _        d| _        d| _        d | _        d | _        d | _        d | _        t        j                         | _
        y )NF)_initialized_cgroups_supported_agent_cgroups_enabled_extensions_cgroups_enabled_cgroups_api_agent_cpu_cgroup_path_agent_memory_cgroup_path_agent_memory_cgroup	threadingRLock_check_cgroups_lockselfs    r(   __init__z!CGroupConfigurator._Impl.__init__   sQ     %D&+D#*/D'/4D, $D*.D'-1D*(,D%'0'8D$r'   c                 ~   	 | j                   r		 d| _         y t        j                         s:t        j                         }	 t
        j                  j                  |      rt
        j                  j                  |      rg }t
        j                  j                  |t              }t
        j                  j                  |t              }t
        j                  j                  |t              }t
        j                  j                  |t              }|j                  ||||g       | j                  |       | j!                          t#        j$                  dt'                      t        j                         | _        | j.                  s't#        j$                  dt'                      	 d| _         y t1               | _        t        j4                         st7        dt'                      	 d| _         y t9        dt        j:                                | j=                         s		 d| _         y t        j>                         }t        j@                  |d      }	|	tB        dfvrt7        d	|	       	 d| _         y | jE                          | jG                         \  }
}| jI                  |	|
|      \  | _%        | _&        | jJ                  | jL                  | jO                          | jJ                  ft9        d
| jJ                         | jQ                  tS        jT                                tW        jX                  t[        t\        | jJ                               | jL                  Tt9        d| jL                         t_        t\        | jL                        | _0        tW        jX                  | j`                         t9        d| jb                         d| _         y # t(        $ r/}t#        j*                  dj-                  |             Y d }~d }~ww xY w# t(        $ r}t7        dte        |             Y d }~fd }~ww xY w# d| _         w xY w)NTzMAgent reset the quotas if distro: {0} goes from supported to unsupported listzDUnable to delete Agent drop-in files while resetting the quotas: {0}z)Cgroup monitoring is not supported on {0}zsystemd was not detected on {0}zsystemd version: {0}Slicezsystem.slicez,The agent is within an unexpected slice: {0}zAgent CPU cgroup: {0}zAgent Memory cgroup: {0}zAgent cgroups enabled: {0}zError initializing cgroups: {0})3r?   r	   cgroups_supportedr   get_agent_drop_in_pathospathexistsisdirjoin_AGENT_DROP_IN_FILE_SLICE_DROP_IN_FILE_CPU_ACCOUNTING_DROP_IN_FILE_MEMORY_ACCOUNTING_DROP_IN_FILE_CPU_QUOTAextend_Impl__cleanup_all_files_Impl__reload_systemd_configr   r/   r   	Exceptionwarnr.   r@   r
   rC   
is_systemdr9   r4   get_version_Impl__check_no_legacy_cgroupsget_agent_unit_nameget_unit_propertyAZURE_SLICE_Impl__setup_azure_slice_Impl__get_cgroup_controllers_Impl__get_agent_cgroupsrD   rE   enable_Impl__set_cpu_quotar   get_agent_cpu_quotar   track_cgroupr   r   r   rF   rA   r   )rK   agent_drop_in_pathfiles_to_cleanupagent_drop_in_file_slice!agent_drop_in_file_cpu_accounting$agent_drop_in_file_memory_accountingagent_drop_in_file_cpu_quotaerragent_unit_nameagent_slicecpu_controller_rootmemory_controller_root	exceptions                r(   
initializez#CGroupConfigurator._Impl.initialize   s   K)$$R %)!O "335)0)G)G)I&x77>>*<="''--PbBc/1,79ww||DVXq7r4@BM_MiAk=CE77<<PbPoDq@;=77<<HZ\s;t8,335MOp5Y[w5y z 445EF 88:"KK(w  zD  zF  G
 +5*F*F*H'..KK KZ\Z` %)![ %6$7!))+'(I:<XT %)!Q !!79L9L9NO 557B %)!? #*"="="?%77Q{N&CC'(VXcd6 %)!3 ((*>B>[>[>];#%;NRNfNfgrgzg}OK+T-K ..:d>\>\>hKKM..:$%<d>Y>YZ(()A)A)CD$11)<PRVRmRm2no11=$%?A_A_`0<=QSWSqSq0rD-$11$2K2KL !=t?Z?Z[
 %)!o % x$j$q$qru$vwwxh  X#$EtIWWX %)!st   P )P D%O &AP 27P 2.P )A P 2EP 	P$P :P  PP 	P0P+&P3 +P00P3 3	P<c            	         g } 	 t        j                  g d      }|j                  d      D ]L  }t        j                  d|t        j
                        }|+| j                  |j                  d      |f       N 	 | D ]+  \  }}d}	 t        j                  |d      }t        d	||       - t        |       d
k(  r	 t        j                  d      }	|	j                  d      D ]p  }t        j                  d|t        j                         s)t#        j$                  t        d      j'                  |	             t)        t*        j,                  d       r y y # t         j                  $ r }t        dt        |             Y d }~d }~ww xY w# t        $ r!}t        d|t        |             Y d }~d }~ww xY w# t         j                  $ r}t        dt        |             Y d }~y d }~ww xY w)N)	systemctlz
list-unitszazure*z-all
z\s?(azure[^\s]*)\s?   z!Failed to list systemd units: {0}UnknownrN   z"Failed to query Slice for {0}: {1}z(Found an Azure unit under slice {0}: {1}r   zsystemd-cglsz[^\x00-\xff]+azure\.slice\s*z"Found a cgroup for azure.slice
{0}zFound a cgroup for azure.slicer*   )r   run_commandsplitrematch
IGNORECASEappendgroupCommandErrorr9   r   r   rc   r]   r4   lenUNICODEr   r/   r.   r   r   r0   )
azure_unitsunitsliner   command_error	unit_nameunit_description
unit_slicerw   cgroupss
             r(   __collect_azure_unit_telemetryz7CGroupConfigurator._Impl.__collect_azure_unit_telemetry   s   K^!--.[\!KK- CDHH%;T2==QE(#**EKKND+ABC 0; k+	+&
j!(!:!:9g!NJ !!KZYijk ;1$b'33NCG 'd 3 s88$CT2::V"KK-R(S(Z(Z[b(cd%);)G)GQqr	s % )) ^#$GmI\]]^ ! j'(LiY]^gYhiij !-- b'(KTR_M`aabsV   AE $E F;AF9 
A
F9 F	)FF		F6F11F69G+G&&G+c            	         g } t               j                         }	 t        j                  |d      }|t        j                         k7  r| j                  |       	 t        j                  |d      }|j                         D ]  }| j                  |        	 | D ]3  }	 t        |d      5 }t        d||j                                d d d        5 y # t        $ r}t        dt        |             Y d }~d }~ww xY w# t        $ r}t        dt        |             Y d }~d }~ww xY w# 1 sw Y   bxY w# t        $ r }t        d|t        |             Y d }~d }~ww xY w)NFragmentPathz-Failed to query the agent's FragmentPath: {0}DropInPathsz,Failed to query the agent's DropInPaths: {0}rz/Found a custom unit file for the agent: {0}
{1}zCan't read {0}: {1})r   get_service_namer   rc   get_agent_unit_filer   r]   r9   r   r   openr4   read)agent_unit_filesagent_service_namefragment_pathrw   drop_in_pathsrR   	unit_filefile_objects           r(   $__collect_agent_unit_files_telemetryz=CGroupConfigurator._Impl.__collect_agent_unit_files_telemetry  s]   !!+!>!>!@f ' 9 9:Ln ] G$?$?$AA$++M:e ' 9 9:Lm \)//1 2D$++D12
 . [	[i- =()[]f)4)9)9);==[  f#$SUYZcUdeef  e#$RTXYbTcdde
= = ! ['(=y$y/ZZ[s_   >C <C< D3*D'D3	C9C44C9<	D$DD$'D0	,D33	E<EEc                 Z    | j                   j                         }|dkD  rt        d       yy)a  
            Older versions of the daemon (2.2.31-2.2.40) wrote their PID to /sys/fs/cgroup/{cpu,memory}/WALinuxAgent/WALinuxAgent. When running
            under systemd this could produce invalid resource usage data. Cgroups should not be enabled under this condition.
            r   zOThe daemon's PID was added to a legacy cgroup; will not monitor resource usage.FT)rC   cleanup_legacy_cgroupsr9   )rK   legacy_cgroupss     r(   __check_no_legacy_cgroupsz2CGroupConfigurator._Impl.__check_no_legacy_cgroups  s/    
 "..EEGN!#$uvr'   c                    | j                   j                         \  }}d}|t        j                  d|       nt	        d       d}|t        j                  d|       nt	        d       d}|r^| j                   j                         \  }}|?t        d||       d}d|vsd	|v rt	        d
       d}d|vsd|v rt	        d       d}|s||fS ||fS )NFz+The CPU cgroup controller is mounted at {0}z(The CPU cgroup controller is not mountedTz.The memory cgroup controller is mounted at {0}z+The memory cgroup controller is not mountedz.cgroups v2 mounted at {0}.  Controllers: [{1}]memoryz-memoryz)Memory controller not active in cgroup v2cpuz-cpuz&CPU controller not active in cgroup v2)rC   get_cgroup_mount_pointsr   r/   r9   get_cgroup2_controllersr4   )rK   ru   rv   controller_missingcgroup2_mount_pointcgroup2_controllerss         r(   __get_cgroup_controllersz1CGroupConfigurator._Impl.__get_cgroup_controllers)  s    ;?:K:K:c:c:e7!7!&".IK^_#$NO%)"%1LNde#$QR%)"
 ";?;L;L;d;d;f8#%8&2$%UWj%8:).&'::iK^>^+,WX-1*$776EX;X+,TU-1*-24GGG&(>>>r'   c                  |   t         j                  j                  d       t        j                         } t
        j                  j                  | t              }t
        j                  j                  | t              }t
        j                  j                  | t              }t        j                         }t        j                         }t
        j                  j                  |t              }t
        j                  j                  |t              }t
        j                  j                  |t              }g }	t
        j                  j!                  |      s|	j#                  |t$        f       t
        j                  j!                  |      s|	j#                  |t&        f       t(        j+                  t,              }
|	j#                  ||
f       t/        j0                  |d       t         j                  j                  |       n6t
        j                  j!                  |      s|	j#                  |t2        f       t/        j0                  |d       t         j                  j                  |       n6t
        j                  j!                  |      s|	j#                  |t4        f       t/        j0                  |d       t         j                  j                  |       n6t
        j                  j!                  |      s|	j#                  |t6        f       t9        |	      dkD  rK	 |	D ]%  \  }}t         j                  j;                  ||       ' 	 t         j                  jC                          yy# t<        $ rE}t?        dtA        |             |	D ]!  }t         j                  j                  |       # Y d}~yd}~ww xY w)	u  
            The agent creates "azure.slice" for use by extensions and the agent. The agent runs under "azure.slice" directly and each
            extension runs under its own slice ("Microsoft.CPlat.Extension.slice" in the example below). All the slices for
            extensions are grouped under "vmextensions.slice".

            Example:  -.slice
                      ├─user.slice
                      ├─system.slice
                      └─azure.slice
                        ├─walinuxagent.service
                        │ ├─5759 /usr/bin/python3 -u /usr/sbin/waagent -daemon
                        │ └─5764 python3 -u bin/WALinuxAgent-2.2.53-py2.7.egg -run-exthandlers
                        └─azure-vmextensions.slice
                          └─Microsoft.CPlat.Extension.slice
                              └─5894 /usr/bin/python3 /var/lib/waagent/Microsoft.CPlat.Extension-1.0.0.0/enable.py

            This method ensures that the "azure" and "vmextensions" slices are created. Setup should create those slices
            under /lib/systemd/system; but if they do not exist, __ensure_azure_slices_exist will create them.

            It also creates drop-in files to set the agent's Slice and CPUAccounting if they have not been
            set up in the agent's unit file.

            Lastly, the method also cleans up unit files left over from previous versions of the agent.
            z8/etc/systemd/system/system-walinuxagent.extensions.slice	cpu_quotazSlice=NzCPUAccounting=zMemoryAccounting=r   z4Failed to create unit files for the azure slice: {0})"r;   _Impl_Impl__cleanup_unit_filer   get_unit_file_install_pathrQ   rR   rU   rd   _VMEXTENSIONS_SLICELOGCOLLECTOR_SLICEr   rP   rV   rW   rX   rS   r   _AZURE_SLICE_CONTENTS_VMEXTENSIONS_SLICE_CONTENTS _LOGCOLLECTOR_SLICE_CONTENTS_FMTr.   _LOGCOLLECTOR_CPU_QUOTAr   findre_in_file"_AGENT_DROP_IN_FILE_SLICE_CONTENTS%_DROP_IN_FILE_CPU_ACCOUNTING_CONTENTS(_DROP_IN_FILE_MEMORY_ACCOUNTING_CONTENTSr   _Impl__create_unit_filer]   r9   r   r\   )unit_file_install_pathazure_slicevmextensions_slicelogcollector_sliceagent_unit_filerl   rn   ro   rp   files_to_createslice_contentsrR   contentsrw   r   s                  r(   __setup_azure_slicez,CGroupConfigurator._Impl.__setup_azure_sliceP  s   8 $$889st%,%G%G%I"'',,'={KK!#.DFY!Z!#.DFX!Y%99;O!(!?!?!A')ww||4FHa'b$02=OQm0n-3577<<@RTs3t0 O77>>+.&&5J'KL77>>"45&&(:<X'YZ >DDOfDgN""$6#GH&&	BN"((<<=UVww~~&>?#**,DFh+ij&&8IJV"((<<=^_ww~~&GH#**,MOt+uv&&8LMY"((<<=abww~~&JK#**=?ghj ?#a'*9 Th*00CCD(ST #((@@B (
 ! '(^`den`op%4 P	*00DDYOP	s   "*M- -	N;6;N66N;c                      	 t        j                  d       t        j                  ddg       y # t        $ r} t        dt        |              Y d } ~ y d } ~ ww xY w)N$Executing systemctl daemon-reload...rz   daemon-reloadz.daemon-reload failed (create azure slice): {0})r   r/   r   r~   r]   r9   r   )rw   s    r(   __reload_systemd_configz0CGroupConfigurator._Impl.__reload_systemd_config  sO    gBC%%{O&DE g#$TVZ[dVeffgs   ,/ 	AAAc                 L   t         j                  j                  |       \  }}t         j                  j                  |      st	        j
                  |d       t         j                  j                  |       }t	        j                  | |       t        d|rd|        y d|        y )Ni  )modez{0} {1}UpdatedCreated)rQ   rR   r   rS   r   mkdir
write_filer4   )rR   r   parent_rS   s        r(   __create_unit_filez+CGroupConfigurator._Impl.__create_unit_file  sm    d+IFA77>>&)vE2WW^^D)Fh/YV	DQDQr'   c                     t         j                  j                  |       r#	 t        j                  |        t	        d|        y y # t
        $ r }t        d| t        |             Y d }~y d }~ww xY wNzRemoved {0}zFailed to remove {0}: {1}rQ   rR   rS   remover4   r]   r9   r   )rR   rw   s     r(   __cleanup_unit_filez,CGroupConfigurator._Impl.__cleanup_unit_file  s[    ww~~d#\IIdO$]D9 $ ! \'(CT4PY?[[\s   !A 	A-A((A-c           	          | D ]D  }t         j                  j                  |      s#	 t        j                  |       t	        d|       F y # t
        $ r }t        d|t        |             Y d }~ld }~ww xY wr   r   )rm   rR   rw   s      r(   __cleanup_all_filesz,CGroupConfigurator._Impl.__cleanup_all_files  sg    ( `77>>$'`		$(=	`
 % `+,GtT]__`s   !A	A4A//A4c                     	 | D ]%  \  }}t         j                  j                  ||       ' y # t        $ rE}t	        dt        |             | D ]!  }t         j                  j                  |       # Y d }~y d }~ww xY w)Nz!Failed to create unit files : {0})r;   r   r   r]   r9   r   r   )r   rR   r   rw   r   s        r(   __create_all_filesz+CGroupConfigurator._Impl.__create_all_files  sy    &5 PND(&,,??hOP #$GiY!0 LI&,,@@KL	s   *- 	A;;A66A;Nc                    t        j                         }t        j                  j	                  |t        j                  |d            }t        j                  j                  |      rt        j                  j                  |       t        j                  j	                  |t        j                  |            }|t        |      dz   nd}t        j                  ||      }t        j                  j                  |      r4t        |d      5 }|j                         |k(  r
	 d d d        y	 d d d        yy# 1 sw Y   yxY w)NT)	old_slice% extension_namer   r   F)r   r   rQ   rR   rU   r
   get_extension_slice_namerS   r;   r   r   str_EXTENSION_SLICE_CONTENTSr.   r   r   )rK   r   r   r   old_extension_slice_pathextension_slice_pathr   file_s           r(   ,is_extension_resource_limits_setup_completedzECGroupConfigurator._Impl.is_extension_resource_limits_setup_completed  s(   %,%G%G%I"')ww||4JL]LvLv  xF  RV  MW  (X$ww~~67"((<<=UV#%77<<0F0A0Z0Z[i0j$l  %.$9  !?A 6==^HQ > SNww~~23.4 $zz|~5#$ $5$ $ s   D88Ec                    t        j                         }t        j                  j	                  ||      }| j
                  j                  d      \  }}|t        d       nU||k(  rAt        dt        j                  |d             t        dt        j                  |d             nt        d||       d }|t        d       n7||k(  r#t        j                  |d	      }t        d
|       nt        d||       d }|#|!t        j                  j	                  ||      }	nd }	|&|$t        j                  j	                  ||      }
|	|
fS d }
|	|
fS )NrK   z.The agent's process is not within a CPU cgroupzCPUAccounting: {0}CPUAccountingCPUQuota: {0}CPUQuotaPerSecUSeczdThe Agent is not in the expected CPU cgroup; will not enable monitoring. Cgroup:[{0}] Expected:[{1}]z1The agent's process is not within a memory cgroupMemoryAccountingzMemoryAccounting: {0}zgThe Agent is not in the expected memory cgroup; will not enable monitoring. CGroup:[{0}] Expected:[{1}])
r   rb   rQ   rR   rU   rC   !get_process_cgroup_relative_pathsr9   r4   rc   )rK   rt   ru   rv   rs   expected_relative_pathcpu_cgroup_relative_pathmemory_cgroup_relative_pathmemory_accountingagent_cpu_cgroup_pathagent_memory_cgroup_paths              r(   __get_agent_cgroupsz,CGroupConfigurator._Impl.__get_agent_cgroups  sn   %99;O%'WW\\+%O"DHDUDUDwDwEA$&A (/#$TU+/EE$%97;T;TUdfu;vw$_g6O6OP_au6vw'~0.0 04,*2#$WX.2HH(/(A(A/Se(f%$%<>OP$ B3.0 37/".3K3W(*5HJb(c%(,%%16Q6]+-77<<8NPk+l( )*BBB ,0((*BBBr'   c                     | j                   S N)r@   rJ   s    r(   	supportedz"CGroupConfigurator._Impl.supported  s    ***r'   c                 6    | j                   xs | j                  S r   )rA   rB   rJ   s    r(   enabledz CGroupConfigurator._Impl.enabled  s    ..R$2R2RRr'   c                     | j                   S r   )rA   rJ   s    r(   agent_enabledz&CGroupConfigurator._Impl.agent_enabled  s    ...r'   c                     | j                   S r   )rB   rJ   s    r(   extensions_enabledz+CGroupConfigurator._Impl.extensions_enabled  s    333r'   c                 V    | j                         st        d      d| _        d| _        y )NzOAttempted to enable cgroups, but they are not supported on the current platformT)r   r   rA   rB   rJ   s    r(   rh   zCGroupConfigurator._Impl.enable!  s.    >>#&eg g*.D'/3D,r'   c                    |t         j                  k(  r| j                          | j                         }|D ]P  }t	        j
                  dj                  |||                | j                  |       | j                  ||          R | j                          t        j                          d| _        d| _        nW|t         j                  k(  rDd| _        | j                          t        j                  t!        t"        | j$                               dj                  |      }t	        j
                  |       t'        t(        j*                  |dd       y )Nz9Resetting extension : {0} and it's services: {1} CPUQuota)r   Fz6[CGW] Disabling resource usage monitoring. Reason: {0}r6   )r   r#   _Impl__reset_agent_cpu_quotaget_extension_services_listr   r/   r.    _Impl__reset_extension_cpu_quota)_Impl__reset_extension_services_cpu_quotar\   r   resetrA   rB   r$   stop_trackingr   r   rD   r   r   CGroupsDisabled)rK   reasondisable_cgroupsextension_services	extensionr,   s         r(   disablez CGroupConfigurator._Impl.disable(  s2   ."4"44,,.%)%E%E%G"!3 ]IKK [ b bcl  oA  BK  oL  !M  N44I4N==>PQZ>[\] ,,. &&(.3+380 N$8$88.3+,,. ..y9MtOjOj/klNUUV\]GKK +;;WY^jopr'   c                     dj                  |       }t        d|       t        j                  j	                  |      rt        j                  d       yy)a  
            Sets the agent's CPU quota to the given percentage (100% == 1 CPU)

            NOTE: This is done using a dropin file in the default dropin directory; any local overrides on the VM will take precedence
            over this setting.
            z{0}%z$Ensuring the agent's CPUQuota is {0}TN)r.   r4   r;   r   _Impl__try_set_cpu_quotar   set_track_throttled_time)quotaquota_percentages     r(   __set_cpu_quotaz(CGroupConfigurator._Impl.__set_cpu_quota?  sH      &}}U3CEUV!'';;<LM 99$? Nr'   c                      t        j                  d       t        j                  j	                  d      r3t        dt        j                  t        j                         d             yy)z
            Removes any CPUQuota on the agent

            NOTE: This resets the quota on the agent's default dropin file; any local overrides on the VM will take precedence
            over this setting.
            zResetting agent's CPUQuotar   r   r   N)	r   r/   r;   r   r  r4   r   rc   rb   r&   r'   r(   __reset_agent_cpu_quotaz0CGroupConfigurator._Impl.__reset_agent_cpu_quotaL  sP     KK45!'';;B? !(!:!:7;V;V;XZn!oq @r'   c                    	 t         j                  j                  t        j                         t
              }t        j                  |       }t         j                  j                  |      r3t        |d      5 }|j                         |k(  r
	 d d d        y	 d d d        t        j                  j                  ||       	 t#        j$                  d       t'        j(                  ddg       y# 1 sw Y   WxY w# t        $ r}t        dt!        |             Y d }~yd }~ww xY w# t        $ r}t        dt!        |             Y d }~yd }~ww xY w)	Nr   TzFailed to set CPUQuota: {0}Fr   rz   r   z%daemon-reload failed (set quota): {0})rQ   rR   rU   r   rP   rY   '_DROP_IN_FILE_CPU_QUOTA_CONTENTS_FORMATr.   rS   r   r   r;   r   r   r]   r9   r   r   r/   r   r~   )r  drop_in_filer   r   rw   s        r(   __try_set_cpu_quotaz,CGroupConfigurator._Impl.__try_set_cpu_quotaY  s   
!ww||G,J,J,LNefBII%P77>>,/lC0 (E ::<83#'( (3( #((;;L(SBC%%{O&DE ( (  #$A4	?S  #$KTR[_]sN   A6C9 8C-C9 (C9  ,D$ -C62C9 9	D!DD!$	E-EEc           
      P   | j                   j                          	 | j                         s	 | j                   j                          y g }d}	 | j	                          d}d}	 |r| j                  |       d}dj                  dj                  |D cg c]  }t        |       c}            }|s4t        j                         r | j                  |t        j                         |s4t        j                          r | j                  |t        j"                         | j                   j                          y # t
        $ r}|j                  |       Y d }~d }~ww xY w# t
        $ r}|j                  |       Y d }~d }~ww xY wc c}w # | j                   j                          w xY w)NFTzCheck on cgroups failed:
{0}r{   )rI   acquirer   release _check_processes_in_agent_cgroupr   r   _check_agent_throttled_timer.   rU   r   r   +get_cgroup_disable_on_process_check_failurer  r   r#   )get_cgroup_disable_on_quota_check_failurer$   )rK   cgroup_metricserrorsprocess_check_successrw   quota_check_successer	  s           r(   check_cgroupsz&CGroupConfigurator._Impl.check_cgroupsn  sa   $$,,.3||~6 ((0023 (-%-99;,0) ',#-%88H*.' 9??		\bJcWX4PQ7Jc@de,1a1a1cLL););<*t/]/]/_LL)=)=>((002' ( -MM),,- ( -MM),,- Kd ((002sr   F	 F	 D5 F	 "E 7F	 F#A7F	 5	E>EF	 EF	 	F%E<6F	 <FF	 	F%c                    g }g }	 t        j                         }t        j                         }t               }|j	                  t        j                                t               }|j	                  | j                  j                                t        j                  | j                        }|j	                  t        j                                |j	                  | j                  j                                |D ]  }|j                  | j                  |             |||fv s||v r.| j                  |      r@| j                  |      |v r| j!                  |      dk(  rh|}	|	dk7  r|	|vr| j                  |	      }	|	dk7  r|	|vr|	dk(  s| j#                  |      r| j%                  |      r|j                  | j                  |             t'        |      dk\  s n t'        |      dkD  r,| j1                  ||       t3        dj-                  |            y# t(        $ r-}
t+        dj-                  t/        |
                   Y d}
~
ld}
~
ww xY w)a  
            Verifies that the agent's cgroup includes only the current process, its parent, commands started using shellutil and instances of systemd-run
            (those processes correspond, respectively, to the extension handler, the daemon, commands started by the extension handler, and the systemd-run
            commands used to start extensions on their own cgroup).
            Other processes started by the agent (e.g. extensions) and processes not started by the agent (e.g. services installed by extensions) are reported
            as unexpected, since they should belong to their own cgroup.

            Raises a CGroupsException if the check fails
            zsystemd-runr      z7Error checking the processes in the agent's cgroup: {0}Nz5The agent's cgroup includes unexpected processes: {0})rQ   getppidgetpidsetupdater   get_running_commandsrC   get_systemd_run_commandsr	   get_processes_in_cgrouprD   r   _Impl__format_process_check_systemd_run_process_get_parent_get_command)_Impl__is_process_descendant_of_the_agent_Impl__is_zombie_processr   r]   r9   r.   r   _report_agent_cgroups_procsr   )rK   
unexpectedagent_cgroup_proc_namesdaemonextension_handleragent_commandssystemd_run_commandsagent_cgroupprocesscurrentrw   s              r(   r  z9CGroupConfigurator._Impl._check_processes_in_agent_cgroup  s3    J&(##w$&IIK!!$%%i&D&D&FG'*u$$++D,=,=,V,V,XY)AA$B]B]^%%i&D&D&FG$++D,=,=,V,V,XY+ "G+2243H3H3QR6+<"==L`A` 66w? ''04HHTM^M^#N%(5N6 %G!Q,7.+H"&"2"27"; "Q,7.+H !|T-V-VW^-_cgc{c{  }D  dE"))$*?*?*HIz?a/!+"2 :"001H*U&'^'e'efp'qrr #  w#$]$d$deijset$uvvws6   FH  	H  H  !H  3.H  "H   	I)#IIc                     	 t        dj                  |       d      5 }|j                         }|r|d   dk(  r|d d }|j                         cd d d        S # 1 sw Y   y xY w# t        $ r Y yw xY w)Nz/proc/{0}/commr    UNKNOWN)r   r.   r   rstripr]   )pidr   comms      r(   r3  z%CGroupConfigurator._Impl._get_command  st    !*11#6< ) ::<DRF 2#CRy;;=	) ) )
  ! !s.   A" /A	A" AA" A" "	A.-A.c                 (   	 dj                  |       }t        j                  j                  |      r6t	        |d      5 }dj                  | |j                               cddd       S dj                  |       S # 1 sw Y   xY w# t        $ r Y (w xY w)z
            Formats the given PID as a string containing the PID and the corresponding command line truncated to 64 chars
            /proc/{0}/cmdliner   z[PID: {0}] {1:64.64}Nz[PID: {0}] UNKNOWN)r.   rQ   rR   rS   r   r   r]   )rE  cmdlinecmdline_files      r(   __format_processz)CGroupConfigurator._Impl.__format_process  s    
-44S977>>'*gs+ W|5<<S,BSBSBUVW W (..s33	W W s(   <B  A9	B 9B>B 	BBc                 h   	 dj                  |       }t        j                  j                  |      ret	        |d      5 }|j                         }|r|d   dk(  r|dd }dj                  t        j                  t        j                        |v cddd       S 	 y# 1 sw Y   yxY w# t        $ r Y yw xY w)z
            Returns True if the process is descendant of the agent by looking at the env flag(AZURE_GUEST_AGENT_PARENT_PROCESS_NAME)
            that we set when the process starts otherwise False.
            z/proc/{0}/environr   rA  rB  Nz{0}={1}F)
r.   rQ   rR   rS   r   r   r   PARENT_PROCESS_NAMEAZURE_GUEST_AGENTr]   )rE  envenv_fileenvirons       r(   $__is_process_descendant_of_the_agentz=CGroupConfigurator._Impl.__is_process_descendant_of_the_agent  s    	)00577>>#&c3 w8"*--/"wr{f'<&-crlG(//	0M0MyOjOjkovv	w w ' w   s/   <B% AB	B% B"B% "B% %	B10B1c                    	 dj                  |       }t        j                  j                  |      r:t	        |d      5 }|j                         j                         d   dk(  cddd       S 	 y# 1 sw Y   yxY w# t        $ r Y yw xY w)z
            Returns True if process is in Zombie state otherwise False.

            Ex: cat /proc/18171/stat
            18171 (python3) S 18103 18103 18103 0 -1 4194624 57736 64902 0 3
            /proc/{0}/statr      ZNF)r.   rQ   rR   rS   r   r   r   r]   rE  stat	stat_files      r(   __is_zombie_processz,CGroupConfigurator._Impl.__is_zombie_process  s    '..s377>>$'dC BI(~~/557:cAB B (
 	B   s.   <A: $A."	A: .A73A: 7A: :	BBc                 <   	 d}dj                  |       }t        j                  j                  |      r4t	        |d      5 }dj                  |j                               }ddd       t        j                  d|      }|y	 y# 1 sw Y   $xY w# t        $ r Y yw xY w)	at  
            Returns True if process is shell systemd-run process started by agent otherwise False.

            Ex: sh,7345 -c systemd-run --unit=enable_7c5cab19-eb79-4661-95d9-9e5091bd5ae0 --scope --slice=azure-vmextensions-Microsoft.OSTCExtensions.VMAccessForLinux_1.5.11.slice /var/lib/waagent/Microsoft.OSTCExtensions.VMAccessForLinux-1.5.11/processes.sh
            rC  rH  r   z{0}Nz;systemd-run.*--unit=.*--scope.*--slice=azure-vmextensions.*TF)	r.   rQ   rR   rS   r   r   r   searchr]   )r>  process_namerI  rJ  r   s        r(   r1  z3CGroupConfigurator._Impl._check_systemd_run_process   s    
(-44W=77>>'*gs+ I|',||L4E4E4G'HI		"`bno$ % I I
  s)   >B   B  B BB 	BBc                     |D ]Y  }d|v sdj                  dj                  | D cg c]  }t        |       c}            }t        t        j
                  |       [ y c c}w )NrC  zBAgent includes following processes when UNKNOWN process found: {0}r{   r*   )r.   rU   r   r   r   r0   )r8  r7  	proc_nameprocmsgs        r(   r6  z4CGroupConfigurator._Impl._report_agent_cgroups_procs  sz    ' N		)^eefjfofo  I`  qa  AEquvzq{  qa  gb  cC!3!?!?MN qas   A c                     | D ]y  }|j                   t        k(  s|j                  t        j                  k(  s5|j
                  t        j                         kD  sWt        dj                  |j
                               y )Nz,The agent has been throttled for {0} seconds)
instancer   counterr   THROTTLED_TIMEvaluer   &get_agent_cpu_throttled_time_thresholdr   r.   )r!  metrics     r(   r  z4CGroupConfigurator._Impl._check_agent_throttled_time  se    ( t??&::v~~Q_QnQn?n||d&Q&Q&SS./]/d/dekeqeq/rsstr'   c                    | j                         r| j                  r| j                  j                         }d}|D ]\  }|j                  t        j
                  k(  r||j                  z  }0|j                  t        j                  k(  sN||j                  z  }^ |t        j                         kD  r-t        dj                  t        j                         |            y y y )Nr   zSThe agent memory limit {0} bytes exceeded. The current reported usage is {1} bytes.)r   rF   get_tracked_metricsrd  r   TOTAL_MEM_USAGErf  SWAP_MEM_USAGEr   get_agent_memory_quotar   r.   )rK   metricscurrent_usagerh  s       r(   check_agent_memory_usagez1CGroupConfigurator._Impl.check_agent_memory_usage"  s    ||~$";";33GGI !% 6F~~)G)GG%5>+H+HH%5	6 !4#>#>#@@6  8M  8T  8T  UY  Up  Up  Ur  tA  8B  C  C A #<~r'   c                    	 dj                  |       }t        j                  j                  |      r@t	        |d      5 }t        |j                         j                         d         cddd       S 	 y# 1 sw Y   yxY w# t        $ r Y yw xY w)z
            Returns the parent of the given process. If the parent cannot be determined returns 0 (which is the PID for the scheduler)
            rT  r      Nr   )	r.   rQ   rR   rS   r   intr   r   r]   rW  s      r(   r2  z$CGroupConfigurator._Impl._get_parent/  s    
'..s377>>$'dC @I"9>>#3#9#9#;A#>?@ @ (
 	@   s.   <B  *A4(	B  4A=9B  =B   	BBc                    	 | j                   j                  |      \  }}|t        j                  d       nt	        j
                  t        ||             |t        j                  d       yt	        j
                  t        ||             y# t        $ r)}t        j                  dt        |             Y d}~yd}~ww xY w)z=
            TODO: Start tracking Memory Cgroups
            Nz@The CPU controller is not mounted; will not track resource usagezCThe Memory controller is not mounted; will not track resource usagez>Failed to start tracking resource usage for the extension: {0})
rC   get_unit_cgroup_pathsr   r/   r   rk   r   r   r]   r   rK   r   cpu_cgroup_pathmemory_cgroup_pathrw   s        r(   start_tracking_unit_cgroupsz4CGroupConfigurator._Impl.start_tracking_unit_cgroups=  s    o6:6G6G6]6]^g6h3!3"*KK bc$11)I2WX%-KK ef$11,yJ\2]^ o\^bcl^mnnos   A,B /B 	CB<<Cc                 2   	 | j                   j                  |      \  }}|t        j                  t	        ||             | t        j                  t        ||             yy# t        $ r)}t        j                  dt        |             Y d}~yd}~ww xY w)zH
            TODO: remove Memory cgroups from tracked list.
            NEFailed to stop tracking resource usage for the extension service: {0})
rC   ru  r   r  r   r   r]   r   r/   r   rv  s        r(   stop_tracking_unit_cgroupsz3CGroupConfigurator._Impl.stop_tracking_unit_cgroupsQ  s    
v6:6G6G6]6]^g6h3!3".$229Y3XY%1$22<	K]3^_ 2  vceijsetuuvs   A A$ $	B-BBc                 "   	 t        j                  |      }t        j                  j	                  t
        |      }| j                  j                         \  }}t        j                  j	                  ||      }t        j                  j	                  ||      }|t        j                  t        ||             | t        j                  t        ||             yy# t        $ r)}t        j                  dt        |             Y d}~yd}~ww xY w)zQ
            TODO: remove extension Memory cgroups from tracked list
            Nr{  )r
   r   rQ   rR   rU   _AZURE_VMEXTENSIONS_SLICErC   r   r   r  r   r   r]   r   r/   r   )	rK   r   extension_slice_namecgroup_relative_pathcpu_cgroup_mountpointmemory_cgroup_mountpointrw  rx  rw   s	            r(   stop_tracking_extension_cgroupsz8CGroupConfigurator._Impl.stop_tracking_extension_cgroupsa  s    v'8'Q'QR`'a$')ww||4M4H(J$ CGBSBSBkBkBm?%'?"$'',,/DFZ"[%'WW\\2JL`%a"".$229^_3]^%1$22<Pb3cd 2  vceijsetuuvs   CC 	D%D		Dc                    | j                         r&	 | j                  j                  |||||||||	|

      S t        j                  ||||||	t        j                        }t        |||||	|
      S # t        $ rE}dj	                  |t        |            }| j                  |t        j                         Y d}~d}~ww xY w)a$  
            Starts a command (install/enable/etc) for an extension and adds the command's PID to the extension's cgroup
            :param extension_name: The extension executing the command
            :param command: The command to invoke
            :param cmd_name: The type of the command(enable, install, etc.)
            :param timeout: Number of seconds to wait for command completion
            :param cwd: The working directory for the command
            :param env:  The environment to pass to the command's process
            :param stdout: File object to redirect stdout to
            :param stderr: File object to redirect stderr to
            :param stderr: File object to redirect stderr to
            :param error_code: Extension error code to raise in case of error
            )shellcwdrO  stdoutstderr
error_codez[Failed to start {0} using systemd-run, will try invoking the extension directly. Error: {1}N)r  r  rO  r  r  
preexec_fn)r>  commandtimeoutr  r  r  )r   rC   start_extension_commandr   r.   r   r  r   r#   
subprocessPopenrQ   setsidr   )rK   r   r  cmd_namer  r  r  rO  r  r  r  rw   r	  r>  s                 r(   r  z0CGroupConfigurator._Impl.start_extension_commandw  s     ||~=,,DD^U\^fhoKPVY_bkqLR_i E k k !&&we#V\ekxz  yB  yB  CG,WgW^gmv|  JT  U  U ' =z  B  B&Y9FLL););<<=s   $A2 2	C ;;B;;C c                 L    | j                         r| j                  |d       yy)z
            Removes any CPUQuota on the extension

            NOTE: This resets the quota on the extension's slice; any local overrides on the VM will take precedence
            over this setting.
            Nr   )r   setup_extension_slice)rK   r   s     r(   __reset_extension_cpu_quotaz4CGroupConfigurator._Impl.__reset_extension_cpu_quota  s%     ||~**>T*J r'   c                    | j                         rt        j                         }t        j                  j                  |t        j                  |            }	 |t        |      dz   nd}|dk(  rt        d|       nt        d||       t        j                  ||      }t        j                  j                  ||       yy# t        $ r?}t!        d|t#        |             t        j                  j%                  |       Y d}~yd}~ww xY w)ax  
            Each extension runs under its own slice (Ex "Microsoft.CPlat.Extension.slice"). All the slices for
            extensions are grouped under "azure-vmextensions.slice.

            This method ensures that the extension slice is created. Setup should create
            under /lib/systemd/system if it is not exist.
            TODO: set memory quotas
            Nr   r   zCPUQuota not set for {0}"Ensuring the {0}'s CPUQuota is {1}r   z5Failed to set the extension {0} slice and quotas: {1})r   r   r   rQ   rR   rU   r
   r   r   r4   r   r.   r;   r   r   r]   r9   r   r   )rK   r   r   r   r   r   rw   s          r(   r  z.CGroupConfigurator._Impl.setup_extension_slice  s     ||~)0)K)K)M&')ww||4J4E4^4^_m4n(p$W8A8MI 4SUI B()C^T()M~_hi%>%E%EUcPY &F &[N&,,??@TVde  ! W'(_ao(,Y9&,,@@AUVVWs   A(C 	D5DDc                 X   | j                         rt        j                         }t        j                  |      }t
        j                  j                  ||      }t
        j                  j                  |      r1| j                  |       t        j                  j                  |       yyy)z
            This method ensures that the extension slice gets removed from /lib/systemd/system if it exist
            Lastly stop the unit. This would ensure the cleanup the /sys/fs/cgroup controller paths
            N)r   r   r   r
   r   rQ   rR   rU   rS   r  r;   r   r   )rK   r   r   r  r   s        r(   remove_extension_slicez/CGroupConfigurator._Impl.remove_extension_slice  s    
 ||~)0)K)K)M&'8'Q'QR`'a$')ww||4JL`'a$77>>"6788H&,,@@AUV 8	 r'   c                     | j                         r}|y|D ]r  }|j                  dd      }t        j                         }|-|0g }t        j
                  j                  |dj                  |            }t        j
                  j                  |t              }|j                  |t        f       t        j
                  j                  |t              }|j                  |t        f       |j                  dd      }	|	gt        |	      dz   }	t        d||	       t        j
                  j                  |t              }
t         j                  |	      }|j                  |
|f       | j#                  |       | j%                          u yyy)a7  
            Each extension service will have name, systemd path and it's quotas.
            This method ensures that drop-in files are created under service.d folder if quotas given.
            ex: /lib/systemd/system/extension.service.d/11-CPUAccounting.conf
            TODO: set memory quotas
            Nname{0}.dcpuQuotaPercentager   r  )r   getr   r   rQ   rR   rU   r.   rW   r   r   rX   r   r   r4   rY   r  _Impl__create_all_filesr\   )rK   services_listserviceservice_nameunit_file_pathr   drop_in_pathdrop_in_file_cpu_accountingdrop_in_file_memory_accountingr   drop_in_file_cpu_quotacpu_quota_contentss               r(   'set_extension_services_cpu_memory_quotaz@CGroupConfigurator._Impl.set_extension_services_cpu_memory_quota  s`    ||~-";, 7G#*;;vt#<L%,%G%G%IN#/N4N*,')ww||NGNNS_D`'a68ggll<C_7a3'..0KMr/st9;lFe:g6'..;=efh %,KK0Dd$K	$0(+I(<I,-QS_ajk57WW\\,Pg5h21X1_1_`i1j.+224JL^3_`//@446/7 #<~r'   c                    | j                         r |d}	 |D ]  }|j                  dd      }t        j                         }|-|0g }t        j
                  j                  |dj                  |            }d}t        j
                  j                  |t              }t        j                  |      }	t        j
                  j                  |      rGt        |d      5 }
|
j                         |	k(  r	 ddd        y	 ddd       |j                  ||	f       | j                  |        yyy# 1 sw Y   3xY w# t        $ r }t!        d|t#        |             Y d}~yd}~ww xY w)z
            Removes any CPUQuota on the extension service

            NOTE: This resets the quota on the extension service's default dropin file; any local overrides on the VM will take precedence
            over this setting.
            Nr  r  r   r   z&Failed to reset CPUQuota for {0} : {1})r   r  r   r   rQ   rR   rU   r.   rY   r  rS   r   r   r   r  r]   r9   r   )rK   r  r  r  r  r   r  r   r  r  r   rw   s               r(   $__reset_extension_services_cpu_quotaz=CGroupConfigurator._Impl.__reset_extension_services_cpu_quota  sP    ||~-";#q#0 E'.{{64'@)0)K)K)M'38R.0O+-77<<WcHd+eL(*I57WW\\,Pg5h21X1_1_`i1j.!ww~~.DE%)*@#%F !/%',zz|7I'I(.!/ !/'I!/ !0 6 68NPb7c d 33ODE #<~!/ !/
 ! q'(PR^`den`oppqsB   .D? D? 
BD? !D36	D? /D? 3D<	8D? ?	E(E##E(c                    |S|D ]L  }|j                  dd      }t        j                         }|-|0g }t        j                  j                  |dj                  |            }t        j                  j                  |t              }|j                  |       t        j                  j                  |t              }|j                  |       |j                  dd      }	|	5t        j                  j                  |t              }
|j                  |
       t        j                  j                  |       t        dj                  |             O yy)z^
            Remove the dropin files from service .d folder for the given service
            Nr  r  r  zDrop in files removed for {0})r  r   r   rQ   rR   rU   r.   rW   r   rX   rY   r;   r   r[   r4   )rK   r  r  r  r  rm   r  r  r  r   r  s              r(   'remove_extension_services_drop_in_filesz@CGroupConfigurator._Impl.remove_extension_services_drop_in_files  s#    (, _G#*;;vt#<L%,%G%G%IN#/N4N+-(')ww||NGNNS_D`'a68ggll<C_7a3(//0KL9;lFe:g6(//0NO$+KK0Dd$K	$057WW\\,Pg5h2,334JK*00DDEUV()H)O)OP\)]^%_ )r'   c                     | j                         r1|.|D ](  }|j                  dd      }|| j                  |       * yyy)z[
            Remove the cgroup entry from the tracked groups to stop tracking.
            Nr  )r   r  r|  rK   r  r  r  s       r(   (stop_tracking_extension_services_cgroupszACGroupConfigurator._Impl.stop_tracking_extension_services_cgroups  sN     ||~-";, FG#*;;vt#<L#/77EF #<~r'   c                     | j                         r1|.|D ](  }|j                  dd      }|| j                  |       * yyy)zV
            Add the cgroup entry to start tracking the services cgroups.
            Nr  )r   r  ry  r  s       r(   )start_tracking_extension_services_cgroupszBCGroupConfigurator._Impl.start_tracking_extension_services_cgroups'  sN     ||~-";, GG#*;;vt#<L#/88FG #<~r'   c                     i } t        j                  t        j                  j	                  t        j                         d            D ]  }t        j                  d|      }||j                  d      }|j                  d      r?	 t        j                  t        j                  |            }|d   j                  dd      }|r|j                  d      nd}|| |<    | S # t         t"        f$ r/}t%        d	j'                  ||j(                               Y d}~d}~wt*        $ r t%        d
j'                  |             Y w xY w)a  
            ResourceLimits for extensions are coming from <extName>/HandlerManifest.json file.
            Use this pattern to determine all the installed extension HandlerManifest files and
            read the extension services if ResourceLimits are present.
            z*/HandlerManifest.jsonz,(?P<extname>[\w+\.-]+).HandlerManifest\.jsonNextnameWALinuxAgentr   resourceLimitsservicesz'Failed to load manifest file ({0}): {1}zMalformed manifest file ({0}).)globiglobrQ   rR   rU   r   get_lib_dirr   r\  r   
startswithjsonloadsr   	read_filer  IOErrorOSErrorr9   r.   strerror
ValueError)extensions_servicesmanifest_pathr   extensions_namedataresource_limitsr  r%  s           r(   r  z4CGroupConfigurator._Impl.get_extension_services_list1  s+    #%!%BGGLL9I9I9KMe,f!g h		"SUbc$&+kk)&<O*55nE	h#'::h.@.@.O#PD.21gkk:JD.QOJY':'::'F_cHCK/@h '& !(1 m/ I P PQ^`a`j`j km m) h/0P0W0WXe0fghs   AC##E2%D&EEr   )5r    r!   r"   rL   rx   staticmethod#_Impl__collect_azure_unit_telemetry)_Impl__collect_agent_unit_files_telemetryra   rf   re   r\   r   r   r[   r  r   rg   r   r   r   r   rh   r  ri   r  r  r&  r  r3  r0  r4  r5  r1  r6  r  rp  r2  ry  r|  r  r   PluginUnknownFailurer  r  r  r  r  r  r  r  r  r  r&   r'   r(   r   r=      sV   		9L	)\ 
	b 
	b@ 
	[ 
	[2		%	?N 
Q	C 
Q	Cf 
	g 
	g 
	R 
	R 
	\ 
	\ 
	` 
	` 
		 
			&+	CZ	+	S	/	4	4	q. 

	@ 

	@ 

	q 

	q 
	 
	(	3B3	sj 
	! 
	! 
	4 
	4 
	 
	" 
	 
	  
	 
	& 
	N 
	N 
	t 
	t	C 
	 
		o(	v 	v. 0C/W/W	U<	K	W6	W	7B	q8	_2	F	G 
	' 
	'r'   r   Nc                  |    t         j                  t         j                         t         _        t         j                  S r   )r;   	_instancer   r&   r'   r(   get_instancezCGroupConfigurator.get_instanceM  s,    ''/+=+C+C+E(!+++r'   )	r    r!   r"   __doc__objectr   r  r  r  r&   r'   r(   r;   r;      s/    ' 'D I, ,r'   r;   )?r  r  rQ   r   r  rG   azurelinuxagent.commonr   r   azurelinuxagent.common.cgroupr   r   r   r    azurelinuxagent.common.cgroupapir	   r
   r   r   'azurelinuxagent.common.cgroupstelemetryr    azurelinuxagent.common.exceptionr   r   r   azurelinuxagent.common.futurer   azurelinuxagent.common.osutilr   r   azurelinuxagent.common.versionr   azurelinuxagent.common.utilsr   r   1azurelinuxagent.common.utils.extensionprocessutilr   azurelinuxagent.common.eventr   r   rd   r   r   r~  r   r   r   r   r   LOGCOLLECTOR_MEMORY_LIMITrV   r   rW   r   rY   r  rX   r   r  r   r4   r9   r;   r&   r'   r(   <module>r     s  "   	 	   ' ) g g s s D p p . = 5 < W F  -x7 '#-0CC   	  = 	$    * + & "  7 ) % - + ' #= , (V BeP, P,r'   