Mini Shell

Direktori : /sbin/
Upload File :
Current File : //sbin/processpaneluserspackages

#!/opt/cloudlinux/venv/bin/python3 -bb

import os.path
import sys
import fcntl
from subprocess import call
from os.path import isfile, islink

from clcommon.cpapi import panel_hooks_lib, list_all
from clcommon.lib.cledition import skip_without_lve

skip_without_lve()

# compare it with user plan from
CACHE_FILE = "/etc/container/user_plan.cache"
# IF any user differs or does not exist THEN updates user with "lvectl apply USER"
# and write new user plan into CACHE_FILE


_GOVERNOR_PACKAGE_UTILITY_PATH = "/usr/share/lve/dbgovernor/governor_package_limitting.py"

# only one copy of this program is allowed to run at a time,
# so we will lock this script file.
lock_file = open(sys.argv[0], 'r')
try:
    fcntl.flock(lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
    print('Cannot lock script file, probably another copy of process is running.')
    exit(1)


def parse_user_plan_file(user_plan_file):
    """Parse given file with lines like 'user_id plan_name'
    :return dict(user_id = plan_name, ...) """
    plan_info = dict()
    for line in user_plan_file:
        try:
            user_id, plan_name = line.strip().split(None, 1)
            plan_info[user_id] = plan_name
        except ValueError:
            sys.stderr.write("ERROR parsing file. Current line is: %s" % line)
            sys.stderr.write("Valid line format is 'user_id  plan_name'")
    return plan_info


# ----------------------MAIN WORK STARTS HERE----------------------------
# reading actual user plan
new_plan = {str(uid): package for uid, package in list_all().items()}

# assume that normally CACHE_FILE is valid
CACHE_INVALID = False
# reading cache file
if isfile(CACHE_FILE) and not islink(CACHE_FILE):
    cached_user_plan = open(CACHE_FILE, 'r')
    try:
        old_plan = parse_user_plan_file(cached_user_plan)
    except ValueError:
        print("cache file is damaged, and will be rewritten")
        CACHE_INVALID = True
    else:
        # comparing new_plan with old_plan
        for user in new_plan:
            if not old_plan.get(user) or old_plan[user] != new_plan[user]:
                # print 'calling "lvectl apply %s"' % user  # uncomment for logging
                call(['/usr/sbin/lvectl', 'apply', user])
                CACHE_INVALID = True

    if CACHE_INVALID and os.path.exists(_GOVERNOR_PACKAGE_UTILITY_PATH):
        call([_GOVERNOR_PACKAGE_UTILITY_PATH, 'sync'])

else:
    CACHE_INVALID = True

if CACHE_INVALID:
    # leave cache in old format in order to avoid
    # problems during update
    # TODO: change cache format to json some day
    with open(CACHE_FILE, 'w') as cache_file:
        for user, plan in new_plan.items():
            cache_file.write("%s %s\n" % (user, plan))

# Reseller limits support
panel_hooks_lib.call_sync_map()

# Unlock
fcntl.flock(lock_file, fcntl.LOCK_UN)
lock_file.close()
exit(0)

Zerion Mini Shell 1.0