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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 282 - (show annotations) (download) (as text)
Sat Jan 22 08:58:05 2005 UTC (15 years, 10 months ago) by codeman
File MIME type: text/x-python
File size: 20230 byte(s)
added code to allow custom kernel .config.

1 """
2 Gentoo Linux Installer
3
4 $Id: x86ArchitectureTemplate.py,v 1.20 2005/01/22 08:58:05 codeman Exp $
5 Copyright 2004 Gentoo Technologies Inc.
6
7
8 This fills in x86 specific functions.
9 """
10
11 import GLIUtility, string
12 from GLIArchitectureTemplate import ArchitectureTemplate
13 from GLIException import *
14 import parted
15
16 class x86ArchitectureTemplate(ArchitectureTemplate):
17 def __init__(self,configuration=None, install_profile=None, client_controller=None):
18 ArchitectureTemplate.__init__(self, configuration, install_profile, client_controller)
19 self._architecture_name = 'x86'
20 self._kernel_bzimage = "arch/i386/boot/bzImage"
21
22 def install_bootloader(self):
23 "Installs and configures bootloader"
24 #
25 # THIS IS ARCHITECTURE DEPENDANT!!!
26 # This is the x86 way.. it uses grub
27
28 if self._install_profile.get_boot_loader_pkg():
29 exitstatus = self._emerge(self._install_profile.get_boot_loader_pkg())
30 if exitstatus != 0:
31 raise GLIException("BootLoaderEmergeError", 'fatal', 'install_bootloader', "Could not emerge bootloader!")
32 else:
33 pass
34
35 if self._install_profile.get_boot_loader_pkg() == "grub":
36 self._install_grub()
37 elif self._install_profile.get_boot_loader_pkg() == "lilo":
38 self._install_lilo()
39 else:
40 raise Exception("BootLoaderError",'fatal','install_bootloader',"Invalid bootloader selected:"+self._install_profile.get_boot_loader_pkg())
41
42 def _sectors_to_megabytes(self, sectors, sector_bytes=512):
43 return float((float(sectors) * sector_bytes)/ float(1024*1024))
44
45 def _add_partition(self, disk, start, end, type, fs):
46 types = { 'primary': parted.PARTITION_PRIMARY, 'extended': parted.PARTITION_EXTENDED, 'logical': parted.PARTITION_LOGICAL }
47 fsTypes = {}
48 fs_type = parted.file_system_type_get_next ()
49 while fs_type:
50 fsTypes[fs_type.name] = fs_type
51 fs_type = parted.file_system_type_get_next (fs_type)
52 fstype = None
53 if fs: fstype = fsTypes[fs]
54 newpart = disk.partition_new(types[type], fstype, start, end)
55 constraint = disk.dev.constraint_any()
56 disk.add_partition(newpart, constraint)
57
58 def partition(self):
59 import GLIStorageDevice
60 import pprint
61
62 devices_old = {}
63 parts_old = {}
64 parts_new = self._install_profile.get_partition_tables()
65 drives = GLIStorageDevice.detect_devices()
66 drives.sort()
67 for drive in drives:
68 devices_old[drive] = GLIStorageDevice.Device(drive)
69 devices_old[drive].set_partitions_from_disk()
70 for part in devices_old.keys(): parts_old[part] = devices_old[part].get_install_profile_structure()
71
72 # pp = pprint.PrettyPrinter(indent=4)
73 # pp.pprint(parts_old)
74 # pp.pprint(parts_new)
75
76 for dev in parts_old.keys():
77 if not parts_new.has_key(dev) or not parts_new[dev]:
78 print "Partition table for " + dev + " does not exist in install profile"
79 continue
80 table_changed = 1
81 for part in parts_old[dev]:
82 oldpart = parts_old[dev][part]
83 newpart = parts_new[dev][part]
84 if oldpart['type'] == newpart['type'] and oldpart['start'] == newpart['start'] and oldpart['end'] == newpart['end'] and newpart['format'] == False:
85 table_changed = 0
86 else:
87 table_changed = 1
88 break
89 if not table_changed:
90 print "Partition table for " + dev + " is unchanged"
91 continue
92 parts_active = []
93 parts_lba = []
94 print "\nProcessing " + dev + "..."
95 parted_dev = parted.PedDevice.get(dev)
96 parted_disk = parted.PedDisk.new(parted_dev)
97 # First pass to delete old partitions that aren't resized
98 for part in parts_old[dev]:
99 if part > 4: continue
100 oldpart = parts_old[dev][part]
101 matchingminor = 0
102 delete = 0
103 if oldpart['type'] == "extended":
104 logical_to_resize = 0
105 for part_log in parts_old[dev]:
106 if part_log < 5: continue
107 matchingminor = 0
108 delete_log = 0
109 for new_part in parts_new[dev]:
110 if new_part < 5: continue
111 tmppart = parts_new[dev][new_part]
112 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) == int(oldpart['end']):
113 matchingminor = new_part
114 print " Deleting old minor " + str(part_log) + " to be recreated later"
115 delete_log = 1
116 break
117 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
118 matchingminor = new_part
119 print " Ignoring old minor " + str(part_log) + " to resize later"
120 logical_to_resize = 1
121 break
122 if not matchingminor:
123 print " No match found...deleting partition " + str(part_log)
124 parted_disk.delete_partition(parted_disk.get_partition(part_log))
125 else:
126 if parted_disk.get_partition(part_log).get_flag(1): # Active/boot
127 print " Partition " + str(part_log) + " was active...noted"
128 parts_active.append(int(matchingminor))
129 if parted_disk.get_partition(part_log).get_flag(7): # LBA
130 print " Partition " + str(part_log) + " was LBA...noted"
131 parts_lba.append(int(matchingminor))
132 if delete_log:
133 parted_disk.delete_partition(parted_disk.get_partition(part_log))
134 if not logical_to_resize:
135 print " Deleting old minor " + str(part)
136 parted_disk.delete_partition(parted_disk.get_partition(part))
137 continue
138 for new_part in parts_new[dev]:
139 tmppart = parts_new[dev][new_part]
140 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) == int(oldpart['end']):
141 matchingminor = new_part
142 print " Deleting old minor " + str(part) + " to be recreated later"
143 delete = 1
144 break
145 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
146 matchingminor = new_part
147 print " Ignoring old minor " + str(part) + " to resize later"
148 break
149 if not matchingminor:
150 print " No match found...deleting partition " + str(part)
151 parted_disk.delete_partition(parted_disk.get_partition(part))
152 else:
153 if parted_disk.get_partition(part).get_flag(1): # Active/boot
154 print " Partition " + str(part) + " was active...noted"
155 parts_active.append(int(matchingminor))
156 if parted_disk.get_partition(part).get_flag(7): # LBA
157 print " Partition " + str(part) + " was LBA...noted"
158 parts_lba.append(int(matchingminor))
159 if delete:
160 parted_disk.delete_partition(parted_disk.get_partition(part))
161 parted_disk.commit()
162 # Second pass to resize old partitions that need to be resized
163 print " Second pass..."
164 for part in parts_old[dev]:
165 oldpart = parts_old[dev][part]
166 for new_part in parts_new[dev]:
167 tmppart = parts_new[dev][new_part]
168 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
169 print " Resizing old minor " + str(part) + " from " + str(oldpart['start']) + "-" + str(oldpart['end'])+ " to " + str(tmppart['start']) + "-" + str(tmppart['end'])
170 type = tmppart['type']
171 device = dev
172 minor = part
173 start = tmppart['start']
174 end = tmppart['end']
175 if type == "ext2" or type == "ext3":
176 total_sectors = end - start + 1
177 ret = GLIUtility.spawn("resize2fs " + device + str(minor) + " " + str(total_sectors) + "s")
178 if ret: # Resize error
179 raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + dev + str(minor))
180 elif type == "ntfs":
181 total_sectors = end - start + 1
182 total_bytes = int(total_sectors) * 512
183 ret = GLIUtility.spawn("ntfsresize --size " + str(total_bytes) + " " + device + str(minor))
184 if ret: # Resize error
185 raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + dev + str(minor))
186 else:
187 parted_fs = parted_disk.get_partition(part).geom.file_system_open()
188 resize_constraint = parted_fs.get_resize_constraint()
189 if end < (start + resize_constraint.min_size) or start != resize_constraint.start_range.start:
190 raise GLIException("PartitionError", 'fatal', 'partition', "New size specified for " + dev + str(minor) + " is not within allowed boundaries")
191 new_geom = resize_constraint.start_range.duplicate()
192 new_geom.set_start(start)
193 new_geom.set_end(end)
194 try:
195 parted_fs.resize(new_geom)
196 except:
197 raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + dev + str(minor))
198 print " Deleting old minor " + str(part) + " to be recreated in 3rd pass"
199 parted_disk.delete_partition(parted_disk.get_partition(part))
200 break
201 parted_disk.delete_all()
202 parted_disk.commit()
203 # Third pass to create new partition table
204 print " Third pass..."
205 for part in parts_new[dev]:
206 newpart = parts_new[dev][part]
207 new_start, new_end = newpart['start'], newpart['end']
208 if newpart['type'] == "extended":
209 print " Adding extended partition from " + str(newpart['start']) + " to " + str(newpart['end'])
210 self._add_partition(parted_disk, new_start, new_end, "extended", "")
211 elif int(part) < 5:
212 print " Adding primary partition from " + str(newpart['start']) + " to " + str(newpart['end'])
213 self._add_partition(parted_disk, new_start, new_end, "primary", newpart['type'])
214 elif int(part) > 4:
215 print " Adding logical partition from " + str(newpart['start']) + " to " + str(newpart['end'])
216 self._add_partition(parted_disk, new_start, new_end, "logical", newpart['type'])
217 if int(part) in parts_active and not newpart['format']:
218 print " Partition was previously active...setting"
219 parted_disk.get_partition(part).set_flag(1)
220 if int(part) in parts_lba and not newpart['format']:
221 print " Partition was previously LBA...setting"
222 parted_disk.get_partition(part).set_flag(7)
223 parted_disk.commit()
224 if newpart['format']:
225 if newpart['type'] == "ext2":
226 if GLIUtility.spawn("mke2fs " + dev + str(part)):
227 raise GLIException("PartitionFormatError", 'fatal', 'partition', "could't create ext2 filesystem on " + dev + str(part))
228 elif newpart['type'] == "ext3":
229 if GLIUtility.spawn("mke2fs -j " + dev + str(part)):
230 raise GLIException("PartitionFormatError", 'fatal', 'partition', "could't create ext3 filesystem on " + dev + str(part))
231 elif newpart['type'] == "linux-swap":
232 if GLIUtility.spawn("mkswap " + dev + str(part)):
233 raise GLIException("PartitionFormatError", 'fatal', 'partition', "could't create swap on " + dev + str(part))
234 elif newpart['type'] == "fat32":
235 if GLIUtility.spawn("mkfs.vfat -F 32 " + dev + str(part)):
236 raise GLIException("PartitionFormatError", 'fatal', 'partition', "could't create fat32 filesystem on " + dev + str(part))
237 elif newpart['type'] == "ntfs":
238 if GLIUtility.spawn("mkntfs " + dev + str(part)):
239 raise GLIException("PartitionFormatError", 'fatal', 'partition', "could't create ntfs filesystem on " + dev + str(part))
240
241 def _install_grub(self):
242 boot_device = ""
243 boot_minor = ""
244 root_device = ""
245 root_minor = ""
246 grub_root_minor = ""
247 grub_boot_minor = ""
248 grub_boot_drive = ""
249 grub_root_drive = ""
250 minornum = 0
251 #Assign root to the root mount point to make lines more readable
252 root = self._chroot_dir
253 file_name = root + "/boot/grub/bootdevice"
254 file_name1 = root + "/boot/grub/rootdevice"
255 file_name2 = root + "/boot/grub/device.map"
256 file_name3 = root + "/boot/grub/kernel_name"
257 foundboot = False
258 parts = self._install_profile.get_partition_tables()
259 for device in parts:
260 for partition in parts[device]:
261 mountpoint = parts[device][partition]['mountpoint']
262 if (mountpoint == "/boot"):
263 foundboot = True
264 if (( (mountpoint == "/") and (not foundboot) ) or (mountpoint == "/boot")):
265 boot_minor = str(parts[device][partition]['minor'])
266 grub_boot_minor = str(parts[device][partition]['minor'] - 1)
267 boot_device = device
268 if mountpoint == "/":
269 root_minor = str(parts[device][partition]['minor'])
270 grub_root_minor = str(parts[device][partition]['minor'] - 1)
271 root_device = device
272
273
274 exitstatus0 = GLIUtility.spawn("ls -l " + boot_device + " > " + file_name)
275 exitstatus1 = GLIUtility.spawn("ls -l " + root_device + " > " + file_name1)
276 exitstatus2 = GLIUtility.spawn("echo quit | "+ root+"/sbin/grub --device-map="+file_name2)
277 exitstatus3 = GLIUtility.spawn("ls "+root+"/boot/kernel-* > "+file_name3)
278 exitstatus4 = GLIUtility.spawn("ls "+root+"/boot/initrd-* >> "+file_name3)
279 if (exitstatus0 != 0) or (exitstatus1 != 0) or (exitstatus2 != 0) or (exitstatus3 != 0) or (exitstatus4 != 0):
280 raise GLIException("BootloaderError", 'fatal', '_install_grub', "Error in one of THE FOUR run commands")
281
282 """
283 read the device map. sample looks like this:
284 (fd0) /dev/floppy/0
285 (hd0) /dev/ide/host2/bus0/target0/lun0/disc
286 (hd1) /dev/ide/host0/bus0/target0/lun0/disc
287 (hd2) /dev/ide/host0/bus0/target1/lun0/disc
288 """
289 e = open(file_name) #Looking for the boot device
290 ls_output = e.readlines()
291 e.close()
292 # looks like lr-xr-xr-x 1 root root 32 Oct 1 16:09 /dev/hda -> ide/host0/bus0/target0/lun0/disc
293 ls_output = ls_output[0].split(">")[-1]
294 ls_output = ls_output[1:]
295
296 eb = open(file_name1) #Looking for the root device
297 ls_outputb = eb.readlines()
298 eb.close()
299 ls_outputb = ls_outputb[0].split(">")[-1]
300 ls_outputb = ls_outputb[1:]
301
302 # Search for the key
303 f = open(file_name2)
304 file = f.readlines()
305 f.close()
306 for i in range(len(file)):
307 if file[i][11:] == ls_output:
308 #eurika we found the drivenum
309 grub_boot_drive = file[i][1:4]
310 if file[i][11:] == ls_outputb:
311 grub_root_drive = file[i][1:4]
312 if (not grub_root_drive) or (not grub_boot_drive):
313 raise GLIException("BootloaderError", 'fatal', '_install_grub',"Couldn't find the drive num in the list from the device.map")
314
315 g = open(file_name3)
316 kernel_name = g.readlines()
317 g.close()
318 if not kernel_name[0]:
319 raise GLIException("BootloaderError", 'fatal', '_install_grub',"Error: We have no kernel in /boot to put in the grub.conf file!")
320 kernel_name = map(string.strip, kernel_name)
321 kernel_name[0] = kernel_name[0].split(root)[1]
322 kernel_name[1] = kernel_name[1].split(root)[1]
323 #-------------------------------------------------------------
324 #OK, now that we have all the info, let's build that grub.conf
325 newgrubconf = ""
326 newgrubconf += "default 0\ntimeout 30\n"
327 if foundboot: #we have a /boot
328 newgrubconf += "splashimage=(" + grub_boot_drive + "," + grub_boot_minor + ")/grub/splash.xpm.gz\n"
329 else: #we have / and /boot needs to be included
330 newgrubconf += "splashimage=(" + grub_boot_drive + "," + grub_boot_minor + ")/boot/grub/splash.xpm.gz\n"
331
332 newgrubconf += "title=Gentoo Linux\n"
333 newgrubconf += "root (" + grub_boot_drive + "," + grub_boot_minor + ")\n"
334 if foundboot:
335 newgrubconf += "kernel " + kernel_name[0][5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
336 newgrubconf += root_device + root_minor + "\n"
337 newgrubconf += "initrd " + kernel_name[1][5:] + "\n"
338 else:
339 newgrubconf += "kernel /boot" + kernel_name[0][5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
340 newgrubconf += root_device + root_minor + "\n"
341 newgrubconf += "initrd /boot" + kernel_name[1][5:] + "\n"
342
343 #-------------------------------------------------------------
344 #OK, now that the file is built. Install grub.
345 #cp /proc/mounts /etc/mtab
346 #grub-install --root-directory=/boot /dev/hda
347 #shutil.copy("/proc/mounts",root +"/etc/mtab")
348 grubinstallstring = "echo -en 'root ("+grub_boot_drive + "," + grub_boot_minor + ")\n"
349 if not self._install_profile.get_boot_loader_mbr():
350 grubinstallstring +="setup ("+grub_boot_drive + "," + grub_boot_minor + ")\n"
351 else:
352 grubinstallstring +="setup ("+grub_boot_drive+")\n"
353 grubinstallstring += "quit\n' | "+root+"/sbin/grub"
354 #print grubinstallstring
355 exitstatus = GLIUtility.spawn(grubinstallstring,chroot=self._chroot_dir)
356 if exitstatus != 0:
357 raise GLIException("GrubInstallError", 'fatal', '_install_grub', "Could not install grub!")
358
359 #now make the grub.conf file
360 file_name = root + "/boot/grub/grub.conf"
361 try:
362 shutil.move(file_name, file_name + ".OLDdefault")
363 except:
364 pass
365 f = open(file_name, 'w')
366 f.writelines(newgrubconf)
367 f.close()
368
369 def _install_lilo(self):
370 boot_device = ""
371 boot_minor = ""
372 root_device = ""
373 root_minor = ""
374 minornum = 0
375 #Assign root to the root mount point to make lines more readable
376 root = self._chroot_dir
377 file_name3 = root + "/boot/grub/kernel_name"
378 foundboot = False
379 parts = self._install_profile.get_partition_tables()
380 for device in parts:
381 for partition in parts[device]:
382 mountpoint = parts[device][partition]['mountpoint']
383 if (mountpoint == "/boot"):
384 foundboot = True
385 if (( (mountpoint == "/") and (not foundboot) ) or (mountpoint == "/boot")):
386 boot_minor = str(parts[device][partition]['minor'])
387 boot_device = device
388 if mountpoint == "/":
389 root_minor = str(parts[device][partition]['minor'])
390 root_device = device
391 exitstatus0 = GLIUtility.spawn("ls "+root+"/boot/kernel-* > "+file_name3)
392 exitstatus1 = GLIUtility.spawn("ls "+root+"/boot/initrd-* >> "+file_name3)
393 if (exitstatus0 != 0) or (exitstatus1 != 0):
394 raise GLIException("BootloaderError", 'fatal', '_install_lilo', "Error in one of THE TWO run commands")
395 g = open(file_name3)
396 kernel_name = g.readlines()
397 g.close()
398 if not kernel_name[0]:
399 raise GLIException("BootloaderError", 'fatal', '_install_lilo',"Error: We have no kernel in /boot to put in the grub.conf file!")
400 kernel_name = map(string.strip, kernel_name)
401 kernel_name[0] = kernel_name[0].split(root)[1]
402 kernel_name[1] = kernel_name[1].split(root)[1]
403 #-------------------------------------------------------------
404 #time to build the lilo.conf
405 newliloconf = ""
406 if self._install_profile.get_boot_loader_mbr():
407 newliloconf += "boot="+boot_device+" # Install LILO in the MBR \n"
408 else:
409 newliloconf += "boot="+boot_device+boot_minor+" # Install LILO in the MBR \n"
410 newliloconf += "prompt # Give the user the chance to select another section\n"
411 newliloconf += "timeout=50 # Wait 5 (five) seconds before booting the default section\n"
412 newliloconf += "default=gentoo # When the timeout has passed, boot the \"gentoo\" section\n"
413 newliloconf += "# Only if you use framebuffer. Otherwise remove the following line:\n"
414 if not self._install_profile.get_kernel_bootsplash():
415 newliloconf += "#"
416 newliloconf += "vga=788 # Framebuffer setting. Adjust to your own will\n"
417 newliloconf += "image=/boot"+kernel_name[0][5:]+" \n"
418 newliloconf += " label=gentoo \n read-only \n root=/dev/ram0 \n"
419 newliloconf += " append=\"init=/linuxrc ramdisk=8192 real_root="+root_device+root_minor+"\" \n"
420 newliloconf += " initrd=/boot"+kernel_name[1][5:] + "\n\n"
421 newliloconf = self._lilo_add_windows(newliloconf)
422 #now make the lilo.conf file
423 file_name = root + "/etc/lilo.conf"
424 try:
425 shutil.move(file_name, file_name + ".OLDdefault")
426 except:
427 pass
428 f = open(file_name, 'w')
429 f.writelines(newliloconf)
430 f.close()
431 #-------------------------------------------------------------
432 #OK, now that the file is built. Install lilo.
433 exitstatus = GLIUtility.spawn("/sbin/lilo",chroot=self._chroot_dir)
434 if exitstatus != 0:
435 raise GLIException("LiloInstallError", 'fatal', '_install_lilo', "Running lilo failed!")
436
437 def _lilo_add_windows(self, newliloconf):
438 parts = self._install_profile.get_partition_tables()
439 for device in parts:
440 for partition in parts[device]:
441 if (parts[device][partition]['type'] == "vfat") or (parts[device][partition]['type'] == "ntfs"):
442 newliloconf += "other="+device+str(parts[device][partition]['minor'])+"\n"
443 newliloconf += "label=Windows_P"+str(parts[device][partition]['minor'])+"\n\n"
444 return newliloconf

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20