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

Contents of /trunk/src/GLIArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1280 - (show annotations) (download) (as text)
Tue Feb 7 02:05:39 2006 UTC (14 years, 6 months ago) by agaffney
File MIME type: text/x-python
File size: 66863 byte(s)
  src/GLIPortage, src/GLIArchitectureTemplate.py:
  ignore_missing flag for copy_pkg_to_chroot()

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

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20