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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1291 - (hide annotations) (download) (as text)
Fri Feb 10 02:01:58 2006 UTC (14 years, 8 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 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 agaffney 1291 $Id: x86ArchitectureTemplate.py,v 1.97 2006/02/10 02:01:58 agaffney 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 agaffney 1208 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 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 1227 self.notify_frontend("progress", (0, "Examining partitioning data"))
87 agaffney 1231 total_steps = float(len(parts_new) * 3)
88 agaffney 1227 cur_progress = 0
89 agaffney 497 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 agaffney 220
95 agaffney 497 # 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 agaffney 501 if not part in parts_old[device]:
99     table_changed = 1
100     break
101 agaffney 497 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 agaffney 691 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 agaffney 497 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 agaffney 498 tmppart_old = parts_old[device][tmppart_new['origminor']]
128 agaffney 497 # 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 agaffney 1291 # if tmppart_old['mb'] == tmppart_new['mb']:
137     if tmppart_new['resized']:
138 agaffney 497 tmppart_new['start'] = tmppart_old['start']
139 agaffney 1291 tmppart_new['end'] = 0
140 agaffney 497 else:
141     tmppart_new['start'] = tmppart_old['start']
142 agaffney 1291 tmppart_new['end'] = tmppart_old['end']
143 agaffney 497
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 agaffney 639 # part_bytes = long(tmppart_log['mb'] * MEGABYTE)
171 agaffney 497 # 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 agaffney 639 # part_bytes = long(tmppart['mb'] * MEGABYTE)
180 agaffney 497 # 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 agaffney 220 # First pass to delete old partitions that aren't resized
187 agaffney 497 self._logger.log("partitioning: Processing " + device + "...")
188 agaffney 1227 self.notify_frontend("progress", (cur_progress / total_steps, "Deleting partitioning that aren't being resized for " + device))
189     cur_progress += 1
190 agaffney 497 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 agaffney 278 delete = 0
195 agaffney 228 if oldpart['type'] == "extended":
196     logical_to_resize = 0
197 agaffney 497 for part_log in parts_old[device]:
198     if part_log < 5 or parts_old[device][part_log]['type'] == "free": continue
199 agaffney 278 delete_log = 0
200 agaffney 497 for new_part in parts_new[device]:
201 agaffney 228 if new_part < 5: continue
202 agaffney 497 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 codeman 427 self._logger.log(" Deleting old minor " + str(part_log) + " to be recreated later")
206 agaffney 278 delete_log = 1
207 agaffney 228 break
208 agaffney 497 # 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 codeman 427 self._logger.log(" Ignoring old minor " + str(part_log) + " to resize later")
211 agaffney 278 logical_to_resize = 1
212 agaffney 228 break
213 agaffney 497 if delete_log:
214 codeman 427 self._logger.log(" No match found...deleting partition " + str(part_log))
215 agaffney 228 parted_disk.delete_partition(parted_disk.get_partition(part_log))
216     if not logical_to_resize:
217 agaffney 497 self._logger.log(" Deleting extended partition with minor " + str(part))
218 agaffney 228 parted_disk.delete_partition(parted_disk.get_partition(part))
219     continue
220 agaffney 497 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 codeman 427 self._logger.log(" Deleting old minor " + str(part) + " to be recreated later")
224 agaffney 278 delete = 1
225 agaffney 220 break
226 agaffney 497 if tmppart['origminor'] == part and tmppart['start'] and not tmppart['end']:
227 codeman 427 self._logger.log(" Ignoring old minor " + str(part) + " to resize later")
228 agaffney 220 break
229 agaffney 497 if delete:
230 codeman 427 self._logger.log(" No match found...deleting partition " + str(part))
231 agaffney 225 parted_disk.delete_partition(parted_disk.get_partition(part))
232     parted_disk.commit()
233 agaffney 497
234 agaffney 220 # Second pass to resize old partitions that need to be resized
235 codeman 427 self._logger.log("Partitioning: Second pass...")
236 agaffney 1227 self.notify_frontend("progress", (cur_progress / total_steps, "Resizing remaining partitions for " + device))
237     cur_progress += 1
238 agaffney 497 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 codeman 427 self._logger.log(" Resizing old minor " + str(part) + " from " + str(oldpart['start']) + "-" + str(oldpart['end'])+ " to " + str(tmppart['start']) + "-" + str(tmppart['end']))
244 agaffney 220 type = tmppart['type']
245     minor = part
246 agaffney 230 start = tmppart['start']
247 agaffney 497 # Replace 512 with code to retrieve bytes per sector for device
248 agaffney 639 end = start + (long(tmppart['mb']) * MEGABYTE / 512)
249 agaffney 497 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 agaffney 220 if type == "ext2" or type == "ext3":
257     total_sectors = end - start + 1
258 agaffney 231 ret = GLIUtility.spawn("resize2fs " + device + str(minor) + " " + str(total_sectors) + "s")
259     if ret: # Resize error
260 agaffney 497 raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + device + str(minor))
261 agaffney 220 elif type == "ntfs":
262     total_sectors = end - start + 1
263 agaffney 639 total_bytes = long(total_sectors) * 512
264 agaffney 231 ret = GLIUtility.spawn("ntfsresize --size " + str(total_bytes) + " " + device + str(minor))
265     if ret: # Resize error
266 agaffney 497 raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + device + str(minor))
267 agaffney 918 elif type == "linux-swap" or type == "fat32" or type == "fat16":
268 agaffney 230 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 agaffney 497 raise GLIException("PartitionError", 'fatal', 'partition', "New size specified for " + device + str(minor) + " is not within allowed boundaries")
272 agaffney 230 new_geom = resize_constraint.start_range.duplicate()
273     new_geom.set_start(start)
274     new_geom.set_end(end)
275 agaffney 231 try:
276     parted_fs.resize(new_geom)
277     except:
278 agaffney 497 raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + device + str(minor))
279 codeman 427 self._logger.log(" Deleting old minor " + str(part) + " to be recreated in 3rd pass")
280 agaffney 225 parted_disk.delete_partition(parted_disk.get_partition(part))
281 agaffney 220 break
282 agaffney 229 parted_disk.delete_all()
283 agaffney 225 parted_disk.commit()
284 agaffney 497
285 agaffney 220 # Third pass to create new partition table
286 agaffney 497 self._logger.log("Partitioning: Third pass....creating partitions")
287 agaffney 1227 self.notify_frontend("progress", (cur_progress / total_steps, "Recreating partition table for " + device))
288     cur_progress += 1
289 agaffney 497 start = 0
290 agaffney 507 end = 0
291 agaffney 506 extended_start = 0
292 agaffney 497 extended_end = 0
293 agaffney 501 self._logger.log(" Drive has " + str(device_sectors) + " sectors")
294 agaffney 506 # for part in parts_new[device]:
295     for part in new_part_list:
296 agaffney 497 newpart = parts_new[device][part]
297 agaffney 501 self._logger.log(" Partition " + str(part) + " has " + str(newpart['mb']) + "MB")
298 agaffney 639 part_sectors = long(newpart['mb']) * MEGABYTE / 512
299 agaffney 507 end = start + part_sectors
300 agaffney 497 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 agaffney 639 # cap to end of device
306 agaffney 503 if end >= device_sectors:
307     end = device_sectors - 1
308 agaffney 639 # now the actual creation
309 agaffney 497 if newpart['type'] == "free":
310     # Nothing to be done for this type
311     pass
312     elif newpart['type'] == "extended":
313 agaffney 501 self._logger.log(" Adding extended partition " + str(part) + " from " + str(start) + " to " + str(end))
314     self._add_partition(parted_disk, start, end, "extended", "")
315 agaffney 506 extended_start = start
316     extended_end = end
317 agaffney 505 elif part < 5 or not GLIStorageDevice.archinfo['x86']['extended']:
318 agaffney 501 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 agaffney 497 elif GLIStorageDevice.archinfo['x86']['extended'] and part > 4:
321 agaffney 506 if start >= extended_end:
322     start = extended_start + 1
323 agaffney 507 end = start + part_sectors
324 agaffney 497 if part == new_part_list[-1] and end > extended_end:
325     end = extended_end
326 agaffney 508 self._logger.log(" Adding logical partition " + str(part) + " from " + str(start) + " to " + str(end))
327 agaffney 501 self._add_partition(parted_disk, start, end, "logical", newpart['type'])
328 agaffney 497 if "flags" in newpart:
329 agaffney 589 for flag in newpart['flags']:
330     if parted_disk.get_partition(part).is_flag_available(flag):
331 agaffney 798 parted_disk.get_partition(part).set_flag(flag, True)
332 agaffney 639 # write to disk
333 agaffney 264 parted_disk.commit()
334 robbat2 740
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 agaffney 639 # now format the partition
340 agaffney 691 # extended and 'free' partitions should never be formatted
341     if newpart['format'] and newpart['type'] not in ('extended', 'free'):
342 agaffney 724 devnode = device + str(int(part))
343 robbat2 648 errormsg = "could't create %s filesystem on %s" % (newpart['type'],devnode)
344     # if you need a special command and
345 robbat2 649 # some base options, place it here.
346     if newpart['type'] == 'linux-swap':
347     cmdname = 'mkswap'
348 agaffney 918 elif newpart['type'] == 'fat16':
349     cmdname = 'mkfs.vfat -F 16'
350 robbat2 649 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 robbat2 648 else: # this should catch everything else
362 robbat2 649 raise GLIException("PartitionFormatError", 'fatal', 'partition',"Unknown partition type "+newpart['type'])
363 robbat2 741
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 robbat2 746 # sleep a bit first
368     time.sleep(1)
369     # now sleep until it exists
370 agaffney 869 # while not GLIUtility.is_file(devnode):
371     # self._logger.log("Waiting for device node "+devnode+" to exist...")
372     # time.sleep(1)
373 robbat2 741 # one bit of extra sleep is needed, as there is a blip still
374 agaffney 869 # time.sleep(1)
375 robbat2 741
376 agaffney 869 tries = 0
377 agaffney 1277 while tries <= 10:
378 agaffney 869 # 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 agaffney 876 self._logger.log("Try %d failed formatting partition %s...waiting 5 seconds" % (tries, devnode))
389     time.sleep(5)
390 agaffney 869 else:
391     break
392     if tries == 3:
393 robbat2 648 raise GLIException("PartitionFormatError", 'fatal', 'partition', errormsg)
394 agaffney 501 start = end + 1
395 agaffney 1227 self.notify_frontend("progress", (cur_progress / total_steps, "Done with partitioning for " + device))
396     # cur_progress += 1
397 agaffney 264
398 robbat2 740 def _configure_grub(self):
399 codeman 1166 self.build_mode = self._install_profile.get_kernel_build_method()
400     self._gather_grub_drive_info()
401 codeman 235 root = self._chroot_dir
402 codeman 1077 exitstatus2, kernel_names = GLIUtility.spawn("ls -1 --color=no " + root + "/boot/kernel-*", return_output=True)
403 codeman 1087 self._logger.log("Output of Kernel Names:\n"+kernel_names)
404 codeman 825 if not GLIUtility.exitsuccess(exitstatus2):
405     raise GLIException("BootloaderError", 'fatal', '_configure_grub', "Error listing the kernels in /boot")
406 codeman 1166 if self.build_mode == "genkernel" or self._install_profile.get_kernel_source_pkg() == "livecd-kernel":
407 codeman 1077 exitstatus3, initrd_names = GLIUtility.spawn("ls -1 --color=no " + root + "/boot/init*", return_output=True)
408 codeman 1087 self._logger.log("Output of Initrd Names:\n"+initrd_names)
409 codeman 825 if not GLIUtility.exitsuccess(exitstatus3):
410 codeman 1077 raise GLIException("BootloaderError", 'fatal', '_configure_grub', "Error listing the initrds")
411 codeman 427 self._logger.log("Bootloader: the three information gathering commands have been run")
412 codeman 235
413 codeman 1077 if not kernel_names[0]:
414 robbat2 740 raise GLIException("BootloaderError", 'fatal', '_configure_grub',"Error: We have no kernel in /boot to put in the grub.conf file!")
415 codeman 1077
416 codeman 235 #-------------------------------------------------------------
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 codeman 1166 if self.foundboot: #we have a /boot
421     newgrubconf += "splashimage=(" + self.grub_boot_drive + "," + self.grub_boot_minor + ")/grub/splash.xpm.gz\n"
422 codeman 235 else: #we have / and /boot needs to be included
423 codeman 1166 newgrubconf += "splashimage=(" + self.grub_boot_drive + "," + self.grub_boot_minor + ")/boot/grub/splash.xpm.gz\n"
424 codeman 1077 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 agaffney 1112 kernel_names = map(string.strip, kernel_names.strip().split("\n"))
429     initrd_names = map(string.strip, initrd_names.strip().split("\n"))
430 agaffney 1113 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 codeman 1077 #i think this means take the last one it finds.. i.e. the newest.
437    
438 codeman 235 newgrubconf += "title=Gentoo Linux\n"
439 codeman 1166 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 codeman 286 else:
444 codeman 1166 newgrubconf += "kernel /boot"+ grub_kernel_name[5:] + " root="+self.root_device+self.root_minor+"\n"
445 codeman 734 else: #using genkernel so it has an initrd.
446 codeman 1166 if self.foundboot:
447 codeman 286 newgrubconf += "kernel " + grub_kernel_name[5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
448 codeman 1166 newgrubconf += self.root_device + self.root_minor + " " + bootloader_kernel_args + "\n"
449 codeman 286 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 codeman 1166 newgrubconf += self.root_device + self.root_minor + " " + bootloader_kernel_args + "\n"
453 codeman 286 newgrubconf += "initrd /boot" + grub_initrd_name[5:] + "\n"
454 codeman 235
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 codeman 1099 self._logger.log("Grub installed and configured. Contents of grub.conf:\n"+newgrubconf)
465 codeman 1166 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 codeman 235 minornum = 0
479     #Assign root to the root mount point to make lines more readable
480     root = self._chroot_dir
481 codeman 1166
482    
483     self.foundboot = False
484 codeman 235 parts = self._install_profile.get_partition_tables()
485     for device in parts:
486 agaffney 805 tmp_partitions = parts[device].get_install_profile_structure()
487 agaffney 601 for partition in tmp_partitions:
488     mountpoint = tmp_partitions[partition]['mountpoint']
489 codeman 235 if (mountpoint == "/boot"):
490 codeman 1166 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 codeman 235 if mountpoint == "/":
497 codeman 1166 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 codeman 1168 root = self._chroot_dir
516 codeman 1167 file_name3 = root + "/boot/kernel_name"
517 codeman 1166 root = self._chroot_dir
518 codeman 235 exitstatus0 = GLIUtility.spawn("ls "+root+"/boot/kernel-* > "+file_name3)
519 codeman 825 if (exitstatus0 != 0):
520     raise GLIException("BootloaderError", 'fatal', '_configure_lilo', "Could not list kernels in /boot or no kernels found.")
521 codeman 1166 if self.build_mode == "genkernel" or self._install_profile.get_kernel_source_pkg() == "livecd-kernel":
522 codeman 825 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 codeman 235 g = open(file_name3)
526     kernel_name = g.readlines()
527     g.close()
528     if not kernel_name[0]:
529 robbat2 740 raise GLIException("BootloaderError", 'fatal', '_configure_lilo',"Error: We have no kernel in /boot to put in the grub.conf file!")
530 codeman 235 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 agaffney 461 if self._install_profile.get_bootloader_kernel_args(): bootloader_kernel_args = self._install_profile.get_bootloader_kernel_args()
534     else: bootloader_kernel_args = ""
535 codeman 235 #-------------------------------------------------------------
536     #time to build the lilo.conf
537     newliloconf = ""
538     if self._install_profile.get_boot_loader_mbr():
539 codeman 1166 newliloconf += "boot="+self.mbr_device+" # Install LILO in the MBR \n"
540 codeman 235 else:
541 codeman 1166 newliloconf += "boot="+self.boot_device+self.boot_minor+" # Install LILO in the MBR \n"
542 codeman 235 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 codeman 237 newliloconf += "image=/boot"+kernel_name[0][5:]+" \n"
550 codeman 825 newliloconf += " label=gentoo \n read-only \n"
551 codeman 1166 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 codeman 825 if bootloader_kernel_args:
554     newliloconf += " append=\""+bootloader_kernel_args+"\" \n"
555     else:
556     newliloconf += " root=/dev/ram0 \n"
557 codeman 1166 newliloconf += " append=\"init=/linuxrc ramdisk=8192 real_root="+self.root_device+self.root_minor + " " + bootloader_kernel_args + "\" \n"
558 agaffney 964 newliloconf += " initrd=/boot"+kernel_name[1][5:] + "\n\n"
559 codeman 248 newliloconf = self._lilo_add_windows(newliloconf)
560 codeman 235 #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 codeman 1166 self._logger.log("Lilo installed and configured. Not run yet.")
570 codeman 314
571 codeman 1166 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 codeman 248 def _lilo_add_windows(self, newliloconf):
601     parts = self._install_profile.get_partition_tables()
602     for device in parts:
603 agaffney 809 tmp_partitions = parts[device].get_install_profile_structure()
604 agaffney 601 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 codeman 263 return newliloconf
609 codeman 1077
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 codeman 1086 f = open(file_name) #open the device map
627 codeman 1077 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 codeman 1166
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