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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 263 - (show annotations) (download) (as text)
Tue Jan 18 08:03:23 2005 UTC (13 years, 6 months ago) by codeman
Original Path: trunk/src/templates/x86ArchitectureTemplate.py
File MIME type: text/x-python
File size: 19039 byte(s)
Took out unnecessary setting of random livecd root password.

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

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20