/[gli]/trunk/src/GLIArchitectureTemplate.py
Gentoo

Contents of /trunk/src/GLIArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 133 - (hide annotations) (download) (as text)
Fri Nov 19 03:02:27 2004 UTC (13 years, 8 months ago) by agaffney
File MIME type: text/x-python
File size: 35227 byte(s)
split ArchTemplate's preinstall() into unpack_stage_tarball() and prepare_chroot()

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