+
    ).i
1                    Z   R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIt^ RIt^ RIHt ^ RIHt Rt]! ]P(                  P+                  RR4      4      t^t]P0                  ! R4      t]P4                  ! ]P6                  R	R
7       R9R R lltR R ltR R ltR R ltR R lt R R lt!R R lt"R:R R llt#R R lt$R R lt%R R  lt&R! R" lt'R# R$ lt(R% R& lt)R' R( lt*R)R*R+R,R-R/R. R/ llt+R0 R1 lt,R2 R3 lt-R4 R5 lt.R6 R7 lt/]0R88X  d
   ]/! 4        R# R# );u   Manage agent — runs as a systemd service on each Ubuntu host.

Polls the configured server, executes queued tasks, reports results.
)annotationsN)Path)Anyz0.1.0MANAGE_CONFIGz/etc/manage-agent/config.jsonzmanage-agentz'%(asctime)s [%(levelname)s] %(message)s)levelformatc               0    V ^8  d   QhRRRRRRRRRR	R
R/# )   methodstrurlheaderszdict[str, str] | Nonebodydict | Nonetimeoutintreturndict )r   s   "agent/manage-agent.py__annotate__r   $   sA     J J# JC J*? Jk Jkn Jx| J    c           	        Ve%   \         P                  ! V4      P                  4       MR p\        P                  P                  WV R7      pVP                  RR4       VP                  RR\         24       T;'       g    / P                  4        F  w  rxVP                  Wx4       K  	   \        P                  P                  WdR7      ;_uu_ 4       p	V	P                  4       P                  4       ;'       g    Rp
\         P                  ! V
4      uuR R R 4       #   + '       g   i     R # ; i  \        P                  P                   dY   pTP                  '       d!   TP                  4       P                  RR	7      MR
p\!        RTP"                   RT RT 24      ThR p?i\        P                  P$                   d   p\!        RT RT 24      ThR p?ii ; i)N)datar
   zContent-Typezapplication/jsonz
