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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1223 - (hide annotations) (download) (as text)
Sat Jan 7 17:12:00 2006 UTC (12 years, 11 months ago) by agaffney
Original Path: trunk/src/GLIArchitectureTemplate.py
File MIME type: text/x-python
File size: 71107 byte(s)
  src/GLIPortage.py:
  show 'Calculating dependencies for ...' in subprogress bar at beginning of
  emerge()
  src/GLIArchitectureTemplate.py:
  copy /etc/X11/gdm/gdm.conf.old into chroot if /etc/X11/gdm/gdm.conf exists
  in the chroot

1 samyron 79 """
2 codeman 851 # Copyright 1999-2005 Gentoo Foundation
3     # This source code is distributed under the terms of version 2 of the GNU
4     # General Public License as published by the Free Software Foundation, a copy
5     # of which can be found in the main directory of this project.
6 samyron 79 Gentoo Linux Installer
7    
8 agaffney 1223 $Id: GLIArchitectureTemplate.py,v 1.254 2006/01/07 17:12:00 agaffney Exp $
9 samyron 79
10     The ArchitectureTemplate is largely meant to be an abstract class and an
11     interface (yes, it is both at the same time!). The purpose of this is to create
12     subclasses that populate all the methods with working methods for that architecture.
13     The only definitions that are filled in here are architecture independent.
14    
15     """
16    
17 agaffney 782 import GLIUtility, GLILogger, os, string, sys, shutil, re, time
18 agaffney 1182 import GLIPortage
19 agaffney 126 from GLIException import *
20 samyron 79
21     class ArchitectureTemplate:
22 agaffney 509 ##
23 codeman 512 # Initialization of the ArchitectureTemplate. Called from some other arch template.
24     # @param selfconfiguration=None A Client Configuration
25     # @param install_profile=None An Install Profile
26 agaffney 587 # @param client_controller=None Client Controller. not same as configuration.
27 agaffney 108 def __init__(self,configuration=None, install_profile=None, client_controller=None):
28 codeman 200 self._client_configuration = configuration
29 samyron 79 self._install_profile = install_profile
30 agaffney 108 self._cc = client_controller
31 samyron 79
32 samyron 102 # This will get used a lot, so it's probably
33     # better to store it in a variable than to call
34     # this method 100000 times.
35 codeman 200 self._chroot_dir = self._client_configuration.get_root_mount_point()
36 codeman 314 self._logger = GLILogger.Logger(self._client_configuration.get_log_file())
37 agaffney 384 self._compile_logfile = "/tmp/compile_output.log"
38 codeman 995 self._debug = self._client_configuration.get_verbose()
39 agaffney 1182
40 agaffney 1205 self._portage = GLIPortage.GLIPortage(self._chroot_dir, self._install_profile.get_grp_install(), self._logger, self._debug, self._cc, self._compile_logfile)
41 agaffney 1182
42 codeman 801 # This will cleanup the logfile if it's a dead link (pointing
43     # to the chroot logfile when partitions aren't mounted, else
44     # no action needs to be taken
45 samyron 102
46 codeman 801 if os.path.islink(self._compile_logfile) and not os.path.exists(self._compile_logfile):
47     os.unlink(self._compile_logfile)
48    
49 robbat2 675 # cache the list of successfully mounted swap devices here
50     self._swap_devices = []
51    
52 samyron 79 # These must be filled in by the subclass. _steps is a list of
53     # functions, that will carry out the installation. They must be
54     # in order.
55     #
56     # For example, self._steps might be: [preinstall, stage1, stage2, stage3, postinstall],
57     # where each entry is a function (with no arguments) that carries out the desired actions.
58     # Of course, steps will be different depending on the install_profile
59 codeman 995
60 samyron 79 self._architecture_name = "generic"
61 agaffney 136 self._install_steps = [
62 agaffney 1164 { 'function': self.partition, 'name': "Partition", 'modes': ("normal", "stage4") },
63     { 'function': self.mount_local_partitions, 'name': "Mount local partitions", 'modes': ("normal", "stage4") },
64     { 'function': self.mount_network_shares, 'name': "Mount network (NFS) shares", 'modes': ("normal", "stage4") },
65     { 'function': self.unpack_stage_tarball, 'name': "Unpack stage tarball", 'modes': ("normal", "stage4", "chroot") },
66     { 'function': self.update_config_files, 'name': "Updating config files", 'modes': ("normal", "chroot") },
67     { 'function': self.configure_make_conf, 'name': "Configure /etc/make.conf", 'modes': ("normal", "chroot") },
68     { 'function': self.prepare_chroot, 'name': "Preparing chroot", 'modes': ("normal", "stage4", "chroot") },
69     { 'function': self.install_portage_tree, 'name': "Syncing the Portage tree", 'modes': ("normal", "chroot") },
70     { 'function': self.stage1, 'name': "Performing bootstrap", 'modes': ("normal", "chroot") },
71     { 'function': self.stage2, 'name': "Performing 'emerge system'", 'modes': ("normal", "chroot") },
72     { 'function': self.set_root_password, 'name': "Set the root password", 'modes': ("normal", "chroot") },
73     { 'function': self.set_timezone, 'name': "Setting timezone", 'modes': ("normal", "chroot") },
74     { 'function': self.emerge_kernel_sources, 'name': "Emerge kernel sources", 'modes': ("normal", "chroot") },
75     { 'function': self.build_kernel, 'name': "Building kernel", 'modes': ("normal", "chroot") },
76     { 'function': self.install_distcc, 'name': "Install distcc", 'modes': ("normal", "chroot") },
77     { 'function': self.install_mta, 'name': "Installing MTA", 'modes': ("normal", "chroot") },
78     { 'function': self.install_logging_daemon, 'name': "Installing system logger", 'modes': ("normal", "chroot") },
79     { 'function': self.install_cron_daemon, 'name': "Installing Cron daemon", 'modes': ("normal", "chroot") },
80     { 'function': self.install_filesystem_tools, 'name': "Installing filesystem tools", 'modes': ("normal", "chroot") },
81     { 'function': self.setup_network_post, 'name': "Configuring post-install networking", 'modes': ("normal", "chroot") },
82 codeman 1166 { 'function': self.install_bootloader, 'name': "Configuring and installing bootloader", 'modes': ("normal", "chroot") },
83     { 'function': self.setup_and_run_bootloader, 'name': "Setting up and running bootloader", 'modes': ( "normal", "stage4") },
84 agaffney 1164 { 'function': self.update_config_files, 'name': "Re-Updating config files", 'modes': ("normal", "chroot") },
85     # { 'function': self.configure_rc_conf, 'name': "Updating /etc/rc.conf", 'modes': ("normal", "stage4", "chroot") },
86     { 'function': self.set_users, 'name': "Add additional users.", 'modes': ("normal", "chroot") },
87     { 'function': self.install_packages, 'name': "Installing additional packages.", 'modes': ("normal", "chroot") },
88     # services for startup need to come after installing extra packages
89     # otherwise some of the scripts will not exist.
90     { 'function': self.set_services, 'name': "Setting up services for startup", 'modes': ("normal", "chroot") },
91     { 'function': self.run_post_install_script, 'name': "Running custom post-install script", 'modes': ("normal", "stage4", "chroot") },
92     { 'function': self.finishing_cleanup, 'name': "Cleanup and unmounting local filesystems.", 'modes': ("normal", "stage4", "chroot") }
93     ]
94 codeman 200
95 samyron 79
96 agaffney 509 ##
97 codeman 512 # Returns the steps and their comments in an array
98 agaffney 136 def get_install_steps(self):
99     return self._install_steps
100    
101 agaffney 509 ##
102 codeman 512 # Tells the frontend something
103     # @param type type of data
104     # @param data the data itself. usually a number.
105 codeman 201 def notify_frontend(self, type, data):
106     self._cc.addNotification(type, data)
107    
108 samyron 79 # It is possible to override these methods in each Arch Template.
109     # It might be necessary to do so, if the arch needs something 'weird'.
110    
111 agaffney 509 ##
112 codeman 512 # Private function to add a /etc/init.d/ script to the given runlevel in the chroot environement
113     # @param script_name the script to be added
114     # @param runlevel="default" the runlevel to add to
115 codeman 201 def _add_to_runlevel(self, script_name, runlevel="default"):
116 robbat2 656 if not GLIUtility.is_file(self._chroot_dir + '/etc/init.d/' + script_name):
117 codeman 710 #raise GLIException("RunlevelAddError", 'fatal', '_add_to_runlevel', "Failure adding " + script_name + " to runlevel " + runlevel + "!")
118     #This is not a fatal error. If the init script is important it will exist.
119     self._logger.log("ERROR! Failure adding" + script_name + " to runlevel " + runlevel + " because it was not found!")
120 codeman 995 if self._debug: self._logger.log("DEBUG: running rc-update add " + script_name + " " + runlevel + " in chroot.")
121 agaffney 451 status = GLIUtility.spawn("rc-update add " + script_name + " " + runlevel, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True)
122 codeman 216 if not GLIUtility.exitsuccess(status):
123 codeman 710 #raise GLIException("RunlevelAddError", 'fatal', '_add_to_runlevel', "Failure adding " + script_name + " to runlevel " + runlevel + "!")
124     #Again, an error here will not prevent a new system from booting. But it is important to log the error.
125     self._logger.log("ERROR! Could not add " + script_name + " to runlevel " + runlevel + ". returned a bad status code.")
126     else:
127     self._logger.log("Added "+script_name+" to runlevel "+runlevel)
128 codeman 201
129 agaffney 509 ##
130 agaffney 538 # Private Function. Will return a list of packages to be emerged for a given command. Not yet used.
131     # @param cmd full command to run ('/usr/portage/scripts/bootstrap.sh --pretend' or 'emerge -p system')
132     def _get_packages_to_emerge(self, cmd):
133 codeman 995 if self._debug: self._logger.log("DEBUG: _get_packages_to_emerge() called with '%s'" % cmd)
134 agaffney 865 return GLIUtility.spawn(cmd + r" 2>/dev/null | grep -e '\[ebuild' | sed -e 's:\[ebuild .\+ \] ::' -e 's: \[.\+\] ::' -e 's: \+$::'", chroot=self._chroot_dir, return_output=True)[1].strip().split("\n")
135 agaffney 538
136     ##
137 codeman 512 # Private function. For binary installs it will attempt to quickpkg packages that are on the livecd.
138     # @param package package to be quickpkg'd.
139 agaffney 865 def _quickpkg_deps(self, package, nodeps=False):
140 codeman 995 if self._debug:
141     self._logger.log("DEBUG: _quickpkg_deps() called with '%s'" % package)
142 agaffney 322 PKGDIR = "/usr/portage/packages"
143     PORTAGE_TMPDIR = "/var/tmp"
144 agaffney 415 make_conf = self._install_profile.get_make_conf()
145 codeman 995 if "PKGDIR" in make_conf and make_conf['PKGDIR']:
146     if self._debug: self._logger.log("DEBUG: overwriting PKGDIR with make_conf value." + make_conf['PKGDIR'])
147     PKGDIR = make_conf['PKGDIR']
148     if "PORTAGE_TMPDIR" in make_conf and make_conf['PORTAGE_TMPDIR']:
149 codeman 996 if self._debug: self._logger.log("DEBUG: overwriting PORTAGE_TMPDIR with make_conf value." + make_conf['PORTAGE_TMPDIR'])
150 codeman 995 PORTAGE_TMPDIR = make_conf['PORTAGE_TMPDIR']
151     if self._debug: self._logger.log("DEBUG: creating PKGDIR if necessary")
152 agaffney 451 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PKGDIR, logfile=self._compile_logfile, append_log=True)
153 codeman 995 if self._debug: self._logger.log("DEBUG: creating PORTAGE_TMPDIR if necessary")
154 agaffney 451 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PORTAGE_TMPDIR, logfile=self._compile_logfile, append_log=True)
155 agaffney 865 if nodeps:
156     packages = package.split()
157     else:
158     packages = self._get_packages_to_emerge("emerge -p " + package)
159 codeman 995 if self._debug: self._logger.log("DEBUG: packages obtained from _get_packages_to_emerge(): %s" % str(packages))
160 agaffney 324 for pkg in packages:
161 agaffney 728 if not pkg: continue
162 agaffney 998 if self._debug: self._logger.log("DEBUG: Trying to quickpkg '" + pkg + "'")
163 agaffney 784 pkgparts = pkg.split('/')
164     if not len(pkgparts) == 2: continue
165     if not GLIUtility.is_file(self._chroot_dir + PKGDIR + "/All/" + pkgparts[1] + ".tbz2"):
166 codeman 995 if self._debug: self._logger.log("DEBUG: running quickpkg on pkg: "+pkg)
167 agaffney 484 ret = GLIUtility.spawn("env PKGDIR='" + self._chroot_dir + PKGDIR + "' PORTAGE_TMPDIR='" + self._chroot_dir + PORTAGE_TMPDIR + "' quickpkg =" + pkg)
168 agaffney 698 if not GLIUtility.exitsuccess(ret):
169 agaffney 322 # This package couldn't be quickpkg'd. This may be an error in the future
170 codeman 995 self._logger.log("DEBUG: Package "+pkg+" could not be quickpkg'd. This may be an error in the future.")
171 agaffney 322
172 agaffney 509 ##
173 codeman 512 # Private Function. Will emerge a given package in the chroot environment.
174     # @param package package to be emerged
175     # @param binary=False defines whether to try a binary emerge (if GRP this gets ignored either way)
176     # @param binary_only=False defines whether to only allow binary emerges.
177 agaffney 1182 def _emerge(self, package, binary=True, binary_only=False):
178 codeman 314 #Error checking of this function is to be handled by the parent function.
179 agaffney 728 # self._logger.log("_emerge() called with: package='%s', binary='%s', binary_only='%s', grp_install='%s'" % (package, str(binary), str(binary_only), str(self._install_profile.get_grp_install())))
180 robbat2 652 # now short-circuit for GRP
181 agaffney 322 if self._install_profile.get_grp_install():
182 codeman 730 cmd="emerge -k " + package
183 robbat2 652 # now normal installs
184 codeman 201 else:
185 agaffney 322 if binary_only:
186 codeman 730 cmd="emerge -K " + package
187 agaffney 322 elif binary:
188 codeman 730 cmd="emerge -k " + package
189 agaffney 322 else:
190 codeman 730 cmd="emerge " + package
191 codeman 201
192 robbat2 648 self._logger.log("Calling emerge: "+cmd)
193     return GLIUtility.spawn(cmd, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True)
194    
195 agaffney 509 ##
196 agaffney 1162 # Returns the full version of a package to be emerged when given a short name. This looks in PORDIR
197 agaffney 857 # @param package short name of package (i.e. xorg-x11)
198 agaffney 999 def _portage_best_visible(self, package, chroot=True):
199     chroot_dir = None
200     if chroot:
201     chroot_dir = self._chroot_dir
202     return GLIUtility.spawn("portageq best_visible / " + package, chroot=chroot_dir, return_output=True)[1].strip()
203 agaffney 857
204     ##
205 agaffney 1162 # Returns the full version of an installed package when given a short name. This looks in vdb
206     # @param package short name of package (i.e. xorg-x11)
207     def _portage_best_version(self, package, chroot=True):
208     chroot_dir = None
209     if chroot:
210     chroot_dir = self._chroot_dir
211     return GLIUtility.spawn("portageq best_version / " + package, chroot=chroot_dir, return_output=True)[1].strip()
212    
213     ##
214 codeman 512 # Private Function. Will edit a config file and insert a value or two overwriting the previous value
215     # (actually it only just comments out the old one)
216 robbat2 655 # @param filename file to be edited
217     # @param newvalues a dictionary of VARIABLE:VALUE pairs
218     # @param delimeter='=' what is between the key and the value
219 codeman 560 # @param quotes_around_value=True whether there are quotes around the value or not (ex. "local" vs. localhost)
220 robbat2 655 # @param only_value=False Ignore the keys and output only a value.
221     # @param create_file=True Create the file if it does not exist.
222     def _edit_config(self, filename, newvalues, delimeter='=', quotes_around_value=True, only_value=False,create_file=True):
223     # don't use 'file' as a normal variable as it conflicts with the __builtin__.file
224 agaffney 729 newvalues = newvalues.copy()
225 agaffney 999 if self._debug: self._logger.log("DEBUG: _edit_config() called with " + str(newvalues)+" and flags: "+delimeter + "quotes: "+str(quotes_around_value)+" value: "+str(only_value))
226 robbat2 655 if GLIUtility.is_file(filename):
227     f = open(filename)
228     contents = f.readlines()
229     f.close()
230     elif create_file:
231     contents = []
232     else:
233 codeman 209 raise GLIException("NoSuchFileError", 'notice','_edit_config',filename + ' does not exist!')
234 codeman 201
235     for key in newvalues.keys():
236 agaffney 917 newline = ""
237 codeman 560 if key == "SPACER":
238 agaffney 917 newline = "\n"
239 agaffney 576 elif key == "COMMENT":
240 agaffney 917 newline = '# ' + newvalues[key] + "\n"
241 agaffney 576 elif newvalues[key] == "##comment##" or newvalues[key] == "##commented##":
242 agaffney 917 newline = '#' + key + delimeter + '""' + "\n"
243 codeman 201 else:
244 codeman 560 if quotes_around_value:
245     newvalues[key] = '"' + newvalues[key] + '"'
246     #Only the printing of values is required.
247     if only_value:
248 agaffney 917 newline = newvalues[key] + "\n"
249 codeman 560 else:
250 agaffney 917 newline = key + delimeter + newvalues[key] + "\n"
251 agaffney 921 add_at_line = len(contents)
252 agaffney 919 for i in range(len(contents)):
253     if newline == contents[i]:
254     break
255     if contents[i].startswith(key + delimeter):
256     contents[i] = "#" + contents[i]
257 agaffney 920 add_at_line = i + 1
258 agaffney 921 else:
259     contents.insert(add_at_line, newline)
260 agaffney 999 if self._debug: self._logger.log("DEBUG: Contents of file "+filename+": "+str(contents))
261 codeman 201 f = open(filename,'w')
262 robbat2 655 f.writelines(contents)
263 codeman 201 f.flush()
264     f.close()
265 codeman 314 self._logger.log("Edited Config file "+filename)
266 codeman 201
267 agaffney 509 ##
268 codeman 512 # Stage 1 install -- bootstraping the system
269     # If we are doing a stage 1 install, then bootstrap
270 samyron 79 def stage1(self):
271     if self._install_profile.get_install_stage() == 1:
272 codeman 314 self._logger.mark()
273     self._logger.log("Starting bootstrap.")
274 agaffney 385 pkgs = self._get_packages_to_emerge("/usr/portage/scripts/bootstrap.sh --pretend")
275 agaffney 1097 if self._debug: self._logger.log("DEBUG: Packages to emerge: "+str(pkgs)+". Now running bootstrap.sh")
276 agaffney 451 exitstatus = GLIUtility.spawn("/usr/portage/scripts/bootstrap.sh", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
277 samyron 79 if not GLIUtility.exitsuccess(exitstatus):
278 samyron 186 raise GLIException("Stage1Error", 'fatal','stage1', "Bootstrapping failed!")
279 codeman 314 self._logger.log("Bootstrap complete.")
280 agaffney 385
281 agaffney 509 ##
282 codeman 512 # Stage 2 install -- emerge -e system
283     # If we are doing a stage 1 or 2 install, then emerge system
284 samyron 79 def stage2(self):
285     if self._install_profile.get_install_stage() in [ 1, 2 ]:
286 codeman 314 self._logger.mark()
287     self._logger.log("Starting emerge system.")
288 codeman 512 pkgs = self._get_packages_to_emerge("emerge -p system") #currently quite the useless
289 agaffney 1098 if self._debug: self._logger.log("DEBUG: Packages to emerge: "+str(pkgs)+"/ Now running emerge --emptytree system")
290 codeman 476 exitstatus = self._emerge("--emptytree system")
291 samyron 79 if not GLIUtility.exitsuccess(exitstatus):
292 samyron 186 raise GLIException("Stage2Error", 'fatal','stage2', "Building the system failed!")
293 codeman 314 self._logger.log("Emerge system complete.")
294 agaffney 384
295 agaffney 509 ##
296 codeman 512 # Unpacks the stage tarball that has been specified in the profile (it better be there!)
297 agaffney 133 def unpack_stage_tarball(self):
298     if not os.path.isdir(self._chroot_dir):
299 codeman 995 if self._debug: self._logger.log("DEBUG: making the chroot dir:"+self._chroot_dir)
300 agaffney 133 os.makedirs(self._chroot_dir)
301 agaffney 765 if self._install_profile.get_install_stage() == 3 and self._install_profile.get_dynamic_stage3():
302 agaffney 731 # stage3 generation code here
303     if not GLIUtility.is_file("/usr/livecd/systempkgs.txt"):
304 agaffney 761 raise GLIException("CreateStage3Error", "fatal", "unpack_stage_tarball", "Required file /usr/livecd/systempkgs.txt does not exist")
305 agaffney 999 try:
306     syspkgs = open("/usr/livecd/systempkgs.txt", "r")
307     systempkgs = syspkgs.readlines()
308     syspkgs.close()
309     except:
310     raise GLIException("CreateStage3Error", "fatal", "unpack_stage_tarball", "Could not open /usr/livecd/systempkgs.txt")
311     # make_conf = self._install_profile.get_make_conf()
312     # PKGDIR = '/usr/portage/packages'
313     # PORTAGE_TMPDIR = '/var/tmp'
314     # if 'PKGDIR' in make_conf: PKGDIR = make_conf['PKGDIR']
315     # if 'PORTAGE_TMPDIR' in make_conf: PORTAGE_TMPDIR = make_conf['PORTAGE_TMPDIR']
316     # GLIUtility.spawn("mkdir -p " + self._chroot_dir + PKGDIR)
317     # GLIUtility.spawn("mkdir -p " + self._chroot_dir + PORTAGE_TMPDIR)
318     # os.environ["PKGDIR"] = self._chroot_dir + PKGDIR
319     # os.environ["PORTAGE_TMPDIR"] = self._chroot_dir + PORTAGE_TMPDIR
320     # ret = GLIUtility.spawn("quickpkg $(sed -e 's:^:=:' /usr/livecd/systempkgs.txt)", display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
321     # if not GLIUtility.exitsuccess(ret):
322     # raise GLIException("CreateStage3Error", "fatal", "unpack_stage_tarball", "Could not quickpkg necessary packages for generating stage3")
323     # ret = GLIUtility.spawn("env ROOT=" + self._chroot_dir + " emerge -KO $(sed -e 's:^:=:' /usr/livecd/systempkgs.txt)", display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
324     # if not GLIUtility.exitsuccess(ret):
325     # raise GLIException("CreateStage3Error", "fatal", "unpack_stage_tarball", "Could not emerge necessary packages in chroot for generating stage3")
326     # del os.environ["PKGDIR"]
327     # del os.environ["PORTAGE_TMPDIR"]
328     syspkglen = len(systempkgs)
329     for i, pkg in enumerate(systempkgs):
330     pkg = pkg.strip()
331     self.notify_frontend("progress", (float(i) / (syspkglen+1), "Copying " + pkg + " (" + str(i+1) + "/" + str(syspkglen) + ")"))
332 agaffney 1198 self._portage.copy_pkg_to_chroot(pkg, True)
333 agaffney 999 self.notify_frontend("progress", (float(syspkglen) / (syspkglen+1), "Finishing"))
334 agaffney 731 GLIUtility.spawn("cp /etc/make.conf " + self._chroot_dir + "/etc/make.conf")
335     GLIUtility.spawn("ln -s `readlink /etc/make.profile` " + self._chroot_dir + "/etc/make.profile")
336 agaffney 813 GLIUtility.spawn("cp -f /etc/inittab.old " + self._chroot_dir + "/etc/inittab")
337 agaffney 731 chrootscript = r"""
338     #!/bin/bash
339 agaffney 384
340 agaffney 731 source /etc/make.conf
341     export LDPATH="/usr/lib/gcc-lib/${CHOST}/$(cd /usr/lib/gcc-lib/${CHOST} && ls -1 | head -n 1)"
342    
343     ldconfig $LDPATH
344     gcc-config 1
345     env-update
346     source /etc/profile
347     modules-update
348     [ -f /usr/bin/binutils-config ] && binutils-config 1
349 agaffney 811 source /etc/profile
350 agaffney 1001 #mount -t proc none /proc
351     #cd /dev
352     #/sbin/MAKEDEV generic-i386
353     #umount /proc
354     [ -f /lib/udev-state/devices.tar.bz2 ] && tar -C /dev -xjf /lib/udev-state/devices.tar.bz2
355 agaffney 731 """
356     script = open(self._chroot_dir + "/tmp/extrastuff.sh", "w")
357     script.write(chrootscript)
358     script.close()
359     GLIUtility.spawn("chmod 755 /tmp/extrastuff.sh && /tmp/extrastuff.sh", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
360     GLIUtility.spawn("rm -rf /var/tmp/portage/* /usr/portage /tmp/*", chroot=self._chroot_dir)
361 agaffney 999 self.notify_frontend("progress", (1, "Done"))
362 agaffney 731 self._logger.log("Stage3 was generated successfully")
363     else:
364 codeman 995 self._logger.log("Unpacking tarball: "+self._install_profile.get_stage_tarball_uri())
365 agaffney 980 GLIUtility.fetch_and_unpack_tarball(self._install_profile.get_stage_tarball_uri(), self._chroot_dir, temp_directory=self._chroot_dir, keep_permissions=True, cc=self._cc)
366 agaffney 731 self._logger.log(self._install_profile.get_stage_tarball_uri()+" was unpacked.")
367    
368 agaffney 509 ##
369 codeman 512 # Prepares the Chroot environment by copying /etc/resolv.conf and mounting proc and dev
370 agaffney 133 def prepare_chroot(self):
371 codeman 215 # Copy resolv.conf to new env
372     try:
373 codeman 995 if self._debug: self._logger.log("DEBUG: copying /etc/resolv.conf over.")
374 codeman 215 shutil.copy("/etc/resolv.conf", self._chroot_dir + "/etc/resolv.conf")
375     except:
376     pass
377 codeman 995 if self._debug: self._logger.log("DEBUG: mounting proc")
378 codeman 215 ret = GLIUtility.spawn("mount -t proc none "+self._chroot_dir+"/proc")
379 samyron 79 if not GLIUtility.exitsuccess(ret):
380 codeman 215 raise GLIException("MountError", 'fatal','prepare_chroot','Could not mount /proc')
381 agaffney 1173 bind_mounts = [ '/dev' ]
382 robbat2 675 uname = os.uname()
383     if uname[0] == 'Linux' and uname[2].split('.')[1] == '6':
384     bind_mounts.append('/sys')
385 agaffney 1173 if self._debug: self._logger.log("DEBUG: bind-mounting " + ", ".join(bind_mounts))
386 robbat2 665 for mount in bind_mounts:
387     ret = GLIUtility.spawn('mount -o bind %s %s%s' % (mount,self._chroot_dir,mount))
388     if not GLIUtility.exitsuccess(ret):
389     raise GLIException("MountError", 'fatal','prepare_chroot','Could not mount '+mount)
390 codeman 995 if self._debug: self._logger.log("DEBUG: copying logfile to new system!")
391 agaffney 384 GLIUtility.spawn("mv " + self._compile_logfile + " " + self._chroot_dir + self._compile_logfile + " && ln -s " + self._chroot_dir + self._compile_logfile + " " + self._compile_logfile)
392 codeman 314 self._logger.log("Chroot environment ready.")
393 samyron 79
394 agaffney 509 ##
395 codeman 512 # Installs a list of packages specified in the profile. Will install any extra software!
396     # In the future this function will lead to better things. It may even wipe your ass for you.
397 samyron 102 def install_packages(self):
398     installpackages = self._install_profile.get_install_packages()
399 agaffney 1182 if installpackages:
400 agaffney 1205 # pkglist = self._portage.get_deps(" ".join(installpackages))
401     # if self._debug: self._logger.log("install_packages(): pkglist is " + str(pkglist))
402     # for i, pkg in enumerate(pkglist):
403     # if self._debug: self._logger.log("install_packages(): processing package " + pkg)
404     # self.notify_frontend("progress", (float(i) / len(pkglist), "Emerging " + pkg + " (" + str(i) + "/" + str(len(pkglist)) + ")"))
405     # if not self._portage.get_best_version_vdb("=" + pkg):
406     # status = self._emerge("=" + pkg)
407     # if not GLIUtility.exitsuccess(status):
408     # raise GLIException("ExtraPackagesError", "fatal", "install_packages", "Could not emerge " + pkg + "!")
409     # else:
410     # try:
411     # self._portage.copy_pkg_to_chroot(pkg)
412     # except:
413     # raise GLIException("ExtraPackagesError", "fatal", "install_packages", "Could not emerge " + pkg + "!")
414     self._portage.emerge(installpackages)
415 agaffney 867
416 agaffney 1182 if GLIUtility.is_file(self._chroot_dir + "/etc/X11"):
417     # Copy the xorg.conf from the LiveCD if they installed xorg-x11
418 codeman 848 exitstatus = GLIUtility.spawn("cp /etc/X11/xorg.conf " + self._chroot_dir + "/etc/X11/xorg.conf")
419     if not GLIUtility.exitsuccess(exitstatus):
420     self._logger.log("Could NOT copy the xorg configuration from the livecd to the new system!")
421     else:
422     self._logger.log("xorg.conf copied to new system. X should be ready to roll!")
423 agaffney 1223 if GLIUtility.is_file(self._chroot_dir + "/etc/X11/gdm/gdm.conf"):
424     GLIUtility.spawn("cp -f /etc/X11/gdm/gdm.conf.old " + self._chroot_dir + "/etc/X11/gdm/gdm.conf")
425 samyron 102
426 agaffney 509 ##
427 codeman 512 # Will set the list of services to runlevel default. This is a temporary solution!
428 codeman 361 def set_services(self):
429     services = self._install_profile.get_services()
430     for service in services:
431 robbat2 675 self._add_to_runlevel(service)
432    
433 agaffney 509 ##
434 codeman 512 # Will grab partition info from the profile and mount all partitions with a specified mountpoint (and swap too)
435 samyron 102 def mount_local_partitions(self):
436 codeman 213 #{ 1: { 'end': 1999871, 'format': False, 'mb': 0,
437     #'mountopts': '', 'mountpoint': '', 'start': 63, 'type': 'linux-swap'},
438     #2: { 'end': 240121727, 'format': False, 'mb': 0, 'mountopts': '',
439     #'mountpoint': '', 'start': 1999872, 'type': 'ext3'}}
440 codeman 216
441 codeman 213 parts = self._install_profile.get_partition_tables()
442 codeman 215 parts_to_mount = {}
443 codeman 213 for device in parts:
444 agaffney 599 tmp_partitions = parts[device].get_install_profile_structure()
445 agaffney 810 tmp_minor = -1
446 agaffney 795 for minor in tmp_partitions:
447     if not tmp_partitions[minor]['type'] == "free":
448     tmp_minor = minor
449     break
450 agaffney 781 time.sleep(1)
451 agaffney 810 if tmp_minor == -1: continue
452 agaffney 781 # now sleep until it exists
453 agaffney 795 while not GLIUtility.is_file(parts[device].get_device() + str(tmp_minor)):
454 codeman 995 if self._debug: self._logger.log("DEBUG: Waiting for device node " + parts[device].get_device() + str(tmp_minor) + " to exist...")
455 agaffney 781 time.sleep(1)
456     # one bit of extra sleep is needed, as there is a blip still
457     time.sleep(1)
458 agaffney 599 for partition in tmp_partitions:
459 agaffney 600 mountpoint = tmp_partitions[partition]['mountpoint']
460     mountopts = tmp_partitions[partition]['mountopts']
461     minor = str(int(tmp_partitions[partition]['minor']))
462     partition_type = tmp_partitions[partition]['type']
463 codeman 213 if mountpoint:
464     if mountopts:
465 agaffney 693 mountopts = "-o " + mountopts + " "
466 codeman 213 if partition_type:
467 agaffney 1068 if partition_type == "fat32" or partition_type == "fat16": partition_type = "vfat"
468 agaffney 693 partition_type = "-t " + partition_type + " "
469     parts_to_mount[mountpoint]= (mountopts, partition_type, device + minor)
470 codeman 215
471 codeman 213 if partition_type == "linux-swap":
472 agaffney 693 ret = GLIUtility.spawn("swapon " + device + minor)
473 agaffney 272 if not GLIUtility.exitsuccess(ret):
474 agaffney 693 self._logger.log("ERROR! : Could not activate swap (" + device + minor + ")!")
475 robbat2 675 else:
476 agaffney 693 self._swap_devices.append(device + minor)
477     sorted_list = parts_to_mount.keys()
478 codeman 215 sorted_list.sort()
479    
480 codeman 780 if not GLIUtility.is_file(self._chroot_dir):
481 codeman 995 if self._debug: self._logger.log("DEBUG: making the chroot dir")
482 codeman 780 exitstatus = GLIUtility.spawn("mkdir -p " + self._chroot_dir)
483     if not GLIUtility.exitsuccess(exitstatus):
484     raise GLIException("MkdirError", 'fatal','mount_local_partitions', "Making the ROOT mount point failed!")
485     else:
486     self._logger.log("Created root mount point")
487 codeman 215 for mountpoint in sorted_list:
488     mountopts = parts_to_mount[mountpoint][0]
489     partition_type = parts_to_mount[mountpoint][1]
490 agaffney 692 partition = parts_to_mount[mountpoint][2]
491 agaffney 693 if not GLIUtility.is_file(self._chroot_dir + mountpoint):
492 codeman 995 if self._debug: self._logger.log("DEBUG: making mountpoint: "+mountpoint)
493 codeman 215 exitstatus = GLIUtility.spawn("mkdir -p " + self._chroot_dir + mountpoint)
494 agaffney 698 if not GLIUtility.exitsuccess(exitstatus):
495 codeman 215 raise GLIException("MkdirError", 'fatal','mount_local_partitions', "Making the mount point failed!")
496 codeman 780 else:
497 agaffney 1100 self._logger.log("Created mountpoint " + mountpoint)
498 agaffney 693 ret = GLIUtility.spawn("mount " + partition_type + mountopts + partition + " " + self._chroot_dir + mountpoint, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
499 codeman 215 if not GLIUtility.exitsuccess(ret):
500 codeman 314 raise GLIException("MountError", 'fatal','mount_local_partitions','Could not mount a partition')
501 robbat2 742 # double check in /proc/mounts
502     # This current code doesn't work and needs to be fixed, because there is a case that it is needed for - robbat2
503     #ret, output = GLIUtility.spawn('awk \'$2 == "%s" { print "Found" }\' /proc/mounts | head -n1' % (self._chroot_dir + mountpoint), display_on_tty8=True, return_output=True)
504     #if output.strip() != "Found":
505     # raise GLIException("MountError", 'fatal','mount_local_partitions','Could not mount a partition (failed in double-check)')
506 agaffney 693 self._logger.log("Mounted mountpoint: " + mountpoint)
507    
508 agaffney 509 ##
509 codeman 512 # Mounts all network shares to the local machine
510 samyron 102 def mount_network_shares(self):
511 codeman 226 """
512     <agaffney> it'll be much easier than mount_local_partitions
513 codeman 248 <agaffney> make sure /etc/init.d/portmap is started
514     <agaffney> then mount each one: mount -t nfs -o <mountopts> <host>:<export> <mountpoint>
515 codeman 226 """
516     nfsmounts = self._install_profile.get_network_mounts()
517     for netmount in nfsmounts:
518 agaffney 266 if netmount['type'] == "NFS" or netmount['type'] == "nfs":
519     mountopts = netmount['mountopts']
520 codeman 226 if mountopts:
521 agaffney 693 mountopts = "-o " + mountopts
522 agaffney 266 host = netmount['host']
523     export = netmount['export']
524     mountpoint = netmount['mountpoint']
525 agaffney 693 if not GLIUtility.is_file(self._chroot_dir + mountpoint):
526 codeman 226 exitstatus = GLIUtility.spawn("mkdir -p " + self._chroot_dir + mountpoint)
527 agaffney 698 if not GLIUtility.exitsuccess(exitstatus):
528 codeman 226 raise GLIException("MkdirError", 'fatal','mount_network_shares', "Making the mount point failed!")
529 codeman 995 else:
530     if self._debug: self._logger.log("DEBUG: mounting nfs mount")
531 agaffney 693 ret = GLIUtility.spawn("mount -t nfs " + mountopts + " " + host + ":" + export + " " + self._chroot_dir + mountpoint, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
532 codeman 226 if not GLIUtility.exitsuccess(ret):
533 codeman 314 raise GLIException("MountError", 'fatal','mount_network_shares','Could not mount an NFS partition')
534 agaffney 693 self._logger.log("Mounted netmount at mountpoint: " + mountpoint)
535     else:
536     self._logger.log("Netmount type " + netmount['type'] + " not supported...skipping " + netmount['mountpoint'])
537 codeman 314
538 codeman 836
539 agaffney 509 ##
540 codeman 512 # Configures the new /etc/make.conf
541 samyron 102 def configure_make_conf(self):
542     # Get make.conf options
543 robbat2 675 make_conf = self._install_profile.get_make_conf()
544 samyron 102
545     # For each configuration option...
546 robbat2 677 filename = self._chroot_dir + "/etc/make.conf"
547 agaffney 1208 # self._edit_config(filename, {"COMMENT": "GLI additions ===>"})
548 robbat2 675 for key in make_conf.keys():
549 samyron 102 # Add/Edit it into make.conf
550 robbat2 677 self._edit_config(filename, {key: make_conf[key]})
551 agaffney 1208 # self._edit_config(filename, {"COMMENT": "<=== End GLI additions"})
552 robbat2 677
553 codeman 314 self._logger.log("Make.conf configured")
554 robbat2 664 # now make any directories that emerge needs, otherwise it will fail
555     # this must take place before ANY calls to emerge.
556     # otherwise emerge will fail (for PORTAGE_TMPDIR anyway)
557 robbat2 675 # defaults first
558     # this really should use portageq or something.
559 robbat2 664 PKGDIR = '/usr/portage/packages'
560     PORTAGE_TMPDIR = '/var/tmp'
561     PORT_LOGDIR = None
562     PORTDIR_OVERLAY = None
563 robbat2 675 # now other stuff
564 robbat2 664 if 'PKGDIR' in make_conf: PKGDIR = make_conf['PKGDIR']
565     if 'PORTAGE_TMPDIR' in make_conf: PORTAGE_TMPDIR = make_conf['PORTAGE_TMPDIR']
566     if 'PORT_LOGDIR' in make_conf: PORT_LOGDIR = make_conf['PORT_LOGDIR']
567     if 'PORTDIR_OVERLAY' in make_conf: PORTDIR_OVERLAY = make_conf['PORTDIR_OVERLAY']
568 codeman 995 if self._debug: self._logger.log("DEBUG: making PKGDIR if necessary: "+PKGDIR)
569 robbat2 664 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PKGDIR, logfile=self._compile_logfile, append_log=True)
570 codeman 995 if self._debug: self._logger.log("DEBUG: making PORTAGE_TMPDIR if necessary: "+PORTAGE_TMPDIR)
571 robbat2 664 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PORTAGE_TMPDIR, logfile=self._compile_logfile, append_log=True)
572     if PORT_LOGDIR != None:
573 codeman 995 if self._debug: self._logger.log("DEBUG: making PORT_LOGDIR if necessary: "+PORT_LOGDIR)
574 robbat2 664 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PORT_LOGDIR, logfile=self._compile_logfile, append_log=True)
575     if PORTDIR_OVERLAY != None:
576 codeman 995 if self._debug: self._logger.log("DEBUG: making PORTDIR_OVERLAY if necessary "+PORTDIR_OVERLAY)
577 robbat2 664 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PORTDIR_OVERLAY, logfile=self._compile_logfile, append_log=True)
578 samyron 102
579 agaffney 509 ##
580 codeman 512 # This will get/update the portage tree. If you want to snapshot or mount /usr/portage use "custom".
581 samyron 102 def install_portage_tree(self):
582     # Check the type of portage tree fetching we'll do
583     # If it is custom, follow the path to the custom tarball and unpack it
584 agaffney 533
585     # This is a hack to copy the LiveCD's rsync into the chroot since it has the sigmask patch
586 codeman 995 if self._debug: self._logger.log("DEBUG: Doing the hack where we copy the LiveCD's rsync into the chroot since it has the sigmask patch")
587 agaffney 539 GLIUtility.spawn("cp -a /usr/bin/rsync " + self._chroot_dir + "/usr/bin/rsync")
588     GLIUtility.spawn("cp -a /usr/lib/libpopt* " + self._chroot_dir + "/usr/lib")
589 samyron 102
590 codeman 831 sync_type = self._install_profile.get_portage_tree_sync_type()
591     if sync_type == "snapshot" or sync_type == "custom": # Until this is finalized
592    
593 samyron 102 # Get portage tree info
594     portage_tree_snapshot_uri = self._install_profile.get_portage_tree_snapshot_uri()
595 codeman 216 if portage_tree_snapshot_uri:
596     # Fetch and unpack the tarball
597 codeman 995 if self._debug: self._logger.log("DEBUG: grabbing custom snapshot uri: "+portage_tree_snapshot_uri)
598 agaffney 981 GLIUtility.fetch_and_unpack_tarball(portage_tree_snapshot_uri, self._chroot_dir + "/usr/", self._chroot_dir + "/", cc=self._cc)
599 agaffney 1180 if GLIUtility.is_file("/usr/livecd/metadata.tar.bz2"):
600     GLIUtility.fetch_and_unpack_tarball("/usr/livecd/metadata.tar.bz2", self._chroot_dir + "/", self._chroot_dir + "/", cc=self._cc)
601 codeman 314 self._logger.log("Portage tree install was custom.")
602 codeman 831 elif sync_type == "sync":
603 codeman 995 if self._debug: self._logger.log("DEBUG: starting emerge sync")
604     exitstatus = GLIUtility.spawn("emerge sync", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
605     if not GLIUtility.exitsuccess(exitstatus):
606     self._logger.log("ERROR! Could not sync the portage tree using emerge sync. Falling back to emerge-webrsync as a backup.")
607     sync_type = "webrsync"
608     else:
609     self._logger.log("Portage tree sync'd")
610 samyron 102 # If the type is webrsync, then run emerge-webrsync
611 codeman 831 elif sync_type == "webrsync":
612 codeman 995 if self._debug: self._logger.log("DEBUG: starting emerge webrsync")
613 agaffney 451 exitstatus = GLIUtility.spawn("emerge-webrsync", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
614 agaffney 698 if not GLIUtility.exitsuccess(exitstatus):
615 codeman 831 raise GLIException("EmergeWebRsyncError", 'fatal','install_portage_tree', "Failed to retrieve portage tree using webrsync!")
616 codeman 314 self._logger.log("Portage tree sync'd using webrsync")
617 codeman 831 # Otherwise, spit out a message because its probably a bad thing.
618 samyron 102 else:
619 codeman 831 self._logger.log("NOTICE! No valid portage tree sync method was selected. This will most likely result in a failed installation unless the tree is mounted.")
620 codeman 314
621 agaffney 509 ##
622 codeman 512 # Sets the timezone for the new environment
623 samyron 102 def set_timezone(self):
624 codeman 512
625 samyron 102 # Set symlink
626 codeman 475 if os.access(self._chroot_dir + "/etc/localtime", os.W_OK):
627 codeman 995 if self._debug: self._logger.log("DEBUG: /etc/localtime already exists, removing it so it can be symlinked")
628 agaffney 551 GLIUtility.spawn("rm "+self._chroot_dir + "/etc/localtime")
629 codeman 995 if self._debug: self._logger.log("DEBUG: running ln -s ../usr/share/zoneinfo/" + self._install_profile.get_time_zone() + " /etc/localtime")
630 agaffney 551 GLIUtility.spawn("ln -s ../usr/share/zoneinfo/" + self._install_profile.get_time_zone() + " /etc/localtime", chroot=self._chroot_dir)
631 samyron 102 if not (self._install_profile.get_time_zone() == "UTC"):
632 codeman 995 if self._debug: self._logger.log("DEBUG: timezone was not UTC, setting CLOCK to local. This may be overwritten later.")
633 codeman 216 self._edit_config(self._chroot_dir + "/etc/rc.conf", {"CLOCK":"local"})
634 codeman 314 self._logger.log("Timezone set.")
635 samyron 102
636 agaffney 509 ##
637 codeman 512 # Configures /etc/fstab on the new envorinment
638 samyron 102 def configure_fstab(self):
639     newfstab = ""
640 codeman 216 parts = self._install_profile.get_partition_tables()
641     for device in parts:
642 agaffney 599 tmp_partitions = parts[device].get_install_profile_structure()
643     for partition in tmp_partitions:
644 agaffney 600 mountpoint = tmp_partitions[partition]['mountpoint']
645     minor = str(int(tmp_partitions[partition]['minor']))
646     partition_type = tmp_partitions[partition]['type']
647     mountopts = tmp_partitions[partition]['mountopts']
648 agaffney 481 if not mountopts.strip(): mountopts = "defaults"
649 codeman 216 if mountpoint:
650     if not GLIUtility.is_file(self._chroot_dir+mountpoint):
651 codeman 995 if self._debug: self._logger.log("DEBUG: making mountpoint: "+mountpoint)
652 codeman 217 exitstatus = GLIUtility.spawn("mkdir -p " + self._chroot_dir + mountpoint)
653 agaffney 698 if not GLIUtility.exitsuccess(exitstatus):
654 codeman 217 raise GLIException("MkdirError", 'fatal','configure_fstab', "Making the mount point failed!")
655 codeman 216 newfstab += device+minor+"\t "+mountpoint+"\t "+partition_type+"\t "+mountopts+"\t\t "
656     if mountpoint == "/boot":
657     newfstab += "1 2\n"
658     elif mountpoint == "/":
659     newfstab += "0 1\n"
660     else:
661     newfstab += "0 0\n"
662     if partition_type == "linux-swap":
663     newfstab += device+minor+"\t none swap sw 0 0\n"
664 samyron 102 newfstab += "none /proc proc defaults 0 0\n"
665     newfstab += "none /dev/shm tmpfs defaults 0 0\n"
666     if GLIUtility.is_device("/dev/cdroms/cdrom0"):
667     newfstab += "/dev/cdroms/cdrom0 /mnt/cdrom auto noauto,user 0 0\n"
668 agaffney 161
669     for netmount in self._install_profile.get_network_mounts():
670     if netmount['type'] == "nfs":
671     newfstab += netmount['host'] + ":" + netmount['export'] + "\t" + netmount['mountpoint'] + "\tnfs\t" + netmount['mountopts'] + "\t0 0\n"
672 samyron 102
673 codeman 201 file_name = self._chroot_dir + "/etc/fstab"
674 samyron 102 try:
675 codeman 995 if self._debug: self._logger.log("DEBUG: backing up original fstab")
676 samyron 102 shutil.move(file_name, file_name + ".OLDdefault")
677     except:
678 codeman 995 self._logger.log("ERROR: could not backup original fstab.")
679     if self._debug: self._logger.log("DEBUG: Contents of new fstab: "+newfstab)
680 samyron 102 f = open(file_name, 'w')
681     f.writelines(newfstab)
682     f.close()
683 codeman 314 self._logger.log("fstab configured.")
684 samyron 102
685 agaffney 509 ##
686 codeman 512 # Fetches desired kernel sources, unless you're using a livecd-kernel in which case it does freaky stuff.
687 samyron 102 def emerge_kernel_sources(self):
688 codeman 560 self._logger.log("Starting emerge_kernel")
689 codeman 314 kernel_pkg = self._install_profile.get_kernel_source_pkg()
690 agaffney 401 # if kernel_pkg:
691 robbat2 649 # Special case, no kernel installed
692     if kernel_pkg == "none":
693     return
694     # Special case, livecd kernel
695     elif kernel_pkg == "livecd-kernel":
696 codeman 995 if self._debug: self._logger.log("DEBUG: starting livecd-kernel setup")
697 agaffney 1214 self.notify_frontend("progress", (0, "Copying livecd-kernel to chroot"))
698 agaffney 1215 self._portage.copy_pkg_to_chroot(self._portage.get_best_version_vdb("livecd-kernel"))
699 agaffney 1214 self.notify_frontend("progress", (1, "Done copying livecd-kernel to chroot"))
700 agaffney 1208
701     exitstatus = self._portage.emerge("coldplug")
702 codeman 996 self._logger.log("Coldplug emerged. Now they should be added to the boot runlevel.")
703 codeman 476 self._add_to_runlevel("coldplug", runlevel="boot")
704 agaffney 1005
705 agaffney 1006 # Extra modules from kernelpkgs.txt...disabled until I can figure out why it sucks
706     # try:
707     # kernpkgs = open("/usr/livecd/kernelpkgs.txt", "r")
708     # pkgs = ""
709     # for line in kernpkgs.readlines():
710     # pkgs += line.strip() + " "
711     # kernpkgs.close()
712     # except:
713     # raise GLIException("EmergeColdplugError", 'fatal','build_kernel', "Could not read kernelpkgs.txt")
714     # exitstatus = self._emerge(pkgs)
715     # if not GLIUtility.exitsuccess(exitstatus):
716     # raise GLIException("EmergeExtraKernelModulesError", 'fatal','build_kernel', "Could not emerge extra kernel packages")
717     # self._logger.log("Extra kernel packages emerged.")
718 agaffney 1005
719 robbat2 649 # normal case
720 codeman 434 else:
721 agaffney 1208 exitstatus = self._portage.emerge(kernel_pkg)
722     # if not GLIUtility.exitsuccess(exitstatus):
723     # raise GLIException("EmergeKernelSourcesError", 'fatal','emerge_kernel_sources',"Could not retrieve kernel sources!")
724 codeman 314 try:
725     os.stat(self._chroot_dir + "/usr/src/linux")
726     except:
727     kernels = os.listdir(self._chroot_dir+"/usr/src")
728 codeman 995 if self._debug: self._logger.log("DEBUG: no /usr/src/linux found. found kernels: "+kernels)
729 codeman 314 found_a_kernel = False
730     counter = 0
731     while not found_a_kernel:
732     if kernels[counter][0:6]=="linux-":
733 codeman 995 if self._debug: self._logger.log("DEBUG: found one. linking it. running: ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux in the chroot.")
734 codeman 314 exitstatus = GLIUtility.spawn("ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux",chroot=self._chroot_dir)
735 agaffney 698 if not GLIUtility.exitsuccess(exitstatus):
736 codeman 314 raise GLIException("EmergeKernelSourcesError", 'fatal','emerge_kernel_sources',"Could not make a /usr/src/linux symlink")
737     found_a_kernel = True
738     else:
739     counter = counter + 1
740     self._logger.log("Kernel sources:"+kernel_pkg+" emerged and /usr/src/linux symlinked.")
741 samyron 102
742 agaffney 509 ##
743 codeman 512 # Builds the kernel using genkernel or regularly if given a custom .config file in the profile
744 samyron 102 def build_kernel(self):
745 codeman 314 self._logger.mark()
746     self._logger.log("Starting build_kernel")
747 robbat2 681
748     build_mode = self._install_profile.get_kernel_build_method()
749    
750 agaffney 401 # No building necessary if using the LiveCD's kernel/initrd
751 robbat2 649 # or using the 'none' kernel bypass
752 codeman 995 if self._install_profile.get_kernel_source_pkg() in ["livecd-kernel","none"]:
753     if self._debug: self._logger.log("DEBUG: using "+self._install_profile.get_kernel_source_pkg()+ " so skipping this function.")
754 robbat2 649 return
755 samyron 102 # Get the uri to the kernel config
756     kernel_config_uri = self._install_profile.get_kernel_config_uri()
757 robbat2 686
758     # is there an easier way to do this?
759 codeman 996 if self._debug: self._logger.log("DEBUG: running command: awk '/^PATCHLEVEL/{print $3}' /usr/src/linux/Makefile in chroot.")
760 robbat2 689 ret, kernel_major = GLIUtility.spawn("awk '/^PATCHLEVEL/{print $3}' /usr/src/linux/Makefile",chroot=self._chroot_dir,return_output=True)
761 robbat2 686 # 6 == 2.6 kernel, 4 == 2.4 kernel
762     kernel_major = int(kernel_major)
763 codeman 1170 if self._debug: self._logger.log("DEBUG: kernel major version is: "+str(kernel_major))
764 robbat2 689 #Copy the kernel .config to the proper location in /usr/src/linux
765     if kernel_config_uri != '':
766     try:
767 codeman 995 if self._debug: self._logger.log("DEBUG: grabbing kernel config from "+kernel_config_uri+" and putting it in "+self._chroot_dir + "/var/tmp/kernel_config")
768 robbat2 689 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/var/tmp/kernel_config")
769     except:
770     raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not copy kernel config!")
771    
772     # the && stuff is important so that we can catch any errors.
773     kernel_compile_script = "#!/bin/bash\n"
774     kernel_compile_script += "cp /var/tmp/kernel_config /usr/src/linux/.config && "
775     kernel_compile_script += "cd /usr/src/linux && "
776     # required for 2.[01234] etc kernels
777     if kernel_major in [0,1,2,3,4]:
778     kernel_compile_script += " yes 'n' | make oldconfig && make symlinks && make dep"
779     # not strictly needed, but recommended by upstream
780     else: #elif kernel_major in [5,6]:
781     kernel_compile_script += "make prepare"
782 robbat2 686
783     # bypass to install a kernel, but not compile it
784 robbat2 689 if build_mode == "none":
785 robbat2 652 return
786 robbat2 686 # this mode is used to install kernel sources, and have then configured
787     # but not actually build the kernel. This is needed for netboot
788     # situations when you have packages that require kernel sources
789     # to build.
790     elif build_mode == "prepare-only":
791 codeman 995 if self._debug: self._logger.log("DEBUG: writing kernel script with contents: "+kernel_compile_script)
792 robbat2 689 f = open(self._chroot_dir+"/var/tmp/kernel_script", 'w')
793     f.writelines(kernel_compile_script)
794     f.close()
795     #Build the kernel
796 codeman 995 if self._debug: self._logger.log("DEBUG: running: chmod u+x "+self._chroot_dir+"/var/tmp/kernel_script")
797 robbat2 689 exitstatus1 = GLIUtility.spawn("chmod u+x "+self._chroot_dir+"/var/tmp/kernel_script")
798 codeman 995 if self._debug: self._logger.log("DEBUG: running: /var/tmp/kernel_script in chroot.")
799 robbat2 689 exitstatus2 = GLIUtility.spawn("/var/tmp/kernel_script", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
800 codeman 995 if not GLIUtility.exitsuccess(exitstatus1):
801     raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not handle prepare-only build! died on chmod.")
802     if not GLIUtility.exitsuccess(exitstatus2):
803     raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not handle prepare-only build! died on running of kernel script.")
804 robbat2 689 #i'm sure i'm forgetting something here.
805     #cleanup
806     exitstatus = GLIUtility.spawn("rm -f "+self._chroot_dir+"/var/tmp/kernel_script "+self._chroot_dir+"/var/tmp/kernel_config")
807     #it's not important if this fails.
808     self._logger.log("prepare-only build complete")
809 robbat2 686 # Genkernel mode, including custom kernel_config. Initrd always on.
810 codeman 995 elif build_mode == "genkernel":
811     if self._debug: self._logger.log("DEBUG: build_kernel(): starting emerge genkernel")
812 agaffney 1208 exitstatus = self._portage.emerge("genkernel")
813     # if not GLIUtility.exitsuccess(exitstatus):
814     # raise GLIException("EmergeGenKernelError", 'fatal','build_kernel', "Could not emerge genkernel!")
815 codeman 314 self._logger.log("Genkernel emerged. Beginning kernel compile.")
816 codeman 282 # Null the genkernel_options
817     genkernel_options = ""
818    
819     # If the uri for the kernel config is not null, then
820     if kernel_config_uri != "":
821 codeman 995 if self._debug: self._logger.log("DEBUG: build_kernel(): getting kernel config "+kernel_config_uri)
822 robbat2 678 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/var/tmp/kernel_config")
823     genkernel_options = genkernel_options + " --kernel-config=/var/tmp/kernel_config"
824 codeman 282
825     # Decide whether to use bootsplash or not
826     if self._install_profile.get_kernel_bootsplash():
827 codeman 1220 genkernel_options = genkernel_options + " --gensplash"
828 codeman 282 else:
829 codeman 1220 genkernel_options = genkernel_options + " --no-gensplash"
830 codeman 282 # Run genkernel in chroot
831 codeman 435 #print "genkernel all " + genkernel_options
832 codeman 995 if self._debug: self._logger.log("DEBUG: build_kernel(): running: genkernel all " + genkernel_options + " in chroot.")
833 agaffney 451 exitstatus = GLIUtility.spawn("genkernel all " + genkernel_options, chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
834 agaffney 698 if not GLIUtility.exitsuccess(exitstatus):
835 codeman 282 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build kernel!")
836 codeman 395
837 agaffney 727 # exitstatus = self._emerge("hotplug")
838     # if not GLIUtility.exitsuccess(exitstatus):
839     # raise GLIException("EmergeHotplugError", 'fatal','build_kernel', "Could not emerge hotplug!")
840     # self._logger.log("Hotplug emerged.")
841 agaffney 1208 exitstatus = self._portage.emerge("coldplug")
842     # if not GLIUtility.exitsuccess(exitstatus):
843     # raise GLIException("EmergeColdplugError", 'fatal','build_kernel', "Could not emerge coldplug!")
844 codeman 395 self._logger.log("Coldplug emerged. Now they should be added to the default runlevel.")
845    
846 agaffney 727 # self._add_to_runlevel("hotplug")
847 codeman 361 self._add_to_runlevel("coldplug", runlevel="boot")
848 codeman 314 self._logger.log("Genkernel complete.")
849 codeman 685 elif build_mode == "custom": #CUSTOM CONFIG
850 samyron 102
851 robbat2 686 kernel_compile_script += " && make && make modules && make modules_install"
852 codeman 287
853     #Ok now that it's built, copy it to /boot/kernel-* for bootloader code to find it
854     if self._client_configuration.get_architecture_template() == "x86":
855 robbat2 686 kernel_compile_script += " && cp /usr/src/linux/arch/i386/boot/bzImage /boot/kernel-custom\n"
856 codeman 751 elif self._client_configuration.get_architecture_template() == "amd64":
857     kernel_compile_script += " && cp /usr/src/linux/arch/x86_64/boot/bzImage /boot/kernel-custom\n"
858     elif self._client_configuration.get_architecture_template() == "ppc":
859     kernel_compile_script += " && cp /usr/src/linux/vmlinux /boot/kernel-custom\n"
860 codeman 995 if self._debug: self._logger.log("DEBUG: build_kernel(): writing custom kernel script: "+kernel_compile_script)
861 robbat2 652 f = open(self._chroot_dir+"/var/tmp/kernel_script", 'w')
862 codeman 287 f.writelines(kernel_compile_script)
863     f.close()
864 codeman 282 #Build the kernel
865 codeman 995 if self._debug: self._logger.log("DEBUG: build_kernel(): running: chmod u+x "+self._chroot_dir+"/var/tmp/kernel_script")
866 robbat2 652 exitstatus1 = GLIUtility.spawn("chmod u+x "+self._chroot_dir+"/var/tmp/kernel_script")
867 codeman 995 if self._debug: self._logger.log("DEBUG: build_kernel(): running: /var/tmp/kernel_script in chroot")
868 robbat2 652 exitstatus2 = GLIUtility.spawn("/var/tmp/kernel_script", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
869 codeman 995 if not GLIUtility.exitsuccess(exitstatus1):
870     raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build custom kernel! died on chmod.")
871     if not GLIUtility.exitsuccess(exitstatus2):
872     raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build custom kernel! died on running of kernel script.")
873 codeman 287
874 codeman 282 #i'm sure i'm forgetting something here.
875 codeman 288 #cleanup
876 robbat2 678 exitstatus = GLIUtility.spawn("rm -f "+self._chroot_dir+"/var/tmp/kernel_script "+self._chroot_dir+"/var/tmp/kernel_config")
877 codeman 288 #it's not important if this fails.
878 codeman 314 self._logger.log("Custom kernel complete")
879    
880 agaffney 509 ##
881 codeman 907 # Installs and starts up distccd if the user has it set, so that it will get used for the rest of the install
882     def install_distcc(self):
883     if self._install_profile.get_install_distcc():
884 codeman 995 if self._debug: self._logger.log("DEBUG: install_distcc(): we ARE installing distcc")
885     if self._debug: self._logger.log("DEBUG: install_distcc(): running: USE='-*' emerge --nodeps sys-devel/distcc in chroot.")
886 codeman 911 exitstatus = GLIUtility.spawn("USE='-*' emerge --nodeps sys-devel/distcc", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
887 codeman 907 if not GLIUtility.exitsuccess(exitstatus):
888     self._logger.log("ERROR! : Could not emerge distcc!")
889     else:
890     self._logger.log("distcc emerged.")
891    
892     ##
893 robbat2 652 # Installs mail MTA. Does not put into runlevel, as this is not simple with MTAs.
894     def install_mta(self):
895 agaffney 733 # Get MTA info
896 robbat2 652 mta_pkg = self._install_profile.get_mta_pkg()
897     if mta_pkg:
898 agaffney 733 # Emerge MTA
899 codeman 995 if self._debug: self._logger.log("DEBUG: install_mta(): installing mta: "+mta_pkg)
900 agaffney 1208 exitstatus = self._portage.emerge(mta_pkg)
901     # if not GLIUtility.exitsuccess(exitstatus):
902     # raise GLIException("MTAError", 'fatal','install_mta', "Could not emerge " + mta_pkg + "!")
903 robbat2 652 self._logger.log("MTA installed: "+mta_pkg)
904 agaffney 733
905 robbat2 652 ##
906 codeman 512 # Installs and sets up logging daemon on the new system. adds to runlevel too.
907 samyron 102 def install_logging_daemon(self):
908     # Get loggin daemon info
909     logging_daemon_pkg = self._install_profile.get_logging_daemon_pkg()
910     if logging_daemon_pkg:
911     # Emerge Logging Daemon
912 codeman 995 if self._debug: self._logger.log("DEBUG: install_logging_daemon: emerging "+logging_daemon_pkg)
913 agaffney 1208 exitstatus = self._portage.emerge(logging_daemon_pkg)
914     # if not GLIUtility.exitsuccess(exitstatus):
915     # raise GLIException("LoggingDaemonError", 'fatal','install_logging_daemon', "Could not emerge " + logging_daemon_pkg + "!")
916 samyron 102
917     # Add Logging Daemon to default runlevel
918 robbat2 656 # After we find the name of it's initscript
919     # This current code is a hack, and should be better.
920     initscript = logging_daemon_pkg[(logging_daemon_pkg.find('/')+1):]
921 codeman 995 if self._debug: self._logger.log("DEBUG: install_logging_daemon: adding "+initscript+" to runlevel")
922 robbat2 656 self._add_to_runlevel(initscript)
923 codeman 314 self._logger.log("Logging daemon installed: "+logging_daemon_pkg)
924 agaffney 509 ##
925 codeman 512 # Installs and sets up cron package.
926 samyron 102 def install_cron_daemon(self):
927     # Get cron daemon info
928     cron_daemon_pkg = self._install_profile.get_cron_daemon_pkg()
929     if cron_daemon_pkg:
930 agaffney 806 if cron_daemon_pkg == "none":
931     self._logger.log("Skipping installation of cron daemon")
932     else:
933     # Emerge Cron Daemon
934 codeman 995 if self._debug: self._logger.log("DEBUG: install_cron_daemon: emerging "+cron_daemon_pkg)
935 agaffney 1208 exitstatus = self._portage.emerge(cron_daemon_pkg)
936     # if not GLIUtility.exitsuccess(exitstatus):
937     # raise GLIException("CronDaemonError", 'fatal', 'install_cron_daemon', "Could not emerge " + cron_daemon_pkg + "!")
938 samyron 102
939 agaffney 806 # Add Cron Daemon to default runlevel
940     # After we find the name of it's initscript
941     # This current code is a hack, and should be better.
942     initscript = cron_daemon_pkg[(cron_daemon_pkg.find('/')+1):]
943 codeman 995 if self._debug: self._logger.log("DEBUG: install_cron_daemon: adding "+initscript+" to runlevel")
944 agaffney 806 self._add_to_runlevel(initscript)
945    
946     # If the Cron Daemon is not vixie-cron, run crontab
947     if "vixie-cron" not in cron_daemon_pkg:
948 codeman 995 if self._debug: self._logger.log("DEBUG: install_cron_daemon: running: crontab /etc/crontab in chroot.")
949 agaffney 806 exitstatus = GLIUtility.spawn("crontab /etc/crontab", chroot=self._chroot_dir, display_on_tty8=True)
950     if not GLIUtility.exitsuccess(exitstatus):
951     raise GLIException("CronDaemonError", 'fatal', 'install_cron_daemon', "Failure making crontab!")
952     self._logger.log("Cron daemon installed and configured: "+cron_daemon_pkg)
953 robbat2 675
954 agaffney 509 ##
955 codeman 512 # This will parse the partitions looking for types that require fstools and emerge them if found.
956 samyron 102 def install_filesystem_tools(self):
957     "Installs and sets up fstools"
958     # Get the list of file system tools to be installed
959 codeman 443 parts = self._install_profile.get_partition_tables()
960 robbat2 675 # don't use an array, use a set instead
961     filesystem_types = {}
962 codeman 443 for device in parts:
963 agaffney 599 tmp_partitions = parts[device].get_install_profile_structure()
964     for partition in tmp_partitions:
965 robbat2 675 partition_type = tmp_partitions[partition]['type'].lower()
966     if partition_type not in filesystem_types:
967     filesystem_types[partition_type] = None
968    
969     package_list = []
970     for filesystem in filesystem_types.keys():
971     if filesystem == 'xfs':
972     package_list.append('sys-fs/xfsprogs')
973     elif filesystem == 'reiserfs':
974     package_list.append('sys-fs/reiserfsprogs')
975     elif filesystem == 'jfs':
976     package_list.append('sys-fs/jfsutils')
977     elif filesystem == 'ntfs':
978     package_list.append('sys-fs/ntfsprogs')
979     elif filesystem in ['fat','vfat', 'msdos', 'umsdos']:
980     package_list.append('sys-fs/dosfstools')
981     elif filesystem == 'hfs':
982     # should check with the PPC guys on this
983     package_list.append('sys-fs/hfsutils')
984     package_list.append('sys-fs/hfsplusutils')
985     #else:
986     # should be code here for every FS type!
987     failed_list = []
988     for package in package_list:
989 codeman 995 if self._debug: self._logger.log("DEBUG: install_filesystem_tools(): emerging "+package)
990 agaffney 1208 exitstatus = self._portage.emerge(package)
991     # if not GLIUtility.exitsuccess(exitstatus):
992     # self._logger.log("ERROR! : Could not emerge "+package+"!")
993     # failed_list.append(package)
994     # else:
995     self._logger.log("FileSystemTool "+package+" was emerged successfully.")
996 robbat2 675 # error checking is important!
997     if len(failed_list) > 0:
998     raise GLIException("InstallFileSystemToolsError", 'warning', 'install_filesystem_tools', "Could not emerge " + failed_list + "!")
999 codeman 443
1000 agaffney 509 ##
1001 codeman 512 # Installs rp-pppoe but does not configure it. This function is quite the unknown.
1002 samyron 102 def install_rp_pppoe(self):
1003     # If user wants us to install rp-pppoe, then do so
1004     if self._install_profile.get_install_rp_pppoe():
1005 codeman 995 if self._debug: self._logger.log("DEBUG: install_rp_pppoe: emerging rp-pppoe")
1006 agaffney 1208 exitstatus = self._portage.emerge("rp-pppoe")
1007     # if not GLIUtility.exitsuccess(exitstatus):
1008     # self._logger.log("ERROR! : Could not emerge rp-pppoe!")
1009 codeman 318 # raise GLIException("RP_PPPOEError", 'warning', 'install_rp_pppoe', "Could not emerge rp-pppoe!")
1010 agaffney 1208 # else:
1011     self._logger.log("rp-pppoe emerged but not set up.")
1012 samyron 102 # Should we add a section here to automatically configure rp-pppoe?
1013     # I think it should go into the setup_network_post section
1014 codeman 512 # What do you guys think? <-- said by unknown. samyron or npmcallum
1015 samyron 102
1016 agaffney 509 ##
1017 codeman 512 # Installs and sets up pcmcia-cs if selected in the profile
1018 samyron 102 def install_pcmcia_cs(self):
1019 codeman 995 if self._debug: self._logger.log("DEBUG: install_pcmcia_cs(): emerging pcmcia-cs")
1020 agaffney 1208 exitstatus = self._portage.emerge("pcmcia-cs")
1021     # if not GLIUtility.exitsuccess(exitstatus):
1022     # self._logger.log("ERROR! : Could not emerge pcmcia-cs!")
1023 codeman 836
1024     # Add pcmcia-cs to the default runlevel
1025 agaffney 1208 # else:
1026     self._add_to_runlevel('pcmcia')
1027     self._logger.log("PCMCIA_CS emerged and configured.")
1028 codeman 836
1029     ##
1030 codeman 512 # This runs etc-update and then re-overwrites the files by running the configure_*'s to keep our values.
1031 samyron 102 def update_config_files(self):
1032     "Runs etc-update (overwriting all config files), then re-configures the modified ones"
1033     # Run etc-update overwriting all config files
1034 codeman 995 if self._debug: self._logger.log("DEBUG: update_config_files(): running: "+'echo "-5" | chroot '+self._chroot_dir+' etc-update')
1035     status = GLIUtility.spawn('echo "-5" | chroot '+self._chroot_dir+' etc-update', display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
1036 codeman 218 if not GLIUtility.exitsuccess(status):
1037 codeman 318 self._logger.log("ERROR! : Could not update the config files!")
1038     else:
1039 agaffney 720 # self.configure_make_conf()
1040 codeman 318 self.configure_fstab()
1041 agaffney 720 # self.configure_rc_conf()
1042     etc_files = self._install_profile.get_etc_files()
1043     for etc_file in etc_files:
1044 codeman 995 if self._debug: self._logger.log("DEBUG: update_config_files(): updating config file: "+etc_file)
1045 agaffney 720 if isinstance(etc_files[etc_file], dict):
1046 agaffney 729 self._edit_config(self._chroot_dir + "/etc/" + etc_file, etc_files[etc_file])
1047 agaffney 720 else:
1048     for entry in etc_files[etc_file]:
1049 agaffney 891 self._edit_config(self._chroot_dir + "/etc/" + etc_file, { "0": entry }, only_value=True)
1050 codeman 318 self._logger.log("Config files updated using etc-update. make.conf/fstab/rc.conf restored.")
1051 samyron 102
1052 agaffney 509 ##
1053 agaffney 720 # Configures /etc/rc.conf (deprecated by above code)
1054 samyron 102 def configure_rc_conf(self):
1055 codeman 512
1056 samyron 102 # Get make.conf options
1057     options = self._install_profile.get_rc_conf()
1058    
1059     # For each configuration option...
1060 robbat2 677 filename = self._chroot_dir + "/etc/rc.conf"
1061 agaffney 1208 # self._edit_config(filename, {"COMMENT": "GLI additions ===>"})
1062 samyron 102 for key in options.keys():
1063     # Add/Edit it into rc.conf
1064 robbat2 677 self._edit_config(filename, {key: options[key]})
1065 agaffney 1208 # self._edit_config(filename, {"COMMENT": "<=== End GLI additions"})
1066 codeman 314 self._logger.log("rc.conf configured.")
1067    
1068 agaffney 509 ##
1069 codeman 512 # Sets up the network for the first boot
1070 samyron 102 def setup_network_post(self):
1071 codeman 995 if self._debug: self._logger.log("DEBUG: setup_network_post(): starting network configuration")
1072 samyron 102 # Get hostname, domainname and nisdomainname
1073     hostname = self._install_profile.get_hostname()
1074     domainname = self._install_profile.get_domainname()
1075     nisdomainname = self._install_profile.get_nisdomainname()
1076    
1077     # Write the hostname to the hostname file
1078 codeman 710 #open(self._chroot_dir + "/etc/hostname", "w").write(hostname + "\n")
1079     self._edit_config(self._chroot_dir + "/etc/conf.d/hostname", {"HOSTNAME": hostname})
1080 samyron 102
1081     # Write the domainname to the nisdomainname file
1082     if domainname:
1083 codeman 710 #open(self._chroot_dir + "/etc/dnsdomainname", "w").write(domainname + "\n")
1084     self._edit_config(self._chroot_dir + "/etc/conf.d/domainname", {"DNSDOMAIN": domainname})
1085 codeman 409 self._add_to_runlevel("domainname")
1086 samyron 102
1087     # Write the nisdomainname to the nisdomainname file
1088     if nisdomainname:
1089 codeman 710 #open(self._chroot_dir + "/etc/nisdomainname", "w").write(nisdomainname + "\n")
1090     self._edit_config(self._chroot_dir + "/etc/conf.d/domainname", {"NISDOMAIN": nisdomainname})
1091 codeman 409 self._add_to_runlevel("domainname")
1092 samyron 102
1093     #
1094     # EDIT THE /ETC/HOSTS FILE
1095     #
1096    
1097     # The address we are editing is 127.0.0.1
1098     hosts_ip = "127.0.0.1"
1099    
1100     # If the hostname is localhost
1101     if hostname == "localhost":
1102     # If a domainname is set
1103     if domainname:
1104     hosts_line = hostname + "." + domainname + "\t" + hostname
1105     else:
1106     hosts_line = hostname
1107     # If the hostname is not localhost
1108     else:
1109     # If a domainname is set
1110     if domainname:
1111     hosts_line = hostname + "." + domainname + "\t" + hostname + "\tlocalhost"
1112     else:
1113     hosts_line = "localhost\t" + hostname
1114    
1115     # Write to file
1116 codeman 218 self._edit_config(self._chroot_dir + "/etc/hosts", {hosts_ip: hosts_line}, delimeter='\t', quotes_around_value=False)
1117 samyron 102
1118     #
1119     # SET DEFAULT GATEWAY
1120     #
1121    
1122     # Get default gateway
1123     default_gateway = self._install_profile.get_default_gateway()
1124    
1125     # If the default gateway exists, add it
1126     if default_gateway:
1127 codeman 359 default_gateway_string = default_gateway[0] + "/" + default_gateway[1]
1128 codeman 995 if self._debug: self._logger.log("DEBUG: setup_network_post(): found gateway. adding to confing. "+default_gateway_string)
1129 codeman 359 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"gateway": default_gateway_string})
1130 samyron 102
1131     #
1132     # SET RESOLV INFO
1133     #
1134    
1135     # Get dns servers
1136     dns_servers = self._install_profile.get_dns_servers()
1137    
1138     # Clear the list
1139     resolv_output = []
1140    
1141     # If dns servers are set
1142     if dns_servers:
1143    
1144    
1145     # Parse each dns server
1146     for dns_server in dns_servers:
1147     # Add the server to the output
1148     resolv_output.append("nameserver " + dns_server +"\n")
1149    
1150     # If the domainname is set, then also output it
1151     if domainname:
1152     resolv_output.append("search " + domainname + "\n")
1153    
1154 codeman 347 # Output to file
1155 codeman 995 if self._debug: self._logger.log("DEBUG: setup_network_post(): writing resolv.conf with contents: "+resolv_output)
1156 codeman 347 resolve_conf = open(self._chroot_dir + "/etc/resolv.conf", "w")
1157     resolve_conf.writelines(resolv_output)
1158     resolve_conf.close()
1159 samyron 102
1160     #
1161     # PARSE INTERFACES
1162     #
1163    
1164     # Fetch interfaces
1165     interfaces = self._install_profile.get_network_interfaces()
1166 codeman 347 emerge_dhcp = False
1167 samyron 102 # Parse each interface
1168     for interface in interfaces.keys():
1169 codeman 995 if self._debug: self._logger.log("DEBUG: setup_network_post(): configuring interface: "+ interface)
1170 samyron 102 # Set what kind of interface it is
1171     interface_type = interface[:3]
1172    
1173     # Check to see if there is a startup script for this interface, if there isn't link to the proper script
1174     try:
1175 codeman 201 os.stat(self._chroot_dir + "/etc/init.d/net." + interface)
1176 samyron 102 except:
1177 codeman 995 if self._debug: self._logger.log("DEBUG: setup_network_post(): /etc/init.d/net." + interface + " didn't exist, symlinking it.")
1178 agaffney 789 os.symlink("net." + interface_type + "0", self._chroot_dir + "/etc/init.d/net." + interface)
1179 samyron 102
1180 codeman 409 # If we are going to load the network at boot...
1181 codeman 479 #if interfaces[interface][2]: #THIS FEATURE NO LONGER EXISTS
1182 codeman 409
1183 agaffney 702 # Add it to the default runlevel
1184 codeman 995 if self._debug: self._logger.log("DEBUG: setup_network_post(): adding net."+interface+" to runlevel.")
1185 codeman 479 self._add_to_runlevel("net."+interface) # moved a bit <-- for indentation
1186 codeman 409
1187 samyron 102 #
1188     # ETHERNET
1189     #
1190     if interface_type == "eth":
1191    
1192     #
1193     # STATIC IP
1194     #
1195     # If the post-install device info is not None, then it is a static ip addy
1196 agaffney 702 if interfaces[interface][0] != "dhcp":
1197 samyron 102 ip = interfaces[interface][0]
1198     broadcast = interfaces[interface][1]
1199     netmask = interfaces[interface][2]
1200     # aliases = interfaces[interface][1][3]
1201     # alias_ips = []
1202     # alias_broadcasts = []
1203     # alias_netmasks = []
1204    
1205     # Write the static ip config to /etc/conf.d/net
1206 codeman 217 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"iface_" + interface: ip + " broadcast " + broadcast + " netmask " + netmask})
1207 samyron 102
1208     # If aliases are set
1209     # if aliases:
1210    
1211     # Parse aliases to format alias info
1212     # for alias in aliases:
1213     # alias_ips.append(alias[0])
1214     # alias_broadcasts.append(alias[1])
1215     # alias_netmasks.append(allias[2])
1216    
1217     # Once the alias info has been gathered, then write it out
1218     # Alias ips first
1219 codeman 201 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "alias_" + interface, string.join(alias_ips))
1220 samyron 102 # Alias broadcasts next
1221 codeman 201 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "broadcast_" + interface, string.join(alias_broadcasts))
1222 samyron 102 # Alias netmasks last
1223 codeman 201 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "netmask_" + interface, string.join(alias_netmasks))
1224 samyron 102
1225     #
1226     # DHCP IP
1227     #
1228     else:
1229 robbat2 742 dhcpcd_options = interfaces[interface][1]
1230 codeman 997 if not dhcpcd_options:
1231 robbat2 742 dhcpcd_options = ""
1232     self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"iface_" + interface: "dhcp", "dhcpcd_" + interface: dhcpcd_options})
1233 codeman 347 emerge_dhcp = True
1234 codeman 319 if emerge_dhcp:
1235 codeman 995 if self._debug: self._logger.log("DEBUG: setup_network_post(): emerging dhcpcd.")
1236 agaffney 1208 exitstatus = self._portage.emerge("dhcpcd")
1237     # if not GLIUtility.exitsuccess(exitstatus):
1238     # self._logger.log("ERROR! : Could not emerge dhcpcd!")
1239     # else:
1240     self._logger.log("dhcpcd emerged.")
1241 codeman 319
1242 agaffney 509 ##
1243 codeman 512 # Sets the root password
1244 samyron 102 def set_root_password(self):
1245 codeman 995 if self._debug: self._logger.log("DEBUG: set_root_password(): running: "+ 'echo \'root:' + self._install_profile.get_root_pass_hash() + '\' | chroot '+self._chroot_dir+' chpasswd -e')
1246 agaffney 564 status = GLIUtility.spawn('echo \'root:' + self._install_profile.get_root_pass_hash() + '\' | chroot '+self._chroot_dir+' chpasswd -e')
1247 codeman 237 if not GLIUtility.exitsuccess(status):
1248 codeman 318 raise GLIException("SetRootPasswordError", 'fatal', 'set_root_password', "Failure to set root password!")
1249 codeman 314 self._logger.log("Root Password set on the new system.")
1250    
1251 agaffney 509 ##
1252 codeman 512 # Sets up the new users for the system
1253 samyron 102 def set_users(self):
1254     # Loop for each user
1255     for user in self._install_profile.get_users():
1256    
1257     # Get values from the tuple
1258     username = user[0]
1259     password_hash = user[1]
1260     groups = user[2]
1261     shell = user[3]
1262     home_dir = user[4]
1263     uid = user[5]
1264     comment = user[6]
1265    
1266 agaffney 473 options = [ "-m", "-p '" + password_hash + "'" ]
1267 samyron 102
1268     # If the groups are specified
1269     if groups:
1270    
1271     # If just one group is listed as a string, make it a list
1272     if groups == str:
1273     groups = [ groups ]
1274    
1275     # If only 1 group is listed
1276     if len(groups) == 1:
1277     options.append("-G " + groups[0])
1278    
1279     # If there is more than one group
1280     elif len(groups) > 1:
1281     options.append('-G "' + string.join(groups, ",") + '"')
1282 codeman 526
1283     # Attempt to add the group (will return success when group exists)
1284     for group in groups:
1285     # Add the user
1286 codeman 995 if self._debug: self._logger.log("DEBUG: set_users(): adding user to groups with (in chroot): "+'groupadd -f ' + group)
1287 codeman 526 exitstatus = GLIUtility.spawn('groupadd -f ' + group, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True, display_on_tty8=True)
1288     if not GLIUtility.exitsuccess(exitstatus):
1289     self._logger.log("ERROR! : Failure to add group " + group+" and it wasn't that the group already exists!")
1290    
1291 samyron 102
1292     # If a shell is specified
1293     if shell:
1294     options.append("-s " + shell)
1295    
1296     # If a home dir is specified
1297     if home_dir:
1298     options.append("-d " + home_dir)
1299    
1300     # If a UID is specified
1301     if uid:
1302     options.append("-u " + str(uid))
1303    
1304     # If a comment is specified
1305     if comment:
1306     options.append('-c "' + comment + '"')
1307    
1308     # Add the user
1309 codeman 995 if self._debug: self._logger.log("DEBUG: set_users(): adding user with (in chroot): "+'useradd ' + string.join(options) + ' ' + username)
1310 agaffney 451 exitstatus = GLIUtility.spawn('useradd ' + string.join(options) + ' ' + username, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True, display_on_tty8=True)
1311 codeman 237 if not GLIUtility.exitsuccess(exitstatus):
1312 codeman 318 self._logger.log("ERROR! : Failure to add user " + username)
1313     # raise GLIException("AddUserError", 'warning', 'set_users', "Failure to add user " + username)
1314     else:
1315     self._logger.log("User "+username+"was added.")
1316 codeman 314
1317 agaffney 509 ##
1318 codeman 512 # This function will handle the various cleanup tasks as well as unmounting the filesystems for reboot.
1319 codeman 432 def finishing_cleanup(self):
1320     #These are temporary until I come up with a nicer idea.
1321 codeman 443 #get rid of the compile_output file so the symlink doesn't get screwed up.
1322    
1323     #we copy the log over to the new system.
1324 codeman 432 install_logfile = self._client_configuration.get_log_file()
1325     try:
1326 codeman 995 if self._debug: self._logger.log("DEBUG: finishing_cleanup(): copying logfile over to new system's root.")
1327 codeman 432 shutil.copy(install_logfile, self._chroot_dir + install_logfile)
1328     except:
1329 codeman 995 if self._debug: self._logger.log("DEBUG: finishing_cleanup(): ERROR! could not copy logfile over to /root.")
1330 codeman 432 #Now we're done logging as far as the new system is concerned.
1331 codeman 618 GLIUtility.spawn("cp /tmp/installprofile.xml " + self._chroot_dir + "/root/installprofile.xml")
1332     GLIUtility.spawn("cp /tmp/clientconfiguration.xml " + self._chroot_dir + "/root/clientconfiguration.xml")
1333 codeman 432
1334 codeman 577 #Unmount mounted fileystems in preparation for reboot
1335 codeman 591 mounts = GLIUtility.spawn(r"mount | sed -e 's:^.\+ on \(.\+\) type .\+$:\1:' | grep -e '^" + self._chroot_dir + "' | sort -r", return_output=True)[1].split("\n")
1336 agaffney 588 for mount in mounts:
1337 codeman 577 GLIUtility.spawn("umount -l " + mount)
1338 robbat2 664
1339 robbat2 675 # now turn off all swap as well.
1340     # we need to find the swap devices
1341     for swap_device in self._swap_devices:
1342     ret = GLIUtility.spawn("swapoff "+swap_device)
1343     if not GLIUtility.exitsuccess(ret):
1344     self._logger.log("ERROR! : Could not deactivate swap ("+swap_device+")!")
1345 codeman 577
1346     #OLD WAY: Unmount the /proc and /dev that we mounted in prepare_chroot
1347 codeman 432 #There really isn't a reason to log errors here.
1348 codeman 577 #ret = GLIUtility.spawn("umount "+self._chroot_dir+"/proc", display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
1349     #ret = GLIUtility.spawn("umount "+self._chroot_dir+"/dev", display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
1350 codeman 432 #temp hack to unmount the new root.
1351 codeman 577 #ret = GLIUtility.spawn("umount "+self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
1352 codeman 432 #insert code here to unmount the swap partition, if there is one.
1353 agaffney 453
1354     GLIUtility.spawn("rm /tmp/compile_output.log && rm " + install_logfile)
1355 codeman 432
1356 agaffney 509 ##
1357 codeman 512 # This is a stub function to be done by the individual arch. I don't think it's even needed here.
1358     # but it's nice having it just incase.
1359 codeman 213 def install_bootloader(self):
1360     "THIS FUNCTION MUST BE DONE BY THE INDIVIDUAL ARCH"
1361     pass
1362 agaffney 525
1363     def run_post_install_script(self):
1364     if self._install_profile.get_post_install_script_uri():
1365     try:
1366 codeman 995 if self._debug: self._logger.log("DEBUG: run_post_install_script(): getting script: "+self._install_profile.get_post_install_script_uri())
1367 agaffney 646 GLIUtility.get_uri(self._install_profile.get_post_install_script_uri(), self._chroot_dir + "/var/tmp/post-install")
1368 codeman 995 if self._debug: self._logger.log("DEBUG: run_post_install_script(): running: chmod a+x /var/tmp/post-install && /var/tmp/post-install in chroot")
1369 agaffney 646 GLIUtility.spawn("chmod a+x /var/tmp/post-install && /var/tmp/post-install", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
1370 agaffney 525 except:
1371     raise GLIException("RunPostInstallScriptError", 'fatal', 'run_post_install_script', "Failed to retrieve and/or execute post-install script")
1372 codeman 560
1373 agaffney 828 ##
1374     # This function should only be called in the event of an install failure. It performs
1375     # general cleanup to prepare the system for another installer run.
1376     def install_failed_cleanup(self):
1377 codeman 995 if self._debug: self._logger.log("DEBUG: install_failed_cleanup(): gathering mounts to unmount")
1378 agaffney 828 mounts = GLIUtility.spawn(r"mount | sed -e 's:^.\+ on \(.\+\) type .\+$:\1:' | grep -e '^" + self._chroot_dir + "' | sort -r", return_output=True)[1].split("\n")
1379     for mount in mounts:
1380 codeman 995 if self._debug: self._logger.log("DEBUG: install_failed_cleanup(): running: umount -l " + mount)
1381 agaffney 828 GLIUtility.spawn("umount -l " + mount)
1382    
1383     # now turn off all swap as well.
1384     # we need to find the swap devices
1385     for swap_device in self._swap_devices:
1386 codeman 995 if self._debug: self._logger.log("DEBUG: install_failed_cleanup(): running: swapoff "+swap_device)
1387 agaffney 828 ret = GLIUtility.spawn("swapoff "+swap_device)
1388     if not GLIUtility.exitsuccess(ret):
1389     self._logger.log("ERROR! : Could not deactivate swap ("+swap_device+")!")
1390    
1391 codeman 995 if self._debug: self._logger.log("DEBUG: install_failed_cleanup(): running: cp /tmp/compile_output.log /tmp/compile_output.log.failed then removing /tmp/compile_output.log")
1392     GLIUtility.spawn("cp /tmp/compile_output.log /tmp/compile_output.log.failed")
1393 agaffney 828 GLIUtility.spawn("rm /tmp/compile_output.log")
1394 agaffney 1201 GLIUtility.spawn("cp /var/log/installer.log /var/log/installer.log.failed")
1395     GLIUtility.spawn("rm /var/log/installer.log")

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20