ó
    °ÁJj™�  ã                  ó„  • S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKJr  SSK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  \" S5      r\ " S S5      5       rSrSrSrSr Sr!\\4SS jjr"\RF                  " S5      r$SS jr%SS jr&S S jr'Sr(S!S jr)S"S jr*S#S jr+S$S%S jjr,S#S jr-g)&a^  Update check foundation.

v1 only DETECTS and REPORTS whether a newer version is available on the
configured channel. It does NOT download, swap, or restart anything. The
production update pipeline is sketched below as no-op stubs with TODOs so the
structure is ready: download -> verify checksum -> stage -> atomic swap ->
health check -> rollback.
é    )ÚannotationsN)ÚPath)Ú	dataclass)ÚAny)Ú	ApiClientÚApiError)ÚConfig)Úload_agent_token)Ú
get_loggerÚupdatec                  óz   • \ rS rSr% S\S'   S\S'   S\S'   SrS\S	'   SrS\S
'   SrS\S'   SrS\S'   Sr	S\S'   Sr
g)Ú
UpdateInfoé!   ÚstrÚcurrentÚlatestÚboolÚupdate_availableNz
str | NoneÚurlÚsha256Ú	signatureÚchannelz
int | NoneÚ
size_bytes© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__annotations__r   r   r   r   r   Ú__static_attributes__r   ó    Ú0D:\Programs\laragon\www\wolf\agent\src\update.pyr   r   !   sD   ‡ àƒLØƒKØÓØ€CˆÓØ€FˆJÓØ €IˆzÓ Ø€GˆZÓØ!€J�
Ö!r!   r   l‰   ehöÏm†>?ÕfÈK–q"0½awÅ
•p�plkQPo3Þ?Ê%?!y‰P[{Ì™0ºg<M«.ÕÕ©9`Ž>s ~¢ƒN�cvaö ¥-\R !£nV5o_W;BŠtJz¹AëwPµ9§(æzÏDukJ åVK{µgIä	Òs çx
s£^SAKã9�qäiU1RDŽò#Ô Î\tO^sk¢rSWà á@ÿ\Ö47H*@AJj]»e QÚR¼Mz	ÕXeyç+?“ Ô)“)³kRÂcxNìu
Ån}‰vFbXØqôu‹.?¯ i  l‰   I`ú2„¾}ÛzkR¾9t>mt¾¤Ú@a%Ax}]�}i³GÔ[_/oB|³s >¤+ß8Y3Æ	f+R´{fpöšxQw|‹wB	w{¢KGoðd¾x�XzmQÍNêF£v±X:hdN[aö)Í–MQôÛÓRj>GGÌ2q!RUüDy¯9Ø#¶-`t`h"u:¢]Ù3Ê)ZY¹dWi¼G\QÂ'1yy.ZSÞaz:ä{­ªƒgæE‡rÛ<ÂH/o¡YEâ:ëWu0!;S‡ Üj�.VP'½>S_H$xVS0Ys•~Ù?Nyäç2švâ l‰   ízP£�9ÎWJú(pCÆ@I]ùHLM�9yHAGÌ)îE»q§%U=;ª'.YubÎX˜nÈP:vˆLs•KÀ"ép±d2%$Á0N-Þ£ 4(« ;n0~S,s4
�zg	D_¬<X±Uäik.q`*Q	ï]r)°YïcvsGp“E*’T9åµy4\ÇÕs‡?š	uã+ˆ@LM ù{ý¨`úmø/0u–|ÂH#)·R;ä?¯SBöVü7ï4cÚ\:À^oâYÙ|I´¡D[\xdsFPZ[ð9,[m­Fòd!Tê=²J&¢_	 c                óJ  •  U(       d  g[         R                  U5      n[        U5      S:w  a  g[        R	                  US5      n[        XSU5      nUR                  SS5      n[        R                  " U 5      R                  5       nSn	SU	-   U-   n
Xz:H  $ ! [         a     gf = f)zÇVerify standard RSASSA-PKCS1-v1_5 signature using the given public key.

Defaults to the production public key; pass n=TEST_PUBLIC_KEY_N,
e=TEST_PUBLIC_KEY_E to verify a mock/test signature instead.
Fé   Úbigó   010	`†He  óÍ    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ )ÚbytesÚfromhexÚlenÚintÚ
from_bytesÚpowÚto_bytesÚhashlibr   ÚdigestÚ	Exception)ÚdataÚsignature_hexÚnÚeÚ	sig_bytesÚsÚmÚ	decryptedÚsha256_hashÚasn1_prefixÚexpecteds              r"   Úverify_signaturer=   G   s›   € ðÞØÜ—M‘M -Ó0ˆ	Üˆy‹>˜SÓ ØÜ�N‰N˜9 eÓ,ˆÜ��a‹LˆØ—J‘J˜s EÓ*ˆ	ä—n’n TÓ*×1Ñ1Ó3ˆàeˆØ8¸;ÑFÈÑTˆØÑ$Ð$øÜó Ùðús   ‚B Š$B ¯A%B Â
B"Â!B"z¤^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$c                ó2  • [         R                  U =(       d    SR                  5       5      nU(       d  [        SU < 35      e[	        US   5      [	        US   5      [	        US   5      pCnUS   (       a  [        US   R                  S5      5      OSnX#XE4$ )	zIParse a semver.org version string into (major, minor, patch, prerelease).Ú zinvalid semantic version: ÚmajorÚminorÚpatchÚ
prereleaseÚ.N)Ú
_SEMVER_REÚmatchÚstripÚ
ValueErrorr+   ÚtupleÚsplit)Úversionr8   r@   rA   rB   rC   s         r"   Úparse_semverrL   h   s„   € ä×Ñ˜'Ÿ- R×.Ñ.Ó0Ó1€AÞÜÐ5°g±[ÐAÓBÐBÜ˜a ™j›/¬3¨q°©z«?¼CÀÀ'Á
»O�%€EØ67¸·o”�q˜‘×,Ñ,¨SÓ1Ô2È4€JØ˜Ð*Ð*r!   c                óN   • U R                  5       (       a  S[        U 5      4$ SU 4$ )Nr   é   )Úisdigitr+   )Úidents    r"   Ú_prerelease_identifier_keyrQ   r   s'   € ð ‡}�}‡�Ø”3�u“:ˆÐØˆuˆ:Ðr!   c                ó~  • [        U 5      u  p#pE[        U5      u  pgp‰X&4X74XH44 H  u  p«X«:w  d  M  X«:  a  Ss  $ Ss  $    Uc  U	c  gUc  gU	c  g[        XY5       H,  u  p«[        U
5      [        U5      pÜXÍ:w  d  M!  XÍ:  a  Ss  $ Ss  $    [        U5      [        U	5      :w  a  [        U5      [        U	5      :  a  S$ S$ g)aa  Return -1, 0, or 1 comparing semver strings a and b per semver.org precedence.

Core versions compare numerically field-by-field; a version with a
pre-release always has lower precedence than the same core version
without one (e.g. 1.2.0-rc.1 < 1.2.0); pre-release identifiers compare
left-to-right per semver.org rule 11 (e.g. beta.1 < beta.2 < rc.1).
éÿÿÿÿrN   r   )rL   ÚziprQ   r*   )ÚaÚbÚa_majorÚa_minorÚa_patchÚa_preÚb_majorÚb_minorÚb_patchÚb_preÚxÚyÚkxÚkys                 r"   Úcompare_semverrc   {   sÕ   € ô (4°A£Ñ$€G�gÜ'3°A£Ñ$€G�gàÐ# gÐ%7¸'Ð9KÓL‰ˆØ�6Ø›�2Ò% AÒ%ñ Mð �}˜™ØØ�}ØØ�}Øä�EÖ!‰ˆÜ+¨AÓ.Ô0JÈ1Ó0MˆBØ�8Ø›�2Ò' aÒ'ñ "ô ˆ5ƒz”S˜“ZÓÜ˜“Z¤# e£*Ó,ˆrÐ3°!Ð3Ør!   )rN   c                ób  •  UR                  U R                  5      nUR                  S5      nU[        ;  a  [        R                  SU[        5        gUR                  S5      nXPR                  :w  a"  [        R                  SU R                  U5        gUR                  SS5      n [        X`R                  5      S	:„  nUR                  S5      nU(       d  U R                  (       a  SnUR                  S5      n	Sn
U	(       aC  [        R                  R                  SS5      R                  S5      nU SU R                   SU	 3n
[!        U R                  UUU
UR                  S5      UUUR                  S5      S9nU(       a-  [        R#                  SUR$                  UR&                  5        U$ [        R#                  SUR$                  5        U$ ! [         a   n[        R	                  SU5         SnAgSnAff = f! [         a   n[        R                  S
U5         SnAgSnAff = f)zCFetch the channel manifest and compare against the running version.zupdate check failed: %sNÚmanifest_versionzCrejecting manifest: unsupported manifest_version %r (supported: %s)r   zNrejecting manifest: channel mismatch (agent is on '%s', manifest reports '%s')rK   r?   r   zrejecting manifest: %sr   Úmock_signatureÚfileÚWOLFPANEL_RELEASE_BASEzhttps://downloads.wolfpanel.netÚ/r   r   )r   r   r   r   r   r   r   r   zupdate available: %s -> %szagent is up to date (%s))Úfetch_manifestÚmanifest_urlr   ÚlogÚwarningÚgetÚ_SUPPORTED_MANIFEST_VERSIONSÚerrorÚrelease_channelrc   Úagent_versionrH   Úapi_mockÚosÚenvironÚrstripr   Úinfor   r   )ÚconfigÚ
api_clientÚmanifestÚexcre   Úmanifest_channelr   Ú	availableÚsigÚmanifest_fileÚdownload_urlÚrelease_baserw   s                r"   Úcheckr‚   �   së  € ðØ#-×#<Ñ#<¸V×=PÑ=PÓ#Qˆð
  —|‘|Ð$6Ó7ÐØÔ;Ó;Ü�	‰	ØQØÔ:ô	
ð à—|‘| IÓ.ÐØ×1Ñ1Ó1Ü�	‰	Ø\Ø×"Ñ"Ð$4ô	
ð à�\‰\˜) RÓ(€FðÜ" 6×+?Ñ+?Ó@À1ÑDˆ	ð
 �,‰,�{Ó
#€CÞ�6—?—?ØˆØ—L‘L Ó(€MØ€LÞÜ—z‘z—~‘~Ð&>Ð@aÓb×iÑiÐjmÓnˆØ&˜ q¨×)?Ñ)?Ð(@ÀÀ-ÀÐQˆäØ×$Ñ$ØØ"ØØ�|‰|˜HÓ%ØØ Ø—<‘< Ó-ñ	€Dö Ü�‰Ð-¨t¯|©|¸T¿[¹[ÔIð €Kô 	�‰Ð+¨T¯\©\Ô:Ø€Køôe ó Ü�‰Ð-¨sÔ3Üûðûô. ó Ü�	‰	Ð*¨CÔ0Üûðús/   ‚G Â)H Ç
HÇ!G<Ç<HÈ
H.ÈH)È)H.c                óˆ  • [        [        S5      (       a„   UR                  UR                   S3-  nUR	                  5       (       d  UR                  5       (       a  UR                  5         [        R                  " X5        [        R                  " X!5        g UR	                  5       (       d  UR                  5       (       a<  UR                  5       (       a  UR                  5         O[        R                  " U5        [        R                  " X5        g ! [         a   n[        R                  SU5         S nAN¢S nAff = f)NÚsymlinkÚ_tempz<Symlink creation failed (%s), falling back to directory swap)Úhasattrrt   ÚparentÚnameÚexistsÚ
is_symlinkÚunlinkr„   ÚreplaceÚOSErrorrl   rm   ÚshutilÚrmtreeÚcopytree)Úsrc_dirÚ	dest_linkÚ	temp_linkr5   s       r"   Úswap_directories_atomicr”   Ö   sî   € ÜŒr�9×Ñð	[Ø!×(Ñ(¨i¯n©nÐ-=¸UÐ+CÑCˆIØ×Ñ×!Ñ! Y×%9Ñ%9×%;Ñ%;Ø× Ñ Ô"Ü�JŠJ�wÔ*Ü�JŠJ�yÔ,Øð ×Ñ×Ñ˜Y×1Ñ1×3Ñ3Ø×Ñ×!Ñ!Ø×ÑÕä�MŠM˜)Ô$Ü
‡O‚O�GÕ'øô ó 	[Ü�K‰KÐVÐXY×ZÑZûð	[ús   —BD Ä
EÄ!D<Ä<Ec                óº  •  [        U SS5      nU R                  S-  nUR                  5       (       d  gU R                  S-  nSnUR                  5       (       a  UR	                  5       R
                  n/ nUR                  5        H›  nUR                  5       (       d  M  UR
                  R                  S5      (       a  M<  U(       a  UR
                  U:X  a  MU  UR
                  U R                  :X  a  Mq  UR                  XfR                  5       R                  45        M�     UR                  S S9  [        U5      U:”  a=  USU*   H2  u  pg [        R                   " U5        ["        R%                  S	U5        M4     gg! [&         a!  n["        R)                  S
Xh5         SnAM^  SnAff = f! [&         a   n	["        R)                  SU	5         Sn	A	gSn	A	ff = f)z?Clean up old extracted version directories under opt/versions/.Úupdate_retentioné   ÚversionsNr   ú.backupc                ó   • U S   $ )NrN   r   )r_   s    r"   Ú<lambda>Ú$clean_old_versions.<locals>.<lambda>  s   €   !¢r!   )Úkeyz$Cleaned up old version directory: %sz-Failed to remove old version directory %s: %sz.Failed to clean up old version directories: %s)ÚgetattrÚopt_dirr‰   rŠ   Úreadlinkrˆ   ÚiterdirÚis_dirÚendswithrr   ÚappendÚstatÚst_mtimeÚsortr*   rŽ   r�   rl   rw   r1   rm   )
rx   Ú	retentionÚversions_dirÚcurrent_symlinkÚcurrent_targetÚdirsÚpÚ_r5   r{   s
             r"   Úclean_old_versionsr¯   ê   sŒ  € ð%KÜ˜FÐ$6¸Ó:ˆ	Ø—~‘~¨
Ñ2ˆØ×"Ñ"×$Ñ$Øà Ÿ.™.¨9Ñ4ˆØˆØ×%Ñ%×'Ñ'Ø,×5Ñ5Ó7×<Ñ<ˆNð ˆØ×%Ñ%Ö'ˆAØ�x‰x�z‹zØ—6‘6—?‘? 9×-Ñ-Ùæ! a§f¡f°Ó&>Ùà—6‘6˜V×1Ñ1Ó1ÙØ—‘˜Q§¡£× 1Ñ 1Ð2Ö3ñ (ð 	�	‰	‘nˆ	Ñ%ô ˆt‹9�yÓ Ø˜[˜y˜jÓ)‘�ðWÜ—M’M !Ô$Ü—H‘HÐCÀQÖGò *ð !øô
 !ó WÜ—K‘KÐ OÐQR×VÒVûðWûäó KÜ�‰ÐDÀc×JÑJûðKúsN   ‚1F0 ´A(F0 Â B/F0 Å,FÅ<F0 Æ
F-ÆF(Æ"F0 Æ(F-Æ-F0 Æ0
GÆ:GÇGc                ó¨  • SSK n[        R                  SU5        UR                  R	                  U SS0S9nUR                  R                  XBS9 n[        US5       nUR                  S	5      =n(       a+  UR                  U5        UR                  S	5      =n(       a  M+  SSS5        SSS5        g! , (       d  f       N= f! , (       d  f       g= f)
zBDownload a file from url to dest_path with a timeout using urllib.r   Nz$Downloading file with timeout %ds...z
User-Agentúwolfpanel-agent)Úheaders)ÚtimeoutÚwbé    )	Úurllib.requestrl   rw   ÚrequestÚRequestÚurlopenÚopenÚreadÚwrite)r   Ú	dest_pathr³   ÚurllibÚreqÚresponseÚfÚchunks           r"   Údownload_with_timeoutrÃ     s¨   € ãÜ‡H�HÐ3°WÔ=Ø
�.‰.×
 Ñ
  ¨|Ð=NÐ.OÐ
 Ð
P€CØ	�‰×	Ñ	 Ð	Ñ	5¸Ü�)˜TÔ" aØ#Ÿ=™=¨Ó.Ð.�%Õ.Ø—‘˜”ð $Ÿ=™=¨Ó.Ð.�%×.÷ #÷ 
6Ð	5ß"Õ"ú÷ 
6Õ	5ús%   ÁCÁAB2Â!CÂ2
C 	Â<CÃ
Cc           
     ó\'  • SnSnSn[        U5      S:¼  a  US   n[        U[        5      (       a  UnOUn[        U5      S:¼  a  US   nU(       a  UR                  S5      OSnU(       a  [	        U 5      OSnU(       a6  U(       a/   [
        R                  SU5        UR                  USSS	0S
.U5        U(       d=  U(       d  SSK
Jn
  U
" U 5      n[	        U 5      n[        X5      nU(       d  [        S5      eUR                  (       a~  UR                  U R                  :w  ad  SU R                   SUR                   S3n[
        R                  U5        U(       a   U(       a   UR                  USSU0S
.U5        [        U5      eU R                   (       a  U(       a  UR"                  (       d  SUl        UR$                  (       a"  UR&                  (       a  UR"                  (       dI  Sn[
        R                  U5        U(       a   U(       a   UR                  USSU0S
.U5        [        U5      eUR(                  (       dX  [
        R                  SUR*                  5        U(       a0  U(       a)   UR                  USSSUR*                   S3S.S
.U5        ggU R,                  S-  n UR/                  5       (       a  [0        R2                  " U5        UR5                  SSS9  US-  n[
        R                  SUR$                  U5        U R                   (       GaÞ  US -  nUR5                  SSS9  US!-  R5                  SSS9  US!-  S"-  R7                  S#S$S%9  US&-  R7                  UR8                  S$S%9  US'-  R7                  S(S$S%9  US)-  R5                  SSS9  US)-  S*-  R7                  S(S$S%9  [:        R<                  " US+5       nUR?                  US!-  S!S,9  UR?                  US&-  S&S,9  UR?                  US'-  S'S,9  UR?                  US)-  S)S,9  SSS5        [=        US-5       nURA                  5       nSSS5        [B        R&                  " 5       nURE                  W5        URG                  5       Ul        [        U5      Ul$        URK                  5       nS.nS/U-   U-   n[L        RO                  US05      n[Q        U[R        [T        5      nURW                  S1S05      RY                  5       Ul        O%[[        U S2S35      n[]        UR$                  UU5          UR_                  5       R`                  nURH                  b+  UURH                  :w  a  [        S5URH                   S6U 35      e[B        R&                  " 5       n[=        US-5       nURA                  S75      =n(       a+  URE                  U5        URA                  S75      =n(       a  M+  SSS5        URG                  5       nUUR&                  :w  a  [        S8UR&                   S9U 35      e[
        R                  S:5        [=        US-5       nURA                  5       nSSS5        U R                   (       a  [c        WUR"                  [T        [d        S;9nO[c        WUR"                  5      nU(       d  [        S<5      e[
        R                  S=5        U Rf                  S?-  nU Rf                  S@-  U Rh                   SA3-  nSn  UR/                  5       (       a  [0        R2                  " U5        URk                  5       (       aC  URm                  5       n U Ro                  5       (       d  U Rf                  U -  Rq                  5       n O%UR/                  5       (       a  URq                  5       n [
        R                  SBU U5        U (       a,  U R/                  5       (       a  [0        Rr                  " U U5        U Rf                  S@-  UR8                  -  n! U!R/                  5       (       a  [0        R2                  " U!5        U!R5                  SSS9  [
        R                  SDU!5        [:        R<                  " USE5       nURu                  U!SF9  SSS5        U!S&-  n"U"Rw                  5       (       d  [        SG5      eU"Ry                  S$S%9R{                  5       n#U#UR8                  :w  a  [        SHUR8                   SIU# SJ35      e[
        R                  SKU#5        UR/                  5       (       a  [0        R2                  " U5        U!SL-  n$U$R7                  SM[|        R~                   SN3S$S%9  U$R�                  SO5        [
        R                  SPU!5        [ƒ        U 5        U R„                  SR-  n%SSn&[†        Rˆ                  R                  ST5      (       a  Sn&O9 [Š        RŒ                  " / SUQSSSV9n'U'RŽ                  R{                  5       SW:X  a  Sn&U[‘        U5      [‘        U5      U Rh                  UR8                  [‘        U5      U R’                  UU&SX.	n( [=        U%SY5       n[”        R–                  " U(U5        SSS5        [
        R                  SZU(5        SSKLn)U)Rš                  Gb  [
        R                  S\5        SU)Rš                  lN        [ž        Rž                  " 5       n*[[        U S]S^5      S_-
  n+U+S_:  a  S3n+[ž        Rž                  " 5       U*-
  U+:  až  U)Rš                  R                      U)Rš                  R¢                   V,s/ sH  n,U,U:w  d  M  U,PM     n-n,SSS5        W-(       d  OJ[
        R                  S`U-5        [ž        R¤                  " Sa5        [ž        Rž                  " 5       U*-
  U+:  a  Mž  [
        R                  Sb5         [§        U!U5        Sdn.[|        R~                  SeU.[‘        U%5      [‘        U Rª                  5      /n/SSn0U&(       a›  [0        R¬                  " Sf5      (       a€  SgU=(       d    Sh Si[M        [ž        Rž                  " 5       5       3n1 [
        R                  SjU15        [Š        R®                  " SfSkU1SlSmSn/U/Q[Š        R°                  [Š        R°                  So9  Sn0U0(       dI   [
        R                  Sq5        [Š        R®                  " U/S[Š        R°                  [Š        R°                  Sr9  St[|        R²                  ;   a;  [
        R                  Su5        U%Rw                  5       (       a  U%R©                  5         gU&(       aD  [
        R                  Sv5         [Š        R®                  " / SwQ5        [|        R´                  " S5        U&(       dc  [
        R                  Sy5         [Š        R®                  " [|        R~                  [‘        US!-  S"-  5      Sz/5        [|        R´                  " S5        gg! [         a!  n	[
        R                  SU	5         Sn	A	GNdSn	A	ff = f! [         a     GN±f = f! [         a     GNf = f! [         a   n	[
        R                  SU	5         Sn	A	gSn	A	ff = f! , (       d  f       G
N\= f! , (       d  f       G
NI= f! [         ay  n	UR/                  5       (       a  [0        R2                  " U5        U(       a4  U(       a-   UR                  USSS4U	 30S
.U5        O! [         a     Of = f[        S4U	 35      eSn	A	ff = f! , (       d  f       G	NF= f! , (       d  f       GNã= f! [         ay  n	UR/                  5       (       a  [0        R2                  " U5        U(       a4  U(       a-   UR                  USSS>U	 30S
.U5        O! [         a     Of = f[        S>U	 35      eSn	A	ff = f! [         ay  n	UR/                  5       (       a  [0        R2                  " U5        U(       a4  U(       a-   UR                  USSSCU	 30S
.U5        O! [         a     Of = f[        SCU	 35      eSn	A	ff = f! , (       d  f       GNÔ= f! [         aÏ  n	UR/                  5       (       a  [0        R2                  " U5        U!R/                  5       (       a  [0        R2                  " U!5        UR/                  5       (       a  [0        R2                  " U5        U(       a4  U(       a-   UR                  USSSQU	 30S
.U5        O! [         a     Of = f[        SQU	 35      eSn	A	ff = f! [         a     GNGf = f! , (       d  f       GNè= f! [         a¤  n	U!R/                  5       (       a  [0        R2                  " U!5        UR/                  5       (       a  [0        R2                  " U5        U(       a4  U(       a-   UR                  USSS[U	 30S
.U5        O! [         a     Of = f[        S[U	 35      eSn	A	ff = fs  sn,f ! , (       d  f       GNÍ= f! [         aÉ  n	U!R/                  5       (       a  [0        R2                  " U!5        UR/                  5       (       a  [0        R2                  " U5        U%Rw                  5       (       a  U%R©                  5         U(       a4  U(       a-   UR                  USSScU	 30S
.U5        O! [         a     Of = f[        ScU	 35      eSn	A	ff = f! [         a!  n	[
        R                  SpU	5         Sn	A	GN�Sn	A	ff = f! [         a!  n	[
        R                  SsU	5         Sn	A	GN_Sn	A	ff = f! [         a#  n	[
        R                  SxU	5        SSn& Sn	A	GNõSn	A	ff = f! [         a  n	[
        R                  S{U	5        U	eSn	A	ff = f)|z!Perform self-update of the agent.NrN   r   é   Újob_idz3Reporting status 'running' to backend for job_id=%sÚrunningÚmessagezUpdate in progress...)ÚstatusÚresultz#Failed to report running status: %s)Úget_api_clientzManifest check returned no infoz'channel mismatch: agent is on channel 'z' but manifest is for channel 'z'; refusing to updateÚfailedrp   rf   z5Manifest missing download_url, checksum, or signaturez!Agent is already up to date (v%s)Ú	succeededTzAgent is up to date (vÚ))ÚsuccessrÈ   z#Failed to report success status: %szwolfpanel-agent-update)ÚparentsÚexist_okzagent.tar.gzz(Downloading update archive from %s to %sÚmock_agent_srcÚsrczmain.pyz‘
import os, sys
flag_file = os.environ.get("WOLFPANEL_UPDATE_FLAG_FILE")
if flag_file:
    with open(flag_file, "w") as f:
        f.write("OK")
zutf-8)ÚencodingÚVERSIONz	README.mdÚmockÚsystemdzwolfpanel-agent.servicezw:gz)ÚarcnameÚrbr&   r'   r%   r$   Údownload_timeouté   zDownload failed: zSize mismatch: expected z bytes, got rµ   zChecksum mismatch: expected z, got zChecksum verified successfully)r4   r5   zDSignature verification failed: release package signature is invalid!z'Release signature verified successfullyzVerification failed: r   r˜   r™   z(Backing up current version from %s to %szFailed to create backup: zExtracting update to %szr:gz)Úpathz*staged package is missing its VERSION filez(package VERSION mismatch: manifest says z but extracted package is z; refusing to activate itz+staged package VERSION matches manifest: %sr±   z#!/usr/bin/env bash
exec z$ "$(dirname "$0")/src/main.py" "$@"
ií  zStaged new version files at %szFailed to stage new files: zupdate_state.jsonFÚINVOCATION_ID)Ú	systemctlz	is-activer±   )Úcapture_outputÚtextÚactive)	rÆ   Ú
backup_dirrª   Úrollback_versionÚupdating_to_versionÚtemp_dirÚapi_urlÚtokenr×   ÚwzWrote update_state.json: %szFailed to write update state: zCSelf-update initiated: pausing new command polling and execution...Úupdate_timeouté<   é
   z0Waiting for other running commands to finish: %sg      ð?z1Swapping current directory path to new version...zFailed to swap symlink: aˆ  
import os, sys, time, json, shutil, urllib.request
from pathlib import Path

state_file_path = sys.argv[1]
timeout = int(sys.argv[2]) if len(sys.argv) > 2 else 60
time.sleep(timeout)

if not os.path.exists(state_file_path):
    sys.exit(0)

try:
    with open(state_file_path, "r") as f:
        state = json.load(f)
except Exception:
    sys.exit(1)

job_id = state.get("job_id")
backup_dir = Path(state.get("backup_dir"))
current_symlink = Path(state.get("current_symlink"))
temp_dir = Path(state.get("temp_dir"))
api_url = state.get("api_url")
token = state.get("token")
use_systemd = state.get("systemd")

print("Timeout/failure detected. Restoring backup...", flush=True)
try:
    if backup_dir.exists():
        if current_symlink.is_symlink():
            current_symlink.unlink()
        elif current_symlink.exists():
            if current_symlink.is_dir():
                shutil.rmtree(current_symlink)
            else:
                current_symlink.unlink()
        
        try:
            os.symlink(backup_dir, current_symlink)
        except Exception:
            shutil.copytree(backup_dir, current_symlink)
except Exception as e:
    print(f"Failed to restore backup: {e}", flush=True)

try:
    if temp_dir.exists():
        shutil.rmtree(temp_dir)
except Exception:
    pass

try:
    os.unlink(state_file_path)
except Exception:
    pass

if api_url and job_id:
    try:
        url = f"{api_url}/api/v1/agent/commands/{job_id}/result"
        headers = {"Content-Type": "application/json", "User-Agent": "wolfpanel-agent"}
        if token:
            headers["X-Agent-Token"] = token
        payload = {"status": "failed", "result": {"error": "new version failed to connect"}}
        req = urllib.request.Request(url, data=json.dumps(payload).encode("utf-8"), headers=headers, method="POST")
        with urllib.request.urlopen(req, timeout=15) as res:
            pass
    except Exception as e:
        print(f"Failed to report failure to backend: {e}", flush=True)

if use_systemd:
    os.system("systemctl restart wolfpanel-agent")
else:
    os.spawnv(os.P_NOWAIT, sys.executable, [sys.executable, str(current_symlink / "src" / "main.py"), "run"])
z-czsystemd-runzwolfpanel-agent-rollback-r   Ú-z;Spawning rollback watcher as independent systemd unit %s...z--unitz	--collectz--quietz--)ÚstdoutÚstderrz+Failed to spawn watcher via systemd-run: %sz-Spawning detached rollback watcher process...)Ústart_new_sessionrí   rî   z$Failed to spawn detached watcher: %sÚpytestz7Running under pytest; skipping reload and process exit.zERunning under systemd. Executing systemctl restart wolfpanel-agent...)rÞ   Úrestartr±   zFFailed to run systemctl restart: %s. Falling back to standalone spawn.z3Running standalone. Spawning new version process...Úrunz*Failed to spawn new standalone process: %s)[r*   Ú
isinstancer   rn   r
   rl   rw   Úpost_command_resultr1   rm   ry   rË   r‚   r   rq   rp   rs   r   r   r   r   r   Ú	cache_dirr‰   rŽ   r�   ÚmkdirÚ
write_textr   Útarfilerº   Úaddr»   r/   r   Ú	hexdigestr   r0   r+   r,   r-   ÚTEST_PRIVATE_KEY_DÚTEST_PUBLIC_KEY_Nr.   Úhexrž   rÃ   r¥   Úst_sizer=   ÚTEST_PUBLIC_KEY_ErŸ   rr   rŠ   r    Úis_absoluteÚresolver�   Ú
extractallÚis_fileÚ	read_textrG   ÚsysÚ
executableÚchmodr¯   Úvar_dirrt   ru   Ú
subprocessrò   rí   r   ræ   ÚjsonÚdumpÚcommand_runnerÚ_worker_managerÚupdatingÚtimeÚlockÚactive_commandsÚsleepr”   r‹   ré   ÚwhichÚPopenÚDEVNULLÚmodulesÚexit)2rx   ÚargsÚkwargsrw   ry   ÚpayloadÚfirstrÆ   rç   r{   rË   Úmsgrå   Útemp_tarÚmock_srcÚtarrÁ   Ú	tar_bytesr   r:   r;   Úpaddedr8   Úsig_intrÚ   Úactual_sizerÂ   Úactual_checksumÚtar_dataÚsig_okrª   râ   r«   Únew_version_dirÚpackage_version_fileÚpackage_versionÚwrapper_pathÚ
state_fileÚuse_systemdÚresÚupdate_stater  Ú
start_waitÚmax_waitÚcidÚother_activeÚwatcher_codeÚwatcher_argvÚwatcher_spawnedÚ	unit_names2                                                     r"   Úself_updater7    s  € à€DØ€JØ€Gä
ˆ4ƒy�Aƒ~Ø�Q‘ˆÜ�eœZ×(Ñ(Ø‰DàˆJä
ˆ4ƒy�Aƒ~Ø�q‘'ˆæ&-ˆW�[‰[˜Ô"°4€FÞ(2Ô˜VÔ$¸€Eö –fð	DÜ�H‰HÐJÈFÔSØ×*Ñ*ØØ$°Ð<SÐ0TÑUØôö ÞÝ1Ù'¨Ó/ˆJÜ$ VÓ,ˆEÜ�VÓ(ˆÞÜÐ=Ó>Ð>ð
 ‡|‡|˜Ÿ™¨×(>Ñ(>Ó>à5°f×6LÑ6LÐ5Mð N,Ø,0¯L©L¨>Ð9NðPð 	ô 	�	‰	�#ŒÞž&ðØ×.Ñ.¨vÀ(ÐW^Ð`cÐVdÑ7eÐglÔmô ˜‹nÐà‡‡ž4¨¯¯Ø)ˆŒà�8�8˜4Ÿ;Ÿ;¨d¯n¯nØEˆÜ�	‰	�#ŒÞž&ðØ×.Ñ.¨vÀ(ÐW^Ð`cÐVdÑ7eÐglÔmô ˜‹nÐð × × Ü�‰Ð4°d·l±lÔCÞž&ðHØ×.Ñ.ØØ*À$ÐUkÐlp×lxÑlxÐkyÐyzÐS{Ñ6|Ñ}Øôñ 	ð ×ÑÐ":Ñ:€Hð@3Ø�?‰?×ÑÜ�MŠM˜(Ô#Ø�‰˜t¨dˆÑ3Ø˜nÑ,ˆä�‰Ð;¸T¿X¹XÀxÔPØ�?�?ˆ?àÐ"2Ñ2ˆHØ�N‰N 4°$ˆNÑ7Ø˜Ñ×$Ñ$¨T¸DÐ$ÑAð ˜Ñ 	Ñ)×5Ñ5ð 7ð ð 6ñ ð ˜	Ñ!×-Ñ-¨d¯k©kÀGÐ-ÑLØ˜Ñ#×/Ñ/°ÀÐ/ÑIØ˜	Ñ!×(Ñ(°ÀÐ(ÑEØ˜	Ñ!Ð$=Ñ=×IÑIÈ&Ð[bÐIÑcä—’˜h¨Ô/°3Ø—‘˜ 5Ñ(°%�Ñ8Ø—‘˜ 9Ñ,°i�Ñ@Ø—‘˜ ;Ñ.¸�ÑDØ—‘˜ 9Ñ,°i�Ñ@÷	 0ô �h Ô%¨ØŸF™F›H�	÷ &ô —^’^Ó%ˆFØ�M‰M˜)Ô$Ø ×*Ñ*Ó,ˆDŒKÜ! )›nˆDŒOð
 !Ÿ-™-›/ˆKØiˆKØ:¸[ÑHÈ;ÑVˆFÜ—‘˜v uÓ-ˆAÜ˜!Ô/Ô1BÓCˆGØ$×-Ñ-¨c°5Ó9×=Ñ=Ó?ˆD�Nä& vÐ/AÀ2ÓFÐÜ! $§(¡(¨HÐ6FÕGð '7Ø—m‘m“o×-Ñ-ˆØ�?‰?Ñ&¨;¸$¿/¹/Ó+IÜÐ6°t·±Ð6GÀ|ÐT_ÐS`ÐaÓbÐbä—’Ó!ˆÜ�(˜DÔ! QØŸ6™6 $›<Ð'�%Õ'Ø—‘˜eÔ$ð Ÿ6™6 $›<Ð'�%×'÷ "ð !×*Ñ*Ó,ˆà˜dŸk™kÓ)ÜÐ:¸4¿;¹;¸-ÀvÈoÐM^Ð_Ó`Ð`Ü�‰Ð1Ô2ô
 �(˜DÔ! QØ—v‘v“xˆH÷ "à�?�?Ü% h°·±ÔBSÔWhÑi‰Fä% h°·±Ó?ˆFÞÜÐbÓcÐcÜ�‰Ð:Ô;ð  —n‘n yÑ0€OØ—‘ *Ñ,°&×2FÑ2FÐ1GÀwÐ/OÑO€Jà€Nð;Ø×Ñ×ÑÜ�MŠM˜*Ô%à×%Ñ%×'Ñ'Ø,×5Ñ5Ó7ˆNØ!×-Ñ-×/Ñ/Ø"(§.¡.°>Ñ"A×!JÑ!JÓ!L�øØ×#Ñ#×%Ñ%Ø,×4Ñ4Ó6ˆNä�‰Ð;¸^ÈZÔXÞ˜n×3Ñ3×5Ñ5Ü�OŠO˜N¨JÔ7ð  —n‘n zÑ1°D·K±KÑ?€Oð5=Ø×!Ñ!×#Ñ#Ü�MŠM˜/Ô*Ø×Ñ d°TÐÑ:ä�‰Ð*¨OÔ<Ü�\Š\˜( FÔ+¨sØ�N‰N ˆNÑ0÷ ,ð  /°Ñ:ÐØ#×+Ñ+×-Ñ-ÜÐHÓIÐIØ.×8Ñ8À'Ð8ÐJ×PÑPÓRˆØ˜dŸk™kÓ)ÜØ:¸4¿;¹;¸-ð H(Ø(7Ð'8Ð8QðSóð ô 	�‰Ð>ÀÔPð �?‰?×ÑÜ�MŠM˜(Ô#à&Ð):Ñ:ˆØ×Ñð %Ü	‡n�nÐð ð!àð 	 ñ 	ð 	×Ñ˜5Ô!Ü�‰Ð1°?ÔCä˜6Ô"ð( —‘Ð"5Ñ5€Jà€KÜ	‡z�z‡~�~�o×&Ñ&Ø‰ð	Ü—.’.Ò!NÐ_cÐjnÑoˆCØ�z‰z×ÑÓ! XÓ-Ø"�ð
 Ü˜*“oÜ˜Ó/Ø"×0Ñ0Ø#Ÿ{™{Ü˜“MØ—>‘>ØØñ
€Lð@Ü�*˜cÔ" aÜ�IŠI�l AÔ&÷ #ä�‰Ð.°Ô=ó" Ø×%Ñ%Ò1Ü�‰ÐVÔWØ26ˆ×&Ñ&Ô/ô —Y’Y“[ˆ
Ü˜6Ð#3°RÓ8¸2Ñ=ˆØ�b‹=ØˆHÜ�iŠi‹k˜JÑ&¨Ó1Ø×/Ñ/×4Ó4Ø/=×/MÑ/M×/]Ò/]ÓoÑ/]¨ÐadÐhnÑan§Ñ/]�Ðo÷ 5æØÜ�H‰HÐGÈÔVÜ�JŠJ�sŒOô �iŠi‹k˜JÑ&¨Õ1ô ‡H�HÐ@ÔAð:Ü °ÔAð(G€LôP —N‘N D¨,¼¸J»ÌÈV×MbÑMbÓIcÐd€LØ€OÞ”v—|’| M×2Ñ2ð 0°×0B¸(Ð/CÀ1ÄSÌÏÊËÓEUÐDVÐWˆ	ð		LÜ�H‰HÐRÐT]Ô^Ü×ÒØ ¨)°[À)ÈTÐaÐT`ÐaÜ!×)Ñ)Ü!×)Ñ)òð
 #ˆOö ð		EÜ�H‰HÐDÔEÜ×ÒØØ"&Ü!×)Ñ)Ü!×)Ñ)ò	ð ”3—;‘;ÓÜ�‰ÐJÔKØ×Ñ×ÑØ×ÑÔØö Ü�‰ÐXÔYð	 Ü×ÒÒHÔIÜ�HŠH�QŒKö
 Ü�‰ÐFÔGð	Ü×ÒœcŸn™n¬c°/ÀEÑ2IÈIÑ2UÓ.VÐX]Ð^Ô_Ü�HŠH�Q�Kð	 øôe ó 	DÜ�K‰KÐ=¸s×CÒCûð	Dûô2 ó Úðûô ó Úðûô ó HÜ—‘ÐAÀ3×GÐGØûðHú÷B 0Ö/ú÷ &Ö%ûô( ó 3Ø�?‰?×ÑÜ�MŠM˜(Ô#Þž&ðØ×.Ñ.ØØ'°GÐ?PÐQTÐPUÐ=VÐ3WÑXØõøô
 ó ÙðúäÐ+¨C¨5Ð1Ó2Ð2ûð3ú÷* "Ö!ú÷ "Ö!ûô ó 7Ø�?‰?×ÑÜ�MŠM˜(Ô#Þž&ðØ×.Ñ.ØØ'°GÐ?TÐUXÐTYÐ=ZÐ3[Ñ\Øõøô
 ó ÙðúäÐ/°¨uÐ5Ó6Ð6ûð7ûôB ó ;Ø�?‰?×ÑÜ�MŠM˜(Ô#Þž&ðØ×.Ñ.ØØ'°GÐ?XÐY\ÐX]Ð=^Ð3_Ñ`Øõøô
 ó ÙðúäÐ3°C°5Ð9Ó:Ð:ûð;ú÷, ,Ö+ûô> ó =Ø�?‰?×ÑÜ�MŠM˜(Ô#Ø×!Ñ!×#Ñ#Ü�MŠM˜/Ô*Ø×Ñ×ÑÜ�MŠM˜*Ô%Þž&ðØ×.Ñ.ØØ'°GÐ?ZÐ[^ÐZ_Ð=`Ð3aÑbØõøô
 ó ÙðúäÐ5°c°UÐ;Ó<Ð<ûð!=ûô: ó 	Úð	ú÷  #Ö"ûô ó @Ø×!Ñ!×#Ñ#Ü�MŠM˜/Ô*Ø×Ñ×ÑÜ�MŠM˜*Ô%Þž&ðØ×.Ñ.ØØ'°GÐ?]Ð^aÐ]bÐ=cÐ3dÑeØõøô
 ó ÙðúäÐ8¸¸Ð>Ó?Ð?ûð@üò8  p÷ 5Ö4ûô ó :Ø×!Ñ!×#Ñ#Ü�MŠM˜/Ô*Ø×Ñ×ÑÜ�MŠM˜*Ô%Ø×Ñ×ÑØ×ÑÔÞž&ðØ×.Ñ.ØØ'°GÐ?WÐX[ÐW\Ð=]Ð3^Ñ_Øõøô
 ó ÙðúäÐ2°3°%Ð8Ó9Ð9ûð!:ûô^ ó 	LÜ�K‰KÐEÀs×KÒKûð	Lûô ó 	EÜ�K‰KÐ>À×DÒDûð	Eûô ó 	 Ü�I‰IÐ^Ð`cÔdØŽKûð	 ûô ó 	Ü�I‰IÐBÀCÔHØˆIûð	úsv  Â.w2 Å$x  Èx1 É3'y Ê,D!z ÏAy/Ðz Ð.zÐ?B=z Ó=$z Ô#A3|= ÖA|×A$|= Ø>|+ÙA5|= Û5C2 àA(AA á,AA	á<DAA ç8AD7 éAE éAEé'AE ìAHì5	AHíAHíAHî:AH" ñAAK8 ò%AAL& õ.AM ö$AAN ÷2
x÷<xøxø 
x.ø-x.ø1
x?ø>x?ù
y,ùy'ù'y,ù/
y>ù9z ú
zúz ú
|ú9|û{3û2|û3
| û=|û?| ü |ü|ü
|(ü#|= ü+
|:ü5|= ü=
 ý9~;þ~þ~;þ
~*þ'~;þ)~*þ*~;þ; ÿ
AAÿ9AAÁ@A@#Á@"AAÁ@#
A@0Á@-AAÁ@/A@0Á@0AAÁAAAÁA	
AAÁAAA ÁA
AD4ÁA%BAD/ÁC5ADÁDAD/ÁD
ADÁDAD/ÁDADÁDAD/ÁD/AD4ÁD7
AEÁEAEÁE
AEÁEAE ÁE
AHÁE$A$AHÁG	AG%ÁG$AHÁG%
AG2ÁG/AHÁG1AG2ÁG2AHÁHAHÁHAHÁH
AHÁH"
AK5ÁH,B	AK0ÁJ6AKÁKAK0ÁK
AKÁKAK0ÁKAKÁKAK0ÁK0AK5ÁK8
AL#ÁLALÁLAL#ÁL&
AMÁL0AMÁMAMÁM
ANÁMAM<ÁM<ANÁN
AN+ÁNAN&ÁN&AN+)
r2   r(   r3   r   r4   r+   r5   r+   Úreturnr   )rK   r   r8  z,tuple[int, int, int, tuple[str, ...] | None])rP   r   r8  ztuple[int, Any])rU   r   rV   r   r8  r+   )rx   r	   ry   r   r8  zUpdateInfo | None)r‘   r   r’   r   )rx   r	   r8  ÚNone)rÛ   )r   r   r½   r   r³   r+   r8  r9  ).Ú__doc__Ú
__future__r   rt   Úrer  r  r
  rŽ   rø   r/   r	  Úpathlibr   Údataclassesr   Útypingr   ry   r   r   rx   r	   Úidentityr
   Úloggerr   rl   r   ÚPUBLIC_KEY_NÚPUBLIC_KEY_Erü   rÿ   rû   r=   ÚcompilerE   rL   rQ   rc   ro   r‚   r”   r¯   rÃ   r7  r   r!   r"   Ú<module>rE     sß   ðñõ #ã 	Û 	Û 
Û Û Û Û Û Û Ý Ý !Ý ç *Ý Ý %Ý á�Ó€ð ÷"ð "ó ð"ð, y	€Ø€ð ~	Ð ØÐ ð ~	Ð ð @LÐVbö ð4 �ZŠZð1ó€
ô+ôôð>  $Ð ô6ôr(ô('KöTõur!   