| 1 |
"""
|
| 2 |
Gentoo Linux Installer
|
| 3 |
|
| 4 |
$Id: x86ArchitectureTemplate.py,v 1.26 2005/03/30 00:10:50 agaffney 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 |
self._logger.log("Emerged the selected bootloader.")
|
| 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 GLIException("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 |
MEGABYTE = 1024 * 1024
|
| 63 |
devices_old = {}
|
| 64 |
parts_old = {}
|
| 65 |
parts_new = self._install_profile.get_partition_tables()
|
| 66 |
drives = GLIStorageDevice.detect_devices()
|
| 67 |
drives.sort()
|
| 68 |
for drive in drives:
|
| 69 |
devices_old[drive] = GLIStorageDevice.Device(drive)
|
| 70 |
devices_old[drive].set_partitions_from_disk()
|
| 71 |
for part in devices_old.keys(): parts_old[part] = devices_old[part].get_install_profile_structure()
|
| 72 |
|
| 73 |
# pp = pprint.PrettyPrinter(indent=4)
|
| 74 |
# pp.pprint(parts_old)
|
| 75 |
# pp.pprint(parts_new)
|
| 76 |
|
| 77 |
for dev in parts_old.keys():
|
| 78 |
parted_dev = parted.PedDevice.get(dev)
|
| 79 |
parted_disk = parted.PedDisk.new(parted_dev)
|
| 80 |
if not parts_new.has_key(dev) or not parts_new[dev]:
|
| 81 |
self._logger.log("Partition table for " + dev + " does not exist in install profile")
|
| 82 |
#print "Partition table for " + dev + " does not exist in install profile"
|
| 83 |
continue
|
| 84 |
if parts_new[dev][parts_new[dev].keys()[0]]['mb']:
|
| 85 |
# Change MB/%/* into sectors
|
| 86 |
total_sectors = parted_dev.length
|
| 87 |
sector_size = parted_dev.sector_size
|
| 88 |
total_mb = float(total_sectors * sector_size) / MEGABYTE
|
| 89 |
start_sector = 63
|
| 90 |
mb_left = total_mb
|
| 91 |
for part in parts_new[dev]:
|
| 92 |
tmppart = parts_new[dev][part]
|
| 93 |
if tmppart['type'] == "extended": continue
|
| 94 |
if tmppart['mb'][-1] == "%":
|
| 95 |
tmppart['mb'] = float(tmppart['mb'][:-1]) / 100 * total_mb
|
| 96 |
mb_left = mb_left - float(tmppart['mb'])
|
| 97 |
partlist = parts_new.keys()
|
| 98 |
partlist.sort()
|
| 99 |
for part in partlist:
|
| 100 |
if part > 4: continue
|
| 101 |
tmppart = parts_new[dev][part]
|
| 102 |
if tmppart['type'] == "extended":
|
| 103 |
for part_log in partlist:
|
| 104 |
if part < 5: continue
|
| 105 |
tmppart_log = parts_new[dev][part_log]
|
| 106 |
if not tmppart['start']:
|
| 107 |
tmppart['start'] = start_sector
|
| 108 |
if tmppart_log['mb'] == "*":
|
| 109 |
tmppart_log['mb'] = mb_left
|
| 110 |
part_bytes = int(tmppart_log['mb'] * MEGABYTE)
|
| 111 |
part_sectors = round(part_bytes / sector_size)
|
| 112 |
tmppart_log['start'] = start_sector
|
| 113 |
tmppart_log['end'] = start_sector + part_sectors - 1
|
| 114 |
tmppart['end'] = tmppart_log['end']
|
| 115 |
start_sector = start_sector + part_sectors
|
| 116 |
continue
|
| 117 |
if tmppart['mb'] == "*":
|
| 118 |
tmppart['mb'] = mb_left
|
| 119 |
part_bytes = int(tmppart['mb'] * MEGABYTE)
|
| 120 |
part_sectors = round(part_bytes / sector_size)
|
| 121 |
tmppart['start'] = start_sector
|
| 122 |
tmppart['end'] = start_sector + part_sectors - 1
|
| 123 |
start_sector = start_sector + part_sectors
|
| 124 |
else:
|
| 125 |
table_changed = 1
|
| 126 |
for part in parts_old[dev]:
|
| 127 |
oldpart = parts_old[dev][part]
|
| 128 |
newpart = parts_new[dev][part]
|
| 129 |
if oldpart['type'] == newpart['type'] and oldpart['start'] == newpart['start'] and oldpart['end'] == newpart['end'] and newpart['format'] == False:
|
| 130 |
table_changed = 0
|
| 131 |
else:
|
| 132 |
table_changed = 1
|
| 133 |
break
|
| 134 |
if not table_changed:
|
| 135 |
self._logger.log("Partition table for " + dev + " is unchanged")
|
| 136 |
#print "Partition table for " + dev + " is unchanged"
|
| 137 |
continue
|
| 138 |
parts_active = []
|
| 139 |
parts_lba = []
|
| 140 |
self._logger.log("Processing "+dev+"...")
|
| 141 |
#print "\nProcessing " + dev + "..."
|
| 142 |
# First pass to delete old partitions that aren't resized
|
| 143 |
for part in parts_old[dev]:
|
| 144 |
if part > 4: continue
|
| 145 |
oldpart = parts_old[dev][part]
|
| 146 |
matchingminor = 0
|
| 147 |
delete = 0
|
| 148 |
if oldpart['type'] == "extended":
|
| 149 |
logical_to_resize = 0
|
| 150 |
for part_log in parts_old[dev]:
|
| 151 |
if part_log < 5: continue
|
| 152 |
matchingminor = 0
|
| 153 |
delete_log = 0
|
| 154 |
for new_part in parts_new[dev]:
|
| 155 |
if new_part < 5: continue
|
| 156 |
tmppart = parts_new[dev][new_part]
|
| 157 |
if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) == int(oldpart['end']):
|
| 158 |
matchingminor = new_part
|
| 159 |
self._logger.log(" Deleting old minor " + str(part_log) + " to be recreated later")
|
| 160 |
#print " Deleting old minor " + str(part_log) + " to be recreated later"
|
| 161 |
delete_log = 1
|
| 162 |
break
|
| 163 |
if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
|
| 164 |
matchingminor = new_part
|
| 165 |
self._logger.log(" Ignoring old minor " + str(part_log) + " to resize later")
|
| 166 |
#print " Ignoring old minor " + str(part_log) + " to resize later"
|
| 167 |
logical_to_resize = 1
|
| 168 |
break
|
| 169 |
if not matchingminor:
|
| 170 |
self._logger.log(" No match found...deleting partition " + str(part_log))
|
| 171 |
#print " No match found...deleting partition " + str(part_log)
|
| 172 |
parted_disk.delete_partition(parted_disk.get_partition(part_log))
|
| 173 |
else:
|
| 174 |
if parted_disk.get_partition(part_log).get_flag(1): # Active/boot
|
| 175 |
self._logger.log(" Partition " + str(part_log) + " was active...noted")
|
| 176 |
#print " Partition " + str(part_log) + " was active...noted"
|
| 177 |
parts_active.append(int(matchingminor))
|
| 178 |
if parted_disk.get_partition(part_log).get_flag(7): # LBA
|
| 179 |
self._logger.log(" Partition " + str(part_log) + " was LBA...noted")
|
| 180 |
#print " Partition " + str(part_log) + " was LBA...noted"
|
| 181 |
parts_lba.append(int(matchingminor))
|
| 182 |
if delete_log:
|
| 183 |
parted_disk.delete_partition(parted_disk.get_partition(part_log))
|
| 184 |
if not logical_to_resize:
|
| 185 |
self._logger.log(" Deleting old minor " + str(part))
|
| 186 |
#print " Deleting old minor " + str(part)
|
| 187 |
parted_disk.delete_partition(parted_disk.get_partition(part))
|
| 188 |
continue
|
| 189 |
for new_part in parts_new[dev]:
|
| 190 |
tmppart = parts_new[dev][new_part]
|
| 191 |
if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) == int(oldpart['end']):
|
| 192 |
matchingminor = new_part
|
| 193 |
self._logger.log(" Deleting old minor " + str(part) + " to be recreated later")
|
| 194 |
#print " Deleting old minor " + str(part) + " to be recreated later"
|
| 195 |
delete = 1
|
| 196 |
break
|
| 197 |
if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
|
| 198 |
matchingminor = new_part
|
| 199 |
self._logger.log(" Ignoring old minor " + str(part) + " to resize later")
|
| 200 |
#print " Ignoring old minor " + str(part) + " to resize later"
|
| 201 |
break
|
| 202 |
if not matchingminor:
|
| 203 |
self._logger.log(" No match found...deleting partition " + str(part))
|
| 204 |
#print " No match found...deleting partition " + str(part)
|
| 205 |
parted_disk.delete_partition(parted_disk.get_partition(part))
|
| 206 |
else:
|
| 207 |
if parted_disk.get_partition(part).get_flag(1): # Active/boot
|
| 208 |
self._logger.log(" Partition " + str(part) + " was active...noted")
|
| 209 |
#print " Partition " + str(part) + " was active...noted"
|
| 210 |
parts_active.append(int(matchingminor))
|
| 211 |
if parted_disk.get_partition(part).get_flag(7): # LBA
|
| 212 |
self._logger.log(" Partition " + str(part) + " was LBA...noted")
|
| 213 |
#print " Partition " + str(part) + " was LBA...noted"
|
| 214 |
parts_lba.append(int(matchingminor))
|
| 215 |
if delete:
|
| 216 |
parted_disk.delete_partition(parted_disk.get_partition(part))
|
| 217 |
parted_disk.commit()
|
| 218 |
# Second pass to resize old partitions that need to be resized
|
| 219 |
self._logger.log("Partitioning: Second pass...")
|
| 220 |
#print " Second pass..."
|
| 221 |
for part in parts_old[dev]:
|
| 222 |
oldpart = parts_old[dev][part]
|
| 223 |
for new_part in parts_new[dev]:
|
| 224 |
tmppart = parts_new[dev][new_part]
|
| 225 |
if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
|
| 226 |
self._logger.log(" Resizing old minor " + str(part) + " from " + str(oldpart['start']) + "-" + str(oldpart['end'])+ " to " + str(tmppart['start']) + "-" + str(tmppart['end']))
|
| 227 |
#print " Resizing old minor " + str(part) + " from " + str(oldpart['start']) + "-" + str(oldpart['end'])+ " to " + str(tmppart['start']) + "-" + str(tmppart['end'])
|
| 228 |
type = tmppart['type']
|
| 229 |
device = dev
|
| 230 |
minor = part
|
| 231 |
start = tmppart['start']
|
| 232 |
end = tmppart['end']
|
| 233 |
if type == "ext2" or type == "ext3":
|
| 234 |
total_sectors = end - start + 1
|
| 235 |
ret = GLIUtility.spawn("resize2fs " + device + str(minor) + " " + str(total_sectors) + "s")
|
| 236 |
if ret: # Resize error
|
| 237 |
raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + dev + str(minor))
|
| 238 |
elif type == "ntfs":
|
| 239 |
total_sectors = end - start + 1
|
| 240 |
total_bytes = int(total_sectors) * 512
|
| 241 |
ret = GLIUtility.spawn("ntfsresize --size " + str(total_bytes) + " " + device + str(minor))
|
| 242 |
if ret: # Resize error
|
| 243 |
raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + dev + str(minor))
|
| 244 |
else:
|
| 245 |
parted_fs = parted_disk.get_partition(part).geom.file_system_open()
|
| 246 |
resize_constraint = parted_fs.get_resize_constraint()
|
| 247 |
if end < (start + resize_constraint.min_size) or start != resize_constraint.start_range.start:
|
| 248 |
raise GLIException("PartitionError", 'fatal', 'partition', "New size specified for " + dev + str(minor) + " is not within allowed boundaries")
|
| 249 |
new_geom = resize_constraint.start_range.duplicate()
|
| 250 |
new_geom.set_start(start)
|
| 251 |
new_geom.set_end(end)
|
| 252 |
try:
|
| 253 |
parted_fs.resize(new_geom)
|
| 254 |
except:
|
| 255 |
raise GLIException("PartitionResizeError", 'fatal', 'partition', "could not resize " + dev + str(minor))
|
| 256 |
self._logger.log(" Deleting old minor " + str(part) + " to be recreated in 3rd pass")
|
| 257 |
#print " Deleting old minor " + str(part) + " to be recreated in 3rd pass"
|
| 258 |
parted_disk.delete_partition(parted_disk.get_partition(part))
|
| 259 |
break
|
| 260 |
parted_disk.delete_all()
|
| 261 |
parted_disk.commit()
|
| 262 |
# Third pass to create new partition table
|
| 263 |
self._logger.log("Partitioning: Third pass.")
|
| 264 |
#print " Third pass..."
|
| 265 |
for part in parts_new[dev]:
|
| 266 |
newpart = parts_new[dev][part]
|
| 267 |
new_start, new_end = newpart['start'], newpart['end']
|
| 268 |
if newpart['type'] == "extended":
|
| 269 |
self._logger.log(" Adding extended partition from " + str(newpart['start']) + " to " + str(newpart['end']))
|
| 270 |
#print " Adding extended partition from " + str(newpart['start']) + " to " + str(newpart['end'])
|
| 271 |
self._add_partition(parted_disk, new_start, new_end, "extended", "")
|
| 272 |
elif int(part) < 5:
|
| 273 |
self._logger.log(" Adding primary partition from " + str(newpart['start']) + " to " + str(newpart['end']))
|
| 274 |
#print " Adding primary partition from " + str(newpart['start']) + " to " + str(newpart['end'])
|
| 275 |
self._add_partition(parted_disk, new_start, new_end, "primary", newpart['type'])
|
| 276 |
elif int(part) > 4:
|
| 277 |
self._logger.log(" Adding logical partition from " + str(newpart['start']) + " to " + str(newpart['end']))
|
| 278 |
#print " Adding logical partition from " + str(newpart['start']) + " to " + str(newpart['end'])
|
| 279 |
self._add_partition(parted_disk, new_start, new_end, "logical", newpart['type'])
|
| 280 |
if int(part) in parts_active and not newpart['format']:
|
| 281 |
self._logger.log(" Partition was previously active...setting")
|
| 282 |
#print " Partition was previously active...setting"
|
| 283 |
parted_disk.get_partition(part).set_flag(1)
|
| 284 |
if int(part) in parts_lba and not newpart['format']:
|
| 285 |
self._logger.log(" Partition was previously LBA...setting")
|
| 286 |
#print " Partition was previously LBA...setting"
|
| 287 |
parted_disk.get_partition(part).set_flag(7)
|
| 288 |
parted_disk.commit()
|
| 289 |
if newpart['format']:
|
| 290 |
if newpart['type'] == "ext2":
|
| 291 |
if GLIUtility.spawn("mke2fs " + dev + str(part)):
|
| 292 |
raise GLIException("PartitionFormatError", 'fatal', 'partition', "could't create ext2 filesystem on " + dev + str(part))
|
| 293 |
elif newpart['type'] == "ext3":
|
| 294 |
if GLIUtility.spawn("mke2fs -j " + dev + str(part)):
|
| 295 |
raise GLIException("PartitionFormatError", 'fatal', 'partition', "could't create ext3 filesystem on " + dev + str(part))
|
| 296 |
elif newpart['type'] == "linux-swap":
|
| 297 |
if GLIUtility.spawn("mkswap " + dev + str(part)):
|
| 298 |
raise GLIException("PartitionFormatError", 'fatal', 'partition', "could't create swap on " + dev + str(part))
|
| 299 |
elif newpart['type'] == "fat32":
|
| 300 |
if GLIUtility.spawn("mkfs.vfat -F 32 " + dev + str(part)):
|
| 301 |
raise GLIException("PartitionFormatError", 'fatal', 'partition', "could't create fat32 filesystem on " + dev + str(part))
|
| 302 |
elif newpart['type'] == "ntfs":
|
| 303 |
if GLIUtility.spawn("mkntfs " + dev + str(part)):
|
| 304 |
raise GLIException("PartitionFormatError", 'fatal', 'partition', "could't create ntfs filesystem on " + dev + str(part))
|
| 305 |
|
| 306 |
def _install_grub(self):
|
| 307 |
boot_device = ""
|
| 308 |
boot_minor = ""
|
| 309 |
root_device = ""
|
| 310 |
root_minor = ""
|
| 311 |
grub_root_minor = ""
|
| 312 |
grub_boot_minor = ""
|
| 313 |
grub_boot_drive = ""
|
| 314 |
grub_root_drive = ""
|
| 315 |
minornum = 0
|
| 316 |
#Assign root to the root mount point to make lines more readable
|
| 317 |
root = self._chroot_dir
|
| 318 |
file_name2 = root + "/boot/grub/device.map"
|
| 319 |
file_name3 = root + "/boot/grub/kernel_name"
|
| 320 |
file_name4 = root + "/boot/grub/initrd_name"
|
| 321 |
foundboot = False
|
| 322 |
parts = self._install_profile.get_partition_tables()
|
| 323 |
for device in parts:
|
| 324 |
for partition in parts[device]:
|
| 325 |
mountpoint = parts[device][partition]['mountpoint']
|
| 326 |
if (mountpoint == "/boot"):
|
| 327 |
foundboot = True
|
| 328 |
if (( (mountpoint == "/") and (not foundboot) ) or (mountpoint == "/boot")):
|
| 329 |
boot_minor = str(parts[device][partition]['minor'])
|
| 330 |
grub_boot_minor = str(parts[device][partition]['minor'] - 1)
|
| 331 |
boot_device = device
|
| 332 |
if mountpoint == "/":
|
| 333 |
root_minor = str(parts[device][partition]['minor'])
|
| 334 |
grub_root_minor = str(parts[device][partition]['minor'] - 1)
|
| 335 |
root_device = device
|
| 336 |
if GLIUtility.is_file(root+file_name2):
|
| 337 |
exitstatus = GLIUtility.spawn("rm "+root+file_name2)
|
| 338 |
exitstatus1 = GLIUtility.spawn("echo quit | "+ root+"/sbin/grub --device-map="+file_name2)
|
| 339 |
exitstatus2 = GLIUtility.spawn("ls "+root+"/boot/kernel-* > "+file_name3)
|
| 340 |
exitstatus3 = GLIUtility.spawn("ls "+root+"/boot/initrd-* > "+file_name4)
|
| 341 |
if (exitstatus1 != 0) or (exitstatus2 != 0) or (exitstatus3 != 0):
|
| 342 |
raise GLIException("BootloaderError", 'fatal', '_install_grub', "Error in one of THE THREE run commands")
|
| 343 |
self._logger.log("Bootloader: the three information gathering commands have been run")
|
| 344 |
"""
|
| 345 |
read the device map. sample looks like this:
|
| 346 |
(fd0) /dev/floppy/0
|
| 347 |
(hd0) /dev/ide/host2/bus0/target0/lun0/disc
|
| 348 |
(hd1) /dev/ide/host0/bus0/target0/lun0/disc
|
| 349 |
(hd2) /dev/ide/host0/bus0/target1/lun0/disc
|
| 350 |
"""
|
| 351 |
|
| 352 |
# Search for the key
|
| 353 |
f = open(file_name2) #open the device map
|
| 354 |
file = f.readlines()
|
| 355 |
f.close()
|
| 356 |
for i in range(len(file)):
|
| 357 |
if file[i][6:-1] == boot_device:
|
| 358 |
#eurika we found the drivenum
|
| 359 |
grub_boot_drive = file[i][1:4]
|
| 360 |
if file[i][6:-1] == root_device:
|
| 361 |
grub_root_drive = file[i][1:4]
|
| 362 |
if (not grub_root_drive) or (not grub_boot_drive):
|
| 363 |
raise GLIException("BootloaderError", 'fatal', '_install_grub',"Couldn't find the drive num in the list from the device.map")
|
| 364 |
|
| 365 |
g = open(file_name3)
|
| 366 |
h = open(file_name4)
|
| 367 |
initrd_name = h.readlines()
|
| 368 |
kernel_name = g.readlines()
|
| 369 |
g.close()
|
| 370 |
h.close()
|
| 371 |
if not kernel_name[0]:
|
| 372 |
raise GLIException("BootloaderError", 'fatal', '_install_grub',"Error: We have no kernel in /boot to put in the grub.conf file!")
|
| 373 |
kernel_name = map(string.strip, kernel_name)
|
| 374 |
initrd_name = map(string.strip, initrd_name)
|
| 375 |
for i in range(len(kernel_name)):
|
| 376 |
grub_kernel_name = kernel_name[i].split(root)[1]
|
| 377 |
for i in range(len(initrd_name)):
|
| 378 |
grub_initrd_name = initrd_name[i].split(root)[1]
|
| 379 |
#-------------------------------------------------------------
|
| 380 |
#OK, now that we have all the info, let's build that grub.conf
|
| 381 |
newgrubconf = ""
|
| 382 |
newgrubconf += "default 0\ntimeout 30\n"
|
| 383 |
if self._install_profile.get_kernel_args(): kernel_args = self._install_profile.get_kernel_args()
|
| 384 |
else: kernel_args = ""
|
| 385 |
if foundboot: #we have a /boot
|
| 386 |
newgrubconf += "splashimage=(" + grub_boot_drive + "," + grub_boot_minor + ")/grub/splash.xpm.gz\n"
|
| 387 |
else: #we have / and /boot needs to be included
|
| 388 |
newgrubconf += "splashimage=(" + grub_boot_drive + "," + grub_boot_minor + ")/boot/grub/splash.xpm.gz\n"
|
| 389 |
|
| 390 |
newgrubconf += "title=Gentoo Linux\n"
|
| 391 |
newgrubconf += "root (" + grub_boot_drive + "," + grub_boot_minor + ")\n"
|
| 392 |
if self._install_profile.get_kernel_config_uri() != "": #using CUSTOM kernel
|
| 393 |
if foundboot:
|
| 394 |
newgrubconf += "kernel " + grub_kernel_name[5:] + " root="+root_device+root_minor+"\n"
|
| 395 |
else:
|
| 396 |
newgrubconf += "kernel /boot"+ grub_kernel_name[5:] + " root="+root_device+root_minor+"\n"
|
| 397 |
else:
|
| 398 |
if foundboot:
|
| 399 |
newgrubconf += "kernel " + grub_kernel_name[5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
|
| 400 |
newgrubconf += root_device + root_minor + " " + kernel_args + "\n"
|
| 401 |
newgrubconf += "initrd " + grub_initrd_name[5:] + "\n"
|
| 402 |
else:
|
| 403 |
newgrubconf += "kernel /boot" + grub_kernel_name[5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
|
| 404 |
newgrubconf += root_device + root_minor + " " + kernel_args + "\n"
|
| 405 |
newgrubconf += "initrd /boot" + grub_initrd_name[5:] + "\n"
|
| 406 |
|
| 407 |
#-------------------------------------------------------------
|
| 408 |
#OK, now that the file is built. Install grub.
|
| 409 |
#cp /proc/mounts /etc/mtab
|
| 410 |
#grub-install --root-directory=/boot /dev/hda
|
| 411 |
#shutil.copy("/proc/mounts",root +"/etc/mtab")
|
| 412 |
grubinstallstring = "echo -en 'root ("+grub_boot_drive + "," + grub_boot_minor + ")\n"
|
| 413 |
if not self._install_profile.get_boot_loader_mbr():
|
| 414 |
grubinstallstring +="setup ("+grub_boot_drive + "," + grub_boot_minor + ")\n"
|
| 415 |
else:
|
| 416 |
grubinstallstring +="setup ("+grub_boot_drive+")\n"
|
| 417 |
grubinstallstring += "quit\n' | "+root+"/sbin/grub"
|
| 418 |
#print grubinstallstring
|
| 419 |
exitstatus = GLIUtility.spawn(grubinstallstring)
|
| 420 |
if exitstatus != 0:
|
| 421 |
raise GLIException("GrubInstallError", 'fatal', '_install_grub', "Could not install grub!")
|
| 422 |
self._logger.log("Bootloader: grub has been installed!")
|
| 423 |
#now make the grub.conf file
|
| 424 |
file_name = root + "/boot/grub/grub.conf"
|
| 425 |
try:
|
| 426 |
shutil.move(file_name, file_name + ".OLDdefault")
|
| 427 |
except:
|
| 428 |
pass
|
| 429 |
f = open(file_name, 'w')
|
| 430 |
f.writelines(newgrubconf)
|
| 431 |
f.close()
|
| 432 |
self._logger.log("Grub installed and configured.")
|
| 433 |
|
| 434 |
def _install_lilo(self):
|
| 435 |
boot_device = ""
|
| 436 |
boot_minor = ""
|
| 437 |
root_device = ""
|
| 438 |
root_minor = ""
|
| 439 |
minornum = 0
|
| 440 |
#Assign root to the root mount point to make lines more readable
|
| 441 |
root = self._chroot_dir
|
| 442 |
file_name3 = root + "/boot/grub/kernel_name"
|
| 443 |
foundboot = False
|
| 444 |
parts = self._install_profile.get_partition_tables()
|
| 445 |
for device in parts:
|
| 446 |
for partition in parts[device]:
|
| 447 |
mountpoint = parts[device][partition]['mountpoint']
|
| 448 |
if (mountpoint == "/boot"):
|
| 449 |
foundboot = True
|
| 450 |
if (( (mountpoint == "/") and (not foundboot) ) or (mountpoint == "/boot")):
|
| 451 |
boot_minor = str(parts[device][partition]['minor'])
|
| 452 |
boot_device = device
|
| 453 |
if mountpoint == "/":
|
| 454 |
root_minor = str(parts[device][partition]['minor'])
|
| 455 |
root_device = device
|
| 456 |
exitstatus0 = GLIUtility.spawn("ls "+root+"/boot/kernel-* > "+file_name3)
|
| 457 |
exitstatus1 = GLIUtility.spawn("ls "+root+"/boot/initrd-* >> "+file_name3)
|
| 458 |
if (exitstatus0 != 0) or (exitstatus1 != 0):
|
| 459 |
raise GLIException("BootloaderError", 'fatal', '_install_lilo', "Error in one of THE TWO run commands")
|
| 460 |
g = open(file_name3)
|
| 461 |
kernel_name = g.readlines()
|
| 462 |
g.close()
|
| 463 |
if not kernel_name[0]:
|
| 464 |
raise GLIException("BootloaderError", 'fatal', '_install_lilo',"Error: We have no kernel in /boot to put in the grub.conf file!")
|
| 465 |
kernel_name = map(string.strip, kernel_name)
|
| 466 |
kernel_name[0] = kernel_name[0].split(root)[1]
|
| 467 |
kernel_name[1] = kernel_name[1].split(root)[1]
|
| 468 |
if self._install_profile.get_kernel_args(): kernel_args = self._install_profile.get_kernel_args()
|
| 469 |
else: kernel_args = ""
|
| 470 |
#-------------------------------------------------------------
|
| 471 |
#time to build the lilo.conf
|
| 472 |
newliloconf = ""
|
| 473 |
if self._install_profile.get_boot_loader_mbr():
|
| 474 |
newliloconf += "boot="+boot_device+" # Install LILO in the MBR \n"
|
| 475 |
else:
|
| 476 |
newliloconf += "boot="+boot_device+boot_minor+" # Install LILO in the MBR \n"
|
| 477 |
newliloconf += "prompt # Give the user the chance to select another section\n"
|
| 478 |
newliloconf += "timeout=50 # Wait 5 (five) seconds before booting the default section\n"
|
| 479 |
newliloconf += "default=gentoo # When the timeout has passed, boot the \"gentoo\" section\n"
|
| 480 |
newliloconf += "# Only if you use framebuffer. Otherwise remove the following line:\n"
|
| 481 |
if not self._install_profile.get_kernel_bootsplash():
|
| 482 |
newliloconf += "#"
|
| 483 |
newliloconf += "vga=788 # Framebuffer setting. Adjust to your own will\n"
|
| 484 |
newliloconf += "image=/boot"+kernel_name[0][5:]+" \n"
|
| 485 |
newliloconf += " label=gentoo \n read-only \n root=/dev/ram0 \n"
|
| 486 |
newliloconf += " append=\"init=/linuxrc ramdisk=8192 real_root="+root_device+root_minor + " " + kernel_args + "\" \n"
|
| 487 |
newliloconf += " initrd=/boot"+kernel_name[1][5:] + "\n\n"
|
| 488 |
newliloconf = self._lilo_add_windows(newliloconf)
|
| 489 |
#now make the lilo.conf file
|
| 490 |
file_name = root + "/etc/lilo.conf"
|
| 491 |
try:
|
| 492 |
shutil.move(file_name, file_name + ".OLDdefault")
|
| 493 |
except:
|
| 494 |
pass
|
| 495 |
f = open(file_name, 'w')
|
| 496 |
f.writelines(newliloconf)
|
| 497 |
f.close()
|
| 498 |
#-------------------------------------------------------------
|
| 499 |
#OK, now that the file is built. Install lilo.
|
| 500 |
exitstatus = GLIUtility.spawn("/sbin/lilo",chroot=self._chroot_dir)
|
| 501 |
if exitstatus != 0:
|
| 502 |
raise GLIException("LiloInstallError", 'fatal', '_install_lilo', "Running lilo failed!")
|
| 503 |
self._logger.log("Lilo installed, configured, and run.")
|
| 504 |
|
| 505 |
def _lilo_add_windows(self, newliloconf):
|
| 506 |
parts = self._install_profile.get_partition_tables()
|
| 507 |
for device in parts:
|
| 508 |
for partition in parts[device]:
|
| 509 |
if (parts[device][partition]['type'] == "vfat") or (parts[device][partition]['type'] == "ntfs"):
|
| 510 |
newliloconf += "other="+device+str(parts[device][partition]['minor'])+"\n"
|
| 511 |
newliloconf += "label=Windows_P"+str(parts[device][partition]['minor'])+"\n\n"
|
| 512 |
return newliloconf
|