pull/32/merge
apexliu 2017-03-18 01:34:36 +08:00
parent 8a04467e2a
commit 9b59d6ec99
6 changed files with 204 additions and 70 deletions

View File

@ -3,9 +3,6 @@
from eom_app.app.util import sec_generate_password
from eom_common.eomcore.logger import log
# 升级数据表结构时必须升级此版本号并编写响应的升级SQL
TELEPORT_DATABASE_VERSION = 10
def _db_exec(db, step_begin, step_end, msg, sql):
_step = step_begin(msg)
@ -18,7 +15,7 @@ def _db_exec(db, step_begin, step_end, msg, sql):
step_end(_step, 0)
def create_and_init(db, step_begin, step_end):
def create_and_init(db, step_begin, step_end, db_ver):
try:
_db_exec(db, step_begin, step_end, '创建表 account', """CREATE TABLE `{}account` (
`account_id` integer PRIMARY KEY AUTOINCREMENT,
@ -107,7 +104,7 @@ PRIMARY KEY (`name` ASC)
_db_exec(db, step_begin, step_end,
'设定数据库版本',
'INSERT INTO `{}config` VALUES ("db_ver", "{}");'.format(db.table_prefix, TELEPORT_DATABASE_VERSION)
'INSERT INTO `{}config` VALUES ("db_ver", "{}");'.format(db.table_prefix, db_ver)
)
return True

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from eom_app.app.util import sec_generate_password
from eom_common.eomcore.logger import log
def _db_exec(db, step_begin, step_end, msg, sql):
_step = step_begin(msg)
ret = db.exec(sql)
if not ret:
step_end(_step, -1)
raise RuntimeError('[FAILED] {}'.format(sql))
else:
step_end(_step, 0)
def upgrade_database(db, step_begin, step_end, db_ver):
try:
pass
return True
except:
log.e('ERROR')
return False

View File

@ -7,7 +7,8 @@ import threading
from eom_common.eomcore.logger import log
from .configs import app_cfg
from .database.create import create_and_init, TELEPORT_DATABASE_VERSION
from .database.create import create_and_init
from .database.upgrade import upgrade_database
cfg = app_cfg()
@ -15,7 +16,7 @@ __all__ = ['get_db']
# 注意,每次调整数据库结构,必须增加版本号,并且在升级接口中编写对应的升级操作
# TELEPORT_DATABASE_VERSION = 2
TELEPORT_DATABASE_VERSION = 10
class TPDatabase:
@ -55,7 +56,7 @@ class TPDatabase:
# 尝试从配置表中读取当前数据库版本号如果不存在说明是比较旧的版本了则置为0
ret = self.query('SELECT `value` FROM {}config WHERE `name`="db_ver";'.format(self._table_prefix))
if ret is None or 0 == len(ret):
if ret is None or 0 == len(ret) or ret[0][0] < TELEPORT_DATABASE_VERSION:
log.w('database need upgrade.\n')
self.need_upgrade = True
@ -67,12 +68,20 @@ class TPDatabase:
def create_and_init(self, step_begin, step_end):
step_begin('准备创建数据表')
if create_and_init(self, step_begin, step_end):
if create_and_init(self, step_begin, step_end, TELEPORT_DATABASE_VERSION):
self.need_create = False
return True
else:
return False
def upgrade_database(self, step_begin, step_end):
step_begin('准备升级数据表')
if upgrade_database(self, step_begin, step_end, TELEPORT_DATABASE_VERSION):
self.need_upgrade = False
return True
else:
return False
class TPDatabasePool:
def __init__(self):

View File

@ -2,7 +2,6 @@
import json
import threading
import time
from eom_app.app.configs import app_cfg
from eom_app.app.const import *
@ -11,8 +10,6 @@ from .base import TPBaseUserAuthHandler, TPBaseAdminAuthHandler, TPBaseAdminAuth
cfg = app_cfg()
# from eom_app.app.util import sec_generate_password, sec_verify_password
class IndexHandler(TPBaseUserAuthHandler):
def get(self):
@ -56,6 +53,17 @@ class RpcThreadManage:
return task_id
def upgrade_db(self):
with self._lock:
self._id_base += 1
task_id = self._id_base
t = threading.Thread(target=self._upgrade_db, args=[task_id])
self._threads[task_id] = {'cmd': 'create_db', 'running': True, 'stop': False, 'steps': list()}
t.start()
return task_id
def get_task(self, task_id):
with self._lock:
if task_id in self._threads:
@ -83,34 +91,31 @@ class RpcThreadManage:
self._threads[task_id]['stop'] = True
def _create_db(self, tid):
# x = sec_generate_password('admin')
# print(sec_verify_password('admin', x))
# print(sec_verify_password('.admin', x))
def _step_begin(msg):
self._step_begin(tid, msg)
def _step_end(sid, code, msg=None):
self._step_end(tid, sid, code, msg)
time.sleep(1)
# self._add_step_result(tid, 0, '正在初始化 1...')
if get_db().create_and_init(_step_begin, _step_end):
cfg.app_mode = APP_MODE_NORMAL
self._step_begin(tid, '操作已完成')
# time.sleep(1)
# self._add_step_result(tid, 0, '正在初始化 2...')
# time.sleep(1)
# self._add_step_result(tid, 0, '正在初始化 3...')
# time.sleep(1)
# self._add_step_result(tid, 0, '正在初始化 4...')
self._thread_end(tid)
def _upgrade_db(self, tid):
def _step_begin(msg):
self._step_begin(tid, msg)
def _step_end(sid, code, msg=None):
self._step_end(tid, sid, code, msg)
if get_db().upgrade_database(_step_begin, _step_end):
cfg.app_mode = APP_MODE_NORMAL
self._step_begin(tid, '操作已完成')
# self._threads[tid]['steps'].append({'stat': 0, 'msg': '执行已结束'})
# if self._threads[tid]['stop']:
# self._add_step_result(tid, -1, '操作被终止')
self._thread_end(tid)
def _step_begin(self, tid, msg):
@ -133,11 +138,6 @@ class RpcThreadManage:
return len(self._threads[tid]['steps']) - 1
# def _add_step_result(self, tid, code, msg):
# if len(self._threads[tid]['steps']) > 0:
# self._threads[tid]['steps'][-1]['stat'] = 0 # 0 表示此步骤已完成
# self._threads[tid]['steps'].append({'stat': 1, 'code': code, 'msg': msg})
def _thread_end(self, tid):
with self._lock:
if tid in self._threads:
@ -171,13 +171,18 @@ class RpcHandler(TPBaseAdminAuthJsonHandler):
task_id = thread_mgr.create_db()
return self.write_json(0, data={"task_id": task_id})
if cmd == 'upgrade_db':
if not get_db().need_upgrade:
return self.write_json(-1)
task_id = thread_mgr.upgrade_db()
return self.write_json(0, data={"task_id": task_id})
elif cmd == 'get_task_ret':
# return self.write_json(-1)
r = thread_mgr.get_task(args['tid'])
if r is None:
return self.write_json(0, data={'running': False, 'steps': []})
else:
# del r['stop']
return self.write_json(0, data=r)
else:

View File

@ -53,8 +53,8 @@
<h1>配置TELEPORT服务</h1>
<hr/>
<h2>第一步:创建数据表 <span id="step-create-db-result"></span></h2>
<div id="step-create-db">
<h2>第一步:创建数据表</h2>
<div>
<p>请选择要使用的数据库类型暂时仅支持sqlite其它类型开发中</p>
<input id="db-sqlite" type="radio" checked="checked" name="database" value="sqlite"/> <label for="db-sqlite">SQLite</label><br/>
<input id="db-mysql" type="radio" name="database" value="mysql" disabled="disabled"/> <label for="db-mysql">MySQL开发中暂不支持</label>

View File

@ -1,7 +1,5 @@
<%!
page_title_ = '系统升级'
## page_menu_ = ['user']
## page_id_ = 'user'
page_title_ = '升级TELEPORT服务'
%>
<%inherit file="../page_maintenance_base.mako"/>
@ -13,34 +11,34 @@
<%block name="embed_css">
<style type="text/css">
.content_box {
margin-top:48px;
.container {
background-color: #fff;
padding-bottom: 20px;
}
.content_box .error_sidebar {
float: left;
width: 160px;
margin-left: 120px;
font-size: 260px;
color: #e3693b;
h1 {
font-size: 200%;
}
.content_box .error_content {
min-height: 400px;
width: 800px;
padding: 30px;
margin-left: 300px;
background: #ffffff;
border-radius: 5px;
background: rgba(255, 255, 255, 0.8);
background: #fff \9;
z-index: 9;
position: relative;
h2 {
font-size: 160%;
}
h1 .fa-spin {
color:#aaa;
.steps-detail {
display: none;
margin:10px;
padding:10px;
border:1px solid #b4b4b4;
background-color: #dcdcdc;
}
.steps-detail p {
padding-left:5px;
margin:2px 0 2px 1px;
}
.steps-detail p.error {
color:#ffffff;
margin:2px 0 2px 0;
background-color: #cc3632;
border:1px solid #9c2a26;
}
</style>
</%block>
@ -52,18 +50,119 @@
<div class="content_box">
<div class="container">
<div class="error_sidebar">
<i class="fa fa-exclamation-triangle"></i>
<h1>升级TELEPORT服务</h1>
<hr/>
<h2>第一步:升级数据库</h2>
<div>
<div>
<button id="btn-upgrade-db" type="button" class="btn btn-primary"><i class="fa fa-wrench fa-fw"></i> 开始升级</button>
</div>
<div id="steps-detail" class="steps-detail"></div>
</div>
<div class="error_content">
<br/>
<h1><i class="fa fa-cog fa-spin"></i> 系统维护中...</h1>
<hr/>
<p>系统管理员正在紧张地维护系统,请稍后刷新页面重试!</p>
</div>
</div>
</div>
</div>
<%block name="embed_js">
<script type="text/javascript">
"use strict";
ywl.on_init = function (cb_stack, cb_args) {
ywl.dom = {
btn_upgrade_db: $('#btn-upgrade-db'),
steps_detail: $('#steps-detail')
};
ywl.dom.btn_upgrade_db.click(function () {
ywl.dom.btn_upgrade_db.attr('disabled', 'disabled').hide();
ywl.dom.steps_detail.show();
console.log('upgrade-db-click');
ywl.ajax_post_json('/maintenance/rpc', {cmd: 'upgrade_db'},
function (ret) {
console.log('upgrade-db:', ret);
if (ret.code == 0) {
var cb_stack = CALLBACK_STACK.create();
cb_stack
.add(ywl.get_task_ret, {task_id: ret.data.task_id})
.add(ywl.delay_exec, {delay_ms: 500})
.exec();
}
},
function () {
ywl.show_message('error', '无法连接到服务器!');
}
);
});
ywl.get_task_ret = function (cb_stack, cb_args) {
var task_id = cb_args.task_id || 0;
if (task_id == 0) {
console.log('task-id', task_id);
return;
}
ywl.ajax_post_json('/maintenance/rpc', {cmd: 'get_task_ret', 'tid': task_id},
function (ret) {
console.log('get_task_ret:', ret);
if (ret.code == 0) {
// show step progress.
var steps = ret.data.steps;
ywl.dom.steps_detail.empty();
var html = [];
var icon_class = '';
var err_class = '';
for(var i = 0; i < steps.length; ++i) {
if(steps[i].stat == 0)
icon_class = 'fa-check';
else
icon_class = 'fa-cog fa-spin';
if(steps[i].code != 0)
err_class = ' class="error"';
else
err_class = '';
html.push('<p');
html.push(err_class);
html.push('><i class="fa ');
html.push(icon_class);
html.push('"></i> ');
html.push(steps[i].msg);
html.push('</p>')
}
ywl.dom.steps_detail.html(html.join(''));
if (!ret.data.running) {
return;
}
cb_stack
.add(ywl.get_task_ret, {task_id: task_id})
.add(ywl.delay_exec, {delay_ms: 500})
.exec();
}
},
function () {
ywl.show_message('error', '无法连接到服务器!');
}
);
};
cb_stack.exec();
};
</script>
</%block>