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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1291 - (show annotations) (download) (as text)
Fri Feb 10 02:01:58 2006 UTC (14 years, 7 months ago) by agaffney
File MIME type: text/x-python
File size: 31375 byte(s)
  src/GLIPortage.py:
  use tar to transfer files from image dir to /mnt/gentoo instead of 'cp -a'
  src/GLIStorageDevice.py,src/GLIInstallProfile.py,src/templates/x86AT.py:
  'resized' flag

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

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20