Download bt-source/panel/class/btdockerModel/setupModel.py from SZFSPC/page: direct link, hf CLI and curl.
- Browser
- Download file 52.2 kB
-
https://huggingface.co/spaces/SZFSPC/page/resolve/main/bt-source/panel/class/btdockerModel/setupModel.py
- Command line
-
hf download hf://spaces/SZFSPC/page/bt-source/panel/class/btdockerModel/setupModel.py
-
curl -L -o setupModel.py https://huggingface.co/spaces/SZFSPC/page/resolve/main/bt-source/panel/class/btdockerModel/setupModel.py
52.2 kB
| # coding: utf-8 | |
| # ------------------------------------------------------------------- | |
| # 宝塔Linux面板 | |
| # ------------------------------------------------------------------- | |
| # Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved. | |
| # ------------------------------------------------------------------- | |
| # Author: wzz <wzz@bt.cn> | |
| # ------------------------------------------------------------------- | |
| # ------------------------------ | |
| # Docker模型 | |
| # ------------------------------ | |
| import json | |
| import os | |
| import shutil | |
| import time | |
| from typing import Dict, Callable, Any | |
| import public | |
| from btdockerModel import dk_public as dp | |
| from btdockerModel.dockerBase import dockerBase | |
| class main(dockerBase): | |
| __CONFIG_FILE = "/etc/docker/daemon.json" | |
| def __init__(self): | |
| if not os.path.exists(self.__CONFIG_FILE): | |
| public.ExecShell("mkdir -p /etc/docker") | |
| public.writeFile(self.__CONFIG_FILE, '{}') | |
| def get_docker_compose_version(self): | |
| try: | |
| key = "dk_compose_version" | |
| if public.get_cache_func(key)['data']: | |
| if int(time.time()) - public.get_cache_func(key)["time"] < 86400: | |
| return public.get_cache_func(key)["data"] | |
| stdout, stderr = public.ExecShell("docker compose version --short") | |
| if stderr != "": | |
| stdout, stderr = public.ExecShell("docker-compose version --short") | |
| if stderr != "": | |
| return "" | |
| public.set_cache_func(key, stdout.strip()) | |
| return stdout.strip() | |
| except: | |
| return "" | |
| def get_config(self, get): | |
| """ | |
| 获取设置配置信息 | |
| @param get: | |
| @return: | |
| """ | |
| # 检查docker-compose服务 | |
| check_docker_compose = self.check_docker_compose_service() | |
| # 检查docker服务安装状态 | |
| try: | |
| installing = public.M('tasks').where('name=? and status=?', ("安装[Docker服务]", "-1")).count() | |
| if not installing: | |
| installing = public.M('tasks').where('name=? and status=?', ("安装[Docker服务]", "-1")).count() | |
| except: | |
| installing = 0 | |
| if not os.path.exists("/www/server/panel/data/db/docker.db"): | |
| public.ExecShell("mv -f /www/server/panel/data/docker.db /www/server/panel/data/db/docker.db") | |
| # 检查docker服务状态 | |
| service_status = self.get_service_status() | |
| if not service_status: | |
| service_status = self.get_service_status() | |
| # 获取 Docker 守护进程文件配置 | |
| daemon_config = self._get_daemon_config() | |
| # # 获取docker-compose版本 | |
| docker_compose_version = self.get_docker_compose_version() | |
| # try: | |
| # bad_registry = os.path.exists("/www/server/panel/config/bad_registry.pl") | |
| # bad_registry_path = public.readFile("/www/server/panel/config/bad_registry.pl") | |
| # if not bad_registry_path: | |
| # bad_registry = False | |
| # bad_registry_path = "" | |
| # except: | |
| # bad_registry = False | |
| # bad_registry_path = "" | |
| #应用商店路径 | |
| from mod.project.docker.app.base import App | |
| dk_project_path = App.dk_project_path | |
| install_path = os.path.join(dk_project_path,'dk_app','installed.json') | |
| allow_update_install_path = True | |
| if os.path.exists(install_path): | |
| try: | |
| installed_apps = json.loads(public.readFile(install_path)) | |
| for type,apps in installed_apps.items(): | |
| if len(apps) > 0: | |
| allow_update_install_path = False | |
| except: | |
| allow_update_install_path = False | |
| return { | |
| "service_status": service_status, | |
| "docker_installed": self.check_docker_service(), | |
| "docker_compose_installed": check_docker_compose[0], | |
| "docker_compose_path": check_docker_compose[1], | |
| "monitor_status": self.get_monitor_status(), | |
| "monitor_save_date": dp.docker_conf()['SAVE'], | |
| "daemon_path": self.__CONFIG_FILE, | |
| "installing": installing, | |
| **daemon_config, | |
| "docker_compose_version": docker_compose_version, | |
| "bad_registry": True, | |
| "bad_registry_path": "https://docker.1ms.run", | |
| "dk_project_path": dk_project_path, | |
| "allow_update_install_path": allow_update_install_path | |
| } | |
| def _get_daemon_config(cls): | |
| """获取 Docker 守护进程配置""" | |
| default_config = { | |
| "warehouse": [], | |
| "log_cutting": {}, | |
| "iptables": True, | |
| "live_restore": False, | |
| "driver": ["native.cgroupdriver=systemd"], | |
| "socket": "unix:///var/run/docker.sock", | |
| "ipv6_status": False, | |
| "ipv6_addr": "", | |
| "proxy":{}, | |
| "data-root":"/var/lib/docker" | |
| } | |
| try: | |
| data = json.loads(public.readFile(cls.__CONFIG_FILE)) | |
| return { | |
| "warehouse": data.get("insecure-registries", default_config["warehouse"]), | |
| "log_cutting": data.get("log-opts", default_config["log_cutting"]), | |
| "iptables": data.get("iptables", default_config["iptables"]), | |
| "live_restore": data.get("live-restore", default_config["live_restore"]), | |
| "driver": data.get("exec-opts", default_config["driver"])[0], | |
| "socket": data.get("hosts", default_config["socket"]), | |
| "ipv6_status": data.get("ipv6", default_config["ipv6_status"]), | |
| "ipv6_addr": data.get("fixed-cidr-v6", default_config["ipv6_addr"]), | |
| "proxy": data.get('proxies', default_config['proxy']), | |
| "data-root": data.get("data-root", default_config["data-root"]) | |
| } | |
| except: | |
| # public.print_log(public.get_error_info()) | |
| return default_config | |
| def _get_com_registry_mirrors(): | |
| """ | |
| 获取常用加速配置 | |
| @return: | |
| """ | |
| com_reg_mirror_file = "{}/class/btdockerModel/config/com_reg_mirror.json".format(public.get_panel_path()) | |
| try: | |
| com_reg_mirror = json.loads(public.readFile(com_reg_mirror_file)) | |
| except: | |
| public.ExecShell("rm -f {}".format(com_reg_mirror_file)) | |
| public.downloadFile("{}/src/com_reg_mirror.json".format(public.get_url()), com_reg_mirror_file) | |
| try: | |
| com_reg_mirror = json.loads(public.readFile(com_reg_mirror_file)) | |
| except: | |
| com_reg_mirror = { | |
| "https://mirror.ccs.tencentyun.com": "腾讯云镜像加速站", | |
| } | |
| return com_reg_mirror | |
| def set_monitor_save_date(self, get): | |
| """ | |
| :param save_date: int 例如30 表示 30天 | |
| :param get: | |
| :return: | |
| """ | |
| import re | |
| conf_path = "{}/data/docker.conf".format(public.get_panel_path()) | |
| docker_conf = public.readFile(conf_path) | |
| try: | |
| save_date = int(get.save_date) | |
| except: | |
| return public.returnMsg(False, "监控保存时间需要为正整数!") | |
| if save_date > 999: | |
| return public.returnMsg(False, "监控数据不能保留超过999天!") | |
| if not docker_conf: | |
| docker_conf = "SAVE={}".format(save_date) | |
| public.writeFile(conf_path, docker_conf) | |
| return public.returnMsg(True, "设置成功!") | |
| docker_conf = re.sub("SAVE\s*=\s*\d+", "SAVE={}".format(save_date), | |
| docker_conf) | |
| public.writeFile(conf_path, docker_conf) | |
| dp.write_log("设置监控时间为[{}]天!".format(save_date)) | |
| return public.returnMsg(True, "设置成功!") | |
| def get_service_status(self): | |
| sock = '/var/run/docker.pid' | |
| # Nas镜像标识文件 | |
| tagfile = "/www/server/panel/data/o.pl" | |
| if os.path.exists(tagfile) and self.check_docker_service(): | |
| try: | |
| if public.cache_get(tagfile): | |
| return True | |
| content = public.readFile(tagfile).strip() | |
| if content == "docker_bt_nas": | |
| public.cache_set(tagfile, 1, 86400) | |
| return True | |
| except: | |
| pass | |
| if os.path.exists(sock): | |
| try: | |
| client = dp.docker_client() | |
| if client: | |
| return True | |
| return False | |
| except: | |
| return False | |
| else: | |
| return False | |
| # docker服务状态设置 | |
| def docker_service(self, get): | |
| """ | |
| :param act start/stop/restart | |
| :param get: | |
| :return: | |
| """ | |
| act_dict = {'start': '启动', 'stop': '停止', 'restart': '重启'} | |
| if get.act not in act_dict: | |
| return public.returnMsg(False, '只允许传start|stop|restart!') | |
| exec_str = 'systemctl {} docker'.format(get.act) | |
| if get.act == "stop": | |
| exec_str += ";systemctl {} docker.socket".format(get.act) | |
| stdout, stderr = public.ExecShell(exec_str) | |
| if stderr and not "but it can still be activated by:\n docker.socket\n" in stderr: | |
| dp.write_log("将 Docker 服务状态设置为 [{}]失败,失败原因:{}".format(act_dict[get.act], stderr)) | |
| jou_stdout, jou_stderr = public.ExecShell("journalctl -xe -u docker -n 100 --no-pager|grep libusranalyse.so") | |
| if jou_stdout != "": | |
| return public.returnMsg("docker服务设置失败,请关闭堡塔防入侵后再尝试!") | |
| if "Can't operate. Failed to connect to bus" in stderr: | |
| wsl_cmd = "/etc/init.d/docker {}".format(get.act) | |
| wsl_stdout, wsl_stderr = public.ExecShell(wsl_cmd) | |
| if not wsl_stderr: | |
| return public.returnMsg(True, "设置成功!") | |
| return public.returnMsg(False, "设置失败!失败原因:{}".format(wsl_stderr)) | |
| return public.returnMsg(False, "设置失败!失败原因:{}".format(stderr)) | |
| if get.act != "stop": | |
| service_status = self.get_service_status() | |
| if not service_status: | |
| import time | |
| public.ExecShell("systemctl stop docker") | |
| public.ExecShell("systemctl stop docker.socket") | |
| time.sleep(1) | |
| public.ExecShell("systemctl start docker") | |
| dp.write_log("将 Docker 服务状态设置为 [{}]".format(act_dict[get.act])) | |
| return public.returnMsg(True, "{}成功".format(act_dict[get.act])) | |
| # 获取加速配置 | |
| def get_registry_mirrors(self, get): | |
| """ | |
| 获取镜像加速信息 | |
| @param get: | |
| @return: | |
| """ | |
| try: | |
| conf = json.loads(public.readFile(self.__CONFIG_FILE)) | |
| if "registry-mirrors" not in conf: | |
| reg_mirrors = [] | |
| else: | |
| reg_mirrors = conf['registry-mirrors'] | |
| except: | |
| reg_mirrors = [] | |
| # 获取镜像源状态缓存 | |
| cache_key = 'detector_mirrors' | |
| if str(get.get('force',"0")) == "1": | |
| from mod.project.docker.config.mirrorDetector import DockerMirrorDetector | |
| detector_mirrors = DockerMirrorDetector.test_batch(reg_mirrors,max_workers=4) | |
| detector_mirrors = {item["url"]:item for item in detector_mirrors} | |
| public.cache_set(cache_key, detector_mirrors, 86400) | |
| else: | |
| detector_mirrors = public.cache_get(cache_key) | |
| if not detector_mirrors: | |
| detector_mirrors = {} | |
| res_mirrors = [] | |
| for mirr_url in reg_mirrors: | |
| if mirr_url in detector_mirrors.keys(): | |
| res_mirrors.append({ | |
| "url": mirr_url, | |
| "ts": detector_mirrors[mirr_url]["ts"], | |
| "available": detector_mirrors[mirr_url]["available"] | |
| }) | |
| else: | |
| res_mirrors.append({"url": mirr_url,"ts": "","available": None}) | |
| # 缓存一天获取列表 不用每次都去请求 | |
| com_reg_mirrors = public.cache_get("com_reg_mirrors") | |
| if not com_reg_mirrors: | |
| com_reg_mirrors = self._get_com_registry_mirrors() | |
| public.cache_set("com_reg_mirrors", com_reg_mirrors, 86400) | |
| # 将com_reg_mirrors与reg_mirrors进行过滤 如果reg_mirrors中有 则去除com_reg_mirrors中的项 | |
| com_reg_mirrors = dict(filter(lambda x: x[0] not in reg_mirrors, com_reg_mirrors.items())) | |
| return { | |
| "registry_mirrors": res_mirrors, | |
| "com_reg_mirrors": com_reg_mirrors | |
| } | |
| # 设置加速配置 | |
| def set_registry_mirrors(self, get): | |
| """ | |
| :param registry_mirrors_address registry.docker-cn.com,hub-mirror.c.163.com | |
| :param get: | |
| :return: | |
| """ | |
| import re | |
| try: | |
| registry_mirrors_address = get.get("registry_mirrors_address/s", "").strip() | |
| conf = self.get_daemon_json() | |
| # 处理镜像地址列表 | |
| new_mirrors = [] | |
| if registry_mirrors_address: | |
| mirrors = registry_mirrors_address.split(',') | |
| for mirror in mirrors: | |
| mirror = mirror.strip().rstrip('/') | |
| if not mirror: | |
| continue | |
| # 校验URL格式 | |
| if not re.match(r'^https?://', mirror): | |
| return public.returnMsg(False,'加速地址[{}]格式错误 参考:https://mirror.ccs.tencentyun.com'.format(mirror)) | |
| if mirror not in new_mirrors: | |
| new_mirrors.append(mirror) | |
| # 获取当前配置中的镜像 | |
| current_mirrors = conf.get('registry-mirrors', []) | |
| if not isinstance(current_mirrors, list): | |
| if isinstance(current_mirrors, str): | |
| current_mirrors = [current_mirrors] | |
| else: | |
| current_mirrors = [] | |
| # 如果配置未发生变化,直接返回成功 | |
| if current_mirrors == new_mirrors: | |
| return public.returnMsg(True, '设置成功') | |
| # 更新配置 | |
| if new_mirrors: | |
| conf['registry-mirrors'] = new_mirrors | |
| else: | |
| if 'registry-mirrors' in conf: | |
| del conf['registry-mirrors'] | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(conf, indent=2)) | |
| dp.write_log("设置Docker加速成功!") | |
| return public.returnMsg(True, '设置成功') | |
| except Exception as e: | |
| return public.returnMsg(False, "设置失败!{}".format(str(e))) | |
| def detector_mirrors(self, get): | |
| """ | |
| 检测当前加速源地址是否可用 | |
| @param get: | |
| @return: | |
| """ | |
| mirrors_list = get.get("mirrors","").split(",") | |
| if mirrors_list == [""]: | |
| return public.return_data(True,[]) | |
| cache_key = "detector_mirrors" | |
| detector_dict = public.cache_get(cache_key) | |
| if not detector_dict: | |
| detector_dict = {} | |
| from mod.project.docker.config.mirrorDetector import DockerMirrorDetector | |
| detector_result = DockerMirrorDetector.test_batch(mirrors_list,max_workers=4) | |
| for detector in detector_result: | |
| detector_dict[detector["url"]] = { | |
| "ts": detector["ts"], | |
| "available": detector["available"] | |
| } | |
| public.cache_set(cache_key, detector_dict, 86400) | |
| return public.return_data(True,detector_result) | |
| def update_com_registry_mirrors(self, get): | |
| """ | |
| 更新常用加速配置 | |
| @param get: | |
| @return: | |
| """ | |
| if get.registry_mirrors_address == "": | |
| return public.returnMsg(True, "设置成功!") | |
| import time | |
| com_reg_mirror_file = "{}/class/btdockerModel/config/com_reg_mirror.json".format(public.get_panel_path()) | |
| try: | |
| com_reg_mirror = json.loads(public.readFile(com_reg_mirror_file)) | |
| except: | |
| com_reg_mirror = { | |
| "https://mirror.ccs.tencentyun.com": "腾讯云镜像加速站", | |
| } | |
| if get.registry_mirrors_address in com_reg_mirror: | |
| return public.returnMsg(True, "设置成功!") | |
| remarks = get.remarks if "remarks" in get and get.remarks != "" else ("自定义镜像站" + str(int(time.time()))) | |
| com_reg_mirror.update({"{}".format(get.registry_mirrors_address): remarks}) | |
| public.writeFile(com_reg_mirror_file, json.dumps(com_reg_mirror, indent=2)) | |
| dp.write_log("更新常用加速配置成功!") | |
| return public.returnMsg(True, "更新成功!") | |
| def del_com_registry_mirror(self, get): | |
| """ | |
| 删除常用加速配置 | |
| @param get: | |
| @return: | |
| """ | |
| com_reg_mirror_file = "{}/class/btdockerModel/config/com_reg_mirror.json".format(public.get_panel_path()) | |
| try: | |
| com_reg_mirror = json.loads(public.readFile(com_reg_mirror_file)) | |
| except: | |
| com_reg_mirror = { | |
| "https://mirror.ccs.tencentyun.com": "腾讯云镜像加速站", | |
| } | |
| if get.registry_mirrors_address not in com_reg_mirror: | |
| return public.returnMsg(True, "删除成功!") | |
| del com_reg_mirror["{}".format(get.registry_mirrors_address)] | |
| public.writeFile(com_reg_mirror_file, json.dumps(com_reg_mirror, indent=2)) | |
| dp.write_log("删除常用加速配置成功!") | |
| return public.returnMsg(True, "删除成功!") | |
| def get_monitor_status(self): | |
| """ | |
| 获取docker监控状态 | |
| @return: | |
| """ | |
| try: | |
| from BTPanel import cache | |
| except: | |
| from cachelib import SimpleCache | |
| cache = SimpleCache() | |
| skey = "docker_monitor_status" | |
| result = cache.get(skey) | |
| if isinstance(result, bool): | |
| return result | |
| import psutil | |
| is_monitor = False | |
| try: | |
| for proc in psutil.process_iter(): | |
| try: | |
| pinfo = proc.as_dict(attrs=['pid', 'name']) | |
| if "monitorModel.py" in pinfo['name']: | |
| is_monitor = True | |
| except: | |
| pass | |
| except: | |
| pass | |
| cache.set(skey, is_monitor, 86400) | |
| return is_monitor | |
| def set_docker_monitor(self, get): | |
| """ | |
| 开启docker监控获取docker相取资源信息 | |
| :param act: start/stop | |
| :return: | |
| """ | |
| import time | |
| python = "/www/server/panel/pyenv/bin/python" | |
| if not os.path.exists(python): | |
| python = "/www/server/panel/pyenv/bin/python3" | |
| cmd_line = "/www/server/panel/class/btdockerModel/monitorModel.py" | |
| if get.act == "start": | |
| self.stop_monitor(get) | |
| if not os.path.exists(self.moinitor_lock): | |
| public.writeFile(self.moinitor_lock, "1") | |
| shell = "nohup {} {} &".format(python, cmd_line) | |
| public.ExecShell(shell) | |
| time.sleep(1) | |
| if self.get_monitor_status(): | |
| dp.write_log("Docker监控启动成功!") | |
| self.add_monitor_cron(get) | |
| return public.returnMsg(True, "启动监控成功!") | |
| return public.returnMsg(False, "启动监控失败!") | |
| else: | |
| from BTPanel import cache | |
| skey = "docker_monitor_status" | |
| cache.set(skey, False) | |
| if os.path.exists(self.moinitor_lock): | |
| os.remove(self.moinitor_lock) | |
| self.stop_monitor(get) | |
| return public.returnMsg(True, "Docker监控成功停止!") | |
| # 2024/1/4 上午 9:32 停止容器监控进程 | |
| def stop_monitor(self, get): | |
| ''' | |
| @name 名称/描述 | |
| @param 参数名<数据类型> 参数描述 | |
| @return 数据类型 | |
| ''' | |
| cmd_line = [ | |
| "/www/server/panel/class/btdockerModel/monitorModel.py", | |
| "/www/server/panel/class/projectModel/bt_docker/dk_monitor.py" | |
| ] | |
| for cmd in cmd_line: | |
| in_pid = True | |
| sum = 0 | |
| while in_pid: | |
| in_pid = False | |
| pid = dp.get_process_id( | |
| "python", | |
| "{}".format(cmd)) | |
| if pid: | |
| in_pid = True | |
| if not pid: | |
| pid = dp.get_process_id( | |
| "python3", | |
| "{}".format(cmd) | |
| ) | |
| if pid: | |
| in_pid = True | |
| public.ExecShell("kill -9 {}".format(pid)) | |
| sum += 1 | |
| if sum > 100: | |
| break | |
| import os | |
| # 指定目录路径 | |
| directory = "/www/server/cron/" | |
| if not os.path.exists(directory): | |
| os.makedirs(directory) | |
| # 遍历目录下的所有非.log结尾的文件 | |
| for filename in os.listdir(directory): | |
| if not filename.endswith(".log"): | |
| filepath = os.path.join(directory, filename) | |
| if os.path.isdir(filepath): | |
| continue | |
| # 检查文件内容是否包含 "monitorModel.py" | |
| with open(filepath, 'r') as file: | |
| content = file.read() | |
| if "monitorModel.py" in content or "dk_monitor.py" in content: | |
| # 删除原文件和对应的.log文件 | |
| if os.path.exists(filepath): | |
| os.remove(filepath) | |
| if os.path.exists(os.path.join(directory, "{}.log".format(filename))): | |
| os.remove(os.path.join(directory, "{}.log".format(filename))) | |
| public.ExecShell("crontab -l | sed '/{}/d' | crontab -".format(filename)) | |
| dp.write_log("Docker监控成功停止!") | |
| public.M('crontab').where('name=?', ("[勿删]docker监控守护程序",)).delete() | |
| return public.returnMsg(True, "Docker监控成功停止!") | |
| # 2023/12/7 下午 6:24 创建计划任务,监听监控进程是否存在,如果不存在则添加 | |
| def add_monitor_cron(self, get): | |
| ''' | |
| @name 名称/描述 | |
| @author wzz <2023/12/7 下午 6:24> | |
| @param 参数名<数据类型> 参数描述 | |
| @return 数据类型 | |
| ''' | |
| try: | |
| import crontab | |
| if public.M('crontab').where('name', ("[勿删]docker监控守护程序",)).count() == 0: | |
| p = crontab.crontab() | |
| llist = p.GetCrontab(None) | |
| if type(llist) == list: | |
| for i in llist: | |
| if i['name'] == '[勿删]docker监控守护程序': | |
| return | |
| get = { | |
| "name": "[勿删]docker监控守护程序", | |
| "type": "minute-n", | |
| "where1": 5, | |
| "hour": "", | |
| "minute": "", | |
| "week": "", | |
| "sType": "toShell", | |
| "sName": "", | |
| "backupTo": "localhost", | |
| "save": '', | |
| "sBody": """ | |
| if [ -f {} ]; then | |
| new_mt=`ps aux|grep monitorModel.py|grep -v grep` | |
| old_mt=`ps aux|grep dk_monitor.py|grep -v grep` | |
| if [ -z "$new_mt" ] && [ -z "$old_mt" ]; then | |
| nohup /www/server/panel/pyenv/bin/python /www/server/panel/class/btdockerModel/monitorModel.py & | |
| fi | |
| fi | |
| """.format(self.moinitor_lock), | |
| "urladdress": "undefined" | |
| } | |
| p.AddCrontab(get) | |
| except Exception as e: | |
| return False | |
| def check_docker_compose_service(self): | |
| """ | |
| 检查docker-compose是否已经安装 | |
| :return: | |
| """ | |
| docker_compose = "/usr/bin/docker-compose" | |
| docker_compose_path = "{}/class/btdockerModel/config/docker_compose_path.pl".format(public.get_panel_path()) | |
| if os.path.exists(docker_compose_path): | |
| docker_compose = public.readFile(docker_compose_path).strip() | |
| if not os.path.exists(docker_compose): | |
| dk_compose_list = ["/usr/libexec/docker/cli-plugins/docker-compose", "/usr/local/docker-compose"] | |
| for i in dk_compose_list: | |
| if os.path.exists(i): | |
| public.ExecShell("ln -sf {} {}".format(i, "/usr/bin/docker-compose")) | |
| break | |
| if not os.path.exists(docker_compose): | |
| return False, "" | |
| return True, docker_compose | |
| def check_docker_service(self): | |
| """ | |
| 检查docker是否安装 | |
| @return: | |
| """ | |
| docker = "/usr/bin/docker" | |
| if not os.path.exists(docker): | |
| return False | |
| return True | |
| def set_docker_compose_path(self, get): | |
| """ | |
| 设置docker-compose的路径 | |
| @param get: | |
| @return: | |
| """ | |
| docker_compose_file = get.docker_compose_path if "docker_compose_path" in get else "" | |
| if docker_compose_file == "": | |
| return public.returnMsg(False, "docker-compose文件路径不能为空!") | |
| if not os.path.exists(docker_compose_file): | |
| return public.returnMsg(False, "docker-compose文件不存在!") | |
| public.ExecShell("chmod +x {}".format(docker_compose_file)) | |
| cmd_result = public.ExecShell("{} --version".format(docker_compose_file)) | |
| if not cmd_result[0]: | |
| return public.returnMsg(False, "docker-compose文件不可执行或不是docker-compose文件!") | |
| docker_compose_path = "{}/class/btdockerModel/config/docker_compose_path.pl".format(public.get_panel_path()) | |
| public.writeFile(docker_compose_path, docker_compose_file) | |
| dp.write_log("设置docker-compose路径成功!") | |
| return public.returnMsg(True, "设置成功!") | |
| # 2024/9/2 下午2:22 检查本机公网IP归属地是否为中国大陆IP | |
| def check_area(self, get): | |
| ''' | |
| @name 检查本机公网IP归属地是否为中国大陆IP | |
| @param get: | |
| @return dict{"status":True/False,"msg":"提示信息"} | |
| ''' | |
| flag = "0" | |
| try: | |
| client_ip = public.get_server_ip() | |
| c_area = public.get_free_ip_info(client_ip) | |
| if ("中国" in c_area["country"] and | |
| "中国" in c_area["info"] and | |
| "CN" in c_area["en_short_code"] and | |
| not "local" in c_area): | |
| if "腾讯云" in c_area["carrier"]: | |
| flag = "2" | |
| elif "阿里云" in c_area["carrier"]: | |
| flag = "3" | |
| else: | |
| flag = "1" | |
| except: | |
| # 如果获取失败,就默认为中国大陆IP | |
| flag = "1" | |
| return flag | |
| # 2024/9/2 下午3:07 安装docker和docker-compose | |
| def install_docker_program(self, get): | |
| """ | |
| 安装docker和docker-compose | |
| :param get: | |
| :return: | |
| """ | |
| import time | |
| url = get.get("url/s", "") | |
| type = get.get("type/d", 0) | |
| public.ExecShell("rm -f /etc/yum.repos.d/docker-ce.repo") | |
| if url == "": | |
| c_flag = self.check_area(get) | |
| if c_flag != "0": | |
| if c_flag == "2": | |
| url = "mirrors.tencent.com/docker-ce" | |
| elif c_flag == "3": | |
| url = "mirrors.aliyun.com/docker-ce" | |
| else: | |
| url_file = "/www/server/panel/class/btdockerModel/config/install_url.pl" | |
| public.ExecShell("rm -f {}".format(url_file)) | |
| public.downloadFile("{}/src/dk_app/apps/install_url.pl".format(public.get_url()), url_file) | |
| url_body = public.readFile(url_file) | |
| url = url_body.strip() if url_body else "" | |
| # 2024/3/28 上午 10:36 检测是否已存在安装任务 | |
| if public.M('tasks').where('name=? and status=?', ("安装[Docker服务]", "-1")).count(): | |
| return public.returnMsg(False, "已存在安装任务,请勿重复添加!") | |
| mmsg = "安装[Docker服务]" | |
| if type == 0 and url == "": | |
| # 默认安装 | |
| execstr = ("wget -O /tmp/docker_install.sh {}/install/0/docker_install.sh && bash /tmp/docker_install.sh install").format(public.get_url()) | |
| elif type == 0 and url != "": | |
| # 选择镜像源安装 | |
| execstr = ("wget -O /tmp/docker_install.sh {}/install/0/docker_install.sh && bash /tmp/docker_install.sh install {}").format(public.get_url(), url.strip('"')) | |
| else: | |
| # 二进制安装 | |
| execstr = "wget -O /tmp/docker_bin.sh {}/install/0/docker_bin.sh && bash /tmp/docker_bin.sh install".format(public.get_url()) | |
| sid_result = public.M('tasks').add('id,name,type,status,addtime,execstr', (None, mmsg, 'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr)) | |
| from panelPlugin import panelPlugin | |
| panelPlugin().create_install_wait_msg(sid_result, mmsg, False) | |
| public.httpPost( | |
| public.GetConfigValue('home') + '/api/panel/plugin_total', { | |
| "pid": "1111111", | |
| 'p_name': "Docker商用模块" | |
| }, 3) | |
| return public.returnMsg(True, "安装任务已添加到队列中!") | |
| def uninstall_status(get): | |
| """ | |
| 检测docker是否可以卸载 | |
| :param get: | |
| :return: | |
| """ | |
| # 获取容器 | |
| from btdockerModel import containerModel | |
| docker_list = containerModel.main().get_list(get) | |
| # 获取镜像 | |
| from btdockerModel import imageModel | |
| images_list = imageModel.main().image_list(get) | |
| if len(images_list) > 0 or len(docker_list["container_list"]) > 0: | |
| return public.returnMsg(False, "请手动删除所有容器和所有镜像后再进行卸载docker!") | |
| return public.returnMsg(True, "可以卸载!") | |
| def uninstall_docker_program(self, get): | |
| """ | |
| 卸载docker和docker-compose | |
| :param get: | |
| :return: | |
| """ | |
| type = get.get("type/d", 0) | |
| if type == 0: | |
| uninstall_status = self.uninstall_status(get) | |
| if not uninstall_status["status"]: | |
| return uninstall_status | |
| public.ExecShell( | |
| "wget -O /tmp/docker_install.sh {}/install/0/docker_install.sh && bash /tmp/docker_install.sh uninstall" | |
| .format(public.get_url() | |
| )) | |
| public.ExecShell("rm -rf /usr/bin/docker-compose") | |
| return public.returnMsg(True, "卸载成功!") | |
| def repair_docker(self, get): | |
| """ | |
| 修复docker | |
| @param get: | |
| @return: | |
| """ | |
| import time | |
| mmsg = "Repair Docker service" | |
| execstr = "curl -fsSL https://get.docker.com -o /tmp/get-docker.sh && sed -i '/sleep 20/d' /tmp/get-docker.sh && /bin/bash /tmp/get-docker.sh" | |
| public.M('tasks').add('id,name,type,status,addtime,execstr', | |
| (None, mmsg, 'execshell', '0', | |
| time.strftime('%Y-%m-%d %H:%M:%S'), execstr)) | |
| public.httpPost( | |
| public.GetConfigValue('home') + '/api/panel/plugin_total', { | |
| "pid": "1111111", | |
| 'p_name': "Docker商用模块" | |
| }, 3) | |
| return public.returnMsg(True, "修复任务已添加到队列中!") | |
| def get_daemon_json(self): | |
| """ | |
| 获取daemon.json配置信息 | |
| @param get: | |
| @return: | |
| """ | |
| try: | |
| return json.loads(public.readFile(self.__CONFIG_FILE)) | |
| except Exception as e: | |
| raise RuntimeError("读取配置文件失败:{}".format(str(e))) | |
| def save_daemon_json(self, get): | |
| """ | |
| 保存daemon.json配置信息,保存前备份,验证可以成功执行后再替换 | |
| @param get: | |
| @return: | |
| """ | |
| if getattr(get, "daemon_json", "") == "": | |
| public.ExecShell("rm -f {}".format(self.__CONFIG_FILE)) | |
| return public.returnMsg(True, "保存成功!") | |
| try: | |
| conf = json.loads(get.daemon_json) | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(conf, indent=2)) | |
| dp.write_log("保存daemon.json配置成功!") | |
| return public.returnMsg(True, "保存成功!") | |
| except Exception as e: | |
| print(e) | |
| if "Expecting property name enclosed in double quotes" in str(e): | |
| return public.returnMsg(False, "保存失败,原因:daemon.json配置文件格式错误!") | |
| return public.returnMsg(False, "保存失败,原因:{}!".format(e)) | |
| def set_docker_global(self, get): | |
| ''' | |
| docker全局配置接口 | |
| 根据传值进行不同操作的写入/etc/docker/daemon.json | |
| 全局设置后都需要重启docker生效 | |
| ''' | |
| # 配置项与对应的处理方法的映射 | |
| ''' | |
| 加速URL 默认 https://docker.1ms.run | |
| 私有仓库 | |
| 日志切割 | |
| iptables 是否自动管理iptables规则 默认True | |
| live-restore docker实时恢复 默认False | |
| driver方式 指定容器运行参数 默认systemd | |
| 全局开启ipv6 | |
| ''' | |
| config_actions: Dict[str, Callable[[Any], Any]] = { | |
| 'registry_mirrors_address': self.set_registry_mirrors, | |
| 'warehouse': self.set_warehouse, | |
| 'log_cutting': self.set_log_cutting, | |
| 'iptables': self.set_iptables, | |
| 'live_restore': self.set_live_restore, | |
| 'driver': self.set_drive, | |
| 'status': self.set_ipv6_global, | |
| 'proxy_settings': self.set_proxy, | |
| "docker_root_dir": self.set_docker_root_dir | |
| } | |
| # 遍历每个配置项,调用相应的方法 | |
| for key, func_name in config_actions.items(): | |
| if hasattr(get, key): | |
| result = func_name(get) | |
| return result | |
| return public.returnMsg(False, "不存在的配置项!") | |
| def set_docker_root_dir(self, get): | |
| ''' | |
| 设置docker根目录 | |
| @param get: docker_root_dir | |
| @return: | |
| ''' | |
| try: | |
| # 停止docker服务 | |
| get.act = "stop" | |
| self.docker_service(get) | |
| # 获取当前和目标Docker根目录 | |
| data = self.get_daemon_json() | |
| current_root_dir = data.get("data-root", "/var/lib/docker") | |
| new_root_dir = get.get("docker_root_dir", "") | |
| if not new_root_dir: | |
| return public.returnMsg(False, "Docker根目录不能为空!") | |
| if current_root_dir == new_root_dir: | |
| return public.returnMsg(True, "当前Docker根目录已是目标目录,无需更改!") | |
| # 检查是否需要移动现有的Docker数据 | |
| move_data = get.get("move_data", False) | |
| if move_data and os.path.exists(current_root_dir): | |
| try: | |
| # 检查当前目录大小 | |
| current_size = sum(os.path.getsize(os.path.join(dirpath, filename)) | |
| for dirpath, dirnames, filenames in os.walk(current_root_dir) | |
| for filename in filenames) | |
| # 使用shutil.copytree进行拷贝 | |
| shutil.copytree(current_root_dir, new_root_dir) | |
| # 检查新目录大小 | |
| new_size = sum(os.path.getsize(os.path.join(dirpath, filename)) | |
| for dirpath, dirnames, filenames in os.walk(new_root_dir) | |
| for filename in filenames) | |
| if current_size != new_size: | |
| raise Exception("文件大小不匹配,可能存在数据丢失!") | |
| # 拷贝成功后删除源目录 | |
| shutil.rmtree(current_root_dir) | |
| except Exception as e: | |
| # 如果移动失败,恢复原来的配置并返回错误 | |
| data = self.get_daemon_json() | |
| data["data-root"] = current_root_dir | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(data, indent=2)) | |
| # 重启docker服务 | |
| get.act = "start" | |
| self.docker_service(get) | |
| return public.returnMsg(False, "移动失败,已恢复原有配置,原因:{}".format(str(e))) | |
| # 写入新的Docker根目录到配置文件 | |
| data["data-root"] = new_root_dir | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(data, indent=2)) | |
| # 重启docker服务 | |
| get.act = "start" | |
| self.docker_service(get) | |
| return public.returnMsg(True, "设置成功!") | |
| except Exception as e: | |
| return public.returnMsg(False, "设置失败!{}".format(str(e))) | |
| def set_proxy(self, get): | |
| ''' | |
| 设置全局代理 | |
| @param get: proxy_settings | |
| @return: | |
| ''' | |
| try: | |
| # 从 JSON 字符串中解析代理设置 | |
| try: | |
| proxy_settings = json.loads(get.get("proxy_settings", "{}")) | |
| http_proxy = proxy_settings.get("http_proxy", "").strip() | |
| https_proxy = proxy_settings.get("https_proxy", "").strip() | |
| no_proxy = proxy_settings.get("no_proxy", "localhost,127.0.0.1").strip() | |
| except json.JSONDecodeError: | |
| return public.returnMsg(False, "代理设置的JSON格式错误!") | |
| data = self.get_daemon_json() | |
| if not proxy_settings and "proxies" in data: | |
| del data["proxies"] | |
| else: | |
| daemon_proxy = data.get("proxies", {}) | |
| daemon_proxy["http-proxy"] = http_proxy | |
| daemon_proxy["https-proxy"] = https_proxy | |
| daemon_proxy["no-proxy"] = no_proxy | |
| data["proxies"] = daemon_proxy | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(data, indent=2)) | |
| # 重载全局配置文件 | |
| self.reload_global_config() | |
| # 重启docker服务 | |
| get.act = "restart" | |
| self.docker_service(get) | |
| return public.returnMsg(True, "代理设置成功!") | |
| except Exception as e: | |
| return public.returnMsg(False, "设置失败!{}".format(str(e))) | |
| def set_warehouse(self, get): | |
| ''' | |
| 设置私有仓库 | |
| @param get: warehouse | |
| @return: | |
| ''' | |
| try: | |
| warehouse = get.get("warehouse", "").strip() | |
| data = self.get_daemon_json() | |
| if warehouse == "" and "insecure-registries" in data: | |
| del data["insecure-registries"] | |
| else: | |
| warehouse = [i.strip() for i in warehouse.split(",")] | |
| data["insecure-registries"] = warehouse | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(data, indent=2)) | |
| # 重启docker服务 | |
| get.act = "restart" | |
| self.docker_service(get) | |
| return public.returnMsg(True, "设置成功!") | |
| except Exception as e: | |
| return public.returnMsg(False, "设置失败!{}".format(str(e))) | |
| def set_log_cutting(self, get): | |
| ''' | |
| 设置日志切割 | |
| @param get: log_cutting | |
| @return: | |
| ''' | |
| try: | |
| log_cutting = get.get("log_cutting", {}) | |
| if isinstance(log_cutting, str): | |
| try: | |
| log_cutting = json.loads(log_cutting) | |
| except: | |
| log_cutting = {} | |
| # 确保 log_cutting 里的所有值都转换为字符串 | |
| if isinstance(log_cutting, dict): | |
| log_cutting = {k: str(v) for k, v in log_cutting.items()} | |
| data = self.get_daemon_json() | |
| if not log_cutting and "log-opts" in data: | |
| del data["log-opts"] | |
| else: | |
| data["log-opts"] = log_cutting | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(data, indent=2)) | |
| # 重启docker服务 | |
| get.act = "restart" | |
| self.docker_service(get) | |
| return public.returnMsg(True, "设置成功!") | |
| except Exception as e: | |
| return public.returnMsg(False, "设置失 败!{}".format(str(e))) | |
| def set_iptables(self, get): | |
| ''' | |
| 设置 Docker 对 iptables 规则的自动配置 | |
| @param get:a | |
| @return: dict | |
| ''' | |
| try: | |
| iptables = get.get("iptables/d", "") | |
| data = self.get_daemon_json() | |
| data["iptables"] = True if iptables == 1 else False | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(data, indent=2)) | |
| # 重启docker服务 | |
| get.act = "restart" | |
| self.docker_service(get) | |
| return public.returnMsg(True, "设置成功!") | |
| except Exception as e: | |
| return public.returnMsg(False, "设置失败!{}".format(str(e))) | |
| def set_live_restore(self, get): | |
| ''' | |
| 设置 docker实时恢复容器 | |
| 允许在 Docker 守护进程发生意外停机或崩溃时保留正在运行的容器状态 | |
| @param get: | |
| @return: dict | |
| ''' | |
| try: | |
| live_restore = get.get("live_restore/d", "") | |
| data = self.get_daemon_json() | |
| data["live-restore"] = True if live_restore == 1 else False | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(data, indent=2)) | |
| # 重启docker服务 | |
| get.act = "restart" | |
| self.docker_service(get) | |
| return public.returnMsg(True, "设置成功!") | |
| except Exception as e: | |
| return public.returnMsg(False, "设置失败!{}".format(str(e))) | |
| def set_drive(self, get): | |
| ''' | |
| 设置docker driver方式 | |
| @param get: | |
| @return: dict | |
| ''' | |
| try: | |
| drive = get.get("driver", "") | |
| data = self.get_daemon_json() | |
| if drive == "systemd": | |
| data["exec-opts"] = ["native.cgroupdriver=systemd"] | |
| elif drive == "cgroupfs": | |
| data["exec-opts"] = ["native.cgroupdriver=cgroupfs"] | |
| elif drive == "" and "exec-opts" in data: | |
| del data["exec-opts"] | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(data, indent=2)) | |
| # 重启docker服务 | |
| get.act = "restart" | |
| self.docker_service(get) | |
| return public.returnMsg(True, "设置成功!") | |
| except Exception as e: | |
| return public.returnMsg(False, "设置失败!{}".format(str(e))) | |
| def set_ipv6_global(self, get): | |
| ''' | |
| 设置全局开启ipv6 | |
| @param get: | |
| @return: dict | |
| ''' | |
| try: | |
| status = get.get("status/d", 0) | |
| ipaddr = get.get("ipaddr", "") | |
| data = self.get_daemon_json() | |
| if status == 1: | |
| data["ipv6"] = True | |
| if ipaddr == "": | |
| subnet = self.random_ipv6_subnet() | |
| data["fixed-cidr-v6"] = subnet | |
| else: | |
| if not self.is_valid_ipv6_subnet(ipaddr): | |
| return public.returnMsg(False, "请输入正确的IPv6地址!") | |
| data["fixed-cidr-v6"] = ipaddr | |
| else: | |
| if "ipv6" in data and data["ipv6"]: | |
| del data["ipv6"] | |
| if "fixed-cidr-v6" in data and data["fixed-cidr-v6"]: | |
| del data["fixed-cidr-v6"] | |
| public.writeFile(self.__CONFIG_FILE, json.dumps(data, indent=2)) | |
| # 重启docker服务 | |
| get.act = "restart" | |
| self.docker_service(get) | |
| return public.returnMsg(True, "设置成功!") | |
| except Exception as e: | |
| return public.returnMsg(False, "设置失败!{}".format(str(e))) | |
| def random_ipv6_subnet(self): | |
| """ | |
| 在2001:db8前缀中生成一个随机IPv6子网 | |
| Returns: | |
| str: Random IPv6 subnet in CIDR format. | |
| """ | |
| import random | |
| prefix = "2001:db8:" | |
| hextets = ["".join(random.choice("123456789abcdef") + ''.join(random.choice("0123456789abcdef") for _ in range(3))) for _ in range(6)] | |
| return prefix + ":".join(hextets) + "/64" | |
| def is_valid_ipv6_subnet(self, subnet): | |
| import ipaddress | |
| try: | |
| # 尝试解析IPv6子网 | |
| ipaddress.IPv6Network(subnet, strict=False) | |
| return True | |
| except (ipaddress.AddressValueError, ValueError) as e: | |
| # 解析失败,不是合法的IPv6子网 | |
| return False | |
| # 2024/12/16 17:49 获取系统信息 | |
| def get_system_info(self, get): | |
| ''' | |
| @name 获取系统信息 | |
| ''' | |
| from btdockerModel.dockerSock.system import dockerSystem | |
| import psutil | |
| system_info = dockerSystem().get_system_info() | |
| if not system_info: | |
| try: | |
| if os.path.exists("/etc/redhat-release"): | |
| OperatingSystem = public.readFile("/etc/redhat-release").strip() | |
| elif os.path.exists("/etc/issue"): | |
| OperatingSystem = public.readFile("/etc/issue").strip() | |
| else: | |
| OperatingSystem = public.ExecShell(". /etc/os-release && echo $VERSION")[0].strip() | |
| except: | |
| OperatingSystem = "Linux系统,无法正确获取版本号!" | |
| system_info = { | |
| "Name": public.ExecShell("hostname")[0].strip(), | |
| "OperatingSystem": OperatingSystem, | |
| "Architecture": public.ExecShell("uname -m")[0].strip(), | |
| "KernelVersion": public.ExecShell("uname -r")[0].strip(), | |
| "NCPU": public.ExecShell("nproc")[0].strip(), | |
| "MemTotal": psutil.virtual_memory().total, | |
| "ServerVersion": "", | |
| "DockerRootDir": "", | |
| } | |
| return public.returnResult(True, data=system_info) | |
| def update_compose(self, get): | |
| ''' | |
| 升级docker-compose版本 | |
| ''' | |
| try: | |
| pid_file = "/tmp/update_dk-compose.pid" | |
| log_file = "/tmp/update_dk-compose.log" | |
| try: | |
| import psutil | |
| p = psutil.Process(int(public.readFile(pid_file))) | |
| if p.is_running(): | |
| return public.returnMsg(True, "升级进程PID正在执行中,请等待完成!") | |
| except: | |
| pass | |
| if os.path.exists(log_file): | |
| public.writeFile(log_file, "") | |
| if os.path.exists(pid_file): | |
| os.remove(pid_file) | |
| # 获取当前compose版本 | |
| key = "dk_compose_version" | |
| skey = "dk_compose_github_version" | |
| compose_version, stderr = public.ExecShell("docker compose version --short") | |
| if stderr != "": | |
| compose_version, stderr = public.ExecShell("docker-compose version --short") | |
| if stderr != "": | |
| return public.returnMsg(False, "获取当前compose版本失败!失败原因:{}".format(stderr)) | |
| # 写入缓存compose version 版本文件 | |
| public.set_cache_func(key, compose_version.strip()) | |
| github_version = public.cache_get(skey) | |
| if not public.cache_get(skey): | |
| # 获取github最新compose版本 | |
| github_version, stderr = public.ExecShell( | |
| ''' | |
| curl -s https://api.github.com/repos/docker/compose/releases/latest | awk -F'"' '/"tag_name":/ {print $4}' | sed 's/^v//' | |
| ''' | |
| ) | |
| if stderr != "": | |
| return public.returnMsg(False, "获取github最新compose版本失败!失败原因:{}".format(stderr)) | |
| # 写入缓存github version 版本 | |
| public.cache_set(skey, github_version.strip(), 86400) | |
| if compose_version.strip() == github_version.strip(): | |
| return public.returnMsg(False, "当前compose版本与github最新版本一致,无需升级!") | |
| if compose_version.strip() < github_version.strip(): | |
| # 删除旧版本 | |
| try: | |
| if os.path.exists("/usr/bin/docker-compose"): | |
| os.remove("/usr/bin/docker-compose") | |
| if os.path.exists("/usr/local/lib/docker/cli-plugins/docker-compose"): | |
| os.remove("/usr/local/lib/docker/cli-plugins/docker-compose") | |
| except: | |
| pass | |
| public.ExecShell( | |
| ''' | |
| nohup bash -c ' | |
| sudo curl -L "https://1ms.run/install/docker-compose/latest/$(uname -s)/$(uname -m)" -o /usr/local/bin/docker-compose && | |
| sudo chmod +x /usr/local/bin/docker-compose && | |
| sudo ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose && | |
| sudo ln -sf /usr/local/bin/docker-compose /usr/libexec/docker/cli-plugins/docker-compose | |
| ' >{log_file} 2>&1 && echo 'bt_successful' >> {log_file} || echo 'bt_failed' >> {log_file} & | |
| echo $! > {pid_file} | |
| '''.format(log_file=log_file, pid_file=pid_file) | |
| ) | |
| return public.returnMsg(True, "正在升级docker-compose版本,请稍后查看日志!最新版本:{}".format(github_version.strip())) | |
| except Exception as e: | |
| return public.returnMsg(False, "升级失败!失败原因:{}".format(str(e))) | |
| def reload_global_config(): | |
| ''' | |
| 重载全局配置文件 | |
| ''' | |
| try: | |
| # 执行重载命令 | |
| stdout, stderr = public.ExecShell("systemctl reload docker") | |
| if stderr: | |
| return public.returnMsg(False, "重载失败,原因:{}".format(stderr)) | |
| return public.returnMsg(True, "重载成功!") | |
| except Exception as e: | |
| error_message = "全局配置文件重载失败:{}".format(str(e)) | |
| dp.write_log(error_message) | |
| return public.returnMsg(False, error_message) | |
| def set_dk_project_path(self,get): | |
| ''' | |
| @name 设置docker项目路径 | |
| @param "data":{"参数名":""} <数据类型> 参数描述 | |
| @return dict{"status":True/False,"msg":"提示信息"} | |
| ''' | |
| if not hasattr(get, 'path') and get.path is None and get.path == "": | |
| return public.returnResult(False, "参数错误,path参数!") | |
| if get.path.strip() == "": | |
| get.path = "/www/dk_project" | |
| project_path_file = "{}/class/btdockerModel/config/project_path.pl".format(public.get_panel_path()) | |
| res = public.writeFile(project_path_file, get.path) | |
| msg = "设置成功!" | |
| if not res: | |
| msg = "设置失败!" | |
| return public.returnMsg(res,msg) |