1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
8
# todo(ja): does the definition of network_path belong here?
10
from nova import flags
14
if FLAGS.fake_network:
15
print "FAKE NET: %s" % cmd
18
nova.utils.execute(cmd)
20
def runthis(desc, cmd):
21
if FLAGS.fake_network:
24
nova.utils.runthis(desc,cmd)
27
if FLAGS.fake_network:
28
execute(' '.join(cmd))
33
def device_exists(device):
34
(out, err) = execute("ifconfig %s" % device)
37
def confirm_rule(cmd):
38
execute("sudo iptables --delete %s" % (cmd))
39
execute("sudo iptables -I %s" % (cmd))
42
execute("sudo iptables --delete %s" % (cmd))
44
def bind_public_ip(ip, interface):
45
runthis("Binding IP to interface: %s", "sudo ip addr add %s dev %s" % (ip, interface))
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))
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))
67
execute("sudo ifconfig %s up" % net.bridge_name)
70
cmd = ['sudo dnsmasq',
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')]
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'])
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, ...)
93
def start_dnsmasq(network):
94
""" (re)starts a dnsmasq server for a given network
96
if a dnsmasq instance is already running then send a HUP
97
signal causing it to reload, otherwise spawn a new instance
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]))
103
pid = dnsmasq_pid_for(network)
105
# if dnsmasq is already running, then tell it to reload
107
# todo(ja): use "/proc/%d/cmdline" % (pid) to determine if pid refers
108
# correct dnsmasq process
110
os.kill(pid, signal.SIGHUP)
113
logging.debug("Killing dnsmasq threw %s", e)
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)
120
Popen(dnsmasq_cmd(network).split(" "))
122
def stop_dnsmasq(network):
123
""" stops the dnsmasq instance for a given network """
124
pid = dnsmasq_pid_for(network)
127
os.kill(pid, signal.SIGTERM)
129
def dhcp_file(vlan, kind):
130
""" return path to a pid, leases or conf file for a vlan """
132
return os.path.abspath("%s/nova-%s.%s" % (FLAGS.networks_path, vlan, kind))
134
def dnsmasq_pid_for(network):
135
""" the pid for prior dnsmasq instance for a vlan,
136
returns None if no pid file exists
138
if machine has rebooted pid might be incorrect (caller should check)
141
pid_file = dhcp_file(network.vlan, 'pid')
143
if os.path.exists(pid_file):
144
with open(pid_file, 'r') as f: