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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 225 - (show annotations) (download) (as text)
Sat Jan 8 09:35:01 2005 UTC (15 years, 10 months ago) by agaffney
File MIME type: text/x-python
File size: 13601 byte(s)
install.py updates and partition code fixes

1 """
2 Gentoo Linux Installer
3
4 $Id: x86ArchitectureTemplate.py,v 1.8 2005/01/08 09:35:01 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
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 boot_device = ""
35 boot_minor = ""
36 root_device = ""
37 root_minor = ""
38 grub_root_minor = ""
39 grub_boot_minor = ""
40 grub_boot_drive = ""
41 grub_root_drive = ""
42 minornum = 0
43 #Assign root to the root mount point to make lines more readable
44 root = self._chroot_dir
45 file_name = root + "/boot/grub/bootdevice"
46 file_name1 = root + "/boot/grub/rootdevice"
47 file_name2 = root + "/boot/grub/device.map"
48 file_name3 = root + "/boot/grub/kernel_name"
49 foundboot = False
50 #partitions = self._install_profile.get_fstab()
51 parts = self._install_profile.get_partition_tables()
52 for device in parts:
53 #in parts['/dev/hda']
54 for partition in parts[device]:
55 #print parts[device][partition]
56 mountpoint = parts[device][partition]['mountpoint']
57 if (mountpoint == "/boot"):
58 foundboot = True
59 if (( (mountpoint == "/") and (not foundboot) ) or (mountpoint == "/boot")):
60 boot_minor = str(parts[device][partition]['minor'])
61 grub_boot_minor = str(parts[device][partition]['minor'] - 1)
62 boot_device = device
63 if mountpoint == "/":
64 root_minor = str(parts[device][partition]['minor'])
65 grub_root_minor = str(parts[device][partition]['minor'] - 1)
66 root_device = device
67
68
69 #for partition in partitions:
70 #if find a /boot then stop.. else we'll take a / and overwrite with a /boot if we find it too.
71 # if (partition == "/boot"):
72 #try to get the drive LETTER from /dev/hdc1 8th character
73 # boot_minor = partitions[partition][0][8]
74 # grub_boot_minor = str(int(boot_minor) - 1)
75 # boot_device = partitions[partition][0][0:8]
76 # foundboot = True
77 # if ( (partition == "/") and (not foundboot) ):
78 # boot_minor = partitions[partition][0][8]
79 # grub_boot_minor = str(int(boot_minor) - 1)
80 # boot_device = partitions[partition][0][0:8]
81 #Foundboot IS STILL FALSE
82 # if partition == "/":
83 # root_minor = partitions[partition][0][8]
84 # grub_root_minor = str(int(root_minor) - 1)
85 # root_device = partitions[partition][0][0:8]
86
87 exitstatus0 = GLIUtility.spawn("ls -l " + boot_device + " > " + file_name)
88 exitstatus1 = GLIUtility.spawn("ls -l " + root_device + " > " + file_name1)
89 exitstatus2 = GLIUtility.spawn("echo quit | "+ root+"/sbin/grub --device-map="+file_name2)
90 exitstatus3 = GLIUtility.spawn("ls "+root+"/boot/kernel-* > "+file_name3)
91 exitstatus4 = GLIUtility.spawn("ls "+root+"/boot/initrd-* >> "+file_name3)
92 if (exitstatus0 != 0) or (exitstatus1 != 0) or (exitstatus2 != 0) or (exitstatus3 != 0) or (exitstatus4 != 0):
93 raise GLIException("BootloaderError", 'fatal', 'install_bootloader', "Error in one of THE FOUR run commands")
94
95 """
96 read the device map. sample looks like this:
97 (fd0) /dev/floppy/0
98 (hd0) /dev/ide/host2/bus0/target0/lun0/disc
99 (hd1) /dev/ide/host0/bus0/target0/lun0/disc
100 (hd2) /dev/ide/host0/bus0/target1/lun0/disc
101 """
102 e = open(file_name) #Looking for the boot device
103 ls_output = e.readlines()
104 e.close()
105 # looks like lr-xr-xr-x 1 root root 32 Oct 1 16:09 /dev/hda -> ide/host0/bus0/target0/lun0/disc
106 ls_output = ls_output[0].split(">")[-1]
107 ls_output = ls_output[1:]
108
109 eb = open(file_name1) #Looking for the root device
110 ls_outputb = eb.readlines()
111 eb.close()
112 ls_outputb = ls_outputb[0].split(">")[-1]
113 ls_outputb = ls_outputb[1:]
114
115 # Search for the key
116 f = open(file_name2)
117 file = f.readlines()
118 f.close()
119 for i in range(len(file)):
120 if file[i][11:] == ls_output:
121 #eurika we found the drivenum
122 grub_boot_drive = file[i][1:4]
123 if file[i][11:] == ls_outputb:
124 grub_root_drive = file[i][1:4]
125 if (not grub_root_drive) or (not grub_boot_drive):
126 raise GLIException("BootloaderError", 'fatal', 'install_bootloader',"Couldn't find the drive num in the list from the device.map")
127
128 g = open(file_name3)
129 kernel_name = g.readlines()
130 g.close()
131 if not kernel_name[0]:
132 raise GLIException("BootloaderError", 'fatal', 'install_bootloader',"Error: We have no kernel in /boot to put in the grub.conf file!")
133 kernel_name = map(string.strip, kernel_name)
134 kernel_name[0] = kernel_name[0].split(root)[1]
135 kernel_name[1] = kernel_name[1].split(root)[1]
136 #-------------------------------------------------------------
137 #OK, now that we have all the info, let's build that grub.conf
138 newgrubconf = ""
139 newgrubconf += "default 0\ntimeout 30\n"
140 if foundboot: #we have a /boot
141 newgrubconf += "splashimage=(" + grub_boot_drive + "," + grub_boot_minor + ")/grub/splash.xpm.gz\n"
142 else: #we have / and /boot needs to be included
143 newgrubconf += "splashimage=(" + grub_boot_drive + "," + grub_boot_minor + ")/boot/grub/splash.xpm.gz\n"
144
145 newgrubconf += "title=Gentoo Linux\n"
146 newgrubconf += "root (" + grub_boot_drive + "," + grub_boot_minor + ")\n"
147 if foundboot:
148 newgrubconf += "kernel " + kernel_name[0][5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
149 newgrubconf += root_device + root_minor + "\n"
150 newgrubconf += "initrd " + kernel_name[1][5:] + "\n"
151 else:
152 newgrubconf += "kernel /boot" + kernel_name[0][5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
153 newgrubconf += root_device + root_minor + "\n"
154 newgrubconf += "initrd /boot" + kernel_name[1][5:] + "\n"
155
156 #-------------------------------------------------------------
157 #OK, now that the file is built. Install grub.
158 #cp /proc/mounts /etc/mtab
159 #grub-install --root-directory=/boot /dev/hda
160 #shutil.copy("/proc/mounts",root +"/etc/mtab")
161 grubinstallstring = "echo -en 'root ("+grub_boot_drive + "," + grub_boot_minor + ")\n"
162 if not self._install_profile.get_boot_loader_mbr():
163 grubinstallstring +="setup ("+grub_boot_drive + "," + grub_boot_minor + ")\n"
164 else:
165 grubinstallstring +="setup ("+grub_boot_drive+")\n"
166 grubinstallstring += "quit\n' | "+root+"/sbin/grub"
167 print grubinstallstring
168 exitstatus = GLIUtility.spawn(grubinstallstring,chroot=self._chroot_dir)
169 if exitstatus != 0:
170 raise GLIException("GrubInstallError", 'fatal', 'install_bootloader', "Could not install grub!")
171
172 #now make the grub.conf file
173 file_name = root + "/boot/grub/grub.conf"
174 try:
175 shutil.move(file_name, file_name + ".OLDdefault")
176 except:
177 pass
178 f = open(file_name, 'w')
179 f.writelines(newgrubconf)
180 f.close()
181
182 def _sectors_to_megabytes(self, sectors, sector_bytes=512):
183 return float((float(sectors) * sector_bytes)/ float(1024*1024))
184
185 def _add_partition(self, disk, start, end, type, fs):
186 types = { 'primary': parted.PARTITION_PRIMARY, 'extended': parted.PARTITION_EXTENDED, 'logical': parted.PARTITION_LOGICAL }
187 fsTypes = {}
188 fs_type = parted.file_system_type_get_next ()
189 while fs_type:
190 fsTypes[fs_type.name] = fs_type
191 fs_type = parted.file_system_type_get_next (fs_type)
192 fstype = None
193 if fs: fstype = fsTypes[fs]
194 newpart = disk.partition_new(types[type], fstype, start, end)
195 constraint = disk.dev.constraint_any()
196 disk.add_partition(newpart, constraint)
197
198 def partition(self):
199 import GLIStorageDevice
200 import pprint
201
202 devices_old = {}
203 parts_old = {}
204 parts_new = self._install_profile.get_partition_tables()
205 drives = GLIStorageDevice.detect_devices()
206 drives.sort()
207 for drive in drives:
208 devices_old[drive] = GLIStorageDevice.Device(drive)
209 devices_old[drive].set_partitions_from_disk()
210 for part in devices_old.keys(): parts_old[part] = devices_old[part].get_install_profile_structure()
211
212 pp = pprint.PrettyPrinter(indent=4)
213 pp.pprint(parts_old)
214 pp.pprint(parts_new)
215
216 for dev in parts_old.keys():
217 if not parts_new.has_key(dev) or not parts_new[dev]:
218 print "Partition table for " + dev + " does not exist in install profile"
219 continue
220 table_changed = 1
221 for part in parts_old[dev]:
222 oldpart = parts_old[dev][part]
223 newpart = parts_new[dev][part]
224 if oldpart['type'] == newpart['type'] and oldpart['start'] == newpart['start'] and oldpart['end'] == newpart['end'] and newpart['format'] == False:
225 table_changed = 0
226 else:
227 table_changed = 1
228 break
229 if not table_changed:
230 print "Partition table for " + dev + " is unchanged"
231 continue
232 parts_active = []
233 parts_lba = []
234 print "\nProcessing " + dev + "..."
235 parted_dev = parted.PedDevice.get(dev)
236 parted_disk = parted.PedDisk.new(parted_dev)
237 # First pass to delete old partitions that aren't resized
238 for part in parts_old[dev]:
239 oldpart = parts_old[dev][part]
240 matchingminor = 0
241 for new_part in parts_new[dev]:
242 tmppart = parts_new[dev][new_part]
243 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) == int(oldpart['end']):
244 matchingminor = new_part
245 print " Deleting old minor " + str(part) + " to be recreated later"
246 parted_disk.delete_partition(parted_disk.get_partition(part))
247 break
248 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
249 matchingminor = new_part
250 print " Ignoring old minor " + str(part) + " to resize later"
251 break
252 if not matchingminor:
253 print " No match found...deleting partition " + str(part)
254 # This is broke for logical partitions
255 parted_disk.delete_partition(parted_disk.get_partition(part))
256
257 else:
258 if parted_disk.get_partition(part).get_flag(1): # Active/boot
259 print " Partition " + str(part) + " was active...noted"
260 parts_active.append(int(matchingminor))
261 if parted_disk.get_partition(part).get_flag(7): # LBA
262 print " Partition " + str(part) + " was LBA...noted"
263 parts_lba.append(int(matchingminor))
264 parted_disk.commit()
265 # Second pass to resize old partitions that need to be resized
266 print " Second pass..."
267 for part in parts_old[dev]:
268 oldpart = parts_old[dev][part]
269 for new_part in parts_new[dev]:
270 tmppart = parts_new[dev][new_part]
271 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
272 print " Resizing old minor " + str(part) + " from " + str(oldpart['start']) + "-" + str(oldpart['end'])+ " to " + str(tmppart['start']) + "-" + str(tmppart['end'])
273 type = tmppart['type']
274 device = dev
275 minor = part
276 start = int(new_start)
277 end = int(new_end)
278 if type == "ext2" or type == "ext3":
279 total_sectors = end - start + 1
280 # commands.getstatus("resize2fs " + device + str(minor) + " " + str(total_sectors) + "s")
281 # print "resize2fs " + device + str(minor) + " " + str(total_sectors) + "s"
282 elif type == "ntfs":
283 total_sectors = end - start + 1
284 total_bytes = int(total_sectors) * 512)
285 # commands.getstatus("ntfsresize --size " + str(total_bytes) + " " + device + str(minor))
286 # print "ntfsresize --size " + str(total_bytes) + " " + device + str(minor)
287 else:
288 start = float(self._sectors_to_megabytes(start))
289 end = float(self._sectors_to_megabytes(end))
290 # self._run_parted_command(device, "resize " + str(minor) + " " + str(start) + " " + str(end))
291 print " Deleting old minor " + str(part) + " to be recreated in 3rd pass"
292 # self._run_parted_command(dev, "rm " + str(part))
293 parted_disk.delete_partition(parted_disk.get_partition(part))
294 break
295 parted_disk.commit()
296 # Third pass to create new partition table
297 print " Third pass..."
298 for part in parts_new[dev]:
299 newpart = parts_new[dev][part]
300 new_start, new_end = newpart['start'], newpart['end']
301 if newpart['type'] == "extended":
302 print " Adding extended partition from " + str(newpart['start']) + " to " + str(newpart['end'])
303 self._add_partition(parted_disk, new_start, new_end, "extended", "")
304 elif int(part) < 5:
305 print " Adding primary partition from " + str(newpart['start']) + " to " + str(newpart['end'])
306 self._add_partition(parted_disk, new_start, new_end, "primary", newpart['type'])
307 elif int(part) > 4:
308 print " Adding logical partition from " + str(newpart['start']) + " to " + str(newpart['end'])
309 self._add_partition(parted_disk, new_start, new_end, "logical", newpart['type'])
310 if int(part) in parts_active and not newpart['format']:
311 print " Partition was previously active...setting"
312 parted_disk.get_partition(part).set_flag(1)
313 if int(part) in parts_lba and not newpart['format']:
314 print " Partition was previously LBA...setting"
315 parted_disk.get_partition(part).set_flag(7)
316 parted_disk.commit()
317

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20