mirror of https://github.com/midoks/mdserver-web
parent
ff3067f233
commit
367d6c5b78
@ -0,0 +1,57 @@ |
|||||||
|
[{ |
||||||
|
"name":"七牛云存储", |
||||||
|
"type":"计划任务", |
||||||
|
"ps":"将网站或数据库打包备份到七牛对象存储空间,七牛提供10GB免费存储空间, <a class='link' href='https://portal.qiniu.com/signup?code=3liz7nbopjd5e' target='_blank'>点击申请</a>", |
||||||
|
"status":false, |
||||||
|
"opt":"qiniu", |
||||||
|
"module":"qiniu", |
||||||
|
"script":"qiniu", |
||||||
|
"help":"http://www.bt.cn/bbs/thread-839-1-1.html", |
||||||
|
"key":"access_key|请输入AccessKey|七牛秘钥中的AK", |
||||||
|
"secret":"secret_key|请输入SecretKey|七牛秘钥中的SK", |
||||||
|
"bucket":"存储空间|请输入对象存储空间名称|七牛对象存储中您创建的空间名称", |
||||||
|
"domain":"外链域名|请输入绑定域名或测试域名|绑定的七牛外链域名,若没有则填测试域名", |
||||||
|
"check":["/usr/lib/python2.6/site-packages/qiniu/auth.py","/usr/lib/python2.7/site-packages/qiniu/auth.py"] |
||||||
|
},{ |
||||||
|
"name":"阿里云OSS", |
||||||
|
"type":"计划任务", |
||||||
|
"ps":"将网站或数据库打包备份到阿里云OSS对象存储空间,阿里云OSS提供5GB免费存储空间, <a class='link' href='https://www.aliyun.com/product/oss?spm=5176.8142029.388261.46.psCRgl' target='_blank'>点击申请</a>", |
||||||
|
"status":false, |
||||||
|
"opt":"alioss", |
||||||
|
"module":"oss2", |
||||||
|
"script":"alioss", |
||||||
|
"help":"http://www.bt.cn/bbs/thread-1061-1-1.html", |
||||||
|
"key":"AccessKeyId|请输入AccessKeyId|阿里云的AccessKeyId", |
||||||
|
"secret":"AccessKeySecret|请输入AccessKeySecret|阿里云的AccessKeySecret", |
||||||
|
"bucket":"Bucket|请输入Bucket名称|阿里云OSS中您创建的Bucket名称", |
||||||
|
"domain":"外链域名|请输入Endpoint域名|阿里云OSS外链域名,不包括Bucket名", |
||||||
|
"check":["/usr/lib/python2.6/site-packages/oss2/auth.py","/usr/lib/python2.7/site-packages/oss2/auth.py"] |
||||||
|
},{ |
||||||
|
"name":"FTP存储空间", |
||||||
|
"type":"计划任务", |
||||||
|
"ps":"将网站或数据库打包备份到FTP存储空间.", |
||||||
|
"status":false, |
||||||
|
"opt":"ftp", |
||||||
|
"module":"ftp", |
||||||
|
"script":"ftp", |
||||||
|
"help":"http://www.bt.cn/bbs", |
||||||
|
"key":"Host|请输入主机地址|FTP服务器地址,例:192.168.0.1:21", |
||||||
|
"secret":"用户名|请输入登陆用户名|指定FTP用户名", |
||||||
|
"bucket":"密码|请输入登陆密码|指定FTP密码", |
||||||
|
"domain":"存储位置|请输入存储位置|相对于FTP根目录的路径,如 /backup", |
||||||
|
"check":["/www/server/panel/script/backup_ftp.py"] |
||||||
|
},{ |
||||||
|
"name":"申请内测资格", |
||||||
|
"type":"其它", |
||||||
|
"ps":"申请内测资格,审核完成后将会获得内测版本更新推送,并可在宝塔论坛内测专用版块参与讨论", |
||||||
|
"status":false, |
||||||
|
"opt":"beta", |
||||||
|
"module":"beta", |
||||||
|
"script":"beta", |
||||||
|
"help":"http://www.bt.cn/bbs/thread-1392-1-1.html", |
||||||
|
"key":"", |
||||||
|
"secret":"", |
||||||
|
"bucket":"", |
||||||
|
"domain":"", |
||||||
|
"check":["data/beta.pl"] |
||||||
|
}] |
@ -0,0 +1,226 @@ |
|||||||
|
#!/usr/bin/python |
||||||
|
# coding: utf-8 |
||||||
|
#----------------------------- |
||||||
|
# 网站备份工具 |
||||||
|
#----------------------------- |
||||||
|
|
||||||
|
import sys |
||||||
|
import os |
||||||
|
|
||||||
|
if sys.platform != 'darwin': |
||||||
|
os.chdir('/www/server/mdserver-web') |
||||||
|
|
||||||
|
|
||||||
|
chdir = os.getcwd() |
||||||
|
sys.path.append(chdir + '/class/core') |
||||||
|
reload(sys) |
||||||
|
sys.setdefaultencoding('utf-8') |
||||||
|
|
||||||
|
|
||||||
|
import public |
||||||
|
import db |
||||||
|
import time |
||||||
|
|
||||||
|
|
||||||
|
class backupTools: |
||||||
|
|
||||||
|
def backupSite(self, name, count): |
||||||
|
sql = db.Sql() |
||||||
|
path = sql.table('sites').where('name=?', (name,)).getField('path') |
||||||
|
startTime = time.time() |
||||||
|
if not path: |
||||||
|
endDate = time.strftime('%Y/%m/%d %X', time.localtime()) |
||||||
|
log = u"网站[" + name + "]不存在!" |
||||||
|
print(u"★[" + endDate + "] " + log) |
||||||
|
print( |
||||||
|
"----------------------------------------------------------------------------") |
||||||
|
return |
||||||
|
|
||||||
|
backup_path = public.getRootDir() + '/backup/site' |
||||||
|
if not os.path.exists(backup_path): |
||||||
|
public.execShell("mkdir -p " + backup_path) |
||||||
|
|
||||||
|
filename = backup_path + "/web_" + name + "_" + \ |
||||||
|
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + '.tar.gz' |
||||||
|
public.execShell("cd " + os.path.dirname(path) + " && tar zcvf '" + |
||||||
|
filename + "' '" + os.path.basename(path) + "' > /dev/null") |
||||||
|
|
||||||
|
endDate = time.strftime('%Y/%m/%d %X', time.localtime()) |
||||||
|
|
||||||
|
print filename |
||||||
|
if not os.path.exists(filename): |
||||||
|
log = u"网站[" + name + u"]备份失败!" |
||||||
|
print(u"★[" + endDate + "] " + log) |
||||||
|
print( |
||||||
|
u"----------------------------------------------------------------------------") |
||||||
|
return |
||||||
|
|
||||||
|
outTime = time.time() - startTime |
||||||
|
pid = sql.table('sites').where('name=?', (name,)).getField('id') |
||||||
|
sql.table('backup').add('type,name,pid,filename,addtime,size', ('0', os.path.basename( |
||||||
|
filename), pid, filename, endDate, os.path.getsize(filename))) |
||||||
|
log = u"网站[" + name + u"]备份成功,用时[" + str(round(outTime, 2)) + u"]秒" |
||||||
|
public.writeLog(u'计划任务', log) |
||||||
|
print(u"★[" + endDate + "] " + log) |
||||||
|
print(u"|---保留最新的[" + count + u"]份备份") |
||||||
|
print(u"|---文件名:" + filename) |
||||||
|
|
||||||
|
# 清理多余备份 |
||||||
|
backups = sql.table('backup').where( |
||||||
|
'type=? and pid=?', ('0', pid)).field('id,filename').select() |
||||||
|
|
||||||
|
num = len(backups) - int(count) |
||||||
|
if num > 0: |
||||||
|
for backup in backups: |
||||||
|
public.execShell("rm -f " + backup['filename']) |
||||||
|
sql.table('backup').where('id=?', (backup['id'],)).delete() |
||||||
|
num -= 1 |
||||||
|
print(u"|---已清理过期备份文件:" + backup['filename']) |
||||||
|
if num < 1: |
||||||
|
break |
||||||
|
|
||||||
|
def backupDatabase(self, name, count): |
||||||
|
sql = db.Sql() |
||||||
|
path = sql.table('databases').where('name=?', (name,)).getField('path') |
||||||
|
startTime = time.time() |
||||||
|
if not path: |
||||||
|
endDate = time.strftime('%Y/%m/%d %X', time.localtime()) |
||||||
|
log = u"数据库[" + name + u"]不存在!" |
||||||
|
print(u"★[" + endDate + "] " + log) |
||||||
|
print( |
||||||
|
u"----------------------------------------------------------------------------") |
||||||
|
return |
||||||
|
|
||||||
|
backup_path = public.getRootDir() + '/backup/database' |
||||||
|
if not os.path.exists(backup_path): |
||||||
|
public.execShell("mkdir -p " + backup_path) |
||||||
|
|
||||||
|
filename = backup_path + "/Db_" + name + "_" + \ |
||||||
|
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz" |
||||||
|
|
||||||
|
import re |
||||||
|
mysql_root = sql.table('config').where( |
||||||
|
"id=?", (1,)).getField('mysql_root') |
||||||
|
|
||||||
|
mycnf = public.readFile('/etc/my.cnf') |
||||||
|
rep = "\[mysqldump\]\nuser=root" |
||||||
|
sea = "[mysqldump]\n" |
||||||
|
subStr = sea + "user=root\npassword=" + mysql_root + "\n" |
||||||
|
mycnf = mycnf.replace(sea, subStr) |
||||||
|
if len(mycnf) > 100: |
||||||
|
public.writeFile('/etc/my.cnf', mycnf) |
||||||
|
|
||||||
|
public.execShell( |
||||||
|
"/www/server/mysql/bin/mysqldump --opt --default-character-set=utf8 " + name + " | gzip > " + filename) |
||||||
|
|
||||||
|
if not os.path.exists(filename): |
||||||
|
endDate = time.strftime('%Y/%m/%d %X', time.localtime()) |
||||||
|
log = u"数据库[" + name + u"]备份失败!" |
||||||
|
print(u"★[" + endDate + "] " + log) |
||||||
|
print( |
||||||
|
u"----------------------------------------------------------------------------") |
||||||
|
return |
||||||
|
|
||||||
|
mycnf = public.readFile('/etc/my.cnf') |
||||||
|
mycnf = mycnf.replace(subStr, sea) |
||||||
|
if len(mycnf) > 100: |
||||||
|
public.writeFile('/etc/my.cnf', mycnf) |
||||||
|
|
||||||
|
endDate = time.strftime('%Y/%m/%d %X', time.localtime()) |
||||||
|
outTime = time.time() - startTime |
||||||
|
pid = sql.table('databases').where('name=?', (name,)).getField('id') |
||||||
|
|
||||||
|
sql.table('backup').add('type,name,pid,filename,addtime,size', (1, os.path.basename( |
||||||
|
filename), pid, filename, endDate, os.path.getsize(filename))) |
||||||
|
log = u"数据库[" + name + u"]备份成功,用时[" + str(round(outTime, 2)) + u"]秒" |
||||||
|
public.WriteLog(u'计划任务', log) |
||||||
|
print("★[" + endDate + "] " + log) |
||||||
|
print(u"|---保留最新的[" + count + u"]份备份") |
||||||
|
print(u"|---文件名:" + filename) |
||||||
|
|
||||||
|
# 清理多余备份 |
||||||
|
backups = sql.table('backup').where( |
||||||
|
'type=? and pid=?', ('1', pid)).field('id,filename').select() |
||||||
|
|
||||||
|
num = len(backups) - int(count) |
||||||
|
if num > 0: |
||||||
|
for backup in backups: |
||||||
|
public.execShell("rm -f " + backup['filename']) |
||||||
|
sql.table('backup').where('id=?', (backup['id'],)).delete() |
||||||
|
num -= 1 |
||||||
|
print(u"|---已清理过期备份文件:" + backup['filename']) |
||||||
|
if num < 1: |
||||||
|
break |
||||||
|
|
||||||
|
# 备份指定目录 |
||||||
|
def backupPath(self, path, count): |
||||||
|
sql = db.Sql() |
||||||
|
startTime = time.time() |
||||||
|
if path[-1:] == '/': |
||||||
|
path = path[:-1] |
||||||
|
name = os.path.basename(path) |
||||||
|
backup_path = sql.table('config').where( |
||||||
|
"id=?", (1,)).getField('backup_path') + '/path' |
||||||
|
if not os.path.exists(backup_path): |
||||||
|
os.makedirs(backup_path) |
||||||
|
filename = backup_path + "/Path_" + name + "_" + \ |
||||||
|
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + '.tar.gz' |
||||||
|
os.system("cd " + os.path.dirname(path) + " && tar zcvf '" + |
||||||
|
filename + "' '" + os.path.basename(path) + "' > /dev/null") |
||||||
|
|
||||||
|
endDate = time.strftime('%Y/%m/%d %X', time.localtime()) |
||||||
|
if not os.path.exists(filename): |
||||||
|
log = u"目录[" + path + "]备份失败" |
||||||
|
print(u"★[" + endDate + "] " + log) |
||||||
|
print( |
||||||
|
u"----------------------------------------------------------------------------") |
||||||
|
return |
||||||
|
|
||||||
|
outTime = time.time() - startTime |
||||||
|
sql.table('backup').add('type,name,pid,filename,addtime,size', |
||||||
|
('2', path, '0', filename, endDate, os.path.getsize(filename))) |
||||||
|
log = u"目录[" + path + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒" |
||||||
|
public.writeLog(u'计划任务', log) |
||||||
|
print(u"★[" + endDate + "] " + log) |
||||||
|
print(u"|---保留最新的[" + count + u"]份备份") |
||||||
|
print(u"|---文件名:" + filename) |
||||||
|
|
||||||
|
# 清理多余备份 |
||||||
|
backups = sql.table('backup').where( |
||||||
|
'type=? and pid=? and name=?', ('2', 0, path)).field('id,filename').select() |
||||||
|
num = len(backups) - int(count) |
||||||
|
if num > 0: |
||||||
|
for backup in backups: |
||||||
|
public.execShell("rm -f " + backup['filename']) |
||||||
|
sql.table('backup').where('id=?', (backup['id'],)).delete() |
||||||
|
num -= 1 |
||||||
|
print(u"|---已清理过期备份文件:" + backup['filename']) |
||||||
|
if num < 1: |
||||||
|
break |
||||||
|
|
||||||
|
def backupSiteAll(self, save): |
||||||
|
sites = public.M('sites').field('name').select() |
||||||
|
for site in sites: |
||||||
|
self.backupSite(site['name'], save) |
||||||
|
|
||||||
|
def backupDatabaseAll(self, save): |
||||||
|
databases = public.M('databases').field('name').select() |
||||||
|
for database in databases: |
||||||
|
self.backupDatabase(database['name'], save) |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
backup = backupTools() |
||||||
|
type = sys.argv[1] |
||||||
|
if type == 'site': |
||||||
|
if sys.argv[2] == 'ALL': |
||||||
|
backup.backupSiteAll(sys.argv[3]) |
||||||
|
else: |
||||||
|
backup.backupSite(sys.argv[2], sys.argv[3]) |
||||||
|
elif type == 'path': |
||||||
|
backup.backupPath(sys.argv[2], sys.argv[3]) |
||||||
|
elif type == 'database': |
||||||
|
if sys.argv[2] == 'ALL': |
||||||
|
backup.backupDatabaseAll(sys.argv[3]) |
||||||
|
else: |
||||||
|
backup.backupDatabase(sys.argv[2], sys.argv[3]) |
@ -0,0 +1,70 @@ |
|||||||
|
#!/usr/bin/python |
||||||
|
# coding: utf-8 |
||||||
|
#----------------------------- |
||||||
|
# 网站日志切割脚本 |
||||||
|
#----------------------------- |
||||||
|
import sys |
||||||
|
import os |
||||||
|
import shutil |
||||||
|
import time |
||||||
|
import glob |
||||||
|
|
||||||
|
if sys.platform != 'darwin': |
||||||
|
os.chdir('/www/server/mdserver-web') |
||||||
|
|
||||||
|
|
||||||
|
chdir = os.getcwd() |
||||||
|
sys.path.append(chdir + '/class/core') |
||||||
|
reload(sys) |
||||||
|
sys.setdefaultencoding('utf-8') |
||||||
|
|
||||||
|
import public |
||||||
|
print('==================================================================') |
||||||
|
print('★[' + time.strftime("%Y/%m/%d %H:%M:%S") + '],切割日志') |
||||||
|
print('==================================================================') |
||||||
|
print('|--当前保留最新的[' + sys.argv[2] + ']份') |
||||||
|
logsPath = public.getLogsDir() |
||||||
|
px = '.log' |
||||||
|
|
||||||
|
|
||||||
|
def split_logs(oldFileName, num): |
||||||
|
global logsPath |
||||||
|
if not os.path.exists(oldFileName): |
||||||
|
print('|---' + oldFileName + '文件不存在!') |
||||||
|
return |
||||||
|
|
||||||
|
logs = sorted(glob.glob(oldFileName + "_*")) |
||||||
|
count = len(logs) |
||||||
|
num = count - num |
||||||
|
|
||||||
|
for i in range(count): |
||||||
|
if i > num: |
||||||
|
break |
||||||
|
os.remove(logs[i]) |
||||||
|
print('|---多余日志[' + logs[i] + ']已删除!') |
||||||
|
|
||||||
|
newFileName = oldFileName + '_' + time.strftime("%Y-%m-%d_%H%M%S") + '.log' |
||||||
|
shutil.move(oldFileName, newFileName) |
||||||
|
print('|---已切割日志到:' + newFileName) |
||||||
|
|
||||||
|
|
||||||
|
def split_all(save): |
||||||
|
sites = public.M('sites').field('name').select() |
||||||
|
for site in sites: |
||||||
|
oldFileName = logsPath + site['name'] + px |
||||||
|
split_logs(oldFileName, save) |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
num = int(sys.argv[2]) |
||||||
|
if sys.argv[1].find('ALL') == 0: |
||||||
|
split_all(num) |
||||||
|
else: |
||||||
|
siteName = sys.argv[1] |
||||||
|
if siteName[-4:] == '.log': |
||||||
|
siteName = siteName[:-4] |
||||||
|
else: |
||||||
|
siteName = siteName.replace("-access_log", '') |
||||||
|
oldFileName = logsPath + '/' + sys.argv[1] |
||||||
|
split_logs(oldFileName, num) |
||||||
|
path = public.getServerDir() |
||||||
|
os.system("kill -USR1 `cat " + path + "/openresty/nginx/logs/nginx.pid`") |
Loading…
Reference in new issue