User-Agentzmanage-agent/r   z{}replace)errors zHTTP  z: zNetwork error contacting )jsondumpsencodeurllibrequestRequest
add_headerAGENT_VERSIONitemsurlopenreaddecodeloadserror	HTTPErrorfpRuntimeErrorcodeURLError)r
   r   r   r   r   r   reqkvresprawe	body_texts   &&&&&        r   _httpr9   $   sj   (,(84::d""$dD
..
 
 
 
?CNN>#56NN<=!@AB%%'q (J^^##C#99T))+$$&..$C::c? :999 <<!! G9:AFFHOO9O52	U166(!C59+>?QF<<   J6se2aSABIJsI   ,(D1 >D
D1 D.	(D1 .D1 1GAF## GGGGc                    V ^8  d   QhRRRR/# )r	   pathr   r   r   )r   s   "r   r   r   9   s      S S r   c                Z     \        V 4      P                  4       #   \         d     R # i ; i)r   )r   	read_textOSError)r;   s   &r   
_read_procr?   9   s,    Dz##%% s    **c                   V ^8  d   QhRR/# r	   r   r   r   )r   s   "r   r   r   @   s     - -C -r   c                     \        R 4      P                  4        FC  p V P                  R4      '       g   K  V P                  R^4      ^,          P	                  4       u # 	  \
        P                  ! 4       ;'       g    R# )z/proc/cpuinfoz
model name:unknown)r?   
splitlines
startswithsplitstripplatform	processor)lines    r   
_cpu_modelrL   @   sa    ?+668??<((::c1%a(..00 9 ,,9,r   c                   V ^8  d   QhRR/# r	   r   r   r   )r   s   "r   r   r   G   s      C r   c                 @    \         P                  ! 4       ;'       g    ^ # )    )os	cpu_countr   r   r   
_cpu_coresrS   G   s    <<>Qr   c                   V ^8  d   QhRR/# r	   r   ztuple[int, int]r   )r   s   "r   r   r   K   s     - -/ -r   c                 ,  a / o\        R 4      P                  4        F8  p V P                  R4      w  rpVP                  4       SVP                  4       &   K:  	  R V3R llpV! R4      pV! R4      p\	        ^ WV,
          4      pVR,          VR,          3# )z/proc/meminforC   c                    V ^8  d   QhRRRR/# )r	   namer   r   r   r   )r   s   "r   r   _meminfo.<locals>.__annotate__P   s        r   c                   < SP                  V R 4      P                  4       p \        V^ ,          4      #   \        \        3 d     ^ # i ; i)z0 kB)getrG   r   
ValueError
IndexError)rX   r4   fieldss   & r   kb_meminfo.<locals>.kbP   sF    JJtV$**,	qt9J' 		s   5 A
	A
MemTotalMemAvailablei   )r?   rE   	partitionrH   max)	rK   r3   _r4   r_   total_kbavail_kbused_kbr^   s	           @r   _meminfori   K   s    F?+668..%aGGIqwwy 9  *~H.!H!X()Gd?H,,,r   c                   V ^8  d   QhRR/# rU   r   )r   s   "r   r   r   \   s     1 1? 1r   c                      \         P                  ! R 4      p T P                  T P                  ,          pT P
                  T P                  ,          pY,
          pTR,          TR,          3#   \         d    Ru # i ; i)/)rP   rP   i   @)rQ   statvfsr>   f_blocksf_frsizef_bavail)stotalfreeuseds       r   	_diskinforu   \   sl    JJsO JJ#E::

"D<DGe000  s   A, ,A<;A<c                   V ^8  d   QhRR/# rN   r   )r   s   "r   r   r   g   s       r   c                      \        \        \        R 4      P                  4       ^ ,          4      4      #   \        \
        3 d     ^ # i ; i)z/proc/uptime)r   floatr?   rG   r]   r\   r   r   r   _uptimery   g   sA    5N399;A>?@@
# s   14 A	A	c                    V ^8  d   QhRRRR/# )r	   sample_secondsrx   r   r   )r   s   "r   r   r   n   s        r   c           	     
   R  R lp V! 4       w  r#\         P                  ! V 4       V! 4       w  rEWS,
          pWB,
          pV^ 8:  d   R# \        R\        RRWv,          ,
          R,          4      4      #   \         d     R# i ; i)c                   V ^8  d   QhRR/# rU   r   )r   s   "r   r   "_cpu_percent.<locals>.__annotate__o   s      / r   c                    \        R 4      P                  4       ^ ,          p V P                  4       R,           Uu. uF  p\        V4      NK  	  ppV^,          \	        V4      ^8  d
   V^,          M^ ,           p\        V4      pW43# u upi )z
/proc/stat:   NN)r?   rE   rG   r   lensum)rK   xpartsidlerr   s        r   snap_cpu_percent.<locals>.snapo   ss    ,'224Q7!%b!12!1AQ!12Qxs5zA~581=E
{ 3s   Bg        g      Y@g      ?)timesleeprd   min	Exception)r{   r   i1t1i2t2dtdis   &       r   _cpu_percentr   n   ss    


>"WW73EC"'MU#:;<< s   ?A3 	)A3 3BBc                   V ^8  d   QhRR/# )r	   r   ztuple[str, str]r   )r   s   "r   r   r      s     > >_ >r   c                 
   / p \        R 4      P                  4        FA  pRV9   g   K  VP                  R^4      w  r#VP                  4       P                  R4      W&   KC  	  V P	                  RR4      V P	                  RR4      3# )z/etc/os-release="NAMELinuxVERSIONr   )r?   rE   rG   rH   r[   )inforK   r3   r4   s       r   _os_releaser      sr    D,-88:$;::c1%DAggiooc*DG ; 88FG$dhhy"&===r   c                   V ^8  d   QhRR/# rA   r   )r   s   "r   r   r      s      S r   c                     \         P                   ! \         P                  \         P                  4      p V P                  R 4       V P	                  R4       V P                  4       ^ ,          pV P                  4        V#   \         dA     \         P                  ! \         P                  ! 4       4      u #   \         d      R# i ; ii ; i)      ?r   )z1.1.1.1P   )
socketAF_INET
SOCK_DGRAM
settimeoutconnectgetsocknamecloser>   gethostbynamegethostname)rq   ips     r   _primary_ipr      s    MM&..&*;*;<	S			/"]]_Q			 	''(:(:(<== 		s0   A=B   C(B74C7CCCCc                   V ^8  d   QhRR/# rA   r   )r   s   "r   r   r      s       r   c                 h    \         P                  ! . RORR^R7      p V P                  P                  4        F>  pVP	                  4       p\        V4      ^8  g   K%  V^,          R9  g   K5  V^,          u # 	   \         P                  ! R.RR^R7      p V P                  '       d"   V P                  P                  4       ^ ,          MRpV'       d   VP	                  4       ^ ,          # R#   \        \         P                  3 d     Li ; i  \        \         P                  \        3 d     R# i ; i)loginctlT)capture_outputtextr   whor   )r   zlist-sessionsz--no-legend)rootgdmlightdm)	
subprocessrunstdoutrE   rG   r   FileNotFoundErrorSubprocessErrorr]   )outrK   r   s      r   _logged_in_userr      s    
nn8dA
 JJ))+DJJLE5zQ583M#MQx ,nneWTaP-0ZZZszz$$&q)R"&tzz|A.B. z99:  z99:F sH   AC, C, -
