renaming SliceAttribute into SliceTag and InterfaceSetting into InterfaceTag
[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_tag_ids']) > 0:
188                 tags =  BootAPI.call_api_function(vars, "GetInterfaceTags",
189                                                   ({'interface_tag_id': interface['interface_tag_ids']},))
190                 for tag in tags:
191                     # to explicitly set interface name
192                     if   tag['tagname'].upper() == "IFNAME":
193                         ifname=tag['value']
194                     elif tag['tagname'].upper() == "DRIVER":
195                         # xxx not sure how to do that yet - probably add a line in modprobe.conf
196                         pass
197                     elif tag['tagname'].upper() == "ALIAS":
198                         alias = ":" + tag['value']
199
200                     # a hack for testing before a new setting is hardcoded here
201                     # use the backdoor tag and put as a value 'var=value'
202                     elif tag['tagname'].upper() == "BACKDOOR":
203                         [var,value]=tag['value'].split('=',1)
204                         inter[var]=value
205
206                     elif tag['tagname'].lower() in \
207                             [  "mode", "essid", "nw", "freq", "channel", "sens", "rate",
208                                "key", "key1", "key2", "key3", "key4", "securitymode", 
209                                "iwconfig", "iwpriv" ] :
210                         inter [tag['tagname'].upper()] = tag['value']
211                         inter ['TYPE']='Wireless'
212                     else:
213                         log.write("Warning - ignored tag named %s\n"%tag['tagname'])
214
215             if alias and 'HWADDR' in inter:
216                 for (dev, i) in interfaces.iteritems():
217                     if i['HWADDR'] == inter['HWADDR']:
218                         break
219                 del inter['HWADDR']
220                 interfaces[dev + alias] =inter 
221                 interface_count -= 1
222             else:
223                 if not ifname:
224                     ifname="eth%d" % ifnum
225                 else:
226                     interface_count -= 1
227                 interfaces[ifname] =inter 
228
229     for (dev, inter) in interfaces.iteritems():
230         path = "%s/etc/sysconfig/network-scripts/ifcfg-%s" % (
231                SYSIMG_PATH, dev)
232         f = file(path, "w")
233         log.write("Writing %s\n" % path.replace(SYSIMG_PATH, ""))
234
235         f.write("DEVICE=%s\n" % dev)
236         f.write("ONBOOT=yes\n")
237         f.write("USERCTL=no\n")
238         for (key, val) in inter.iteritems():
239             f.write('%s="%s"\n' % (key, val))
240
241         f.close()
242