功能:用websocket技术,在运行工具的浏览器上实时呈现远程服务器上的日志音信

序言:工作中在验证前端页面显示数据时,接触到websocket这一定义,那里差不离记录下关于websocket的驾驭和常用方式。

python制作websocket服务器实例分享,pythonwebsocket

壹、初步的话

  使用python不难的兑现websocket服务器,可以在浏览器上实时显示远程服务器的日记音信。

  在此以前做了3个web版的发布连串,但没完毕在线看日志,每一次发布版本后,都亟待登录到服务器上查看日志,十分麻烦,为了偷懒,能在页面点几下按钮达成工作,这几天查找了那上头的素材,达成了这么些功用,眨眼间间觉的看日志什么的,太方便了,今后也得以给支付们查日志,再也不用辛苦运转了,废话少说,先看效果呢。

澳门金沙国际 1

二、代码

  要求:在web上弹出iframe层来实时展现远程服务器的日记,点击stop按钮,甘休日志输出,以便查占卜关日志,点start按钮,继续输出日志,点close按钮,关闭iframe层。

  在促成那意义前,google了有的资料,发现众八只万幸web上显得本地的日志,不能够看远程服务器的日记,能看远程日志的是援引了别样框架(例如bottle,tornado)来兑现的,而且装有那么些都以要重写thread的run方法来落实的,由于自个儿技术太菜,不了然怎么改成本身索要的指南,而且本人是用django那么些web框架的,不想引进其余框架,搞的太复杂,所以用python简单的贯彻websocket服务器。recv_data方法和send_data是平昔引用旁人的代码。由于技术难点,代码有点粗糙,不过能兑现效益就行,先将就着用吧。

推行下边发号施令运维django和websocketserver

nohup python manage.py runserver 10.1.12.110 &
nohup python websocketserver.py &

  运行websocket后,接收到请求,起三个线程和客户端握手,然后根据客户端发送的ip和type,去数据库查找对应的日志路径,用paramiko模块ssh登录到长途服务器上tail查看日志,再推送给浏览器,服务端完整代码如下:

# coding:utf-8
import os
import struct
import base64
import hashlib
import socket
import threading
import paramiko


def get_ssh(ip, user, pwd):
  try:
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(ip, 22, user, pwd, timeout=15)
    return ssh
  except Exception, e:
    print e
    return "False"


def recv_data(conn):  # 服务器解析浏览器发送的信息
  try:
    all_data = conn.recv(1024)
    if not len(all_data):
      return False
  except:
    pass
  else:
    code_len = ord(all_data[1]) & 127
    if code_len == 126:
      masks = all_data[4:8]
      data = all_data[8:]
    elif code_len == 127:
      masks = all_data[10:14]
      data = all_data[14:]
    else:
      masks = all_data[2:6]
      data = all_data[6:]
    raw_str = ""
    i = 0
    for d in data:
      raw_str += chr(ord(d) ^ ord(masks[i % 4]))
      i += 1
    return raw_str


def send_data(conn, data):  # 服务器处理发送给浏览器的信息
  if data:
    data = str(data)
  else:
    return False
  token = "\x81"
  length = len(data)
  if length < 126:
    token += struct.pack("B", length)  # struct为Python中处理二进制数的模块,二进制流为C,或网络流的形式。
  elif length <= 0xFFFF:
    token += struct.pack("!BH", 126, length)
  else:
    token += struct.pack("!BQ", 127, length)
  data = '%s%s' % (token, data)
  conn.send(data)
  return True


def handshake(conn, address, thread_name):
  headers = {}
  shake = conn.recv(1024)
  if not len(shake):
    return False

  print ('%s : Socket start handshaken with %s:%s' % (thread_name, address[0], address[1]))
  header, data = shake.split('\r\n\r\n', 1)
  for line in header.split('\r\n')[1:]:
    key, value = line.split(': ', 1)
    headers[key] = value

  if 'Sec-WebSocket-Key' not in headers:
    print ('%s : This socket is not websocket, client close.' % thread_name)
    conn.close()
    return False

  MAGIC_STRING = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
  HANDSHAKE_STRING = "HTTP/1.1 101 Switching Protocols\r\n" \
            "Upgrade:websocket\r\n" \
            "Connection: Upgrade\r\n" \
            "Sec-WebSocket-Accept: {1}\r\n" \
            "WebSocket-Origin: {2}\r\n" \
            "WebSocket-Location: ws://{3}/\r\n\r\n"

  sec_key = headers['Sec-WebSocket-Key']
  res_key = base64.b64encode(hashlib.sha1(sec_key + MAGIC_STRING).digest())
  str_handshake = HANDSHAKE_STRING.replace('{1}', res_key).replace('{2}', headers['Origin']).replace('{3}', headers['Host'])
  conn.send(str_handshake)
  print ('%s : Socket handshaken with %s:%s success' % (thread_name, address[0], address[1]))
  print 'Start transmitting data...'
  print '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'
  return True


