python统一管理多台linux机器
来源:互联网 发布:映客刷人气软件 购买 编辑:程序博客网 时间:2024/06/04 19:59
一:使用方法
1. 该脚本可以统一管理多台linux, 测试发行版为redhat 和 suse,同时支持基于口令的连接和基于秘钥的连接
2. 其中BatchMan的目录内容如下:
[root@admin BatchMan]# ls
node.conf pexpect README runcmd.py
注:其中目录pexpect内为suse10,11和rhel5,6发行版所需要的pexpect二进制包,内容如下
linux-xwc7:~ # ls Unify/pexpect
pexpect-2.3-1.rhel5.rpm pexpect-2.3-1.sles10.rpm
pexpect-2.3-1.rhel6.rpm pexpect-2.3-1.sles11.rpm
3. node.conf 的格式如下:
[NodeInfo]
User = root
Passwd = 111111
Port = 22
Nodes = suse[1-2]
User为连接时使用的用户名,Passwd为对应的用户名密码, SSHport为ssh服务监听端口
注: 使用时只需要按实际情况修改该文件即可
4.具体格式可查看README:
[root@admin BatchMan]# cat README
#
# Wed Dec 30 15:35:07 CST 2015
#
1. Before you run this script, please edit the node.conf file properly.
2. A example for node.conf
[NodeInfo]
User = root # the user for remote host
Passwd = 123456 # the passwd for user root
Port = 22 # the port for ssh service
Nodes = node[1-20] # the nodes which you want to manage
Typically, you only need to change the 'Passwd' and 'Nodes' fields
3. Examples for Nodes:
example_1 (Multi nodes):
"Nodes = nb0[01-99]" ==> nb001,nb002...nb009...nb099
"Nodes = nb[01-52]-eth1" ==> nb01-eth1,nb02-eth1...nb52-eth1
"Nodes = node[1-22]" ==> node1,node2...node22
example_2 (starting from serial number 2):
"Nodes = nb0[02-99]" ==> nb002...nb099
"Nodes = node[2-9]" ==> node2...node9
example_3 (only one node):
"Nodes = node[1-1]" ==> node1
"Nodes = compute[2-2]" ==> compute2
5. runcmd.py内容为:
#!/usr/bin/env pythonimport sysimport platformfrom re import compilefrom ConfigParser import ConfigParserfrom subprocess import PIPE, STDOUT, calldist, ver, arch = platform.dist()if dist not in ("redhat", "centos", "SuSE"): print '''This script only support "redhat" and "SuSE"''' sys.exit(1)try: import pexpectexcept ImportError: rhel5 = "rpm -ivh pexpect/pexpect-2.3-1.rhel5.rpm --force" rhel6 = "rpm -ivh pexpect/pexpect-2.3-1.rhel6.rpm --force" sles10 = "rpm -ivh pexpect/pexpect-2.3-1.sles10.rpm --force" sles11 = "rpm -ivh pexpect/pexpect-2.3-1.sles11.rpm --force" if dist in ('redhat', 'centos') and int(eval(ver)) == 5: state = call(rhel5, shell=True, stdout=PIPE, stderr=STDOUT) elif dist in ('redhat', 'centos') and int(eval(ver)) == 6: state = call(rhel6, shell=True, stdout=PIPE, stderr=STDOUT) elif dist == 'SuSE' and int(eval(ver)) == 10: source_path = "/usr/local/lib64/python2.4/site-packages" dest_path = "/usr/lib64/python2.4/site-packages" state = call(sles10, shell=True, stdout=PIPE, stderr=STDOUT) elif dist == 'SuSE' and int(eval(ver)) == 11: source_path = "/usr/local/lib64/python2.6/site-packages" dest_path = "/usr/lib64/python2.6/site-packages" state = call(sles11, shell=True, stdout=PIPE, stderr=STDOUT) if state == 0: if dist in ('redhat', 'centos'): import pexpect else: call("cp %s/* %s/" % (source_path, dest_path), shell=True, stdout=PIPE) import pexpect else: print '''sorry, can't find the python module "pexpect"''' sys.exit(1)user_admin = '''Password <%s> for %s@%s is incorrect. Please check the "node.conf" for Passwd !'''user_common = '''User <%s> does't exists or Password <%s> for %s@%s is incorrect.Please check the "node.conf" for User and Passwd !'''class BatchMan(object): def __init__(self, user, passwd, command, port=22): self.user = user self.passwd = passwd self.command = command self.port = port self.p3_obj = compile('continue connecting (yes/no)?') self.p4_obj = compile('[Pp]assword:') def __myExpect(self, child, time_out=30): try: try: index = child.expect([self.p3_obj, self.p4_obj], timeout=time_out) if index == 0: child.sendline('yes') child.expect(self.p4_obj) child.sendline(self.passwd) if child.expect(self.p4_obj) == 0: if self.user == "root": retval = user_admin % (self.passwd, self.user, host) else: retval = user_common % (self.user, self.passwd, self.user, host) return retval = child.read().strip() elif index == 1: child.sendline(self.passwd) if child.expect(self.p4_obj) == 0: if self.user == "root": retval = user_admin % (self.passwd, self.user, host) else: retval = user_common % (self.user, self.passwd, self.user, host) return retval = child.read().strip() except pexpect.EOF: if 'scp: command not found' in child.before: retval = '===> command "scp" not found in %s' % host else: retval = child.before.strip() except pexpect.TIMEOUT: retval = "Can't connect to host %s" % host finally: while child.isalive(): child.close() print retval def runCmd(self, host): ssh = pexpect.spawn("ssh -p %s %s@%s %s" % (self.port, self.user, host, self.command)) self.__myExpect(ssh) def runScp(self, host, source, dest): scp = pexpect.spawn('scp -P %s %s %s@%s:%s' %(self.port, source, self.user, host, dest)) self.__myExpect(scp, 3600)if __name__ == "__main__": ####### sys section ########## args = sys.argv[1:] if len(args) == 0: print 'Usage: python %s <command>' % sys.argv[0] sys.exit(1) if args[0] == 'scp': if len(args) != 3: print 'Usage: python %s scp <local_source> <dest>' % sys.argv[0] sys.exit(1) command = ' '.join(args) ####### ConfigParser ######### cf = ConfigParser() cf.read('node.conf') user = cf.get('NodeInfo', 'User') passwd = cf.get('NodeInfo', 'Passwd') port = cf.get('NodeInfo', 'Port') exp = cf.get('NodeInfo', 'Nodes') ######## get nodes ############ p1 = r'(^[a-zA-Z]+(\d+)?)\[(\d+)\-(\d+)\](.+)?' p1_obj = compile(p1) mo1 = p1_obj.search(exp) if not mo1: print '''"nodes" in "node.conf" should be writed as the following:example_1 (Multi nodes): "Nodes = nb0[01-99]" ==> nb001,nb002...nb009...nb099 "Nodes = nb[01-52]-eth1" ==> nb01-eth1,nb02-eth1...nb52-eth1 "Nodes = node[1-22]" ==> node1,node2...node22example_2 (starting from serial number 2): "Nodes = nb0[02-99]" ==> nb002...nb099 "Nodes = node[2-9]" ==> node2...node9example_3 (only one node): "Nodes = node[1-1]" ==> node1 "Nodes = compute[2-2]" ==> compute2''' sys.exit(1) prefix = mo1.group(1) start = mo1.group(3) stop = mo1.group(4) if mo1.group(5): suffix = mo1.group(5) else: suffix = '' p2 = r'0*' p2_obj = compile(p2) mo2 = p2_obj.search(start) if mo2: zeronum = mo2.group() else: zeornum = '' range_begin = int(start) range_end = int(stop) + 1 hosts = [] for i in range(range_begin, range_end): if i >= 10: hosts.append(prefix + str(i) + suffix) else: hosts.append(prefix + zeronum + str(i) + suffix) ########################################################### batch = BatchMan(user, passwd, command) if args[0] == 'scp': source = args[1] dest = args[2] for host in hosts: print '-' * 16 , '%s' % host, '-' * 16 print 'copying "%s" to "%s" ...' % (source, dest) batch.runScp(host, source, dest) else: for host in hosts: print '-' * 16 , '%s' % host, '-' * 16 batch.runCmd(host)二. 使用示例
1.统一执行系统命令,比如执行date和df -h命令
admin:~/BatchMan # python runcmd.py date
---------------- suse1 ----------------
Thu Oct 29 19:25:16 CST 2015
---------------- suse2 ----------------
Thu Oct 29 19:25:15 CST 2015
admin:~/BatchMan # python runcmd.py df -h |egrep "suse|sda2"
-------------------- suse1 --------------------
/dev/sda2 4.0G 1.5G 2.3G 40% /
-------------------- suse2 --------------------
/dev/sda2 4.0G 1.5G 2.3G 40% /
2.如果是要管理的机器已关机,或因网络问题、SSH服务问题连不上等原因,输出如下:
linux-xwc7:~/BatchMan # python runcmd.py df -h
---------------- suse1 ----------------
ssh: Could not resolve hostname suse1: Temporary failure in name resolution
---------------- suse2 ----------------
ssh: Could not resolve hostname suse2: Temporary failure in name resolution
3.往远程服务器复制文件,如复制/etc/hosts文件到各个节点的/etc目录下
linux-xwc7:~/BatchMan # python runcmd.py scp /etc/hosts /etc
---------------- suse1 ----------------
copying "/etc/hosts" to "/etc/" ...
---------------- suse2 ----------------
copying "/etc/hosts" to "/etc/" ...
- python统一管理多台linux机器
- 多台linux机器全自动安装jdk
- 用python脚本执行ssh远程登录多台机器
- 用python脚本执行ssh远程登录多台机器
- 同一台机器安装多个python版本
- 在多台Linux机器上执行命令
- Linux下相同配置的机器间内核拷贝【一台编译,多台拷贝】
- scp 多台机器复制
- 多台机器上真机调试
- 两台Linux机器实现文件交换
- Linux 两台机器互拷文件
- Linux 两台机器互拷文件
- 两台linux机器时间同步
- linux 两台机器时间同步
- 两台linux机器时间同步
- 两台linux机器时间同步
- 两台linux机器建立信任
- virtualenv:在一台机器上运行多个Python环境的利器
- 工作3年的技术积累概要
- android 签名、混淆打包
- 基于用户行为的兴趣标签模型
- django rest framework - 数据解析
- VMWare funtion MAC分辨率自动
- python统一管理多台linux机器
- LintCode_中位数
- 字符串的块链实现
- 飞天马软件下载
- Java编程思想 - 第6章、访问权限控制
- Linux中vi编辑器的使用详解
- 避免Android内存泄露
- StoryBoard不使用AutoLayout情况下 按比例快速兼容适配iPhone6/6 Plus教程【原创】
- 如何用matlab画正态分布曲线