/[gli]/branches/overhaul/src/GLIArchitectureTemplate.py
Gentoo

Contents of /branches/overhaul/src/GLIArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 131 - (hide annotations) (download) (as text)
Tue Nov 16 07:07:59 2004 UTC (14 years ago) by agaffney
Original Path: trunk/src/GLIArchitectureTemplate.py
File MIME type: text/x-python
File size: 35294 byte(s)
new size passed to ntfsresize in bytes instead of KiB

1 samyron 79 """
2     Gentoo Linux Installer
3    
4 agaffney 131 $Id: GLIArchitectureTemplate.py,v 1.12 2004/11/16 07:07:59 agaffney Exp $
5 samyron 79 Copyright 2004 Gentoo Technologies Inc.
6    
7    
8     The ArchitectureTemplate is largely meant to be an abstract class and an
9     interface (yes, it is both at the same time!). The purpose of this is to create
10     subclasses that populate all the methods with working methods for that architecture.
11     The only definitions that are filled in here are architecture independent.
12    
13     """
14    
15     import GLIUtility
16 samyron 102 from signal import SIGUSR1
17 agaffney 126 from GLIException import *
18 agaffney 127 # Until I switch my partition code to GLIUtility.spawn()
19     import commands
20 samyron 79
21     class ArchitectureTemplate:
22    
23 agaffney 108 def __init__(self,configuration=None, install_profile=None, client_controller=None):
24 samyron 79 self._configuration = configuration
25     self._install_profile = install_profile
26 agaffney 108 self._cc = client_controller
27 samyron 79
28 samyron 102 # This will get used a lot, so it's probably
29     # better to store it in a variable than to call
30     # this method 100000 times.
31     self._chroot_dir = self._configuration.get_root_mount_point()
32    
33 samyron 79 # These must be filled in by the subclass. _steps is a list of
34     # functions, that will carry out the installation. They must be
35     # in order.
36     #
37     # For example, self._steps might be: [preinstall, stage1, stage2, stage3, postinstall],
38     # where each entry is a function (with no arguments) that carries out the desired actions.
39     # Of course, steps will be different depending on the install_profile
40    
41     self._steps = []
42     self._architecture_name = "generic"
43    
44     def _depends(self, depends):
45     # Type checking
46     if type(depends) not in [ list, str, tuple ]:
47     raise "Dependencies must be a string or a list of strings"
48    
49     # If it is a string, change it to a list for parsing
50     if type(depends) == str:
51     depends = [ depends ]
52    
53     # Parse dependencies
54     for dependency in depends:
55     # If the dependency has not been satisfied, check to see if 'ignore' has been turned on
56     if not dependency in self._client_configuration.install_steps_completed:
57    
58     #If ignore is on, just print a warning
59     if self._install_profile.get_ignore_install_step_depends():
60     print "Warning: You chose to ignore install step dependencies. The " + dependency + " was not met. Ignoring."
61     #If ignore is off, then raise exception
62     else:
63     raise "InstallTemplateError", "Install step dependency not met!"
64    
65     # It is possible to override these methods in each Arch Template.
66     # It might be necessary to do so, if the arch needs something 'weird'.
67    
68     def stage1(self):
69     "Stage 1 install -- bootstraping"
70     # Dependency checking
71     self._depends("preinstall")
72    
73     # If we are doing a stage 1 install, then bootstrap
74     if self._install_profile.get_install_stage() == 1:
75 samyron 86 exitstatus = GLIUtility.spawn("/usr/portage/scripts/bootstrap.sh", True)
76 samyron 79 if not GLIUtility.exitsuccess(exitstatus):
77     raise Stage1Error('fatal','stage1', "Bootstrapping failed!")
78    
79     self._configuration.add_install_steps_completed("stage1")
80    
81     def stage2(self):
82     # Dependency checking
83     self._depends("stage1")
84    
85     # If we are doing a stage 1 or 2 install, then emerge system
86     if self._install_profile.get_install_stage() in [ 1, 2 ]:
87     exitstatus = GLIUtility.emerge("system")
88     if not GLIUtility.exitsuccess(exitstatus):
89     raise Stage2Error('fatal','stage2', "Building the system failed!")
90    
91     self._configuration.add_install_steps_completed("stage2")
92    
93     def preinstall(self):
94     if not os.path.isdir(self._configuration.get_root_mount_point()):
95 agaffney 126 os.makedirs(self._configuration.get_root_mount_point())
96 samyron 79
97     # Fetch and unpack the stage tarball here.
98     GLIUtility.fetch_and_unpack_tarball(self._install_profile.get_stage_tarball_uri(), self._configuration.get_root_mount_point(),keep_permissions=True)
99    
100 samyron 86 ret = GLIUtility.spawn("cp -L /etc/resolv.conf /mnt/gentoo/etc/resolv.conf",True)
101 samyron 79 if not GLIUtility.exitsuccess(ret):
102     raise CopyError('warning','preinstall','Could not copy resolv.conf!',True)
103    
104 samyron 86 ret = GLIUtility.spawn("mount -t proc none /mnt/gentoo /proc")
105 samyron 79 if not GLIUtility.exitsuccess(ret):
106     raise MountError('fatal','preinstall','Could not mount /proc')
107    
108     # Set USE flags here
109     # might want to rewrite/use _edit_config from the GLIInstallTemplate
110     # Then you should be done... at least with the preinstall.
111    
112 samyron 102 def notify_frontend(self):
113     os.kill(os.getpid(), SIGUSR1)
114    
115     def install_packages(self):
116     "Will install any extra software!"
117     # Dependency checking
118     self._depends("emerge system")
119     installpackages = self._install_profile.get_install_packages()
120     for package in installpackages:
121     status = GLIUtility.emerge(package)
122     if not GLIUtility.exit_success(status):
123     raise "InstallPackagesError", "Could not emerge " + package + "!"
124    
125 samyron 79 # This is part of the interface... subclasses MUST
126     # provide these methods filled in.
127     def stage3(self):
128     # This should probably start with building the kernel,
129     # that might be the only thing this actually needs
130     # to do.
131     pass
132    
133     def postinstall(self):
134     pass
135    
136     def partition(self):
137     pass
138 samyron 102
139     # **************************************************************************************
140    
141     def _add_to_runlevel(self, script_name, runlevel="default"):
142     "Adds the script named 'script_name' to the runlevel 'runlevel' in the chroot environement"
143    
144     # Do it
145     status = GLIUtility._run("rc-update add " + script_name + " " + runlevel, chroot=self._chroot_dir)
146     if not GLIUtility.exit_success(status):
147     raise "RunlevelAddError", "Failure adding " + script_name + " to runlevel " + runlevel + "!"
148    
149     def mount_local_partitions(self):
150     "Mounts all partitions that are on the local machine"
151     # Dependency checking
152     self._depends("partition_local_drives")
153    
154     def mount_network_shares(self):
155     "Mounts all network shares to the local machine"
156     # Dependency checking
157     self._depends([ "setup_network_pre", "mount_local_partitions" ])
158    
159     def fetch_sources_from_cd(self):
160     "Gets sources from CD (required for non-network installation)"
161     # Dependency checking
162     self._depends("unpack_tarball")
163    
164     def fetch_grp_from_cd(self):
165     "Gets grp binary packages from CD (required for non-network binary installation)"
166     # Dependency checking
167     self._depends("unpack_tarball")
168    
169     def configure_make_conf(self):
170     "Configures make.conf"
171     # Dependency checking
172     self._depends("prepare_chroot")
173    
174     # Get make.conf options
175     options = self._install_profile.get_make_conf()
176    
177     # For each configuration option...
178     for key in options.keys():
179    
180     # Add/Edit it into make.conf
181     GLIUtility.edit_config(self._chroot_dir + "/etc/make.conf", key, options[key])
182    
183     def install_portage_tree(self):
184     "Get/update the portage tree"
185     # Dependency checking
186     self._depends("prepare_chroot")
187    
188     # Check the type of portage tree fetching we'll do
189     # If it is custom, follow the path to the custom tarball and unpack it
190     if self._install_profile.get_portage_tree_sync_type() == "custom":
191    
192     # Get portage tree info
193     portage_tree_snapshot_uri = self._install_profile.get_portage_tree_snapshot_uri()
194    
195     # Fetch and unpack the tarball
196     self._fetch_and_unpack_tarball(portage_tree_snapshot_uri, self._client_configuration.get_root_mount_point() + "/usr/", self._client_configuration.get_root_mount_point() + "/")
197     if not GLIUtility.is_file(self._client_configuration.get_root_mount_point()+"/usr/portage/distfiles"):
198     exitstatus = self._run("mkdir /usr/portage/distfiles",True)
199     if exitstatus != 0:
200     raise "MkdirError","Making the distfiles directory failed."
201     exitstatus = self._run("cp /mnt/cdrom/distfiles/* "+self._client_configuration.get_root_mount_point()+"/usr/portage/distfiles/")
202     if exitstatus != 0:
203     raise "PortageError","Failed to copy the distfiles to the new system"
204     # If the type is webrsync, then run emerge-webrsync
205     elif self._install_profile.get_portage_tree_sync_type() == "webrsync":
206     exitstatus = self._run("emerge-webrsync", True)
207     if exitstatus != 0:
208     raise "EmergeWebRsyncError", "Failed to retrieve portage tree!"
209    
210     # Otherwise, just run emerge sync
211     else:
212     exitstatus = self._emerge("sync")
213     if exitstatus != 0:
214     raise "EmergeSyncError", "Failed to retrieve portage tree!"
215    
216     def set_timezone(self):
217     "Sets the timezone for the new environment"
218    
219     # Dependency checking
220     self._depends("unpack_tarball")
221     #self._process_desc("Setting the timezone")
222    
223     # Set symlink
224     if not os.access(self._client_configuration.get_root_mount_point() + "/etc/localtime", os.W_OK):
225     os.symlink(self._client_configuration.get_root_mount_point() + "/usr/share/zoneinfo/" + self._install_profile.get_time_zone(), self._client_configuration.get_root_mount_point() + "/etc/localtime")
226     if not (self._install_profile.get_time_zone() == "UTC"):
227     self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/rc.conf", "CLOCK", "local")
228    
229     def configure_fstab(self):
230     "Configures fstab"
231     # Dependency checking
232     self._depends("unpack_tarball")
233     newfstab = ""
234     partitions = self._install_profile.get_fstab()
235     for partition in partitions:
236     if not GLIUtility.is_file(self._client_configuration.get_root_mount_point()+partition):
237     exitstatus = self._run("mkdir " + partition, True)
238     if exitstatus != 0:
239     raise "MkdirError", "Making the mount point failed!"
240     newfstab += partitions[partition][0] + "\t " + partition + "\t " + partitions[partition][1]
241     newfstab += "\t " + partitions[partition][2] + "\t "
242     if partition == "/boot":
243     newfstab += "1 2\n"
244     elif partition == "/":
245     newfstab += "0 1\n"
246     else:
247     newfstab += "0 0\n"
248     newfstab += "none /proc proc defaults 0 0\n"
249     newfstab += "none /dev/shm tmpfs defaults 0 0\n"
250     if GLIUtility.is_device("/dev/cdroms/cdrom0"):
251     newfstab += "/dev/cdroms/cdrom0 /mnt/cdrom auto noauto,user 0 0\n"
252    
253     file_name = self._client_configuration.get_root_mount_point() + "/etc/fstab"
254     try:
255     shutil.move(file_name, file_name + ".OLDdefault")
256     except:
257     pass
258     f = open(file_name, 'w')
259     f.writelines(newfstab)
260     f.close()
261    
262    
263     def emerge_kernel_sources(self):
264     "Fetches desired kernel sources"
265     # Dependency checking
266     self._depends("emerge_system")
267     exitstatus = self._emerge(self._install_profile.get_kernel_source_pkg())
268     if exitstatus != 0:
269     raise "EmergeKernelSourcesError", "Could not retrieve kernel sources!"
270     try:
271     os.stat(self._client_configuration.get_root_mount_point() + "/usr/src/linux")
272     except:
273     kernels = os.listdir(self._client_configuration.get_root_mount_point()+"/usr/src")
274     found_a_kernel = False
275     counter = 0
276     while not found_a_kernel:
277     if kernels[counter][0:6]=="linux-":
278     exitstatus = self._run("ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux",True)
279     found_a_kernel = True
280     else:
281     counter = counter + 1
282    
283     def build_kernel(self):
284     "Builds kernel"
285     # Dependency checking
286     self._depends("emerge_kernel_sources")
287    
288     exitstatus = self._emerge("genkernel")
289     if exitstatus != 0:
290     raise "EmergeGenKernelError", "Could not emerge genkernel!"
291    
292    
293     # Null the genkernel_options
294     genkernel_options = ""
295    
296     # Get the uri to the kernel config
297     kernel_config_uri = self._install_profile.get_kernel_config_uri()
298    
299     # If the uri for the kernel config is not null, then
300     if kernel_config_uri != "":
301     self._get_uri(kernel_config_uri, self._client_configuration.get_root_mount_point() + "/root/kernel_config")
302     genkernel_options = genkernel_options + " --kernel-config=/root/kernel_config"
303    
304     # Decide whether to use bootsplash or not
305     if self._install_profile.get_kernel_bootsplash():
306     genkernel_options = genkernel_options + " --bootsplash"
307     else:
308     genkernel_options = genkernel_options + " --no-bootsplash"
309    
310     # This is code to choose whether or not genekernel will build an initrd or not
311     # Genkernel currently does not support this
312     #if self._install_profile.get_kernel_initrd():
313     # pass
314     #else:
315     # pass
316    
317     # Run genkernel in chroot
318     print "genkernel all " + genkernel_options
319     exitstatus = self._run("genkernel all " + genkernel_options, True)
320     if exitstatus != 0:
321     raise "KernelBuildError", "Could not build kernel!"
322    
323     def install_logging_daemon(self):
324     "Installs and sets up logger"
325     # Dependency checking
326     self._depends("emerge_system")
327    
328     # Get loggin daemon info
329     logging_daemon_pkg = self._install_profile.get_logging_daemon_pkg()
330     if logging_daemon_pkg:
331     # Emerge Logging Daemon
332     exitstatus = self._emerge(logging_daemon_pkg)
333     if exitstatus != 0:
334     raise "LoggingDaemonError", "Could not emerge " + logging_daemon_pkg + "!"
335    
336     # Add Logging Daemon to default runlevel
337     self._add_to_runlevel(logging_daemon_pkg)
338    
339     def install_cron_daemon(self):
340     "Installs and sets up cron"
341     # Dependency checking
342     self._depends("emerge_system")
343    
344     # Get cron daemon info
345     cron_daemon_pkg = self._install_profile.get_cron_daemon_pkg()
346     if cron_daemon_pkg:
347     # Emerge Cron Daemon
348     exitstatus = self._emerge(cron_daemon_pkg)
349     if exitstatus != 0:
350     raise "CronDaemonError", "Could not emerge " + cron_daemon_pkg + "!"
351    
352     # Add Cron Daemon to default runlevel
353     self._add_to_runlevel(cron_daemon_pkg)
354    
355     # If the Cron Daemon is not vixie-cron, run crontab
356     if cron_daemon_pkg != "vixie-cron":
357     exitstatus = self._run("crontab /etc/crontab", True)
358     if exitstatus != 0:
359     raise "CronDaemonError", "Failure making crontab!"
360    
361     def install_filesystem_tools(self):
362     "Installs and sets up fstools"
363     # Dependency checking
364     self._depends("emerge_system")
365    
366     # Get the list of file system tools to be installed
367     filesystem_tools = self._install_profile.get_filesystem_tools_pkgs()
368    
369     # If the fstools var is a str, convert it to a list
370     if type(filesystem_tools) == str:
371     filesystem_tools = [ filesystem_tools ]
372    
373     # For each fstool package in the list, install it
374     for package in filesystem_tools:
375     exitstatus = self._emerge(package)
376     if exitstatus != 0:
377     raise "FilesystemToolsError", "Could not emerge " + package + "!"
378    
379     def install_rp_pppoe(self):
380     "Installs rp-pppoe"
381     # Dependency checking
382     self._depends("emerge_system")
383    
384     # If user wants us to install rp-pppoe, then do so
385     if self._install_profile.get_install_rp_pppoe():
386     exitstatus = self._emerge("rp-pppoe")
387     if exitstatus != 0:
388     raise "RP-PPPOEError", "Could not emerge rp-pppoe!"
389    
390     # Should we add a section here to automatically configure rp-pppoe?
391     # I think it should go into the setup_network_post section
392     # What do you guys think?
393    
394     def install_pcmcia_cs(self):
395     "Installs and sets up pcmcia-cs"
396     # Dependency checking
397     self._depends("build_kernel")
398    
399     # If user wants us to install pcmcia-cs, then do so
400     if self._install_profile.get_install_pcmcia_cs():
401     exitstatus = self._emerge("pcmcia-cs")
402     if exitstatus != 0:
403     raise "PCMCIA-CSError", "Could not emerge pcmcia-cs!"
404    
405     # Add pcmcia-cs to the default runlevel
406     exitstatus = self._run("rc-update add pcmcia default", True)
407     if exitstatus != 0:
408     raise "PCMCIA-CSError", "Could not add pcmcia-cs to the default runlevel!"
409    
410     def install_bootloader(self):
411     "Installs and configures bootloader"
412     #
413     # THIS IS ARCHITECTURE DEPENDANT!!!
414     # This is the x86 way.. it uses grub
415     # Dependency checking
416     self._depends("build_kernel")
417    
418     if self._install_profile.get_boot_loader_pkg():
419     exitstatus = self._emerge(self._install_profile.get_boot_loader_pkg())
420     if exitstatus != 0:
421     raise "BootLoaderEmergeError", "Could not emerge bootloader!"
422     else:
423     pass
424    
425     boot_device = ""
426     boot_minor = ""
427     root_device = ""
428     root_minor = ""
429     grub_root_minor = ""
430     grub_boot_minor = ""
431     grub_boot_drive = ""
432     grub_root_drive = ""
433     minornum = 0
434     #Assign root to the root mount point to make lines more readable
435     root = self._client_configuration.get_root_mount_point()
436     file_name = root + "/boot/grub/bootdevice"
437     file_name1 = root + "/boot/grub/rootdevice"
438     file_name2 = root + "/boot/grub/device.map"
439     file_name3 = root + "/boot/grub/kernel_name"
440     foundboot = False
441     partitions = self._install_profile.get_fstab()
442     for partition in partitions:
443     #if find a /boot then stop.. else we'll take a / and overwrite with a /boot if we find it too.
444     if (partition == "/boot"):
445     #try to get the drive LETTER from /dev/hdc1 8th character
446     boot_minor = partitions[partition][0][8]
447     grub_boot_minor = str(int(boot_minor) - 1)
448     boot_device = partitions[partition][0][0:8]
449     foundboot = True
450     if ( (partition == "/") and (not foundboot) ):
451     boot_minor = partitions[partition][0][8]
452     grub_boot_minor = str(int(boot_minor) - 1)
453     boot_device = partitions[partition][0][0:8]
454     #Foundboot IS STILL FALSE
455     if partition == "/":
456     root_minor = partitions[partition][0][8]
457     grub_root_minor = str(int(root_minor) - 1)
458     root_device = partitions[partition][0][0:8]
459    
460     exitstatus0 = self._run("ls -l " + boot_device + " > " + file_name)
461     exitstatus1 = self._run("ls -l " + root_device + " > " + file_name1)
462     exitstatus2 = self._run("echo quit | "+ root+"/sbin/grub --device-map="+file_name2)
463     exitstatus3 = self._run("ls "+root+"/boot/kernel-* > "+file_name3)
464     exitstatus4 = self._run("ls "+root+"/boot/initrd-* >> "+file_name3)
465     if (exitstatus0 != 0) or (exitstatus1 != 0) or (exitstatus2 != 0) or (exitstatus3 != 0) or (exitstatus4 != 0):
466     raise "Bootloadererror", "Error in one of THE FOUR run commands"
467    
468     """
469     read the device map. sample looks like this:
470     (fd0) /dev/floppy/0
471     (hd0) /dev/ide/host2/bus0/target0/lun0/disc
472     (hd1) /dev/ide/host0/bus0/target0/lun0/disc
473     (hd2) /dev/ide/host0/bus0/target1/lun0/disc
474     """
475     e = open(file_name) #Looking for the boot device
476     ls_output = e.readlines()
477     e.close()
478     # looks like lr-xr-xr-x 1 root root 32 Oct 1 16:09 /dev/hda -> ide/host0/bus0/target0/lun0/disc
479     ls_output = ls_output[0].split(">")[-1]
480     ls_output = ls_output[1:]
481    
482     eb = open(file_name1) #Looking for the root device
483     ls_outputb = eb.readlines()
484     eb.close()
485     ls_outputb = ls_outputb[0].split(">")[-1]
486     ls_outputb = ls_outputb[1:]
487    
488     # Search for the key
489     f = open(file_name2)
490     file = f.readlines()
491     f.close()
492     for i in range(len(file)):
493     if file[i][11:] == ls_output:
494     #eurika we found the drivenum
495     grub_boot_drive = file[i][1:4]
496     if file[i][11:] == ls_outputb:
497     grub_root_drive = file[i][1:4]
498     if (not grub_root_drive) or (not grub_boot_drive):
499     raise "BootloaderError","Couldn't find the drive num in the list from the device.map"
500    
501     g = open(file_name3)
502     kernel_name = g.readlines()
503     g.close()
504     if not kernel_name[0]:
505     raise "BootloaderError","Error: We have no kernel in /boot to put in the grub.conf file!"
506     kernel_name = map(string.strip, kernel_name)
507     kernel_name[0] = kernel_name[0].split(root)[1]
508     kernel_name[1] = kernel_name[1].split(root)[1]
509     #-------------------------------------------------------------
510     #OK, now that we have all the info, let's build that grub.conf
511     newgrubconf = ""
512     newgrubconf += "default 0\ntimeout 30\n"
513     if foundboot: #we have a /boot
514     newgrubconf += "splashimage=(" + grub_boot_drive + "," + grub_boot_minor + ")/grub/splash.xpm.gz\n"
515     else: #we have / and /boot needs to be included
516     newgrubconf += "splashimage=(" + grub_boot_drive + "," + grub_boot_minor + ")/boot/grub/splash.xpm.gz\n"
517    
518     newgrubconf += "title=Gentoo Linux\n"
519     newgrubconf += "root (" + grub_boot_drive + "," + grub_boot_minor + ")\n"
520     if foundboot:
521     newgrubconf += "kernel " + kernel_name[0][5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
522     newgrubconf += root_device + root_minor + "\n"
523     newgrubconf += "initrd " + kernel_name[1][5:] + "\n"
524     else:
525     newgrubconf += "kernel /boot" + kernel_name[0][5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
526     newgrubconf += root_device + root_minor + "\n"
527     newgrubconf += "initrd /boot" + kernel_name[1][5:] + "\n"
528    
529     #-------------------------------------------------------------
530     #OK, now that the file is built. Install grub.
531     #cp /proc/mounts /etc/mtab
532     #grub-install --root-directory=/boot /dev/hda
533     #shutil.copy("/proc/mounts",root +"/etc/mtab")
534     grubinstallstring = "echo -en 'root ("+grub_boot_drive + "," + grub_boot_minor + ")\n"
535     if not self._install_profile.get_boot_loader_mbr():
536     grubinstallstring +="setup ("+grub_boot_drive + "," + grub_boot_minor + ")\n"
537     else:
538     grubinstallstring +="setup ("+grub_boot_drive+")\n"
539     grubinstallstring += "quit\n' | "+root+"/sbin/grub"
540     print grubinstallstring
541     exitstatus = self._run(grubinstallstring,True)
542     if exitstatus != 0:
543     raise "GrubInstallError", "Could not install grub!"
544    
545     #now make the grub.conf file
546     file_name = root + "/boot/grub/grub.conf"
547     try:
548     shutil.move(file_name, file_name + ".OLDdefault")
549     except:
550     pass
551     f = open(file_name, 'w')
552     f.writelines(newgrubconf)
553     f.close()
554    
555     def update_config_files(self):
556     "Runs etc-update (overwriting all config files), then re-configures the modified ones"
557     # Dependency checking
558     self._depends("emerge_system")
559    
560     # Run etc-update overwriting all config files
561     status = GLIUtility.spawn('echo "-5" | etc-update', chroot=self._chroot_dir)
562     if not GLIUtility.exit_success(status):
563     raise "EtcUpdateError", "Could not update config files!"
564    
565     self.configure_make_conf()
566     self.configure_fstab()
567    
568     def configure_rc_conf(self):
569     "Configures rc.conf"
570     # Dependency checking
571     self._depends("update_config_files")
572    
573     # Get make.conf options
574     options = self._install_profile.get_rc_conf()
575    
576     # For each configuration option...
577     for key in options.keys():
578    
579     # Add/Edit it into rc.conf
580     self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/rc.conf", key, option[key])
581    
582     def setup_network_post(self):
583     "Sets up the network for the first boot"
584     # Dependency checking
585     self._depends("unpack_tarball")
586    
587     # Get hostname, domainname and nisdomainname
588     hostname = self._install_profile.get_hostname()
589     domainname = self._install_profile.get_domainname()
590     nisdomainname = self._install_profile.get_nisdomainname()
591    
592     # Write the hostname to the hostname file
593     open(self._client_configuration.get_root_mount_point() + "/etc/hostname", "w").write(hostname + "\n")
594    
595     # Write the domainname to the nisdomainname file
596     if domainname:
597     open(self._client_configuration.get_root_mount_point() + "/etc/dnsdomainname", "w").write(domainname + "\n")
598    
599     # Write the nisdomainname to the nisdomainname file
600     if nisdomainname:
601     open(self._client_configuration.get_root_mount_point() + "/etc/nisdomainname", "w").write(nisdomainname + "\n")
602    
603     #
604     # EDIT THE /ETC/HOSTS FILE
605     #
606    
607     # The address we are editing is 127.0.0.1
608     hosts_ip = "127.0.0.1"
609    
610     # If the hostname is localhost
611     if hostname == "localhost":
612     # If a domainname is set
613     if domainname:
614     hosts_line = hostname + "." + domainname + "\t" + hostname
615     else:
616     hosts_line = hostname
617     # If the hostname is not localhost
618     else:
619     # If a domainname is set
620     if domainname:
621     hosts_line = hostname + "." + domainname + "\t" + hostname + "\tlocalhost"
622     else:
623     hosts_line = "localhost\t" + hostname
624    
625     # Write to file
626     self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/hosts", hosts_ip, hosts_line, True, '\t', False)
627    
628     #
629     # SET DEFAULT GATEWAY
630     #
631    
632     # Get default gateway
633     default_gateway = self._install_profile.get_default_gateway()
634    
635     # If the default gateway exists, add it
636     if default_gateway:
637     self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "gateway", default_gateway)
638    
639     #
640     # SET RESOLV INFO
641     #
642    
643     # Get dns servers
644     dns_servers = self._install_profile.get_dns_servers()
645    
646     # Clear the list
647     resolv_output = []
648    
649     # If dns servers are set
650     if dns_servers:
651    
652    
653     # Parse each dns server
654     for dns_server in dns_servers:
655     # Add the server to the output
656     resolv_output.append("nameserver " + dns_server +"\n")
657    
658     # If the domainname is set, then also output it
659     if domainname:
660     resolv_output.append("search " + domainname + "\n")
661    
662     # Output to file
663     resolve_conf = open(self._client_configuration.get_root_mount_point() + "/etc/resolv.conf", "w")
664     resolve_conf.writelines(resolv_output)
665     resolve_conf.close()
666    
667     #
668     # PARSE INTERFACES
669     #
670    
671     # Fetch interfaces
672     interfaces = self._install_profile.get_network_interfaces()
673    
674     # Parse each interface
675     for interface in interfaces.keys():
676    
677     # If we are going to load the network at boot...
678     if interfaces[interface][2]:
679    
680     # Add it to the default runlevel
681     exitstatus = self._run("rc-update add net." + interface + " default", True)
682     if exitstatus != 0:
683     raise "NetStartupError", "Cannot add interface " + interface + " to the default runlevel!"
684    
685     # Set what kind of interface it is
686     interface_type = interface[:3]
687    
688     # Check to see if there is a startup script for this interface, if there isn't link to the proper script
689     try:
690     os.stat(self._client_configuration.get_root_mount_point() + "/etc/init.d/net." + interface)
691     except:
692     os.symlink(self._client_configuration.get_root_mount_point() + "/etc/init.d/net." + interface_type + "0", self._client_configuration.get_root_mount_point() + "/etc/init.d/net." + interface)
693    
694     #
695     # ETHERNET
696     #
697     if interface_type == "eth":
698    
699     #
700     # STATIC IP
701     #
702     # If the post-install device info is not None, then it is a static ip addy
703     if interfaces[interface][1]:
704     ip = interfaces[interface][0]
705     broadcast = interfaces[interface][1]
706     netmask = interfaces[interface][2]
707     # aliases = interfaces[interface][1][3]
708     # alias_ips = []
709     # alias_broadcasts = []
710     # alias_netmasks = []
711    
712     # Write the static ip config to /etc/conf.d/net
713     self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "iface_" + interface, ip + " broadcast " + broadcast + " netmask " + netmask)
714    
715     # If aliases are set
716     # if aliases:
717    
718     # Parse aliases to format alias info
719     # for alias in aliases:
720     # alias_ips.append(alias[0])
721     # alias_broadcasts.append(alias[1])
722     # alias_netmasks.append(allias[2])
723    
724     # Once the alias info has been gathered, then write it out
725     # Alias ips first
726     # self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "alias_" + interface, string.join(alias_ips))
727     # Alias broadcasts next
728     # self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "broadcast_" + interface, string.join(alias_broadcasts))
729     # Alias netmasks last
730     # self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "netmask_" + interface, string.join(alias_netmasks))
731    
732     #
733     # DHCP IP
734     #
735     else:
736     self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "iface_" + interface, "dhcp")
737    
738     def set_root_password(self):
739     "Sets the root password"
740     # Dependency checking
741     self._depends("emerge_system")
742    
743     status = GLIUtility.spawn('echo "root:' + self._install_profile.get_root_pass_hash() + '" | chpasswd -e', chroot=self._chroot_dir)
744     if not GLIUtility.exit_success(status):
745     raise "SetRootPasswordError", "Failure to set root password!"
746    
747     def set_users(self):
748     "Sets up the new users for the system"
749     # Dependency checking
750     self._depends("emerge_system")
751    
752     # Loop for each user
753     for user in self._install_profile.get_users():
754    
755     # Get values from the tuple
756     username = user[0]
757     password_hash = user[1]
758     groups = user[2]
759     shell = user[3]
760     home_dir = user[4]
761     uid = user[5]
762     comment = user[6]
763    
764     options = [ "-m", "-p " + password_hash ]
765    
766     # If the groups are specified
767     if groups:
768    
769     # If just one group is listed as a string, make it a list
770     if groups == str:
771     groups = [ groups ]
772    
773     # If only 1 group is listed
774     if len(groups) == 1:
775     options.append("-G " + groups[0])
776    
777     # If there is more than one group
778     elif len(groups) > 1:
779     options.append('-G "' + string.join(groups, ",") + '"')
780    
781     # If a shell is specified
782     if shell:
783     options.append("-s " + shell)
784    
785     # If a home dir is specified
786     if home_dir:
787     options.append("-d " + home_dir)
788    
789     # If a UID is specified
790     if uid:
791     options.append("-u " + str(uid))
792    
793     # If a comment is specified
794     if comment:
795     options.append('-c "' + comment + '"')
796    
797     # Add the user
798     exitstatus = GLIUtility.spawn('useradd ' + string.join(options) + ' ' + username, chroot=self._chroot_dir)
799     if not GLIUtility.exit_success(exitstatus):
800     raise "AddUserError", "Failure to add user " + username
801 agaffney 111
802 agaffney 126 def _cylinders_to_sectors(self, minor, start, end, sectors_in_cylinder):
803 agaffney 127 cylinders = int(end) - int(start) + 1
804     total_sectors = cylinders * int(sectors_in_cylinder)
805     start_sector = int(start) * sectors_in_cylinder
806 agaffney 111 end_sector = start_sector + total_sectors - 1
807 agaffney 127 if int(minor) == 1 and start_sector == 0: start_sector = 63
808 agaffney 111 return (start_sector, end_sector)
809    
810 agaffney 126 def _sectors_to_megabytes(self, sectors, sector_bytes=512):
811 agaffney 111 return float((float(sectors) * sector_bytes)/ float(1024*1024))
812    
813 agaffney 131 def _sectors_to_bytes(self, sectors, sector_bytes=512):
814     return (int(sectors) * sector_bytes)
815 agaffney 111
816 agaffney 126 def _run_parted_command(self, device, cmd):
817 agaffney 127 parted_output = commands.getoutput("parted -s " + device + " " + cmd)
818 agaffney 111 print "parted -s " + device + " " + cmd
819    
820 agaffney 126 def _add_partition(self, device, start, end, type, fs):
821 agaffney 118 start = self._sectors_to_megabytes(start)
822     end = self._sectors_to_megabytes(end)
823 agaffney 127 self._run_parted_command(device, "mkpart " + type + " " + fs + " " + str(start) + " " + str(end))
824 agaffney 117 if type == "ntfs":
825     pass
826     elif type == "ext2" or type == "ext3":
827     pass
828     else:
829     pass
830 agaffney 111
831     def do_partitioning(self):
832 agaffney 127 import GLIStorageDevice, parted, pprint
833 agaffney 111
834     devices_old = {}
835     parts_old = {}
836     parts_new = self._install_profile.get_partition_tables()
837     drives = GLIStorageDevice.detect_devices()
838     drives.sort()
839     for drive in drives:
840     devices_old[drive] = GLIStorageDevice.Device(drive)
841     devices_old[drive].set_partitions_from_disk()
842     for part in devices_old.keys(): parts_old[part] = devices_old[part].get_install_profile_structure()
843    
844 agaffney 127 pp = pprint.PrettyPrinter(indent=4)
845     pp.pprint(parts_old)
846     pp.pprint(parts_new)
847    
848 agaffney 111 for dev in parts_old.keys():
849     parts_active = []
850 agaffney 123 parts_lba = []
851 agaffney 111 print "\nProcessing " + dev + "..."
852     parted_dev = parted.PedDevice.get(dev)
853     parted_disk = parted.PedDisk.new(parted_dev)
854     last_partition_touched = 0
855     sectors_in_cylinder = devices_old[dev]._sectors_in_cylinder
856     # First pass to delete old partitions that aren't resized
857     for part in parts_old[dev]:
858     oldpart = parts_old[dev][part]
859 agaffney 118 old_start, old_end = self._cylinders_to_sectors(part, oldpart['start'], oldpart['end'], sectors_in_cylinder)
860 agaffney 111 matchingminor = 0
861     for new_part in parts_new[dev]:
862     tmppart = parts_new[dev][new_part]
863 agaffney 118 new_start, new_end = self._cylinders_to_sectors(new_part, tmppart['start'], tmppart['end'], sectors_in_cylinder)
864 agaffney 127 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) == int(oldpart['end']):
865 agaffney 111 matchingminor = new_part
866     print " Deleting old minor " + str(part) + " to be recreated later"
867 agaffney 118 self._run_parted_command(dev, "rm " + str(part))
868 agaffney 111 break
869 agaffney 127 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
870 agaffney 111 matchingminor = new_part
871     print " Ignoring old minor " + str(part) + " to resize later"
872     break
873     if not matchingminor:
874     print " No match found...deleting partition " + str(part)
875 agaffney 118 self._run_parted_command(dev, "rm " + str(part))
876 agaffney 111 else:
877 agaffney 123 if parted_disk.get_partition(part).get_flag(1): # Active/boot
878 agaffney 111 print " Partition " + str(part) + " was active...noted"
879 agaffney 127 parts_active.append(int(matchingminor))
880 agaffney 123 if parted_disk.get_partition(part).get_flag(7): # LBA
881     print " Partition " + str(part) + " was LBA...noted"
882 agaffney 127 parts_lba.append(int(matchingminor))
883 agaffney 111 # Second pass to resize old partitions that need to be resized
884     print " Second pass..."
885     for part in parts_old[dev]:
886     oldpart = parts_old[dev][part]
887 agaffney 118 old_start, old_end = self._cylinders_to_sectors(part, oldpart['start'], oldpart['end'], sectors_in_cylinder)
888 agaffney 111 for new_part in parts_new[dev]:
889     tmppart = parts_new[dev][new_part]
890 agaffney 118 new_start, new_end = self._cylinders_to_sectors(new_part, tmppart['start'], tmppart['end'], sectors_in_cylinder)
891 agaffney 127 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
892 agaffney 111 print " Resizing old minor " + str(part) + " from " + str(oldpart['start']) + "-" + str(oldpart['end'])+ " to " + str(tmppart['start']) + "-" + str(tmppart['end'])
893 agaffney 118 type = tmppart['type']
894     device = dev
895     minor = part
896 agaffney 127 start = int(new_start)
897     end = int(new_end)
898 agaffney 118 if type == "ext2" or type == "ext3":
899     total_sectors = end - start + 1
900     commands.getstatus("resize2fs " + device + str(minor) + " " + str(total_sectors) + "s")
901     print "resize2fs " + device + str(minor) + " " + str(total_sectors) + "s"
902     elif type == "ntfs":
903     total_sectors = end - start + 1
904 agaffney 131 total_bytes = int(self._sectors_to_bytes(total_sectors))
905     commands.getstatus("ntfsresize --size " + str(total_bytes) + " " + device + str(minor))
906     print "ntfsresize --size " + str(total_bytes) + " " + device + str(minor)
907 agaffney 118 else:
908     start = float(self._sectors_to_megabytes(start))
909     end = float(self._sectors_to_megabytes(end))
910     self._run_parted_command(device, "resize " + str(minor) + " " + str(start) + " " + str(end))
911 agaffney 111 print " Deleting old minor " + str(part) + " to be recreated in 3rd pass"
912 agaffney 118 self._run_parted_command(dev, "rm " + str(part))
913 agaffney 111 break
914     # Third pass to create new partition table
915     print " Third pass..."
916     for part in parts_new[dev]:
917     newpart = parts_new[dev][part]
918 agaffney 118 new_start, new_end = self._cylinders_to_sectors(part, newpart['start'], newpart['end'], sectors_in_cylinder)
919 agaffney 111 if newpart['type'] == "extended":
920     print " Adding extended partition from " + str(newpart['start']) + " to " + str(newpart['end'])
921 agaffney 127 self._add_partition(dev, new_start, new_end, "extended", "")
922     elif int(part) < 5:
923 agaffney 111 print " Adding primary partition from " + str(newpart['start']) + " to " + str(newpart['end'])
924 agaffney 127 self._add_partition(dev, new_start, new_end, "primary", newpart['type'])
925     elif int(part) > 4:
926 agaffney 111 print " Adding logical partition from " + str(newpart['start']) + " to " + str(newpart['end'])
927 agaffney 127 self._add_partition(dev, new_start, new_end, "logical", newpart['type'])
928     if int(part) in parts_active and not newpart['format']:
929 agaffney 111 print " Partition was previously active...setting"
930 agaffney 118 self._run_parted_command(dev, "set " + str(part) + " boot on")
931 agaffney 127 if int(part) in parts_lba and not newpart['format']:
932 agaffney 123 print " Partition was previously LBA...setting"
933     self._run_parted_command(dev, "set " + str(part) + " lba on")

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20