def dojob(conn, address, thread_name):
  handshake(conn, address, thread_name)   # 握手
  conn.setblocking(0)            # 设置socket为非阻塞

  ssh = get_ssh('192.168.1.1', 'root', '123456')  # 连接远程服务器
  ssh_t = ssh.get_transport()
  chan = ssh_t.open_session()
  chan.setblocking(0)  # 设置非阻塞
  chan.exec_command('tail -f /var/log/messages')

  while True:
    clientdata = recv_data(conn)
    if clientdata is not None and 'quit' in clientdata:  # 但浏览器点击stop按钮或close按钮时,断开连接
      print ('%s : Socket close with %s:%s' % (thread_name, address[0], address[1]))
      send_data(conn, 'close connect')
      conn.close()
      break
    while True:
      while chan.recv_ready():
        clientdata1 = recv_data(conn)
        if clientdata1 is not None and 'quit' in clientdata1:
          print ('%s : Socket close with %s:%s' % (thread_name, address[0], address[1]))
          send_data(conn, 'close connect')
          conn.close()
          break
        log_msg = chan.recv(10000).strip()  # 接收日志信息
        print log_msg
        send_data(conn, log_msg)
      if chan.exit_status_ready():
        break
      clientdata2 = recv_data(conn)
      if clientdata2 is not None and 'quit' in clientdata2:
        print ('%s : Socket close with %s:%s' % (thread_name, address[0], address[1]))
        send_data(conn, 'close connect')
        conn.close()
        break
    break


def ws_service():

  index = 1
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  sock.bind(("127.0.0.1", 12345))
  sock.listen(100)

  print ('\r\n\r\nWebsocket server start, wait for connect!')
  print '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'
  while True:
    connection, address = sock.accept()
    thread_name = 'thread_%s' % index
    print ('%s : Connection from %s:%s' % (thread_name, address[0], address[1]))
    t = threading.Thread(target=dojob, args=(connection, address, thread_name))
    t.start()
    index += 1


ws_service()

get_ssh的代码如下:

import paramiko
def get_ssh(ip, user, pwd):
  try:
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(ip, 22, user, pwd, timeout=15)
    return ssh
  except Exception, e:
    print e
    return "False"

开拓页面时,自动一连websocket服务器,完毕握手,并发送ip和type给服务端,所以可以看差异品种,不相同机器上的日志,

澳门金沙国际 2

 页面代码如下:

<!DOCTYPE html>
<html>
<head>
  <title>WebSocket</title>

  <style>
  #log {
    width: 440px;
    height: 200px;
    border: 1px solid #7F9DB9;
    overflow: auto;
  }
  pre {
    margin: 0 0 0;
    padding: 0;
    border: hidden;
    background-color: #0c0c0c;
    color: #00ff00;
  }
  #btns {
    text-align: right;
  }
  </style>

  <script>
    var socket;
    function init() {
      var host = "ws://127.0.0.1:12345/";

      try {
        socket = new WebSocket(host);
        socket.onopen = function () {
          log('Connected');
        };
        socket.onmessage = function (msg) {
          log(msg.data);
          var obje = document.getElementById("log");  //日志过多时清屏
          var textlength = obje.scrollHeight;
          if (textlength > 10000) {
            obje.innerHTML = '';
          }
        };
        socket.onclose = function () {
          log("Lose Connection!");
          $("#start").attr('disabled', false);
          $("#stop").attr('disabled', true);
        };
        $("#start").attr('disabled', true);
        $("#stop").attr('disabled', false);
      }
      catch (ex) {
        log(ex);
      }
    }
    window.onbeforeunload = function () {
      try {
        socket.send('quit');
        socket.close();
        socket = null;
      }
      catch (ex) {
        log(ex);
      }
    };
    function log(msg) {
      var obje = document.getElementById("log");
      obje.innerHTML += '<pre><code>' + msg + '</code></pre>';
      obje.scrollTop = obje.scrollHeight;  //滚动条显示最新数据
    }
    function stop() {
      try {
        log('Close connection!');
        socket.send('quit');
        socket.close();
        socket = null;
        $("#start").attr('disabled', false);
        $("#stop").attr('disabled', true);
      }
      catch (ex) {
        log(ex);
      }
    }
    function closelayer() {
      try {
        log('Close connection!');
        socket.send('quit');
        socket.close();
        socket = null;
      }
      catch (ex) {
        log(ex);
      }
      var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
      parent.layer.close(index); //再执行关闭
    }
  </script>

