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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1391 - (hide annotations) (download) (as text)
Thu Mar 30 17:50:31 2006 UTC (12 years, 6 months ago) by agaffney
Original Path: trunk/src/GLIArchitectureTemplate.py
File MIME type: text/x-python
File size: 67754 byte(s)
  src/GLIArchitectureTemplate.py:
  use get_devnode() in local mount and fstab stuff

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

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20