~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to nova/compute/linux_net.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
 
 
3
import signal
 
4
import os
 
5
import nova.utils
 
6
import subprocess
 
7
 
 
8
# todo(ja): does the definition of network_path belong here?
 
9
 
 
10
from nova import flags
 
11
FLAGS=flags.FLAGS
 
12
 
 
13
def execute(cmd):
 
14
    if FLAGS.fake_network:
 
15
        print "FAKE NET: %s" % cmd
 
16
        return "fake", 0
 
17
    else:
 
18
        nova.utils.execute(cmd)
 
19
 
 
20
def runthis(desc, cmd):
 
21
    if FLAGS.fake_network:
 
22
        execute(cmd)
 
23
    else:
 
24
        nova.utils.runthis(desc,cmd)
 
25
 
 
26
def Popen(cmd):
 
27
    if FLAGS.fake_network:
 
28
        execute(' '.join(cmd))
 
29
    else:
 
30
        subprocess.Popen(cmd)
 
31
 
 
32
 
 
33
def device_exists(device):
 
34
    (out, err) = execute("ifconfig %s" % device)
 
35
    return not err
 
36
 
 
37
def confirm_rule(cmd):
 
38
    execute("sudo iptables --delete %s" % (cmd))
 
39
    execute("sudo iptables -I %s" % (cmd))
 
40
 
 
41
def remove_rule(cmd):
 
42
    execute("sudo iptables --delete %s" % (cmd))
 
43
 
 
44
def bind_public_ip(ip, interface):
 
45
    runthis("Binding IP to interface: %s", "sudo ip addr add %s dev %s" % (ip, interface))
 
46
 
 
47
def vlan_create(net):
 
48
    """ create a vlan on on a bridge device unless vlan already exists """
 
49
    if not device_exists("vlan%s" % net.vlan):
 
50
        execute("sudo vconfig set_name_type VLAN_PLUS_VID_NO_PAD")
 
51
        execute("sudo vconfig add %s %s" % (net.bridge_dev, net.vlan))
 
52
        execute("sudo ifconfig vlan%s up" % (net.vlan))
 
53
 
 
54
def bridge_create(net):
 
55
    """ create a bridge on a vlan unless it already exists """
 
56
    if not device_exists(net.bridge_name):
 
57
        execute("sudo brctl addbr %s" % (net.bridge_name))
 
58
        # execute("sudo brctl setfd %s 0" % (net.bridge_name))
 
59
        # execute("sudo brctl setageing %s 10" % (net.bridge_name))
 
60
        execute("sudo brctl stp %s off" % (net.bridge_name))
 
61
        execute("sudo brctl addif %s vlan%s" % (net.bridge_name, net.vlan))
 
62
        if net.bridge_gets_ip:
 
63
            execute("sudo ifconfig %s %s broadcast %s netmask %s up" % \
 
64
                (net.bridge_name, net.gateway, net.broadcast, net.netmask))
 
65
            confirm_rule("FORWARD --in-interface %s -j ACCEPT" % (net.bridge_name))
 
66
        else:
 
67
            execute("sudo ifconfig %s up" % net.bridge_name)
 
68
 
 
69
def dnsmasq_cmd(net):
 
70
    cmd = ['sudo dnsmasq',
 
71
        ' --strict-order',
 
72
        ' --bind-interfaces',
 
73
        ' --conf-file=',
 
74
        ' --pid-file=%s' % dhcp_file(net.vlan, 'pid'),
 
75
        ' --listen-address=%s' % net.dhcp_listen_address,
 
76
        ' --except-interface=lo',
 
77
        ' --dhcp-range=%s,%s,120s' % (net.dhcp_range_start, net.dhcp_range_end),
 
78
        ' --dhcp-lease-max=61',
 
79
        ' --dhcp-hostsfile=%s' % dhcp_file(net.vlan, 'conf'),
 
80
        ' --dhcp-leasefile=%s' % dhcp_file(net.vlan, 'leases')]
 
81
    return ''.join(cmd)
 
82
 
 
83
def hostDHCP(network, host):
 
84
    idx = host['address'].split(".")[-1] # Logically, the idx of instances they've launched in this net
 
85
    return "%s,%s-%s-%s.novalocal,%s" % \
 
86
        (host['mac'], host['user_id'], network.vlan, idx, host['address'])
 
87
 
 
88
# todo(ja): if the system has restarted or pid numbers have wrapped
 
89
#           then you cannot be certain that the pid refers to the
 
90
#           dnsmasq.  As well, sending a HUP only reloads the hostfile,
 
91
#           so any configuration options (like dchp-range, vlan, ...)
 
92
#           aren't reloaded
 
93
def start_dnsmasq(network):
 
94
    """ (re)starts a dnsmasq server for a given network
 
95
 
 
96
    if a dnsmasq instance is already running then send a HUP
 
97
    signal causing it to reload, otherwise spawn a new instance
 
98
    """
 
99
    with open(dhcp_file(network.vlan, 'conf'), 'w') as f:
 
100
        for host_name in network.hosts:
 
101
            f.write("%s\n" % hostDHCP(network, network.hosts[host_name]))
 
102
 
 
103
    pid = dnsmasq_pid_for(network)
 
104
 
 
105
    # if dnsmasq is already running, then tell it to reload
 
106
    if pid:
 
107
        # todo(ja): use "/proc/%d/cmdline" % (pid) to determine if pid refers
 
108
        #           correct dnsmasq process
 
109
        try:
 
110
            os.kill(pid, signal.SIGHUP)
 
111
            return
 
112
        except Exception, e:
 
113
            logging.debug("Killing dnsmasq threw %s", e)
 
114
 
 
115
    # otherwise delete the existing leases file and start dnsmasq
 
116
    lease_file = dhcp_file(network.vlan, 'leases')
 
117
    if os.path.exists(lease_file):
 
118
        os.unlink(lease_file)
 
119
 
 
120
    Popen(dnsmasq_cmd(network).split(" "))
 
121
 
 
122
def stop_dnsmasq(network):
 
123
    """ stops the dnsmasq instance for a given network """
 
124
    pid = dnsmasq_pid_for(network)
 
125
 
 
126
    if pid:
 
127
        os.kill(pid, signal.SIGTERM)
 
128
 
 
129
def dhcp_file(vlan, kind):
 
130
    """ return path to a pid, leases or conf file for a vlan """
 
131
 
 
132
    return os.path.abspath("%s/nova-%s.%s" % (FLAGS.networks_path, vlan, kind))
 
133
 
 
134
def dnsmasq_pid_for(network):
 
135
    """ the pid for prior dnsmasq instance for a vlan,
 
136
    returns None if no pid file exists
 
137
 
 
138
    if machine has rebooted pid might be incorrect (caller should check)
 
139
    """
 
140
 
 
141
    pid_file = dhcp_file(network.vlan, 'pid')
 
142
 
 
143
    if os.path.exists(pid_file):
 
144
        with open(pid_file, 'r') as f:
 
145
            return int(f.read())
 
146