</head>


<body onload="init()">
  <div >
    <div >
      <div id="log" ></div>
      <br>
    </div>
  </div>
  <div >
    <div >
      <div id="btns">
        <input disabled="disabled" type="button" value="start" id="start" onclick="init()">
        <input disabled="disabled" type="button" value="stop" id="stop" onclick="stop()" >
        <input type="button" value="close" id="close" onclick="closelayer()" >
      </div>
    </div>
  </div>
</body>

</html>

上述正是本文的全体内容了,希望大家能够欣赏

一、起始的话
使用python简单的兑现websocket服务器,能够在浏览器上实时显示远程服务器的日…

近日感觉到在集群里逐台布置ganglia,
cacti这一个监察和控制的东西很困苦,就写了个小程序去批量活动安插。原理是透过python的pexpect用ssh去复制文件和施行系统命令,小编用它来安顿ganglia等,可是任何的东西也得以经过这几个脚本来批量安排,只要自身编排安插脚本就足以了。首借使提议多个解决思路,看对咱们是否享有帮衬。

诚如大家在运行工具铺排环境的时候,需要实时呈现安插进程中的新闻,或许在浏览器中实时显示程序日志给开发人员看。你还在用ajax每隔段日子去获取服务器日志?out了,试试用websocket方式吗

(1)什么是websocket?

先预订1个定义,大家把停放python和本子的服务器叫做主要控制节点依旧server,把要求安装的节点叫做受控节点依然client。以下均以server和client代称。

我用bottle框架,写了个websocket服务端,浏览器连接到websocket
server,再用python
subprocess获取远程服务器的日记音讯,subprocess,正是用Popen调用shell的shell命令而已,这样能够博获得实时的日志了,然后再send到websocket
server
中,那连接到websocket
server的浏览器,就会实时呈现出来了

命名:看起来好像和socket有某种关系,可是遵照查询通晓到,WebSocket只是借用了这一定义,使用方面,完全多个东西,大概因为Socket早在它从前早已是多少个深入人心的概念。

率先是布局文件,小编索要先定义一个布署文件,来约定server的1对门路,和client具体消息。

用2台服务器来兑现这几个情景,A服务器是websocket服务端,B服务器是日志端

合法表明:WebSocket协议是根据TCP的1种新的网络协议。它达成了浏览器与服务器全双工(full-duplex)通讯——允许服务器主动发送新闻给客户端。–百度百科

#-*-coding:UTF-8 -*-

A服务器是自笔者浏览器本机,websocket服务端也是那台机,IP是:19二.16八.贰.22二

简单精晓:WebSocket是一种为了满意浏览器与劳务器端实时数据交互须要而制定的1种新的互连网协议。

log_dir = ‘./logs/’#概念日志路径,但是小编还没写,打算用log四py来做

B服务器是要远程查看日志的服务器,小编那边用:1玖二.168.二.2二4

能够把WebSocket想象成HTTP,同为应用层协议,在与服务器通讯进度扮演剧中人物类似。可是WebSocket是依据TCP的应用层协议,只需求二遍接二连三(握手),今后传输数据不必要再行创制连接,能够直接发送数据,那里就分别了和http协议的不等(每便都要双重请求,服务端重回数据后甘休)。javascript中常用的ajax技术所做的办事也是成就前端和服务器的数目交互,可是Ajax技术要求客户端发起呼吁,而WebSocket服务器和客户端能够相互推送消息,更为灵活的支撑业务必要。

