....................................../////.===Shadow-Here===./////................................................ > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < > < ------------------------------------------------------------------------------------------------------------------- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RIFF¤ WEBPVP8 ˜ ðÑ *ôô>‘HŸK¥¤"§£±¨àð enü¹%½_F‘åè¿2ºQú³íªú`N¿­3ÿƒügµJžaÿ¯ÿ°~¼ÎùnúîÞÖô•òíôÁÉß®Sm¥Ü/ ‡ó˜f£Ùà<˜„xëJ¢Ù€SO3x<ªÔ©4¿+ç¶A`q@Ì“Úñè™ÍÿJÌ´ª-˜ÆtÊÛL]Ïq*‘Ý”ì#ŸÌÏãY]@ê`¿ /ªfkØB4·®£ó z—Üw¥Pxù–ÞLШKÇN¾AkÙTf½è'‰g gÆv›Øuh~ a˜Z— ïj*á¥t d£“uÒ ¨`K˜¹ßþ]b>˜]_ÏÔ6W—è2r4x•íÖ…"ƒÖNîä!¦å Ú}ýxGøÌ —@ ;ÆÚŠ=ɾ1ý8lªË¥ô ^yf®Œ¢u&2©nÙÇ›ñÂñŒ³ aPo['½»øFùà­+4ê“$!lövlüÞ=;N®3ð‚õ›DÉKòÞ>ÄÍ ¥ˆuߤ#ˆ$6ù™¥îЇy’ÍB¼ çxÛ;X"WL£R÷͝*ó-¶Zu}º.s¸sšXqù–DþÿvªhüïwyŸ ¯é³lÀ:KCûÄ£Ëá\…­ ~—ýóî ¼ûûÜTÓüÇy…ŽÆvc»¾×U ñ¸žþоP÷¦ó:Ò¨¨5;Ð#&#ÖúñläÿÁœ GxÉ­/ñ‡áQðìYÉtÒw޼GÔ´zàÒò ð*ëzƒ•4~H]Ø‹f ñÓÈñ`NåWçs'ÆÏW^ø¹!XžµmQ5ÃËoLœÎ: ÞËÍ¥J ù…î èo£ßPÎñ¶ž8.Œ]ʵ~5›ÙË-ù*8ÙÖß±~ ©¹rÓê‚j¶d¸{^Q'˜±Crß ÚH—#¥¥QlÀ×ëã‡DÜ«èî þ&Çæžî;ŽÏºò6ÒLÃXy&ZŒ'j‚¢Ù€IßÚù+–MGi‰*jE€‘JcÜ ÓÌ EÏÚj]o˜ Þr <¾U ûŪæÍ/šÝH¥˜b”¼ ÁñßX GP›ï2›4WŠÏà×£…íÓk†¦H·ÅíMh–*nó÷à]ÁjCº€b7<ب‹¨5車bp2:Á[UªM„QŒçiNMa#<5›áËó¸HýÊ"…×Éw¹¦ì2º–x<›»a±¸3Weü®FÝ⑱ö–î–³|LPÈ~çð~Çå‡|º kD¢µÏàÆAI %1À% ¹Ò – ”ϝS¦‰4&¶£°à Öý”û_Ò Áw°A«Å€?mÇÛgHÉ/8)á¾ÛìáöŽP í¨PŸNÙµº¦‡§Ùš"ÿ«>+ªÕ`Ê÷‡‚ß Õû˜þãÇ-PÍ.¾XV‘€ dÜ"þ4¹ ±Oú‘©t¥¦FªÄÃÄ•b‚znýu½—#cDs˜ÃiÑOˆñ×QO=*IAÊ,¶ŽZƒ;‡wøXè%EÐk:F±Ú” .Ѽ+Áu&Ç`."pÈÉw o&¿dE6‘’EqTuK@Ì¥ã™À(Êk(h‰,H}RÀIXÛš3µ1©_OqÚÒJAñ$ÊÙÜ;D3çŒ[þùœh¬Ã³™ö6ç†NY".Ú‰ï[ªŸŒ '²Ð öø_¨ÂÉ9ué¶³ÒŠõTàîMØ#û¯gN‡bÙ놚X„ö …ÉeüÌ^J ‹€.œ$Æ)βÄeæW#óüßĺŸ€ ÀzwV 9oä»f4V*uB «Ë†¹ì¯žR霓æHXa=&“I4K;¯ç‹h×·"UŠ~<•╪Vêª&ÍSÃÆÅ?ÔqÎ*mTM ˜›µwêd#[C¡©§‘D<©àb†–ÁœøvH/,í:¯( ²£|4-„Æövv„Yͼ™^Á$ˆ„¢Û[6yB.åH*V¨æ?$=˜Ñ€•ñ·­(VlŸ‘ nÀt8W÷´Bûba?q9ú¶Xƒl«ÿ\ù¶’þòUÐj/õ¢Ìµ³g$ƒÎR!¸»|Oߍë’BhîÚÑ¢ñåŒJ„®„£2Ð3•ô02Nt…!£Í]Ïc½Qÿ?ˆ<&ÃA¾Ú,JˆijÌ#5yz„‰Î|ÊŽ5QÏ:‹ÐaóVÔxW—CpeÏzÐïíçôÿÅ_[hãsÐ_/ŽTÝ?BîˆííV$<¿i>²F¬_Eß¿ †bÊŒº­ÿ®Z H“C}”¬,Mp ý/Bá£w>˜YV°aƒúh+cŠ- r/[%|üUMHäQ°X»|û/@|°¥Ð !BÔ Ç¢Ä©š+Õì D«7ìN¶ŽðÔ " ƶ’ÖçtA‰Û×}{tþz­¾GÍ›k¹OEJR$ Â׃ «ëÁ"oÉôž$oUK(Ä)Ãz³Ê-‹êN[Ò3Œñbï8P 4ƒ×q¢bo|?<ÛX¬òÄͰL–±›(™ûG?ýË©ÚÄ–ÂDØÐ_Ç¡ô ¾–ÄÏø ×e8Ë©$ÄF¹Å‹ì[©óìl:F¾f´‹‹Xì²ï®\¬ôùƒ ÿat¥óèÒùHß0äe‚;ü×h:ÆWðHž=Ã8骣"kœ'Y?³}Tûè€>?0l›e1Lòñ„aæKÆw…hÖŠùW…ÈÆÄ0ši·›[pcwËþñiêíY/~-Á5˜!¿†A›™Mÿþ(±“t@â“ö2­´TG5yé]çå僳 .·ÍïçÝ7UÚ±Ð/Nè»,_Ï ùdj7\ï Wì4›„»c¸àešg#ÒÊ⥭áØo5‘?ÌdÝô¯ ¹kzsƒ=´#ëÉK›Ø´±-¥eW?‡çßtòTã…$Ý+qÿ±ƒ÷_3Ô¥í÷:æ–ž<·Ö‡‰Å¢ š‡%Ô—utÌÈìðžgÖÀz²À—ï÷Óîäõ{K'´È÷³yaÏÁjƒô}ž§®æÊydÕÈë5¯èˆõvÕ©ã*çD„ “z„Ó‡^^xÂ3M§A´JG‚öï 3W'ˆ.OvXè¡ÊÕª?5º7†˜(˜Ç¶#çê’¶!ÌdZK§æ 0fãaN]òY³RV ™î$®K2R¨`W!1Ôó\;Ý ýB%qæK•&ÓÈe9È0êI±žeŸß -ú@žQr¦ ö4»M¼Áè¹µmw 9 EÆE_°2ó„ŸXKWÁ×Hóì^´²GѝF©óäR†¦‰ç"V»eØ<3ùd3ÿÚ¤Žú“Gi" —‘_ÙËÎ~Üö¯¥½Î»üŸEÚŽåmÞþí ;ÞólËΦMzA"Âf(´òá;Éï(/7½ûñÌ­cïÕçлþÝz¾-ÍvÑ“pH­–ðÓj$¸Äû¤‚‘ãUBË-n“2åPkS5&‹Â|+g^œ®Ì͆d!OïäîU«c;{Û!ÅŽ«ëZ9Ókóˆ]¯ƒ›né `ÇÒ+tÆš (ØKá¾—=3œ®•vuMñg²\ï Ec€ 05±d™‡×iÇ×›UúvÌ¢£Èþ¡ÕØô¶ßÎA"ß±#Ö²ˆÊŸ¦*Ä~ij|àø.-¼'»Ú¥£h ofº¦‡VsR=N½„Î v˜Z*SÌ{=jÑB‹tê…;’HžH¯8–îDù8ñ¢|Q•bÛçš–‹m³“ê¨ åÏ^m¬Žãþ©ïêO‡½6] µÆ„Ooòü ²x}N¦Ë3ïé¿»€›HA˜m%çÞ/¿í7Fø“‹léUk)É°Œµ8Q8›:ÀŠeT*šõ~ôڝG6 ¢}`ùH­–”¡k ‰P1>š†®9z11!X wKfmÁ¦xÑ,N1Q”–æB¶M…ÒÃv6SMˆhU¬ÊPŽï‘öj=·CŒ¯u¹ƒVIЃsx4’ömÛýcå¡¶7ßŠß 57^\wÒÐÆ k§h,Œý î«q^R½3]J¸ÇðN ‚çU¬ôº^Áì} ³f©Õœ§ˆã:FÄÈ‚é(€™?àýÓüè1Gô£¼éj‚OÅñ  #>×—ßtà 0G¥Åa뀐kßhc™À_ÉñÞ#±)GD" YîäË-ÿÙ̪ ¹™a¯´¢E\ÝÒö‚;™„ë]_ p8‰o¡ñ+^÷ 3‘'dT4œŽ ðVë½° :¬víÑ«£tßÚS-3¶“þ2 †üüʨòrš¹M{É_¤`Û¨0ìjœøJ‡:÷ÃáZ˜†@GP&œÑDGÏs¡þ¦þDGú‘1Yá9Ôþ¼ ûø…§÷8&–ÜÑnÄ_m®^üÆ`;ÉVÁJ£?â€-ßê}suÍ2sõA NÌúA磸‘îÿÚ»ƒìö·á¿±tÑÐ"Tÿü˜[@/äj¬€uüªìù¥Ý˜á8Ý´sõj 8@rˆð äþZÇD®ÿUÏ2ùôõrBzÆÏÞž>Ì™xœ“ wiÎ×7_… ¸ \#€MɁV¶¥üÕÿPÔ9Z‡ø§É8#H:ƒ5ÀÝå9ÍIŒ5åKÙŠ÷qÄ>1AÈøžj"µÂд/ªnÀ qªã}"iŸBå˜ÓÛŽ¦…&ݧ;G@—³b¯“•"´4í¨ôM¨åñC‹ïùÉó¯ÓsSH2Ý@ßáM‡ˆKÀªÛUeø/4\gnm¥‹ŸŒ qÄ b9ÞwÒNÏ_4Ég³ú=܆‚´ •â¥õeíþkjz>éÚyU«Íӝ݃6"8/ø{=Ô¢»G¥ äUw°W«,ô—¿ãㆅү¢³xŠUû™yŒ (øSópÐ 9\åTâ»—*oG$/×ÍT†Y¿1¤Þ¢_‡ ¼ „±ÍçèSaÓ 3ÛMÁBkxs‰’R/¡¤ˆÙçª(*õ„üXÌ´ƒ E§´¬EF"Ù”R/ÐNyÆÂ^°?™6¡œïJ·±$§?º>ÖüœcNÌù¯G ‹ñ2ЁBB„^·úìaz¨k:#¨Æ¨8LÎõލ£^§S&cŒÐU€ü(‡F±Š¼&P>8ÙÁ ‰ p5?0ÊÆƒZl¸aô š¼¡}gÿ¶zÆC²¹¬ÎÖG*HB¡O<º2#ñŒAƒ–¡B˜´É$¥›É:FÀÔx¾u?XÜÏÓvN©RS{2ʈãk9rmP¼Qq̳ è¼ÐFׄ^¡Öì fE“F4A…!ì/…¦Lƒ… … $%´¾yã@CI¬ á—3PþBÏNÿ<ý°4Ü ËÃ#ØÍ~âW«rEñw‹eùMMHß²`¬Öó½íf³:‹k˜¯÷}Z!ã¿<¥,\#öµÀ¯aÒNÆIé,Ћ–lŽ#Àæ9ÀÒS·I’½-Ïp Äz¤Š Â* ­íÄ9­< h>׍3ZkËU¹§˜ŒŠ±f­’¤º³Q ÏB?‹#µíÃ¥®@(Gs«†vI¥Mµ‹Á©e~2ú³ÁP4ìÕi‚²Ê^ö@-DþÓàlÜOÍ]n"µã:žpsŽ¢:! Aõ.ç~ÓBûH÷JCÌ]õVƒd «ú´QÙEA–¯¯Œ!.ˆˆëQ±ù œ·Ì!Õâ )ùL„ÅÀlÚè5@B…o´Æ¸XÓ&Û…O«˜”_#‡ƒ„ûÈt!¤ÁÏ›ÎÝŠ?c9 â\>lÓÁVÄÑ™£eØY]:fÝ–—ù+p{™ðè û³”g±OƒÚSù£áÁÊ„ä,ï7š²G ÕÌBk)~ÑiCµ|h#u¤¶îK¨² #²vݯGãeÖ϶ú…¾múÀ¶þÔñ‚Š9'^($¤§ò “š½{éúp÷J›ušS¹áªCÂubÃH9™D™/ZöØÁ‡¦ÝÙŸ·kð*_”.C‹{áXó€‡c¡c€§/šò/&éš÷,àéJþ‰X›fµ“C¨œ®r¬"kL‰Â_q…Z–.ÉL~O µ›zn‚¹À¦Öª7\àHµšÖ %»ÇníV[¥*Õ;ƒ#½¾HK-ÖIÊdÏEÚ#=o÷Óò³´Š: Ç?{¾+9›–‘OEáU·S€˜j"ÄaÜ ŒÛWt› á–c#a»pÔZÞdŽtWê=9éöÊ¢µ~ ë ;Öe‡Œ®:bî3±ýê¢wà¼îpêñ¹¾4 zc¾ðÖÿzdêŒÑÒŝÀ‰s6¤í³ÎÙB¿OZ”+F¤á‡3@Ñëäg©·Ž ˆèª<ù@É{&S„œÕúÀA)‰h:YÀ5^ÂÓŒ°õäU\ ùËÍû#²?Xe¬tu‰^zÒÔãë¼ÛWtEtû …‚g¶Úüâî*moGè¨7%u!]PhÏd™Ý%Îx: VÒ¦ôÊD3ÀŽKÛËãvÆî…N¯ä>Eró–ð`5 Œ%u5XkñÌ*NU%¶áœÊ:Qÿú»“úzyÏ6å-၇¾ ´ ÒÊ]y žO‘w2Äøæ…H’²f±ÎÇ.ª|¥'gîV•Ü .̘¯€šòü¤U~Ù†*¢!?ò wý,}´°ÔÞnïoKq5µb!áÓ3"vAßH¡³¡·G(ÐÎ0Îò¼MG!/ài®@—¬04*`…«é8ªøøló“ˆÊ”èù¤…ßÊoÿé'ËuÌÖ5×È¡§ˆˆfŽë9}hìâ_!!¯  B&Ëö¶‰ÀAÙNVŸ Wh›¸®XÑJì¨ú“¿÷3uj²˜¨ÍÎìë±aúŠÝå¯ð*Ó¨ôJ“yºØ)m°WýOè68†ŸÏ2—‰Ïüꪫٚ¥‹l1 ø ÏÄFjêµvÌbü¦èÝx:X±¢H=MÐß—,ˆÉÇ´(9ú¾^ÅÚ4¿m‡$âX‘å%(AlZo@½¨UOÌÕ”1ø¸jÎÀÃÃ_ µ‘Ü.œº¦Ut: Æï’!=¯uwû#,“pþÇúŒø(é@?³ü¥‘Mo §—s@Œ#)§ŒùkL}NOÆêA›¸~r½¼ÙA—HJ«eˆÖ´*¡ÓpÌŸö.m<-"³ûÈ$¬_6­åf£ïÚâj1y§ÕJ½@dÞÁr&Í\Z%D£Íñ·AZ Û³øüd/ªAi†/Й~  ‡âĮҮÏh§°b—›Û«mJžòG'[ÈYýŒ¦9psl ýÁ ®±f¦x,‰½tN ‚Xª9 ÙÖH.«Lo0×?͹m¡å†Ѽ+›2ƒF ±Ê8 7Hցϓ²Æ–m9…òŸï]Â1äN†VLâCˆU .ÿ‰Ts +ÅÎx(%¦u]6AF Š ØF鈄‘ |¢¶c±soŒ/t[a¾–û:s·`i햍ê›ËchÈ…8ßÀUÜewŒðNOƒõD%q#éû\9¤x¹&UE×G¥ Í—™$ð E6-‡¼!ýpãÔM˜ Âsìe¯ñµK¢Ç¡ùôléœ4Ö£”À Š®Ðc ^¨À}ÙËŸ§›ºê{ÊuÉC ×Sr€¤’fÉ*j!úÓ’Gsùìoîßîn%ò· àc Wp÷$¨˜)û»H ×8ŽÒ€Zj¤3ÀÙºY'Ql¦py{-6íÔCeiØp‘‡XÊîÆUߢ܂ž£Xé¼Y8þ©ëgñß}é.ÎógÒ„ÃØËø¯»™§Xýy M%@NŠ À(~áÐvu7&•,Ù˜ó€uP‡^^®=_E„jt’ 403WebShell
403Webshell
Server IP : 104.19.154.92  /  Your IP : 216.73.216.47
Web Server : Apache
System : Linux lon12.onrocket.com 4.18.0-513.9.1.lve.el8.x86_64 #1 SMP Mon Dec 4 15:01:22 UTC 2023 x86_64
User : gd5hzp4 ( 1069)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /opt/cloudlinux/venv/lib64/python3.11/site-packages/clwizard/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/cloudlinux/venv/lib64/python3.11/site-packages/clwizard//wizard.py
# coding=utf-8
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2021 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENCE.TXT
#
import json
import os
import sys
import time
import traceback
from typing import Any, Optional, Dict, NoReturn  # NOQA

