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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20