一,流程图
二,流程简述
运维人员在浏览器中选择要发版的项目,点击发版按钮,程序会首先检测是否有其他进程在发布,通过检查lock的方法,如果lock文件存在,则返回首页,否则将要发版执行的shell命令写入到newfile.txt文件中,待后端进程读取执行。后端python程序每3秒自动执行,读取newfile.txt中的命令,并执行,将结果输出至install.log文件中,前端通过websocket获取日志信息并打印到浏览器。
三,代码实现
1, 前端页面
<?php
//拼接发版命令参数
$srv_s = implode(' ', $_POST['srv']);
//发版命令
$cmd = "./web_test.sh " . $srv_s;
//判断lock文件,是否继续进行发布
if (file_exists('/srv/shell/faban.lock')) {
echo 'There is another process runing!';
echo '<br/><br/>';
echo '<a href="/faban.php">GO_BACK</a>';
exit;
}
//写入将发版命令写入到newfile.txt文件中,供后端python程序读取
$file = fopen("/srv/shell/newfile.txt", "w") or die("Unable to open file!");
fwrite($file, $cmd);
fclose($file);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
#all {margin:10px auto;padding:10px;font-family: "Pingfang SC",STHeiti,"Lantinghei SC","Open Sans",Arial,"Hiragino Sans GB","Microsoft YaHei","WenQuanYi Micro Hei",SimSun,sans-serif;}
#all table img{}
#con {margin:0px auto;padding:10px;width:1220px;border:1px #ccc solid;}
#con .box {display:block;float:left;margin:5px;}
</style>
</head>
<body>
<div id='all'>
<div style='margin:0px auto;padding:10px;width:1220px;'>
<a href='http://172.16.100.225:22122/faban.php'>前端发版系统</a>
</div>
<div id='con'>
<h2>前端测试发版页面</h2>
<form id='form' action='./faban.php' method='post'>
<span>阿里云测试</span><input type='radio' name='env' value='1' checked='checked'/>
<!--<span>环境 3</span><input type='radio' name='env' value='3' />; -->
<hr/>
<!--配置发版的项目名称,与后端脚本参数对应 -->
<input type='radio' name='srv[]' id='apptest' value='apptest' /><label for='apptest'><span>apptest</span></label></br>
</br></br>
<input type='submit' id='submit' value=' 发版 ' />
</form>
<div id="result" style="margin: 30px;color: #888888; text-align: center;"></div>
<div style='clear:both;width:1000px;height:1px'></div>
</div>
<div style="height:100px;margin:0px auto;padding:5px;width:1220px;">
<textarea id='log' style="margin: 0px; width: 1210px; height: 300px; font-weight:800;"></textarea>
</div>
</div>
</body>
</html>
<script src='./jquery-2.1.4.min.js'></script>
<script language='javascript'>
//获取发版项目名称
$(function(){
$('#form').submit(function(){
srv='';
$("input[type=radio][name='srv[]']:checked").each(function(){srv = srv + ' ' +$(this).val();});
if(!confirm('发版项目:'+srv+'?')){
return false;
}
alert('发版任务已提交后台执行,请耐心等待');
});
});
</script>
<script>
// 控制台打印方法,
function log(msg) {
document.getElementById('log').textContent += msg + '\n';
var height = document.getElementById('log').scrollHeight;
//日志自动刷新
$("#log").scrollTop(height);
}
// websocketd回调方法
window.setInterval(function(){ //每隔5秒钟发送一次心跳,避免websocket连接因超时而自动断开
var ping = {"type":"ping"};
ws.send(JSON.stringify(ping));
},5000);
var ws = new WebSocket('ws://172.16.100.225:3888/');
ws.onopen = function() {
document.getElementById("log").style.backgroundColor = " #000000";
document.getElementById("log").style.color="#FFFFFF";
log('CONNECT');
};
ws.onclose = function() {
log('DISCONNECT');
};
ws.onmessage = function(event) {
log('[root@minzitong ~]# ' + event.data);
// console.log(event.data)
};
</script>
2, 后端python程序faban.py(python版本2.7.5)
#!/usr/bin/python
import os
import sys
import time
from subprocess import call
log = open("install.log", "w")
def faban():
if os.stat('newfile.txt').st_size > 0:
with open('newfile.txt') as f:
for line in f:
cmd = line.split(' ')[0] + " " + line.split(' ')[1]
open('/srv/shell/faban.lock', 'w').close()
call(cmd, shell=True, stdout=log)
os.remove('/srv/shell/faban.lock')
open('newfile.txt', 'w').close()
else:
pass
if __name__ == '__main__':
while True:
time.sleep(3)
faban()
设置后台运行
# nohup python faban.py &
3, 启动websocketd
下载地址:http://websocketd.com/ 解压到/usr/local/bin/下
启动:
# nohup /usr/local/bin/websocketd --port=3888 bash ./tailf.sh &
4, shell脚本web_test.sh(vue项目为例)
#!/bin/bash
if [ $# -lt 1 ]; then
echo "usage: $0 <project>"
exit 1
fi
project=$1
echo "=======================开始执行$(date)====================="
cd /srv/shell
if [ -e $project ]; then
rm -rf ${project}*
fi
deploy(){
local USER=$1 # git用户
local PROJECT=$2 # 项目名称
local HOST=$3 # 部署主机
local PORT=$4 # 主机端口
local BRANCH=$5 # git分支
local ENV=$6 # 编译环境
rm -rf /srv/shell/${PROJECT}
# 拉取代码
git clone -b ${BRANCH} git@git.newpro.com:${USER}/${PROJECT}.git
cd /srv/shell/${PROJECT}
/opt/node/bin/npm install
npm run build${ENV}
if [ $? -ne 0 ]; then
echo "${PROJECT} 构建失败。。。"
exit 3
fi
tar -zcvf ${PROJECT}.tar.gz ./dist/
# 发布代码
ssh -p ${PORT} ${HOST} "if [ ! -d /mnt/wwwroot/${PROJECT} ]; then mkdir -pv /mnt/wwwroot/${PROJECT}/dist; fi"
scp -P ${PORT} -r ${PROJECT}.tar.gz ${HOST}:/mnt/wwwroot/${PROJECT}
ssh -p ${PORT} ${HOST} "mv /mnt/wwwroot/${PROJECT}/dist /mnt/wwwroot/${PROJECT}/dist_$(date +'%Y%m%d%H%M')"
ssh -p ${PORT} ${HOST} "cd /mnt/wwwroot/${PROJECT}; tar -xvf ${PROJECT}.tar.gz"
ssh -p ${PORT} ${HOST} "chown -R www.www /mnt/wwwroot/${PROJECT}/"
ssh -p ${PORT} ${HOST} "cd /mnt/wwwroot/${PROJECT}; find . -regex './dist_[0-9]*$' -type d | sort -rn | sed -n '6,\$p' | xargs rm -rf "
echo "${PROJECT} 发版完毕"
}
if [ $project == 'apptest' ]; then
deploy test apptest testapp 22 master :test
fi
四,最终效果展示
转载于:https://blog.51cto.com/hld1992/2386045