用于修改VMware虚机hosts文件的Python脚本

基于VMware Fusion虚拟机搭建Hadoop集群。宿主系统OSX,虚机均为Linux系统。

配置集群时需要修改每个节点的hosts文件,指出相应节点的IP地址。为保证这些虚机的IP地址不会发生变化,应使用Host-only的联网方式。

在Host-only组网方式下,各节点的hosts只需配置一次,今后就不用修改了,比较方便。只是,要想从宿主直接访问Hadoop接口的话,就没办法了,因为宿主与这些虚机不在一个网络内。

若改成Bridge方式,就可以解决网络不通的问题。但只要宿主机器换了网络环境,这些Bridge到它的虚机的IP就有可能发生变化,这样就要挨个修改hosts文件,比较繁琐。

为减轻负担,制作了一个Python脚本,专门用来修改各虚拟机的hosts文件,每当宿主改变网络环境,就在宿主上运行一下这个脚本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env python
# coding: utf-8

import os
import re
import sys
import paramiko
import subprocess

vmpath = '/Users/xushuai/Documents/Virtual Machines.localized/hadoop_cluster'

class NodeInfo:
    ip = ''
    port = 22
    username = 'xushuai'
    password = '1'
    hostname = ''

nodes = []

for root, dirs, files in os.walk(vmpath):
    for f in files:
        t = re.split('.vmx', f)[-1]
        if t == '':
            hostname = f.split('.')[0]
            cmd = re.escape(root + '/' + f)
            cmd = 'vmrun getGuestIPAddress ' + cmd 
            ip = ''
            try:
                ip = subprocess.check_output(cmd, shell=True) 
            except subprocess.CalledProcessError, e:
                continue

            node = NodeInfo()
            node.ip = ip.split('\n')[0]
            node.hostname = hostname + '.hadoop'
            nodes.append(node)

for node in nodes:
    ip = node.ip
    port = node.port
    username = node.username
    hostname = node.hostname
    passwd = node.password
    print '\n---------------------------------------'
    print hostname + '(' + ip + ')'
    print '---------------------------------------'
    print 'ssh ' + username + '@' + ip + ' ...... '
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(ip, port, username=username, password=passwd)
    print 'ssh ' + username + '@' + ip + ' ok !'

    command = 'cp /etc/hosts /tmp' 
    print command
    stdin,stdout,stderr = ssh.exec_command(command)

    command = 'sed -i \"/..hadoop/d\" /tmp/hosts' 
    print command
    stdin,stdout,stderr = ssh.exec_command(command)

    for node in nodes:
        item = node.ip + ' ' + node.hostname
        if node.hostname == hostname: 
            if hostname != 'master.hadoop':
                item = '127.0.0.1 ' + node.hostname

        command = 'echo \"' + item + '\" >> /tmp/hosts' 
        print command
        stdin,stdout,stderr = ssh.exec_command(command)

    session = ssh.get_transport().open_session()
    session.set_combine_stderr(True)
    session.get_pty()
    stdin = session.makefile('wb', -1)
    stdout = session.makefile('rb', -1)
    command = 'sudo cp /tmp/hosts /etc/'
    print command
    session.exec_command(command)
    stdin.write(passwd + '\n')
    stdin.flush()
    stdout.read()

主要工作流程就是:在vmpath目录下找到各虚拟机对应的配置文件(*.vmx),并使用VMware的命令行工具vmrun以获得各虚机当前的IP地址。拿到这些IP地址,再使用Paramiko去访问各个虚机,对hosts进行修改。

注意

  1. 按照本程序的处理逻辑,配置文件*.vmx的命名要求有一定的格式,类似于这种形式:name.aaa.bbb.vmx,基于这个命名程序会得出该虚机的域名为”name.hadoop”。

  2. 虚机账号一律为xushuai,密码为1,记得根据实际情况修改。

  3. 如果不想在升级OSX旧版openssl(0.9.8版)上花时间的话,使用Paramiko的1.16.0版本即可。