1 # Copyright (c) 2003 Intel Corporation
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following
13 # disclaimer in the documentation and/or other materials provided
14 # with the distribution.
16 # * Neither the name of the Intel Corporation nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
24 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 # EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
33 # YOUR JURISDICTION. It is licensee's responsibility to comply with any
34 # export regulations applicable in licensee's jurisdiction. Under
35 # CURRENT (May 2000) U.S. export regulations this software is eligible
36 # for export from the U.S. and can be downloaded by or otherwise
37 # exported or reexported worldwide EXCEPT to U.S. embargoed destinations
38 # which include Cuba, Iraq, Libya, North Korea, Iran, Syria, Sudan,
39 # Afghanistan and any other country to which the U.S. has embargoed
45 from Exceptions import *
47 from systeminfo import systeminfo
50 from GetAndUpdateNodeDetails import SMP_OPT
55 Writes out the following configuration files for the node:
58 /etc/sysconfig/network-scripts/ifcfg-eth0
59 /etc/resolv.conf (if applicable)
60 /etc/sysconfig/network
63 /etc/ssh/ssh_host_rsa_key
64 /etc/ssh/ssh_host_dsa_key
66 Expect the following variables from the store:
67 VERSION the version of the install
68 SYSIMG_PATH the path where the system image will be mounted
69 (always starts with TEMP_PATH)
70 PARTITIONS dictionary of generic part. types (root/swap)
71 and their associated devices.
72 PLCONF_DIR The directory to store the configuration file in
73 NETWORK_SETTINGS A dictionary of the values from the network
75 BOOT_CD_VERSION A tuple of the current bootcd version
77 Sets the following variables:
82 log.write( "\n\nStep: Install: Writing configuration files.\n" )
84 # make sure we have the variables we need
86 VERSION= vars["VERSION"]
88 raise ValueError, "VERSION"
90 SYSIMG_PATH= vars["SYSIMG_PATH"]
92 raise ValueError, "SYSIMG_PATH"
94 PARTITIONS= vars["PARTITIONS"]
95 if PARTITIONS == None:
96 raise ValueError, "PARTITIONS"
98 PLCONF_DIR= vars["PLCONF_DIR"]
100 raise ValueError, "PLCONF_DIR"
102 NETWORK_SETTINGS= vars["NETWORK_SETTINGS"]
103 if NETWORK_SETTINGS == "":
104 raise ValueError, "NETWORK_SETTINGS"
106 BOOT_CD_VERSION= vars["BOOT_CD_VERSION"]
107 if BOOT_CD_VERSION == "":
108 raise ValueError, "BOOT_CD_VERSION"
110 NODE_MODEL_OPTIONS= vars["NODE_MODEL_OPTIONS"]
112 except KeyError, var:
113 raise BootManagerException, "Missing variable in vars: %s\n" % var
114 except ValueError, var:
115 raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
118 # we need to keys in PARTITIONS, root and swap, make sure
120 val= PARTITIONS["root"]
121 val= PARTITIONS["swap"]
122 val= PARTITIONS["vservers"]
123 val= PARTITIONS["mapper-root"]
124 val= PARTITIONS["mapper-swap"]
125 val= PARTITIONS["mapper-vservers"]
126 except KeyError, part:
127 log.write( "Missing partition in PARTITIONS: %s\n" % part )
131 log.write( "Setting local time to UTC\n" )
132 utils.sysexec( "chroot %s ln -sf /usr/share/zoneinfo/UTC /etc/localtime" % \
136 log.write( "Enabling ntp at boot\n" )
137 utils.sysexec( "chroot %s chkconfig ntpd on" % SYSIMG_PATH, log )
139 log.write( "Creating system directory %s\n" % PLCONF_DIR )
140 if not utils.makedirs( "%s/%s" % (SYSIMG_PATH,PLCONF_DIR) ):
141 log.write( "Unable to create directory\n" )
145 log.write( "Writing network configuration\n" )
146 write_network_configuration( vars, log )
148 # write out the modprobe.conf file for the system. make sure
149 # the order of the ethernet devices are listed in the same order
150 # as the boot cd loaded the modules. this is found in /tmp/loadedmodules
151 # ultimately, the order will only match the boot cd order if
152 # the kernel modules have the same name - which should be true for the later
153 # version boot cds because they use the same kernel version.
154 # older boot cds use a 2.4.19 kernel, and its possible some of the network
155 # module names have changed, in which case the system might not boot
156 # if the network modules are activated in a different order that the
158 log.write( "Writing /etc/modprobe.conf\n" )
159 write_modprobeconf_file( vars, log )
161 # dump the modprobe.conf file to the log (not to screen)
162 log.write( "Contents of new modprobe.conf file:\n" )
163 modulesconf_file= file("%s/etc/modprobe.conf" % SYSIMG_PATH, "r" )
164 contents= modulesconf_file.read()
165 log.write( contents + "\n" )
166 modulesconf_file.close()
167 modulesconf_file= None
168 log.write( "End contents of new modprobe.conf file.\n" )
170 log.write( "Writing system /etc/fstab\n" )
171 fstab= file( "%s/etc/fstab" % SYSIMG_PATH, "w" )
172 fstab.write( "%s none swap sw 0 0\n" % \
173 PARTITIONS["mapper-swap"] )
174 fstab.write( "%s / ext3 defaults 0 0\n" % \
175 PARTITIONS["mapper-root"] )
176 fstab.write( "%s /vservers ext3 tagxid,defaults 0 0\n" % \
177 PARTITIONS["mapper-vservers"] )
178 fstab.write( "none /proc proc defaults 0 0\n" )
179 fstab.write( "none /dev/shm tmpfs defaults 0 0\n" )
180 fstab.write( "none /dev/pts devpts defaults 0 0\n" )
182 # fstab.write( "none /rcfs rcfs defaults 0 0\n" )
186 log.write( "Writing system /etc/issue\n" )
187 issue= file( "%s/etc/issue" % SYSIMG_PATH, "w" )
188 issue.write( "PlanetLab Node: \\n\n" )
189 issue.write( "Kernel \\r on an \\m\n" )
190 issue.write( "http://www.planet-lab.org\n\n" )
193 log.write( "Setting up authentication (non-ssh)\n" )
194 utils.sysexec( "chroot %s authconfig --nostart --kickstart --enablemd5 " \
195 "--enableshadow" % SYSIMG_PATH, log )
196 utils.sysexec( "sed -e 's/^root\:\:/root\:*\:/g' " \
197 "%s/etc/shadow > %s/etc/shadow.new" % \
198 (SYSIMG_PATH,SYSIMG_PATH), log )
199 utils.sysexec( "chroot %s mv " \
200 "/etc/shadow.new /etc/shadow" % SYSIMG_PATH, log )
201 utils.sysexec( "chroot %s chmod 400 /etc/shadow" % SYSIMG_PATH, log )
203 # if we are setup with dhcp, copy the current /etc/resolv.conf into
204 # the system image so we can run programs inside that need network access
207 method= vars['NETWORK_SETTINGS']['method']
212 utils.sysexec( "cp /etc/resolv.conf %s/etc/" % SYSIMG_PATH, log )
214 # the kernel rpm should have already done this, so don't fail the
215 # install if it fails
216 log.write( "Mounting /proc in system image\n" )
217 utils.sysexec_noerr( "mount -t proc proc %s/proc" % SYSIMG_PATH, log )
219 # mkinitrd references both /etc/modprobe.conf and /etc/fstab
220 # as well as /proc/lvm/global. The kernel RPM installation
221 # likely created an improper initrd since these files did not
222 # yet exist. Re-create the initrd here.
223 log.write( "Making initrd\n" )
225 # trick mkinitrd in case the current environment does not have device mapper
227 if not os.path.exists( "%s/%s" % (SYSIMG_PATH,PARTITIONS["mapper-root"]) ):
229 utils.makedirs( "%s/dev/mapper" % SYSIMG_PATH )
230 rootdev= file( "%s/%s" % (SYSIMG_PATH,PARTITIONS["mapper-root"]), "w" )
234 if NODE_MODEL_OPTIONS & SMP_OPT:
236 initrd= os.readlink( "%s/boot/initrd-boot%s" % (SYSIMG_PATH,option) )
237 kernel_version= initrd.replace("initrd-", "").replace(".img", "")
238 utils.removefile( "%s/boot/%s" % (SYSIMG_PATH, initrd) )
239 utils.sysexec( "chroot %s mkinitrd /boot/initrd-%s.img %s" % \
240 (SYSIMG_PATH, kernel_version, kernel_version), log )
242 if fake_root_lvm == 1:
243 utils.removefile( "%s/%s" % (SYSIMG_PATH,PARTITIONS["mapper-root"]) )
245 log.write( "Writing node install version\n" )
246 utils.makedirs( "%s/etc/planetlab" % SYSIMG_PATH )
247 ver= file( "%s/etc/planetlab/install_version" % SYSIMG_PATH, "w" )
248 ver.write( "%s\n" % VERSION )
251 log.write( "Creating ssh host keys\n" )
252 key_gen_prog= "/usr/bin/ssh-keygen"
254 log.write( "Generating SSH1 RSA host key:\n" )
255 key_file= "/etc/ssh/ssh_host_key"
256 utils.sysexec( "chroot %s %s -q -t rsa1 -f %s -C '' -N ''" %
257 (SYSIMG_PATH,key_gen_prog,key_file), log )
258 utils.sysexec( "chmod 600 %s/%s" % (SYSIMG_PATH,key_file), log )
259 utils.sysexec( "chmod 644 %s/%s.pub" % (SYSIMG_PATH,key_file), log )
261 log.write( "Generating SSH2 RSA host key:\n" )
262 key_file= "/etc/ssh/ssh_host_rsa_key"
263 utils.sysexec( "chroot %s %s -q -t rsa -f %s -C '' -N ''" %
264 (SYSIMG_PATH,key_gen_prog,key_file), log )
265 utils.sysexec( "chmod 600 %s/%s" % (SYSIMG_PATH,key_file), log )
266 utils.sysexec( "chmod 644 %s/%s.pub" % (SYSIMG_PATH,key_file), log )
268 log.write( "Generating SSH2 DSA host key:\n" )
269 key_file= "/etc/ssh/ssh_host_dsa_key"
270 utils.sysexec( "chroot %s %s -q -t dsa -f %s -C '' -N ''" %
271 (SYSIMG_PATH,key_gen_prog,key_file), log )
272 utils.sysexec( "chmod 600 %s/%s" % (SYSIMG_PATH,key_file), log )
273 utils.sysexec( "chmod 644 %s/%s.pub" % (SYSIMG_PATH,key_file), log )
279 def write_network_configuration( vars, log ):
281 Write out the network configuration for this machine:
283 /etc/sysconfig/network-scripts/ifcfg-eth0
284 /etc/resolv.conf (if applicable)
285 /etc/sysconfig/network
287 It is assumed the caller mounted the root partition and the vserver partition
288 starting on SYSIMG_PATH - it is not checked here.
290 The values to be used for the network settings are to be set in vars
291 in the variable 'NETWORK_SETTINGS', which is a dictionary
294 Key Used by this function
295 -----------------------------------------------
312 SYSIMG_PATH= vars["SYSIMG_PATH"]
313 if SYSIMG_PATH == "":
314 raise ValueError, "SYSIMG_PATH"
316 except KeyError, var:
317 raise BootManagerException, "Missing variable in vars: %s\n" % var
318 except ValueError, var:
319 raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
323 network_settings= vars['NETWORK_SETTINGS']
325 raise BootManagerException, "No network settings found in vars."
328 hostname= network_settings['hostname']
329 domainname= network_settings['domainname']
330 method= network_settings['method']
331 ip= network_settings['ip']
332 gateway= network_settings['gateway']
333 network= network_settings['network']
334 netmask= network_settings['netmask']
335 dns1= network_settings['dns1']
336 mac= network_settings['mac']
338 raise BootManagerException, "Missing value %s in network settings." % str(e)
342 dns2= network_settings['dns2']
347 log.write( "Writing /etc/hosts\n" )
348 hosts_file= file("%s/etc/hosts" % SYSIMG_PATH, "w" )
349 hosts_file.write( "127.0.0.1 localhost\n" )
350 if method == "static":
351 hosts_file.write( "%s %s.%s\n" % (ip, hostname, domainname) )
356 log.write( "Writing /etc/sysconfig/network-scripts/ifcfg-eth0\n" )
357 eth0_file= file("%s/etc/sysconfig/network-scripts/ifcfg-eth0" %
359 eth0_file.write( "DEVICE=eth0\n" )
360 if method == "static":
361 eth0_file.write( "BOOTPROTO=static\n" )
362 eth0_file.write( "IPADDR=%s\n" % ip )
363 eth0_file.write( "NETMASK=%s\n" % netmask )
364 eth0_file.write( "GATEWAY=%s\n" % gateway )
366 eth0_file.write( "BOOTPROTO=dhcp\n" )
367 eth0_file.write( "DHCP_HOSTNAME=%s\n" % hostname )
369 eth0_file.write( "HWADDR=%s\n" % mac )
370 eth0_file.write( "ONBOOT=yes\n" )
371 eth0_file.write( "USERCTL=no\n" )
375 if method == "static":
376 log.write( "Writing /etc/resolv.conf\n" )
377 resolv_file= file("%s/etc/resolv.conf" % SYSIMG_PATH, "w" )
379 resolv_file.write( "nameserver %s\n" % dns1 )
381 resolv_file.write( "nameserver %s\n" % dns2 )
382 resolv_file.write( "search %s\n" % domainname )
386 log.write( "Writing /etc/sysconfig/network\n" )
387 network_file= file("%s/etc/sysconfig/network" % SYSIMG_PATH, "w" )
388 network_file.write( "NETWORKING=yes\n" )
389 network_file.write( "HOSTNAME=%s.%s\n" % (hostname, domainname) )
390 if method == "static":
391 network_file.write( "GATEWAY=%s\n" % gateway )
397 def write_modprobeconf_file( vars, log, filename = "/etc/modprobe.conf"):
399 write out the system file /etc/modprobe.conf with the current
402 returns a tuple of the number of network driver lines and storage
403 driver lines written as (networkcount,storagecount)
406 # make sure we have this class loaded
407 from systeminfo import systeminfo
410 SYSIMG_PATH= vars["SYSIMG_PATH"]
411 if SYSIMG_PATH == "":
412 raise ValueError, "SYSIMG_PATH"
414 NODE_MODEL_OPTIONS= vars["NODE_MODEL_OPTIONS"]
416 except KeyError, var:
417 raise BootManagerException, "Missing variable in vars: %s\n" % var
418 except ValueError, var:
419 raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
422 # get the kernel version
424 if NODE_MODEL_OPTIONS & SMP_OPT:
426 initrd= os.readlink( "%s/boot/initrd-boot%s" % (SYSIMG_PATH,option) )
427 kernel_version= initrd.replace("initrd-", "").replace(".img", "")
429 sysinfo= systeminfo()
430 sysmods= sysinfo.get_system_modules(SYSIMG_PATH, kernel_version)
432 raise BootManagerException, "Unable to get list of system modules."
437 modulesconf_file= file("%s/%s" % (SYSIMG_PATH,filename), "w" )
440 if type == sysinfo.MODULE_CLASS_SCSI:
441 for a_mod in sysmods[type]:
443 modulesconf_file.write( "alias scsi_hostadapter %s\n" %
446 modulesconf_file.write( "alias scsi_hostadapter%d %s\n" %
448 scsi_count= scsi_count + 1
450 elif type == sysinfo.MODULE_CLASS_NETWORK:
451 for a_mod in sysmods[type]:
452 modulesconf_file.write( "alias eth%d %s\n" %
454 eth_count= eth_count + 1
456 modulesconf_file.close()
457 modulesconf_file= None
459 return (eth_count,scsi_count)