ó
    š#JjJ  ã                  óÂ   • S r SSKJr  SSKrSSKJrJr  SSKJr  SSKJ	r	J
r
  SSKJr  SSKJr  SS	KJrJrJr  SS
KJr  \" S5      rSqSqSqSS jrSSS jjrSSS jjrg)a+  Heartbeat: periodic liveness + light metrics to the Central API.

The heartbeat must be resilient: if the API is unavailable the agent logs the
failure and keeps running, retrying on the next interval. It never crashes the
service and never blocks indefinitely (the API client has its own timeout).
é    )ÚannotationsN)ÚdatetimeÚtimezone)ÚAny)Ú	ApiClientÚApiError)ÚConfig)Úsystem)Úload_agent_tokenÚsave_statusÚsave_last_error)Ú
get_loggerÚ	heartbeatg        Fc                óz  • [         R                   " 5       n[        U SS5      n[        b  U[        -
  U:  a  [        [        4$  SSKJn  U" X5      nUb  UR                  qUR                  qUq[        c  U R                  S4$ [        [        4$ ! [         a   n[        R                  SU5         S nANFS nAff = f)NÚheartbeat_intervalé<   r   )Úcheckz0Silent ignore of update manifest fetch error: %sF)ÚtimeÚgetattrÚ_cached_latest_versionÚ_last_fetch_timeÚ_cached_update_availableÚupdater   ÚlatestÚupdate_availableÚ	ExceptionÚlogÚwarningÚagent_version)ÚconfigÚ
api_clientÚnowÚintervalÚcheck_updateÚinfoÚexcs          Ú3D:\Programs\laragon\www\wolf\agent\src\heartbeat.pyÚget_update_statusr(      s½   € ô �)Š)‹+€CÜ�vÐ3°RÓ8€HäÑ)¨sÔ5EÑ/EÈÓ/PÜ%Ô'?Ð?Ð?ðMÝ0Ù˜FÓ/ˆØÑØ%)§[¡[Ð"Ø'+×'<Ñ'<Ð$Ø"Ðô Ñ%Ø×#Ñ# UÐ*Ð*ä!Ô#;Ð;Ð;øô ó MÜ�‰ÐFÈ×LÑLûðMús   Á+B Â
B:ÂB5Â5B:c           	     óš  • [        X5      u  p4 SSKnUR                  U R                  S9  UR	                  5       nU R                  UUUU R                  [        R                  " 5       [        R                  " [        R                  5      R!                  5       US.$ ! [
         a"  n[        R                  SU5        0 n SnAN‰SnAff = f)a  Assemble the heartbeat payload.

The heartbeat contract requires `agent_version`, `update_available`,
`latest_version`, and `status`; the agent is identified by its
X-Agent-Token header, not the body. Light metrics are sent as additional
informational fields.
r   N)r#   zFailed to collect telemetry: %s)r   r   Úlatest_versionÚstatusÚ	server_idÚhostnameÚ	timestampÚmetrics)r(   r/   Ústart_updaterr   Úget_metricsr   r   r   r   r,   r
   r-   r   r"   r   ÚutcÚ	isoformat)r    r!   r+   r*   r   r/   Úcollected_metricsr&   s           r'   Úbuild_payloadr5   4   s³   € ô (9¸Ó'LÑ$€NðÛØ×Ñ v×'@Ñ'@ÐÑAØ#×/Ñ/Ó1Ðð  ×-Ñ-Ø,Ø(ØØ×%Ñ%Ü—O’OÓ%Ü—\’\¤(§,¡,Ó/×9Ñ9Ó;Ø$ñ	ð 	øô	 ó Ü�‰Ð5°sÔ;ØÕûðús   �-B Â
C
Â(CÃC
c                ó@  • U R                   S:X  a  [        R                  S5        g[        XU5      n UR	                  U[        U 5      5        [        R                  SU5        [        U S5        SSKnU R                  S-  nUR                  5       (       Ga   [        US5       nUR                  U5      nSSS5        WR                  S	5      nU(       aE  [        R                  S
U5        UR                  USSSU R                   3S.S.[        U 5      5        UR                  S5      n	U	(       aN  SSKJn
  SSKnU
" U	5      nUR'                  5       (       a'  UR)                  U5        [        R                  SU5        UR+                  5         [        R                  S5        SSKnUR2                  R                  S5      nU(       a=   [        US5       nUR5                  S5        SSS5        [        R                  SU5        UR2                  R                  S5      nU(       aR  SSKn [9        US5      (       a;  UR;                  [=        U5      UR>                  5        [        R                  SU5        gg! , (       d  f       GNÏ= f! [,         a!  n[        R/                  SU5         SnAGNSnAff = f! , (       d  f       NÙ= f! [,         a   n[        R/                  SU5         SnANëSnAff = f! [,         a   n[        R/                  SU5         SnAgSnAff = f! [@         ag  n[        U [C        U5      5        URD                  S:X  a"  [G        U S5        [        R                  S5        O[        R                  S U5         SnAgSnAff = f)!uŸ   Send a single heartbeat. Returns True on success, False on failure.

Never raises â€” transport errors are caught and reported so the caller's
loop continues.
Úrevokedz$Heartbeat skipped: Agent is revoked.Fzheartbeat ok (status=%s)Nr   zupdate_state.jsonÚrÚjob_idz>Reporting self-update command success to backend for job_id=%sÚ	succeededTzSuccessfully updated to )ÚsuccessÚmessage)r+   ÚresultÚ
backup_dir)ÚPathzCleaned up backup directory %szDeleted update state filez2Failed to complete update reporting or cleanup: %sÚWOLFPANEL_UPDATE_FLAG_FILEÚwÚOKz"Wrote update success flag file: %sz$Failed to write update flag file: %sÚWOLFPANEL_UPDATE_PARENT_PIDÚSIGUSR1zSent SIGUSR1 to parent PID: %szFailed to signal parent: %si‘  z3Heartbeat rejected by Central; marked agent revokedz.heartbeat failed, will retry next interval: %s)$r+   r   r   r5   r   r   r%   r   ÚjsonÚvar_dirÚis_fileÚopenÚloadÚgetÚpost_command_resultr   Úpathlibr?   ÚshutilÚexistsÚrmtreeÚunlinkr   ÚerrorÚosÚenvironÚwriteÚsignalÚhasattrÚkillÚintrD   r   ÚstrÚstatus_coder   )r    r!   r+   ÚpayloadrE   Ú
state_fileÚfÚupdate_stater9   Úbackup_dir_pathr?   rM   ÚbdÚerR   Ú	flag_fileÚ
parent_pidrU   r&   s                      r'   Ú	send_oncerd   R   sú  € ð ‡}�}˜	Ó!Ü�‰Ð:Ô;Øä˜F°Ó7€GðAØ×Ñ˜WÔ&6°vÓ&>Ô?Ü�‰Ð+¨VÔ4Ü˜ Ô%ó 	Ø—^‘^Ð&9Ñ9ˆ
Ø×Ñ×ÒðSÜ˜* cÔ*¨aØ#'§9¡9¨Q£<�L÷ +ð &×)Ñ)¨(Ó3�ÞÜ—H‘HÐ]Ð_eÔfØ×2Ñ2ØØ#.ÀdÐYqÐrx÷  sGñ  sGð  rHð  XIñ  ;Jñ  KÜ(¨Ó0ôð #/×"2Ñ"2°<Ó"@�Þ"Ý,Û!Ù˜oÓ.�BØ—y‘y—{‘{ØŸ™ bÔ)ÜŸ™Ð!AÀ2ÔFð ×!Ñ!Ô#Ü—‘Ð4Ô5ó 	Ø—J‘J—N‘NÐ#?Ó@ˆ	ÞðEÜ˜) SÔ)¨QØ—G‘G˜D”M÷ *ä—‘Ð=¸yÔIð —Z‘Z—^‘^Ð$AÓBˆ
ÞÛð<Ü˜6 9×-Ñ-Ø—G‘GœC 
›O¨V¯^©^Ô<Ü—H‘HÐ=¸zÔJñ ÷_ +Ö*ûô2 ó SÜ—	‘	ÐNÐPQ×RÒRûðSú÷ *Õ)ûô ó EÜ—	‘	Ð@À!×DÑDûðEûô ó <Ü—	‘	Ð7¸×;Ð;àûð<ûô ó Ü˜¤ C£Ô)Ø�?‰?˜cÓ!Ü˜ 	Ô*Ü�K‰KÐMÕNä�K‰KÐHÈ#ÔNÜûðúsÃ   ´A&L, ÂJ Â'JÂ9C0J Æ)&L, ÇK ÇKÇ.K È&L, È3AK? Ê
JÊJ Ê
J>ÊJ9Ê3L, Ê9J>Ê>L, Ë
KËK Ë
K<ËK7Ë2L, Ë7K<Ë<L, Ë?
L)Ì	L$ÌL, Ì$L)Ì)L, Ì,
NÌ6ANÎN)r    r	   r!   r   Úreturnztuple[str, bool])Úonline)r    r	   r!   r   r+   rY   re   zdict[str, Any])r    r	   r!   r   r+   rY   re   Úbool)Ú__doc__Ú
__future__r   r   r   r   Útypingr   r!   r   r   r    r	   Ú	discoveryr
   Úidentityr   r   r   Úloggerr   r   r   r   r   r(   r5   rd   © ó    r'   Ú<module>rp      sV   ðñõ #ã ß 'Ý ç *Ý Ý ß CÑ CÝ á�Ó€àÐ ØÐ Ø Ð ô<ö2÷<Lro   