PNG  IHDR pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F@8N ' p @8N@8}' p '#@8N@8N pQ9p!i~}|6-ӪG` VP.@*j>[ K^<֐Z]@8N'KQ<Q(`s" 'hgpKB`R@Dqj '  'P$a ( `D$Na L?u80e J,K˷NI'0eݷ(NI'؀ 2ipIIKp`:O'`ʤxB8Ѥx Ѥx $ $P6 :vRNb 'p,>NB 'P]-->P T+*^h& p '‰a ‰ (ĵt#u33;Nt̵'ޯ; [3W ~]0KH1q@8]O2]3*̧7# *p>us p _6]/}-4|t'|Smx= DoʾM×M_8!)6lq':l7!|4} '\ne t!=hnLn (~Dn\+‰_4k)0e@OhZ`F `.m1} 'vp{F`ON7Srx 'D˸nV`><;yMx!IS钦OM)Ե٥x 'DSD6bS8!" ODz#R >S8!7ّxEh0m$MIPHi$IvS8IN$I p$O8I,sk&I)$IN$Hi$I^Ah.p$MIN$IR8I·N "IF9Ah0m$MIN$IR8IN$I 3jIU;kO$ɳN$+ q.x* tEXtComment

Viewing File: /opt/cloudlinux/venv/lib/python3.11/site-packages/cllimits_validator/ep_nproc_validator.py

# coding: utf-8
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT

from typing import Dict, Optional, Tuple, Union  # NOQA

from cllimitslib_v2 import LimitsDataStorage, DEFAULTS  # NOQA
from cllimitslib_v2.lve_storage import (
    Package, User, Reseller, OWN_SOURCE, RESELLER_SOURCE,  # NOQA
    PACKAGE_SOURCE, GLOBAL_SOURCE
)

from .base import BaseValidator, ENTITY_USER, ENTITY_PACKAGE, ENTITY_RESELLER, ENTITY_DEFAULTS


class EpNprocValidator(BaseValidator):

    def __init__(self, _limits_data_storage=None):
        # type: (LimitsDataStorage) -> None

        super().__init__(_limits_data_storage=_limits_data_storage)

        # difference beetween nproc limit and ep for normal server work
        # see LU-919
        self.diff_nproc_and_ep = 15

    @property
    def message_dict(self):
        # type: () -> Dict

        common_msg = (
            f'NPROC limit must be greater than EP + {self.diff_nproc_and_ep} limit, because '
            'number of processes and threads within LVE includes '
            'also Apache processes/threads, SSH sessions and etc, '
            'which enter into LVE.'
        )

        message_dict = dict(self._message_dict)
        message_dict['common_msg'] = common_msg
        return message_dict

    def _ep_and_nproc_is_valid(self, ep, nproc):
        # type: (int, int) -> bool
        if nproc == 0 or ep == 0:
            result = True
        else:
            result = nproc >= ep + self.diff_nproc_and_ep
        return result

    def _validate_nproc_and_ep_for_user(self, user, ep, nproc, has_input_limits):
        # type: (User, Union[int, None], Union[int, None], bool) -> Tuple[bool, Dict]
        """
        :param has_input_limits: User has input limits, which will be set to it
        """

        message_dict = self.message_dict

        user_limits = self.limits_provider.get_user_limits(user)

        ep = int(ep or user_limits.ep.value)
        nproc = int(nproc or user_limits.nproc.value)

        result = self._ep_and_nproc_is_valid(ep, nproc)

        ep_source = user_limits.ep.source
        nproc_source = user_limits.nproc.source

        if has_input_limits:
            message_dict['affected_entity'] = ENTITY_USER
            message_dict['entity_id'] = user.id
        elif OWN_SOURCE in (nproc_source, ep_source):
            message_dict['affected_entity'] = ENTITY_USER
            message_dict['entity_id'] = user.id
            if ep_source != OWN_SOURCE:
                inheritance_limit = 'ep'
            elif nproc_source != OWN_SOURCE:
                inheritance_limit = 'nproc'
            else:
                inheritance_limit = None
            message_dict['specific_msg'] = None if inheritance_limit is None else (
                f'{inheritance_limit.upper()} is inherited '
                f'from {getattr(user_limits, inheritance_limit).source.capitalize()}'
            )
        elif OWN_SOURCE not in (nproc_source, ep_source) and nproc_source == ep_source:
            message_dict['affected_entity'] = ep_source
            if ep_source == PACKAGE_SOURCE:
                message_dict['entity_id'] = user.package.name
            elif ep_source == RESELLER_SOURCE:
                message_dict['entity_id'] = user.reseller.name
            elif ep_source == GLOBAL_SOURCE:
                message_dict['entity_id'] = ENTITY_DEFAULTS
        elif OWN_SOURCE not in (nproc_source, ep_source) and nproc_source != ep_source:
            message_dict['affected_entity'] = ENTITY_USER
            message_dict['entity_id'] = user.id
            message_dict['specific_msg'] = (
                'Both validated limits (EP, NPROC) inheritance '
                f'from different sources: {ep_source} and {nproc_source}'
            )
        return result, message_dict

    def _validate_nproc_and_ep_for_package(self, package, ep, nproc, has_input_limits):
        # type: (Package, Union[int, None], Union[int, None], bool) -> Tuple[bool, Dict]
        """
        :param has_input_limits: User has input limits, which will be set to it
        """

        message_dict = self.message_dict

        package_limits = self.limits_provider.get_package_limits(package)

        ep = int(ep or package_limits.ep.value)
        nproc = int(nproc or package_limits.nproc.value)

        result = self._ep_and_nproc_is_valid(ep, nproc)

        ep_source = package_limits.ep.source
        nproc_source = package_limits.nproc.source

        if has_input_limits:
            message_dict['affected_entity'] = ENTITY_PACKAGE
            message_dict['entity_id'] = package.name
        elif OWN_SOURCE in (nproc_source, ep_source):
            message_dict['affected_entity'] = ENTITY_PACKAGE
            message_dict['entity_id'] = package.name
            if ep_source != OWN_SOURCE:
                inheritance_limit = 'ep'
            elif nproc_source != OWN_SOURCE:
                inheritance_limit = 'nproc'
            else:
                inheritance_limit = None
            message_dict['specific_msg'] = None if inheritance_limit is None else (
                f'{inheritance_limit.upper()} is inherited '
                f'from {getattr(package_limits, inheritance_limit).source.capitalize()}'
            )
        elif OWN_SOURCE not in (nproc_source, ep_source) and nproc_source == ep_source:
            message_dict['affected_entity'] = ep_source
            if ep_source == RESELLER_SOURCE:
                message_dict['entity_id'] = package.provider.name
            elif ep_source == GLOBAL_SOURCE:
                message_dict['entity_id'] = ENTITY_DEFAULTS
        elif OWN_SOURCE not in (nproc_source, ep_source) and nproc_source != ep_source:
            message_dict['affected_entity'] = ENTITY_PACKAGE
            message_dict['entity_id'] = package.name
            message_dict['specific_msg'] = (
                'Both validated limits (EP, NPROC) inheritance '
                f'from different sources: {ep_source} and {nproc_source}'
            )
        return result, message_dict

    def _validate_nproc_and_ep_for_reseller(self, reseller, ep, nproc, has_input_limits):
        # type: (Reseller, Union[int, None], Union[int, None], bool) -> Tuple[bool, Dict]
        """
        :param has_input_limits: User has input limits, which will be set to it
        """

        message_dict = self.message_dict

        reseller_limits = self.limits_provider.get_reseller_limits(reseller)

        ep = int(ep or reseller_limits.ep.value)
        nproc = int(nproc or reseller_limits.nproc.value)

        result = self._ep_and_nproc_is_valid(ep, nproc)

        ep_source = reseller_limits.ep.source
        nproc_source = reseller_limits.nproc.source

        if has_input_limits:
            message_dict['affected_entity'] = ENTITY_RESELLER
            message_dict['entity_id'] = reseller.name
        elif OWN_SOURCE in (nproc_source, ep_source):
            message_dict['affected_entity'] = ENTITY_RESELLER
            message_dict['entity_id'] = reseller.name
            if ep_source != OWN_SOURCE:
                inheritance_limit = 'ep'
            elif nproc_source != OWN_SOURCE:
                inheritance_limit = 'nproc'
            else:
                inheritance_limit = None
            message_dict['specific_msg'] = None if inheritance_limit is None else (
                f'{inheritance_limit.upper()} is inherited '
                f'from {getattr(reseller_limits, inheritance_limit).source.capitalize()}'
            )

        return result, message_dict

    def _validate_nproc_and_ep_for_defaults(self, reseller, ep, nproc, has_input_limits):
        # type: (Union[Reseller, DEFAULTS], Union[int, None], Union[int, None], bool) -> Tuple[bool, Dict]
        """
        :param has_input_limits: User has input limits, which will be set to it
        """

        message_dict = self.message_dict

        id_entity = reseller.name if isinstance(reseller, Reseller) else DEFAULTS

        default_limits = self.limits_provider.get_defaults_limits(reseller)

        ep = int(ep or default_limits.ep.value)
        nproc = int(nproc or default_limits.nproc.value)

        result = self._ep_and_nproc_is_valid(ep, nproc)

        ep_source = default_limits.ep.source
        nproc_source = default_limits.nproc.source

        if has_input_limits:
            message_dict['affected_entity'] = ENTITY_DEFAULTS
            message_dict['entity_id'] = id_entity
        elif OWN_SOURCE in (nproc_source, ep_source):
            message_dict['affected_entity'] = ENTITY_DEFAULTS
            message_dict['entity_id'] = id_entity
            if ep_source != OWN_SOURCE:
                inheritance_limit = 'ep'
            elif nproc_source != OWN_SOURCE:
                inheritance_limit = 'nproc'
            else:
                inheritance_limit = None
            message_dict['specific_msg'] = None if inheritance_limit is None else (
                f'{inheritance_limit.upper()} is inherited '
                f'from {getattr(default_limits, inheritance_limit).source.capitalize()}'
            )

        return result, message_dict

    def _validate(self, validated_entity, ep, nproc, has_input_limits, check_reseller_defaults=False):
        # type: (Union[User, Reseller, Package, None], Optional[int], Optional[int], bool, bool) -> Tuple[bool, Dict]

        message_dict = self.message_dict
        result = True

        if isinstance(validated_entity, User):
            result, message_dict = self._validate_nproc_and_ep_for_user(
                validated_entity,
                ep,
                nproc,
                has_input_limits
            )
        elif isinstance(validated_entity, Package):
            result, message_dict = self._validate_nproc_and_ep_for_package(
                validated_entity,
                ep,
                nproc,
                has_input_limits
            )
        elif isinstance(validated_entity, Reseller) and not check_reseller_defaults:
            # we validate reseller limits
            result, message_dict = self._validate_nproc_and_ep_for_reseller(
                validated_entity,
                ep,
                nproc,
                has_input_limits
            )
        elif isinstance(validated_entity, Reseller) and check_reseller_defaults or validated_entity == DEFAULTS:
            # we validate default limits (include reseller defaults)
            result, message_dict = self._validate_nproc_and_ep_for_defaults(
                validated_entity,
                ep,
                nproc,
                has_input_limits
            )

        return result, message_dict

    def validate_existing_limits(self, validated_entity, check_reseller_defaults=False):
        # type: (Union[User, Reseller, Package, None], bool) -> Tuple[bool, Dict]
        """
        Validate limits which already are recorded in ve.cfg
        """

        result, message_dict = self._validate(validated_entity, None, None, False, check_reseller_defaults)

        return result, message_dict

    def validate_input_limits(self, validated_entity, input_limits, check_reseller_defaults=False):
        # type: (Union[User, Reseller, Package, None], Dict, bool) -> Tuple[bool, Dict]
        """
        Validate limits which we want to set
        """

        message_dict = self.message_dict

        nproc = input_limits.get('nproc', None)
        ep = input_limits.get('ep', None)
        # if input_limits has no ep and nproc we set has_settable_limits to None
        # It means nothing to validate
        has_input_limits = nproc is not None or ep is not None

        # We skip check if nproc is unlimited or input limits don't have ep and nproc values
        if nproc == 0 or not has_input_limits:
            result = True
        else:
            result, message_dict = self._validate(validated_entity, ep, nproc,
                                                  has_input_limits, check_reseller_defaults)

        return result, message_dict
Back to Directory=ceiIENDB`