§ À•¿j¼Eãóˆ—dZddlZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z m Z ddl mZddlmZejZdZd Zd Zd Zd Zd Zejd¦«ZdZdZdZdZdZdZ dZ!dZ"dZ#e$¦«Z%dZ&Gd„de$¦«Z'efd„Z(efd„Z)d„Z*d'd„Z+dZ,dZ-dZ.d(d„Z/ d)d!„Z0d"„Z1e d#„¦«Z2d$„Z3d%„Z4d*d&„Z5dS)+ašRoot-side orchestration of the install-time delivery. Design: docs/design/nodejs-bun-delivery.md. Same shape as the pnpm delivery hook: `cloudlinux-selector install-modules --user ` is invoked by the panel as root and would normally re-exec the whole selector inside the account's CageFS. The delivery replaces that single descent with three steps driven from the root side that is already there: 1. cagefs_enter_user -> bun_user_phase resolve (user, no package code) 2. root -> cloudlinux-bun-delivery (stage as root; rebuild through CageFS as user; commit or roll back) There is no user->root bridge: inside a cage there is not even a sudo binary. A qualifying enabled request reports a failed delivery if any phase fails; it does not silently proceed with the ordinary npm path. éN)Úcontextmanager)Ú_terminate_process_groupÚrun_process_in_cagefs)Úclselectctlnodejsuseré)Únode_modules_storagez/opt/cl-bun/bunz-/usr/share/l.v.e-manager/utils/bun_user_phasez9/usr/share/l.v.e-manager/utils/cloudlinux-bun-delivery.pyz/usr/sbin/cloudlinux-selectoréxi„z ^[0-9]{1,3}$éz!cl-bun:unsupported-npm-shrinkwrapzcl-bun:unsupported-manifest)ÚpatchedDependenciesÚ workspacesÚsymlinkzcl-bun:legacy-package-lock-v1zcl-bun:no-dependencieszPShared node_modules Store unavailable: cannot determine Node.js Selector supportcó—eZdZd„Zd„ZeZdS)Ú_UserPhaseResultcó0—||_||_||_dS©N)ÚfailedÚ returncodeÚoutput)Úselfrrrs úS/opt/cloudlinux/venv/lib64/python3.11/site-packages/clselector/bun_delivery_hook.pyÚ__init__z_UserPhaseResult.__init__Fs€ØˆŒ Ø$ˆŒØˆŒ ˆ ˆ ócó—|j Sr)r)rs rÚ__bool__z_UserPhaseResult.__bool__Ks €Ø”;ˆÐrN)Ú__name__Ú __module__Ú __qualname__rrÚ __nonzero__©rrrrEs3€€€€€ðððð ððð€K€K€Krrcó`—tj|¦«}|dotj¦«S)zBThe global administrator switch fails closed on bad configuration.Úenabled)rÚ read_configÚnodejs_selector_supported)Ú config_pathÚconfigs rÚ is_enabledr&Qs2€å !Ô -¨kÑ :Ô :€FØ �9Ô ð AÝ$Ô>Ñ@Ô@ðBrcó|—||krdS| d¦«sdS| d¦«s| d¦«rdS| d¦«}|r-|tj|¦« d¦«pgvrdS| d¦«r| d¦«sdSdS) amOnly a bare `install-modules` for a Node.js application qualifies. Named modules and requirements files change package.json first, which is the plain npm path's job. An account outside the administrator's include/exclude lists takes that path too -- a policy narrowing, not a failure, so it is silent by design where a failed delivery is loud. Fzinstall-modulesz --modulesz--requirements-fileú--userÚexcluded_usersú --app-rootT)Úgetrr")ÚoptsÚ interpreterÚnodejs_interpreterr$Úusers rÚis_deliverabler0Xsâ€ðÐ(Ò(Ð(؈uØ �8Š8Ð%Ñ &Ô &ð؈uØ ‡x‚x� ÑÔð §¢Ð)>Ñ ?Ô ?ð؈uØ �8Š8�HÑ Ô €Dð  ð�Õ-Ô9Ø ñôßšÐ-Ñ.Ô.ð5Ø24ð6ð6àˆuØ �8Š8�HÑ Ô ð T§X¢X¨lÑ%;Ô%;ð؈uØ ˆ4rcó‚—ddlm} |¦« ||¦«}n#t$rYdSwxYwt |t ¦«sdS| d¦«}t |t¦«sdS| d¦«d}t  |¦«rt|¦«ndS)a´The Node.js major the selector recorded for this application, or None when there is no usable record. This is the authority on which `~/nodevenv//` an install belongs to. A version change creates the new venv beside the old one and never removes the old (`selectorlib._change_version`), so a directory listing has two answers for any application whose version was ever changed; the record has one. The selector already reads this file as root through `secureio`, so nothing new crosses the boundary here. Imported lazily: the storage module is imported inside every cage on each `npm install`, and the apps manager pulls in the panel API. r)ÚApplicationsManagerNÚnodejs_versionú.) Ú$clselect.clselectnodejs.apps_managerr2Úget_app_configÚ ExceptionÚ isinstanceÚdictr+ÚstrÚsplitÚ _ASCII_DIGITSÚmatchÚint)r/Úapp_rootr2r%ÚversionÚmajors rÚrecorded_node_majorrBssÙ€ðIÐHÐHÐHÐHÐHðØ$Ð$Ñ&Ô&×5Ò5°d¸HÑEÔEˆˆøÝ ððð؈tˆtðøøøå �f�dÑ #Ô #ð؈tØ�jŠjÐ)Ñ*Ô*€GÝ �g�sÑ #Ô #ð؈tð �MŠM˜#Ñ Ô ˜qÔ !€EÝ&×,Ò,¨UÑ3Ô3Ð =�3ˆu‰:Œ:ˆ:¸Ð=s ˆ'§ 5´5có†— tj|¦«j}n!#t$rt ddd¦«cYSwxYw||g}|�"| t |¦«¦«t|t|d|it¬¦«}t |d|  d¦«|  dd¦«¦«S) zÃRun one account-side phase in the cage. `major` names the venv when the selector has a record; npm_wrapper's path carries the same fact in `CL_VIRTUAL_ENV`, which this path does not have.TNÚÚHOME)Úenv_varsÚtimeoutrrr) ÚpwdÚgetpwnamÚpw_dirÚKeyErrorrÚappendr:rÚUSER_PHASE_BINÚUSER_PHASE_TIMEOUTr+)r/Úphaser?rAÚhomeÚargsÚresults rÚ _user_phaserS‘sÔ€ð0ÝŒ|˜DÑ!Ô!Ô(ˆˆøÝ ð0ð0ð0Ý  d¨BÑ/Ô/Ð/Ð/Ð/ð0øøøà �8Ð €DØ ÐØ � Š •C˜‘J”JÑÔÐÝ "Ø �n˜d¨f°d¨^Ý"ð$ñ$ô$€Fõ ˜F 8Ô,¨f¯jªj¸Ñ.FÔ.FØ"ŸJšJ x°Ñ4Ô4ñ 6ô 6ð6s ‚œ:¹:ééécóø— tdd|d|g}|�$| dt|¦«g¦«|�$| dt|¦«g¦«tj|tjtj|€dn|f¬¦«}n#ttjf$rYd SwxYw|j   d d ¦«  ¦«  ¦«}|j |r|d nd fS)zv(returncode, last stdout line) of the privileged delivery, or (None, '') when the subprocess could not run at all.Údeliverr(r*Nz --node-majorz --lock-fdr)ÚstdoutÚstderrÚpass_fds)NrDzutf-8ÚreplaceéÿÿÿÿrD)Ú DELIVERY_CLIÚextendr:Ú subprocessÚrunÚPIPEÚSTDOUTÚOSErrorÚSubprocessErrorrYÚdecodeÚstripÚ splitlinesr)r/r?rAÚlock_fdÚcommandÚprocÚliness rÚ _root_phasermªs€ð Ý ¨H°d¸LÈ(ÐSˆØ Ð Ø �NŠN˜N­C°©J¬JÐ7Ñ 8Ô 8Ð 8Ø Ð Ø �NŠN˜K­¨W©¬Ð6Ñ 7Ô 7Ð 7õŒ~Ø Ý”?­:Ô+<Ø"˜?�R�R°° ð<ñ<ô<ˆˆøõ •ZÔ/Ð 0ððð؈xˆxðøøøà ŒK× Ò ˜w¨ Ñ 2Ô 2× 8Ò 8Ñ :Ô :× EÒ EÑ GÔ G€EØ Œ?¨Ð6˜E "œI˜I°BÐ 6Ð6s‚B B  B'Â&B'Fc ó*‡‡‡ —dŠ ˆˆ ˆfd„}|rt‰‰¦«S tj¦«}tj ‰‰| ‰¦«¦«}n!#t $rt‰‰¦«YdSwxYw|dtjkrt‰‰¦«S tj|d|d|tj dd|||¬¦ « n/#t $r"‰ s |¦«n#t$rYnwxYwYdSwxYwdS)z>Run the same restart and pre/post health check as npm install.FcóJ•—dŠt‰‰¦«std¦«‚dS)NTzselector restart failed)Ú_selector_restartÚ RuntimeError)r?Úrestart_attemptedr/s€€€rÚrestartz%_restart_application..restartÅs/ø€à ÐÝ   xÑ0Ô0ð :ÝÐ8Ñ9Ô9Ð 9؈trÚ app_statusÚdomainÚapp_uriT) ruÚaliasÚactionÚrequest_timeoutÚretry_on_timeoutÚ strict_statusÚbaselineÚpost_action_observationsÚpost_action_interval) rpÚ nodejs_userr2ÚutilsÚget_using_realpath_keysÚget_user_config_datar7ÚAPP_STARTED_CONSTÚcheck_response_from_webappÚWEBAPP_REQUEST_TIMEOUTrq) r/r?Úskip_web_checkÚhealth_baseliner}r~rsÚappsr%rrs `` @rÚ_restart_applicationr‰¿s•øøø€ðÐðððððððð ð1Ý   xÑ0Ô0Ð0ð ÝÔ.Ñ0Ô0ˆÝÔ"×:Ò:Ø �(˜D×5Ò5°dÑ;Ô;ñ=ô=ˆˆøå ðððõ ˜$ Ñ)Ô)Ð)؈uˆuð øøøð ˆlÔ�{Ô<Ò<Ð<Ý   xÑ0Ô0Ð0ðÝÔ.ؘ(Ô#¨6°)Ô+<ÀWÝ'Ô>Ø!°Ø$Ø%=Ø!5ð  7ñ 7ô 7ð 7ð 7øõ ð ð ð ð !ð ð Ø�‘ ” � � øÝð ð ð Ø�ð øøøàˆuˆuð øøøð ˆ4sH AA(Á(BÂBÂ03C$Ã$ DÃ1 C<Ã;DÃ< D ÄDÄD Ä DÄDc óv— tjtddddd|d|g tjtjd¬¦«}n#t $rYd SwxYw | t¬ ¦«nE#tj$rt|¦«Yd Stj $rt|¦«Yd SwxYw|j d kS) zERestart through the selector so its established path validation runs.rsz--jsonz --interpreterÚnodejsr(r*T)rYrZÚstart_new_sessionF)rGr) r`ÚPopenÚ SELECTOR_BINrbrcrdÚ communicateÚRESTART_TIMEOUTÚTimeoutExpiredrrer)r/r?rks rrprpïsõ€ðÝÔÝ ˜9 h°ÀØ �t˜\¨8ð 5å”?­:Ô+<Ø"ð $ñ$ô$ˆˆøõ ððð؈uˆuðøøøðØ ×Ò¥ÐÑ1Ô1Ð1Ð1øÝ Ô $ðððÝ  Ñ&Ô&Ð&؈uˆuÝ Ô %ðððÝ  Ñ&Ô&Ð&؈uˆuðøøøð Œ?˜aÒ Ðs'‚:=½ A Á A ÁA+Á+B- B-Â,B-c#óRK—|r| d¦«ng}|r8tj |¦«st d„|D¦«¦«rt d¦«‚t j|¦«}tj|j tj tj ztj z¦«} dg|zD]˜}tj|tj tj ztj z|¬¦«}tj |¦«j|jkr#tj|¦«t d¦«‚tj|¦«|}Œ™d}d} tjd tjtj z|¬¦«}n÷#t $rê} | jt$jkr‚ tjd tjtjztjztj zd |¬¦«}d }tj||j|j¦«d}n[#t $rN} | jt$jkr‚tjd tjtj z|¬¦«}Yd} ~ nd} ~ wwxYwYd} ~ nd} ~ wwxYwtj |¦«} t3j| j¦«r| j|jkrt d ¦«‚t9j|t8jt8jz¦«nJ#t@$r=|�9|rtC|d |¦« tj|¦«n#t $rYnwxYw‚wxYw |V—tj|¦«n#tj|¦«wxYw tj|¦«dS#tj|¦«wxYw) z@Open the selector lock with no symlink traversal for all phases.ú/c3óK—|]}|dvV—Œ dS))rDr4z..Nr)Ú.0Úparts rú z"_panel_app_lock.. s'èè€Ð=Ð=¨t�4˜?Ð*Ð=Ð=Ð=Ð=Ð=Ð=rz application lock path is invalidÚnodevenv©Údir_fdz*application directory is not account-ownedNFz.locki¤Tz%application lock is not account-owned)"r;ÚosÚpathÚisabsÚanyrdrHrIÚopenrJÚO_RDONLYÚ O_DIRECTORYÚ O_NOFOLLOWÚfstatÚst_uidÚpw_uidÚcloseÚO_RDWRÚerrnoÚENOENTÚO_CREATÚO_EXCLÚfchownÚpw_gidÚEEXISTÚstatÚS_ISREGÚst_modeÚfcntlÚflockÚLOCK_EXÚLOCK_NBr7Ú_unlink_same_inode) r/r?ÚpartsÚaccountÚcurrentÚnameÚchildriÚcreatedÚexcÚ create_excÚinfos rÚ_panel_app_lockrÀs§èè€ð$,Ð 3ˆH�NŠN˜3Ñ Ô Ð °€EØ ð:•R”W—]’] 8Ñ,Ô,ð:ÝÐ=Ð=°uÐ=Ñ=Ô=Ñ=Ô=ð:åÐ8Ñ9Ô9Ð9ÝŒl˜4Ñ Ô €GÝŒg�g”n¥b¤kµB´NÑ&BÅRÄ]Ñ&RÑSÔS€Gð2ð �L 5Ñ(ð ð ˆDÝ”G˜D¥"¤+µ´Ñ">ÅÄÑ"NØ#*ð,ñ,ô,ˆEåŒx˜‰ŒÔ%¨¬Ò7Ð7Ý”˜‘”�ÝÐJÑKÔKÐKÝ ŒH�WÑ Ô Ð ØˆGˆG؈؈ð ð ZÝœ' '­2¬9µr´}Ñ+DÈWÐUÑUÔU��øÝð Zð Zð ZØ”9¥¤ Ò,Ð,Øð ZÝ œg g­r¬y½2¼:Ñ/EÍÌ Ñ/QÕTVÔTaÑ/aØ&+°Gð=ñ=ô=�Gà"�GÝ”I˜g w¤~°w´~ÑFÔFÐFð$�G�GøÝðZðZðZØ!Ô'­5¬<Ò7Ð7ØÝ œg g­r¬y½2¼=Ñ/HÐQXÐYÑYÔY�G�G�G�G�G�GøøøøðZøøøøøøøøøøøøð Zøøøõ ”8˜GÑ$Ô$ˆDÝ”< ¤ Ñ-Ô-ð G°´ÀÄÒ1NÐ1NÝÐEÑFÔFÐFÝ ŒK˜¥¤µ´Ñ!>Ñ ?Ô ?Ð ?Ð ?øÝð ð ð ØÐ"ØðBÝ& w°¸ÑAÔAÐAðÝ”H˜WÑ%Ô%Ð%Ð%øÝðððØ�Dðøøøà ð øøøð ؈MˆMˆMå ŒH�WÑ Ô Ð Ð ø�BŒH�WÑ Ô Ð Ð øøøÐ å Œ�ÑÔÐÐÐø�Œ�ÑÔÐÐøøøs²Â8B#NÅ.F Æ K<Æ JÆI;Æ-A-HÈI;È I3È%AI.É)I;É.I3É3I;É6K<É;JÊA;K<Ë;NË<MÌL1Ì0MÌ1 L>Ì;MÌ=L>Ì>MÍNÍM Í NÍ M6Í6NÎN&cóì— tj|¦«}tj||d¬¦«}|j|jf|j|jfkrtj||¬¦«dSdS#t $rYdSwxYw)zCBest-effort removal of exactly the entry created by this operation.F)ršÚfollow_symlinksr™N)r›r£r¯Úst_devÚst_inoÚunlinkrd)Ú parent_fdrºÚfdÚpinnedr¹s rr¶r¶Bs�€ð Ý”˜"‘”ˆÝ”'˜$ yÀ%ÐHÑHÔHˆØ ŒM˜6œ=Ð )¨g¬n¸g¼nÐ-MÒ MÐ MÝ ŒI�d 9Ð -Ñ -Ô -Ð -Ð -Ð -ð NÐ Møå ð ð ð Ø ˆˆð øøøs‚AA%Á% A3Á2A3cóþ—t|dd¦«tkrdSt|dd¦« ¦«}t|¦«dks|dtkrdS|dt vr|dndS)zÊThe manifest field the account phase refused, or None. Only a known field name is repeated: the rest of that phase's stdout is account-controlled text and must not reach the panel message. rNrrDérr)ÚgetattrÚUNSUPPORTED_MANIFEST_RCr;ÚlenÚUNSUPPORTED_MANIFEST_SENTINELÚUNSUPPORTED_MANIFEST_FIELDS)Úresolvedr·s rÚ_unsupported_manifest_fieldrÑMs~€õ ˆx˜ tÑ,Ô,Õ0GÒGÐG؈tÝ �H˜h¨Ñ +Ô +× 1Ò 1Ñ 3Ô 3€EÝ ˆ5�z„z�Q‚€˜% œ(Õ&CÒCÐC؈tؘQ”xÕ#>Ð>Ð>ˆ5�Œ8ˆ8ÀDÐHrcóB—tj¦«s tjSt||¦«} t ||¦«5}t |d||¦«}|�st |dd¦«tkr-t |dd¦«tkrtcddd¦«St |dd¦«tkr-t |dd¦«tkrtcddd¦«St |dd¦«tkr-t |dd¦«tkrtcddd¦«St|¦«�tcddd¦«S ddd¦«dSt||||¦«\}}|t kr|rd|zcddd¦«S|t"kr|rd|zcddd¦«S|t$kr ddd¦«dS|d kr ddd¦«d S ddd¦«n #1swxYwYn#t&t(f$rYd SwxYwt+|||¬ ¦«sd SdS)a[Run the phases. Returns None on success, or a message naming the phase that failed. The caller reports the message and fails the install rather than quietly running npm. The privileged phase retains the previous tree until the account-side rebuild and marker commit succeed. Any failure restores that exact previous tree. ÚresolverNrrDz(bun delivery failed in the resolve phasezbun delivery refused: %sz@bun delivery failed in the rebuild phase; previous tree restoredrzUbun delivery failed in the privileged phase; see /var/log/cloudlinux/bun-delivery.logz2bun delivery failed acquiring the application lock)r†z(bun delivery failed in the restart phase)rÚengine_availableÚENGINE_UNAVAILABLErBrÀrSrËÚLEGACY_PACKAGE_LOCK_RCÚLEGACY_PACKAGE_LOCK_SENTINELÚCLASSIC_NPM_FALLBACKÚSHRINKWRAP_UNSUPPORTED_RCÚSHRINKWRAP_UNSUPPORTED_SENTINELÚNO_DEPENDENCIES_RCÚNO_DEPENDENCIES_SENTINELrÑrmÚREGISTRY_REFUSED_RCÚUNSUPPORTED_SOURCE_RCÚREBUILD_FAILED_RCrdrKr‰)r/r?r†rArirÐrÚdetails rÚdeliver_modulesrá[s €õ Ô 0Ñ 2Ô 2ð7Ý#Ô6Ð6Ý   hÑ /Ô /€Eð(DÝ ˜T 8Ñ ,Ô ,ð% @°Ý" 4¨°H¸eÑDÔDˆHØñ BݘH l°DÑ9Ô9Õ=SÒSÐSÝ# H¨h¸Ñ;Ô;Ý7ò8ð8å/ð % @ð% @ð% @ð% @ñ% @ô% @ð% @ð% @õ˜H l°DÑ9Ô9Õ=VÒVÐVÝ# H¨h¸Ñ;Ô;Ý:ò;ð;õ 0ð% @ð% @ð% @ð% @ñ% @ô% @ð% @ð% @õ˜H l°DÑ9Ô9Õ=OÒOÐOÝ# H¨h¸Ñ;Ô;Ý3ò4ð4õ 0ð+% @ð% @ð% @ð% @ñ% @ô% @ð% @ð% @õ,/¨xÑ8Ô8ÐDõ0ð5% @ð% @ð% @ð% @ñ% @ô% @ð% @ð% @ð6Bð7% @ð% @ð% @ñ% @ô% @ð% @ð% @ð% @õ8"-¨T°8¸UÀGÑ!LÔ!LÑ ˆJ˜ØÕ0Ò0Ð0°VÐ0Ø1°FÑ:ð=% @ð% @ð% @ð% @ñ% @ô% @ð% @ð% @ð>Õ2Ò2Ð2°vÐ2Ø1°FÑ:ðA% @ð% @ð% @ð% @ñ% @ô% @ð% @ð% @ðBÕ.Ò.Ð.ØYðE% @ð% @ð% @ñ% @ô% @ð% @ð% @ð% @ðF˜QŠˆð?ðI% @ð% @ð% @ñ% @ô% @ð% @ð% @ð% @ðFðG% @ð% @ð% @ñ% @ô% @ð% @ð% @ð% @ð% @ð% @ð% @øøøð% @ð% @ð% @ð% @øøõL •XÐ ðDðDðDØCÐCÐCðDøøøõ   h¸~Ð NÑ NÔ Nð:Ø9Ð9Ø ˆ4sœ±G3ÁAG' G3Â:G'à G3Ã%:G'Ä G3Ä,G'Å G3ÅG'Å G3Å&G'Æ G3ÆG'Æ G3Æ- G'Æ9 G3ÇG'Ç G3Ç G3Ç'G+Ç+G3Ç.G+Ç/G3Ç3HÈHr)NN)FNrr)F)6Ú__doc__r›rHÚrer`r¨r²r¯Ú contextlibrÚclselect.utilsrrÚclselectrrrDrÚ CONFIG_PATHÚBUN_BINrMr^rŽr�rNÚcompiler<rÙrÚrÌrÎrÏrÖr×rÛrÜÚobjectrØÚCAPABILITY_UNAVAILABLErr&r0rBrSrÝrÞrßrmr‰rprÀr¶rÑrárrrúrìsaðððð( € € € Ø € € € Ø € € € ØÐÐÐØ € € € Ø € € € Ø € € € Ø%Ð%Ð%Ð%Ð%Ð%àJÐJÐJÐJÐJÐJÐJÐJØ9Ð9Ð9Ð9Ð9Ð9Ø"Ð"Ð"Ð"Ð"Ð"à"Ô.€ Ø €Ø@€ØJ€ Ø.€ Ø€ØÐØ�” ˜?Ñ+Ô+€ ðÐØ"EÐØÐØ =ÐðOÐØÐØ>ÐðÐØ3ÐØ�v‘x”xÐð?Ðð ð ð ð ð �vñ ô ð ð'ðBðBðBðBðGRððððð6>ð>ð>ð<6ð6ð6ð6ð(ÐØÐØÐð7ð7ð7ð7ð*9>ØHIØ./ð-ð-ð-ð-ð` ð ð ð*ð:ð:ñ„ð:ðz ð ð ð Ið Ið Ið:ð:ð:ð:ð:ð:r