client_tmp_dir = ‘/tmp/’#定义client端存放脚本路径

以下是在A服务器的操作(Python二)

(二)前端常用格局?

ssh_port = ’22’#SSH端口

安装:

websocket网页实时突显远程服务器日志消息,python制作websocket服务器实例分享。前者相比较常用的是在javascript中利用WebSocket,建立与劳务端WebSocket服务的通信,从而请求服务端只怕监听服务端推送数据音讯,达到实时数据交互的急需。

script_dir = ‘./shells/’#server端脚本存放路径

    pip install bottle

二个参阅网上使用python+bottle+javascript的事例

node_list = [

    pip install websocket-client

前端:

{‘ip’:’192.168.1.1′, ‘user’:’root’, ‘passwd’:’123456′, ‘cmd’:’sh
/tmp/dpkg_client_Ubuntu_x.x86_64.sh’},

    pip install bottle-websocket

websocket后端:

#cmd为在client端执行的吩咐,别的不解释

websocket servet的python代码:

(三)调节和测试模拟websocket通讯

{‘ip’:’192.168.1.2′, ‘user’:’root’, ‘passwd’:’123456′, ‘cmd’:’sh
/tmp/dpkg_client_ubuntu_x.x86_64.sh’},

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 from bottle import get, run
 4 from bottle.ext.websocket import GeventWebSocketServer
 5 from bottle.ext.websocket import websocket
 6 users = set()   # 连接进来的websocket客户端集合
 7 @get('/websocket/', apply=[websocket])
 8 def chat(ws):
 9     users.add(ws)
10     while True:
11         msg = ws.receive()  # 接客户端的消息
12         if msg:
13             for u in users:
14                 u.send(msg) # 发送信息给所有的客户端
15         else:
16             break
17     # 如果有客户端断开连接,则踢出users集合
18     users.remove(ws)
19 run(host='0.0.0.0', port=8000, server=GeventWebSocketServer)

Chrome F1二翻看websocket数据交互进程:

]

 

$一$
在您得知用到websocket的界面,进入调节和测试方式,刷新界面,选取2-“Network->WS”后见到的一-Name上面1些对话就是正在通讯的websocket连接;

接下去是主程序

回忆安装bottle、websocket-client 、bottle-websocket 模块,服务端允许具备的IP访问其九千端口

$2$
选拔你的3个websocket会话能够在3-Frames中查阅当前数量(Receive可能Send)

#!/usr/bin/env python

 

$3$ Headers里面是websocket请求的URL和头

#-*-coding:UTF-8 -*-

websocket服务端除了用上述的措施外,还能用那上面包车型地铁艺术完结:

(4)关于websocket自身搜索的壹些可扩大的思绪

import os

 

基于python脚本恐怕java代码的三个websocket后台服务+javascript也许python完结websocket客户端+shell脚本

import sys

在电脑桌面,写3个归纳的HTML伍 javascripts页面,随便命名了,如test.html,那些页面使用了websocket连接受websocket服务端:

2个不难查看后台日志的定制工具

import platform

 1  <!DOCTYPE html>
 2 <html>
 3 <head>
 4 </head>
 5     <style>
 6         #msg{
 7             width:400px; height:400px; overflow:auto; border:2px solid #000000;background-color:#000000;color:#ffffff;
 8     }
 9     </style>
10 </head>
11 <body>
12     <p>实时日志</p>
13     <div id="msg"></div>
14     <script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script>
15     <script>
16     $(document).ready(function() {
17         /* !window.WebSocket、window.MozWebSocket检测浏览器对websocket的支持*/
18         if (!window.WebSocket) {
19             if (window.MozWebSocket) {
20                 window.WebSocket = window.MozWebSocket;
21             } else {
22                 $('#msg').prepend("<p>你的浏览器不支持websocket</p>");
23             }
24         }
25         /* ws = new WebSocket 创建WebSocket的实例  注意设置对以下的websocket的地址哦*/
26         ws = new WebSocket('ws://192.168.2.222:8000/websocket/');
27         /*
28             ws.onopen  握手完成并创建TCP/IP通道,当浏览器和WebSocketServer连接成功后,会触发onopen消息
29             ws.onmessage 接收到WebSocketServer发送过来的数据时,就会触发onmessage消息,参数evt中包含server传输过来的数据;
30         */
31         ws.onopen = function(evt) {
32             $('#msg').append('<li>websocket连接成功</li>');
33         }
34         ws.onmessage = function(evt) {
35             $('#msg').prepend('<li>' + evt.data + '</li>');
36         }
37     });
38 </script>
39 </body>
40 </html>

