Kaynağa Gözat

Merge branch 'master' of https://github.com/meolu/walle-web

owen-carter 6 yıl önce
ebeveyn
işleme
fc3081c327

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
fe/index.html


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/css/app.6139497f1a93e48ac6e3bd2a4af90e8d.css


BIN
fe/static/css/app.6139497f1a93e48ac6e3bd2a4af90e8d.css.gz


Dosya farkı çok büyük olduğundan ihmal edildi
+ 10 - 0
fe/static/js/1.2c1950c52d1dcc261e0d.js


BIN
fe/static/js/1.2c1950c52d1dcc261e0d.js.gz


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/10.d96c5f15a3fdb637bc1b.js


+ 1 - 0
fe/static/js/11.a05279fb08d9b36f0937.js

@@ -0,0 +1 @@
+webpackJsonp([11],{"/Fi9":function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var s={render:function(){this.$createElement;this._self._c;return this._m(0)},staticRenderFns:[function(){var e=this.$createElement,t=this._self._c||e;return t("div",{staticClass:"wl-home"},[t("h2",[this._v("更快,更优,更 Cool !"),t("br"),this._v("欢迎使用 WALLE")])])}]};var i=n("VU/8")(null,s,!1,function(e){n("Cs2V")},null,null);t.default=i.exports},Cs2V:function(e,t){}});

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/12.4b331270130de479fe72.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 10 - 0
fe/static/js/2.5c99d38afd0a8bcc8988.js


BIN
fe/static/js/2.5c99d38afd0a8bcc8988.js.gz


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/3.d1ed3e50473afdd944f1.js


BIN
fe/static/js/3.d1ed3e50473afdd944f1.js.gz


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/4.2601c036dbdd7e1c908e.js


BIN
fe/static/js/4.2601c036dbdd7e1c908e.js.gz


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/5.42f84267389f42087c75.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/6.bf409aaf0cad3365017d.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/7.3ae5229b4a22eff43d97.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/8.72c29cc84541b4585cda.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/9.9749c6d25f7cb7cadccf.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/app.6c2e60168c47ee5a777a.js


BIN
fe/static/js/app.6c2e60168c47ee5a777a.js.gz


Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 0
fe/static/js/manifest.3a71f7d6e65369bc498c.js


+ 1 - 1
walle/app.py

@@ -185,7 +185,7 @@ def register_socketio(app):
         return app
     socketio.init_app(app, async_mode='gevent')
     socketio.on_namespace(WalleSocketIO(namespace='/walle'))
-    socketio.run(app, host=app.config.get('HOST'), port=app.config.get('PORT'))
+    socketio.run(app, debug=True, host=app.config.get('HOST'), port=app.config.get('PORT'))
     return app
 
 

+ 4 - 5
walle/config/settings_prod.py

@@ -19,20 +19,18 @@ class ProdConfig(Config):
     """Production configuration."""
 
     # 服务启动 @TODO
-    # 跟hosts, nginx配置一致
-    # HOST = 'admin.walle-web.io'
     HOST = '0.0.0.0'
     PORT = 5000
 
     ENV = 'prod'
     DEBUG = False
-    PROPAGATE_EXCEPTIONS = True
+    # PROPAGATE_EXCEPTIONS = True
     WTF_CSRF_ENABLED = False
     DEBUG_TB_ENABLED = False
     CACHE_TYPE = 'simple'
 
     # 数据库设置 @TODO
-    SQLALCHEMY_DATABASE_URI = 'mysql://user:password@localhost/walle'
+    SQLALCHEMY_DATABASE_URI = 'mysql://user:password@localhost:3306/walle_python'
 
     # 设置session的保存时间。
     PERMANENT_SESSION_LIFETIME = timedelta(days=1)
@@ -56,9 +54,9 @@ class ProdConfig(Config):
 
     # 日志 @TODO
     LOG_PATH = os.path.join(Config.PROJECT_ROOT, 'logs')
+    LOG_PATH_EXCEPTION = os.path.join(LOG_PATH, 'exception.log')
     LOG_PATH_ERROR = os.path.join(LOG_PATH, 'error.log')
     LOG_PATH_INFO = os.path.join(LOG_PATH, 'info.log')
