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

Contents of /trunk/src/GLIArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 126 - (hide annotations) (download) (as text)
Tue Nov 16 04:04:58 2004 UTC (13 years, 11 months ago) by agaffney
File MIME type: text/x-python
File size: 35005 byte(s)
minor ArchTemplate fixes

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