Support multihoming on a single interface.
[bootmanager.git] / source / steps / WriteNetworkConfig.py
1 #!/usr/bin/python2
2
3 # Copyright (c) 2003 Intel Corporation
4 # All rights reserved.
5 #
6 # Copyright (c) 2004-2006 The Trustees of Princeton University
7 # All rights reserved.
8 # expected /proc/partitions format
9
10 import os, string
11
12 from Exceptions import *
13 import utils
14 import BootServerRequest
15 import ModelOptions
16 import urlparse
17 import BootAPI
18
19 def Run( vars, log ):
20     """
21     Write out the network configuration for this machine:
22     /etc/hosts
23     /etc/sysconfig/network-scripts/ifcfg-eth0
24     /etc/resolv.conf (if applicable)
25     /etc/sysconfig/network
26
27     The values to be used for the network settings are to be set in vars
28     in the variable 'NETWORK_SETTINGS', which is a dictionary
29     with keys:
30
31      Key               Used by this function
32      -----------------------------------------------
33      node_id
34      node_key
35      method            x
36      ip                x
37      mac               x (optional)
38      gateway           x
39      network           x
40      broadcast         x
41      netmask           x
42      dns1              x
43      dns2              x (optional)
44      hostname          x
45      domainname        x
46
47     Expect the following variables from the store:
48     SYSIMG_PATH             the path where the system image will be mounted
49                             (always starts with TEMP_PATH)
50     NETWORK_SETTINGS  A dictionary of the values from the network
51                                 configuration file
52     NODE_NETWORKS           All the network associated with this node
53     Sets the following variables:
54     None
55     """
56
57     log.write( "\n\nStep: Install: Writing Network Configuration files.\n" )
58
59     try:
60         SYSIMG_PATH= vars["SYSIMG_PATH"]
61         if SYSIMG_PATH == "":
62             raise ValueError, "SYSIMG_PATH"
63
64     except KeyError, var:
65         raise BootManagerException, "Missing variable in vars: %s\n" % var
66     except ValueError, var:
67         raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
68
69
70     try:
71         network_settings= vars['NETWORK_SETTINGS']
72     except KeyError, e:
73         raise BootManagerException, "No network settings found in vars."
74
75     try:
76         hostname= network_settings['hostname']
77         domainname= network_settings['domainname']
78         method= network_settings['method']
79         ip= network_settings['ip']
80         gateway= network_settings['gateway']
81         network= network_settings['network']
82         netmask= network_settings['netmask']
83         dns1= network_settings['dns1']
84         mac= network_settings['mac']
85     except KeyError, e:
86         raise BootManagerException, "Missing value %s in network settings." % str(e)
87
88     try:
89         dns2= ''
90         dns2= network_settings['dns2']
91     except KeyError, e:
92         pass
93
94
95     # Node Manager needs at least PLC_API_HOST and PLC_BOOT_HOST
96     log.write("Writing /etc/planetlab/plc_config\n")
97     utils.makedirs("%s/etc/planetlab" % SYSIMG_PATH)
98     plc_config = file("%s/etc/planetlab/plc_config" % SYSIMG_PATH, "w")
99
100     bs= BootServerRequest.BootServerRequest()
101     if bs.BOOTSERVER_CERTS:
102         print >> plc_config, "PLC_BOOT_HOST='%s'" % bs.BOOTSERVER_CERTS.keys()[0]
103
104     api_url = vars['BOOT_API_SERVER']
105     (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(api_url)
106     parts = netloc.split(':')
107     host = parts[0]
108     if len(parts) > 1:
109         port = parts[1]
110     else:
111         port = '80'
112     print >> plc_config, "PLC_API_HOST='%s'" % host
113     print >> plc_config, "PLC_API_PORT='%s'" % port
114     print >> plc_config, "PLC_API_PATH='%s'" % path
115
116     plc_config.close()
117
118
119     log.write( "Writing /etc/hosts\n" )
120     hosts_file= file("%s/etc/hosts" % SYSIMG_PATH, "w" )    
121     hosts_file.write( "127.0.0.1       localhost\n" )
122     if method == "static":
123         hosts_file.write( "%s %s.%s\n" % (ip, hostname, domainname) )
124     hosts_file.close()
125     hosts_file= None
126     
127
128     if method == "static":
129         log.write( "Writing /etc/resolv.conf\n" )
130         resolv_file= file("%s/etc/resolv.conf" % SYSIMG_PATH, "w" )
131         if dns1 != "":
132             resolv_file.write( "nameserver %s\n" % dns1 )
133         if dns2 != "":
134             resolv_file.write( "nameserver %s\n" % dns2 )
135         resolv_file.write( "search %s\n" % domainname )
136         resolv_file.close()
137         resolv_file= None
138
139     log.write( "Writing /etc/sysconfig/network\n" )
140     network_file= file("%s/etc/sysconfig/network" % SYSIMG_PATH, "w" )
141     network_file.write( "NETWORKING=yes\n" )
142     network_file.write( "HOSTNAME=%s.%s\n" % (hostname, domainname) )
143     if method == "static":
144         network_file.write( "GATEWAY=%s\n" % gateway )
145     network_file.close()
146     network_file= None
147
148     interfaces = {}
149     interface = 1
150     for network in vars['NODE_NETWORKS']:
151         if method == "static" or method == "dhcp":
152             if network['is_primary'] == 1:
153                 ifnum = 0
154             else:
155                 ifnum = interface
156                 interface += 1
157
158             int = {}
159             if network['mac']:
160                 int['HWADDR'] = network['mac']
161
162             if network['method'] == "static":
163                 int['BOOTPROTO'] = "static"
164                 int['IPADDR'] = network['ip']
165                 int['NETMASK'] = network['netmask']
166
167             elif network['method'] == "dhcp":
168                 int['BOOTPROTO'] = "dhcp"
169                 if network['hostname']:
170                     int['DHCP_HOSTNAME'] = network['hostname']
171                 else:
172                     int['DHCP_HOSTNAME'] = hostname
173                 if not network['is_primary']:
174                     int['DHCLIENTARGS'] = "-R subnet-mask"
175
176             alias = ""
177             if len(network['nodenetwork_setting_ids']) > 0:
178                 settings = BootAPI.call_api_function(vars, "GetNodeNetworkSettings",
179                     ({'nodenetwork_setting_id': network['nodenetwork_setting_ids']},))
180                 for setting in settings:
181                     if setting['category'].upper() == "WLAN":
182                         if setting['name'].upper() == "SSID":
183                             int['ESSID'] = setting['value']
184                         elif setting['name'].upper() == "IWCONFIG":
185                             int['IWCONFIG'] = setting['value']
186                         elif setting['name'].upper() == "MODE":
187                             int['MODE'] = setting['value']
188                     elif setting['category'].upper() == "MULTIHOME":
189                         if setting['name'].upper() == "ALIAS":
190                             alias = ":" + setting['value']
191
192             if alias and 'HWADDR' in int:
193                 for (dev, i) in interfaces.iteritems():
194                     if i['HWADDR'] == int['HWADDR']:
195                         break
196                 del int['HWADDR']
197                 interfaces[dev + alias] = int
198                 interface -= 1
199             else:
200                 interfaces["eth%d" % ifnum] = int
201
202     for (dev, int) in interfaces.iteritems():
203             path = "%s/etc/sysconfig/network-scripts/ifcfg-%s" % (
204                    SYSIMG_PATH, dev)
205             f = file(path, "w")
206             log.write("Writing %s\n" % path.replace(SYSIMG_PATH, ""))
207
208             f.write("DEVICE=%s\n" % dev)
209             f.write("ONBOOT=yes\n")
210             f.write("USERCTL=no\n")
211             for (key, val) in int.iteritems():
212                 f.write('%s="%s"\n' % (key, val))
213
214             f.close()
215