-    LOG_PATH_DEBUG = os.path.join(LOG_PATH, 'debug.log')
     LOG_FILE_MAX_BYTES = 100 * 1024 * 1024
 
     # 轮转数量是 10 个
@@ -66,6 +64,7 @@ class ProdConfig(Config):
     LOG_FORMAT = "%(asctime)s %(thread)d %(message)s"
 
     # 宿主机(walle部署所在的机器以及用户) @TODO
+    # 启动walle服务的用户A, LOCAL_SERVER_USER == B
     LOCAL_SERVER_HOST = '127.0.0.1'
     LOCAL_SERVER_USER = 'work'
     LOCAL_SERVER_PORT = 22

+ 11 - 0
walle/service/code.py

@@ -51,12 +51,20 @@ class Code():
 
     #: ----------------------- 4xxx git 相关错误 -----------------
     #: 3xxx shell相关错误
+    #: git操作失败
+    shell_git_fail = 4000
+
     #: git尚未初始化
     shell_git_init_fail = 4001
 
     #: git pull 失败
     shell_git_pull_fail = 4002
 
+    #: ----------------------- 5xxx 部署相关错误 -----------------
+    #: 5xxx 部署相关错误
+    #: 任务部署失败,已终止。请修复错误后,重新部署。
+    deploy_fail = 5001
+
     code_msg = {
         unlogin: '未登录',
         error_pwd: '账号密码错误',
@@ -71,6 +79,9 @@ class Code():
         shell_run_fail: '命令运行错误,请联系管理员',
         shell_dir_not_exists: '路径不存在,请联系管理员',
 
+        shell_git_fail: 'git 操作失败,请联系管理员',
         shell_git_init_fail: '项目git初始化失败,请联系管理员',
         shell_git_pull_fail: 'git pull 失败,请联系管理员',
+
+        deploy_fail: '任务部署失败,已终止。请修复错误后,重新部署。',
     }

+ 44 - 49
walle/service/deployer.py

@@ -16,9 +16,9 @@ from walle.model.record import RecordModel
 from walle.model.task import TaskModel
 from walle.service.code import Code
 from walle.service.error import WalleError
-from walle.service.extensions import socketio
 from walle.service.utils import color_clean
 from walle.service.waller import Waller
+from flask_socketio import emit
 
 
 class Deployer:
@@ -77,6 +77,8 @@ class Deployer:
         self.project_name = self.project_info['id']
         self.dir_codebase_project = self.local_codebase + str(self.project_name)
 
+        self.init_repo()
+
         # start to deploy
         self.console = console
 
@@ -139,8 +141,6 @@ class Deployer:
         :param project_name:
         :return:
         '''
-        # TODO
-        socketio.sleep(0.001)
         self.stage = self.stage_deploy
         self.sequence = 2
 
@@ -163,7 +163,8 @@ class Deployer:
         # copy to a local version
         self.release_version = '%s_%s_%s' % (
             self.project_name, self.task_id, time.strftime('%Y%m%d_%H%M%S', time.localtime(time.time())))
-        with self.local.cd(self.dir_codebase):
+
+        with self.local.cd(self.local_codebase):
             command = 'cp -rf %s %s' % (self.dir_codebase_project, self.release_version)
             current_app.logger.info('cd %s  command: %s  ', self.dir_codebase_project, command)
 
@@ -174,7 +175,8 @@ class Deployer:
             command = 'git reset -q --hard %s' % (self.taskMdl.get('commit_id'))
             result = self.local.run(command, wenv=self.config())
 
-        pass
+            if result.exited != Code.Ok:
+                raise WalleError(Code.shell_git_fail, message=result.stdout)
 
     def post_deploy(self):
 
@@ -188,8 +190,6 @@ class Deployer:
         - 传送到版本库 release
         :return:
         '''
-        # TODO
-        socketio.sleep(0.001)
         self.stage = self.stage_post_deploy
         self.sequence = 3
 
@@ -200,8 +200,8 @@ class Deployer:
 
         # 压缩打包
         self.release_version_tar = '%s.tgz' % (self.release_version)
-        with self.local.cd(self.dir_codebase):
-            command = 'tar zcvf %s %s' % (self.release_version_tar, self.release_version)
+        with self.local.cd(self.local_codebase):
+            command = 'tar zcf %s %s' % (self.release_version_tar, self.release_version)
             result = self.local.run(command, wenv=self.config())
 
     def prev_release(self, waller):
