/[gli]/branches/overhaul/src/templates/x86ArchitectureTemplate.py
Gentoo

Contents of /branches/overhaul/src/templates/x86ArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1166 - (hide annotations) (download) (as text)
Sat Dec 17 20:15:00 2005 UTC (12 years, 9 months ago) by codeman
Original Path: trunk/src/templates/x86ArchitectureTemplate.py
File MIME type: text/x-python
File size: 30627 byte(s)
  x86AT: separated out emerge/configure from running of bootloader
  added MBR drive support to lilo.
  these changes will likely not work.
  AT: added setup_and_run_bootloader step.

1 samyron 148 """
2 codeman 851 # Copyright 1999-2005 Gentoo Foundation
3     # This source code is distributed under the terms of version 2 of the GNU
4     # General Public License as published by the Free Software Foundation, a copy
5     # of which can be found in the main directory of this project.
6 samyron 148 Gentoo Linux Installer
7    
8 codeman 1166 $Id: x86ArchitectureTemplate.py,v 1.89 2005/12/17 20:15:00 codeman Exp $
9 samyron 148 Copyright 2004 Gentoo Technologies Inc.
10    
11    
12     This fills in x86 specific functions.
13     """
14    
15 codeman 730 import GLIUtility, string, time
16 samyron 148 from GLIArchitectureTemplate import ArchitectureTemplate
17     from GLIException import *
18 agaffney 225 import parted
19 agaffney 497 import GLIStorageDevice
20 robbat2 651
21     MEGABYTE = 1024 * 1024
22 samyron 148
23     class x86ArchitectureTemplate(ArchitectureTemplate):
24 agaffney 497 def __init__(self,configuration=None, install_profile=None, client_controller=None):
25 samyron 148 ArchitectureTemplate.__init__(self, configuration, install_profile, client_controller)
26     self._architecture_name = 'x86'
27 codeman 282 self._kernel_bzimage = "arch/i386/boot/bzImage"
28 codeman 1083
29 codeman 201 def install_bootloader(self):
30     "Installs and configures bootloader"
31     #
32     # THIS IS ARCHITECTURE DEPENDANT!!!
33     # This is the x86 way.. it uses grub
34 robbat2 740
35     bootloader_pkg = self._install_profile.get_boot_loader_pkg()
36    
37     # first install bootloader
38     if bootloader_pkg and bootloader_pkg.lower() != "none":
39     exitstatus = self._emerge(bootloader_pkg)
40 agaffney 1009 if not GLIUtility.exitsuccess(exitstatus):
41 codeman 201 raise GLIException("BootLoaderEmergeError", 'fatal', 'install_bootloader', "Could not emerge bootloader!")
42 robbat2 740 else:
43     self._logger.log("Emerged the selected bootloader.")
44 codeman 201
45 robbat2 740 # now configure said bootloader
46     # null boot-loader first
47     if bootloader_pkg.lower() == "none":
48     return
49     elif "grub" in bootloader_pkg: # this catches 'grub-static' as well as '=sys-boot/grub-0.95*'
50     self._configure_grub()
51     elif "lilo" in bootloader_pkg:
52     self._configure_lilo()
53     # probably should add in some more bootloaders
54     # dvhtool, raincoat, netboot, gnu-efi, cromwell, syslinux, psoload
55 codeman 201 else:
56 robbat2 740 raise GLIException("BootLoaderError",'fatal','install_bootloader',"Don't know how to configure this bootloader: "+bootloader_pkg)
57 codeman 201
58 agaffney 220 def _sectors_to_megabytes(self, sectors, sector_bytes=512):
59 robbat2 651 return float((float(sectors) * sector_bytes)/ float(MEGABYTE))
60 agaffney 220
61 agaffney 225 def _add_partition(self, disk, start, end, type, fs):
62     types = { 'primary': parted.PARTITION_PRIMARY, 'extended': parted.PARTITION_EXTENDED, 'logical': parted.PARTITION_LOGICAL }
63     fsTypes = {}
64     fs_type = parted.file_system_type_get_next ()
65     while fs_type:
66     fsTypes[fs_type.name] = fs_type
67     fs_type = parted.file_system_type_get_next (fs_type)
68     fstype = None
69     if fs: fstype = fsTypes[fs]
70     newpart = disk.partition_new(types[type], fstype, start, end)
71     constraint = disk.dev.constraint_any()
72     disk.add_partition(newpart, constraint)
73 agaffney 220
74 agaffney 225 def partition(self):
75 agaffney 220 parts_old = {}
76 agaffney 596 tmp_parts_new = self._install_profile.get_partition_tables()
77     parts_new = {}
78     for device in tmp_parts_new:
79     parts_new[device] = tmp_parts_new[device].get_install_profile_structure()
80 agaffney 497 detected_devices = GLIStorageDevice.detect_devices()
81     for device in detected_devices:
82     tmpdevice = GLIStorageDevice.Device(device)
83     tmpdevice.set_partitions_from_disk()
84     parts_old[device] = tmpdevice.get_install_profile_structure()
85 agaffney 220
86 agaffney 497 for device in parts_new.keys():
87     # Skip this device in parts_new if device isn't detected on current system
88     if not device in detected_devices:
89     self._logger.log("There is no physical device " + device + " detected to match the entry in the install profile...skipping")
90     continue
91 agaffney 220
92 agaffney 497 # Check to see if the old and new partition table structures are the same
93     table_changed = 0
94     for part in parts_new[device]:
95 agaffney 501 if not part in parts_old[device]:
96     table_changed = 1
97     break
98 agaffney 497 oldpart = parts_old[device][part]
99     newpart = parts_new[device][part]
100     if oldpart['type'] == newpart['type'] and oldpart['start'] == newpart['start'] and oldpart['end'] == newpart['end'] and newpart['format'] == False:
101     continue
102     else:
103     table_changed = 1
104     break
105     # Skip this device if they are they same
106     if not table_changed:
107     self._logger.log("Partition table for " + device + " is unchanged...skipping")
108     continue
109    
110     # Create pyparted objects for this device
111     parted_dev = parted.PedDevice.get(device)
112 agaffney 691 try:
113     parted_disk = parted.PedDisk.new(parted_dev)
114     except:
115     parted_disk = parted_dev.disk_new_fresh(parted.disk_type_get((tmp_parts_new[device].get_disklabel() or GLIStorageDevice.archinfo[self._architecture_name]['disklabel'])))
116 agaffney 497 new_part_list = parts_new[device].keys()
117     new_part_list.sort()
118     device_sectors = parted_dev.length
119    
120     # Iterate through new partitions and check for 'origminor' and 'format' == False
121     for part in parts_new[device].keys():
122     tmppart_new = parts_new[device][part]
123     if not tmppart_new['origminor'] or tmppart_new['format']: continue
124 agaffney 498 tmppart_old = parts_old[device][tmppart_new['origminor']]
125 agaffney 497 # This partition in parts_new corresponds with an existing partitions, so we save the start/end sector and flags
126     for flag in range(0, 10):
127     # The 10 is completely arbitrary. If flags seem to be missed, this number should be increased
128     parted_part = parted_disk.get_partition(part)
129     if not parted_part: break
130     if parted_part.is_flag_available(flag) and parted_part.get_flag(flag):
131     if not "flags" in tmppart_new: tmppart_new['flags'] = []
132     tmppart_new['flags'].append(flag)
133     if tmppart_old['mb'] == tmppart_new['mb']:
134     tmppart_new['start'] = tmppart_old['start']
135     tmppart_new['end'] = tmppart_old['end']
136     else:
137     tmppart_new['start'] = tmppart_old['start']
138     tmppart_new['end'] = 0
139    
140     # if parts_new[dev][parts_new[dev].keys()[0]]['mb']:
141     # # Change MB/%/* into sectors
142     # total_sectors = parted_dev.length
143     # sector_size = parted_dev.sector_size
144     # total_mb = float(total_sectors * sector_size) / MEGABYTE
145     # start_sector = 0
146     # mb_left = total_mb
147     # for part in parts_new[dev]:
148     # tmppart = parts_new[dev][part]
149     # if tmppart['type'] == "extended": continue
150     # if tmppart['mb'][-1] == "%":
151     # tmppart['mb'] = float(tmppart['mb'][:-1]) / 100 * total_mb
152     # mb_left = mb_left - float(tmppart['mb'])
153     # partlist = parts_new.keys()
154     # partlist.sort()
155     # for part in partlist:
156     # if part > 4: continue
157     # tmppart = parts_new[dev][part]
158     # if tmppart['type'] == "extended":
159     # for part_log in partlist:
160     # if part < 5: continue
161     # tmppart_log = parts_new[dev][part_log]
162     # if not tmppart['start']:
163     # tmppart['start'] = start_sector
164     # if tmppart_log['mb'] == "*":
165     # tmppart_log['mb'] = mb_left
166 agaffney 639 # part_bytes = long(tmppart_log['mb'] * MEGABYTE)
167 agaffney 497 # part_sectors = round(part_bytes / sector_size)
168     # tmppart_log['start'] = start_sector
169     # tmppart_log['end'] = start_sector + part_sectors - 1
170     # tmppart['end'] = tmppart_log['end']
171     # start_sector = start_sector + part_sectors
172     # continue
173     # if tmppart['mb'] == "*":
174     # tmppart['mb'] = mb_left
175 agaffney 639 # part_bytes = long(tmppart['mb'] * MEGABYTE)
176 agaffney 497 # part_sectors = round(part_bytes / sector_size)
177     # tmppart['start'] = start_sector
178     # tmppart['end'] = start_sector + part_sectors - 1
179     # start_sector = start_sector + part_sectors
180     # else:
181    
182 agaffney 220 # First pass to delete old partitions that aren't resized
183 agaffney 497 self._logger.log("partitioning: Processing " + device + "...")
184     for part in parts_old[device]:
185     oldpart = parts_old[device][part]
186     # Replace 'x86' with call function to get arch from CC
187     if (GLIStorageDevice.archinfo['x86']['extended'] and part > 4) or oldpart['type'] == "free": continue
188 agaffney 278 delete = 0
189 agaffney 228 if oldpart['type'] == "extended":
190     logical_to_resize = 0
191 agaffney 497 for part_log in parts_old[device]:
192     if part_log < 5 or parts_old[device][part_log]['type'] == "free": continue
193 agaffney 278 delete_log = 0
194 agaffney 497 for new_part in parts_new[device]:
195 agaffney 228 if new_part < 5: continue
196 agaffney 497 tmppart = parts_new[device][new_part]
197     # This partition is unchanged in the new layout
198     if tmppart['origminor'] == part_log and tmppart['start'] and tmppart['end']:
199 codeman 427 self._logger.log(" Deleting old minor " + str(part_log) + " to be recreated later")
200 agaffney 278 delete_log = 1
201 agaffney 228 break
202 agaffney 497 # This partition is resized with the data preserved in the new layout
203     if tmppart['origminor'] == part_log and tmppart['start'] and not tmppart['end']:
204 codeman 427 self._logger.log(" Ignoring old minor " + str(part_log) + " to resize later")
205 agaffney 278 logical_to_resize = 1
206 agaffney 228 break
207 agaffney 497 if delete_log:
208 codeman 427 self._logger.log(" No match found...deleting partition " + str(part_log))
209 agaffney 228 parted_disk.delete_partition(parted_disk.get_partition(part_log))
210     if not logical_to_resize:
211 agaffney 497 self._logger.log(" Deleting extended partition with minor " + str(part))
212 agaffney 228 parted_disk.delete_partition(parted_disk.get_partition(part))
213     continue
214 agaffney 497 for new_part in parts_new[device]:
215     tmppart = parts_new[device][new_part]
216     if tmppart['origminor'] == part and tmppart['start'] and tmppart['end']:
217 codeman 427 self._logger.log(" Deleting old minor " + str(part) + " to be recreated later")
218 agaffney 278 delete = 1
219 agaffney 220 break
220 agaffney 497 if tmppart['origminor'] == part and tmppart['start'] and not tmppart['end']:
221 codeman 427 self._logger.log(" Ignoring old minor " + str(part) + " to resize later")
222 agaffney 220 break
223 agaffney 497 if delete:
224 codeman 427 self._logger.log(" No match found...deleting partition " + str(part))
225 agaffney 225 parted_disk.delete_partition(parted_disk.get_partition(part))
226     parted_disk.commit()
227 agaffney 497
228 agaffney 220 # Second pass to resize old partitions that need to be resized
229 codeman 427 self._logger.log("Partitioning: Second pass...")
230 agaffney 497 for part in parts_old[device]:
231     oldpart = parts_old[device][part]
232     for new_part in parts_new[device]:
233     tmppart = parts_new[device][new_part]
234     if tmppart['origminor'] == part and tmppart['start'] and not tmppart['end']:
235 codeman 427 self._logger.log(" Resizing old minor " + str(part) + " from " + str(oldpart['start']) + "-" + str(oldpart['end'])+ " to " + str(tmppart['start']) + "-" + str(tmppart['end']))
236 agaffney 220 type = tmppart['type']
237     minor = part
238 agaffney 230 start = tmppart['start']
239 agaffney 497 # Replace 512 with code to retrieve bytes per sector for device
240 agaffney 639 end = start + (long(tmppart['mb']) * MEGABYTE / 512)
241 agaffney 497 for i in new_part_list:
242     if i <= new_part: continue
243     if parts_new[device][i]['start'] and end >= parts_new[device][i]['start']:
244     end = parts_new[device][i]['start'] - 1
245     elif end >= device_sectors:
246     end = device_sectors - 1
247     break
248 agaffney 220 if type == "ext2" or type == "ext3":
249     total_sectors = end - start + 1
250 agaffney 231 ret = GLIUtility.spawn("resize2fs " + device + str(minor) + " " + str(total_sectors) + "s")
251     if ret: # Resize error
252 agaffney 497 raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + device + str(minor))
253 agaffney 220 elif type == "ntfs":
254     total_sectors = end - start + 1
255 agaffney 639 total_bytes = long(total_sectors) * 512
256 agaffney 231 ret = GLIUtility.spawn("ntfsresize --size " + str(total_bytes) + " " + device + str(minor))
257     if ret: # Resize error
258 agaffney 497 raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + device + str(minor))
259 agaffney 918 elif type == "linux-swap" or type == "fat32" or type == "fat16":
260 agaffney 230 parted_fs = parted_disk.get_partition(part).geom.file_system_open()
261     resize_constraint = parted_fs.get_resize_constraint()
262     if end < (start + resize_constraint.min_size) or start != resize_constraint.start_range.start:
263 agaffney 497 raise GLIException("PartitionError", 'fatal', 'partition', "New size specified for " + device + str(minor) + " is not within allowed boundaries")
264 agaffney 230 new_geom = resize_constraint.start_range.duplicate()
265     new_geom.set_start(start)
266     new_geom.set_end(end)
267 agaffney 231 try:
268     parted_fs.resize(new_geom)
269     except:
270 agaffney 497 raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + device + str(minor))
271 codeman 427 self._logger.log(" Deleting old minor " + str(part) + " to be recreated in 3rd pass")
272 agaffney 225 parted_disk.delete_partition(parted_disk.get_partition(part))
273 agaffney 220 break
274 agaffney 229 parted_disk.delete_all()
275 agaffney 225 parted_disk.commit()
276 agaffney 497
277 agaffney 220 # Third pass to create new partition table
278 agaffney 497 self._logger.log("Partitioning: Third pass....creating partitions")
279     start = 0
280 agaffney 507 end = 0
281 agaffney 506 extended_start = 0
282 agaffney 497 extended_end = 0
283 agaffney 501 self._logger.log(" Drive has " + str(device_sectors) + " sectors")
284 agaffney 506 # for part in parts_new[device]:
285     for part in new_part_list:
286 agaffney 497 newpart = parts_new[device][part]
287 agaffney 501 self._logger.log(" Partition " + str(part) + " has " + str(newpart['mb']) + "MB")
288 agaffney 639 part_sectors = long(newpart['mb']) * MEGABYTE / 512
289 agaffney 507 end = start + part_sectors
290 agaffney 497 for i in new_part_list:
291     if i <= part: continue
292     if parts_new[device][i]['start'] and end >= parts_new[device][i]['start']:
293     end = parts_new[device][i]['start'] - 1
294     break
295 agaffney 639 # cap to end of device
296 agaffney 503 if end >= device_sectors:
297     end = device_sectors - 1
298 agaffney 639 # now the actual creation
299 agaffney 497 if newpart['type'] == "free":
300     # Nothing to be done for this type
301     pass
302     elif newpart['type'] == "extended":
303 agaffney 501 self._logger.log(" Adding extended partition " + str(part) + " from " + str(start) + " to " + str(end))
304     self._add_partition(parted_disk, start, end, "extended", "")
305 agaffney 506 extended_start = start
306     extended_end = end
307 agaffney 505 elif part < 5 or not GLIStorageDevice.archinfo['x86']['extended']:
308 agaffney 501 self._logger.log(" Adding primary partition " + str(part) + " from " + str(start) + " to " + str(end))
309     self._add_partition(parted_disk, start, end, "primary", newpart['type'])
310 agaffney 497 elif GLIStorageDevice.archinfo['x86']['extended'] and part > 4:
311 agaffney 506 if start >= extended_end:
312     start = extended_start + 1
313 agaffney 507 end = start + part_sectors
314 agaffney 497 if part == new_part_list[-1] and end > extended_end:
315     end = extended_end
316 agaffney 508 self._logger.log(" Adding logical partition " + str(part) + " from " + str(start) + " to " + str(end))
317 agaffney 501 self._add_partition(parted_disk, start, end, "logical", newpart['type'])
318 agaffney 497 if "flags" in newpart:
319 agaffney 589 for flag in newpart['flags']:
320     if parted_disk.get_partition(part).is_flag_available(flag):
321 agaffney 798 parted_disk.get_partition(part).set_flag(flag, True)
322 agaffney 639 # write to disk
323 agaffney 264 parted_disk.commit()
324 robbat2 740
325     # force rescan of partition table
326     # Should not be needed with current stuff
327     #ret = GLIUtility.spawn("partprobe "+device, logfile=self._compile_logfile, append_log=True)
328    
329 agaffney 639 # now format the partition
330 agaffney 691 # extended and 'free' partitions should never be formatted
331     if newpart['format'] and newpart['type'] not in ('extended', 'free'):
332 agaffney 724 devnode = device + str(int(part))
333 robbat2 648 errormsg = "could't create %s filesystem on %s" % (newpart['type'],devnode)
334     # if you need a special command and
335 robbat2 649 # some base options, place it here.
336     if newpart['type'] == 'linux-swap':
337     cmdname = 'mkswap'
338 agaffney 918 elif newpart['type'] == 'fat16':
339     cmdname = 'mkfs.vfat -F 16'
340 robbat2 649 elif newpart['type'] == 'fat32':
341     cmdname = 'mkfs.vfat -F 32'
342     elif newpart['type'] == 'ntfs':
343     cmdname = 'mkntfs'
344     # All of these types need a -f as they
345     # ask for confirmation of format
346     elif newpart['type'] in ('xfs','jfs','reiserfs'):
347     cmdname = 'mkfs.%s -f' % (newpart['type'])
348     # add common partition stuff here
349     elif newpart['type'] in ('ext2','ext3'):
350     cmdname = 'mkfs.%s' % (newpart['type'])
351 robbat2 648 else: # this should catch everything else
352 robbat2 649 raise GLIException("PartitionFormatError", 'fatal', 'partition',"Unknown partition type "+newpart['type'])
353 robbat2 741
354     # force a stat of the device so that it
355     # is created on demand. (At least if I
356     # recall how udev works... - robbat2).
357 robbat2 746 # sleep a bit first
358     time.sleep(1)
359     # now sleep until it exists
360 agaffney 869 # while not GLIUtility.is_file(devnode):
361     # self._logger.log("Waiting for device node "+devnode+" to exist...")
362     # time.sleep(1)
363 robbat2 741 # one bit of extra sleep is needed, as there is a blip still
364 agaffney 869 # time.sleep(1)
365 robbat2 741
366 agaffney 869 tries = 0
367 agaffney 974 while tries < 4:
368 agaffney 869 # now the actual command
369     cmd = "%s %s %s" % (cmdname,newpart['mkfsopts'],devnode)
370     self._logger.log(" Formatting partition %s as %s with: %s" % (str(part),newpart['type'],cmd))
371     # If logging is not done, then you get errors:
372     # PartitionFormatError :FATAL: partition: could't create ext2 filesystem on /dev/hda1
373     #if GLIUtility.spawn(cmd):
374     #if GLIUtility.spawn(cmd,append_log=True,logfile='/var/log/install-mkfs.log'):
375     ret = GLIUtility.spawn(cmd, logfile=self._compile_logfile, append_log=True)
376     if not GLIUtility.exitsuccess(ret):
377     tries += 1
378 agaffney 876 self._logger.log("Try %d failed formatting partition %s...waiting 5 seconds" % (tries, devnode))
379     time.sleep(5)
380 agaffney 869 else:
381     break
382     if tries == 3:
383 robbat2 648 raise GLIException("PartitionFormatError", 'fatal', 'partition', errormsg)
384 agaffney 501 start = end + 1
385 agaffney 264
386 robbat2 740 def _configure_grub(self):
387 codeman 1166 self.build_mode = self._install_profile.get_kernel_build_method()
388     self._gather_grub_drive_info()
389 codeman 235 root = self._chroot_dir
390 codeman 1077 exitstatus2, kernel_names = GLIUtility.spawn("ls -1 --color=no " + root + "/boot/kernel-*", return_output=True)
391 codeman 1087 self._logger.log("Output of Kernel Names:\n"+kernel_names)
392 codeman 825 if not GLIUtility.exitsuccess(exitstatus2):
393     raise GLIException("BootloaderError", 'fatal', '_configure_grub', "Error listing the kernels in /boot")
394 codeman 1166 if self.build_mode == "genkernel" or self._install_profile.get_kernel_source_pkg() == "livecd-kernel":
395 codeman 1077 exitstatus3, initrd_names = GLIUtility.spawn("ls -1 --color=no " + root + "/boot/init*", return_output=True)
396 codeman 1087 self._logger.log("Output of Initrd Names:\n"+initrd_names)
397 codeman 825 if not GLIUtility.exitsuccess(exitstatus3):
398 codeman 1077 raise GLIException("BootloaderError", 'fatal', '_configure_grub', "Error listing the initrds")
399 codeman 427 self._logger.log("Bootloader: the three information gathering commands have been run")
400 codeman 235
401 codeman 1077 if not kernel_names[0]:
402 robbat2 740 raise GLIException("BootloaderError", 'fatal', '_configure_grub',"Error: We have no kernel in /boot to put in the grub.conf file!")
403 codeman 1077
404 codeman 235 #-------------------------------------------------------------
405     #OK, now that we have all the info, let's build that grub.conf
406     newgrubconf = ""
407     newgrubconf += "default 0\ntimeout 30\n"
408 codeman 1166 if self.foundboot: #we have a /boot
409     newgrubconf += "splashimage=(" + self.grub_boot_drive + "," + self.grub_boot_minor + ")/grub/splash.xpm.gz\n"
410 codeman 235 else: #we have / and /boot needs to be included
411 codeman 1166 newgrubconf += "splashimage=(" + self.grub_boot_drive + "," + self.grub_boot_minor + ")/boot/grub/splash.xpm.gz\n"
412 codeman 1077 if self._install_profile.get_bootloader_kernel_args():
413     bootloader_kernel_args = self._install_profile.get_bootloader_kernel_args()
414     else: bootloader_kernel_args = ""
415    
416 agaffney 1112 kernel_names = map(string.strip, kernel_names.strip().split("\n"))
417     initrd_names = map(string.strip, initrd_names.strip().split("\n"))
418 agaffney 1113 grub_kernel_name = kernel_names[-1].split(root)[-1]
419     if initrd_names: grub_initrd_name = initrd_names[-1].split(root)[-1]
420     # for i in range(len(kernel_names)):
421     # grub_kernel_name = kernel_names[i].split(root)[-1]
422     # for i in range(len(initrd_names)): #this should be okay if blank.
423     # grub_initrd_name = initrd_names[i].split(root)[-1]
424 codeman 1077 #i think this means take the last one it finds.. i.e. the newest.
425    
426 codeman 235 newgrubconf += "title=Gentoo Linux\n"
427 codeman 1166 newgrubconf += "root (" + self.grub_boot_drive + "," + self.grub_boot_minor + ")\n"
428     if self.build_mode != "genkernel" and self._install_profile.get_kernel_source_pkg() != "livecd-kernel": #using CUSTOM kernel
429     if self.foundboot:
430     newgrubconf += "kernel " + grub_kernel_name[5:] + " root="+self.root_device+self.root_minor+"\n"
431 codeman 286 else:
432 codeman 1166 newgrubconf += "kernel /boot"+ grub_kernel_name[5:] + " root="+self.root_device+self.root_minor+"\n"
433 codeman 734 else: #using genkernel so it has an initrd.
434 codeman 1166 if self.foundboot:
435 codeman 286 newgrubconf += "kernel " + grub_kernel_name[5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
436 codeman 1166 newgrubconf += self.root_device + self.root_minor + " " + bootloader_kernel_args + "\n"
437 codeman 286 newgrubconf += "initrd " + grub_initrd_name[5:] + "\n"
438     else:
439     newgrubconf += "kernel /boot" + grub_kernel_name[5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
440 codeman 1166 newgrubconf += self.root_device + self.root_minor + " " + bootloader_kernel_args + "\n"
441 codeman 286 newgrubconf += "initrd /boot" + grub_initrd_name[5:] + "\n"
442 codeman 235
443     #now make the grub.conf file
444     file_name = root + "/boot/grub/grub.conf"
445     try:
446     shutil.move(file_name, file_name + ".OLDdefault")
447     except:
448     pass
449     f = open(file_name, 'w')
450     f.writelines(newgrubconf)
451     f.close()
452 codeman 1099 self._logger.log("Grub installed and configured. Contents of grub.conf:\n"+newgrubconf)
453 codeman 1166 self._logger.log("Grub has not yet been run. If a normal install, it will now be run.")
454    
455     def _gather_grub_drive_info(self):
456     self.boot_minor = ""
457     self.boot_device = ""
458     self.root_device = ""
459     self.root_minor = ""
460     self.mbr_device = ""
461     self.grub_root_minor = ""
462     self.grub_boot_minor = ""
463     self.grub_boot_drive = ""
464     self.grub_root_drive = ""
465     self.grub_mbr_drive = ""
466 codeman 235 minornum = 0
467     #Assign root to the root mount point to make lines more readable
468     root = self._chroot_dir
469 codeman 1166
470    
471     self.foundboot = False
472 codeman 235 parts = self._install_profile.get_partition_tables()
473     for device in parts:
474 agaffney 805 tmp_partitions = parts[device].get_install_profile_structure()
475 agaffney 601 for partition in tmp_partitions:
476     mountpoint = tmp_partitions[partition]['mountpoint']
477 codeman 235 if (mountpoint == "/boot"):
478 codeman 1166 self.foundboot = True
479     if (( (mountpoint == "/") and (not self.foundboot) ) or (mountpoint == "/boot")):
480     self.boot_minor = str(int(tmp_partitions[partition]['minor']))
481     self.grub_boot_minor = str(int(tmp_partitions[partition]['minor']) - 1)
482     self.boot_device = device
483     self.mbr_device = device
484 codeman 235 if mountpoint == "/":
485 codeman 1166 self.root_minor = str(int(tmp_partitions[partition]['minor']))
486     self.grub_root_minor = str(int(tmp_partitions[partition]['minor']) - 1)
487     self.root_device = device
488     #RESET the boot device if one is stored already
489     if self._install_profile.get_boot_device():
490     self.mbr_device = self._install_profile.get_boot_device()
491     self._logger.log("Found a mbr device: " + self.mbr_device)
492    
493     self.grub_boot_drive = self._map_device_to_grub_device(self.boot_device)
494     self.grub_root_drive = self._map_device_to_grub_device(self.root_device)
495     self.grub_mbr_drive = self._map_device_to_grub_device(self.mbr_device)
496    
497     if (not self.grub_root_drive) or (not self.grub_boot_drive):
498     raise GLIException("BootloaderError", 'fatal', '_gather_grub_drive_info',"Couldn't find the drive num in the list from the device.map")
499    
500     def _configure_lilo(self):
501     self.build_mode = self._install_profile.get_kernel_build_method()
502     self._gather_lilo_drive_info()
503     root = self._chroot_dir
504 codeman 235 exitstatus0 = GLIUtility.spawn("ls "+root+"/boot/kernel-* > "+file_name3)
505 codeman 825 if (exitstatus0 != 0):
506     raise GLIException("BootloaderError", 'fatal', '_configure_lilo', "Could not list kernels in /boot or no kernels found.")
507 codeman 1166 if self.build_mode == "genkernel" or self._install_profile.get_kernel_source_pkg() == "livecd-kernel":
508 codeman 825 exitstatus1 = GLIUtility.spawn("ls "+root+"/boot/init* >> "+file_name3)
509     if (exitstatus1 != 0):
510     raise GLIException("BootloaderError", 'fatal', '_configure_lilo', "Could not list initrds in /boot")
511 codeman 235 g = open(file_name3)
512     kernel_name = g.readlines()
513     g.close()
514     if not kernel_name[0]:
515 robbat2 740 raise GLIException("BootloaderError", 'fatal', '_configure_lilo',"Error: We have no kernel in /boot to put in the grub.conf file!")
516 codeman 235 kernel_name = map(string.strip, kernel_name)
517     kernel_name[0] = kernel_name[0].split(root)[1]
518     kernel_name[1] = kernel_name[1].split(root)[1]
519 agaffney 461 if self._install_profile.get_bootloader_kernel_args(): bootloader_kernel_args = self._install_profile.get_bootloader_kernel_args()
520     else: bootloader_kernel_args = ""
521 codeman 235 #-------------------------------------------------------------
522     #time to build the lilo.conf
523     newliloconf = ""
524     if self._install_profile.get_boot_loader_mbr():
525 codeman 1166 newliloconf += "boot="+self.mbr_device+" # Install LILO in the MBR \n"
526 codeman 235 else:
527 codeman 1166 newliloconf += "boot="+self.boot_device+self.boot_minor+" # Install LILO in the MBR \n"
528 codeman 235 newliloconf += "prompt # Give the user the chance to select another section\n"
529     newliloconf += "timeout=50 # Wait 5 (five) seconds before booting the default section\n"
530     newliloconf += "default=gentoo # When the timeout has passed, boot the \"gentoo\" section\n"
531     newliloconf += "# Only if you use framebuffer. Otherwise remove the following line:\n"
532     if not self._install_profile.get_kernel_bootsplash():
533     newliloconf += "#"
534     newliloconf += "vga=788 # Framebuffer setting. Adjust to your own will\n"
535 codeman 237 newliloconf += "image=/boot"+kernel_name[0][5:]+" \n"
536 codeman 825 newliloconf += " label=gentoo \n read-only \n"
537 codeman 1166 if self.build_mode != "genkernel" and self._install_profile.get_kernel_source_pkg() != "livecd-kernel":
538     newliloconf += " root="+self.root_device+self.root_minor+" \n"
539 codeman 825 if bootloader_kernel_args:
540     newliloconf += " append=\""+bootloader_kernel_args+"\" \n"
541     else:
542     newliloconf += " root=/dev/ram0 \n"
543 codeman 1166 newliloconf += " append=\"init=/linuxrc ramdisk=8192 real_root="+self.root_device+self.root_minor + " " + bootloader_kernel_args + "\" \n"
544 agaffney 964 newliloconf += " initrd=/boot"+kernel_name[1][5:] + "\n\n"
545 codeman 248 newliloconf = self._lilo_add_windows(newliloconf)
546 codeman 235 #now make the lilo.conf file
547     file_name = root + "/etc/lilo.conf"
548     try:
549     shutil.move(file_name, file_name + ".OLDdefault")
550     except:
551     pass
552     f = open(file_name, 'w')
553     f.writelines(newliloconf)
554     f.close()
555 codeman 1166 self._logger.log("Lilo installed and configured. Not run yet.")
556 codeman 314
557 codeman 1166 def _gather_lilo_drive_info(self):
558     self.boot_device = ""
559     self.boot_minor = ""
560     self.root_device = ""
561     self.root_minor = ""
562     self.mbr_device = ""
563     minornum = 0
564     #Assign root to the root mount point to make lines more readable
565     root = self._chroot_dir
566     file_name3 = root + "/boot/kernel_name"
567     self.foundboot = False
568     parts = self._install_profile.get_partition_tables()
569     for device in parts:
570     tmp_partitions = parts[device].get_install_profile_structure()
571     for partition in tmp_partitions:
572     mountpoint = tmp_partitions[partition]['mountpoint']
573     if (mountpoint == "/boot"):
574     self.foundboot = True
575     if (( (mountpoint == "/") and (not self.foundboot) ) or (mountpoint == "/boot")):
576     self.boot_minor = str(int(tmp_partitions[partition]['minor']))
577     self.boot_device = device
578     self.mbr_device = device
579     if mountpoint == "/":
580     self.root_minor = str(int(tmp_partitions[partition]['minor']))
581     self.root_device = device
582     #RESET the boot device if one is stored already
583     if self._install_profile.get_boot_device():
584     self.mbr_device = self._install_profile.get_boot_device()
585     self._logger.log("Found a mbr device: " + self.mbr_device)
586    
587 codeman 248 def _lilo_add_windows(self, newliloconf):
588     parts = self._install_profile.get_partition_tables()
589     for device in parts:
590 agaffney 809 tmp_partitions = parts[device].get_install_profile_structure()
591 agaffney 601 for partition in tmp_partitions:
592     if (tmp_partitions[partition]['type'] == "vfat") or (tmp_partitions[partition]['type'] == "ntfs"):
593     newliloconf += "other="+device+str(int(tmp_partitions[partition]['minor']))+"\n"
594     newliloconf += "label=Windows_P"+str(int(tmp_partitions[partition]['minor']))+"\n\n"
595 codeman 263 return newliloconf
596 codeman 1077
597     def _map_device_to_grub_device(self, device):
598     file_name = self._chroot_dir + "/boot/grub/glidevice.map"
599     #If we can't find it, make it. If we STILL can't find it. die.
600     if not GLIUtility.is_file(file_name):
601     exitstatus1 = GLIUtility.spawn("echo quit | "+ self._chroot_dir+"/sbin/grub --no-floppy --device-map="+file_name)
602     if not GLIUtility.is_file(file_name):
603     raise GLIException("BootloaderError", 'fatal', '_configure_grub', "Error making the new device map.")
604     """
605     read the device map. sample looks like this:
606     (fd0) /dev/floppy/0
607     (hd0) /dev/sda
608     (hd1) /dev/hda
609     (hd2) /dev/hdb
610     """
611    
612     # Search for the key
613 codeman 1086 f = open(file_name) #open the device map
614 codeman 1077 file = f.readlines()
615     f.close()
616     for i in range(len(file)):
617     if file[i][6:-1] == device:
618     return file[i][1:4]
619     raise GLIException("BootloaderError", 'fatal', '_map_device_to_grub_device', "ERROR, could not map"+device+" to anything in the device map")
620 codeman 1166
621     def setup_and_run_bootloader(self):
622     bootloader_pkg = self._install_profile.get_boot_loader_pkg()
623     if bootloader_pkg.lower() == "none":
624     return
625     elif "grub" in bootloader_pkg: # this catches 'grub-static' as well as '=sys-boot/grub-0.95*'
626     self._setup_grub()
627     elif "lilo" in bootloader_pkg:
628     self._setup_lilo()
629     # probably should add in some more bootloaders
630     # dvhtool, raincoat, netboot, gnu-efi, cromwell, syslinux, psoload
631     else:
632     raise GLIException("BootLoaderError",'fatal','setup_and_run_bootloader',"Don't know how to configure this bootloader: "+bootloader_pkg)
633    
634     def _setup_grub(self):
635     #-------------------------------------------------------------
636     #OK, now that the file is built. Install grub.
637     #cp /proc/mounts /etc/mtab
638     #grub-install --root-directory=/boot /dev/hda
639     #shutil.copy("/proc/mounts",root +"/etc/mtab")
640     self._gather_grub_drive_info()
641     grubinstallstring = "echo -en 'root ("+self.grub_boot_drive + "," + self.grub_boot_minor + ")\n"
642     if not self._install_profile.get_boot_loader_mbr():
643     grubinstallstring +="setup ("+self.grub_boot_drive + "," + self.grub_boot_minor + ")\n"
644     else:
645     grubinstallstring +="setup ("+self.grub_mbr_drive+")\n"
646     grubinstallstring += "quit\n' | "+self._chroot_dir+"/sbin/grub --batch --no-floppy"
647     if self._debug: self._logger.log("DEBUG: _configure_grub(): Grub install string: " + grubinstallstring)
648     exitstatus = GLIUtility.spawn(grubinstallstring, logfile=self._compile_logfile, append_log=True)
649     if not GLIUtility.exitsuccess(exitstatus):
650     raise GLIException("GrubInstallError", 'fatal', '_setup_grub', "Could not install grub!")
651     self._logger.log("Bootloader: grub has been installed!")
652    
653     def _setup_lilo(self):
654     #-------------------------------------------------------------
655     #OK, now that the file is built. Install lilo.
656     exitstatus = GLIUtility.spawn("/sbin/lilo",chroot=self._chroot_dir)
657     if exitstatus != 0:
658     raise GLIException("LiloInstallError", 'fatal', '_setup_lilo', "Running lilo failed!")
659     self._logger.log("Bootloader: lilo has been run/installed!")

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20