C, 8C, ;,D (*D D *D ,D
	D
 D10D1c                   V ^8  d   QhRR/# r	   r   dict[str, Any]r   )r   s   "r   r   r      s      ^ r   c                    \        4       w  r\        4       w  r#\        4       w  rE/ R \        P                  ! 4       bRV bRVbR\
        P                  ! 4       bR\
        P                  ! 4       bR\        4       bR\        4       bR\        4       bRVbR	VbR
VbRVbR\        4       bR\        4       bR\        bR\        4       b# )hostnameos_name
os_versionkernelarch	cpu_model	cpu_corescpu_percentmem_total_mbmem_used_mbdisk_total_gbdisk_used_gbuptime_seconds
ip_addressagent_versionlogged_in_user)r   ri   ru   r   r   rI   releasemachinerL   rS   r   ry   r   r&   r   )r   r   mem_used	mem_total	disk_used
disk_totals         r   collect_system_infor      s   %-G"*H%KIF&&(7 	j 	(""$	
 	  " 	Z\ 	Z\ 	|~ 		 	x 	 		 	') 	km 	  	/+! r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r      s     / /^ /r   c                     \         P                  4       '       g1   \        P                  R \         4       \        P
                  ! ^4       \        P                  ! \         P                  4       4      # )u-   No config at %s — running enrollment first.)	CONFIG_PATHexistslogr,   sysexitr   r+   r=   r   r   r   load_configr      sC    		A;O::k++-..r   c                    V ^8  d   QhRRRR/# r	   cfgr   r   Noner   )r   s   "r   r   r      s      ^  r   c                    \         P                  P                  R R R7       \         P                  \        P
                  ! V ^R7      4        \        P                  ! \         R4       R#   \         d     R# i ; i)Tparentsexist_ok)indenti  N)	r   parentmkdir
write_textr   r    rQ   chmodr>   )r   s   &r   save_configr      sY    TD94::c!45
e$ s   A+ +A:9A:c               $    V ^8  d   QhRRRRRR/# )r	   serverr   enrollment_tokenr   r   r   )r   s   "r   r   r      s!      3 # . r   c                
   R VR\        4       /p\        RV  R2VR7      pRV P                  R4      RVR,          RVR,          R	VP                  R	\        4      /p\        V4       \        P                  R
VR,          4       V# )r   system_infoPOSTz/api/agents/enroll)r   r   rl   agent_idtokencheckin_interval_secondszEnrolled as agent %s)r   r9   rstripr[   DEFAULT_INTERVALr   r   r   )r   r   payloadr5   r   s   &&   r   enrollr      s    !#3]DWDYZGF8#56WED&--$D$g"DHH-GIY$Z	C HH#S_5Jr   shellFr   X  envc          
     ,    V ^8  d   QhRRRRRRRRR	R
