1692 lines
75 KiB
Python
1692 lines
75 KiB
Python
# coding: utf-8
|
||
# -------------------------------------------------------------------
|
||
# yakpanel
|
||
# -------------------------------------------------------------------
|
||
# Copyright (c) 2015-2099 yakpanel(http://www.yakpanel.com) All rights reserved.
|
||
# -------------------------------------------------------------------
|
||
# Author: wzz <wzz@yakpanel.com>
|
||
# -------------------------------------------------------------------
|
||
import json
|
||
import os
|
||
# ------------------------------
|
||
# 一键应用环境包模型
|
||
# ------------------------------
|
||
import sys
|
||
import time
|
||
|
||
if "/www/server/panel/class" not in sys.path:
|
||
sys.path.insert(0, "/www/server/panel/class")
|
||
|
||
os.chdir("/www/server/panel")
|
||
import public
|
||
import panelMysql
|
||
import db_mysql
|
||
|
||
try:
|
||
from YakPanel import cache
|
||
except:
|
||
from cachelib import SimpleCache
|
||
cache = SimpleCache()
|
||
|
||
|
||
class main():
|
||
def __init__(self):
|
||
# 2024/5/6 上午10:09 前期临时使用版本列表,后期再动态获取
|
||
self._php_versions = ['52', '53', '54', '55', '56', '70', '71', '72', '73', '74', '80', '81', '82', '83']
|
||
self._mysql_versions = ['5.1', '5.5', '5.6', '5.7', '8.0']
|
||
# self._nginx_versions = ['1.8', '1.10', '1.12', '1.14', '1.16', '1.18', '1.20', '1.22', '1.24']
|
||
self._nginx_install = True
|
||
self._php_install = True
|
||
self._mysql_install = True
|
||
self._ftpd_install = True
|
||
self.APP_PACKAGE_DB_NAME = "BT_APP_PACKAGE_DB_NAME"
|
||
self.APP_PACKAGE_DB_USER = "BT_APP_PACKAGE_DB_USER"
|
||
self.APP_PACKAGE_DB_PASS = "BT_APP_PACKAGE_DB_PASS"
|
||
self._MYSQLDUMP_BIN = public.get_mysqldump_bin()
|
||
self._rewrite_file = "{panel_path}/vhost/rewrite/{site_name}.conf"
|
||
self._package_dir = "/www/backup/package"
|
||
self._upload_package_dir = "/www/backup/upload_package"
|
||
self._temp_backup_dir = "{}/temp".format(self._package_dir)
|
||
self._temp_upload_package_dir = "{}/temp".format(self._upload_package_dir)
|
||
self._upload_package_path = os.path.join(self._upload_package_dir, "{app_name}")
|
||
self._backup_dir = None
|
||
self.skey = "app_package_create"
|
||
self._package_conf = {
|
||
"app_name": "",
|
||
"app_version": "",
|
||
"exclude_dir": [],
|
||
"php_versions": [],
|
||
"php_libs": [],
|
||
"php_functions": "",
|
||
"mysql_versions": [],
|
||
"init_sql": 0,
|
||
"db_character": "",
|
||
"db_config_file": [],
|
||
"nginx_install": True,
|
||
"php_install": True,
|
||
"mysql_install": False,
|
||
"ftpd_install": True,
|
||
"run_path": "/",
|
||
"dir_permission": [],
|
||
"update_log": "",
|
||
"size": 0,
|
||
"success_url": "",
|
||
}
|
||
|
||
# 2024/5/6 上午10:26 返回支持选择的PHP列表
|
||
def get_php_versions(self, get):
|
||
'''
|
||
@name 返回支持选择的PHP列表
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
return {
|
||
"used": public.get_site_php_version(get.site_name),
|
||
"versions": self._php_versions,
|
||
}
|
||
|
||
# 2024/5/6 上午10:26 返回支持的mysql列表
|
||
def get_mysql_versions(self, get):
|
||
'''
|
||
@name 返回支持的mysql列表
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
used = "00"
|
||
if os.path.exists("{}/mysql/bin/mysqld".format(public.get_setup_path())):
|
||
version = public.ReadFile("{}/mysql/version.pl".format(public.get_setup_path()))
|
||
if version != "" and "." in version:
|
||
used = version.rsplit(".", 1)[0]
|
||
|
||
return {
|
||
"used": used if "." in used else "00",
|
||
"versions": self._mysql_versions,
|
||
}
|
||
|
||
# 2024/5/6 上午10:38 获取指定版本PHP的当前配置情况
|
||
def get_php_config(self, get):
|
||
'''
|
||
@name 获取指定版本PHP的当前配置情况
|
||
@author wzz <2024/5/6 上午10:40>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.version = get.get("version/s", "00")
|
||
if get.version == "00":
|
||
return public.returnResult(status=False, msg="php_version不能为空,请传入需要获取扩展的PHP版本")
|
||
|
||
import ajax
|
||
a = ajax.ajax()
|
||
res = a.GetPHPConfig(get)
|
||
|
||
is_install = []
|
||
for r in res["libs"]:
|
||
if r["status"]:
|
||
is_install.append(r)
|
||
|
||
res["libs"] = is_install
|
||
|
||
return public.returnResult(status=True, data=res)
|
||
|
||
# 2024/5/8 下午4:31 获取环境信息
|
||
def get_env_info(self, get):
|
||
'''
|
||
@name 获取环境信息
|
||
@author wzz <2024/5/8 下午4:31>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.site_name = get.get("site_name/s", "")
|
||
if get.site_name == "":
|
||
return public.returnResult(status=False, msg="site_name不能为空")
|
||
|
||
result = cache.get(self.skey)
|
||
last_php_functions = ""
|
||
last_php_versions = ""
|
||
last_mysql_versions = ""
|
||
last_init_sql = 0
|
||
last_db_name = ""
|
||
last_db_id = ""
|
||
last_db_config_files_l = []
|
||
if isinstance(result, dict):
|
||
last_php_functions = result["php_functions"] if "php_functions" in result else ""
|
||
last_php_versions = result["php_versions"].split(",") if "php_versions" in result else ""
|
||
last_mysql_versions = result["mysql_versions"].split(",") if "mysql_versions" in result else ""
|
||
last_init_sql = result["init_sql"] if "init_sql" in result else 0
|
||
last_db_config_files = result["db_config_files"] if "db_config_files" in result else []
|
||
for db_c in last_db_config_files:
|
||
last_db_config_files_l.append({"file": db_c, "body": ""})
|
||
last_db_name = result["db_name"] if "db_name" in result else ""
|
||
last_db_id = result["db_id"] if "db_id" in result else None
|
||
|
||
php_version = self.get_php_versions(get)
|
||
php_version["last_php_versions"] = last_php_versions
|
||
mysql_version = self.get_mysql_versions(get)
|
||
mysql_version["last_mysql_versions"] = last_mysql_versions
|
||
mysql_version["last_init_sql"] = last_init_sql
|
||
mysql_version["last_db_config_files"] = last_db_config_files_l
|
||
mysql_version["last_db_name"] = last_db_name
|
||
mysql_version["last_db_id"] = last_db_id
|
||
|
||
data = {
|
||
"php": php_version,
|
||
"mysql": mysql_version,
|
||
"db": {
|
||
"used": {},
|
||
"all": [],
|
||
},
|
||
"db_config_file": [],
|
||
"last_php_functions": last_php_functions,
|
||
}
|
||
|
||
get.site_info = public.M('sites').where('name=?', (get.site_name,)).find()
|
||
if not get.site_info:
|
||
return public.returnResult(status=False, msg="获取网站信息失败")
|
||
|
||
get.db_info = public.M('databases').where('pid=?', (get.site_info['id'],)).find()
|
||
get.db_all = public.M('databases').select()
|
||
data["db"]["all"] = get.db_all
|
||
get.config_list = []
|
||
if get.db_info:
|
||
data["db"]["used"] = get.db_info
|
||
|
||
stdout, stderr = public.ExecShell("find {site_path}/* -name *.php|xargs grep \"{db_name}\"".format(
|
||
site_path=get.site_info["path"],
|
||
db_name=get.db_info["name"],
|
||
))
|
||
find_result = stdout.split("\n")
|
||
for fr in find_result:
|
||
if not fr:
|
||
continue
|
||
|
||
find_file = fr.split(":")[0]
|
||
if not os.path.exists(find_file):
|
||
continue
|
||
if not find_file.endswith(".php"):
|
||
continue
|
||
find_body = fr.split(":")[1]
|
||
if not find_body:
|
||
continue
|
||
|
||
if len(get.config_list) > 0:
|
||
for conf in get.config_list:
|
||
if find_file in conf["file"]:
|
||
break
|
||
else:
|
||
get.config_list.append({"file": find_file, "body": find_body})
|
||
else:
|
||
get.config_list.append({"file": find_file, "body": find_body})
|
||
|
||
data["db_config_file"] = get.config_list
|
||
self._package_conf["db_config_file"] = get.config_list
|
||
|
||
return public.returnResult(status=True, data=data)
|
||
|
||
# 2024/5/6 下午3:50 获取指定目录的权限信息
|
||
def get_path_permission(self, get):
|
||
'''
|
||
@name 获取指定目录的权限信息
|
||
@author wzz <2024/5/6 下午3:51>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
try:
|
||
import pwd
|
||
site_path_stat = os.stat(get.check_path)
|
||
info = pwd.getpwuid(site_path_stat.st_uid)
|
||
|
||
return {
|
||
"path": get.check_path,
|
||
"pw_name": info.pw_name,
|
||
"st_mode": site_path_stat.st_mode,
|
||
}
|
||
except Exception as e:
|
||
return {}
|
||
|
||
# 2024/5/11 下午6:02 列出至少X级的目录
|
||
def scan_directory(self, directory):
|
||
for root, dirs, files in os.walk(directory):
|
||
yield root, dirs, files
|
||
# 限制深度为2
|
||
if root.count(os.sep) >= directory.count(os.sep) + 2:
|
||
del dirs[:]
|
||
|
||
# 2024/5/11 上午11:34 根据目录获取最多两层目录
|
||
def get_dir_list(self, get):
|
||
'''
|
||
@name 根据目录获取最多两层目录
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.path = get.site_info["path"]
|
||
get.dir_permission_list = []
|
||
has_root = False
|
||
root_path = ""
|
||
for root, dirs, files in self.scan_directory(get.path):
|
||
if not has_root:
|
||
get.check_path = root
|
||
path_perm = self.get_path_permission(get)
|
||
path_perm["path"] = "/"
|
||
if path_perm:
|
||
get.dir_permission_list.append(path_perm)
|
||
has_root = True
|
||
root_path = root
|
||
|
||
if len(dirs) > 0:
|
||
for d in dirs:
|
||
get.check_path = os.path.join(root, d)
|
||
path_perm = self.get_path_permission(get)
|
||
path_perm["path"] = get.check_path.replace(root_path, "")
|
||
if path_perm:
|
||
get.dir_permission_list.append(path_perm)
|
||
|
||
if len(files) > 0:
|
||
for f in files:
|
||
get.check_path = os.path.join(root, f)
|
||
path_perm = self.get_path_permission(get)
|
||
path_perm["path"] = get.check_path.replace(root_path, "")
|
||
if path_perm:
|
||
get.dir_permission_list.append(path_perm)
|
||
|
||
# 2024/5/6 下午3:52 为指定目录设置权限
|
||
def set_path_permission(self, get):
|
||
'''
|
||
@name 为指定目录设置权限
|
||
@author wzz <2024/5/6 下午3:52>
|
||
@param get.path/s: 指定目录
|
||
get.permission/dict = {
|
||
"pw_name": "root",
|
||
"st_mode": 16877
|
||
}
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
try:
|
||
import pwd
|
||
import stat
|
||
pw_info = pwd.getpwnam(get.permission["pw_name"])
|
||
public.ExecShell("chown -R {}:{} {}".format(pw_info.pw_uid, pw_info.pw_gid, get.path))
|
||
public.ExecShell("chmod -R {} {}".format(stat.S_IMODE(get.permission["st_mode"]), get.path))
|
||
|
||
# 2024/5/6 下午3:54 检查是否设置成功
|
||
site_path_stat = os.stat(get.path)
|
||
info = pwd.getpwuid(site_path_stat.st_uid)
|
||
if info.pw_name == get.permission["pw_name"] and site_path_stat.st_mode == get.permission["st_mode"]:
|
||
return public.returnResult(status=True, msg="Successfully set")
|
||
else:
|
||
return public.returnResult(status=False, msg="设置失败")
|
||
except Exception as e:
|
||
return public.returnResult(status=False, msg="设置失败: {}".format(str(e)))
|
||
|
||
# 2024/5/6 下午3:30 获取指定网站的根目录权限和运行目录权限
|
||
def get_site_permission(self, get):
|
||
'''
|
||
@name 获取指定网站的根目录权限和运行目录权限
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
try:
|
||
get.check_path = get.site_info["path"]
|
||
get.root_path_permission = self.get_path_permission(get)
|
||
get.root_path_permission.pop("path")
|
||
from panelSite import panelSite
|
||
site_obj = panelSite()
|
||
get.id = get.site_info["id"]
|
||
runPath = site_obj.GetSiteRunPath(get)
|
||
get.check_path = get.site_info["path"] + runPath["runPath"]
|
||
get.run_path = runPath["runPath"]
|
||
get.run_path_permission = self.get_path_permission(get)
|
||
get.run_path_permission.pop("path")
|
||
|
||
# 2024/5/6 下午3:37 获取指定目录权限
|
||
get.dir_permission = {
|
||
"root_permission": get.root_path_permission,
|
||
"run_permission": get.run_path_permission,
|
||
}
|
||
except Exception as e:
|
||
get.dir_permission = {}
|
||
|
||
# 2024/5/6 下午5:01 获取系统类型
|
||
def get_os_type(self):
|
||
'''
|
||
@name 获取系统类型
|
||
@author wzz <2024/5/6 下午5:02>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
if os.path.exists('/usr/bin/yum'):
|
||
return "1"
|
||
elif os.path.exists('/usr/bin/apt-get'):
|
||
return "3"
|
||
else:
|
||
return "0"
|
||
|
||
# 2024/5/6 下午4:54 安装指定运行环境
|
||
def install_env_soft(self, get):
|
||
'''
|
||
@name 安装指定运行环境
|
||
@author wzz <2024/5/6 下午4:55>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.lib_name = get.get("name/s", "")
|
||
get.version = get.get("version/s", "")
|
||
if get.lib_name == "" or get.version == "":
|
||
return public.returnResult(status=False, msg="name或version不能为空")
|
||
|
||
# 2024/3/28 上午 10:36 检测是否已存在安装任务
|
||
mmsg = "安装[{}]".format(get.lib_name + "-" + get.version)
|
||
if public.M('tasks').where('name=? and status=?', (mmsg, "-1")).count():
|
||
return public.returnMsg(False, "已存在安装任务,请勿重复添加!")
|
||
|
||
public.ExecShell("rm -rf {}/install/{}.sh".format(public.get_panel_path(), get.lib_name))
|
||
execstr = ("wget -O /tmp/{name}.sh {url}/install/{os_type}/{name}.sh && "
|
||
"bash /tmp/{name}.sh install {version}").format(
|
||
name=get.lib_name,
|
||
url=public.get_url(),
|
||
os_type=self.get_os_type(),
|
||
version=get.version,
|
||
)
|
||
public.M('tasks').add('id,name,type,status,addtime,execstr',
|
||
(None, mmsg, 'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr))
|
||
|
||
return public.returnResult(status=True, msg="安装任务添加成功")
|
||
|
||
# 2024/5/6 下午5:07 将指定目录压缩成tar.gz包
|
||
def tar_path(self, get):
|
||
'''
|
||
@name 将指定目录压缩成tar.gz包
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.path = get.get("path/s", "")
|
||
if get.path == "":
|
||
return public.returnResult(status=False, msg="path不能为空")
|
||
|
||
get.target_path = get.get("target_path/s", "")
|
||
if get.target_path == "":
|
||
return public.returnResult(status=False, msg="target_path不能为空")
|
||
|
||
if not os.path.exists(get.target_path):
|
||
public.ExecShell("mkdir -p {}".format(get.target_path))
|
||
if not os.path.isdir(get.target_path):
|
||
return public.returnResult(status=False, msg="保存位置必须是一个目录")
|
||
|
||
get.package_name = get.get("package_name/s", "")
|
||
if get.package_name == "":
|
||
return public.returnResult(status=False, msg="package_name不能为空")
|
||
get.package_name = get.package_name.replace(".tar.gz", "")
|
||
|
||
# 2024/5/6 下午5:08 排除的目录
|
||
exclude = [
|
||
get.path + "/.git",
|
||
get.path + "/.svn",
|
||
get.path + "/.idea",
|
||
get.path + "/.vscode",
|
||
get.path + "/.vs",
|
||
get.path + "/.github",
|
||
get.path + "/.gitignore",
|
||
get.path + "/.gitattributes",
|
||
get.path + "/.gitmodules",
|
||
get.path + "/.gitkeep",
|
||
get.path + "/.gitlab-ci.yml",
|
||
get.path + "/.gitlab",
|
||
get.path + "/.gitlab-ci",
|
||
get.path + "/.user.ini",
|
||
]
|
||
try:
|
||
exclude.extend(get.exclude_dir)
|
||
except:
|
||
pass
|
||
|
||
exclude_str = ""
|
||
for e in exclude:
|
||
if not os.path.exists(e):
|
||
continue
|
||
|
||
exclude_str += " --exclude='{}'".format(e)
|
||
|
||
temp_sites_path = os.path.join(self._temp_backup_dir, "temp_sites")
|
||
if not os.path.exists(temp_sites_path):
|
||
public.ExecShell("mkdir -p {}".format(temp_sites_path))
|
||
if not os.path.exists(os.path.join(temp_sites_path, get.app_name)):
|
||
public.ExecShell("mkdir -p {}".format(os.path.join(temp_sites_path, get.app_name)))
|
||
public.ExecShell(r"\cp -r {path}/* {temp_sites_path}/{app_name}/".format(
|
||
path=get.path,
|
||
temp_sites_path=temp_sites_path,
|
||
app_name=get.app_name,
|
||
))
|
||
|
||
public.ExecShell(
|
||
"cd {temp_sites_path} && tar -zcvf {target_path}/{package_name}.tar.gz {exclude_str} {target_dir} ".format(
|
||
temp_sites_path=temp_sites_path,
|
||
target_path=get.target_path,
|
||
package_name=get.package_name,
|
||
exclude_str=exclude_str,
|
||
target_dir=get.app_name,
|
||
))
|
||
|
||
if not os.path.exists("{}/{}.tar.gz".format(get.target_path, get.package_name)):
|
||
return public.returnResult(status=False, msg="打包失败")
|
||
|
||
return public.returnResult(status=True, msg="打包成功")
|
||
|
||
def __get_db_name_config(self, db_name: str):
|
||
from database import database
|
||
database = database()
|
||
db_find = public.M("databases").where("name=? AND LOWER(type)=LOWER('mysql')", (db_name,)).find()
|
||
|
||
if db_find["db_type"] == 0: # 本地数据库
|
||
result = panelMysql.panelMysql().execute("show databases")
|
||
isError = database.IsSqlError(result)
|
||
if isError:
|
||
return public.returnResult(status=False, msg=isError)
|
||
db_password = public.M("config").where("id=?", (1,)).getField("mysql_root")
|
||
if not db_password:
|
||
return public.returnResult(status=False, msg="数据库密码为空!请先设置数据库密码!")
|
||
try:
|
||
db_port = int(panelMysql.panelMysql().query("show global variables like 'port'")[0][1])
|
||
except:
|
||
db_port = 3306
|
||
if not db_password:
|
||
return public.returnResult(status=False, msg="{} 数据库密码不能为空".format(db_find["name"]))
|
||
conn_config = {
|
||
"db_host": "localhost",
|
||
"db_port": db_port,
|
||
"db_user": db_find["username"],
|
||
"db_password": db_find["password"],
|
||
}
|
||
elif db_find["db_type"] == 1:
|
||
# 远程数据库
|
||
conn_config = json.loads(db_find["conn_config"])
|
||
res = database.CheckCloudDatabase(conn_config)
|
||
if isinstance(res, dict): return public.returnResult(status=False, msg=res)
|
||
conn_config["db_port"] = int(conn_config["db_port"])
|
||
elif db_find["db_type"] == 2:
|
||
conn_config = public.M("database_servers").where("id=? AND LOWER(db_type)=LOWER('mysql')",
|
||
db_find["sid"]).find()
|
||
res = database.CheckCloudDatabase(conn_config)
|
||
if isinstance(res, dict): return public.returnResult(status=False, msg=res)
|
||
conn_config["db_name"] = None
|
||
conn_config["db_port"] = int(conn_config["db_port"])
|
||
else:
|
||
return public.returnResult(status=False, msg="{} 未知的数据库类型".format(db_find["name"]))
|
||
return public.returnResult(status=True, data=conn_config)
|
||
|
||
# 2024/5/7 上午10:24 备份指定数据库为sql文件
|
||
def backup_database(self, get):
|
||
'''
|
||
@name 备份指定数据库为sql文件
|
||
@author wzz <2024/5/7 上午10:28>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.db_name = get.get("db_name/s", "")
|
||
if get.db_name == "":
|
||
return public.returnResult(status=False, msg="db_name不能为空")
|
||
get.db_id = get.get("db_id/s", "")
|
||
if get.db_id == "":
|
||
return public.returnResult(status=False, msg="db_id不能为空")
|
||
|
||
if not os.path.exists(self._MYSQLDUMP_BIN):
|
||
return public.returnResult(status=False, msg="缺少备份工具,请先通过软件管理安装MySQL!")
|
||
|
||
db_find = public.M("databases").where("id=? AND name=? AND LOWER(type)=LOWER('mysql')",
|
||
(get.db_id, get.db_name)).find()
|
||
if not db_find:
|
||
return public.returnResult(status=False, msg="数据库[{}]不存在".format(get.db_name))
|
||
|
||
from database import database
|
||
database = database()
|
||
|
||
db_name = db_find["name"]
|
||
|
||
conn_config = self.__get_db_name_config(db_name)
|
||
if not conn_config["status"]:
|
||
return conn_config
|
||
|
||
conn_config = conn_config["data"]
|
||
|
||
mysql_obj = db_mysql.panelMysql()
|
||
flag = mysql_obj.set_host(
|
||
conn_config["db_host"],
|
||
conn_config["db_port"],
|
||
None,
|
||
conn_config["db_user"],
|
||
conn_config["db_password"]
|
||
)
|
||
|
||
if flag is False:
|
||
return public.returnMsg(False, database.GetMySQLError(mysql_obj._ex))
|
||
|
||
# 2024/5/7 上午10:56 备份目录待定
|
||
self._MYSQL_BACKUP_DIR = "/www/backup/database"
|
||
db_backup_dir = os.path.join(self._MYSQL_BACKUP_DIR, db_name)
|
||
if not os.path.exists(db_backup_dir):
|
||
os.makedirs(db_backup_dir)
|
||
|
||
file_name = "{db_name}_{backup_time}_mysql_data_{number}".format(
|
||
db_name=db_name,
|
||
backup_time=time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime()),
|
||
number=public.GetRandomString(5),
|
||
)
|
||
|
||
get.db_charset = public.get_database_character(db_name)
|
||
self._package_conf["db_character"] = get.db_charset
|
||
|
||
set_gtid_purged = ""
|
||
resp = public.ExecShell("{} --help | grep set-gtid-purged >> /tmp/backup_sql.log".format(
|
||
self._MYSQLDUMP_BIN))[0]
|
||
if resp.find("--set-gtid-purged") != -1:
|
||
set_gtid_purged = "--set-gtid-purged=OFF"
|
||
|
||
if db_find["db_type"] == 2:
|
||
db_user = conn_config["db_user"]
|
||
db_password = conn_config["db_password"]
|
||
db_port = int(conn_config["db_port"])
|
||
else:
|
||
db_user = "root"
|
||
db_password = public.M("config").where("id=?", (1,)).getField("mysql_root")
|
||
db_port = conn_config["db_port"]
|
||
|
||
shell = "'{mysqldump_bin}' {set_gtid_purged} --opt --skip-lock-tables --single-transaction --routines --events --skip-triggers --default-character-set='{db_charset}' --force " \
|
||
"--host='{db_host}' --port={db_port} --user='{db_user}' --password='{db_password}' '{db_name}'".format(
|
||
mysqldump_bin=self._MYSQLDUMP_BIN,
|
||
set_gtid_purged=set_gtid_purged,
|
||
db_charset=get.db_charset,
|
||
db_host=conn_config["db_host"],
|
||
db_port=db_port,
|
||
db_user=db_user,
|
||
db_password=db_password,
|
||
db_name=db_name,
|
||
)
|
||
|
||
get.export_file = os.path.join(db_backup_dir, file_name + ".sql")
|
||
shell += "| tee /tmp/backup_sql.log > '{backup_path}' ".format(backup_path=get.export_file)
|
||
public.ExecShell(shell, env={"MYSQL_PWD": conn_config["db_password"]})
|
||
|
||
if not os.path.exists(get.export_file):
|
||
return public.returnResult(status=False, msg="备份失败")
|
||
|
||
return public.returnResult(status=True, msg="备份成功", data={"file": get.export_file})
|
||
|
||
# 2024/5/7 下午5:24 备份指定网站的伪静态
|
||
def backup_rewrite(self, get):
|
||
'''
|
||
@name 备份指定网站的伪静态
|
||
@author wzz <2024/5/7 下午5:41>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.site_name = get.get("site_name/s", "")
|
||
if get.site_name == "":
|
||
return public.returnResult(status=False, msg="site_name不能为空")
|
||
|
||
self._rewrite_file = self._rewrite_file.format(panel_path=public.get_panel_path(), site_name=get.site_name)
|
||
if not os.path.exists(self._rewrite_file):
|
||
return public.returnResult(status=True, msg="伪静态文件不存在,不需要备份")
|
||
|
||
public.ExecShell(r"\cp -r {rewrite_file} {backup_dir}/rewrite.conf".format(
|
||
rewrite_file=self._rewrite_file,
|
||
backup_dir=self._backup_dir)
|
||
)
|
||
if not os.path.exists("{}/rewrite.conf".format(self._backup_dir)):
|
||
return public.returnResult(status=False, msg="备份失败")
|
||
|
||
return public.returnResult(status=True, msg="备份成功")
|
||
|
||
# 2024/5/9 下午2:19 还原指定包的伪静态到指定网站中
|
||
def restore_rewrite(self, get):
|
||
'''
|
||
@name 还原指定包的伪静态到指定网站中
|
||
@author wzz <2024/5/9 下午2:20>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
self._rewrite_file = self._rewrite_file.format(panel_path=public.get_panel_path(), site_name=get.site_name)
|
||
|
||
public.ExecShell(r"\cp -r {_temp_import_dir}/{app_name}/rewrite.conf {_rewrite_file}".format(
|
||
_temp_import_dir=self._temp_import_dir,
|
||
app_name=get.app_name,
|
||
_rewrite_file=self._rewrite_file,
|
||
))
|
||
|
||
# 2024/5/9 下午6:05 还原指定上传包的伪静态到指定网站中
|
||
def restore_upload_rewrite(self, get):
|
||
'''
|
||
@name 还原指定上传包的伪静态到指定网站中
|
||
@author wzz <2024/5/9 下午6:05>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
self._rewrite_file = self._rewrite_file.format(panel_path=public.get_panel_path(), site_name=get.site_name)
|
||
|
||
public.ExecShell(r"\cp -r {_upload_package_path}/{app_name}/rewrite.conf {_rewrite_file}".format(
|
||
_upload_package_path=self._upload_package_path,
|
||
app_name=get.app_name,
|
||
_rewrite_file=self._rewrite_file,
|
||
))
|
||
|
||
# 2024/5/8 上午9:45 获取指定数据库连接配置文件的相对路径,并将匹配到的数据库账号密码和数据库名
|
||
def get_db_config_file(self, get):
|
||
'''
|
||
@name 获取指定数据库连接配置文件的相对路径,并将匹配到的数据库账号密码和数据库名
|
||
@author wzz <2024/5/8 上午9:45>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
if len(get.db_config_files) == 0:
|
||
return public.returnResult(status=False, msg="数据库配置文件不能为空,请选择.php文件")
|
||
|
||
get.config_list = []
|
||
for db_conf in get.db_config_files:
|
||
if not db_conf:
|
||
continue
|
||
if not os.path.exists(db_conf):
|
||
return public.returnResult(status=False, msg="{}不存在".format(db_conf))
|
||
if not db_conf.endswith(".php"):
|
||
return public.returnResult(status=False, msg="{}不是PHP文件".format(db_conf))
|
||
|
||
# 2024/5/9 上午10:06 打开指定文件,将匹配到的内容替换成self.APP_PACKAGE_DB_NAME,self.APP_PACKAGE_DB_USER,self.APP_PACKAGE_DB_PASS
|
||
conf_body = public.readFile(db_conf)
|
||
if not conf_body:
|
||
return public.returnResult(status=False, msg="{}内容为空".format(db_conf))
|
||
|
||
db_find = public.M("databases").where("id=? AND name=? AND LOWER(type)=LOWER('mysql')",
|
||
(get.db_id, get.db_name)).find()
|
||
if db_find:
|
||
conf_body = conf_body.replace(db_find["username"], self.APP_PACKAGE_DB_USER)
|
||
conf_body = conf_body.replace(db_find["name"], self.APP_PACKAGE_DB_NAME)
|
||
conf_body = conf_body.replace(db_find["password"], self.APP_PACKAGE_DB_PASS)
|
||
public.writeFile(db_conf, conf_body)
|
||
|
||
get.config_list.append(db_conf.replace(get.path + "/", ""))
|
||
self._package_conf["db_config_file"] = get.config_list
|
||
|
||
return public.returnResult(status=True, msg="据库连接配置文件处理成功")
|
||
|
||
# 2024/5/7 下午6:32 更新json配置文件
|
||
def update_package_conf(self, get):
|
||
'''
|
||
@name 更新json配置文件
|
||
@author wzz <2024/5/7 下午6:32>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
self._package_conf["app_name"] = get.app_name
|
||
self._package_conf["app_version"] = get.app_version
|
||
self._package_conf["exclude_dir"] = get.exclude_dir
|
||
self._package_conf["php_versions"] = get.php_versions
|
||
self._package_conf["php_functions"] = get.php_functions
|
||
self._package_conf["mysql_versions"] = get.mysql_versions
|
||
self._package_conf["init_sql"] = get.init_sql
|
||
self._package_conf["run_path"] = get.run_path
|
||
self._package_conf["dir_permission"] = get.dir_permission
|
||
self._package_conf["update_log"] = get.update_log
|
||
|
||
public.writeFile("{}/dir_permission.json".format(self._backup_dir), json.dumps(get.dir_permission_list))
|
||
public.writeFile("{}/package.json".format(self._backup_dir), json.dumps(self._package_conf))
|
||
|
||
# 2024/5/8 上午10:05 将所有数据打包成一个压缩包
|
||
def tar_package(self, get):
|
||
'''
|
||
@name 将所有数据打包成一个压缩包
|
||
@author wzz <2024/5/8 上午10:06>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.package_name = get.app_name + "_v" + get.app_version
|
||
get.app_package_dir = os.path.join(self._package_dir, get.app_name)
|
||
if not os.path.exists(get.app_package_dir):
|
||
public.ExecShell("mkdir -p {}".format(get.app_package_dir))
|
||
|
||
if get.export_file != "":
|
||
public.ExecShell(r"\cp -r {export_file} {temp_backup_dir}/packages/{app_name}/init.sql".format(
|
||
export_file=get.export_file,
|
||
temp_backup_dir=self._temp_backup_dir,
|
||
app_name=get.app_name,
|
||
))
|
||
|
||
public.ExecShell(
|
||
"cd {temp_backup_dir}/packages/ && tar -zcvf {app_package_dir}/{package_name}.tar.gz {app_name}".format(
|
||
temp_backup_dir=self._temp_backup_dir,
|
||
app_package_dir=get.app_package_dir,
|
||
package_name=get.package_name,
|
||
app_name=get.app_name,
|
||
))
|
||
|
||
public.ExecShell("rm -rf {}/*".format(self._temp_backup_dir))
|
||
|
||
if not os.path.exists("{}/{}.tar.gz".format(get.app_package_dir, get.package_name)):
|
||
return public.returnResult(status=False, msg="打包失败")
|
||
|
||
get.size = os.path.getsize("{}/{}.tar.gz".format(get.app_package_dir, get.package_name))
|
||
|
||
return public.returnResult(status=True, msg="打包成功",
|
||
data={"file": "{}/{}.tar.gz".format(get.app_package_dir, get.package_name)})
|
||
|
||
# 2024/5/8 下午3:33 更新数据库
|
||
def update_database(self, get):
|
||
'''
|
||
@name 更新数据库
|
||
@author wzz <2024/5/8 下午3:34>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
# CREATE TABLE `app_package` (
|
||
# `id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
# `pid` INTEGER,
|
||
# `site_name` TEXT,
|
||
# `app_name` TEXT,
|
||
# `app_version` TEXT,
|
||
# `package_name` TEXT,
|
||
# `package_path` TEXT,
|
||
# `size` TEXT,
|
||
# `addtime` TEXT,
|
||
# `update_log` TEXT,
|
||
# `php_versions` TEXT,
|
||
# `php_libs` TEXT,
|
||
# `php_functions` TEXT,
|
||
# `mysql_versions` TEXT,
|
||
# `db_character` TEXT,
|
||
# `init_sql` TEXT,
|
||
# `db_config_file` TEXT
|
||
# );
|
||
find_version = public.M('app_package').where('site_name=? AND app_name=? AND app_version=?',
|
||
(get.site_name, get.app_name, get.app_version)).find()
|
||
|
||
try:
|
||
php_libs = json.dumps(self._package_conf["php_libs"])
|
||
except:
|
||
php_libs = "[]"
|
||
|
||
if find_version and "site_name" in find_version:
|
||
public.M('app_package').where('id=?', (find_version["id"],)).save(
|
||
'package_name,package_path,size,update_log,addtime,php_versions,php_libs,php_functions,mysql_versions,db_character,init_sql,db_config_file',
|
||
(get.package_name, "{}/{}.tar.gz".format(get.app_package_dir, get.package_name), get.size,
|
||
get.update_log, time.strftime('%Y-%m-%d %H:%M:%S'), get.php_versions, php_libs, get.php_functions,
|
||
get.mysql_versions, get.db_charset, get.init_sql, json.dumps(get.config_list))
|
||
)
|
||
else:
|
||
public.M('app_package').add(
|
||
'pid,site_name,app_name,app_version,package_name,package_path,size,addtime,update_log,php_libs,php_versions,php_functions,mysql_versions,db_character,init_sql,db_config_file',
|
||
(get.site_info["id"], get.site_name, get.app_name, get.app_version, get.package_name,
|
||
"{}/{}.tar.gz".format(get.app_package_dir, get.package_name), get.size,
|
||
time.strftime('%Y-%m-%d %H:%M:%S'), get.update_log, php_libs, get.php_versions, get.php_functions,
|
||
get.mysql_versions, get.db_charset, get.init_sql, json.dumps(get.config_list))
|
||
)
|
||
|
||
# 2024/5/9 下午4:42 更新上传应用包的数据库
|
||
def update_upload_database(self, get):
|
||
'''
|
||
@name 更新上传应用包的数据库
|
||
@author wzz <2024/5/9 下午4:43>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
# CREATE TABLE `app_package_upload` (
|
||
# `id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
# `app_name` TEXT,
|
||
# `app_version` TEXT,
|
||
# `package_name` TEXT,
|
||
# `package_path` TEXT,
|
||
# `size` TEXT,
|
||
# `addtime` TEXT,
|
||
# `update_log` TEXT,
|
||
# `php_versions` TEXT,
|
||
# `php_libs` TEXT,
|
||
# `php_functions` TEXT,
|
||
# `mysql_versions` TEXT,
|
||
# `db_character` TEXT,
|
||
# `init_sql` TEXT,
|
||
# `db_config_file` TEXT
|
||
# );
|
||
find_version = public.M('app_package_upload').where('app_name=? AND app_version=?',
|
||
(get.app_name, get.package_info["app_version"])).find()
|
||
|
||
try:
|
||
php_libs = json.dumps(get.package_info["php_libs"])
|
||
except:
|
||
php_libs = "[]"
|
||
|
||
self._upload_package_path = self._upload_package_path.format(app_name=get.app_name)
|
||
|
||
if find_version and "app_name" in find_version:
|
||
public.M('app_package_upload').where('id=?', (find_version["id"],)).save(
|
||
'package_path,size,update_log,addtime,php_versions,php_libs,php_functions,mysql_versions,db_character,init_sql,db_config_file',
|
||
(self._upload_package_path, get.size, get.package_info["update_log"],
|
||
time.strftime('%Y-%m-%d %H:%M:%S'), get.package_info["php_versions"], php_libs, get.package_info["php_functions"],
|
||
get.package_info["mysql_versions"], get.package_info["db_character"], get.package_info["init_sql"],
|
||
json.dumps(get.package_info["db_config_file"]))
|
||
)
|
||
else:
|
||
public.M('app_package_upload').add(
|
||
'app_name,app_version,package_path,size,addtime,update_log,php_libs,php_versions,php_functions,mysql_versions,db_character,init_sql,db_config_file',
|
||
(get.app_name, get.package_info["app_version"],
|
||
self._upload_package_path, get.size,
|
||
time.strftime('%Y-%m-%d %H:%M:%S'), get.package_info["update_log"], php_libs, get.package_info["php_versions"],
|
||
get.package_info["php_functions"], get.package_info["mysql_versions"], get.package_info["db_character"],
|
||
get.package_info["init_sql"], json.dumps(get.package_info["db_config_file"]))
|
||
)
|
||
|
||
# 2024/5/6 上午10:49 创建一件应用环境包
|
||
def create(self, get):
|
||
'''
|
||
@name 创建一件应用环境包
|
||
@author wzz <2024/5/6 上午10:50>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.site_name = get.get("site_name/s", "")
|
||
if get.site_name == "":
|
||
return public.returnResult(status=False, msg="site_name不能为空")
|
||
|
||
get.app_name = get.get("app_name/s", "")
|
||
if get.app_name == "":
|
||
return public.returnResult(status=False, msg="app_name不能为空")
|
||
get.app_version = get.get("app_version/s", "")
|
||
if get.app_version == "":
|
||
return public.returnResult(status=False, msg="app_version不能为空")
|
||
|
||
get.php_versions = get.get("php_versions/s", "00")
|
||
# get.php_libs = get.get("php_libs/s", "")
|
||
get.php_functions = get.get("php_functions/s", "")
|
||
get.mysql_versions = get.get("mysql_versions/s", "00")
|
||
get.init_sql = int(get.get("init_sql/d", 0))
|
||
get.db_name = get.get("db_name/s", "")
|
||
if get.db_name == "" and get.init_sql == 1:
|
||
return public.returnResult(status=False, msg="db_name不能为空")
|
||
get.db_id = get.get("db_id/s", "")
|
||
if get.db_id == "" and get.init_sql == 1:
|
||
return public.returnResult(status=False, msg="db_id不能为空")
|
||
|
||
get.exclude_dir = get.get("exclude_dir", "[]")
|
||
if type(get.exclude_dir) == str:
|
||
try:
|
||
get.exclude_dir = json.loads(get.exclude_dir)
|
||
except:
|
||
get.exclude_dir = []
|
||
else:
|
||
get.exclude_dir = []
|
||
|
||
get.db_config_files = get.get("db_config_files", "[]")
|
||
if type(get.db_config_files) == str:
|
||
get.db_config_files = json.loads(get.db_config_files)
|
||
|
||
get.success_url = get.get("success_url/s", "")
|
||
if not get.success_url.startswith("/"):
|
||
get.success_url = get.success_url + "/"
|
||
self._package_conf["success_url"] = get.success_url
|
||
|
||
get.update_log = get.get("update_log/s", "")
|
||
get.update_log = public.xssencode2(get.update_log)
|
||
|
||
# 2024/5/9 上午11:56 处理php扩展和函数
|
||
get.version = public.get_site_php_version(get.site_name)
|
||
if get.version != "00":
|
||
php_config = self.get_php_config(get)
|
||
self._package_conf["php_libs"] = php_config["data"]["libs"]
|
||
self._package_conf["php_functions"] = get.php_functions
|
||
|
||
# 2024/5/7 下午6:15 处理打包目录
|
||
self._backup_dir = os.path.join(self._temp_backup_dir, "packages", get.app_name)
|
||
if os.path.exists(self._backup_dir):
|
||
public.ExecShell("rm -rf {}".format(self._backup_dir))
|
||
public.ExecShell("mkdir -p {}".format(self._backup_dir))
|
||
|
||
get.site_info = public.M('sites').where('name=?', (get.site_name,)).find()
|
||
if not get.site_info:
|
||
return public.returnResult(status=False, msg="获取网站信息失败")
|
||
|
||
get.path = get.site_info["path"]
|
||
get.target_path = self._backup_dir
|
||
get.package_name = get.app_name
|
||
|
||
# 2024/5/6 上午11:01 备份数据库
|
||
get.export_file = ""
|
||
get.db_charset = ""
|
||
get.config_list = []
|
||
if get.init_sql == 1:
|
||
bk_result = self.backup_database(get)
|
||
if not bk_result["status"]:
|
||
return public.returnResult(status=False, msg=bk_result["msg"])
|
||
|
||
# 2024/5/8 上午9:51 获取指定数据库连接配置文件的相对路径
|
||
d_result = self.get_db_config_file(get)
|
||
if not d_result["status"]:
|
||
return public.returnResult(status=False, msg=d_result["msg"])
|
||
|
||
# 2024/5/6 上午11:00 备份网站目录
|
||
self.tar_path(get)
|
||
|
||
# 2024/5/6 下午5:41 备份伪静态
|
||
self.backup_rewrite(get)
|
||
|
||
# 2024/5/8 上午9:55 获取原来网站目录的根目录和运行目录权限
|
||
self.get_site_permission(get)
|
||
|
||
# 2024/5/11 下午6:14 获取网站目录下最多2层的文件和目录权限
|
||
self.get_dir_list(get)
|
||
|
||
# 2024/5/8 上午9:59 更新压缩包里面的json配置文件
|
||
self.update_package_conf(get)
|
||
|
||
# 2024/5/8 上午10:12 将所有数据打包成一个压缩包
|
||
self.tar_package(get)
|
||
|
||
# 2024/5/8 下午3:42 更新数据库
|
||
self.update_database(get)
|
||
|
||
# 2024/5/10 下午3:38 保存这次填的php、mysql版本和php函数到一个json文件,方便下一次创建的时候自动填充
|
||
last_config = {
|
||
"php_versions": get.php_versions,
|
||
"php_functions": get.php_functions,
|
||
"mysql_versions": get.mysql_versions,
|
||
"init_sql": get.init_sql,
|
||
"db_config_files": get.db_config_files,
|
||
"db_name": get.db_name,
|
||
"db_id": int(get.db_id) if get.db_id != "" else "",
|
||
}
|
||
cache.set(self.skey, last_config, 86400)
|
||
|
||
public.WriteLog("SITE_APP_PACKAGE", "创建一键应用环境包[{}]".format(get.app_name))
|
||
public.set_module_logs('site_app_package', 'create', 1)
|
||
|
||
return public.returnResult(status=True, msg="打包成功")
|
||
|
||
# 2024/5/10 下午12:10 删除指定的应用包
|
||
def delete(self, get):
|
||
'''
|
||
@name 删除指定的应用包
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.site_name = get.get("site_name/s", "")
|
||
if get.site_name == "":
|
||
return public.returnResult(status=False, msg="site_name不能为空")
|
||
|
||
get.app_name = get.get("app_name/s", "")
|
||
if get.app_name == "":
|
||
return public.returnResult(status=False, msg="app_name不能为空")
|
||
|
||
get.app_version = get.get("app_version/s", "")
|
||
if get.app_version == "":
|
||
return public.returnResult(status=False, msg="app_version不能为空")
|
||
|
||
find_version = public.M('app_package').where('site_name=? AND app_name=? AND app_version=?',
|
||
(get.site_name, get.app_name, get.app_version)).find()
|
||
if not find_version:
|
||
return public.returnResult(status=False, msg="应用包不存在")
|
||
|
||
public.ExecShell("rm -rf {}".format(find_version["package_path"]))
|
||
|
||
public.M('app_package').where('id=?', (find_version["id"],)).delete()
|
||
return public.returnResult(status=True, msg="Successfully delete")
|
||
|
||
# 2024/5/9 上午10:41 返回指定网站的app_package表所有数据
|
||
def get_db_all_result(self, get):
|
||
'''
|
||
@name 返回指定网站的app_package表所有数据
|
||
@author wzz <2024/5/9 上午10:42>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
# return public.M('app_package').where("site_name=?", (get.site_name,)).order('addtime desc').select()
|
||
return public.M('app_package').where("site_name=?", (get.site_name,)).order('app_version asc').select()
|
||
|
||
# 2024/5/9 上午11:02 返回指定网站的app_package表的某条数据
|
||
def get_db_result(self, get):
|
||
'''
|
||
@name 返回指定网站的app_package表的某条数据
|
||
@author wzz <2024/5/9 上午11:03>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
return public.M('app_package').where("site_name=? and app_name=? and app_version=?", (get.site_name, get.app_name, get.app_version)).find()
|
||
|
||
# 2024/5/9 下午5:15 返回上传数据库中所有的数据
|
||
def get_upload_db_all_result(self, get):
|
||
'''
|
||
@name 返回上传数据库中所有的数据
|
||
@author wzz <2024/5/9 下午5:15>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
return public.M('app_package_upload').order('app_version asc').select()
|
||
|
||
# 2024/5/9 下午5:19 返回上传数据库中指定包的数据
|
||
def get_upload_db_result(self, get):
|
||
'''
|
||
@name 返回上传数据库中指定包的数据
|
||
@author wzz <2024/5/9 下午5:19>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
return public.M('app_package_upload').where("app_name=? and app_version=?", (get.app_name, get.app_version)).find()
|
||
|
||
# 2024/5/9 上午10:39 获取所有的应用包列表
|
||
def get_list(self, get):
|
||
'''
|
||
@name 获取所有的应用包列表
|
||
@author wzz <2024/5/9 上午10:40>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.site_name = get.get("site_name/s", "")
|
||
if get.site_name == "":
|
||
return public.returnResult(status=False, msg="site_name不能为空")
|
||
|
||
all_result = self.get_db_all_result(get)
|
||
for result in all_result:
|
||
result["status"] = True
|
||
result["info"] = "正常"
|
||
if not os.path.exists(result["package_path"]) or os.path.getsize(result["package_path"]) < 10:
|
||
result["status"] = False
|
||
result["info"] = "文件小于10B或压缩包不存在,请确认包是否正常,如果异常请删除重新创建!"
|
||
|
||
try:
|
||
result["db_config_file"] = json.loads(result["db_config_file"])
|
||
except:
|
||
pass
|
||
|
||
try:
|
||
result["php_libs"] = json.loads(result["php_libs"])
|
||
except:
|
||
pass
|
||
|
||
all_result.reverse()
|
||
public.set_module_logs('site_app_package', 'get_list', 1)
|
||
return public.returnResult(status=True, data=all_result)
|
||
|
||
# 2024/5/9 上午11:17 获取指定包中的package_conf
|
||
def get_package_conf(self, get):
|
||
'''
|
||
@name 获取指定包中的package_conf
|
||
@author wzz <2024/5/9 上午11:18>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
try:
|
||
get.package_info = json.loads(public.readFile(get.package_json_path))
|
||
except:
|
||
get.package_info = {}
|
||
|
||
# 2024/5/9 下午3:09 检查当前站点的php设置是否符合包要求的php
|
||
def check_php_mysql(self, get):
|
||
'''
|
||
@name 检查当前站点的php设置是否符合包要求的php
|
||
@author wzz <2024/5/9 下午3:10>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.version = public.get_site_php_version(get.site_name)
|
||
if not get.version in get.package_info["php_versions"]:
|
||
return public.returnResult(status=False, msg="当前站点PHP版本[{}]不符合包要求的PHP版本[{}]".format(
|
||
get.version,
|
||
get.package_info["php_versions"]
|
||
))
|
||
|
||
used_mysql = self.get_mysql_versions(get)["used"]
|
||
if get.package_info["mysql_versions"] != "00":
|
||
if not used_mysql in get.package_info["mysql_versions"]:
|
||
return public.returnResult(status=False, msg="当前站点MySQL版本[{}]不符合包要求的MySQL版本[{}]".format(
|
||
used_mysql,
|
||
get.package_info["mysql_versions"]
|
||
))
|
||
|
||
return public.returnResult(status=True, msg="当前站点PHP和MySQL版本符合包要求")
|
||
|
||
# 2024/5/9 下午3:06 设置php函数到指定php版本
|
||
def set_php_disable(self, get):
|
||
'''
|
||
@name 设置php函数到指定php版本
|
||
@author wzz <2024/5/9 下午3:07>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
if len(get.package_info["php_functions"]) != 0:
|
||
php_config = self.get_php_config(get)
|
||
get.disable_functions = php_config["data"]["disable_functions"]
|
||
|
||
p_disable_functions = get.package_info["php_functions"].split(",")
|
||
if len(p_disable_functions) != 0:
|
||
for p_disable_function in p_disable_functions:
|
||
if p_disable_function in get.disable_functions:
|
||
get.disable_functions = get.disable_functions.replace(p_disable_function + ",", "")
|
||
|
||
from config import config
|
||
c = config()
|
||
c.setPHPDisable(get)
|
||
|
||
# 2024/5/9 下午3:07 安装php扩展到指定php版本
|
||
def install_phplib(self, get):
|
||
'''
|
||
@name 安装php扩展到指定php版本
|
||
@author wzz <2024/5/9 下午3:08>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
if len(get.package_info["php_libs"]) != 0:
|
||
for lib_name in get.package_info["php_libs"]:
|
||
get.lib_name = lib_name["name"]
|
||
self.install_env_soft(get)
|
||
|
||
# 2024/5/9 下午3:08 从已经解压的应用包中找到网站文件,然后解压拷贝到指定网站目录
|
||
def copy_site(self, get):
|
||
'''
|
||
@name 从已经解压的应用包中找到网站文件,然后解压拷贝到指定网站目录
|
||
@author wzz <2024/5/9 下午3:08>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
public.ExecShell("cd {_temp_import_dir}/{app_name} && tar -zxvf {app_name}.tar.gz".format(
|
||
_temp_import_dir=self._temp_import_dir,
|
||
app_name=get.app_name,
|
||
))
|
||
public.ExecShell(r"\cp -r {_temp_import_dir}/{app_name}/{app_name}/* {site_path}".format(
|
||
_temp_import_dir=self._temp_import_dir,
|
||
app_name=get.app_name,
|
||
site_path=get.site_info["path"],
|
||
))
|
||
|
||
for dir_permission in get.package_info["dir_permission"].keys():
|
||
if dir_permission == "root_permission":
|
||
get.path = get.site_info["path"]
|
||
if dir_permission == "run_permission":
|
||
if get.package_info["run_path"] == "/":
|
||
continue
|
||
|
||
get.path = os.path.join(get.site_info["path"], get.package_info["run_path"])
|
||
|
||
get.permission = get.package_info["dir_permission"][dir_permission]
|
||
self.set_path_permission(get)
|
||
|
||
# 2024/5/11 下午6:22 恢复网站目录下最多2层的文件和目录权限
|
||
self.set_dir_list_permission(get)
|
||
|
||
# 2024/5/11 下午6:22 恢复网站目录下最多2层的文件和目录权限
|
||
def set_dir_list_permission(self, get):
|
||
'''
|
||
@name 恢复网站目录下最多2层的文件和目录权限
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
try:
|
||
dir_permission_list = json.loads(public.readFile("{}/dir_permission.json".format(self._backup_dir)))
|
||
except:
|
||
return
|
||
|
||
for dir_permission in dir_permission_list:
|
||
get.path = os.path.join(get.site_info["path"], dir_permission["path"])
|
||
get.permission = dir_permission
|
||
self.set_path_permission(get)
|
||
|
||
# 2024/5/9 下午5:52 从上传的应用包目录找到网站文件,然后解压拷贝到指定网站目录
|
||
def copy_upload_site(self, get):
|
||
'''
|
||
@name 从上传的应用包目录找到网站文件,然后解压拷贝到指定网站目录
|
||
@author wzz <2024/5/9 下午5:52>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
public.ExecShell("cd {upload_package_path} && tar -zxvf {app_name}.tar.gz".format(
|
||
upload_package_path=self._upload_package_path,
|
||
app_name=get.app_name,
|
||
))
|
||
public.ExecShell(r"\cp -r {upload_package_path}/{app_name}/* {site_path}".format(
|
||
upload_package_path=self._upload_package_path,
|
||
app_name=get.app_name,
|
||
site_path=get.site_info["path"],
|
||
))
|
||
|
||
for dir_permission in get.package_info["dir_permission"].keys():
|
||
if dir_permission == "root_permission":
|
||
get.path = get.site_info["path"]
|
||
if dir_permission == "run_permission":
|
||
if get.package_info["run_path"] == "/":
|
||
continue
|
||
|
||
get.path = os.path.join(get.site_info["path"], get.package_info["run_path"])
|
||
|
||
get.permission = get.package_info["dir_permission"][dir_permission]
|
||
self.set_path_permission(get)
|
||
|
||
# 2024/5/11 下午6:22 恢复网站目录下最多2层的文件和目录权限
|
||
self.set_dir_list_permission(get)
|
||
|
||
# 2024/5/9 下午3:09 检查包json配置文件中的init_sql是否为1,如果是则执行查询网站关联的数据库并导入init.sql
|
||
def import_init_sql(self, get):
|
||
'''
|
||
@name 检查包json配置文件中的init_sql是否为1,如果是则执行查询网站关联的数据库并导入init.sql
|
||
@author wzz <2024/5/9 下午3:09>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
if get.package_info["init_sql"] == 1:
|
||
get.db_info = public.M('databases').where('pid=?', (get.site_info['id'],)).find()
|
||
if get.db_info:
|
||
for db_conf in get.package_info["db_config_file"]:
|
||
db_conf = os.path.join(get.site_info["path"], db_conf)
|
||
if not os.path.exists(db_conf):
|
||
continue
|
||
|
||
conf_body = public.readFile(db_conf)
|
||
if not conf_body:
|
||
return public.returnResult(status=False, msg="{}内容为空".format(db_conf))
|
||
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_USER, get.db_info["username"])
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_NAME, get.db_info["name"])
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_PASS, get.db_info["password"])
|
||
|
||
public.writeFile(db_conf, conf_body)
|
||
|
||
from database import database
|
||
database = database()
|
||
get.file = "{}/{}/init.sql".format(self._temp_import_dir, get.app_name)
|
||
get.name = get.db_info["name"]
|
||
import_result = database.InputSql(get)
|
||
if not import_result["status"]:
|
||
return public.returnResult(status=False, msg=import_result["msg"])
|
||
|
||
return public.returnResult(status=True, msg="导入init.sql成功")
|
||
|
||
return public.returnResult(status=True, msg="不需要导入")
|
||
|
||
# 2024/5/9 下午6:08 检查指定上传包json配置文件中的init_sql是否为1,如果是则执行查询网站关联的数据库并导入init.sql
|
||
def import_upload_init_sql(self, get):
|
||
'''
|
||
@name 检查指定上传包json配置文件中的init_sql是否为1,如果是则执行查询网站关联的数据库并导入init.sql
|
||
@author wzz <2024/5/9 下午6:08>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.db_info = public.M('databases').where('pid=?', (get.site_info['id'],)).find()
|
||
if get.db_info:
|
||
if get.package_info["init_sql"] == 1:
|
||
from database import database
|
||
database = database()
|
||
get.file = "{}/init.sql".format(self._upload_package_path)
|
||
get.name = get.db_info["name"]
|
||
import_result = database.InputSql(get)
|
||
if not import_result["status"]:
|
||
return public.returnResult(status=False, msg=import_result["msg"])
|
||
|
||
for db_conf in get.package_info["db_config_file"]:
|
||
sample_db_conf = ""
|
||
if "sample" in db_conf:
|
||
sample_db_conf = db_conf.replace("sample_", "").replace("_sample", "").replace("-sample", "").replace("sample-", "").replace(".sample", "").replace("sample.", "").replace("sample", "")
|
||
db_conf = db_conf.replace("sample_", "").replace("_sample", "").replace("-sample", "").replace("sample-", "").replace(".sample", "").replace("sample.", "").replace("sample", "")
|
||
|
||
if sample_db_conf != "":
|
||
sample_db_conf = os.path.join(get.site_info["path"], sample_db_conf)
|
||
if os.path.exists(sample_db_conf):
|
||
conf_body = public.readFile(sample_db_conf)
|
||
if conf_body:
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_USER, get.db_info["username"])
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_NAME, get.db_info["name"])
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_PASS, get.db_info["password"])
|
||
|
||
public.writeFile(sample_db_conf, conf_body)
|
||
|
||
db_conf = os.path.join(get.site_info["path"], db_conf)
|
||
if not os.path.exists(db_conf):
|
||
public.ExecShell("cp -f {} {}".format(sample_db_conf, db_conf))
|
||
|
||
conf_body = public.readFile(db_conf)
|
||
if not conf_body:
|
||
return public.returnResult(status=False, msg="{}内容为空".format(db_conf))
|
||
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_USER, get.db_info["username"])
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_NAME, get.db_info["name"])
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_PASS, get.db_info["password"])
|
||
|
||
public.writeFile(db_conf, conf_body)
|
||
else:
|
||
db_conf = os.path.join(get.site_info["path"], db_conf)
|
||
if not os.path.exists(db_conf):
|
||
continue
|
||
|
||
conf_body = public.readFile(db_conf)
|
||
if not conf_body:
|
||
return public.returnResult(status=False, msg="{}内容为空".format(db_conf))
|
||
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_USER, get.db_info["username"])
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_NAME, get.db_info["name"])
|
||
conf_body = conf_body.replace(self.APP_PACKAGE_DB_PASS, get.db_info["password"])
|
||
|
||
public.writeFile(db_conf, conf_body)
|
||
|
||
return public.returnResult(status=True, msg="导入init.sql成功")
|
||
|
||
# 2024/5/9 上午10:54 应用指定的应用环境包到指定网站
|
||
def apply_site(self, get):
|
||
'''
|
||
@name 应用指定的应用环境包到指定网站
|
||
@author wzz <2024/5/9 上午10:55>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.site_name = get.get("site_name/s", "")
|
||
if get.site_name == "":
|
||
return public.returnResult(status=False, msg="site_name不能为空")
|
||
|
||
get.app_name = get.get("app_name/s", "")
|
||
if get.app_name == "":
|
||
return public.returnResult(status=False, msg="app_name不能为空")
|
||
|
||
get.app_version = get.get("app_version/s", "")
|
||
if get.app_version == "":
|
||
return public.returnResult(status=False, msg="app_version不能为空")
|
||
|
||
get.site_info = public.M('sites').where('name=?', (get.site_name,)).find()
|
||
if not get.site_info:
|
||
return public.returnResult(status=False, msg="获取网站信息失败")
|
||
|
||
get.package_info = self.get_db_result(get)
|
||
if not get.package_info:
|
||
return public.returnResult(status=False, msg="获取应用包信息失败")
|
||
|
||
if not os.path.exists(get.package_info["package_path"]):
|
||
return public.returnResult(status=False, msg="应用包不存在")
|
||
|
||
# 2024/5/9 上午11:15 创建临时导入目录
|
||
self._temp_import_dir = os.path.join(self._temp_backup_dir, "import")
|
||
if os.path.exists(self._temp_import_dir):
|
||
public.ExecShell("rm -rf {}".format(self._temp_import_dir))
|
||
public.ExecShell("mkdir -p {}".format(self._temp_import_dir))
|
||
|
||
# 2024/5/9 上午11:15 解压应用包
|
||
public.ExecShell("tar -zxvf {} -C {}".format(get.package_info["package_path"], self._temp_import_dir))
|
||
|
||
# 2024/5/9 上午11:23 处理包里面的json配置文件
|
||
get.package_json_path = "{_temp_import_dir}/{app_name}/package.json".format(
|
||
_temp_import_dir=self._temp_import_dir,
|
||
app_name=get.app_name,
|
||
)
|
||
|
||
self.get_package_conf(get)
|
||
if not get.package_info:
|
||
return public.returnResult(status=False, msg="包异常,获取package.json配置文件失败")
|
||
|
||
# 2024/5/9 上午11:41 检查当前站点的php设置是否符合包要求的php
|
||
check_result = self.check_php_mysql(get)
|
||
if not check_result["status"]:
|
||
return public.returnResult(status=False, msg=check_result["msg"])
|
||
|
||
# 2024/5/9 上午11:53 设置php函数到指定php版本
|
||
self.set_php_disable(get)
|
||
# 2024/5/9 下午12:08 安装php扩展到指定php版本
|
||
self.install_phplib(get)
|
||
# 2024/5/9 下午2:37 还原指定包的伪静态到指定网站中
|
||
self.restore_rewrite(get)
|
||
# 2024/5/9 上午11:01 从已经解压的应用包中找到网站文件,然后解压拷贝到指定网站目录
|
||
self.copy_site(get)
|
||
# 2024/5/9 上午11:16 检查包json配置文件中的init_sql是否为1,如果是则执行查询网站关联的数据库并导入init.sql
|
||
import_result = self.import_init_sql(get)
|
||
if not import_result["status"]:
|
||
return public.returnResult(status=False, msg=import_result["msg"])
|
||
|
||
public.set_module_logs('site_app_package', 'apply_site', 1)
|
||
return public.returnResult(status=True, msg="应用成功")
|
||
|
||
# 2024/5/9 下午3:50 上传应用包到指定位置
|
||
def upload_package(self, get):
|
||
'''
|
||
@name 上传应用包到指定位置
|
||
@author wzz <2024/5/9 下午3:51>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
if not os.path.exists(self._temp_upload_package_dir):
|
||
public.ExecShell("mkdir -p {}".format(self._temp_upload_package_dir))
|
||
|
||
get.f_path = get.get("f_path/s", "")
|
||
get.f_name = get.get("f_name/s", "")
|
||
get.f_size = get.get("f_size/s", "")
|
||
get.f_start = get.get("f_start/s", "")
|
||
get.blob = get.get("blob/s", "")
|
||
|
||
from files import files
|
||
fileObj = files()
|
||
upload_result = fileObj.upload(get)
|
||
if type(upload_result) == dict and not upload_result["status"]:
|
||
return public.returnResult(status=False, msg=upload_result["msg"])
|
||
|
||
get.size = os.path.getsize(os.path.join(self._temp_upload_package_dir, get.f_name))
|
||
|
||
if get.size != int(get.f_size):
|
||
return public.returnResult(status=False, msg="上传文件大小不一致,上传失败!")
|
||
|
||
# 2024/5/9 下午4:26 解压压缩包
|
||
public.ExecShell("tar -zxvf {}/{} -C {}".format(self._temp_upload_package_dir, get.f_name, self._upload_package_dir))
|
||
|
||
# 2024/5/9 下午4:27 获取配置信息写入数据库
|
||
get.app_name = get.f_name.split("_v")[0]
|
||
# 2024/5/9 上午11:23 处理包里面的json配置文件
|
||
get.package_json_path = "{_upload_package_dir}/{app_name}/package.json".format(
|
||
_upload_package_dir=self._upload_package_dir,
|
||
app_name=get.app_name,
|
||
)
|
||
|
||
self.get_package_conf(get)
|
||
if not get.package_info:
|
||
public.ExecShell("rm -rf {}".format(os.path.join(self._temp_upload_package_dir, get.f_name)))
|
||
public.ExecShell("rm -rf {}".format(os.path.join(self._upload_package_dir, get.app_name)))
|
||
return public.returnResult(status=False, msg="应用包异常,获取package.json配置文件失败")
|
||
|
||
# 2024/5/9 下午4:29 更新数据库
|
||
self.update_upload_database(get)
|
||
|
||
public.set_module_logs('site_app_package', 'upload_package', 1)
|
||
return public.returnResult(status=True, msg="上传成功")
|
||
|
||
# 2024/5/9 下午5:13 获取上传列表的所有包数据
|
||
def get_upload_list(self, get):
|
||
'''
|
||
@name 获取上传列表的所有包数据
|
||
@author wzz <2024/5/9 下午5:13>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
all_result = self.get_upload_db_all_result(get)
|
||
for result in all_result:
|
||
result["status"] = True
|
||
result["info"] = "正常"
|
||
if not os.path.exists(result["package_path"]) or os.path.getsize(result["package_path"]) < 10:
|
||
result["status"] = False
|
||
result["info"] = "文件小于10B或压缩包不存在,请确认包是否正常,如果异常请删除重新创建!"
|
||
|
||
try:
|
||
result["db_config_file"] = json.loads(result["db_config_file"])
|
||
except:
|
||
pass
|
||
|
||
try:
|
||
result["php_libs"] = json.loads(result["php_libs"])
|
||
except:
|
||
pass
|
||
|
||
all_result.reverse()
|
||
|
||
public.set_module_logs('site_app_package', 'get_upload_list', 1)
|
||
return public.returnResult(status=True, data=all_result)
|
||
|
||
# 2024/5/10 下午12:16 删除指定的上传包
|
||
def delete_upload(self, get):
|
||
'''
|
||
@name 删除指定的上传包
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.app_name = get.get("app_name/s", "")
|
||
if get.app_name == "":
|
||
return public.returnResult(status=False, msg="app_name不能为空")
|
||
|
||
get.app_version = get.get("app_version/s", "")
|
||
if get.app_version == "":
|
||
return public.returnResult(status=False, msg="app_version不能为空")
|
||
|
||
find_version = public.M('app_package_upload').where('app_name=? AND app_version=?',
|
||
(get.app_name, get.app_version)).find()
|
||
if not find_version:
|
||
return public.returnResult(status=False, msg="应用包不存在")
|
||
|
||
public.ExecShell("rm -rf {}".format(find_version["package_path"]))
|
||
|
||
public.M('app_package_upload').where('id=?', (find_version["id"],)).delete()
|
||
return public.returnResult(status=True, msg="Successfully delete")
|
||
|
||
# 2024/5/9 下午6:33 获取上传列表中某一个包的数据
|
||
def get_upload_result(self, get):
|
||
'''
|
||
@name 获取上传列表中某一个包的数据
|
||
@author wzz <2024/5/9 下午6:33>
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"sbt 2
|
||
tatus":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.app_name = get.get("app_name/s", "")
|
||
if get.app_name == "":
|
||
return public.returnResult(status=False, msg="app_name不能为空")
|
||
|
||
get.app_version = get.get("app_version/s", "")
|
||
if get.app_version == "":
|
||
return public.returnResult(status=False, msg="app_version不能为空")
|
||
|
||
installed_phps = []
|
||
for v in self._php_versions:
|
||
if os.path.exists(public.get_setup_path() + "/php/" + v + "/bin/php"):
|
||
installed_phps.append(v)
|
||
|
||
result = self.get_upload_db_result(get)
|
||
result["installed_phps"] = installed_phps
|
||
result["installed_mysql"] = self.get_mysql_versions(get)["used"]
|
||
|
||
result["status"] = True
|
||
result["info"] = "正常"
|
||
if not os.path.exists(result["package_path"]) or os.path.getsize(result["package_path"]) < 10:
|
||
result["status"] = False
|
||
result["info"] = "文件小于10B或压缩包不存在,请确认包是否正常,如果异常请删除重新创建!"
|
||
|
||
try:
|
||
result["db_config_file"] = json.loads(result["db_config_file"])
|
||
except:
|
||
pass
|
||
|
||
try:
|
||
result["php_libs"] = json.loads(result["php_libs"])
|
||
except:
|
||
pass
|
||
|
||
return public.returnResult(status=True, data=result)
|
||
|
||
# 2024/5/9 下午3:35 创建网站并应用应用包
|
||
def create_site(self, get):
|
||
'''
|
||
@name 创建网站并应用应用包到指定网站中,如果网站已经存在则直接应用应用包到指定网站中,如果网站不存在则创建网站并应用应用包到指定网站中
|
||
@param "data":{"参数名":""} <数据类型> 参数描述
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
get.site_name = get.get("site_name/s", "")
|
||
if get.site_name == "":
|
||
return public.returnResult(status=False, msg="site_name不能为空")
|
||
|
||
get.port = "80"
|
||
if ":" in get.site_name:
|
||
get.port = get.site_name.split(":")[1]
|
||
get.site_name = get.site_name.split(":")[0]
|
||
|
||
get.webname = get.get("webname", "")
|
||
if get.webname == "":
|
||
return public.returnResult(status=False, msg="webname不能为空")
|
||
|
||
get.app_name = get.get("app_name/s", "")
|
||
if get.app_name == "":
|
||
return public.returnResult(status=False, msg="app_name不能为空")
|
||
|
||
get.app_version = get.get("app_version/s", "")
|
||
if get.app_version == "":
|
||
return public.returnResult(status=False, msg="app_version不能为空")
|
||
|
||
get.ps = get.get("ps/s", "")
|
||
get.ps = public.xssencode2(get.ps)
|
||
|
||
# 2024/5/9 上午11:23 处理包里面的json配置文件
|
||
get.package_json_path = "{_upload_package_dir}/{app_name}/package.json".format(
|
||
_upload_package_dir=self._upload_package_dir,
|
||
app_name=get.app_name,
|
||
)
|
||
|
||
self.get_package_conf(get)
|
||
if not get.package_info:
|
||
return public.returnResult(status=False, msg="包异常,获取package.json配置文件失败")
|
||
|
||
self._upload_package_path = self._upload_package_path.format(app_name=get.app_name)
|
||
|
||
# 2024/5/9 下午5:28 选择get.package_info["php_versions"]里面版本最高的php版本
|
||
get.php_list = get.package_info["php_versions"].split(",")
|
||
get.php_list.sort()
|
||
get.php_list.reverse()
|
||
for php_version in get.php_list:
|
||
if os.path.exists(public.get_setup_path() + "/php/" + php_version + "/bin/php"):
|
||
get.php_version = php_version
|
||
break
|
||
|
||
from panelSite import panelSite
|
||
tmp_args = {
|
||
'webname': get.webname,
|
||
'type': 'PHP',
|
||
'port': get.port,
|
||
'ps': get.ps,
|
||
'path': os.path.join("/www/wwwroot", get.site_name),
|
||
'type_id': 0,
|
||
'version': get.php_version,
|
||
'ftp': False,
|
||
'sql': False,
|
||
}
|
||
if get.package_info["db_config_file"]:
|
||
tmp_args["sql"] = "MySQL"
|
||
tmp_args["codeing"] = get.package_info["db_character"] if get.package_info["db_character"] != "" else "utf8mb4"
|
||
tmp_args["datauser"] = get.site_name.replace(".", "_")
|
||
tmp_args["datapassword"] = public.GetRandomString(16)
|
||
|
||
args = public.to_dict_obj(tmp_args)
|
||
add_site_result = panelSite().AddSite(args)
|
||
if "status" in add_site_result and not add_site_result["status"]:
|
||
return public.returnResult(status=False, msg=add_site_result["msg"])
|
||
if not add_site_result["siteStatus"]:
|
||
return public.returnResult(status=False, msg="创建网站失败")
|
||
|
||
get.site_info = public.M('sites').where('name=?', (get.site_name,)).find()
|
||
if not get.site_info:
|
||
return public.returnResult(status=False, msg="获取网站信息失败")
|
||
|
||
get.version = public.get_site_php_version(get.site_name)
|
||
if not get.version in get.package_info["php_versions"]:
|
||
return public.returnResult(status=False, msg="当前站点PHP版本[{}]不符合包要求的PHP版本[{}]".format(
|
||
get.version,
|
||
get.package_info["php_versions"]
|
||
))
|
||
|
||
# 2024/5/9 上午11:53 设置php函数到指定php版本
|
||
self.set_php_disable(get)
|
||
# 2024/5/9 下午12:08 安装php扩展到指定php版本
|
||
self.install_phplib(get)
|
||
# 2024/5/9 下午2:37 还原指定上传包的伪静态到指定网站中
|
||
self.restore_upload_rewrite(get)
|
||
# 2024/5/9 下午5:54 从上传的应用包目录找到网站文件,然后解压拷贝到指定网站目录
|
||
self.copy_upload_site(get)
|
||
# 2024/5/9 上午11:16 检查包json配置文件中的init_sql是否为1,如果是则执行查询网站关联的数据库并导入init.sql
|
||
import_result = self.import_upload_init_sql(get)
|
||
|
||
if not import_result["status"]:
|
||
return public.returnResult(status=False, msg=import_result["msg"])
|
||
|
||
success_url = "http://{}".format(get.site_name)
|
||
if "success_url" in get.package_info:
|
||
success_url = success_url + get.package_info["success_url"]
|
||
|
||
add_site_result["success_url"] = success_url
|
||
|
||
public.set_module_logs('site_app_package', 'create_site', 1)
|
||
return public.returnResult(status=True, msg="网站创建成功", data=add_site_result)
|