kalor

导航

 

转自:http://blog.csdn.net/napolunyishi/article/details/18219867

这两天做了一个需求,因为上一个版本的/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 version  
    cat /etc/issue | grep "V3.5"  
    if [ $? -ne 0 ]; then  
        echo "This is not V3.5, exit!"  
        exit  
    fi  
      
    ISFABRIC=0  
    ADMPW=""  
      
    echo  
      
    read -rsn1 -p "Is this a fabric with same admin password? [y/n]"  
    echo  
    if [ "$REPLY" = "y" -o "$REPLY" = "Y" ]; then  
        ISFABRIC=1  
        read -esp "Please input the password: " ADMPW  
    else  
        echo "Please run the script doFix.sh manually"  
        exit  
    fi  
    echo  
    echo  
      
    echo "Patch current node..."  
    sh ./doFix.sh  
      
    NODEIP=$(ifconfig eth0 | grep 'inet addr' | cut -d':' -f2 | awk '{print $1}')  
      
    echo "Begin to patch other nodes..."  
    echo  
      
    egrep "MAGICNODE-" /etc/hosts | awk '{print $1}' | sort | uniq | while read LINE  
    do  
        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  
        echo  
    done  
      
    echo "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 target  
      
    system "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 execute  
    spawn scp -r -o StrictHostKeyChecking=no $from $to  
    match_max 100000  
    expect {  
                  "*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 Variables  
set 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 execute  
spawn ssh -o StrictHostKeyChecking=no $user@$ipaddr $command $target  
match_max 100000  
# Look for passwod prompt  
expect "*?assword:*"  
# Send password aka $password  
send -- "$password\r"  
# send blank line (\r) to make sure we get back to gui  
send -- "\r"  
expect eof  

 

posted on 2014-05-04 14:49  kalor  阅读(1048)  评论(0编辑  收藏  举报