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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 664 - (show annotations) (download) (as text)
Mon Jun 13 00:30:12 2005 UTC (13 years, 4 months ago) by robbat2
Original Path: trunk/src/GLIArchitectureTemplate.py
File MIME type: text/x-python
File size: 47948 byte(s)
ensure PORTAGE_TMPDIR/PORT_LOGDIR/PORTDIR_OVERLAY/PKGDIR exist prior to any usage - this caused a failure for stage1/stage2 previously. swapoff for swap space at end of install.

1 """
2 Gentoo Linux Installer
3
4 $Id: GLIArchitectureTemplate.py,v 1.132 2005/06/13 00:30:12 robbat2 Exp $
5 Copyright 2005 Gentoo Technologies Inc.
6
7 The ArchitectureTemplate is largely meant to be an abstract class and an
8 interface (yes, it is both at the same time!). The purpose of this is to create
9 subclasses that populate all the methods with working methods for that architecture.
10 The only definitions that are filled in here are architecture independent.
11
12 """
13
14 import GLIUtility, GLILogger, os, string, sys, shutil, re
15 from GLIException import *
16
17 class ArchitectureTemplate:
18 ##
19 # Initialization of the ArchitectureTemplate. Called from some other arch template.
20 # @param selfconfiguration=None A Client Configuration
21 # @param install_profile=None An Install Profile
22 # @param client_controller=None Client Controller. not same as configuration.
23 def __init__(self,configuration=None, install_profile=None, client_controller=None):
24 self._client_configuration = configuration
25 self._install_profile = install_profile
26 self._cc = client_controller
27
28 # This will get used a lot, so it's probably
29 # better to store it in a variable than to call
30 # this method 100000 times.
31 self._chroot_dir = self._client_configuration.get_root_mount_point()
32 self._logger = GLILogger.Logger(self._client_configuration.get_log_file())
33 self._compile_logfile = "/tmp/compile_output.log"
34
35 # These must be filled in by the subclass. _steps is a list of
36 # functions, that will carry out the installation. They must be
37 # in order.
38 #
39 # For example, self._steps might be: [preinstall, stage1, stage2, stage3, postinstall],
40 # where each entry is a function (with no arguments) that carries out the desired actions.
41 # Of course, steps will be different depending on the install_profile
42
43 self._architecture_name = "generic"
44 self._install_steps = [
45 (self.partition, "Partition"),
46 (self.mount_local_partitions, "Mount local partitions"),
47 (self.mount_network_shares, "Mount network (NFS) shares"),
48 (self.unpack_stage_tarball, "Unpack stage tarball"),
49 (self.configure_make_conf, "Configure /etc/make.conf"),
50 (self.set_etc_portage, "Setting /etc/portage/"),
51 (self.prepare_chroot, "Preparing chroot"),
52 (self.install_portage_tree, "Portage tree voodoo"),
53 (self.stage1, "Performing bootstrap"),
54 (self.stage2, "Performing 'emerge system'"),
55 (self.set_root_password, "Set the root password"),
56 (self.set_timezone, "Setting timezone"),
57 (self.emerge_kernel_sources, "Emerge kernel sources"),
58 (self.build_kernel, "Building kernel"),
59 (self.install_mta, "Installing MTA"),
60 (self.install_logging_daemon, "Installing system logger"),
61 (self.install_cron_daemon, "Installing Cron daemon"),
62 (self.install_filesystem_tools, "Installing filesystem tools"),
63 (self.setup_network_post, "Configuring post-install networking"),
64 (self.install_bootloader, "Configuring and installing bootloader"),
65 (self.update_config_files, "Updating config files"),
66 (self.configure_rc_conf, "Updating /etc/rc.conf"),
67 (self.set_users, "Add additional users."),
68 (self.install_packages, "Installing additional packages."),
69 # services for startup need to come after installing extra packages
70 # otherwise some of the scripts will not exist.
71 (self.set_services, "Setting up services for startup"),
72 (self.run_post_install_script, "Running custom post-install script"),
73 (self.finishing_cleanup, "Cleanup and unmounting local filesystems.")
74 ]
75
76
77 ##
78 # Returns the steps and their comments in an array
79 def get_install_steps(self):
80 return self._install_steps
81
82 ##
83 # Tells the frontend something
84 # @param type type of data
85 # @param data the data itself. usually a number.
86 def notify_frontend(self, type, data):
87 self._cc.addNotification(type, data)
88
89 # It is possible to override these methods in each Arch Template.
90 # It might be necessary to do so, if the arch needs something 'weird'.
91
92 ##
93 # Private function to add a /etc/init.d/ script to the given runlevel in the chroot environement
94 # @param script_name the script to be added
95 # @param runlevel="default" the runlevel to add to
96 def _add_to_runlevel(self, script_name, runlevel="default"):
97 if not GLIUtility.is_file(self._chroot_dir + '/etc/init.d/' + script_name):
98 raise GLIException("RunlevelAddError", 'fatal', '_add_to_runlevel', "Failure adding " + script_name + " to runlevel " + runlevel + "!")
99 status = GLIUtility.spawn("rc-update add " + script_name + " " + runlevel, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True)
100 if not GLIUtility.exitsuccess(status):
101 raise GLIException("RunlevelAddError", 'fatal', '_add_to_runlevel', "Failure adding " + script_name + " to runlevel " + runlevel + "!")
102 self._logger.log("Added "+script_name+" to runlevel "+runlevel)
103
104 ##
105 # Private Function. Will return a list of packages to be emerged for a given command. Not yet used.
106 # @param cmd full command to run ('/usr/portage/scripts/bootstrap.sh --pretend' or 'emerge -p system')
107 def _get_packages_to_emerge(self, cmd):
108 return GLIUtility.spawn(cmd + r" | grep -e '\[ebuild' | sed -e 's:\[ebuild .\+ \] ::' -e 's: \[.\+\] ::' -e 's: +$::'", chroot=self._chroot_dir, return_output=True)[1].split("\n")
109
110 ##
111 # Private function. For binary installs it will attempt to quickpkg packages that are on the livecd.
112 # @param package package to be quickpkg'd.
113 def _quickpkg_deps(self, package):
114 # These need to be changed to pull values from the make.conf stuff
115 PKGDIR = "/usr/portage/packages"
116 PORTAGE_TMPDIR = "/var/tmp"
117 make_conf = self._install_profile.get_make_conf()
118 if "PKGDIR" in make_conf and make_conf['PKGDIR']: PKGDIR = make_conf['PKGDIR']
119 if "PORTAGE_TMPDIR" in make_conf and make_conf['PORTAGE_TMPDIR']: PORTAGE_TMPDIR = make_conf['PORTAGE_TMPDIR']
120 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PKGDIR, logfile=self._compile_logfile, append_log=True)
121 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PORTAGE_TMPDIR, logfile=self._compile_logfile, append_log=True)
122 packages = self._get_packages_to_emerge("emerge -p " + package)
123 for pkg in packages:
124 if not GLIUtility.is_file(self._chroot_dir + PKGDIR + "/All/" + pkg.split('/')[1] + ".tbz2"):
125 ret = GLIUtility.spawn("env PKGDIR='" + self._chroot_dir + PKGDIR + "' PORTAGE_TMPDIR='" + self._chroot_dir + PORTAGE_TMPDIR + "' quickpkg =" + pkg)
126 if ret:
127 # This package couldn't be quickpkg'd. This may be an error in the future
128 pass
129
130 ##
131 # Private Function. Will emerge a given package in the chroot environment.
132 # @param package package to be emerged
133 # @param binary=False defines whether to try a binary emerge (if GRP this gets ignored either way)
134 # @param binary_only=False defines whether to only allow binary emerges.
135 def _emerge(self, package, binary=True, binary_only=False):
136 #Error checking of this function is to be handled by the parent function.
137 # now short-circuit for GRP
138 if self._install_profile.get_grp_install():
139 self._quickpkg_deps(package)
140 cmd="NOCOLOR=yes emerge -k " + package
141 # now normal installs
142 else:
143 if binary_only:
144 cmd="NOCOLOR=yes emerge -K " + package
145 elif binary:
146 cmd="NOCOLOR=yes emerge -k " + package
147 else:
148 cmd="NOCOLOR=yes emerge " + package
149
150 self._logger.log("Calling emerge: "+cmd)
151 return GLIUtility.spawn(cmd, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True)
152
153 ##
154 # Private Function. Will edit a config file and insert a value or two overwriting the previous value
155 # (actually it only just comments out the old one)
156 # @param filename file to be edited
157 # @param newvalues a dictionary of VARIABLE:VALUE pairs
158 # @param delimeter='=' what is between the key and the value
159 # @param quotes_around_value=True whether there are quotes around the value or not (ex. "local" vs. localhost)
160 # @param only_value=False Ignore the keys and output only a value.
161 # @param create_file=True Create the file if it does not exist.
162 def _edit_config(self, filename, newvalues, delimeter='=', quotes_around_value=True, only_value=False,create_file=True):
163 # don't use 'file' as a normal variable as it conflicts with the __builtin__.file
164 if GLIUtility.is_file(filename):
165 f = open(filename)
166 contents = f.readlines()
167 f.close()
168 elif create_file:
169 contents = []
170 else:
171 raise GLIException("NoSuchFileError", 'notice','_edit_config',filename + ' does not exist!')
172
173 for key in newvalues.keys():
174 regexpr = '^\s*#?\s*' + key + '\s*' + delimeter + '.*$'
175 regexpr = re.compile(regexpr)
176
177 for i in range(0, len(contents)):
178 if regexpr.match(contents[i]):
179 if not contents[i][0] == '#':
180 contents[i] = '#' + contents[i]
181
182 contents.append('\n# Added by GLI\n')
183 commentprefix = ""
184 if key == "SPACER":
185 contents.append('\n')
186 elif key == "COMMENT":
187 contents.append('# ' + newvalues[key] + '\n')
188 elif newvalues[key] == "##comment##" or newvalues[key] == "##commented##":
189 contents.append('#' + key + delimeter + '""' + "\n")
190 else:
191 if quotes_around_value:
192 newvalues[key] = '"' + newvalues[key] + '"'
193 #Only the printing of values is required.
194 if only_value:
195 contents.append(newvalues[key] + '\n')
196 else:
197 contents.append(key + delimeter + newvalues[key]+'\n')
198
199 f = open(filename,'w')
200 f.writelines(contents)
201 f.flush()
202 f.close()
203 self._logger.log("Edited Config file "+filename)
204
205 ##
206 # Stage 1 install -- bootstraping the system
207 # If we are doing a stage 1 install, then bootstrap
208 def stage1(self):
209 if self._install_profile.get_install_stage() == 1:
210 self._logger.mark()
211 self._logger.log("Starting bootstrap.")
212 pkgs = self._get_packages_to_emerge("/usr/portage/scripts/bootstrap.sh --pretend")
213 exitstatus = GLIUtility.spawn("/usr/portage/scripts/bootstrap.sh", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
214 if not GLIUtility.exitsuccess(exitstatus):
215 raise GLIException("Stage1Error", 'fatal','stage1', "Bootstrapping failed!")
216 self._logger.log("Bootstrap complete.")
217
218 ##
219 # Stage 2 install -- emerge -e system
220 # If we are doing a stage 1 or 2 install, then emerge system
221 def stage2(self):
222
223 if self._install_profile.get_install_stage() in [ 1, 2 ]:
224 self._logger.mark()
225 self._logger.log("Starting emerge system.")
226 pkgs = self._get_packages_to_emerge("emerge -p system") #currently quite the useless
227 exitstatus = self._emerge("--emptytree system")
228 if not GLIUtility.exitsuccess(exitstatus):
229 raise GLIException("Stage2Error", 'fatal','stage2', "Building the system failed!")
230 self._logger.log("Emerge system complete.")
231
232 ##
233 # Unpacks the stage tarball that has been specified in the profile (it better be there!)
234 def unpack_stage_tarball(self):
235 if not os.path.isdir(self._chroot_dir):
236 os.makedirs(self._chroot_dir)
237 GLIUtility.fetch_and_unpack_tarball(self._install_profile.get_stage_tarball_uri(), self._chroot_dir, temp_directory=self._chroot_dir, keep_permissions=True)
238 self._logger.log(self._install_profile.get_stage_tarball_uri()+" was unpacked.")
239
240 ##
241 # Prepares the Chroot environment by copying /etc/resolv.conf and mounting proc and dev
242 def prepare_chroot(self):
243 # Copy resolv.conf to new env
244 try:
245 shutil.copy("/etc/resolv.conf", self._chroot_dir + "/etc/resolv.conf")
246 except:
247 pass
248 ret = GLIUtility.spawn("mount -t proc none "+self._chroot_dir+"/proc")
249 if not GLIUtility.exitsuccess(ret):
250 raise GLIException("MountError", 'fatal','prepare_chroot','Could not mount /proc')
251 ret = GLIUtility.spawn("mount -o bind /dev " + self._chroot_dir + "/dev")
252 if not GLIUtility.exitsuccess(ret):
253 raise GLIException("MountError", 'fatal','prepare_chroot','Could not mount /dev')
254 ret = GLIUtility.spawn("mount -o bind /sys " + self._chroot_dir + "/sys")
255 if not GLIUtility.exitsuccess(ret):
256 raise GLIException("MountError", 'fatal','prepare_chroot','Could not mount /sys')
257 GLIUtility.spawn("mv " + self._compile_logfile + " " + self._chroot_dir + self._compile_logfile + " && ln -s " + self._chroot_dir + self._compile_logfile + " " + self._compile_logfile)
258 self._logger.log("Chroot environment ready.")
259
260 ##
261 # Installs a list of packages specified in the profile. Will install any extra software!
262 # In the future this function will lead to better things. It may even wipe your ass for you.
263 def install_packages(self):
264 installpackages = self._install_profile.get_install_packages()
265 for package in installpackages:
266 self._logger.log("Starting emerge " + package)
267 status = self._emerge(package)
268 if not GLIUtility.exitsuccess(status):
269 self._logger.log("Could not emerge " + package + "!")
270 # raise GLIException("InstallPackagesError", 'warning', 'install_packages', "Could not emerge " + package + "!")
271 else:
272 self._logger.log("Emerged package: " + package)
273
274 ##
275 # Will set the list of services to runlevel default. This is a temporary solution!
276 def set_services(self):
277 services = self._install_profile.get_services()
278 for service in services:
279 status = self._add_to_runlevel(service)
280
281 ##
282 # Will grab partition info from the profile and mount all partitions with a specified mountpoint (and swap too)
283 def mount_local_partitions(self):
284 #{ 1: { 'end': 1999871, 'format': False, 'mb': 0,
285 #'mountopts': '', 'mountpoint': '', 'start': 63, 'type': 'linux-swap'},
286 #2: { 'end': 240121727, 'format': False, 'mb': 0, 'mountopts': '',
287 #'mountpoint': '', 'start': 1999872, 'type': 'ext3'}}
288
289 parts = self._install_profile.get_partition_tables()
290 parts_to_mount = {}
291 for device in parts:
292 tmp_partitions = parts[device].get_install_profile_structure()
293 for partition in tmp_partitions:
294 mountpoint = tmp_partitions[partition]['mountpoint']
295 mountopts = tmp_partitions[partition]['mountopts']
296 minor = str(int(tmp_partitions[partition]['minor']))
297 partition_type = tmp_partitions[partition]['type']
298 if mountpoint:
299 if mountopts:
300 mountopts = "-o "+mountopts+" "
301 if partition_type:
302 partition_type = "-t "+partition_type+" "
303 parts_to_mount[mountpoint]= {0: mountopts, 1: partition_type, 2: minor}
304
305 if partition_type == "linux-swap":
306 ret = GLIUtility.spawn("swapon "+device+minor)
307 if not GLIUtility.exitsuccess(ret):
308 self._logger.log("ERROR! : Could not activate swap!")
309 # raise GLIException("MountError", 'warning','mount_local_partitions','Could not activate swap')
310 sorted_list = []
311 for key in parts_to_mount.keys(): sorted_list.append(key)
312 sorted_list.sort()
313
314 for mountpoint in sorted_list:
315 mountopts = parts_to_mount[mountpoint][0]
316 partition_type = parts_to_mount[mountpoint][1]
317 minor = parts_to_mount[mountpoint][2]
318 if not GLIUtility.is_file(self._chroot_dir+mountpoint):
319 exitstatus = GLIUtility.spawn("mkdir -p " + self._chroot_dir + mountpoint)
320 if exitstatus != 0:
321 raise GLIException("MkdirError", 'fatal','mount_local_partitions', "Making the mount point failed!")
322 ret = GLIUtility.spawn("mount "+partition_type+mountopts+device+minor+" "+self._chroot_dir+mountpoint, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
323 if not GLIUtility.exitsuccess(ret):
324 raise GLIException("MountError", 'fatal','mount_local_partitions','Could not mount a partition')
325 self._logger.log("Mounted mountpoint:"+mountpoint)
326 ##
327 # Mounts all network shares to the local machine
328 def mount_network_shares(self):
329 """
330 <agaffney> it'll be much easier than mount_local_partitions
331 <agaffney> make sure /etc/init.d/portmap is started
332 <agaffney> then mount each one: mount -t nfs -o <mountopts> <host>:<export> <mountpoint>
333 """
334 nfsmounts = self._install_profile.get_network_mounts()
335 for netmount in nfsmounts:
336 if netmount['type'] == "NFS" or netmount['type'] == "nfs":
337 mountopts = netmount['mountopts']
338 if mountopts:
339 mountopts = "-o "+mountopts
340 host = netmount['host']
341 export = netmount['export']
342 mountpoint = netmount['mountpoint']
343 if not GLIUtility.is_file(self._chroot_dir+mountpoint):
344 exitstatus = GLIUtility.spawn("mkdir -p " + self._chroot_dir + mountpoint)
345 if exitstatus != 0:
346 raise GLIException("MkdirError", 'fatal','mount_network_shares', "Making the mount point failed!")
347 ret = GLIUtility.spawn("mount -t nfs "+mountopts+" "+host+":"+export+" "+self._chroot_dir+mountpoint, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
348 if not GLIUtility.exitsuccess(ret):
349 raise GLIException("MountError", 'fatal','mount_network_shares','Could not mount an NFS partition')
350 self._logger.log("Mounted netmount at mountpoint:"+mountpoint)
351
352 ##
353 # Gets sources from CD (required for non-network installation)
354 # WARNING: There will no longer be sources on the future livecds. this will have to change!
355 def fetch_sources_from_cd(self):
356 """
357 THIS FUNCTION IS NO LONGER VALID
358 if not GLIUtility.is_file(self._chroot_dir+"/usr/portage/distfiles"):
359 exitstatus = GLIUtility.spawn("mkdir -p /usr/portage/distfiles",chroot=self._chroot_dir)
360 if exitstatus != 0:
361 raise GLIException("MkdirError", 'fatal','install_portage_tree',"Making the distfiles directory failed.")
362 exitstatus = GLIUtility.spawn("cp /mnt/cdrom/distfiles/* "+self._chroot_dir+"/usr/portage/distfiles/", display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
363 if exitstatus != 0:
364 raise GLIException("PortageError", 'fatal','install_portage_tree',"Failed to copy the distfiles to the new system")
365 """
366 self._logger.log("Distfiles copied from cd. NOT!")
367
368 ##
369 # Configures the new /etc/make.conf
370 def configure_make_conf(self):
371 # Get make.conf options
372 options = self._install_profile.get_make_conf()
373
374 # For each configuration option...
375 for key in options.keys():
376 # Add/Edit it into make.conf
377 self._edit_config(self._chroot_dir + "/etc/make.conf", {key: options[key]})
378 self._logger.log("Make.conf configured")
379 # now make any directories that emerge needs, otherwise it will fail
380 # this must take place before ANY calls to emerge.
381 # otherwise emerge will fail (for PORTAGE_TMPDIR anyway)
382 PKGDIR = '/usr/portage/packages'
383 PORTAGE_TMPDIR = '/var/tmp'
384 PORT_LOGDIR = None
385 PORTDIR_OVERLAY = None
386 make_conf = self._install_profile.get_make_conf()
387 if 'PKGDIR' in make_conf: PKGDIR = make_conf['PKGDIR']
388 if 'PORTAGE_TMPDIR' in make_conf: PORTAGE_TMPDIR = make_conf['PORTAGE_TMPDIR']
389 if 'PORT_LOGDIR' in make_conf: PORT_LOGDIR = make_conf['PORT_LOGDIR']
390 if 'PORTDIR_OVERLAY' in make_conf: PORTDIR_OVERLAY = make_conf['PORTDIR_OVERLAY']
391 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PKGDIR, logfile=self._compile_logfile, append_log=True)
392 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PORTAGE_TMPDIR, logfile=self._compile_logfile, append_log=True)
393 if PORT_LOGDIR != None:
394 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PORT_LOGDIR, logfile=self._compile_logfile, append_log=True)
395 if PORTDIR_OVERLAY != None:
396 GLIUtility.spawn("mkdir -p " + self._chroot_dir + PORTDIR_OVERLAY, logfile=self._compile_logfile, append_log=True)
397
398 ##
399 # This will get/update the portage tree. If you want to snapshot or mount /usr/portage use "custom".
400 def install_portage_tree(self):
401 # Check the type of portage tree fetching we'll do
402 # If it is custom, follow the path to the custom tarball and unpack it
403
404 # This is a hack to copy the LiveCD's rsync into the chroot since it has the sigmask patch
405 GLIUtility.spawn("cp -a /usr/bin/rsync " + self._chroot_dir + "/usr/bin/rsync")
406 GLIUtility.spawn("cp -a /usr/lib/libpopt* " + self._chroot_dir + "/usr/lib")
407
408 if self._install_profile.get_portage_tree_sync_type() == "snapshot" or self._install_profile.get_portage_tree_sync_type() == "custom": # Until this is finalized
409
410 # Get portage tree info
411 portage_tree_snapshot_uri = self._install_profile.get_portage_tree_snapshot_uri()
412 if portage_tree_snapshot_uri:
413 # Fetch and unpack the tarball
414 GLIUtility.fetch_and_unpack_tarball(portage_tree_snapshot_uri, self._chroot_dir + "/usr/", self._chroot_dir + "/")
415 self._logger.log("Portage tree install was custom.")
416 # If the type is webrsync, then run emerge-webrsync
417 elif self._install_profile.get_portage_tree_sync_type() == "webrsync":
418 exitstatus = GLIUtility.spawn("emerge-webrsync", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
419 if exitstatus != 0:
420 raise GLIException("EmergeWebRsyncError", 'fatal','install_portage_tree', "Failed to retrieve portage tree!")
421 self._logger.log("Portage tree sync'd using webrsync")
422 # Otherwise, just run emerge sync
423 else:
424 exitstatus = self._emerge("sync")
425 if exitstatus != 0:
426 raise GLIException("EmergeSyncError", 'fatal','install_portage_tree', "Failed to retrieve portage tree!")
427 self._logger.log("Portage tree sync'd")
428
429 ##
430 # Sets the timezone for the new environment
431 def set_timezone(self):
432
433 # Set symlink
434 if os.access(self._chroot_dir + "/etc/localtime", os.W_OK):
435 GLIUtility.spawn("rm "+self._chroot_dir + "/etc/localtime")
436 GLIUtility.spawn("ln -s ../usr/share/zoneinfo/" + self._install_profile.get_time_zone() + " /etc/localtime", chroot=self._chroot_dir)
437 if not (self._install_profile.get_time_zone() == "UTC"):
438 self._edit_config(self._chroot_dir + "/etc/rc.conf", {"CLOCK":"local"})
439 self._logger.log("Timezone set.")
440
441 ##
442 # Configures /etc/fstab on the new envorinment
443 def configure_fstab(self):
444 newfstab = ""
445 parts = self._install_profile.get_partition_tables()
446 for device in parts:
447 tmp_partitions = parts[device].get_install_profile_structure()
448 for partition in tmp_partitions:
449 mountpoint = tmp_partitions[partition]['mountpoint']
450 minor = str(int(tmp_partitions[partition]['minor']))
451 partition_type = tmp_partitions[partition]['type']
452 mountopts = tmp_partitions[partition]['mountopts']
453 if not mountopts.strip(): mountopts = "defaults"
454 if mountpoint:
455 if not GLIUtility.is_file(self._chroot_dir+mountpoint):
456 exitstatus = GLIUtility.spawn("mkdir -p " + self._chroot_dir + mountpoint)
457 if exitstatus != 0:
458 raise GLIException("MkdirError", 'fatal','configure_fstab', "Making the mount point failed!")
459 newfstab += device+minor+"\t "+mountpoint+"\t "+partition_type+"\t "+mountopts+"\t\t "
460 if mountpoint == "/boot":
461 newfstab += "1 2\n"
462 elif mountpoint == "/":
463 newfstab += "0 1\n"
464 else:
465 newfstab += "0 0\n"
466 if partition_type == "linux-swap":
467 newfstab += device+minor+"\t none swap sw 0 0\n"
468 newfstab += "none /proc proc defaults 0 0\n"
469 newfstab += "none /dev/shm tmpfs defaults 0 0\n"
470 if GLIUtility.is_device("/dev/cdroms/cdrom0"):
471 newfstab += "/dev/cdroms/cdrom0 /mnt/cdrom auto noauto,user 0 0\n"
472
473 for netmount in self._install_profile.get_network_mounts():
474 if netmount['type'] == "nfs":
475 newfstab += netmount['host'] + ":" + netmount['export'] + "\t" + netmount['mountpoint'] + "\tnfs\t" + netmount['mountopts'] + "\t0 0\n"
476
477 file_name = self._chroot_dir + "/etc/fstab"
478 try:
479 shutil.move(file_name, file_name + ".OLDdefault")
480 except:
481 pass
482 f = open(file_name, 'w')
483 f.writelines(newfstab)
484 f.close()
485 self._logger.log("fstab configured.")
486
487 ##
488 # Fetches desired kernel sources, unless you're using a livecd-kernel in which case it does freaky stuff.
489 def emerge_kernel_sources(self):
490 self._logger.log("Starting emerge_kernel")
491 kernel_pkg = self._install_profile.get_kernel_source_pkg()
492 # if kernel_pkg:
493 # Special case, no kernel installed
494 if kernel_pkg == "none":
495 return
496 # Special case, livecd kernel
497 elif kernel_pkg == "livecd-kernel":
498 PKGDIR = "/usr/portage/packages"
499 PORTAGE_TMPDIR = "/var/tmp"
500 make_conf = self._install_profile.get_make_conf()
501 if "PKGDIR" in make_conf: PKGDIR = make_conf['PKGDIR']
502 if "PORTAGE_TMPDIR" in make_conf: PORTAGE_TMPDIR = make_conf['PORTAGE_TMPDIR']
503 # directories are created previously
504 ret = GLIUtility.spawn("env PKGDIR=" + self._chroot_dir + PKGDIR + " PORTAGE_TMPDIR=" + self._chroot_dir + PORTAGE_TMPDIR + " quickpkg livecd-kernel")
505 ret = GLIUtility.spawn("env PKGDIR=" + PKGDIR + " emerge -K sys-kernel/livecd-kernel", chroot=self._chroot_dir)
506
507 #these are the hotplug/coldplug steps from build_kernel copied over here. they will NOT be run there.
508 exitstatus = self._emerge("hotplug")
509 if exitstatus != 0:
510 raise GLIException("EmergeHotplugError", 'fatal','build_kernel', "Could not emerge hotplug!")
511 self._logger.log("Hotplug emerged.")
512 exitstatus = self._emerge("coldplug")
513 if exitstatus != 0:
514 raise GLIException("EmergeColdplugError", 'fatal','build_kernel', "Could not emerge coldplug!")
515 self._logger.log("Coldplug emerged. Now they should be added to the default runlevel.")
516
517 self._add_to_runlevel("hotplug")
518 self._add_to_runlevel("coldplug", runlevel="boot")
519 # normal case
520 else:
521 exitstatus = self._emerge(kernel_pkg)
522 if exitstatus != 0:
523 raise GLIException("EmergeKernelSourcesError", 'fatal','emerge_kernel_sources',"Could not retrieve kernel sources!")
524 try:
525 os.stat(self._chroot_dir + "/usr/src/linux")
526 except:
527 kernels = os.listdir(self._chroot_dir+"/usr/src")
528 found_a_kernel = False
529 counter = 0
530 while not found_a_kernel:
531 if kernels[counter][0:6]=="linux-":
532 exitstatus = GLIUtility.spawn("ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux",chroot=self._chroot_dir)
533 if exitstatus != 0:
534 raise GLIException("EmergeKernelSourcesError", 'fatal','emerge_kernel_sources',"Could not make a /usr/src/linux symlink")
535 found_a_kernel = True
536 else:
537 counter = counter + 1
538 self._logger.log("Kernel sources:"+kernel_pkg+" emerged and /usr/src/linux symlinked.")
539
540 ##
541 # Builds the kernel using genkernel or regularly if given a custom .config file in the profile
542 def build_kernel(self):
543 self._logger.mark()
544 self._logger.log("Starting build_kernel")
545 # No building necessary if using the LiveCD's kernel/initrd
546 # or using the 'none' kernel bypass
547 if self._install_profile.get_kernel_source_pkg() in ["livecd-kernel","none"]:
548 return
549 # Get the uri to the kernel config
550 kernel_config_uri = self._install_profile.get_kernel_config_uri()
551 if kernel_config_uri == "none": # bypass to install a kernel, but not compile it
552 return
553 elif kernel_config_uri == "": #use genkernel if no specific config
554
555 exitstatus = self._emerge("genkernel")
556 if exitstatus != 0:
557 raise GLIException("EmergeGenKernelError", 'fatal','build_kernel', "Could not emerge genkernel!")
558 self._logger.log("Genkernel emerged. Beginning kernel compile.")
559 # Null the genkernel_options
560 genkernel_options = ""
561
562 # If the uri for the kernel config is not null, then
563 if kernel_config_uri != "":
564 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/root/kernel_config")
565 genkernel_options = genkernel_options + " --kernel-config=/root/kernel_config"
566
567 # Decide whether to use bootsplash or not
568 if self._install_profile.get_kernel_bootsplash():
569 genkernel_options = genkernel_options + " --bootsplash"
570 else:
571 genkernel_options = genkernel_options + " --no-bootsplash"
572 # Run genkernel in chroot
573 #print "genkernel all " + genkernel_options
574 exitstatus = GLIUtility.spawn("genkernel all " + genkernel_options, chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
575 if exitstatus != 0:
576 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build kernel!")
577
578 exitstatus = self._emerge("hotplug")
579 if exitstatus != 0:
580 raise GLIException("EmergeHotplugError", 'fatal','build_kernel', "Could not emerge hotplug!")
581 self._logger.log("Hotplug emerged.")
582 exitstatus = self._emerge("coldplug")
583 if exitstatus != 0:
584 raise GLIException("EmergeColdplugError", 'fatal','build_kernel', "Could not emerge coldplug!")
585 self._logger.log("Coldplug emerged. Now they should be added to the default runlevel.")
586
587 self._add_to_runlevel("hotplug")
588 self._add_to_runlevel("coldplug", runlevel="boot")
589 self._logger.log("Genkernel complete.")
590 else: #CUSTOM CONFIG
591 #Copy the kernel .config to the proper location in /usr/src/linux
592 try:
593 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/root/kernel_config")
594 except:
595 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not copy kernel config!")
596
597 kernel_compile_script = "#!/bin/bash\n"
598 kernel_compile_script += "cp /root/kernel_config /usr/src/linux/.config\n"
599 kernel_compile_script += "cd /usr/src/linux\n"
600 kernel_compile_script += "make \nmake modules_install \n"
601
602 #Ok now that it's built, copy it to /boot/kernel-* for bootloader code to find it
603 if self._client_configuration.get_architecture_template() == "x86":
604 kernel_compile_script += "cp /usr/src/linux/arch/i386/boot/bzImage /boot/kernel-custom\n"
605 f = open(self._chroot_dir+"/var/tmp/kernel_script", 'w')
606 f.writelines(kernel_compile_script)
607 f.close()
608 #Build the kernel
609 exitstatus1 = GLIUtility.spawn("chmod u+x "+self._chroot_dir+"/var/tmp/kernel_script")
610 exitstatus2 = GLIUtility.spawn("/var/tmp/kernel_script", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
611 if (exitstatus1 != 0) or (exitstatus2 != 0):
612 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build custom kernel!")
613
614 #i'm sure i'm forgetting something here.
615 #cleanup
616 exitstatus = GLIUtility.spawn("rm "+self._chroot_dir+"/var/tmp/kernel_script")
617 #it's not important if this fails.
618 self._logger.log("Custom kernel complete")
619
620 ##
621 # Installs mail MTA. Does not put into runlevel, as this is not simple with MTAs.
622 def install_mta(self):
623 # Get loggin daemon info
624 mta_pkg = self._install_profile.get_mta_pkg()
625 if mta_pkg:
626 # Emerge Logging Daemon
627 exitstatus = self._emerge(mta_pkg)
628 if exitstatus != 0:
629 raise GLIException("LoggingDaemonError", 'fatal','install_mta', "Could not emerge " + mta_pkg + "!")
630 self._logger.log("MTA installed: "+mta_pkg)
631 ##
632 # Installs and sets up logging daemon on the new system. adds to runlevel too.
633 def install_logging_daemon(self):
634
635 # Get loggin daemon info
636 logging_daemon_pkg = self._install_profile.get_logging_daemon_pkg()
637 if logging_daemon_pkg:
638 # Emerge Logging Daemon
639 exitstatus = self._emerge(logging_daemon_pkg)
640 if exitstatus != 0:
641 raise GLIException("LoggingDaemonError", 'fatal','install_logging_daemon', "Could not emerge " + logging_daemon_pkg + "!")
642
643 # Add Logging Daemon to default runlevel
644 # After we find the name of it's initscript
645 # This current code is a hack, and should be better.
646 initscript = logging_daemon_pkg[(logging_daemon_pkg.find('/')+1):]
647 self._add_to_runlevel(initscript)
648 self._logger.log("Logging daemon installed: "+logging_daemon_pkg)
649 ##
650 # Installs and sets up cron package.
651 def install_cron_daemon(self):
652
653 # Get cron daemon info
654 cron_daemon_pkg = self._install_profile.get_cron_daemon_pkg()
655 if cron_daemon_pkg:
656 # Emerge Cron Daemon
657 exitstatus = self._emerge(cron_daemon_pkg)
658 if exitstatus != 0:
659 raise GLIException("CronDaemonError", 'fatal', 'install_cron_daemon', "Could not emerge " + cron_daemon_pkg + "!")
660
661 # Add Cron Daemon to default runlevel
662 # After we find the name of it's initscript
663 # This current code is a hack, and should be better.
664 initscript = cron_daemon_pkg[(cron_daemon_pkg.find('/')+1):]
665 self._add_to_runlevel(initscript)
666
667 # If the Cron Daemon is not vixie-cron, run crontab
668 if cron_daemon_pkg != "vixie-cron":
669 exitstatus = GLIUtility.spawn("crontab /etc/crontab", chroot=self._chroot_dir, display_on_tty8=True)
670 if exitstatus != 0:
671 raise GLIException("CronDaemonError", 'fatal', 'install_cron_daemon', "Failure making crontab!")
672 self._logger.log("Cron daemon installed and configured: "+cron_daemon_pkg)
673 ##
674 # This will parse the partitions looking for types that require fstools and emerge them if found.
675 def install_filesystem_tools(self):
676 "Installs and sets up fstools"
677 # Get the list of file system tools to be installed
678 parts = self._install_profile.get_partition_tables()
679 filesystem_tools = []
680 for device in parts:
681 tmp_partitions = parts[device].get_install_profile_structure()
682 for partition in tmp_partitions:
683 partition_type = tmp_partitions[partition]['type']
684 if partition_type not in filesystem_tools:
685 filesystem_tools.append(partition_type)
686 for filesystem in filesystem_tools:
687 if filesystem.lower() == "xfs":
688 exitstatus = self._emerge("xfsprogs")
689 if exitstatus != 0:
690 self._logger.log("ERROR! : Could not emerge xfsprogs!")
691 else:
692 self._logger.log("FileSystemTool xfsprogs was emerged successfully.")
693 if filesystem.lower() == "reiserfs":
694 exitstatus = self._emerge("reiserfsprogs")
695 if exitstatus != 0:
696 self._logger.log("ERROR! : Could not emerge reiserfsprogs!")
697 else:
698 self._logger.log("FileSystemTool reiserfsprogs was emerged successfully.")
699 if filesystem.lower() == "jfs":
700 exitstatus = self._emerge("jfsutils")
701 if exitstatus != 0:
702 self._logger.log("ERROR! : Could not emerge jfsutils!")
703 else:
704 self._logger.log("FileSystemTool jfsutils was emerged successfully.")
705
706 ##
707 # Installs rp-pppoe but does not configure it. This function is quite the unknown.
708 def install_rp_pppoe(self):
709
710 # If user wants us to install rp-pppoe, then do so
711 if self._install_profile.get_install_rp_pppoe():
712 exitstatus = self._emerge("rp-pppoe")
713 if exitstatus != 0:
714 self._logger.log("ERROR! : Could not emerge rp-pppoe!")
715 # raise GLIException("RP_PPPOEError", 'warning', 'install_rp_pppoe', "Could not emerge rp-pppoe!")
716 else:
717 self._logger.log("rp-pppoe emerged but not set up.")
718 # Should we add a section here to automatically configure rp-pppoe?
719 # I think it should go into the setup_network_post section
720 # What do you guys think? <-- said by unknown. samyron or npmcallum
721
722 ##
723 # Installs and sets up pcmcia-cs if selected in the profile
724 def install_pcmcia_cs(self):
725 # If user wants us to install pcmcia-cs, then do so
726 if self._install_profile.get_install_pcmcia_cs():
727 exitstatus = self._emerge("pcmcia-cs")
728 if exitstatus != 0:
729 self._logger.log("ERROR! : Could not emerge pcmcia-cs!")
730 # raise GLIException("PCMCIA_CSError", 'warning', 'install_pcmcia_cs', "Could not emerge pcmcia-cs!")
731
732 # Add pcmcia-cs to the default runlevel
733 else:
734 self._add_to_runlevel('pcmcia')
735 self._logger.log("PCMCIA_CS emerged and configured.")
736
737 ##
738 # This runs etc-update and then re-overwrites the files by running the configure_*'s to keep our values.
739 def update_config_files(self):
740 "Runs etc-update (overwriting all config files), then re-configures the modified ones"
741 # Run etc-update overwriting all config files
742 status = GLIUtility.spawn('echo "-5" | chroot '+self._chroot_dir+' etc-update', display_on_tty8=True)
743 if not GLIUtility.exitsuccess(status):
744 self._logger.log("ERROR! : Could not update the config files!")
745 # raise GLIException("EtcUpdateError", 'warning', 'update_config_files', "Could not update config files!")
746 else:
747 self.configure_make_conf()
748 self.configure_fstab()
749 self.configure_rc_conf()
750 self._logger.log("Config files updated using etc-update. make.conf/fstab/rc.conf restored.")
751
752 ##
753 # Configures /etc/rc.conf
754 def configure_rc_conf(self):
755
756 # Get make.conf options
757 options = self._install_profile.get_rc_conf()
758
759 # For each configuration option...
760 for key in options.keys():
761
762 # Add/Edit it into rc.conf
763 self._edit_config(self._chroot_dir + "/etc/rc.conf", {key: options[key]})
764 self._logger.log("rc.conf configured.")
765
766 ##
767 # Sets up the network for the first boot
768 def setup_network_post(self):
769
770 # Get hostname, domainname and nisdomainname
771 hostname = self._install_profile.get_hostname()
772 domainname = self._install_profile.get_domainname()
773 nisdomainname = self._install_profile.get_nisdomainname()
774
775 # Write the hostname to the hostname file
776 open(self._chroot_dir + "/etc/hostname", "w").write(hostname + "\n")
777
778 # Write the domainname to the nisdomainname file
779 if domainname:
780 open(self._chroot_dir + "/etc/dnsdomainname", "w").write(domainname + "\n")
781 self._add_to_runlevel("domainname")
782
783 # Write the nisdomainname to the nisdomainname file
784 if nisdomainname:
785 open(self._chroot_dir + "/etc/nisdomainname", "w").write(nisdomainname + "\n")
786 self._add_to_runlevel("domainname")
787
788 #
789 # EDIT THE /ETC/HOSTS FILE
790 #
791
792 # The address we are editing is 127.0.0.1
793 hosts_ip = "127.0.0.1"
794
795 # If the hostname is localhost
796 if hostname == "localhost":
797 # If a domainname is set
798 if domainname:
799 hosts_line = hostname + "." + domainname + "\t" + hostname
800 else:
801 hosts_line = hostname
802 # If the hostname is not localhost
803 else:
804 # If a domainname is set
805 if domainname:
806 hosts_line = hostname + "." + domainname + "\t" + hostname + "\tlocalhost"
807 else:
808 hosts_line = "localhost\t" + hostname
809
810 # Write to file
811 self._edit_config(self._chroot_dir + "/etc/hosts", {hosts_ip: hosts_line}, delimeter='\t', quotes_around_value=False)
812
813 #
814 # SET DEFAULT GATEWAY
815 #
816
817 # Get default gateway
818 default_gateway = self._install_profile.get_default_gateway()
819
820 # If the default gateway exists, add it
821 if default_gateway:
822 default_gateway_string = default_gateway[0] + "/" + default_gateway[1]
823 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"gateway": default_gateway_string})
824
825 #
826 # SET RESOLV INFO
827 #
828
829 # Get dns servers
830 dns_servers = self._install_profile.get_dns_servers()
831
832 # Clear the list
833 resolv_output = []
834
835 # If dns servers are set
836 if dns_servers:
837
838
839 # Parse each dns server
840 for dns_server in dns_servers:
841 # Add the server to the output
842 resolv_output.append("nameserver " + dns_server +"\n")
843
844 # If the domainname is set, then also output it
845 if domainname:
846 resolv_output.append("search " + domainname + "\n")
847
848 # Output to file
849 resolve_conf = open(self._chroot_dir + "/etc/resolv.conf", "w")
850 resolve_conf.writelines(resolv_output)
851 resolve_conf.close()
852
853 #
854 # PARSE INTERFACES
855 #
856
857 # Fetch interfaces
858 interfaces = self._install_profile.get_network_interfaces()
859 emerge_dhcp = False
860 # Parse each interface
861 for interface in interfaces.keys():
862
863 # Set what kind of interface it is
864 interface_type = interface[:3]
865
866 # Check to see if there is a startup script for this interface, if there isn't link to the proper script
867 try:
868 os.stat(self._chroot_dir + "/etc/init.d/net." + interface)
869 except:
870 os.symlink(self._chroot_dir + "/etc/init.d/net." + interface_type + "0", self._chroot_dir + "/etc/init.d/net." + interface)
871
872 # If we are going to load the network at boot...
873 #if interfaces[interface][2]: #THIS FEATURE NO LONGER EXISTS
874
875 # Add it to the default runlevel
876 self._add_to_runlevel("net."+interface) # moved a bit <-- for indentation
877
878 #
879 # ETHERNET
880 #
881 if interface_type == "eth":
882
883 #
884 # STATIC IP
885 #
886 # If the post-install device info is not None, then it is a static ip addy
887 if interfaces[interface][1]:
888 ip = interfaces[interface][0]
889 broadcast = interfaces[interface][1]
890 netmask = interfaces[interface][2]
891 # aliases = interfaces[interface][1][3]
892 # alias_ips = []
893 # alias_broadcasts = []
894 # alias_netmasks = []
895
896 # Write the static ip config to /etc/conf.d/net
897 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"iface_" + interface: ip + " broadcast " + broadcast + " netmask " + netmask})
898
899 # If aliases are set
900 # if aliases:
901
902 # Parse aliases to format alias info
903 # for alias in aliases:
904 # alias_ips.append(alias[0])
905 # alias_broadcasts.append(alias[1])
906 # alias_netmasks.append(allias[2])
907
908 # Once the alias info has been gathered, then write it out
909 # Alias ips first
910 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "alias_" + interface, string.join(alias_ips))
911 # Alias broadcasts next
912 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "broadcast_" + interface, string.join(alias_broadcasts))
913 # Alias netmasks last
914 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "netmask_" + interface, string.join(alias_netmasks))
915
916 #
917 # DHCP IP
918 #
919 else:
920 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"iface_" + interface: "dhcp"})
921 emerge_dhcp = True
922 if emerge_dhcp:
923 exitstatus = self._emerge("dhcpcd")
924 if exitstatus != 0:
925 self._logger.log("ERROR! : Could not emerge dhcpcd!")
926 else:
927 self._logger.log("dhcpcd emerged.")
928
929 ##
930 # Sets the root password
931 def set_root_password(self):
932 status = GLIUtility.spawn('echo \'root:' + self._install_profile.get_root_pass_hash() + '\' | chroot '+self._chroot_dir+' chpasswd -e')
933 if not GLIUtility.exitsuccess(status):
934 raise GLIException("SetRootPasswordError", 'fatal', 'set_root_password', "Failure to set root password!")
935 self._logger.log("Root Password set on the new system.")
936
937 ##
938 # Sets up the new users for the system
939 def set_users(self):
940 # Loop for each user
941 for user in self._install_profile.get_users():
942
943 # Get values from the tuple
944 username = user[0]
945 password_hash = user[1]
946 groups = user[2]
947 shell = user[3]
948 home_dir = user[4]
949 uid = user[5]
950 comment = user[6]
951
952 options = [ "-m", "-p '" + password_hash + "'" ]
953
954 # If the groups are specified
955 if groups:
956
957 # If just one group is listed as a string, make it a list
958 if groups == str:
959 groups = [ groups ]
960
961 # If only 1 group is listed
962 if len(groups) == 1:
963 options.append("-G " + groups[0])
964
965 # If there is more than one group
966 elif len(groups) > 1:
967 options.append('-G "' + string.join(groups, ",") + '"')
968
969 # Attempt to add the group (will return success when group exists)
970 for group in groups:
971 # Add the user
972 exitstatus = GLIUtility.spawn('groupadd -f ' + group, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True, display_on_tty8=True)
973 if not GLIUtility.exitsuccess(exitstatus):
974 self._logger.log("ERROR! : Failure to add group " + group+" and it wasn't that the group already exists!")
975
976
977 # If a shell is specified
978 if shell:
979 options.append("-s " + shell)
980
981 # If a home dir is specified
982 if home_dir:
983 options.append("-d " + home_dir)
984
985 # If a UID is specified
986 if uid:
987 options.append("-u " + str(uid))
988
989 # If a comment is specified
990 if comment:
991 options.append('-c "' + comment + '"')
992
993 # Add the user
994 exitstatus = GLIUtility.spawn('useradd ' + string.join(options) + ' ' + username, chroot=self._chroot_dir, logfile=self._compile_logfile, append_log=True, display_on_tty8=True)
995 if not GLIUtility.exitsuccess(exitstatus):
996 self._logger.log("ERROR! : Failure to add user " + username)
997 # raise GLIException("AddUserError", 'warning', 'set_users', "Failure to add user " + username)
998 else:
999 self._logger.log("User "+username+"was added.")
1000
1001 ##
1002 # This function will handle the various cleanup tasks as well as unmounting the filesystems for reboot.
1003 def finishing_cleanup(self):
1004 #These are temporary until I come up with a nicer idea.
1005 #get rid of the compile_output file so the symlink doesn't get screwed up.
1006
1007 #we copy the log over to the new system.
1008 install_logfile = self._client_configuration.get_log_file()
1009 try:
1010 shutil.copy(install_logfile, self._chroot_dir + install_logfile)
1011 except:
1012 pass
1013 #Now we're done logging as far as the new system is concerned.
1014 GLIUtility.spawn("cp /tmp/installprofile.xml " + self._chroot_dir + "/root/installprofile.xml")
1015 GLIUtility.spawn("cp /tmp/clientconfiguration.xml " + self._chroot_dir + "/root/clientconfiguration.xml")
1016
1017 #Unmount mounted fileystems in preparation for reboot
1018 mounts = GLIUtility.spawn(r"mount | sed -e 's:^.\+ on \(.\+\) type .\+$:\1:' | grep -e '^" + self._chroot_dir + "' | sort -r", return_output=True)[1].split("\n")
1019 for mount in mounts:
1020 GLIUtility.spawn("umount -l " + mount)
1021
1022 # we really should only swapoff on the correct device, but that can be for future use.
1023 GLIUtility.spawn('swapoff -a')
1024
1025 #OLD WAY: Unmount the /proc and /dev that we mounted in prepare_chroot
1026 #There really isn't a reason to log errors here.
1027 #ret = GLIUtility.spawn("umount "+self._chroot_dir+"/proc", display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
1028 #ret = GLIUtility.spawn("umount "+self._chroot_dir+"/dev", display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
1029 #temp hack to unmount the new root.
1030 #ret = GLIUtility.spawn("umount "+self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile, append_log=True)
1031 #insert code here to unmount the swap partition, if there is one.
1032
1033 GLIUtility.spawn("rm /tmp/compile_output.log && rm " + install_logfile)
1034
1035 ##
1036 # This is a stub function to be done by the individual arch. I don't think it's even needed here.
1037 # but it's nice having it just incase.
1038 def install_bootloader(self):
1039 "THIS FUNCTION MUST BE DONE BY THE INDIVIDUAL ARCH"
1040 pass
1041
1042 def run_post_install_script(self):
1043 if self._install_profile.get_post_install_script_uri():
1044 try:
1045 GLIUtility.get_uri(self._install_profile.get_post_install_script_uri(), self._chroot_dir + "/var/tmp/post-install")
1046 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)
1047 except:
1048 raise GLIException("RunPostInstallScriptError", 'fatal', 'run_post_install_script', "Failed to retrieve and/or execute post-install script")
1049
1050 ##
1051 # This function adds user-defined entries to the files in /etc/portage
1052 #
1053 def set_etc_portage(self):
1054 etc_portage = self._install_profile.get_etc_portage()
1055
1056 # Loop through the required files.
1057 for file in etc_portage:
1058 contents = enumerate(etc_portage[file])
1059 self._logger.log("Configuring /etc/portage/" + file)
1060 self._edit_config(self._chroot_dir + "/etc/portage/" + file, {"COMMENT": "GLI additions ===>"})
1061
1062 # Set up the contents hash to pass to the config writer.
1063 contents = {}
1064 for key,value in enumerate(etc_portage[file]):
1065 contents[str(key)] = string.strip(value)
1066
1067 # Write out the contents in one go.
1068 self._edit_config(self._chroot_dir + "/etc/portage/" + file, contents, "", False, True)
1069
1070 self._edit_config(self._chroot_dir + "/etc/make.conf", {"COMMENT": "<=== End GLI additions"})
1071 self._logger.log("Finished configuring /etc/portage/" + file)

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20