not all platforms have the python2 hook
[bootmanager.git] / source / steps / WriteNetworkConfig.py
1 #!/usr/bin/python
2 # $Id$
3 #
4 # Copyright (c) 2003 Intel Corporation
5 # All rights reserved.
6 #
7 # Copyright (c) 2004-2006 The Trustees of Princeton University
8 # All rights reserved.
9 # expected /proc/partitions format
10
11 import os, string
12 import traceback
13
14 import utils
15 import urlparse
16 import httplib
17
18 from Exceptions import *
19 import BootServerRequest
20 import ModelOptions
21 import BootAPI
22
23 def Run( vars, log ):
24     """
25     Write out the network configuration for this machine:
26     /etc/hosts
27     /etc/sysconfig/network-scripts/ifcfg-<ifname>
28     /etc/resolv.conf (if applicable)
29     /etc/sysconfig/network
30
31     The values to be used for the network settings are to be set in vars
32     in the variable 'INTERFACE_SETTINGS', which is a dictionary
33     with keys:
34
35      Key               Used by this function
36      -----------------------------------------------
37      node_id
38      node_key
39      method            x
40      ip                x
41      mac               x (optional)
42      gateway           x
43      network           x
44      broadcast         x
45      netmask           x
46      dns1              x
47      dns2              x (optional)
48      hostname          x
49      domainname        x
50
51     Expect the following variables from the store:
52     SYSIMG_PATH             the path where the system image will be mounted
53                                 (always starts with TEMP_PATH)
54     INTERFACES              All the interfaces associated with this node
55     INTERFACE_SETTINGS      dictionary 
56     Sets the following variables:
57     None
58     """
59
60     log.write( "\n\nStep: Install: Writing Network Configuration files.\n" )
61
62     try:
63         SYSIMG_PATH= vars["SYSIMG_PATH"]
64         if SYSIMG_PATH == "":
65             raise ValueError, "SYSIMG_PATH"
66
67     except KeyError, var:
68         raise BootManagerException, "Missing variable in vars: %s\n" % var
69     except ValueError, var:
70         raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
71
72
73     try:
74         interface_settings= vars['INTERFACE_SETTINGS']
75     except KeyError, e:
76         raise BootManagerException, "No interface settings found in vars."
77
78     try:
79         hostname= interface_settings['hostname']
80         domainname= interface_settings['domainname']
81         method= interface_settings['method']
82         ip= interface_settings['ip']
83         gateway= interface_settings['gateway']
84         network= interface_settings['network']
85         netmask= interface_settings['netmask']
86         dns1= interface_settings['dns1']
87         mac= interface_settings['mac']
88     except KeyError, e:
89         raise BootManagerException, "Missing value %s in interface settings." % str(e)
90
91     try:
92         dns2= ''
93         dns2= interface_settings['dns2']
94     except KeyError, e:
95         pass
96
97
98     # Node Manager needs at least PLC_API_HOST and PLC_BOOT_HOST
99     log.write("Writing /etc/planetlab/plc_config\n")
100     utils.makedirs("%s/etc/planetlab" % SYSIMG_PATH)
101     plc_config = file("%s/etc/planetlab/plc_config" % SYSIMG_PATH, "w")
102
103     api_url = vars['BOOT_API_SERVER']
104     (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(api_url)
105     parts = netloc.split(':')
106     host = parts[0]
107     if len(parts) > 1:
108         port = parts[1]
109     else:
110         port = '80'
111     try:
112         log.write("getting via https://%s/PlanetLabConf/get_plc_config.php " % host)
113         bootserver = httplib.HTTPSConnection(host, int(port))
114         bootserver.connect()
115         bootserver.request("GET","https://%s/PlanetLabConf/get_plc_config.php" % host)
116         plc_config.write("%s" % bootserver.getresponse().read())
117         bootserver.close()
118         log.write("Done\n")
119     except :
120         log.write(" .. Failed.  Using old method. -- stack trace follows\n")
121         traceback.print_exc(file=log.OutputFile)
122         bs= BootServerRequest.BootServerRequest()
123         if bs.BOOTSERVER_CERTS:
124             print >> plc_config, "PLC_BOOT_HOST='%s'" % bs.BOOTSERVER_CERTS.keys()[0]
125         print >> plc_config, "PLC_API_HOST='%s'" % host
126         print >> plc_config, "PLC_API_PORT='%s'" % port
127         print >> plc_config, "PLC_API_PATH='%s'" % path
128
129     plc_config.close()
130
131
132     log.write( "Writing /etc/hosts\n" )
133     hosts_file= file("%s/etc/hosts" % SYSIMG_PATH, "w" )    
134     hosts_file.write( "127.0.0.1       localhost\n" )
135     if method == "static":
136         hosts_file.write( "%s %s.%s\n" % (ip, hostname, domainname) )
137     hosts_file.close()
138     hosts_file= None
139     
140
141     if method == "static":
142         log.write( "Writing /etc/resolv.conf\n" )
143         resolv_file= file("%s/etc/resolv.conf" % SYSIMG_PATH, "w" )
144         if dns1 != "":
145             resolv_file.write( "nameserver %s\n" % dns1 )
146         if dns2 != "":
147             resolv_file.write( "nameserver %s\n" % dns2 )
148         resolv_file.write( "search %s\n" % domainname )
149         resolv_file.close()
150         resolv_file= None
151
152     log.write( "Writing /etc/sysconfig/network\n" )
153     network_file= file("%s/etc/sysconfig/network" % SYSIMG_PATH, "w" )
154     network_file.write( "NETWORKING=yes\n" )
155     network_file.write( "HOSTNAME=%s.%s\n" % (hostname, domainname) )
156     if method == "static":
157         network_file.write( "GATEWAY=%s\n" % gateway )
158     network_file.close()
159     network_file= None
160
161     interfaces = {}
162     interface_count = 1
163     for interface in vars['INTERFACES']:
164         if method == "static" or method == "dhcp":
165             if interface['is_primary'] == 1:
166                 ifnum = 0
167             else:
168                 ifnum = interface_count
169                 interface_count += 1
170
171             inter = {}
172             if interface['mac']:
173                 inter['HWADDR'] = interface['mac']
174
175             if interface['method'] == "static":
176                 inter['BOOTPROTO'] = "static"
177                 inter['IPADDR'] = interface['ip']
178                 inter['NETMASK'] = interface['netmask']
179
180             elif interface['method'] == "dhcp":
181                 inter['BOOTPROTO'] = "dhcp"
182                 if interface['hostname']:
183                     inter['DHCP_HOSTNAME'] = interface['hostname']
184                 else:
185                     inter['DHCP_HOSTNAME'] = hostname
186                 if not interface['is_primary']:
187                     inter['DHCLIENTARGS'] = "-R subnet-mask"
188
189             alias = ""
190             ifname=None
191             if len(interface['interface_setting_ids']) > 0:
192                 settings = \
193                     BootAPI.call_api_function(vars, "GetInterfaceSettings",
194                                               ({'interface_setting_id': 
195                                                 interface['interface_setting_ids']},))
196                 for setting in settings:
197                     # to explicitly set interface name
198                     if   setting['name'].upper() == "IFNAME":
199                         ifname=setting['value']
200                     elif setting['name'].upper() == "DRIVER":
201                         # xxx not sure how to do that yet - probably add a line in modprobe.conf
202                         pass
203                     elif setting['name'].upper() == "ALIAS":
204                         alias = ":" + setting['value']
205
206                     # a hack for testing before a new setting is hardcoded here
207                     # use the backdoor setting and put as a value 'var=value'
208                     elif setting['name'].upper() == "BACKDOOR":
209                         [var,value]=setting['value'].split('=',1)
210                         inter[var]=value
211
212                     elif setting['name'].lower() in \
213                             [  "mode", "essid", "nw", "freq", "channel", "sens", "rate",
214                                "key", "key1", "key2", "key3", "key4", "securitymode", 
215                                "iwconfig", "iwpriv" ] :
216                         inter [setting['name'].upper()] = setting['value']
217                         inter ['TYPE']='Wireless'
218                     else:
219                         log.write("Warning - ignored setting named %s\n"%setting['name'])
220
221             if alias and 'HWADDR' in inter:
222                 for (dev, i) in interfaces.iteritems():
223                     if i['HWADDR'] == inter['HWADDR']:
224                         break
225                 del inter['HWADDR']
226                 interfaces[dev + alias] =inter 
227                 interface_count -= 1
228             else:
229                 if not ifname:
230                     ifname="eth%d" % ifnum
231                 else:
232                     interface_count -= 1
233                 interfaces[ifname] =inter 
234
235     for (dev, inter) in interfaces.iteritems():
236         path = "%s/etc/sysconfig/network-scripts/ifcfg-%s" % (
237                SYSIMG_PATH, dev)
238         f = file(path, "w")
239         log.write("Writing %s\n" % path.replace(SYSIMG_PATH, ""))
240
241         f.write("DEVICE=%s\n" % dev)
242         f.write("ONBOOT=yes\n")
243         f.write("USERCTL=no\n")
244         for (key, val) in inter.iteritems():
245             f.write('%s="%s"\n' % (key, val))
246
247         f.close()
248