@@ -210,8 +210,6 @@ class Deployer:
         - 检查 webroot 父目录是否存在
         :return:
         '''
-        # TODO
-        socketio.sleep(0.001)
         self.stage = self.stage_prev_release
         self.sequence = 4
 
@@ -248,8 +246,6 @@ class Deployer:
         - 解压 remote
         :return:
         '''
-        # TODO
-        socketio.sleep(0.001)
         self.stage = self.stage_release
         self.sequence = 5
 
@@ -272,8 +268,6 @@ class Deployer:
         解压版本包
         :return:
         '''
-        # TODO
-        socketio.sleep(0.001)
         with waller.cd(self.project_info['target_releases']):
             command = 'tar zxf %s' % (self.release_version_tar)
             result = waller.run(command, wenv=self.config())
@@ -307,37 +301,33 @@ class Deployer:
             result = waller.run(command, wenv=self.config())
 
     def list_tag(self):
-        self.init_repo()
-
         with self.local.cd(self.dir_codebase_project):
             command = 'git tag -l'
-            result = self.local.run(command, wenv=self.config())
-            tags = color_clean(result.stdout.strip())
+            result = self.local.run(command, pty=False, wenv=self.config())
+            tags = result.stdout.strip()
             tags = tags.split('\n')
             return [color_clean(tag.strip()) for tag in tags]
 
         return None
 
     def list_branch(self):
-        self.init_repo()
-
         with self.local.cd(self.dir_codebase_project):
             command = 'git pull'
             result = self.local.run(command, wenv=self.config())
 
             if result.exited != Code.Ok:
-                raise WalleError(Code.shell_git_pull_fail)
+                raise WalleError(Code.shell_git_pull_fail, message=result.stdout)
 
             current_app.logger.info(self.dir_codebase_project)
 
             command = 'git branch -r'
-            result = self.local.run(command, wenv=self.config())
+            result = self.local.run(command, pty=False, wenv=self.config())
 
             # if result.exited != Code.Ok:
             #     raise WalleError(Code.shell_run_fail)
 
             # TODO 三种可能: false, error, success
-            branches = color_clean(result.stdout.strip())
+            branches = result.stdout.strip()
             branches = branches.split('\n')
             # 去除 origin/HEAD -> 当前指向
             # 去除远端前缀
@@ -348,25 +338,23 @@ class Deployer:
         return None
 
     def list_commit(self, branch):
-        self.init_repo()
-
         with self.local.cd(self.dir_codebase_project):
             command = 'git checkout %s && git pull' % (branch)
             self.local.run(command, wenv=self.config())
 
-            command = 'git log -35 --pretty="%h #_# %an #_# %s"'
-            result = self.local.run(command, wenv=self.config())
+            command = 'git log -50 --pretty="%h #@_@# %an #@_@# %s"'
+            result = self.local.run(command, pty=False, wenv=self.config())
             current_app.logger.info(result.stdout)
 
-            commit_log = color_clean(result.stdout.strip())
+            commit_log = result.stdout.strip()
             current_app.logger.info(commit_log)
             commit_list = commit_log.split('\n')
             commits = []
             for commit in commit_list:
-                if not re.search('^.+ #_# .+ #_# .*$', commit):
+                if not re.search('^.+ #@_@# .+ #@_@# .*$', commit):
                     continue
 
-                commit_dict = commit.split(' #_# ')
+                commit_dict = commit.split(' #@_@# ')
                 current_app.logger.info(commit_dict)
                 commits.append({
                     'id': commit_dict[0],
@@ -405,26 +393,33 @@ class Deployer:
 
     def end(self, success=True):
         status = TaskModel.status_success if success else TaskModel.status_fail
+        current_app.logger.info('success:%s, status:%s' % (success, status))
         TaskModel().get_by_id(self.task_id).update({'status': status})
 
     def walle_deploy(self):
         self.start()
-        self.prev_deploy()
-        self.deploy()
-        self.post_deploy()
-
-        all_servers_success = True
-        for server_info in self.servers:
-            server = server_info['host']
-            try:
-                self.connections[server] = Waller(host=server, user=self.project_info['target_user'])
-                self.prev_release(self.connections[server])
-                self.release(self.connections[server])
-                self.post_release(self.connections[server])
-            except Exception as e:
-                current_app.logger.error(e)
-                all_servers_success = False
-                self.errors[server] = e.message
-
-        self.end(all_servers_success)
+
+        try:
+            self.prev_deploy()
+            self.deploy()
+            self.post_deploy()
+
+            is_all_servers_success = True
+            for server_info in self.servers:
+                server = server_info['host']
+                try:
+                    self.connections[server] = Waller(host=server, user=self.project_info['target_user'])
+                    self.prev_release(self.connections[server])
+                    self.release(self.connections[server])
+                    self.post_release(self.connections[server])
+                except Exception as e:
+                    is_all_servers_success = False
+                    current_app.logger.error(e)
+                    self.errors[server] = e.message
+            self.end(is_all_servers_success)
+
+        except Exception as e:
+            self.end(False)
+            emit('fail', {'event': 'console', 'data': {'message': Code.code_msg[Code.deploy_fail]}}, room=self.task_id)
+
         return {'success': self.success, 'errors': self.errors}

+ 3 - 3
walle/service/waller.py

@@ -16,7 +16,7 @@ class Waller(Connection):
     connections, success, errors = {}, {}, {}
     release_version_tar, release_version = None, None
 
-    def run(self, command, wenv=None, sudo=False, exception=True, **kwargs):
+    def run(self, command, wenv=None, sudo=False, pty=True, exception=True, **kwargs):
         '''
         pty=True/False是直接影响到输出.False较适合在获取文本,True更适合websocket
 
