Server IP : 184.154.167.98 / Your IP : 3.144.117.19 Web Server : Apache System : Linux pink.dnsnetservice.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 User : puertode ( 1767) PHP Version : 8.2.26 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/share/l.v.e-manager/utils/ |
Upload File : |
#!/opt/cloudlinux/venv/bin/python3 -sbb # 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 # for details see LVEMAN-622: Create autorestore quota limits after 1.0-9.9 update from __future__ import print_function from __future__ import division from __future__ import absolute_import from future.utils import iteritems import glob import gzip import os import sys import shutil import subprocess import time UPDATE_USER = "/scripts/modcpuser" UPDATE_QUOTA = "/scripts/editquota" QUOTA_CONF = "/etc/quota.conf" USERS_DIR = "/var/cpanel/users" PACKAGES_DIR = "/var/cpanel/packages" PLAN_KEYS = ["HASCGI", "HASDKIM", "HASSPF", "QUOTA", "BWLIMIT", "MAXPOP", "MAXFTP", "MAXLST", "MAXSQL", "MAXSUB", "MAXPARK", "MAXADDON", "MAX_EMAIL_PER_HOUR", "MAX_DEFER_FAIL_PERCENTAGE"] class Main(object): """ """ _cached_quota = {} _cached_users = {} _cached_packages = {} _packages = {} _users = {} def __init__(self, backup_varcpanel, backup_etcquota): """ Constructor """ self._backup_etcquota = backup_etcquota self._backup_varcpanel = backup_varcpanel self._load_quota_cache() def run(self): """ Run main action """ # load packages data self._load_packages() # load users conf self._load_users() self._load_users_quota() # load varcpanel cache for all users self._load_varcpanel_cache() # create backup user configs before restore self._backup_users() # check users differs self._check_users() def _load_quota_cache(self): """ Load cached quota settings """ # load backup files f = gzip.open(self._backup_etcquota, "rb") for line in f: line = line.strip() if not line: continue user, value = line.split("=") self._cached_quota[user.strip()] = value.strip() f.close() def _load_varcpanel_cache(self): """ Load cache for users and packages """ cmd = ["/bin/tar -C /tmp -xf %s %s %s" % (self._backup_varcpanel, USERS_DIR.lstrip("/"), PACKAGES_DIR.lstrip("/"))] p = subprocess.Popen(cmd, shell=True, executable='/bin/bash', stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = p.communicate() if err: print(err) sys.exit(0) # load users cache users_cache_dir = "/tmp%s" % USERS_DIR for cache_path in glob.glob("%s/*" % users_cache_dir): data = self._read_file(cache_path) username = cache_path.split("/")[-1] self._cached_users[username] = data # load packages cache packages_cache_dir = "/tmp%s" % PACKAGES_DIR for cache_path in glob.glob("%s/*" % packages_cache_dir): if not os.path.isfile(cache_path): # skip extensions directory continue data = self._read_file(cache_path) if "CGI" in data: data["CGI"] = {"y": "1", "n": "0"}.get(data["CGI"], data["CGI"]) username = cache_path.split("/")[-1] self._cached_packages[username] = data shutil.rmtree(users_cache_dir) shutil.rmtree(packages_cache_dir) def _load_packages(self): """ Load current packages configures """ for package_path in glob.glob("%s/*" % PACKAGES_DIR): if not os.path.isfile(package_path): continue pack = self._read_file(package_path) if "CGI" in pack: pack["CGI"] = {"y": "1", "n": "0"}.get(pack["CGI"], pack["CGI"]) self._packages[package_path.split("/")[-1]] = pack def _load_users(self): """ Load current users settings """ for user_path in glob.glob("%s/*" % USERS_DIR): if not os.path.isfile(user_path): continue user = self._read_file(user_path) self._users[user_path.split("/")[-1]] = user def _load_users_quota(self): """ Load config file with all users quotas """ quota = self._read_file(QUOTA_CONF) for user, value in iteritems(quota): if user in self._users: self._users[user]["QUOTA"] = value def _check_users(self): """ Check users settings """ for username, conf in iteritems(self._users): if not self._is_need_restore_settings(username, conf): # skip if different values continue # restore only users with package values print("Restore %s" % username) # reset to backup quota settings if username in self._cached_quota \ and conf["QUOTA"] != self._cached_quota[username]: # reset quota config params = [UPDATE_QUOTA, username, "%sM" % self._cached_quota[username]] p = subprocess.Popen(params, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # print params out, err = p.communicate() if err: print("UPDATE_QUOTA error:") print(err) # skip users without cache if username not in self._cached_users: print(" %s has not cached data - skip" % username) continue # skip users with plan differ from cached if self._cached_users[username]["PLAN"] != conf["PLAN"]: print(" %s changed plan from '%s' to '%s' - skip" % \ (username, self._cached_users[username]["PLAN"], conf["PLAN"])) continue # reset to backup limits settings for key in PLAN_KEYS: if key in self._cached_users[username] \ and conf[key] != self._cached_users[username][key]: # check difference between old package value and current package value if conf["PLAN"] in self._cached_packages and conf["PLAN"] in self._packages \ and self._cached_packages[conf["PLAN"]].get(key) \ != self._packages[conf["PLAN"]].get(key): print("Package value '%s' was changed - skip" % key) continue params = [UPDATE_USER, "--user", username, "--action", "set", "--key", key, "--value", self._cached_users[username][key]] p = subprocess.Popen(params, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # print params out, err = p.communicate() if err: print("UPDATE_USER error:") print(err) def _backup_users(self): """ Backup users configs files before restore """ ts = time.time() # backup users directory backup_dir = "%s.%s" % (USERS_DIR, ts) shutil.copytree(USERS_DIR, backup_dir) # backup quota.conf file backup_file = "%s.%s" % (QUOTA_CONF, ts) shutil.copy2(QUOTA_CONF, backup_file) def _is_need_restore_settings(self, username, conf): """ Compare plan settings and users config :return: bool. if true - need restore data, false - no """ if "default" == conf["PLAN"]: # default plan has no settings, but has user personal settings return True if conf["PLAN"] not in self._packages: # if user current plan no in packages - skip it print(" %s plan no in current packages - skip" % username) return False COMPARE_KEYS = {"CGI": "HASCGI"} for key, value in iteritems(self._packages[conf["PLAN"]]): if key not in ["CGI", "DIGESTAUTH", "HASSHELL"] + PLAN_KEYS: continue conf_key = COMPARE_KEYS.get(key, key) if conf_key in conf and conf[conf_key] != value: return False return True def _read_file(self, filename): """ helper util """ result = {} u = open(filename, "r") for line in u: line = line.strip() if not line or line.startswith("#"): continue key, value = line.split("=") result[key.strip()] = value.strip() u.close() return result if "__main__" == __name__: if len(sys.argv[1:]) < 2: print("%s <backup_varcpanel> <backup_etcquota>" % sys.argv[0]) sys.exit(1) Main(*sys.argv[1:]).run() #./autorestore.py /backup/cpbackup/weekly/dirs/_var_cpanel.tar.gz /backup/cpbackup/weekly/files/_etc_quota.conf.gz #./autorestore.py /tmp/var.tgz /backup/cpbackup/weekly/files/_etc_quota.conf.gz