二个后台服务监察和控制告警功用

#用import格局引进conf.py

 

…(想一千0个比不上尽力做好二个)

import conf

到此地,就解决浏览器连接到websocket服务端的景观了,今后要A服务器里‘远程查看日志.py’,去采集B服务器的实时新闻了,其实采集原理相当的粗略,便是接纳shell中的tailf命令,实时展现最新的音讯而已,大家在那段脚本中,使用subprocess.Popen()来远程查看日志消息:

除开这一个还得有服务器壹些权力吧,会shell脚本吧,懂业务呢?

import subprocess

python代码如下:


”’

 1 #!/usr/bin/python
 2 # encoding=utf-8
 3 import subprocess
 4 import time
 5 from websocket import create_connection
 6 # 配置远程服务器的IP,帐号,密码,端口等,因我做了双机密钥信任,所以不需要密码
 7 r_user = "root"
 8 r_passwd='jason_zhang'
 9 r_ip = "192.168.2.224"
10 r_port = 22
11 r_log = "/tmp/test.log"   # 远程服务器要被采集的日志路径
12 # websocket服务端地址
13 ws_server = "ws://192.168.2.222:8000/websocket/"
14 # 执行的shell命令(使用ssh远程执行)
15 cmd = "/usr/bin/ssh -p {port} {user}@{ip} /usr/bin/tailf {log_path}".format(user=r_user,ip=r_ip,port=r_port,log_path=r_log)
16 def tailfLog():
17     """获取远程服务器实时日志,并发送到websocket服务端"""
18     popen = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
19     print('连接成功')
20     ws = create_connection(ws_server)   # 创建websocket连接
21     while True:
22         line = popen.stdout.readline().strip()  #获取内容
23         if line:
24             ws.send(line)   #把内容发送到websocket服务端
25         print (time.time())
26 if __name__ == '__main__':
27     tailfLog()

参考文章:

判定server(本机)操作系统类型和版本的类

 

文中例子来源

”’

 在服务器B的日志文件随便输入点东西,再运行服务器A的拿走日志脚本

http://blog.csdn.net/qiuhuanmin/article/details/50719114

class System:

 

https://www.cnblogs.com/jinjiangongzuoshi/p/5062092.html

    def GetBranch(self):

获得到的结果

WebSocket 和 Socket
的区别

        Branch = platform.dist()[0]

澳门金沙国际 3

websocket规范 RFC6455
中文版

        return Branch

 

闲暇多查查咯~~

    def GetRelease(self):

   

        Release = platform.dist()[1]

tailfLog()小说最后再解析subprocess.Popen的原理和机能

        return Release

履行websocket服务端脚本和方面那些websocket客户端采集脚本,再打开用浏览器打开上面的html5页面后,环境就着力配备好了,双websocket客户端连接到websocket服务端中

    def GetInstaller(self):

上边脚本钦赐的r_log = “/tmp/web_socket.log”日志路径,我们要求扭转那一个日志文件,并不停地往里面写入日志,那样才能在浏览器中实时展现效果(真实场景中,能够钦点服务器某日志,如apache,nginx日志等)

        if self.GetBranch() in [‘Ubuntu’, ‘debian’]:

 

            installer = ‘apt-get’

刚刚提到subprocess.波普n的法则和功用,请看以下资料:

        elif self.GetBranch() in
[‘RedHat’,
‘Fedora’,
‘CentOS’]:

            installer = ‘yum’

bottle websocket参考资料:

        elif self.GetBranch() in
[‘澳门金沙国际 ,SUSE’]:

            installer = ‘zypper’

 

        else:

            installer = ‘unknown’

        return installer

”’

以操作系统版本为遵照取得相应的pexpect包并尝试引进,因pexpect非暗中同意操作系统安装,那有个别支撑LANDH,Ubuntu,Debian,SuSE

”’

try:

    import pexpect

