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

Contents of /trunk/src/GLIArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1182 - (hide annotations) (download) (as text)
Fri Dec 23 22:32:57 2005 UTC (14 years, 10 months ago) by agaffney
File MIME type: text/x-python
File size: 77616 byte(s)
  move some of portage function from GLIAT
  src/GLIArchitectureTemplate.py:
  revamp install_packages() for new GLIPortage

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

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20