程序设计语言

使用python设计ssh分发工具(zz)

2010年8月28日 阅读(373)

平时工作中做大量的分发工作是使用研发部同事基于twisted设计的一套很不错的程序。当然该同事比较大牛。很好奇也想自己来做这样的一套,做为一个python新手来说,纯粹是在扯淡。在网上看了些资料,依样画葫芦,写个入门级的。配置文件参照了同事大牛的风格。

#!/usr/bin/env python

import subprocess
import ConfigParser

"""
A ssh based command dispatch system

"""

def readConfig(file="config.ini"):
  """Extract IP addresses and CMDS from config file and returns tuple"""
  ips = []
  cmds = []
  Config = ConfigParser.ConfigParser()
  Config.read(file)
  machines = Config.items("MACHINES")
  commands = Config.items("COMMANDS")
  for ip in machines:
    ips.append(ip[1])
  for cmd in commands:
    cmds.append(cmd[1])
  return ips, cmds

ips, cmds = readConfig()

for ip in ips:
  for cmd in cmds:
    subprocess.call("ssh root@%s %s" % (ip, cmd), shell=True)

 

下一步准备解决多线程及异步请求的问题,当然以我目前的python水平来说还属于痴人说梦。当然还是要想想的,主要是想使用django来做套bs构架的分发工具,又或用pyqt来做套desktop级的跨平台的工具。又或者。。。。。。

我还是好好看的入门级书籍《python学习手册》吧.

 

接上次:http://blog.oldyang.net/archives/163

对部分功能进行了完善,先放这里以后接着优化

update:2010-2-28:今天下午看了点资料,对程序的线程处理上进行了部分优化,性能又提高了小小。

查看源代码打印帮助
001 #!/usr/bin/env python 
002 # -*- coding: utf-8 -*- 
003   
004 """ 
005 FileName : dispatch.py 
006 Autor: David Young <e4twood@gmail.com
007 Version:0.1.4(20100228) 
008 A ssh based command simple dispatch tool 
009 Using this program requires paramiko support, so that before the use of the python modules to install paramiko 
010   
011 Usage: 
012  python dispatch.py CONFIGFILE 
013 Example: 
014  python dispatch.py conf/config.ini 
015   
016 More config options please see the config file on conf directory 
017 """
018   
019 #导入相关模块 
020 import Crypto 
021 import paramiko 
022 import os 
023 import time
024 import ConfigParser 
025 import base64 
026 import sys 
027 from threading import Thread 
028 from Queue import Queue 
029 from paramiko import AutoAddPolicy, SSHClient 
030   
031 queue = Queue() 
032   
033 #记录开始时间戳 
034 start = int(time.time()) 
035   
036 # 检查参数个数 
037 if len(sys.argv) <= 1: 
038  print ‘Error!missing parameter.’
039  print ‘Usage:python %s configfile’ % sys.argv[0] 
040  print ‘Example:python %s conf/config.ini’ % sys.argv[0] 
041  exit(1) 
042   
043 #读取配置文件 
044 configfile = sys.argv[1] 
045 def readConfig(file=configfile): 
046  ips = [] 
047  cmds = [] 
048  Config = ConfigParser.ConfigParser() 
049  Config.read(file) 
050  username = Config.get("BASEINFO","USERNAME") 
051  password = base64.b64decode(Config.get("BASEINFO","PASSWORD")) 
052  port = int(Config.get("BASEINFO","PORT")) 
053  threads = int(Config.get("BASEINFO","THREADS")) 
054  log_file = Config.get("BASEINFO","LOG_FILE") 
055  log_level = int(Config.get("BASEINFO","LOG_LEVEL")) 
056  pid_file = Config.get("BASEINFO","PID_FILE") 
057  machines = Config.items("MACHINES") 
058  commands = Config.items("COMMANDS") 
059  for ip in machines: 
060  ips.append(ip[1]) 
061  for cmd in commands: 
062  cmds.append(cmd[1]) 
063  return ips, cmds, username, password, port, threads, log_file, log_level, pid_file 
064   
065 ips, cmds, username, password, port, threads, log_file, log_level, pid_file = readConfig() 
066   
067 #记录当前pid 
068 pid = str(os.getpid()) 
069 f = file(pid_file, ‘w’) 
070 f.write(pid) 
071 f.close 
072   
073 #使用paramiko进行远程SSH调用 
074 def launcher(i,q, cmd): 
075  while True: 
076  ip = q.get() 
077  for cmd in cmds: 
078  try: 
079  paramiko.util.log_to_file(log_file, level = log_level) 
080  client = paramiko.SSHClient() 
081  client.set_missing_host_key_policy(AutoAddPolicy()) 
082  client.connect((ip), username=(username), password=(password), port=(port)) 
083  stdin, stdout, stderr = client.exec_command(cmd) 
084  print stdout.read() 
085  client.close() 
086  except: 
087  pass
088  print "Connect to %s  Failed!" % ip 
089  q.task_done() 
090   
091 #使用线程启动,并检测线程数量 
092 if len(ips) < threads: 
093  num_threads = len(ips) 
094 else: 
095  num_threads = threads 
096   
097 for i in range(num_threads): 
098  for cmd in cmds: 
099  worker = Thread(target=launcher, args=(i, queue, cmd)) 
100  worker.setDaemon(True) 
101  worker.start() 
102   
103 #线程排队 
104 for ip in ips: 
105  queue.put(ip) 
106 queue.join() 
107   
108 #打印任务结束时间戳 
109 end = int(time.time()) 
110   
111 #统计任务运行时间 
112 print "Dispatch Task Completed in %s seconds" % (end – start)
配置文件式例:

查看源代码打印帮助01 ;基本的配置信息 

02 [BASEINFO] 
03 ;远程ssh主机用户名 
04 USERNAME = root 
05 ;远程ssh主机密码,做base64加密处理 
06 PASSWORD = <code>MTIzMzMzMw</code><code>=</code><code>=</code> 
07 ;远程ssh主机端口 
08 PORT = 22
09 ;线程数量 默认为10,并非越多越好。 
10 THREADS = 10
11 ;日志存放路径 
12 LOG_FILE = logs/dispatch.log 
13 ;日志等级,分别为10,20,30,40,50
14 LOG_LEVEL = 10
15 ;pid文件存放路径 
16 PID_FILE = logs/dispatch.pid 
17 ;主机列表 
18 [MACHINES] 
19 APP2 : 192.168.0.1
20 APP3 : 192.168.1.8
21 ;命令列表 
22 [COMMANDS] 
23 B : echo `hostname`

You Might Also Like