mirror of
https://github.com/aaPanel/aaPanel.git
synced 2026-08-17 21:25:47 +02:00
Since version 7.7.0, we recommend yours update python to 3.12. [+] Using nginx technology to load static files improves access speed [+] Refactor homepage, website, FTP, and database using vue3 [+] Table loading changed to skeleton screen [+] Add Website statistics-v2 professional plug-in [+] Add Home page - top 5 resource occupancy [+] Add protection for Files management (requires Tamper-proof for Enterprise 3.7) [+] Website, FTP, Databases page add program status [+] Add FTP log analysis (only supports Centos) [+] Add password-free login to phpMyAdmin [+] Add Proxy Project in Website (Supported when web service uses Nginx) [+] Add WP Toolkit (Pro version only) [+] Redesigned Docker module [+] Add WP Toolkit Protection [+] Add WP Toolkit Backup and Restore [+] Add WP Toolkit Migrated [+] Add WP Toolkit Clone site (supports new domain and subdomain) [+] Add WP Toolkit Create site from backup of other panel [+] Add WP Toolkit support for Cron automatic backup (only save Local disk) [+] Add WP Toolkit operation log [+] Add Integrity check for WP Toolkit [+] Add WP Toolkit plug-in management and themes management [*] Optimize phpMyAdmin formula access method [*] Optimize Home page PHP display problem [*] Optimize jump to the login interface after the login expires [*] Optimize automatic renewal of SSL at some times [*] Optimize Let's Encrypt to increase application success rate [-] Fix Logs Audit cannot be opened [-] Fix apache URL rewrite issue [-] Fix phpmyadmin installation problem [-] Fix the problem that some servers cannot install software [-] Fix upload file error [-] Fix left menu hiding problem [-] Fix aaPanel Mobile QR code display problem [-] Fix problem that third-party plug-ins are not displayed in the App Store [-] Fix issue where the menu bar is blank when opening new tabs [-] Fixed panel not being accessible in some cases [-] Fix the issue where Curl warning caused the inability to apply for SSL [-] Fix Quota issues for Website, FTP, Databases [-] Fix file interface display problem on mobile terminal
185 lines
7.2 KiB
Python
185 lines
7.2 KiB
Python
# coding: utf-8
|
||
# -------------------------------------------------------------------
|
||
# aaPanel
|
||
# -------------------------------------------------------------------
|
||
# Copyright (c) 2015-2099 aaPanel(www.aapanel.com) All rights reserved.
|
||
# -------------------------------------------------------------------
|
||
# Author: wzz <wzz@aapanel.com>
|
||
# -------------------------------------------------------------------
|
||
import os
|
||
import time
|
||
import traceback
|
||
import gettext
|
||
_ = gettext.gettext
|
||
|
||
# ------------------------------
|
||
# Docker模型
|
||
# ------------------------------
|
||
import public
|
||
from btdockerModelV2 import containerModel as dc
|
||
from btdockerModelV2 import dk_public as dp
|
||
from btdockerModelV2.dockerBase import dockerBase
|
||
from public.validate import Param
|
||
|
||
class main(dockerBase):
|
||
|
||
# 2023/12/22 上午 9:56 备份指定容器的mount v11olume
|
||
def backup_volume(self, get):
|
||
'''
|
||
@name 备份指定容器的mount volume
|
||
@author wzz <2023/12/22 上午 11:19>
|
||
@param "data":{"container_id":"容器ID"}
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
|
||
# 校验参数
|
||
try:
|
||
get.validate([
|
||
Param('container_id').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:
|
||
client = dp.docker_client()
|
||
container = client.containers.get(get.container_id)
|
||
volume_list = container.attrs["Mounts"]
|
||
volume_list = [v["Source"] for v in volume_list]
|
||
|
||
if not volume_list:
|
||
return public.return_message(-1, 0, _("There is no volume to back up"))
|
||
|
||
backup_path = "/www/backup/btdocker/volumes/{}".format(container.name)
|
||
if not os.path.exists(backup_path):
|
||
os.makedirs(backup_path, 0o755)
|
||
|
||
import subprocess
|
||
public.ExecShell("echo -n > {}".format(self._backup_log))
|
||
|
||
for v in volume_list:
|
||
backup_name = os.path.basename(v)
|
||
# 2023/12/22 上午 10:34 每个压缩包命名都用v的目录名,如果是文件则用文件名
|
||
tar_name = "{}_{}_{}.tar.gz".format(
|
||
container.name,
|
||
backup_name,
|
||
time.strftime("%Y%m%d_%H%M%S", time.localtime())
|
||
)
|
||
backup_file = os.path.join(backup_path, tar_name)
|
||
source_path = os.path.dirname(v)
|
||
cmd = "cd {} && tar zcvf {} {}".format(source_path, backup_file, backup_name)
|
||
cmd = ("nohup echo 'To start backing up {} of container {}, it may take more than 1-5 minutes...' >> {};"
|
||
"{} >> {} 2>&1 &&"
|
||
"echo 'bt_successful' >> {} || echo 'bt_failed' >> {} &"
|
||
.format(
|
||
container.name,
|
||
tar_name,
|
||
self._backup_log,
|
||
cmd,
|
||
self._backup_log,
|
||
self._backup_log,
|
||
self._backup_log,
|
||
))
|
||
subprocess.Popen(cmd, shell=True)
|
||
|
||
# 2023/12/22 下午 12:17 添加到数据库
|
||
dp.sql('dk_backup').add(
|
||
'type,name,container_id,container_name,filename,size,addtime',
|
||
(3, tar_name, container.id, container.name, backup_file, 0, time.strftime(
|
||
"%Y-%m-%d %H:%M:%S", time.localtime()
|
||
))
|
||
)
|
||
public.WriteLog("Docker module", "The {} of the backup container {} succeeds!".format(container.name, tar_name))
|
||
|
||
return public.return_message(0, 0, _("The backup task was created successfully."))
|
||
except Exception as e:
|
||
print(traceback.format_exc())
|
||
return public.return_message(-1, 0, _("Failed to create a backup task {}".format(str(e))))
|
||
|
||
# 2023/12/22 上午 11:23 获取指定容器的备份列表
|
||
def get_backup_list(self, get):
|
||
'''
|
||
@name 获取指定容器的备份列表
|
||
@param "data":{"container_id":"容器ID"}
|
||
@return list[dict{"":""}]
|
||
'''
|
||
# 校验参数
|
||
try:
|
||
get.validate([
|
||
Param('container_id').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:
|
||
# 2023/12/22 下午 12:24 从数据库中获取已备份的指定容器
|
||
backup_list = dp.sql('dk_backup').where('container_id=?', (get.container_id,)).field(
|
||
'name,container_id,container_name,filename,size,addtime'
|
||
).select()
|
||
|
||
for l in backup_list:
|
||
if not os.path.exists(l['filename']):
|
||
l['size'] = 0
|
||
l['ps'] = 'file does not exist'
|
||
continue
|
||
|
||
l['size'] = os.path.getsize(l['filename'])
|
||
l['ps'] = 'local backup'
|
||
|
||
return public.return_message(0, 0, backup_list)
|
||
|
||
except Exception as e:
|
||
print(traceback.format_exc())
|
||
return public.return_message(0, 0, [])
|
||
|
||
# 2023/12/22 下午 2:25 删除指定容器的备份
|
||
def remove_backup(self, get):
|
||
'''
|
||
@name 删除指定容器的备份
|
||
@param "data":{"container_id":"容器ID","container_name":"容器名","name":"文件名"}
|
||
@return dict{"status":True/False,"msg":"提示信息"}
|
||
'''
|
||
|
||
# 校验参数
|
||
try:
|
||
get.validate([
|
||
Param('container_id').Require().String(),
|
||
Param('container_name').Require().String(),
|
||
Param('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:
|
||
# 2023/12/22 下午 2:26 从数据库中删除指定容器的备份
|
||
dp.sql('dk_backup').where('container_id=? and name=?', (get.container_id, get.name)).delete()
|
||
|
||
# 2023/12/22 下午 2:27 删除本地备份文件
|
||
backup_path = "/www/backup/btdocker/volumes/{}".format(get.container_name)
|
||
file_path = os.path.join(backup_path, get.name)
|
||
if not os.path.exists(file_path):
|
||
return public.return_message(0, 0, _("successfully delete"))
|
||
os.remove(file_path)
|
||
return public.return_message(0, 0, _("successfully delete"))
|
||
except Exception as e:
|
||
print(traceback.format_exc())
|
||
return public.return_message(-1, 0, _("{} Failed to delete the file, reason: {}".format(get.name, str(e))))
|
||
|
||
def get_pull_log(self, get):
|
||
"""
|
||
获取镜像拉取日志,websocket
|
||
@param get:
|
||
@return:
|
||
"""
|
||
get.wsLogTitle = "Start container directory backup, please wait..."
|
||
get._log_path = self._backup_log
|
||
return self.get_ws_log(get) |