Linux ip-172-26-2-223 5.4.0-1018-aws #18-Ubuntu SMP Wed Jun 24 01:15:00 UTC 2020 x86_64
Apache
: 172.26.2.223 | : 3.142.171.199
Cant Read [ /etc/named.conf ]
8.1.13
www
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
BLACK DEFEND!
README
+ Create Folder
+ Create File
/
www /
server /
panel /
class_v2 /
btdockerModelV2 /
[ HOME SHELL ]
Name
Size
Permission
Action
__pycache__
[ DIR ]
drwxr-xr-x
config
[ DIR ]
drwxr-xr-x
dockerSock
[ DIR ]
drwxr-xr-x
script
[ DIR ]
drwxr-xr-x
appModel.py
2.68
KB
-rw-r--r--
backupModel.py
7.32
KB
-rw-r--r--
composeModel.py
44.81
KB
-rw-r--r--
containerModel.py
84.01
KB
-rw-r--r--
dk_public.py
7.83
KB
-rw-r--r--
dkgroupModel.py
11.07
KB
-rw-r--r--
dockerBase.py
4.47
KB
-rw-r--r--
host.py
2.06
KB
-rw-r--r--
imageModel.py
35.43
KB
-rw-r--r--
monitorModel.py
3.92
KB
-rw-r--r--
networkModel.py
12.1
KB
-rw-r--r--
projectModel.py
22.59
KB
-rw-r--r--
proxyModel.py
13.71
KB
-rw-r--r--
registryModel.py
14.26
KB
-rw-r--r--
screen.py
2.86
KB
-rw-r--r--
securityModel.py
69.8
KB
-rw-r--r--
setupModel.py
32.98
KB
-rw-r--r--
statusModel.py
9.64
KB
-rw-r--r--
volumeModel.py
6.27
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : projectModel.py
# coding: utf-8 # ------------------------------------------------------------------- # aaPanel # ------------------------------------------------------------------- # Copyright (c) 2014-2099 aaPanel(www.aapanel.com) All rights reserved. # ------------------------------------------------------------------- # Author: wzz <wzz@aapanel.com> # ------------------------------------------------------------------- # ------------------------------ # Docker模型 # ------------------------------ import public import os import time import json import re from btdockerModelV2 import dk_public as dp from btdockerModelV2 import setupModel as ds from btdockerModelV2 import volumeModel as dv from btdockerModelV2.dockerBase import dockerBase from public.validate import Param class main(dockerBase): compose_path = "{}/data/compose".format(public.get_panel_path()) project_path = "/www/dk_project" templates_path = "{}/templates".format(project_path) config_path = "{}/config".format(public.get_panel_path()) info_path = "{}/docker_project_info.json".format(config_path) __first_pl = "{}/first.pl".format(project_path) def __init__(self): self.log_file = "/tmp/dk_project_run.log" self.docker_setup = ds.main() if not os.path.exists(self.templates_path): os.system("mkdir -p {}".format(self.templates_path)) self.compose_cmd = "/usr/bin/docker-compose" if self.docker_setup.check_docker_compose_service()[0] \ else "/usr/local/bin/docker-compose" def __check_conf(self, filename): ''' 验证配置文件是否可执行 @param filename: docker-compose.yml文件路劲 @return: ''' return public.ExecShell("{} -f {} config".format(self.compose_cmd, filename)) def sync_item(self, get): ''' 同步官方可以一键部署的项目 @param get: 空对象 @return: ''' os.remove(self.info_path) project_info = self._get_project_list(get) failed_list = [] successes_list = [] for info in project_info: if info["server_name"]: down_project_yml = self.__download_project_yml(info["server_name"]) if not down_project_yml["status"]: failed_list.append(info["server_name"]) continue successes_list.append(info["server_name"]) data = [{"successes": len(successes_list), "server_name": successes_list}, {"failed": len(failed_list), "server_name": failed_list}] return public.return_message(0, 0, data) def __first_sync_item(self, project_info): ''' 同步官方可以一键部署的项目 @param get: 空对象 @return: ''' failed_list = [] successes_list = [] for info in project_info: if info["server_name"]: down_project_yml = self.__download_project_yml(info["server_name"]) if not down_project_yml["status"]: failed_list.append(info["server_name"]) continue successes_list.append(info["server_name"]) data = [{"successes": len(successes_list), "server_name": successes_list}, {"failed": len(failed_list), "server_name": failed_list}] return data def get_project_list(self, get): ''' 获取支持一键部署的项目列表 @param get: @return: ''' project_info = [] try: if not os.path.exists(self.info_path): down_info = self.__download_info(self.info_path) if not down_info["status"]: return public.return_message(0, 0, project_info) project_info = json.loads(public.readFile(self.info_path)) project_info.sort(key=lambda x: x["sort"]) if not os.path.exists(self.__first_pl): sync_result = self.__first_sync_item(project_info) for result in sync_result: if result.get("successes") and result["successes"] <= 0: return public.return_message(0, 0, project_info) public.ExecShell("echo \"first\" > {}".format(self.__first_pl)) except Exception as e: project_info = [] return public.return_message(0, 0, project_info) def _get_project_list(self, get): ''' 获取支持一键部署的项目列表 @param get: @return: ''' project_info = [] try: if not os.path.exists(self.info_path): down_info = self.__download_info(self.info_path) if not down_info["status"]: return project_info project_info = json.loads(public.readFile(self.info_path)) project_info.sort(key=lambda x: x["sort"]) if not os.path.exists(self.__first_pl): sync_result = self.__first_sync_item(project_info) for result in sync_result: if result.get("successes") and result["successes"] <= 0: return project_info public.ExecShell("echo \"first\" > {}".format(self.__first_pl)) except Exception as e: project_info = [] return project_info def __get_docker_status(self, args): ''' 获取docker安装和启动状态 @param args: @return: ''' return { "installed": self.docker_setup.check_docker_compose_service(), "service_status": self.docker_setup.get_service_status() } def __download_info(self, info_path): ''' 下载版本信息: info.json @param info_path: string info.json文件的路劲 @return: ''' url = "{}/install/lib/docker_project/docker_project_info.json".format(public.get_url()) dp.download_file(url, info_path) if os.path.exists(info_path): return public.return_message(0, 0, public.lang("info.json is downloaded!")) return public.return_message(-1, 0, public.lang("The info.json download failed!")) def __download_project_yml(self, server_name): ''' 下载指定项目压缩包 @param server_name: string 模板名称,如nextcloud @return: ''' try: path = "{}/{}".format(self.templates_path, server_name) filename = "{}/{}.tar.gz".format(self.templates_path, server_name) compose_file = "{}/docker-compose.yml".format(path) url = "{}/install/lib/docker_project/templates/{}.tar.gz".format(public.get_url(), server_name) dp.download_file(url, filename) if not os.path.exists(filename): return public.return_message(-1, 0, public.lang("{} Download failed, please resync!", server_name)) if os.path.getsize(filename) == 0: os.remove(filename) return public.return_message(-1, 0, public.lang("{} Download failed, please resync!", server_name)) self.__tar_x_yml(server_name, path, filename) if os.path.exists(compose_file): check_conf = self.__check_conf(compose_file) if check_conf[1]: return public.return_message(-1, 0, public.lang("{}yml file test failed,{}", server_name, check_conf[1])) return public.return_message(0, 0, public.lang("{} Download completed!", server_name)) except: return public.return_message(-1, 0, public.lang("{} Download failed, please resync!", server_name)) def __tar_x_yml(self, server_name, path=None, filename=None): ''' 解压项目模板方法 @param server_name: 模板名称,如nextcloud @param path: 项目模板路劲,如/www/dk_project/templates/nextcloud @param filename: 项目模板压缩包,如/www/dk_project/templates/nextcloud.tar.gz @return: ''' tar_result = public.ExecShell("tar xvf {} -C {}".format(filename, self.templates_path)) if tar_result[1]: os.remove(path) os.remove(filename) return public.return_message(-1, 0, public.lang("{} Decompression failed", server_name)) return public.return_message(0, 0, public.lang("{} extracted successfully", server_name)) def create_project_volume(self, server_name, project_name, dir_names, volume_path): ''' 创建指定项目的数据存储卷 @param volume_path: @param project_name: string @param dir_names: list [dir_name,dir_name,...] @return: ''' args = public.dict_obj() args.url = "unix:///var/run/docker.sock" # volumes = dv.main().get_volume_list(args) # {'status': True, 'msg': {'volume': [], 'installed': True, 'service_status': True}} # if volumes['status']: # volumes = volumes['msg']['volume'] # else: # volumes = list() # volume的值,一个list: [] for dir_name in dir_names: # # 如果已经存在就跳过 # for volume in volumes: # if dir_name == volume["Name"]: # continue if volume_path == "": path = "{}/projects/{}/data/{}".format(self.project_path, project_name, dir_name) else: path = "{}/data/{}".format(volume_path, dir_name) is_mkdir = public.ExecShell("mkdir -p {}".format(path)) if is_mkdir[1]: return public.return_message(-1, 0, public.lang("Directory creation failed for the following reasons: {}", is_mkdir[1])) args.name = "{}_{}_{}".format(project_name, server_name, dir_name) args.driver = "local" args.driver_opts = {'type': 'none', 'device': path, 'o': 'bind'} args.labels = {} dv.main().add(args) return public.return_message(0, 0, public.lang("The storage volume has been created")) def get_project(self, get): ''' 获取指定一键部署项目的配置信息 @param get: get.server_name @return: ''' # 校验参数 try: get.validate([ Param('server_name').Require().String(), ], [ public.validate.trim_filter(), ]) except Exception as ex: public.print_log("error info: {}".format(ex)) return public.return_message(-1, 0, str(ex)) try: server_name = getattr(get, "server_name") info_path = "{}/{}/conf.json".format(self.templates_path, server_name) project_info = json.loads(public.readFile(info_path)) volume_placeholder = "Default: {}/projects/ your project name /data/".format(self.project_path) total_sum = len(project_info) volume_path = {"id": total_sum + 1, "sort": total_sum + 1, "type": "string", "key": "VOLUME_PATH", "value": "", "placeholder": volume_placeholder, "ps": "Data storage directory"} project_info.append(volume_path) except: project_info = [] return public.return_message(0, 0, project_info) def _get_project(self, get): ''' 获取指定一键部署项目的配置信息 @param get: get.server_name @return: ''' try: server_name = getattr(get, "server_name") info_path = "{}/{}/conf.json".format(self.templates_path, server_name) project_info = json.loads(public.readFile(info_path)) volume_placeholder = "Default: {}/projects/ your project name /data/".format(self.project_path) total_sum = len(project_info) volume_path = {"id": total_sum + 1, "sort": total_sum + 1, "type": "string", "key": "VOLUME_PATH", "value": "", "placeholder": volume_placeholder, "ps": "Data storage directory"} project_info.append(volume_path) except: project_info = [] return project_info def __get_server_ps(self, project_conf, conf_key): ''' 获取对应服务名的标题 @param project_conf: @param conf_key: @return: ''' get = public.dict_obj() for conf in project_conf: if conf["key"] == "SERVER_NAME": get.server_name = conf["value"] server_conf = self._get_project(get) for server in server_conf: if conf_key == server["key"]: return server["ps"] return conf_key def get_project_logs(self, get): """ 获取一键部署日志,websocket @param get: @return: """ get.wsLogTitle = "Please wait to execute the command..." print(self.log_file) get._log_path = self.log_file return self.get_ws_log(get) def create_project(self, get): ''' 创建一键部署的项目 @param get: @return: ''' # {"project_conf": [{"key": "PROJECT_NAME", "value": "sdfasdf"}, {"key": "PORT", "value": "8180"}, # {"key": "DB_ROOT_PASS", "value": "bt_nextcloud"}, {"key": "DB_NAME", "value": "nextcloud"}, # {"key": "DB_USER", "value": "nextcloud"}, {"key": "DB_PASS", "value": "bt_nextcloud"}, # {"key": "VOLUME_PATH", "value": "/www/dk_project/projects/sdfasdf"}, # {"key": "REMARK", "value": "SDFADSF"}, {"key": "SERVER_NAME", "value": "nextcloud"}, # {"key": "VOLUMES", "value": ["nextcloud", "db"]}]} # 校验参数 try: get.validate([ Param('project_conf').Require().List(), ], [ public.validate.trim_filter(), ]) except Exception as ex: public.print_log("error info: {}".format(ex)) return public.return_message(-1, 0, str(ex)) project_conf = getattr(get, "project_conf") remark = "" for conf in project_conf: if conf["key"] != "REMARK" and type(conf["value"]) != list: if re.search(r'\s', conf["value"]): server_ps = self.__get_server_ps(project_conf, conf["key"]) return public.return_message(-1, 0, public.lang("{} cannot contain Spaces", server_ps)) if conf["key"] != "VOLUME_PATH" and conf["key"] != "REMARK": if conf["value"] == "": server_ps = self.__get_server_ps(project_conf, conf["key"]) return public.return_message(-1, 0, public.lang("{} cannot be null!", server_ps)) if conf["key"].upper() == "PROJECT_NAME": project_name = conf["value"].strip() if conf["key"].upper() == "VOLUME_PATH": project_volume = conf["value"].strip() if conf["key"].upper() == "SERVER_NAME": server_name = conf["value"].strip() if conf["key"].upper() == "VOLUMES": # VOLUMES = list volumes = conf["value"] if conf["key"].upper() == "PORT": if dp.check_socket(conf["value"]): return public.return_message(-1, 0, public.lang("Server port [ {}] is occupied, please change to another port!", conf['value'])) project_port = conf["value"] if conf["key"] == "REMARK": remark = conf["value"] config_path = "{}/config/name_map.json".format(public.get_panel_path()) if not os.path.exists(config_path): public.writeFile(config_path, json.dumps({})) if public.readFile(config_path) == '': public.writeFile(config_path, json.dumps({})) name_map = json.loads(public.readFile(config_path)) name_str = 'q18q' + public.GetRandomString(10).lower() name_map[name_str] = project_name project_name = name_str public.writeFile(config_path, json.dumps(name_map)) server_dir = "{}/{}".format(self.templates_path, server_name) project_dir = "{}/projects/{}/{}_{}".format(self.project_path, project_name, project_name, server_name) public.set_module_logs('docker_project', 'create_project', 1) check_result = self.__create_dir(project_dir, project_name, server_name, server_dir) # todo 修改返回内容 只取msg 测试是否取到 if not check_result["status"]: return public.return_message(-1, 0, check_result["msg"]) self.__write_config(project_dir, project_name, server_name, project_conf) self.create_project_volume(server_name, project_name, volumes, project_volume) run_result = self.__project_run(project_dir, project_name) if run_result["status"]: self.__add_sql(project_dir, project_name, server_name, remark) dp.write_log("One-click deployment project [{}] successful!".format(server_name)) return public.return_message(-1, 0, self.__return_msg(project_port)) return public.return_message(-1, 0, run_result) # return public.return_message(-1, 0, run_result["msg"]) def __project_run(self, project_dir, project_name): ''' 运行项目 @param project_dir: 项目运行目录 @param server_name: 服务名称 @return: ''' filename = "{}/docker-compose.yml".format(project_dir) check_result = self.__check_conf(filename) if check_result[1]: return public.return_message(-1, 0, public.lang("Project startup failed {}", check_result[1])) public.ExecShell("echo -n > {}".format(self.log_file)) public.ExecShell("nohup {} -f {}/docker-compose.yml up -d >> {} 2>&1 &&" " echo 'bt_successful' >> {} || echo 'bt_failed' >> {} &" .format( self.compose_cmd, project_dir, self.log_file, self.log_file, self.log_file )) return public.return_message(0, 0, public.lang("Start creating the project")) def __create_dir(self, project_dir, project_name, server_name, server_dir): ''' 创建项目目录 @param project_dir: 项目目录 @param project_name: 项目名称 @param server_dir: 服务源目录 @return: ''' if self.__check_repeat(project_dir, project_name, server_name): return public.return_message(-1, 0, public.lang("{} already exists, please change the project name", project_name)) mk_result = public.ExecShell("mkdir -p {}".format(project_dir)) if mk_result[1]: return public.return_message(-1, 0, public.lang("User project directory failed to create,details: {}", mk_result[1])) cp_result = public.ExecShell("cp -a {}/. {}/".format(server_dir, project_dir)) if cp_result[1]: return public.return_message(-1, 0, public.lang("Failed to copy project directory. Details: {}", cp_result[1])) return public.return_message(0, 0, public.lang("")) def __add_sql(self, project_dir, project_name, server_name, remark): ''' 添加项目到docker数据库中 @param project_dir: 项目路劲 @param project_name: 项目名称 @return: ''' pdata = { "name": public.xsssec("{}_{}".format(project_name, server_name)), "status": "1", "path": "{}/docker-compose.yml".format(project_dir), "template_id": "", "time": time.time(), "remark": public.xsssec(remark) } dp.sql("stacks").insert(pdata) def __return_msg(self, project_port): ''' 创建成功后返回给用户的数据 @param project_port: @return: ''' server_ip = public.get_server_ip() local_ip = public.GetLocalIp() data = {"protocol": "http", "server_ip": server_ip, "local_ip": local_ip, "port": project_port} return public.return_message(0, 0, data) def __check_repeat(self, project_dir, project_name, server_name): ''' 检查是否存在相同项目 @param project_dir: 项目路劲 @return: ''' # if os.path.exists(project_dir): # return True stacks_info = dp.sql("stacks").where("name=?", ("{}_{}".format(project_name, server_name),)).find() if stacks_info: return True return False def __write_config(self, project_dir, project_name, server_name, project_conf): ''' 写配置文件 @param project_dir: 用户项目目录 @param project_name: 项目名称 @param server_name: 服务名称,如nextcloud @param project_conf: 新的配置文件内容 @return: ''' old_env_path = "{}/{}/.env".format(self.templates_path, server_name) new_env_path = "{}/.env".format(project_dir) env_conf = "" if not os.path.exists(old_env_path): public.ExecShell("echo > {}".format(old_env_path)) with open(old_env_path) as env: lines = env.readlines() # 取旧文件转字典 old_dict = {} for line in lines: if "=" in line: temp = line.split("=") old_dict[temp[0]] = temp[1] # 新数据转字典 new_dict = {} for conf in project_conf: if conf["key"] == "VOLUME_PATH": project_volume = conf["value"] if "Default path" in project_volume: conf["value"] = "{}/{}/data/".format(self.project_path, project_name) continue if conf["key"] == "VOLUMES": continue new_dict[conf["key"].upper()] = conf["value"] # 旧字典更新新字典的内容 old_dict.update(new_dict) # 拼接成新的环境变量文件 for key, value in old_dict.items(): env_conf += "{}={}\n".format(key, value.strip()) public.writeFile(new_env_path, env_conf) return True def sync_compose_template(self, server_name): ''' 同步模板到项目模板页面 @param server_name: 模板名称 @return: ''' data = dp.sql("templates").where("name=?", (server_name,)).find() # if data: dp.sql("templates").delete(id=data["id"]) if data: return pdata = { "name": server_name, "remark": "aaPanel Docker Quick Deployment templates only [Do not delete them and use them separately to create projects]", "path": "{}/{}/docker-compose.yml".format(self.templates_path, server_name) } dp.sql("templates").insert(pdata) dp.write_log("Add template [{}] successful!".format(server_name))
Close