@@ -33,9 +33,9 @@ class Waller(Connection):
         current_app.logger.info(message)
         try:
             if sudo:
-                result = super(Waller, self).sudo(command, pty=False, **kwargs)
+                result = super(Waller, self).sudo(command, pty=pty, **kwargs)
             else:
-                result = super(Waller, self).run(command, pty=True, warn=True, watchers=[say_yes()], **kwargs)
+                result = super(Waller, self).run(command, pty=pty, warn=True, watchers=[say_yes()], **kwargs)
 
             if result.failed:
                 exitcode, stdout, stderr = result.exited, '', result.stdout

+ 15 - 7
walle/service/websocket.py

@@ -16,6 +16,8 @@ from walle.service.deployer import Deployer
 class WalleSocketIO(Namespace):
     namespace, room, app = None, None, None
 
+    task_id, project_id = None, None
+
     task_info = None
 
     def __init__(self, namespace, room=None, app=None):
@@ -31,7 +33,13 @@ class WalleSocketIO(Namespace):
 
     def on_open(self, message):
         current_app.logger.info(message)
-        self.room = message['task']
+        if 'task' in message:
+            self.task_id = message['task']
+            self.room = self.task_id
+        if 'project_id' in message:
+            self.project_id = message['project_id']
+            self.room = self.project_id
+
         if not current_user.is_authenticated:
             emit('close', {'event': 'disconnect', 'data': {}}, room=self.room)
         join_room(room=self.room)
@@ -47,24 +55,24 @@ class WalleSocketIO(Namespace):
         else:
             emit('console', {'event': 'forbidden', 'data': self.task_info}, room=self.room)
 
-    def on_branches(self, message):
-        wi = Deployer(task_id=self.room)
+    def on_branches(self, message=None):
+        wi = Deployer(project_id=self.room)
         try:
             branches = wi.list_branch()
             emit('branches', {'event': 'branches', 'data': branches}, room=self.room)
         except Exception as e:
             emit('branches', {'event': 'error', 'data': {'message': e.message}}, room=self.room)
 
-    def on_tags(self, message):
-        wi = Deployer(task_id=self.room)
+    def on_tags(self, message=None):
+        wi = Deployer(project_id=self.room)
         try:
             tags = wi.list_tag()
             emit('tags', {'event': 'tags', 'data': tags}, room=self.room)
         except Exception as e:
             emit('tags', {'event': 'error', 'data': {'message': e.message}}, room=self.room)
 
-    def on_commits(self, message):
-        wi = Deployer(task_id=self.room)
+    def on_commits(self, message=None):
+        wi = Deployer(project_id=self.room)
         if 'branch' not in message:
             emit('commits', {'event': 'error', 'data': {'message': 'invalid branch'}}, room=self.room)
         else: