Linux Cluster环境下批量分发执行补丁

来源:互联网 发布:软件许可协议模板 编辑:程序博客网 时间:2024/05/18 23:28

这两天做了一个需求,因为上一个版本的/tmp空间默认只分配了5G,而升级程序上传解压路径也是/tmp,且解压过程要占用5G左右的空间,这样就导致/tmp空间占满,解压失败,升级无法进行。后来想了一个办法,就是从/var建了一个软链接到/tmp,这样实际上升级文件上传解压到/var路径下了,解决了/tmp路径空间不足的问题。但是因为客户那里是一个cluster环境,由6个node组成,最好能够在一个机器上执行一次补丁,所有node都生效。

经过几次尝试,写了两个shell脚本,一个run.sh负责调度和分发补丁,另外一个doFix.sh,真正给系统打补丁的脚本。这里只介绍调度分发的部分

基本思路就是从主node上将doFix.sh脚本分发到其他各个node上,然后再从主node上ssh到各node执行补丁脚本。


调度脚本run.sh:

#!/bin/bash#check versioncat /etc/issue | grep "V3.5"if [ $? -ne 0 ]; then    echo "This is not V3.5, exit!"    exitfiISFABRIC=0ADMPW=""echoread -rsn1 -p "Is this a fabric with same admin password? [y/n]"echoif [ "$REPLY" = "y" -o "$REPLY" = "Y" ]; then    ISFABRIC=1    read -esp "Please input the password: " ADMPWelse    echo "Please run the script doFix.sh manually"    exitfiechoechoecho "Patch current node..."sh ./doFix.shNODEIP=$(ifconfig eth0 | grep 'inet addr' | cut -d':' -f2 | awk '{print $1}')echo "Begin to patch other nodes..."echoegrep "MAGICNODE-" /etc/hosts | awk '{print $1}' | sort | uniq | while read LINEdo    if [ "$NODEIP" = "$LINE" ]; then       continue    fi    echo "Patching node $LINE"    # scp doFix.sh to remote node    ./scpExpect $ADMPW./doFix.sh admin@$LINE:/tmp/    if [ $? -ne 0 ]; then       echo "SCP script to node $LINE failed! skip"       continue    fi    # execute patch script    ./sshExpectSudo admin $ADMPW $LINE "sudo bash /tmp/doFix.sh"    if [ $? -ne 0 ]; then        echo "Remote patch node $LINE failed! skip"        continue    fi    echo    echodoneecho "Patch finished."
从/etc/hosts文件中获取cluster环境的所有node IP,然后将doFix.sh脚本通过scp送过去,再执行ssh打补丁。

这里两个关键点是scpExpect和sshExpect,何为Expect文件?请参考http://expect.sourceforge.net/,网上有很多Expect的介绍文章,归结一句话就是一种实现自动化交互的脚本语言,从TCL扩展出来。

上代码:

scpExpect

#!/usr/bin/expect -f# usage: scpExpect user password ip file targetsystem "rm -rf  ~/.ssh/known_hosts"set password [lindex $argv 0]set from  [lindex $argv 1]set to  [lindex $argv 2]set timeout 120# now connect to remote UNIX box (ipaddr) with given script to executespawn scp -r -o StrictHostKeyChecking=no $from $tomatch_max 100000expect {              "*assword:*" {                        send -- "$password\r"                        set timeout -1                        expect {                                 "*assword:*" {                                        exit                                 }                        }            } "yes/no)?" {                       send "yes\r"                       set timeout -1            } -re . {                       exp_continue            } timeout {                       exit            } eof {                       exit            } }

sshExpect

#!/usr/bin/expect -f# usage:  ssh user password ipaddre command target# set Variablesset user [lrange $argv 0 0]set password [lrange $argv 1 1]set ipaddr [lrange $argv 2 2]set command  [lrange $argv 3 3]set target  [lrange $argv 4 4]set timeout -1# now connect to remote UNIX box (ipaddr) with given script to executespawn ssh -o StrictHostKeyChecking=no $user@$ipaddr $command $targetmatch_max 100000# Look for passwod promptexpect "*?assword:*"# Send password aka $passwordsend -- "$password\r"# send blank line (\r) to make sure we get back to guisend -- "\r"expect eof

感概一下:学习脚本切忌眼高手低,看着挺简单的东西,但是真正要自己写的时候发现步履维艰啊。shell脚本里面细节一不注意就容易犯错误,比如说if语句中方括号要注意两边的空格,还有"="两边的空格。另外一些细节的处理,shell很周到地为你考虑到了,比如输入密码时要防止回显,一个-s参数就搞定,所以有时候得多看看男人(man)得意

0 0
原创粉丝点击