Python加Shell急忙安插集群,python制作websocket服务器实例分享

By admin in 美高梅手机版4858 on 2019年5月3日

功能:用websocket技术,在运转为工人身份具的浏览器上实时显示远程服务器上的日记信息

序言:专门的职业中在认证前端页面呈现数据时,接触到websocket这一定义,这里大致记录下关于websocket的驾驭和常用方式。

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

一、初始的话

  使用python简单的兑现websocket服务器,能够在浏览器上实时展现远程服务器的日志消息。

  此前做了二个web版的宣布系列,但没达成在线看日志,每一趟发表版本后,都亟待登陆到服务器上查看日志,卓殊麻烦,为了偷懒,能在页面点几下开关落成工作,这几天查找了那下面的材料,实现了那一个效应,须臾间觉的看日志什么的,太便宜了,未来也足以给支付们查日志,再也不用劳动运营了,废话少说,先看功效啊。

美高梅手机版4858 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后,接收到请求,起1个线程和客户端握手,然后依据客户端发送的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给服务端,所以能够看差异品种,不一致机器上的日记,

美高梅手机版4858 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>

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

1、开头的话
使用python轻巧的完毕websocket服务器,能够在浏览器上实时显示远程服务器的日…

近来感到在集群里逐台计划ganglia,
cacti那一个监督的事物很麻烦,就写了个小程序去批量机动安排。原理是经过python的pexpect用ssh去复制文件和推行系统命令,小编用它来安顿ganglia等,可是任何的东西也得以通过这么些脚本来批量配备,只要本人编排铺排脚本就足以了。首假诺提议3个解决思路,看对大家是还是不是享有扶助。

貌似我们在运营工具铺排意况的时候,供给实时显示安排进度中的音信,也许在浏览器中实时呈现程序日志给开垦人士看。你还在用ajax每隔段时间去赚取服务器日志?out了,试试用websocket格局呢

(1)什么是websocket?

先预约二个定义,大家把停放python和本子的服务器叫做主要调整节点还是server,把需求安装的节点叫做受控节点依旧client。以下均以server和client代称。

我用bottle框架,写了个websocket服务端,浏览器连接到websocket
server,再用python
subprocess获取远程服务器的日志音讯,subprocess,正是用波普n调用shell的shell命令而已,那样可以取获得实时的日志了,然后再send到websocket
server
中,那连接到websocket
server的浏览器,就可以实时展现出来了

命名:看起来好像和socket有某种关系,然则依据查询领悟到,WebSocket只是借用了这一概念,使用方面,完全多个东西,差不离因为Socket早在它此前已经是3个门到户说的概念。

率先是布局文件,作者索要先定义三个计划文件,来约定server的有的门路,和client具体音讯。

用2台服务器来落成那么些现象,A服务器是websocket服务端,B服务器是日志端

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

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

A服务器是自家浏览器本机,websocket服务端也是那台机,IP是:1九二.16八.2.22二

归纳理解:WebSocket是一种为了满足浏览器与劳务器端实时数据交互须求而制定的1种新的网络协议。

log_dir = ‘./logs/’#概念日志路线,不过作者还没写,筹算用log四py来做

B服务器是要远程查看日志的服务器,小编这边用:192.16八.二.2二四

能够把WebSocket想象成HTTP,同为应用层协议,在与服务器通讯进度扮演剧中人物类似。然而WebSocket是依靠TCP的应用层协议,只须求1回一连(握手),今后传输数据无需再度树立连接,能够直接发送数据,这里就分别了和http协议的不如(每一次都要再一次请求,服务端再次来到数据后结束)。javascript中常用的ajax技巧所做的办事也是瓜熟蒂落前端和服务器的多寡交互,可是Ajax本事须要客户端发起呼吁,而WebSocket服务器和客户端可以相互推送音信,更为灵活的支撑业务供给。

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

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

(2)前端常用格局?

ssh_port = ’22’#SSH端口

安装:

前者比较常用的是在javascript中动用WebSocket,建设构造与劳务端WebSocket服务的通讯,从而请求服务端或许监听服务端推送数据新闻,到达实时数据交互的急需。

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

    pip install bottle

2个参阅英特网使用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

Python加Shell急忙安插集群,python制作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 F12查看websocket数据交互进程:

]

 

$一$
在你得知用到websocket的界面,进入调试形式,刷新分界面,接纳二-“Network->WS”后来看的一-Name上面一些会话就是正值通讯的websocket连接;

接下去是主程序

纪念安装bottle、websocket-client 、bottle-websocket 模块,服务端允许具有的IP访问其7000端口

$贰$
选用你的1个websocket会话能够在三-Frames中查阅当前数码(Receive或许Send)

#!/usr/bin/env python

 

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

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

websocket服务端除了用以上的方法外,还是能够用那下边包车型客车法子实现:

(四)关于websocket本人查找的片段可增添的思绪

import os

 

传说python脚本只怕java代码的二个websocket后台服务+javascript恐怕python达成websocket客户端+shell脚本

import sys

在计算机桌面,写三个简约的HTML5 javascripts页面,随意命名了,如test.html,那些页面使用了websocket连接受websocket服务端:

3个粗略查看后台日志的定制工具

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>

3个后台服务监督告警功效

#用import格局引进conf.py

 

…(想一万个不及尽力做好贰个)

import conf

到此处,就化解浏览器连接到websocket服务端的现象了,现在要A服务器里‘远程查看日志.py’,去搜聚B服务器的实时音信了,其实采撷原理很轻巧,便是利用shell中的tailf命令,实时展现最新的音讯而已,大家在那段脚本中,使用subprocess.蒲柏n()来远程查看日志消息:

除了这个还得有服务器一些权力吧,会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]

美高梅手机版4858 3

websocket规范 RFC6455
中文版

        return Branch

 

有空多查查咯~~

    def GetRelease(self):

美高梅手机版4858 ,   

        Release = platform.dist()[1]

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

        return Release

实施websocket服务端脚本和方面那几个websocket客户端收集脚本,再展开用浏览器展开上边的html伍页面后,蒙受就着力配置好了,双websocket客户端连接到websocket服务端中

    def GetInstaller(self):

地点脚本钦赐的r_log = “/tmp/web_socket.log”日志路线,大家要求改换这几个日志文件,并不停地往里面写入日志,那样技术在浏览器中实时显示效果(真实场景中,能够钦命服务器某日志,如apache,nginx日志等)

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

 

            installer = ‘apt-get’

刚才提到subprocess.Popen的法则和功用,请看之下材质:

        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非暗许操作系统安装,那一部分支撑凯雷德H,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,自动推断是或不是第2遍延续,并机关达成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,反正能用脚本实现的事都能够干。

美高梅手机版4858 4

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有