/# )r	   cmdzlist[str] | strr   boolr   r   r   r   r   tuple[int, str, str]r   )r   s   "r   r   r      s1     * *o * * *P[ *g{ *r   c          	     l    \         P                  ! V VR R VVR7      pVP                  VP                  VP                  3#   \         P
                   dC   p^|TP                  ;'       g    RTP                  ;'       g    RRT R2,           3u Rp?# Rp?i\         d   p^RRT 23u Rp?# Rp?ii ; i)T)r   r   r   r   r   r   z
[timeout after zs]Nzagent error: )r   r   
returncoder   stderrTimeoutExpiredr   )r   r   r   r   procr7   s   &$$$  r   _runr     s    *~~
 T[[88$$ WAHHNNQXX^^9J7)SU7V$VVV *"aS)))*s;   >A B3(B?BB3B3 B3!B.(B3.B3c                    V ^8  d   QhRRRR/# )r	   taskr   r   r   r   )r   s   "r   r   r      s     -+ -+~ -+*> -+r   c           
        V R ,          pV P                  R4      ;'       g    / p\        P                  RV R,          V4       VR8X  d/   \        VR,          R\	        VP                  RR4      4      R	7      # VR
8X  d   \        VP                  R4      ;'       g    . 4      pV'       g   R(# / \        P                  CRR/Cp\        RR.VRR7      w  rVp\        . R)OVOVRR7      w  rp
T;'       g    TWi,           Wz,           3# VR8X  dW   \        VP                  R4      ;'       g    . 4      pV'       g   R(# / \        P                  CRR/Cp\        . R*OVOVRR7      # VR8X  dX   / \        P                  CRR/Cp\        RR.VRR7      w  rVp\        . R+OVRR7      w  rp
T;'       g    TWi,           Wz,           3# VR8X  d   \        VR,          4      p\        P                  ! VR,          4      p VP                  P                  RRR7       VP                  V4       VP                  RR4      p\        P                  ! V\	        V^4      4       ^ R\        V4       RV RV R 2R3# VR#8X  d   \"        P$                  ! . R,O4       R-# VR$8X  d   \"        P$                  ! . R.O4       R/# VR%8X  d   \'        VP                  R&R4      4      # ^RR'V 23#   \          d   p^RR!T 23u R"p?# R"p?ii ; i)0typer   zExecuting task #%s (%s)idr   commandTr   r   )r   r   apt_installpackagesr   DEBIAN_FRONTENDnoninteractiveapt-getupdatei,  )r   r   i  
apt_removeapt_upgradei  	push_filer;   content_b64r   mode0644zwrote z
 bytes to z (mode )zpush_file error: Nrebootshutdownset_wallpaperr   zunknown task type )r   r   zno packages)r  install-y)r  remover  )r  upgrader  )r  z-r+1zReboot scheduled by Manage)rP   zreboot scheduled in 60sr   )r  z-hr   zShutdown scheduled by Manage)rP   zshutdown scheduled in 60sr   )r[   r   r   r  r   listrQ   environr   base64	b64decoder   r   write_bytesr   r   r>   r   Popen_set_wallpaper)r  tppkgsr   rc1o1e1rc2o2e2r;   contentmode_strr7   s   &              r   execute_taskr3     s   VA!!rAHH&T
A6G|AiLc!%%	3:O6PQQMAEE*%++,''AA.0@AIx0c3G>>CQTU

sRWbg--LAEE*%++,''AA.0@A66CMMMAA.0@AIx0c3G7S$O

