/[gli]/trunk/src/templates/x86ArchitectureTemplate.py
Gentoo

Contents of /trunk/src/templates/x86ArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1277 - (show annotations) (download) (as text)
Mon Feb 6 15:41:19 2006 UTC (14 years, 9 months ago) by agaffney
File MIME type: text/x-python
File size: 31343 byte(s)
  src/templates/x86ArchitectureTemplate.py:
  10 tries to create filesystem instead of 3

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

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20