平臺化管理Linux環境的客戶端程序的部署、更新、以及進程關閉javascript
平臺是用SSH實現,前端是avalon,數據庫mysql客戶端程序(Monitor, CLientSetup)是spring boot實現平臺操做界面以下:css
客戶端程序訪問路徑爲 http://ip:8034, html
獲取版本方式爲 http://ip:8034/Deploy/Version前端
心跳地址爲 http://ip:8034/Deploy/ReturnOkjava
1. 更新狀態訪問版本地址,返回該ip對應的版本,落入數據庫,更新頁面信息mysql
2. 部署以及更新應用全部服務器路徑都在ftpuser用戶目錄下,即/STRESSjquery
應用源碼放在服務器A上,爲Monitor.tar,上傳腳本Deploy.sh也在服務器A上,linux
上傳腳本以下:ajax
IP=$1 echo "put tar to "${IP} ftp -n<<! open ${IP} user ftpuser ****** binary prompt mkdir tools cd tools put Monitor.tar put ClientSetup.tar put clientDeploy.sh #chmod 777 clientDeploy.sh close bye !
平臺調用上傳腳本把源碼從服務器A傳到目標服務器B上。spring
平臺再調用服務器B上腳本tools/clientDeploy.sh
cd tools rm -rf Monitor rm -rf ClientSetup tar -xvf Monitor.tar tar -xvf ClientSetup.tar cd ~/tools/Monitor sh restart.sh cd ~/tools/ClientSetup sh restart.sh cd ~/tools rm -rf Monitor.tar rm -rf ClientSetup.tar
平臺調用Java代碼
public String DeployEnvAgency(String ip) throws IOException, InterruptedException { RemoteShellTool tool = new RemoteShellTool("172.16.103.126", "ftpuser", "88888", "utf-8"); String result = tool.exec("sh Deploy.sh "+ip); System.out.print("result:"+result); RemoteShellTool tool2 = new RemoteShellTool(ip, "ftpuser", "******", "utf-8"); String result2 = tool2.exec("sh tools/clientDeploy.sh"); System.out.print("result2:"+result2); return "ok"; }
3. 關閉進程
java代碼:
調用RemoteShellTool類以下:
附
html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link href="/css/reset.css" rel="stylesheet"> <link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet"> <link href="/css/admin/layout.css" rel="stylesheet"> <link href="/css/admin/envinfo.css" rel="stylesheet"> <script type="text/javascript" src="/lib/jquery.js"></script> <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="/bootstrap/js/jquery.bootpag.min.js"></script> <script type="text/javascript" src="/lib/avalon.js"></script> <script type="text/javascript" src="/js/common/util.js"></script> <script type="text/javascript" src="/js/admin/common/common.js"></script> <script type="text/javascript" src="/js/admin/monitordeploy.js"></script> <title>基礎信息管理</title> </head> <body ms-controller="vm"> <!-- ADMIN HEAD --> <div ms-include-src="'/admin/header.html'"></div> <!-- Content --> <div class="container"> <div ms-controller="monitordeploy"> <div class="tabbable"> <div class="tab-content"> <div class="tab-pane active" id="vms"> <div id="vmsTab-pane"> <br/> <div class="row" id="search1Div"> <div class="col-md-2"> <div class="input-group"> <span class="input-group-addon">環境:</span> <select class="form-control" ms-duplex="envType"> <option value="STRESS" selected>STRESS</option> <option value="ALL">所有</option> <option value="SIT1">SIT1</option> <option value="SIT2">SIT2</option> <option value="UAT">UAT</option> <option value="other">其餘</option> </select> </div> </div> <div class="row" id="search2Div"> <div class="col-md-2"> <div class="input-group"> <span class="input-group-addon">類型:</span> <select class="form-control" ms-duplex="conType"> <option value="" selected>請選擇</option> <option value=".Net Web">.Net Web</option> <option value="Windows Service">Windows Service</option> <option value="Node">Node</option> <option value="Java App">Java App</option> <option value="Java Web">Java Web</option> <option value="其餘">其餘</option> </select> </div> </div> <div class="col-md-1"> <button type="button" id="searchBtn" class="btn btn-primary" ms-click="listVmInfosByPage('init')" style="margin: auto;"> 搜 索 </button> </div> <div class="col-md-1"> <button type="button" id="allCheckBtn" class="btn btn-info" ms-click="checkAll()" style="margin: auto;"> 全選 </button> </div> <div class="col-md-1"> <button type="button" id="allUncheckBtn" class="btn btn-info" ms-click="uncheckAll()" style="margin: auto;"> 全不選 </button> </div> <div class="col-md-1"> <button type="button" id="allStatusBtn" class="btn btn-success" ms-click="viewAllStatus()" style="margin: auto;"> update all </button> </div> <div class="col-md-1"> <button type="button" id="allDeployBtn" class="btn btn-warning" ms-click="deployAll()" style="margin: auto;"> deploy all </button> </div> <div class="col-md-1"> <button type="button" id="allDeployBtn" class="btn btn-danger" ms-click="killAll()" style="margin: auto;"> kill all </button> </div> </div> <div> <div id="pageSizeSelect"><a><span ms-class="{{pagesize1Cls}}" ms-click="changePageSize(pagesize1)">{{pagesize1}}</span></a> | <a><span ms-class="{{pagesize2Cls}}" ms-click="changePageSize(pagesize2)">{{pagesize2}}</span></a> | <a> <spam ms-class="{{pagesize3Cls}}" ms-click="changePageSize(pagesize3)">{{pagesize3}}</spam> </a> </div> </div> <table class="table table-condensed table-hover"> <thead> <tr> <td class="width-50"></td> <td class="width-50">ID</td> <td>名稱</td> <td class="width-125">IP</td> <td class="width-300">操做系統</td> <td class="width-100">監控版本</td> <td class="width-100">Setup版本</td> <td class="width-100">監控狀態</td> <td class="width-100">Setup狀態</td> <td class="width-100">更新時間</td> <td class="width-50">狀態更新</td> <td class="width-50">部署</td> <td class="width-50">kill</td> </tr> </thead> <tbody> <tr ms-repeat="vmsList"> <td><label><input type="checkbox" ms-class="check_{{el.name}}" ></label></td> <td>{{$index+jpageSize*(jpageIndex-1)+1}}</td> <td>{{el.name}}</td> <td><a ms-href="'/admin/vmdetails.html?vmid='+el.vm.id" target="_blank">{{el.ip}}</a></td> <td>{{el.os}}</td> <td>{{el.version}}</td> <td>{{el.setupVersion}}</td> <td>{{el.clientOn}}</td> <td>{{el.setupOn}}</td> <td>{{el.time}}</td> <td> <div ms-class="buttonDiv_view_{{el.name}}"> <i style="color:#009100;" ms-class="glyphicon glyphicon-eye-open icon-white i_view_{{el.name}}" ms-click="postViewStatus(el.name,el.ClientOn,el.SetupOn,el.ip)"></i> </div> <div ms-class="loadDiv_view_{{el.name}} loadDiv" style="display:none"> <img src="/img/load2.jpg" style="width:16px;height:16px;"/> </div> </td> <td> <div ms-class="buttonDiv_{{el.name}}"> <i style="color:#000066;" ms-class="glyphicon glyphicon-play icon-white i_{{el.name}}" ms-click="postDeploy(el.name,el.ip,el.os)"> </i> </div> <div ms-class="loadDiv_{{el.name}} loadDiv" style="display:none"> <img src="/img/load2.jpg" style="width:16px;height:16px;"/> </div> </td> <td> <div ms-class="buttonDiv_kill_{{el.name}}"> <i style="color:#CE0000;" ms-class="glyphicon glyphicon-remove icon-white ikill_{{el.name}}" ms-click="postkill(el.name,el.ip,el.os)"> </i> </div> <div ms-class="loadDiv_kill_{{el.name}} loadDiv" style="display:none"> <img src="/img/load2.jpg" style="width:16px;height:16px;"/> </div> </td> </tr> </tbody> </table> <div class="text-center"> <p id="pagination"></p> </div> </div> </div> </div> </div> </div> </div> <!-- /.container--> </body> </html>
js
/** * Created by chenjiazhu on 2017/2/15. */ var monitordeploy = avalon.define({ $id: 'monitordeploy', //VM Start pagesize1: "20", pagesize1Cls: "pageSizeSelected", pagesize2: "50", pagesize2Cls: "", pagesize3: "100", pagesize3Cls: "", changePageSize: function(pgsize) { monitordeploy.jpageSize = pgsize; monitordeploy.listVmInfosByPage("init"); }, clearsearch: function() { monitordeploy.conType = ""; monitordeploy.listVmInfosByPage("init"); }, jpageIndex: 1, jpageSize: 20, envType: "STRESS", conType: "", vmsList: [], listVmInfosByPage: function(tag) { if (tag) { monitordeploy.jpageIndex = 1; } $.ajax({ type: "post", url: 'listDeployVmInfosByPageByEnvType.action', data: { "pageindex": monitordeploy.jpageIndex, "pagesize": monitordeploy.jpageSize, "type": monitordeploy.conType, "envType": monitordeploy.envType }, dataType: "json", success: function(data) { if (tag) { $('#pagination').bootpag({ total: data.pagenum, page: monitordeploy.jpageIndex }); } if (data.retCode == "1000") { monitordeploy.vmsList = data.vms; } else { alert(data.retMSG); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("請求數據異常,狀態碼:" + XMLHttpRequest.status+",Error:"+errorThrown+",textStatus:"+textStatus); } }); }, postViewStatus: function(name, status1,status2,ip) { if(status1==null || status1=="") { status1=0; } if(status2==null || status2=="") { status2=0; } $(".loadDiv_view_"+name).show(); $(".buttonDiv_view_"+name).hide(); // 檢查Monitor狀態 $.ajax({ type: "GET", dataType : 'jsonp', jsonp:"jsoncallback", url: "http://"+ip+":8034/Deploy/ReturnOk", success: function (data) { if(data.data=="ok") { if(status1!="ok") { monitordeploy.updateMonitorStatus(ip,"ok"); } } else { if(status1!="fail") { monitordeploy.updateMonitorStatus(ip,"fail"); } } $(".loadDiv_view_"+name).hide(); $(".buttonDiv_view_"+name).show(); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("請求數據異常,狀態碼:" + XMLHttpRequest.status+",Error:"+errorThrown+",textStatus:"+textStatus); $(".loadDiv_view_"+name).hide(); $(".buttonDiv_view_"+name).show(); } }); // 檢查ClientSetup狀態 $.ajax({ type: "GET", dataType : 'jsonp', jsonp:"jsoncallback", url: "http://"+ip+":8035/Deploy/ReturnOk", success: function (data) { if(data.data="ok") { if(status1!="ok") { monitordeploy.updateClientSetupStatus(ip,"ok"); } } else { if(status1!="fail") { monitordeploy.updateClientSetupStatus(ip,"fail"); } } $(".loadDiv_view_"+name).hide(); $(".buttonDiv_view_"+name).show(); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("請求數據異常,狀態碼:" + XMLHttpRequest.status+",Error:"+errorThrown+",textStatus:"+textStatus); $(".loadDiv_view_"+name).hide(); $(".buttonDiv_view_"+name).show(); } }); }, updateMonitorStatus: function(ip,status) { $.ajax({ type: "post", url: 'updateMonitorStatus.action', data: { "ip": ip, "status1": status, }, dataType: "json", success: function(data) { if (data.retCode != "1000") { alert("更新"+ip+"Monitor狀態失敗!"); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("請求數據異常,狀態碼:" + XMLHttpRequest.status+ ",<br/>"+XMLHttpRequest.readyState+ ",<br/>"+XMLHttpRequest.responseText+",<br/>Error:"+errorThrown+",<br/>textStatus:"+textStatus); } }); }, updateClientSetupStatus: function(ip,status) { $.ajax({ type: "post", url: 'updateClientSetupStatus.action', data: { "ip": ip, "status2": status, }, dataType: "json", success: function(data) { if (data.retCode != "1000") { alert("更新"+ip+"ClientSetupStatus!"); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert("請求數據異常,狀態碼:" + XMLHttpRequest.status+ ",<br/>"+XMLHttpRequest.readyState+ ",<br/>"+XMLHttpRequest.responseText+",<br/>Error:"+errorThrown+",<br/>textStatus:"+textStatus); } }); }, postDeploy: function(name,ip,os) { $(".loadDiv_"+name).show(); $(".buttonDiv_"+name).hide(); $.ajax({ type: "post", url: 'deploy.action', data: { "ip": ip, "os": os }, dataType: "json", success: function(data) { $(".loadDiv_"+name).hide(); $(".buttonDiv_"+name).show(); if(data.data=="false") { alert("更新"+ip+"客戶端失敗!"); } else { monitordeploy.listVmInfosByPage(); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { $(".loadDiv_"+name).hide(); $(".buttonDiv_"+name).show(); alert("請求數據異常,狀態碼:" + XMLHttpRequest.status+ ",<br/>"+XMLHttpRequest.readyState+ ",<br/>"+XMLHttpRequest.responseText+",<br/>Error:"+errorThrown+",<br/>textStatus:"+textStatus); } }); }, postkill: function(name,ip,os) { $(".loadDiv_kill_"+name).show(); $(".buttonDiv_kill_"+name).hide(); $.ajax({ type: "post", url: 'kill.action', data: { "ip": ip, "os": os }, dataType: "json", success: function(data) { $(".loadDiv_kill_"+name).hide(); $(".buttonDiv_kill_"+name).show(); if(data.data=="false") { alert("殺死"+ip+"監控進程失敗!"); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { $(".loadDiv_kill_"+name).hide(); $(".buttonDiv_kill_"+name).show(); alert("請求數據異常,狀態碼:" + XMLHttpRequest.status+ ",<br/>"+XMLHttpRequest.readyState+ ",<br/>"+XMLHttpRequest.responseText+",<br/>Error:"+errorThrown+",<br/>textStatus:"+textStatus); } }); }, viewAllStatus:function() { $("input[type='checkbox']").each( function(){ if($(this).get(0).checked) { var name = $(this).attr("class").substr(6); //alert(name); $(".i_view_"+name).click(); } } ); }, deployAll:function() { $("input[type='checkbox']").each( function(){ if($(this).get(0).checked) { var name = $(this).attr("class").substr(6); //alert(name); $(".i_"+name).click(); } } ); }, killAll:function() { $("input[type='checkbox']").each( function(){ if($(this).get(0).checked) { var name = $(this).attr("class").substr(6); //alert(name); $(".ikill_"+name).click(); } } ); }, checkAll:function(){ $("input[type='checkbox']").each( function(){ $(this).attr("checked","true"); } ); }, uncheckAll:function(){ $("input[type='checkbox']").each( function(){ $(this).removeAttr("checked"); } ); }, loadVmTAB: function() { monitordeploy.listVmInfosByPage("init"); $('#vms').tab('show'); }, //VM END userOps: ops(4), bootpagFuc: function() { $('#pagination').bootpag({ total: 1, maxVisible: 10 }).on('page', function(event, num) { monitordeploy.jpageIndex = num; monitordeploy.listVmInfosByPage(); }); } }); avalon.ready(function() { if (monitordeploy.userOps) { monitordeploy.loadVmTAB(); } else { redirectAdminIndexPage(); } monitordeploy.bootpagFuc(); // $(".loadDiv").hide(); }); monitordeploy.$watch("jpageSize", function(newValue) { monitordeploy.pagesize1Cls = ""; monitordeploy.pagesize2Cls = ""; monitordeploy.pagesize3Cls = ""; if (newValue == monitordeploy.pagesize1) { monitordeploy.pagesize1Cls = "pageSizeSelected"; } else if (newValue == monitordeploy.pagesize2) { monitordeploy.pagesize2Cls = "pageSizeSelected"; } else if (newValue == monitordeploy.pagesize3) { monitordeploy.pagesize3Cls = "pageSizeSelected"; } })