sRWbg--KAfI""1]#34	2KKdT:W%uuVV,HHHT3x+,s7|nJtfGH:QOQSSS 	H}OP//JQR11OaeeE2.//b&qc***  	2b-aS111	2s   8A8K K:(K5/K:5K:c                    V ^8  d   QhRRRR/# )r	   r   r   r   r   r   )r   s   "r   r   r   +  s     : : : 4 :r   c                   V '       g   R# \        R4      pVP                  RRR7       VR,          p \        P                  P	                  V ^<R7      ;_uu_ 4       pVP                  VP                  4       4       RRR4       \        R	4      pTP                  RRR7       TR
,          pRTP                  4       '       d   TP                  4       MR9  d   TP                  R4       \        R4      pTP                  RRR7       TR,          P                  RT RT R24       \        RR.^R7      w  rpTRT RT	 2T3#   + '       g   i     L; i  \         d   p^RRT 23u Rp?# Rp?ii ; i)r   r   z/usr/share/backgroundsTr   zmanage-wallpaper.jpgr   Nzdownload failed: z/etc/dconf/profileuserzsystem-db:managezuser-db:user
system-db:manage
z/etc/dconf/db/manage.dz00-wallpaperz3[org/gnome/desktop/background]
picture-uri='file://z'
picture-uri-dark='file://z'
picture-options='zoom'
dconfr  zwallpaper installed at 
)r   r   zno url)r   r   r"   r#   r(   r%  r)   r   r   r=   r   r  )
r   bg_dirtargetrr7   profile_diruser_profiledb_dirrcos
   &         r   r'  r'  +  sq   *+F
LLL-,,F.^^##C#44qvvx( 5
 +,KdT2'Ll>Q>Q>S>S,"8"8":Y[\ BC*+F
LLL-n((	%h '$$*8 ,#	# Wh'4HB1(1#699) 54 .")!---.s;   )E  E<E E	E E E3!E.(E3.E3c                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   r   L  s      n  r   c                   V R ,          pRRV R,           2/p\        V P                  R\        4      4      p  \        RV R2VR\	        4       /^R7      p\        VP                  RV4      4      pWS8w  d   TpVP                  R	4      ;'       g    .  F5  p\        V4      w  rxp	 \        RV R
VR,           R2VRVRVRV	/^<R7       K7  	  \        P                  ! V4       K    \         d*   p
\        P                  RTR,          T
4        Rp
?
K  Rp
?
ii ; i  \         d!   p
\        P                  RT
4        Rp
?
LuRp
?
ii ; i)r   AuthorizationzBearer r   r   r   z/api/agents/checkinr   )r   r   r   tasksz/api/agents/tasks/r
  z/result	exit_coder   r  z'Failed to report result for task %s: %sNzCheck-in failed: %s)r   r[   r   r9   r   r3  r   r   r,   warningr   r   )r   r   r   intervalr5   new_intervalr  r?  r   errr7   s   &          r   checkin_looprJ  L  sP   ]F'#g, 89G37757GHIH
	2(-.#%8%:;D txx(BHMNL'')//R/+D1	X!("4T$ZLH ')2xhL " 0 	

8	 ! XIIGdUVWWX 	2KK-q11	2sH   AD D &#C%	D %D0DD DD E'EEc                   V ^8  d   QhRR/# )r	   r   r   r   )r   s   "r   r   r   n  s      d r   c                    \        \        P                  4      ^8  d   \        P                  ^,          R8X  d   \        P                  P                  R4      p \        P                  P                  R4      pV '       d	   V'       g,   \        P                  R4       \        P                  ! ^4       \        W4       R# \        4       p\        P                  RVR,          VR,          4       \        V4       R# )	r   r   MANAGE_SERVERMANAGE_TOKENz?MANAGE_SERVER and MANAGE_TOKEN env vars required for enrollmentNz'Starting check-in loop against %s as %sr   r   )r   r   argvrQ   r"  r[   r   r,   r   r   r   r   rJ  )r   r   r   s      r   mainrP  n  s    
388}qSXXa[H40

~.UIIWXHHQKv
-CHH6Hs:Wr   __main__)NN   )r   )1__doc__
__future__r   r#  r   loggingrQ   rI   r   r   r   r   urllib.errorr"   urllib.requestpathlibr   typingr   r&   r"  r[   r   r   	getLoggerr   basicConfigINFOr9   r?   rL   rS   ri   ru   ry   r   r   r   r   r   r   r   r   r  r3  r'  rJ  rP  __name__r   r   r   <module>r^     s   #    	    
     2::>>/3RST '   
,,4J*--"1(>(6/"* *c *^b *"-+`:BD zF r   