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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1706 - (show annotations) (download) (as text)
Sat Feb 17 17:16:15 2007 UTC (7 years, 2 months ago) by codeman
File MIME type: text/x-python
File size: 68942 byte(s)
adding a do_recommended_partitioning function
only for use in fully-automated installs.

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 # This is a hack to copy the LiveCD's rsync into the chroot since it has the sigmask patch
561 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")
562 GLIUtility.spawn("cp -a /usr/bin/rsync " + self._chroot_dir + "/usr/bin/rsync")
563 GLIUtility.spawn("cp -a /usr/lib/libpopt* " + self._chroot_dir + "/usr/lib")
564
565 sync_type = self._install_profile.get_portage_tree_sync_type()
566 if sync_type == "snapshot" or sync_type == "custom": # Until this is finalized
567
568 # Get portage tree info
569 portage_tree_snapshot_uri = self._install_profile.get_portage_tree_snapshot_uri()
570 if portage_tree_snapshot_uri:
571 # Fetch and unpack the tarball
572 if self._debug: self._logger.log("DEBUG: grabbing custom snapshot uri: "+portage_tree_snapshot_uri)
573 GLIUtility.fetch_and_unpack_tarball(portage_tree_snapshot_uri, self._chroot_dir + "/usr/", self._chroot_dir + "/", cc=self._cc)
574 if GLIUtility.is_file("/usr/livecd/metadata.tar.bz2"):
575 GLIUtility.fetch_and_unpack_tarball("/usr/livecd/metadata.tar.bz2", self._chroot_dir + "/", self._chroot_dir + "/", cc=self._cc)
576 self._logger.log("Portage tree install was custom.")
577 elif sync_type == "sync":
578 if self._debug: self._logger.log("DEBUG: starting emerge sync")
579 exitstatus = GLIUtility.spawn("emerge sync", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
580 if not GLIUtility.exitsuccess(exitstatus):
581 self._logger.log("ERROR! Could not sync the portage tree using emerge sync. Falling back to emerge-webrsync as a backup.")
582 sync_type = "webrsync"
583 else:
584 self._logger.log("Portage tree sync'd")
585 # If the type is webrsync, then run emerge-webrsync
586 elif sync_type == "webrsync":
587 if self._debug: self._logger.log("DEBUG: starting emerge webrsync")
588 exitstatus = GLIUtility.spawn("emerge-webrsync", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
589 if not GLIUtility.exitsuccess(exitstatus):
590 raise GLIException("EmergeWebRsyncError", 'fatal','install_portage_tree', "Failed to retrieve portage tree using webrsync!")
591 self._logger.log("Portage tree sync'd using webrsync")
592 # Otherwise, spit out a message because its probably a bad thing.
593 else:
594 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.")
595
596
597 ##
598 # Stage 1 install -- bootstraping the system
599 # If we are doing a stage 1 install, then bootstrap
600 def stage1(self):
601 if self._install_profile.get_install_stage() == 1:
602 self._logger.mark()
603 self._logger.log("Starting bootstrap.")
604 pkgs = self._get_packages_to_emerge("/usr/portage/scripts/bootstrap.sh --pretend")
605 if self._debug: self._logger.log("DEBUG: Packages to emerge: "+str(pkgs)+". Now running bootstrap.sh")
606 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)
607 if not GLIUtility.exitsuccess(exitstatus):
608 raise GLIException("Stage1Error", 'fatal','stage1', "Bootstrapping failed!")
609 self._logger.log("Bootstrap complete.")
610
611 ##
612 # Stage 2 install -- emerge -e system
613 # If we are doing a stage 1 or 2 install, then emerge system
614 def stage2(self):
615 if self._install_profile.get_install_stage() in [ 1, 2 ]:
616 self._logger.mark()
617 self._logger.log("Starting emerge system.")
618 pkgs = self._get_packages_to_emerge("emerge -p system") #currently quite the useless
619 if self._debug: self._logger.log("DEBUG: Packages to emerge: "+str(pkgs)+"/ Now running emerge --emptytree system")
620 # exitstatus = self._emerge("--emptytree system")
621 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)
622 if not GLIUtility.exitsuccess(exitstatus):
623 raise GLIException("Stage2Error", 'fatal','stage2', "Building the system failed!")
624 self._logger.log("Emerge system complete.")
625
626 ##
627 # Sets the root password
628 def set_root_password(self):
629 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')
630 status = GLIUtility.spawn('echo \'root:' + self._install_profile.get_root_pass_hash() + '\' | chroot '+self._chroot_dir+' chpasswd -e')
631 if not GLIUtility.exitsuccess(status):
632 raise GLIException("SetRootPasswordError", 'fatal', 'set_root_password', "Failure to set root password!")
633 self._logger.log("Root Password set on the new system.")
634
635 ##
636 # Sets the timezone for the new environment
637 def set_timezone(self):
638
639 # Set symlink
640 if os.access(self._chroot_dir + "/etc/localtime", os.W_OK):
641 if self._debug: self._logger.log("DEBUG: /etc/localtime already exists, removing it so it can be symlinked")
642 GLIUtility.spawn("rm "+self._chroot_dir + "/etc/localtime")
643 if self._debug: self._logger.log("DEBUG: running ln -s ../usr/share/zoneinfo/" + self._install_profile.get_time_zone() + " /etc/localtime")
644 GLIUtility.spawn("ln -s ../usr/share/zoneinfo/" + self._install_profile.get_time_zone() + " /etc/localtime", chroot=self._chroot_dir)
645 if not (self._install_profile.get_time_zone() == "UTC"):
646 if self._debug: self._logger.log("DEBUG: timezone was not UTC, setting CLOCK to local. This may be overwritten later.")
647 self._edit_config(self._chroot_dir + "/etc/conf.d/clock", {"CLOCK":"local"})
648 self._logger.log("Timezone set.")
649
650 ##
651 # Fetches desired kernel sources, unless you're using a livecd-kernel in which case it does freaky stuff.
652 def emerge_kernel_sources(self):
653 kernel_pkg = self._install_profile.get_kernel_source_pkg()
654 self._logger.log("Starting emerge_kernel, package is %s" % kernel_pkg)
655 # if kernel_pkg:
656 # Special case, no kernel installed
657 if kernel_pkg == "none":
658 return
659 # Special case, livecd kernel
660 elif kernel_pkg == "livecd-kernel":
661 if self._debug: self._logger.log("DEBUG: starting livecd-kernel setup")
662 self.notify_frontend("progress", (0, "Copying livecd-kernel to chroot"))
663 self._portage.copy_pkg_to_chroot(self._portage.get_best_version_vdb("livecd-kernel"))
664 self.notify_frontend("progress", (1, "Done copying livecd-kernel to chroot"))
665
666 exitstatus = self._portage.emerge("coldplug", self._install_profile.get_grp_install())
667 self._logger.log("Coldplug emerged. Now they should be added to the boot runlevel.")
668 self._add_to_runlevel("coldplug", runlevel="boot")
669
670 if self._install_profile.get_kernel_bootsplash():
671 self._logger.log("Bootsplash enabled for livecd-kernel...this is currently broken, so we're skipping the package install")
672 # self._logger.log("Bootsplash enabled...emerging necessary packages")
673 # self._portage.emerge(["splashutils", "splash-themes-livecd"])
674
675 # Extra modules from kernelpkgs.txt...disabled until I can figure out why it sucks
676 # try:
677 # kernpkgs = open("/usr/livecd/kernelpkgs.txt", "r")
678 # pkgs = ""
679 # for line in kernpkgs.readlines():
680 # pkgs += line.strip() + " "
681 # kernpkgs.close()
682 # except:
683 # raise GLIException("EmergeColdplugError", 'fatal','build_kernel', "Could not read kernelpkgs.txt")
684 # exitstatus = self._emerge(pkgs)
685 # if not GLIUtility.exitsuccess(exitstatus):
686 # raise GLIException("EmergeExtraKernelModulesError", 'fatal','build_kernel', "Could not emerge extra kernel packages")
687 # self._logger.log("Extra kernel packages emerged.")
688
689 # normal case
690 else:
691 exitstatus = self._portage.emerge(kernel_pkg, self._install_profile.get_grp_install())
692 # if not GLIUtility.exitsuccess(exitstatus):
693 # raise GLIException("EmergeKernelSourcesError", 'fatal','emerge_kernel_sources',"Could not retrieve kernel sources!")
694 try:
695 os.stat(self._chroot_dir + "/usr/src/linux")
696 except:
697 kernels = os.listdir(self._chroot_dir+"/usr/src")
698 if self._debug: self._logger.log("DEBUG: no /usr/src/linux found. found kernels: "+kernels)
699 found_a_kernel = False
700 counter = 0
701 while not found_a_kernel:
702 if (len(kernels[counter]) > 6) and (kernels[counter][0:6]=="linux-"):
703 if self._debug: self._logger.log("DEBUG: found one. linking it. running: ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux in the chroot.")
704 exitstatus = GLIUtility.spawn("ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux",chroot=self._chroot_dir)
705 if not GLIUtility.exitsuccess(exitstatus):
706 raise GLIException("EmergeKernelSourcesError", 'fatal','emerge_kernel_sources',"Could not make a /usr/src/linux symlink")
707 found_a_kernel = True
708 else:
709 counter = counter + 1
710 self._logger.log("Kernel sources:"+kernel_pkg+" emerged and /usr/src/linux symlinked.")
711
712 ##
713 # Builds the kernel using genkernel or regularly if given a custom .config file in the profile
714 def build_kernel(self):
715 self._logger.mark()
716 self._logger.log("Starting build_kernel")
717
718 build_mode = self._install_profile.get_kernel_build_method()
719
720 # No building necessary if using the LiveCD's kernel/initrd
721 # or using the 'none' kernel bypass
722 if self._install_profile.get_kernel_source_pkg() in ["livecd-kernel","none"]:
723 if self._debug: self._logger.log("DEBUG: using "+self._install_profile.get_kernel_source_pkg()+ " so skipping this function.")
724 return
725 # Get the uri to the kernel config
726 kernel_config_uri = self._install_profile.get_kernel_config_uri()
727
728 # is there an easier way to do this?
729 if self._debug: self._logger.log("DEBUG: running command: awk '/^PATCHLEVEL/{print $3}' /usr/src/linux/Makefile in chroot.")
730 ret, kernel_major = GLIUtility.spawn("awk '/^PATCHLEVEL/{print $3}' /usr/src/linux/Makefile",chroot=self._chroot_dir,return_output=True)
731 # 6 == 2.6 kernel, 4 == 2.4 kernel
732 kernel_major = int(kernel_major)
733 if self._debug: self._logger.log("DEBUG: kernel major version is: "+str(kernel_major))
734 #Copy the kernel .config to the proper location in /usr/src/linux
735 if kernel_config_uri != '':
736 try:
737 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")
738 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/var/tmp/kernel_config")
739 except:
740 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not copy kernel config!")
741
742 # the && stuff is important so that we can catch any errors.
743 kernel_compile_script = "#!/bin/bash\n"
744 kernel_compile_script += "cp /var/tmp/kernel_config /usr/src/linux/.config && "
745 kernel_compile_script += "cd /usr/src/linux && "
746 # required for 2.[01234] etc kernels
747 if kernel_major in [0,1,2,3,4]:
748 kernel_compile_script += " yes 'n' | make oldconfig && make symlinks && make dep"
749 # not strictly needed, but recommended by upstream
750 else: #elif kernel_major in [5,6]:
751 kernel_compile_script += "make prepare"
752
753 # bypass to install a kernel, but not compile it
754 if build_mode == "none":
755 return
756 # this mode is used to install kernel sources, and have then configured
757 # but not actually build the kernel. This is needed for netboot
758 # situations when you have packages that require kernel sources
759 # to build.
760 elif build_mode == "prepare-only":
761 if self._debug: self._logger.log("DEBUG: writing kernel script with contents: "+kernel_compile_script)
762 f = open(self._chroot_dir+"/var/tmp/kernel_script", 'w')
763 f.writelines(kernel_compile_script)
764 f.close()
765 #Build the kernel
766 if self._debug: self._logger.log("DEBUG: running: chmod u+x "+self._chroot_dir+"/var/tmp/kernel_script")
767 exitstatus1 = GLIUtility.spawn("chmod u+x "+self._chroot_dir+"/var/tmp/kernel_script")
768 if self._debug: self._logger.log("DEBUG: running: /var/tmp/kernel_script in chroot.")
769 exitstatus2 = GLIUtility.spawn("/var/tmp/kernel_script", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
770 if not GLIUtility.exitsuccess(exitstatus1):
771 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not handle prepare-only build! died on chmod.")
772 if not GLIUtility.exitsuccess(exitstatus2):
773 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not handle prepare-only build! died on running of kernel script.")
774 #i'm sure i'm forgetting something here.
775 #cleanup
776 exitstatus = GLIUtility.spawn("rm -f "+self._chroot_dir+"/var/tmp/kernel_script "+self._chroot_dir+"/var/tmp/kernel_config")
777 #it's not important if this fails.
778 self._logger.log("prepare-only build complete")
779 # Genkernel mode, including custom kernel_config. Initrd always on.
780 elif build_mode == "genkernel":
781 if self._debug: self._logger.log("DEBUG: build_kernel(): starting emerge genkernel")
782 exitstatus = self._portage.emerge("genkernel", self._install_profile.get_grp_install())
783 # if not GLIUtility.exitsuccess(exitstatus):
784 # raise GLIException("EmergeGenKernelError", 'fatal','build_kernel', "Could not emerge genkernel!")
785 self._logger.log("Genkernel emerged. Beginning kernel compile.")
786 # Null the genkernel_options
787 genkernel_options = ""
788
789 # If the uri for the kernel config is not null, then
790 if kernel_config_uri != "":
791 if self._debug: self._logger.log("DEBUG: build_kernel(): getting kernel config "+kernel_config_uri)
792 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/var/tmp/kernel_config")
793 genkernel_options = genkernel_options + " --kernel-config=/var/tmp/kernel_config"
794
795 # Decide whether to use bootsplash or not
796 if self._install_profile.get_kernel_bootsplash():
797 genkernel_options = genkernel_options + " --gensplash"
798 else:
799 genkernel_options = genkernel_options + " --no-gensplash"
800 # Run genkernel in chroot
801 #print "genkernel all " + genkernel_options
802 self.notify_frontend("progress", 0, "Compiling kernel. Please be patient!")
803 if self._debug: self._logger.log("DEBUG: build_kernel(): running: genkernel all " + genkernel_options + " in chroot.")
804 exitstatus = GLIUtility.spawn("genkernel all " + genkernel_options, chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
805 if not GLIUtility.exitsuccess(exitstatus):
806 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build kernel!")
807
808 # exitstatus = self._emerge("hotplug")
809 # if not GLIUtility.exitsuccess(exitstatus):
810 # raise GLIException("EmergeHotplugError", 'fatal','build_kernel', "Could not emerge hotplug!")
811 # self._logger.log("Hotplug emerged.")
812 exitstatus = self._portage.emerge("coldplug", self._install_profile.get_grp_install())
813 # if not GLIUtility.exitsuccess(exitstatus):
814 # raise GLIException("EmergeColdplugError", 'fatal','build_kernel', "Could not emerge coldplug!")
815 self._logger.log("Coldplug emerged. Now they should be added to the default runlevel.")
816
817 # self._add_to_runlevel("hotplug")
818 self._add_to_runlevel("coldplug", runlevel="boot")
819
820 if self._install_profile.get_kernel_bootsplash():
821 self._logger.log("Bootsplash enabled...emerging necessary packages")
822 self._portage.emerge(["splashutils", "splash-themes-livecd"], self._install_profile.get_grp_install())
823
824 self._logger.log("Genkernel complete.")
825 elif build_mode == "custom": #CUSTOM CONFIG
826
827 kernel_compile_script += " && make && make modules && make modules_install"
828
829 #Ok now that it's built, copy it to /boot/kernel-* for bootloader code to find it
830 if self._architecture_name == "x86":
831 kernel_compile_script += " && cp /usr/src/linux/arch/i386/boot/bzImage /boot/kernel-custom\n"
832 elif self._architecture_name == "amd64":
833 kernel_compile_script += " && cp /usr/src/linux/arch/x86_64/boot/bzImage /boot/kernel-custom\n"
834 elif self._architecture_name == "ppc":
835 kernel_compile_script += " && cp /usr/src/linux/vmlinux /boot/kernel-custom\n"
836 if self._debug: self._logger.log("DEBUG: build_kernel(): writing custom kernel script: "+kernel_compile_script)
837 f = open(self._chroot_dir+"/var/tmp/kernel_script", 'w')
838 f.writelines(kernel_compile_script)
839 f.close()
840 #Build the kernel
841 if self._debug: self._logger.log("DEBUG: build_kernel(): running: chmod u+x "+self._chroot_dir+"/var/tmp/kernel_script")
842 exitstatus1 = GLIUtility.spawn("chmod u+x "+self._chroot_dir+"/var/tmp/kernel_script")
843 if self._debug: self._logger.log("DEBUG: build_kernel(): running: /var/tmp/kernel_script in chroot")
844 exitstatus2 = GLIUtility.spawn("/var/tmp/kernel_script", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
845 if not GLIUtility.exitsuccess(exitstatus1):
846 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build custom kernel! died on chmod.")
847 if not GLIUtility.exitsuccess(exitstatus2):
848 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build custom kernel! died on running of kernel script.")
849
850 #i'm sure i'm forgetting something here.
851 #cleanup
852 exitstatus = GLIUtility.spawn("rm -f "+self._chroot_dir+"/var/tmp/kernel_script "+self._chroot_dir+"/var/tmp/kernel_config")
853 #it's not important if this fails.
854
855 if self._install_profile.get_kernel_bootsplash():
856 self._logger.log("Bootsplash enabled...emerging necessary packages")
857 self._portage.emerge(["splashutils", "splash-themes-livecd"], self._install_profile.get_grp_install())
858
859 self._logger.log("Custom kernel complete")
860
861 ##
862 # Installs and starts up distccd if the user has it set, so that it will get used for the rest of the install
863 def install_distcc(self):
864 if self._install_profile.get_install_distcc():
865 if self._debug: self._logger.log("DEBUG: install_distcc(): we ARE installing distcc")
866 if self._debug: self._logger.log("DEBUG: install_distcc(): running: USE='-*' emerge --nodeps sys-devel/distcc in chroot.")
867 exitstatus = GLIUtility.spawn("USE='-*' emerge --nodeps sys-devel/distcc", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
868 if not GLIUtility.exitsuccess(exitstatus):
869 self._logger.log("ERROR! : Could not emerge distcc!")
870 else:
871 self._logger.log("distcc emerged.")
872
873 ##
874 # Installs mail MTA. Does not put into runlevel, as this is not simple with MTAs.
875 def install_mta(self):
876 # Get MTA info
877 mta_pkg = self._install_profile.get_mta_pkg()
878 if mta_pkg:
879 # Emerge MTA
880 if self._debug: self._logger.log("DEBUG: install_mta(): installing mta: "+mta_pkg)
881 exitstatus = self._portage.emerge(mta_pkg, self._install_profile.get_grp_install())
882 # if not GLIUtility.exitsuccess(exitstatus):
883 # raise GLIException("MTAError", 'fatal','install_mta', "Could not emerge " + mta_pkg + "!")
884 self._logger.log("MTA installed: "+mta_pkg)
885 else:
886 installpackages = self._install_profile.get_install_packages()
887 if installpackages:
888 for pkg in installpackages:
889 if pkg in ['esmtp', 'exim', 'msmtp', 'nbsmtp', 'nullmailer', 'sendmail', 'ssmtp', 'xmail']:
890 self._logger.log("Found an mta in the package list: "+pkg+". Installing early.")
891 exitstatus = self._portage.emerge(pkg, self._install_profile.get_grp_install())
892 self._logger.log("MTA installed.")
893 break # We only want to install one
894
895 ##
896 # Installs and sets up logging daemon on the new system. adds to runlevel too.
897 def install_logging_daemon(self):
898 # Get loggin daemon info
899 logging_daemon_pkg = self._install_profile.get_logging_daemon_pkg()
900 if logging_daemon_pkg:
901 # Emerge Logging Daemon
902 if self._debug: self._logger.log("DEBUG: install_logging_daemon: emerging "+logging_daemon_pkg)
903 exitstatus = self._portage.emerge(logging_daemon_pkg, self._install_profile.get_grp_install())
904 # if not GLIUtility.exitsuccess(exitstatus):
905 # raise GLIException("LoggingDaemonError", 'fatal','install_logging_daemon', "Could not emerge " + logging_daemon_pkg + "!")
906
907 # Add Logging Daemon to default runlevel
908 # After we find the name of it's initscript
909 # This current code is a hack, and should be better.
910 initscript = logging_daemon_pkg[(logging_daemon_pkg.find('/')+1):]
911 if self._debug: self._logger.log("DEBUG: install_logging_daemon: adding "+initscript+" to runlevel")
912 self._add_to_runlevel(initscript)
913 self._logger.log("Logging daemon installed: "+logging_daemon_pkg)
914 ##
915 # Installs and sets up cron package.
916 def install_cron_daemon(self):
917 # Get cron daemon info
918 cron_daemon_pkg = self._install_profile.get_cron_daemon_pkg()
919 if cron_daemon_pkg:
920 if cron_daemon_pkg == "none":
921 self._logger.log("Skipping installation of cron daemon")
922 else:
923 # Emerge Cron Daemon
924 if self._debug: self._logger.log("DEBUG: install_cron_daemon: emerging "+cron_daemon_pkg)
925 exitstatus = self._portage.emerge(cron_daemon_pkg, self._install_profile.get_grp_install())
926 # if not GLIUtility.exitsuccess(exitstatus):
927 # raise GLIException("CronDaemonError", 'fatal', 'install_cron_daemon', "Could not emerge " + cron_daemon_pkg + "!")
928
929 # Add Cron Daemon to default runlevel
930 # After we find the name of it's initscript
931 # This current code is a hack, and should be better.
932 initscript = cron_daemon_pkg[(cron_daemon_pkg.find('/')+1):]
933 if self._debug: self._logger.log("DEBUG: install_cron_daemon: adding "+initscript+" to runlevel")
934 self._add_to_runlevel(initscript)
935
936 # If the Cron Daemon is not vixie-cron, run crontab
937 if "vixie-cron" not in cron_daemon_pkg:
938 if self._debug: self._logger.log("DEBUG: install_cron_daemon: running: crontab /etc/crontab in chroot.")
939 exitstatus = GLIUtility.spawn("crontab /etc/crontab", chroot=self._chroot_dir, display_on_tty8=True)
940 if not GLIUtility.exitsuccess(exitstatus):
941 raise GLIException("CronDaemonError", 'fatal', 'install_cron_daemon', "Failure making crontab!")
942 self._logger.log("Cron daemon installed and configured: "+cron_daemon_pkg)
943
944 ##
945 # This will parse the partitions looking for types that require fstools and emerge them if found.
946 def install_filesystem_tools(self):
947 "Installs and sets up fstools"
948 # Get the list of file system tools to be installed
949 mounts = self._install_profile.get_mounts()
950 # don't use an array, use a set instead
951 filesystem_types = []
952 for mount in mounts:
953 partition_type = mount['type'].lower()
954 if mount['mountpoint'] and partition_type not in filesystem_types:
955 filesystem_types.append(partition_type)
956
957 package_list = []
958 for filesystem in filesystem_types:
959 if filesystem == 'xfs':
960 package_list.append('sys-fs/xfsprogs')
961 elif filesystem == 'reiserfs':
962 package_list.append('sys-fs/reiserfsprogs')
963 elif filesystem == 'jfs':
964 package_list.append('sys-fs/jfsutils')
965 elif filesystem == 'ntfs':
966 package_list.append('sys-fs/ntfsprogs')
967 elif filesystem in ['fat','vfat', 'msdos', 'umsdos']:
968 package_list.append('sys-fs/dosfstools')
969 elif filesystem == 'hfs':
970 # should check with the PPC guys on this
971 package_list.append('sys-fs/hfsutils')
972 package_list.append('sys-fs/hfsplusutils')
973 #else:
974 # should be code here for every FS type!
975 failed_list = []
976 for package in package_list:
977 if self._debug: self._logger.log("DEBUG: install_filesystem_tools(): emerging "+package)
978 exitstatus = self._portage.emerge(package, self._install_profile.get_grp_install())
979 # if not GLIUtility.exitsuccess(exitstatus):
980 # self._logger.log("ERROR! : Could not emerge "+package+"!")
981 # failed_list.append(package)
982 # else:
983 self._logger.log("FileSystemTool "+package+" was emerged successfully.")
984 # error checking is important!
985 if len(failed_list) > 0:
986 raise GLIException("InstallFileSystemToolsError", 'warning', 'install_filesystem_tools', "Could not emerge " + failed_list + "!")
987
988
989 ##
990 # Installs and sets up pcmcia-cs if selected in the profile IS THIS USED AT ALL????
991 def install_pcmcia_cs(self):
992 if self._debug: self._logger.log("DEBUG: install_pcmcia_cs(): emerging pcmcia-cs")
993 exitstatus = self._portage.emerge("pcmcia-cs", self._install_profile.get_grp_install())
994 # if not GLIUtility.exitsuccess(exitstatus):
995 # self._logger.log("ERROR! : Could not emerge pcmcia-cs!")
996
997 # Add pcmcia-cs to the default runlevel
998 # else:
999 self._add_to_runlevel('pcmcia')
1000 self._logger.log("PCMCIA_CS emerged and configured.")
1001
1002
1003 ##
1004 # Sets up the network for the first boot
1005 def setup_network_post(self):
1006 if self._debug: self._logger.log("DEBUG: setup_network_post(): starting network configuration")
1007 # Get hostname, domainname and nisdomainname
1008 hostname = self._install_profile.get_hostname()
1009 domainname = self._install_profile.get_domainname()
1010 nisdomainname = self._install_profile.get_nisdomainname()
1011
1012 # Write the hostname to the hostname file
1013 #open(self._chroot_dir + "/etc/hostname", "w").write(hostname + "\n")
1014 self._edit_config(self._chroot_dir + "/etc/conf.d/hostname", {"HOSTNAME": hostname})
1015
1016 # Write the domainname to the nisdomainname file
1017 if domainname:
1018 #open(self._chroot_dir + "/etc/dnsdomainname", "w").write(domainname + "\n")
1019 self._edit_config(self._chroot_dir + "/etc/conf.d/domainname", {"DNSDOMAIN": domainname})
1020 self._add_to_runlevel("domainname")
1021
1022 # Write the nisdomainname to the nisdomainname file
1023 if nisdomainname:
1024 #open(self._chroot_dir + "/etc/nisdomainname", "w").write(nisdomainname + "\n")
1025 self._edit_config(self._chroot_dir + "/etc/conf.d/domainname", {"NISDOMAIN": nisdomainname})
1026 self._add_to_runlevel("domainname")
1027
1028 #
1029 # EDIT THE /ETC/HOSTS FILE
1030 #
1031
1032 # The address we are editing is 127.0.0.1
1033 hosts_ip = "127.0.0.1"
1034
1035 # If the hostname is localhost
1036 if hostname == "localhost":
1037 # If a domainname is set
1038 if domainname:
1039 hosts_line = hostname + "." + domainname + "\t" + hostname
1040 else:
1041 hosts_line = hostname
1042 # If the hostname is not localhost
1043 else:
1044 # If a domainname is set
1045 if domainname:
1046 hosts_line = hostname + "." + domainname + "\t" + hostname + "\tlocalhost"
1047 else:
1048 hosts_line = "localhost\t" + hostname
1049
1050 # Write to file
1051 self._edit_config(self._chroot_dir + "/etc/hosts", {hosts_ip: hosts_line}, delimeter='\t', quotes_around_value=False)
1052
1053 #
1054 # SET DEFAULT GATEWAY
1055 #
1056
1057 # Get default gateway
1058 default_gateway = self._install_profile.get_default_gateway()
1059
1060 # If the default gateway exists, add it
1061 if default_gateway:
1062 default_gateway_string = '( "default via ' + default_gateway[1] + '" )'
1063 if self._debug: self._logger.log("DEBUG: setup_network_post(): found gateway. adding to confing. "+default_gateway_string)
1064 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"routes_"+default_gateway[0]: default_gateway_string}, quotes_around_value=False)
1065
1066 #
1067 # SET RESOLV INFO
1068 #
1069
1070 # Get dns servers
1071 dns_servers = self._install_profile.get_dns_servers()
1072
1073 # Clear the list
1074 resolv_output = []
1075
1076 # If dns servers are set
1077 if dns_servers:
1078
1079
1080 # Parse each dns server
1081 for dns_server in dns_servers:
1082 # Add the server to the output
1083 resolv_output.append("nameserver " + dns_server +"\n")
1084
1085 # If the domainname is set, then also output it
1086 if domainname:
1087 resolv_output.append("search " + domainname + "\n")
1088
1089 # Output to file
1090 if self._debug: self._logger.log("DEBUG: setup_network_post(): writing resolv.conf with contents: " + str(resolv_output))
1091 resolve_conf = open(self._chroot_dir + "/etc/resolv.conf", "w")
1092 resolve_conf.writelines(resolv_output)
1093 resolve_conf.close()
1094
1095 #
1096 # PARSE INTERFACES
1097 #
1098
1099 # Fetch interfaces
1100 interfaces = self._install_profile.get_network_interfaces()
1101 emerge_dhcp = False
1102 # Parse each interface
1103 for interface in interfaces.keys():
1104 if self._debug: self._logger.log("DEBUG: setup_network_post(): configuring interface: "+ interface)
1105 # Set what kind of interface it is
1106 interface_type = interface[:3]
1107
1108 # Check to see if there is a startup script for this interface, if there isn't link to the proper script
1109 try:
1110 os.stat(self._chroot_dir + "/etc/init.d/net." + interface)
1111 except:
1112 if self._debug: self._logger.log("DEBUG: setup_network_post(): /etc/init.d/net." + interface + " didn't exist, symlinking it.")
1113 os.symlink("net." + interface_type + "0", self._chroot_dir + "/etc/init.d/net." + interface)
1114
1115 # If we are going to load the network at boot...
1116 #if interfaces[interface][2]: #THIS FEATURE NO LONGER EXISTS
1117
1118 # Add it to the default runlevel
1119 if self._debug: self._logger.log("DEBUG: setup_network_post(): adding net."+interface+" to runlevel.")
1120 self._add_to_runlevel("net."+interface) # moved a bit <-- for indentation
1121
1122 #
1123 # ETHERNET
1124 #
1125 if interface_type == "eth":
1126
1127 #
1128 # STATIC IP
1129 #
1130 # If the post-install device info is not None, then it is a static ip addy
1131 if interfaces[interface][0] != "dhcp":
1132 ip = interfaces[interface][0]
1133 broadcast = interfaces[interface][1]
1134 netmask = interfaces[interface][2]
1135 # aliases = interfaces[interface][1][3]
1136 # alias_ips = []
1137 # alias_broadcasts = []
1138 # alias_netmasks = []
1139
1140 # Write the static ip config to /etc/conf.d/net
1141 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"iface_" + interface: ip + " broadcast " + broadcast + " netmask " + netmask})
1142
1143 # If aliases are set
1144 # if aliases:
1145
1146 # Parse aliases to format alias info
1147 # for alias in aliases:
1148 # alias_ips.append(alias[0])
1149 # alias_broadcasts.append(alias[1])
1150 # alias_netmasks.append(allias[2])
1151
1152 # Once the alias info has been gathered, then write it out
1153 # Alias ips first
1154 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "alias_" + interface, string.join(alias_ips))
1155 # Alias broadcasts next
1156 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "broadcast_" + interface, string.join(alias_broadcasts))
1157 # Alias netmasks last
1158 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "netmask_" + interface, string.join(alias_netmasks))
1159
1160 #
1161 # DHCP IP
1162 #
1163 else:
1164 dhcpcd_options = interfaces[interface][1]
1165 if not dhcpcd_options:
1166 dhcpcd_options = ""
1167 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"iface_" + interface: "dhcp", "dhcpcd_" + interface: dhcpcd_options})
1168 emerge_dhcp = True
1169 if emerge_dhcp:
1170 if self._debug: self._logger.log("DEBUG: setup_network_post(): emerging dhcpcd.")
1171 exitstatus = self._portage.emerge("dhcpcd", self._install_profile.get_grp_install())
1172 # if not GLIUtility.exitsuccess(exitstatus):
1173 # self._logger.log("ERROR! : Could not emerge dhcpcd!")
1174 # else:
1175 self._logger.log("dhcpcd emerged.")
1176
1177
1178 ##
1179 # This is a stub function to be done by the individual arch. I don't think it's even needed here.
1180 # but it's nice having it just incase.
1181 def install_bootloader(self):
1182 "THIS FUNCTION MUST BE DONE BY THE INDIVIDUAL ARCH"
1183 pass
1184
1185 ##
1186 # Sets up the new users for the system
1187 def set_users(self):
1188 # Loop for each user
1189 for user in self._install_profile.get_users():
1190
1191 # Get values from the tuple
1192 username = user[0]
1193 password_hash = user[1]
1194 groups = user[2]
1195 shell = user[3]
1196 home_dir = user[4]
1197 uid = user[5]
1198 comment = user[6]
1199
1200 options = [ "-m", "-p '" + password_hash + "'" ]
1201
1202 # If the groups are specified
1203 if groups:
1204
1205 # If just one group is listed as a string, make it a list
1206 if groups == str:
1207 groups = [ groups ]
1208
1209 # If only 1 group is listed
1210 if len(groups) == 1:
1211 options.append("-G " + groups[0])
1212
1213 # If there is more than one group
1214 elif len(groups) > 1:
1215 options.append('-G "' + string.join(groups, ",") + '"')
1216
1217 # Attempt to add the group (will return success when group exists)
1218 for group in groups:
1219 if not group: continue
1220 # Add the user
1221 if self._debug: self._logger.log("DEBUG: set_users(): adding user to groups with (in chroot): "+'groupadd -f ' + group)
1222 exitstatus = GLIUtility.spawn('groupadd -f ' + group, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True, display_on_tty8=True)
1223 if not GLIUtility.exitsuccess(exitstatus):
1224 self._logger.log("ERROR! : Failure to add group " + group+" and it wasn't that the group already exists!")
1225
1226
1227 # If a shell is specified
1228 if shell:
1229 options.append("-s " + shell)
1230
1231 # If a home dir is specified
1232 if home_dir:
1233 options.append("-d " + home_dir)
1234
1235 # If a UID is specified
1236 if uid:
1237 options.append("-u " + str(uid))
1238
1239 # If a comment is specified
1240 if comment:
1241 options.append('-c "' + comment + '"')
1242
1243 # Add the user
1244 if self._debug: self._logger.log("DEBUG: set_users(): adding user with (in chroot): "+'useradd ' + string.join(options) + ' ' + username)
1245 exitstatus = GLIUtility.spawn('useradd ' + string.join(options) + ' ' + username, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True, display_on_tty8=True)
1246 if not GLIUtility.exitsuccess(exitstatus):
1247 self._logger.log("ERROR! : Failure to add user " + username)
1248 # raise GLIException("AddUserError", 'warning', 'set_users', "Failure to add user " + username)
1249 else:
1250 self._logger.log("User " + username + " was added.")
1251
1252 ##
1253 # Installs a list of packages specified in the profile. Will install any extra software!
1254 # In the future this function will lead to better things. It may even wipe your ass for you.
1255 def install_packages(self):
1256 installpackages = self._install_profile.get_install_packages()
1257 if installpackages:
1258 # pkglist = self._portage.get_deps(" ".join(installpackages))
1259 # if self._debug: self._logger.log("install_packages(): pkglist is " + str(pkglist))
1260 # for i, pkg in enumerate(pkglist):
1261 # if self._debug: self._logger.log("install_packages(): processing package " + pkg)
1262 # self.notify_frontend("progress", (float(i) / len(pkglist), "Emerging " + pkg + " (" + str(i) + "/" + str(len(pkglist)) + ")"))
1263 # if not self._portage.get_best_version_vdb("=" + pkg):
1264 # status = self._emerge("=" + pkg)
1265 # if not GLIUtility.exitsuccess(status):
1266 # raise GLIException("ExtraPackagesError", "fatal", "install_packages", "Could not emerge " + pkg + "!")
1267 # else:
1268 # try:
1269 # self._portage.copy_pkg_to_chroot(pkg)
1270 # except:
1271 # raise GLIException("ExtraPackagesError", "fatal", "install_packages", "Could not emerge " + pkg + "!")
1272 self._portage.emerge(installpackages, self._install_profile.get_grp_install())
1273
1274 if GLIUtility.is_file(self._chroot_dir + "/etc/X11"):
1275 # Copy the xorg.conf from the LiveCD if they installed xorg-x11
1276 exitstatus = GLIUtility.spawn("cp /etc/X11/xorg.conf " + self._chroot_dir + "/etc/X11/xorg.conf")
1277 if not GLIUtility.exitsuccess(exitstatus):
1278 self._logger.log("Could NOT copy the xorg configuration from the livecd to the new system!")
1279 else:
1280 self._logger.log("xorg.conf copied to new system. X should be ready to roll!")
1281 if GLIUtility.is_file(self._chroot_dir + "/etc/X11/gdm/gdm.conf"):
1282 GLIUtility.spawn("cp -f /etc/X11/gdm/gdm.conf.old " + self._chroot_dir + "/etc/X11/gdm/gdm.conf")
1283 if GLIUtility.is_file(self._chroot_dir + "/etc/X11/gdm/custom.conf"):
1284 GLIUtility.spawn("cp -f /etc/X11/gdm/custom.conf.old " + self._chroot_dir + "/etc/X11/gdm/custom.conf")
1285
1286 ##
1287 # Will set the list of services to runlevel default. This is a temporary solution!
1288 def set_services(self):
1289 services = self._install_profile.get_services()
1290 for service in services:
1291 if service:
1292 self._add_to_runlevel(service)
1293
1294
1295 ##
1296 # Will execute any arbritraially defined script here for post-install customization.
1297 def run_post_install_script(self):
1298 if self._install_profile.get_post_install_script_uri():
1299 try:
1300 if self._debug: self._logger.log("DEBUG: run_post_install_script(): getting script: "+self._install_profile.get_post_install_script_uri())
1301 GLIUtility.get_uri(self._install_profile.get_post_install_script_uri(), self._chroot_dir + "/var/tmp/post-install")
1302 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")
1303 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)
1304 except:
1305 raise GLIException("RunPostInstallScriptError", 'fatal', 'run_post_install_script', "Failed to retrieve and/or execute post-install script")
1306
1307
1308 ##
1309 # This function will handle the various cleanup tasks as well as unmounting the filesystems for reboot.
1310 def finishing_cleanup(self):
1311 #These are temporary until I come up with a nicer idea.
1312 #get rid of the compile_output file so the symlink doesn't get screwed up.
1313
1314 #we copy the log over to the new system.
1315 install_logfile = LOGFILE
1316 try:
1317 if self._debug: self._logger.log("DEBUG: finishing_cleanup(): copying logfile over to new system's root.")
1318 shutil.copy(install_logfile, self._chroot_dir + install_logfile)
1319 except:
1320 if self._debug: self._logger.log("DEBUG: finishing_cleanup(): ERROR! could not copy logfile over to /root.")
1321 #Now we're done logging as far as the new system is concerned.
1322 GLIUtility.spawn("cp /tmp/installprofile.xml " + self._chroot_dir + "/root/installprofile.xml")
1323
1324
1325 #Unmount mounted fileystems in preparation for reboot
1326 #mounts = GLIUtility.spawn(r"mount | sed -e 's:^.\+ on \(.\+\) type .\+$:\1:' | grep -e '^" + self._chroot_dir + "' | sort -r", return_output=True)[1].split("\n")
1327 if self._debug: self._logger.log("DEBUG: mounted_devices is %s" % str(self._mounted_devices))
1328 mounted_devices = self._mounted_devices
1329 mounted_devices.sort()
1330 mounted_devices.reverse()
1331 for mount in mounted_devices:
1332 if self._debug: self._logger.log("DEBUG: finishing_cleanup(): running: umount -l " + mount)
1333 ret = GLIUtility.spawn("umount -l " + self._chroot_dir + mount)
1334 if not GLIUtility.exitsuccess(ret):
1335 self._logger.log("ERROR! : Could not unmount mountpoint %s" % mount)
1336
1337 # now turn off all swap as well.
1338 # we need to find the swap devices
1339 for swap_device in self._swap_devices:
1340 if self._debug: self._logger.log("DEBUG: finishing_cleanup(): running: swapoff "+swap_device)
1341 ret = GLIUtility.spawn("swapoff "+swap_device)
1342 if not GLIUtility.exitsuccess(ret):
1343 self._logger.log("ERROR! : Could not deactivate swap ("+swap_device+")!")
1344
1345 GLIUtility.spawn("rm /tmp/compile_output.log && rm " + install_logfile)
1346
1347
1348
1349 ##
1350 # This function should only be called in the event of an install failure. It performs
1351 # general cleanup to prepare the system for another installer run.
1352 def install_failed_cleanup(self):
1353 steps = len(self._mounted_devices) + len(self._swap_devices) + 2
1354 cur_step = 0
1355 if self._debug: self._logger.log("DEBUG: install_failed_cleanup(): gathering mounts to unmount")
1356 #mounts = GLIUtility.spawn(r"mount | sed -e 's:^.\+ on \(.\+\) type .\+$:\1:' | grep -e '^" + self._chroot_dir + "' | sort -r", return_output=True)[1].split("\n")
1357 if self._debug: self._logger.log("DEBUG: mounted_devices is %s" % str(self._mounted_devices))
1358 mounted_devices = self._mounted_devices
1359 mounted_devices.sort()
1360 mounted_devices.reverse()
1361 for mount in mounted_devices:
1362 cur_step += 1
1363 self.notify_frontend("progress", (float(cur_step) / (steps), "Unmounting " + mount))
1364 if self._debug: self._logger.log("DEBUG: install_failed_cleanup(): running: umount -l " + mount)
1365 ret = GLIUtility.spawn("umount -l " + self._chroot_dir + mount)
1366 if not GLIUtility.exitsuccess(ret):
1367 self._logger.log("ERROR! : Could not unmount mountpoint %s" % mount)
1368
1369 # now turn off all swap as well.
1370 # we need to find the swap devices
1371 for swap_device in self._swap_devices:
1372 cur_step += 1
1373 self.notify_frontend("progress", (float(cur_step) / (steps), "Deactivating swap on " + swap_device))
1374 if self._debug: self._logger.log("DEBUG: install_failed_cleanup(): running: swapoff "+swap_device)
1375 ret = GLIUtility.spawn("swapoff "+swap_device)
1376 if not GLIUtility.exitsuccess(ret):
1377 self._logger.log("ERROR! : Could not deactivate swap ("+swap_device+")!")
1378
1379 if self._debug: self._logger.log("DEBUG: install_failed_cleanup(): running: mv /tmp/compile_output.log /tmp/compile_output.log.failed")
1380 self.notify_frontend("progress", (float(cur_step + 1) / (steps), "Moving compile output logfile"))
1381 GLIUtility.spawn("mv " + self._compile_logfile + " " + self._compile_logfile + ".failed")
1382 # GLIUtility.spawn("rm /tmp/compile_output.log")
1383 self.notify_frontend("progress", (float(cur_step + 2) / (steps), "Moving install logfile"))
1384 GLIUtility.spawn("mv " + LOGFILE + " " + LOGFILE + ".failed")
1385 # GLIUtility.spawn("rm /var/log/installer.log")

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20