import psutil

from clcommon import FormattedException
from clcommon.utils import (
    run_command,
    ExternalProgramFailed,
    get_cl_version,
)
from clcommon.utils import get_package_db_errors, is_ubuntu
from clwizard.config import NoSuchModule

from .config import acquire_config_access
from .config import Config  # NOQA
from .modules import run_installation, ALL_MODULES, get_supported_modules
from .constants import (
    WizardStatus,
    ModuleStatus,
    CRASH_LOG_PATH,
    FILE_MARKER_PATH,
    MAIN_LOG_PATH,
)
from .exceptions import CancelModuleException, InstallationFailedException
from .parser import parse_cloudlinux_wizard_opts
from .utils import (
    is_background_process_running,
    run_background,
    setup_logger,
)


class CloudlinuxWizard:
    """Main class for working with Wizard that exposes high level logic."""

    # states in which we can remove the module from queue
    CANCELLABLE_MODULE_STATUSES = [
        ModuleStatus.PENDING,
        ModuleStatus.FAILED,
        ModuleStatus.CANCELLED,
    ]

    # modules states in which wizard modules can be considered as done
    DONE_MODULES_STATUSES = [
        ModuleStatus.INSTALLED,
        ModuleStatus.CANCELLED,
        ModuleStatus.AUTO_SKIPPED,
    ]

    def __init__(self):
        self._opts = None
        self._supported_modules = get_supported_modules()
        self.log = setup_logger("wizard.main", MAIN_LOG_PATH)

    def run(self, argv):
        """
        CL Wizard main function
        :param argv: command line arguments for wizard
        :return: None
        """
        self._opts = parse_cloudlinux_wizard_opts(argv)
        try:
            if self._opts.subparser == "install":
                self._validate_system()
                if self.is_installation_finished() and not self._opts.force:
                    self._print_result_and_exit(
                        result="Installation already finished", exit_code=1
                    )
                self._prepare_for_installation()
                if self._opts.no_async:
                    run_installation()
                else:
                    self.run_background_installation(options=self._opts.json_data)
            elif self._opts.subparser == "status":
                self._validate_system()
                if self._opts.initial:
                    self._get_initial_status()
                else:
                    self._get_modules_statuses()
            elif self._opts.subparser == "cancel":
                self._cancel_module_installation(self._opts.module)
            elif self._opts.subparser == "finish":
                self.create_completion_marker()
            else:
                raise NotImplementedError

            if (
                self._opts.subparser in ["install", "cancel"]
                and self.is_all_modules_installed()
            ) or (
                self._opts.subparser == "finish" and not self.is_all_modules_installed()
            ):
                # Called only once if:
                #  -- in case of an install:   -all modules were installed successfully
                #                              -a module failed during installation,
                #                              but was installed after resuming
                #  -- in case of cancelling:   -a module failed during installation,
                #                              but was canceled by the user and as a result,
                #                              all modules in a 'done' status
                #  -- in case of finish:       -only if user closed the wizard while a module
                #                              had a status other than installed, cancelled or skipped
                self.run_collecting_statistics()
                self.run_cagefs_force_update()

            self._print_result_and_exit()
        except FormattedException as err:
            self.log.error(
                "Got an error while running cloudlinux-wizard, message: '%s'", str(err)
            )
            self._print_result_and_exit(
                result=err.message, context=err.context, details=err.details, exit_code=1
            )
        except InstallationFailedException:
            self._print_result_and_exit(
                result="Module installation failed, see the log for more information",
                exit_code=1,
            )
        except Exception as err:
            self.log.exception("Unknown error in cloudlinux-wizard, %s", str(err))
            self._print_result_and_exit(
                result="Unknown error occured, please, try again "
                "or contact CloudLinux support if it persists.",
                details=traceback.format_exc(),
            )

    @staticmethod
    def is_installation_finished():
        # type: () -> bool
        return os.path.isfile(FILE_MARKER_PATH)

    def create_completion_marker(self):
        # type: () -> None
        try:
            os.mknod(FILE_MARKER_PATH)
            self.log.info("Wizard execution complete")
        except (OSError, IOError) as err:
            self.log.warning(
                "Wizard 'finish' command called more than once, error: '%s'", str(err)
            )
            self._print_result_and_exit(
                result="Wizard 'finish' command called more than once", exit_code=1
            )

    def run_background_installation(self, options=None):
        # type: (Optional[Dict]) -> Optional[None]
        cmd = sys.argv[:]
        cmd.append("--no-async")
        with acquire_config_access() as config:
            # two processes cannot use config at same time
            # so we can safely do check for running process here
            if is_background_process_running():
                self._print_result_and_exit(
                    result="Unable to start a new installation because "
                    "a background task is still working",
                    exit_code=1,
                )
            # the only case when options are None is the 'resume' case
            if options is not None:
                config.set_modules(options)
            # worker will not be able to acquire reading lock
            # and will wait unless we finally close config file
            worker_pid = run_background(cmd).pid
            config.worker_pid = worker_pid
        self._print_result_and_exit(result="success", pid=worker_pid)

    def _validate_system(self):
        """
        Check that wizard supports current system
        """
        if get_cl_version() is None:
            self._print_result_and_exit(
                result="Could not identify the CloudLinux version. "
                "Restart your system. If you have the same problem again - "
                "contact CloudLinux support."
            )

    def _prepare_for_installation(self):
        """
        Prepare the enviroment before performing the installation.
        This function updates the package lists if run on Ubuntu, expires Yum
        cache when running on RHEL-based systems.
        """
        if is_ubuntu():
            cmd = ["apt-get", "-q", "update"]
            try:
                out = run_command(cmd)
                self.log.info("apt-get update output:\n%s", out)
            except ExternalProgramFailed as err:
                self.log.error("Error during apt-get update: '%s'", err, exc_info=err)
        else:
            cmd = ["yum", "-qy", "clean", "expire-cache"]
            try:
                out = run_command(cmd)
                self.log.info("yum clean expire-cache output:\n%s", out)
            except ExternalProgramFailed as err:
                self.log.error("Error during yum clean expire-cache: '%s'", err, exc_info=err)


    def _get_module_log_path(self, module_name):
        """Get path to module log file"""
        return self._supported_modules[module_name].LOG_FILE

    def _get_modules_statuses(self):
        """
        Get information about background worker state
        """
        # we should return modules in order, but config
        # does not know about it, let's sort modules here
        modules = []
        with acquire_config_access() as config:
            state = self._get_wizard_state(config)
            for name in self._supported_modules:
                try:
                    status = config.get_module_status(name)
                    status_time = config.get_module_status_time(name)
                except NoSuchModule:
                    continue
                module_status = {
                    "status": status,
                    "name": name,
                    "status_time": status_time,
                }
                if status in [ModuleStatus.FAILED, ModuleStatus.AUTO_SKIPPED]:
                    module_status["log_file"] = self._get_module_log_path(name)
                modules.append(module_status)
        if state == WizardStatus.CRASHED:
            self._print_result_and_exit(
                wizard_status=state, modules=modules, crash_log=CRASH_LOG_PATH
            )
        self._print_result_and_exit(wizard_status=state, modules=modules)

    def _get_initial_status(self):
        """
        Get initial modules status that is used
        by lvemanager to display wizard pages
        """
        error_message = get_package_db_errors()
        if error_message:
            # package manager DB corrupted
            self._print_result_and_exit(result=error_message)
        else:
            self._print_result_and_exit(
                modules={
                    module_name: cls().initial_status()
                    for module_name, cls in self._supported_modules.items()
                },
                unsuppored_by_cp=list(set(ALL_MODULES) - set(self._supported_modules)),
            )

    def _cancel_module_installation(self, module):
        # type: (str) -> Optional[None]
        """Remove module from queue or print the error if it's not possible"""
        self.log.info("Trying to cancel the installation of module '%s'", module)
        with acquire_config_access() as config:
            status = config.get_module_status(module)
            if status in self.CANCELLABLE_MODULE_STATUSES:
                config.set_module_status(
                    module_name=module, new_state=ModuleStatus.CANCELLED
                )
                self.log.info("Module '%s' installation successfully canceled", module)
            else:
                self.log.warning(
                    "Unable to cancel module '%s' installation, "
                    "because it is in status '%s'",
                    module,
                    status,
                )
                raise CancelModuleException(module, status)

    def run_collecting_statistics(self):
        """
        Collects user`s statistics
        """
        cmd = ["/usr/sbin/cloudlinux-summary", "--send"]
        if not os.environ.get("SYNCHRONOUS_SUMMARY"):
            cmd.append("--async")

        self.log.info("Collecting statistics...")
        try:
            out = run_command(cmd)
            self.log.info("Statistics collection command output: '%s'", out)
        except ExternalProgramFailed as err:
            self.log.error("Error during statistics collection: '%s'", err)

    def is_all_modules_installed(self):
        # type: () -> bool
        """
        Check that all modules were either:
        -- installed
        -- canceled
        -- or auto-skipped
        """
        with acquire_config_access() as config:
            statuses = list(config.statuses.values())
        return all(status in self.DONE_MODULES_STATUSES for status in statuses)

    def run_cagefs_force_update(self):
        """
        Runs cagefsctl --force-update in background
        """
        cagefsctl_bin = "/usr/sbin/cagefsctl"

        if not os.path.isfile(cagefsctl_bin):
            return
        cmd = [cagefsctl_bin, "--force-update", "--wait-lock"]
        self.log.info("Starting cagefs force-update in the background: %s", cmd)
        cagefsctl_proc = run_background(cmd)
        # In Cloudlinux tests environment statistics wait for cagefsctl --force-update terminate
        is_test_environment = bool(os.environ.get("CL_TEST_SYSTEM"))
        if is_test_environment:
            cagefsctl_proc.communicate()

    def _get_wizard_state(self, config):
        # type: (Config) -> str
        # worker pid is None only in the case when wizard
        # wasn't EVER called, this worker pid will stay
        # in config forever, even after wizard is Done
        if config.worker_pid is None:
            return WizardStatus.IDLE

        try:
            psutil.Process(config.worker_pid)
        except psutil.NoSuchProcess:
            # Background process is no longer alive.
            # 1. Wizard DONE: all modules are in state "installed", "cancelled" or "auto-skipped".
            # 2. Wizard FAILED: one of the modules in state "failed" or "cancelled"
            # and no modules are in status "installing"
            # 3. Wizard CRASHED: none of the above.
            statuses = list(config.statuses.values())
            if all(status in self.DONE_MODULES_STATUSES for status in statuses):
                return WizardStatus.DONE
            # cancel module`s status is acceptable for general wizard status FAILED, DO NOT CHANGE IT PLS (LU-1295)
            # An extra check for "installing" status is needed to exclude possible CRASHED wizard status
            if any(
                    status in (ModuleStatus.FAILED, ModuleStatus.CANCELLED)
                    for status in statuses
            ) and not any(status in (ModuleStatus.INSTALLING,) for status in statuses):
                return WizardStatus.FAILED
            return WizardStatus.CRASHED

        return WizardStatus.IN_PROGRESS

    @staticmethod
    def _print_result_and_exit(result="success", exit_code=0, **extra):
        # type: (str, int, **Any) -> NoReturn
        """
        Print data in default format for web and exit
        :param dict extra: extra fields for the response,
                           usually we expect 'context' here
        """
        message = {"result": result, "timestamp": time.time()}
        message.update(extra)
        print(json.dumps(message, indent=2, sort_keys=True))
        sys.exit(exit_code)

Youez - 2016 - github.com/yon3zu
LinuXploit