Daniel rightly pointed out that my change to use
[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     # dns2 is not required to be set
92     dns2 = interface_settings.get('dns2','')
93
94     # Node Manager needs at least PLC_API_HOST and PLC_BOOT_HOST
95     log.write("Writing /etc/planetlab/plc_config\n")
96     utils.makedirs("%s/etc/planetlab" % SYSIMG_PATH)
97     plc_config = file("%s/etc/planetlab/plc_config" % SYSIMG_PATH, "w")
98
99     api_url = vars['BOOT_API_SERVER']
100     (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(api_url)
101     parts = netloc.split(':')
102     host = parts[0]
103     if len(parts) > 1:
104         port = parts[1]
105     else:
106         port = '80'
107     try:
108         log.write("getting via https://%s/PlanetLabConf/get_plc_config.php " % host)
109         bootserver = httplib.HTTPSConnection(host, int(port))
110         bootserver.connect()
111         bootserver.request("GET","https://%s/PlanetLabConf/get_plc_config.php" % host)
112         plc_config.write("%s" % bootserver.getresponse().read())
113         bootserver.close()
114         log.write("Done\n")
115     except :
116         log.write(" .. Failed.  Using old method. -- stack trace follows\n")
117         traceback.print_exc(file=log.OutputFile)
118         bs= BootServerRequest.BootServerRequest()
119         if bs.BOOTSERVER_CERTS:
120             print >> plc_config, "PLC_BOOT_HOST='%s'" % bs.BOOTSERVER_CERTS.keys()[0]
121         print >> plc_config, "PLC_API_HOST='%s'" % host
122         print >> plc_config, "PLC_API_PORT='%s'" % port
123         print >> plc_config, "PLC_API_PATH='%s'" % path
124
125     plc_config.close()
126
127
128     log.write( "Writing /etc/hosts\n" )
129     hosts_file= file("%s/etc/hosts" % SYSIMG_PATH, "w" )    
130     hosts_file.write( "127.0.0.1       localhost\n" )
131     if method == "static":
132         hosts_file.write( "%s %s.%s\n" % (ip, hostname, domainname) )
133     hosts_file.close()
134     hosts_file= None
135     
136
137     if method == "static":
138         log.write( "Writing /etc/resolv.conf\n" )
139         resolv_file= file("%s/etc/resolv.conf" % SYSIMG_PATH, "w" )
140         if dns1 != "":
141             resolv_file.write( "nameserver %s\n" % dns1 )
142         if dns2 != "":
143             resolv_file.write( "nameserver %s\n" % dns2 )
144         resolv_file.write( "search %s\n" % domainname )
145         resolv_file.close()
146         resolv_file= None
147
148     log.write( "Writing /etc/sysconfig/network\n" )
149     network_file= file("%s/etc/sysconfig/network" % SYSIMG_PATH, "w" )
150     network_file.write( "NETWORKING=yes\n" )
151     network_file.write( "HOSTNAME=%s.%s\n" % (hostname, domainname) )
152     if method == "static":
153         network_file.write( "GATEWAY=%s\n" % gateway )
154     network_file.close()
155     network_file= None
156
157     interfaces = {}
158     interface_count = 1
159     for interface in vars['INTERFACES']:
160         if method == "static" or method == "dhcp":
161             if interface['is_primary'] == 1:
162                 ifnum = 0
163             else:
164                 ifnum = interface_count
165                 interface_count += 1
166
167             inter = {}
168             if interface['mac']:
169                 inter['HWADDR'] = interface['mac']
170
171             if interface['method'] == "static":
172                 inter['BOOTPROTO'] = "static"
173                 inter['IPADDR'] = interface['ip']
174                 inter['NETMASK'] = interface['netmask']
175
176             elif interface['method'] == "dhcp":
177                 inter['BOOTPROTO'] = "dhcp"
178                 if interface['hostname']:
179                     inter['DHCP_HOSTNAME'] = interface['hostname']
180                 else:
181                     inter['DHCP_HOSTNAME'] = hostname 
182                 if not interface['is_primary']:
183                     inter['DHCLIENTARGS'] = "-R subnet-mask"
184
185             alias = ""
186             ifname=None
187             if len(interface['interface_setting_ids']) > 0:
188                 settings = \
189                     BootAPI.call_api_function(vars, "GetInterfaceSettings",
190                                               ({'interface_setting_id': 
191                                                 interface['interface_setting_ids']},))
192                 for setting in settings:
193                     # to explicitly set interface name
194                     if   setting['name'].upper() == "IFNAME":
195                         ifname=setting['value']
196                     elif setting['name'].upper() == "DRIVER":
197                         # xxx not sure how to do that yet - probably add a line in modprobe.conf
198                         pass
199                     elif setting['name'].upper() == "ALIAS":
200                         alias = ":" + setting['value']
201
202                     # a hack for testing before a new setting is hardcoded here
203                     # use the backdoor setting and put as a value 'var=value'
204                     elif setting['name'].upper() == "BACKDOOR":
205                         [var,value]=setting['value'].split('=',1)
206                         inter[var]=value
207
208                     elif setting['name'].lower() in \
209                             [  "mode", "essid", "nw", "freq", "channel", "sens", "rate",
210                                "key", "key1", "key2", "key3", "key4", "securitymode", 
211                                "iwconfig", "iwpriv" ] :
212                         inter [setting['name'].upper()] = setting['value']
213                         inter ['TYPE']='Wireless'
214                     else:
215                         log.write("Warning - ignored setting named %s\n"%setting['name'])
216
217             if alias and 'HWADDR' in inter:
218                 for (dev, i) in interfaces.iteritems():
219                     if i['HWADDR'] == inter['HWADDR']:
220                         break
221                 del inter['HWADDR']
222                 interfaces[dev + alias] =inter 
223                 interface_count -= 1
224             else:
225                 if not ifname:
226                     ifname="eth%d" % ifnum
227                 else:
228                     interface_count -= 1
229                 interfaces[ifname] =inter 
230
231     for (dev, inter) in interfaces.iteritems():
232         path = "%s/etc/sysconfig/network-scripts/ifcfg-%s" % (
233                SYSIMG_PATH, dev)
234         f = file(path, "w")
235         log.write("Writing %s\n" % path.replace(SYSIMG_PATH, ""))
236
237         f.write("DEVICE=%s\n" % dev)
238         f.write("ONBOOT=yes\n")
239         f.write("USERCTL=no\n")
240         for (key, val) in inter.iteritems():
241             f.write('%s="%s"\n' % (key, val))
242
243         f.close()
244