except ImportError:

    installer = System()

    inst = install.GetInstaller()

    if (inst == ‘apt-get’) or (inst == ‘zypper’):

        cmd = ‘%s install python-pexpect’ % (inst)

    elif inst == ‘yum’:

        cmd = ‘$s install pexpect’ % (inst)

    else:

        cmd = ‘echo “Not support yet:)”‘;

    try:

        fd = subprocess.Popen( cmd, shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE )

        out = fd.stdout.readlines()

        err = fd.stderr.readlines()

        all = out+err

        all = “”.join(all)

    except OSError,e:

        all = “Cannot run command, Exception:”+e+os.linesep

    import pexpect

#print all

”’

pexpect执行类,分五个主意,ssh和scp,自动判断是不是第三次延续,并活动完毕yes或输入密码的答应。

”’

class Expect:

    #概念ssh方法,入口变量包蕴ip, port,username,password,执行命令

    def ssh(self, ip, port, user, passwd, cmd):

        #创制连接子进度对象

        ssh = pexpect.spawn(‘ssh -p %s %s@%s “%s”‘ %
(port, user, ip, cmd))

        r = ”

        try:

           
#看清是还是不是第3回三番五次,假如是第贰次,则回答yes并输入密码,不然直接输入密码

            i = ssh.expect([‘password:’, ‘continue connecting
(yes/no)?’], timeout=5)

            if i == 0 :

                ssh.sendline(passwd)

            elif i == 1:

                ssh.sendline(‘yes’)

                ssh.expect(‘password:’)

                ssh.sendline(passwd)

        except pexpect.EOF:

            ssh.close()

        else:

            r = ssh.read()

            ssh.expect(pexpect.EOF)

            ssh.close()

        return r

   
#定义scp方法,入口变量包罗ip,port,username,password,要求复制到client的文书名,复制到client的路径

    def scp(self, ip, port, user, passwd, srcfile = “index.html”,
distpath):

        #创设连接子进度对象

        ssh = pexpect.spawn(‘scp -P %s %s %s@%s:%s ‘
% (port, file, user, ip, distpath))

        r= ”

        try:

           
#判定是还是不是第二遍一连,如若是第三次,则回答yes并输入密码,不然直接输入密码

            i = ssh.expect([‘password:’, ‘continue connecting
(yes/no)?’], timeout=5)

            if i == 0:

                ssh.sendline(passwd)

            elif i == 1:

                ssh.senline(‘yes’)

                ssh.expect(‘password:’)

                ssh.sendline(passwd)

        except pexpect.EOF:

            ssh.close()

        else:

            r = ssh.read()

            ssh.expect(pexpect.EOF)

            ssh.close()

        return r

#始建conf中的对象,只是为着写起来方便。不创立直接用也行

packages = conf.package_dir

logs = conf.log_dir

c_tmp = conf.client_tmp_dir

port = conf.ssh_port

scripts = conf.script_dir

nodes = conf.node_list

expect = Expect()

#在本机执行server端脚本。该脚本会安装Ganglia
gmetad,gmond,cacti,nagios,gangliaweb,mysql,apache等等

os.system(“sh ” + scripts + “dpkg_server_ubuntu_x.x86_64.sh”)

#循环列出conf的列表中安排的主机,用户名,密码,执行命令

for i in range(len(nodes)):

    ip = nodes[i][‘ip’]

    user = nodes[i][‘user’]

    passwd = nodes[i][‘passwd’]

    cmd = nodes[i][‘cmd’]

   
#将本机的client执行脚本复制到client端的conf.py中定义的路径client_tmp_dir

    r = expect.scp(ip, port, user, passwd,
scripts+’dpkg_client_ubuntu_x.x86_64.sh’, c_tmp)

    print r

   
#在client端执行刚复制过去的脚本,脚本中涵盖gmond,nagios-client,snmpd等等

    r = expect.ssh(ip, port, user, passwd, cmd)

    print r

自己还没写按自动判断client端操作系统安装不一样脚本的逻辑,有趣味的能够团结改改,其实笔者脚本并简单,宗旨都以在pexpect,作者第一是不想用puppet,不想用puppet的第一缘由是不想学ruby和他那复杂的配备文件。不光是计划监督,自个儿写shell脚本,随便配置怎样都足以。nginx,php,反正能用脚本完毕的事都能够干。

澳门金沙国际 4

相关文章