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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 401 - (hide annotations) (download) (as text)
Thu Mar 24 03:12:24 2005 UTC (13 years, 4 months ago) by agaffney
Original Path: trunk/src/GLIArchitectureTemplate.py
File MIME type: text/x-python
File size: 35681 byte(s)
lots of stuff in both FEs and backend...read the ChangeLogs :P

1 samyron 79 """
2     Gentoo Linux Installer
3    
4 agaffney 401 $Id: GLIArchitectureTemplate.py,v 1.60 2005/03/24 03:12:24 agaffney Exp $
5 samyron 79 Copyright 2004 Gentoo Technologies Inc.
6    
7    
8     The ArchitectureTemplate is largely meant to be an abstract class and an
9     interface (yes, it is both at the same time!). The purpose of this is to create
10     subclasses that populate all the methods with working methods for that architecture.
11     The only definitions that are filled in here are architecture independent.
12    
13     """
14    
15 codeman 341 import GLIUtility, GLILogger, os, string, sys, shutil, re
16 agaffney 126 from GLIException import *
17 samyron 79
18     class ArchitectureTemplate:
19 agaffney 108 def __init__(self,configuration=None, install_profile=None, client_controller=None):
20 codeman 200 self._client_configuration = configuration
21 samyron 79 self._install_profile = install_profile
22 agaffney 108 self._cc = client_controller
23 samyron 79
24 samyron 102 # This will get used a lot, so it's probably
25     # better to store it in a variable than to call
26     # this method 100000 times.
27 codeman 200 self._chroot_dir = self._client_configuration.get_root_mount_point()
28 codeman 314 self._logger = GLILogger.Logger(self._client_configuration.get_log_file())
29 agaffney 384 self._compile_logfile = "/tmp/compile_output.log"
30 samyron 102
31 samyron 79 # These must be filled in by the subclass. _steps is a list of
32     # functions, that will carry out the installation. They must be
33     # in order.
34     #
35     # For example, self._steps might be: [preinstall, stage1, stage2, stage3, postinstall],
36     # where each entry is a function (with no arguments) that carries out the desired actions.
37     # Of course, steps will be different depending on the install_profile
38    
39     self._architecture_name = "generic"
40 agaffney 136 self._install_steps = [
41 agaffney 266 (self.partition, "Partition"),
42 agaffney 136 (self.mount_local_partitions, "Mount local partitions"),
43     (self.mount_network_shares, "Mount network (NFS) shares"),
44     (self.unpack_stage_tarball, "Unpack stage tarball"),
45     (self.configure_make_conf, "Configure /etc/make.conf"),
46 codeman 345 (self.prepare_chroot, "Preparing chroot"),
47 codeman 248 (self.install_portage_tree, "Portage tree voodoo"),
48 agaffney 136 (self.stage1, "Performing bootstrap"),
49     (self.stage2, "Performing 'emerge system'"),
50 codeman 248 (self.set_root_password, "Set the root password"),
51     (self.set_timezone, "Setting timezone"),
52 agaffney 136 (self.emerge_kernel_sources, "Emerge kernel sources"),
53     (self.build_kernel, "Building kernel"),
54     (self.install_logging_daemon, "Logger"),
55     (self.install_cron_daemon, "Cron daemon"),
56     (self.install_filesystem_tools, "Installing filesystem tools"),
57     (self.setup_network_post, "Configuring post-install networking"),
58     (self.install_bootloader, "Configuring and installing bootloader"),
59     (self.update_config_files, "Updating config files"),
60 codeman 223 (self.configure_rc_conf, "Updating /etc/rc.conf"),
61 codeman 361 (self.set_services, "Setting up services for startup"),
62 codeman 223 (self.set_users, "Add additional users.")
63 agaffney 136 ]
64 codeman 200
65 samyron 79
66 agaffney 136 def get_install_steps(self):
67     return self._install_steps
68    
69 codeman 201 def notify_frontend(self, type, data):
70     self._cc.addNotification(type, data)
71    
72 samyron 79 # It is possible to override these methods in each Arch Template.
73     # It might be necessary to do so, if the arch needs something 'weird'.
74    
75 codeman 201 def _add_to_runlevel(self, script_name, runlevel="default"):
76     "Adds the script named 'script_name' to the runlevel 'runlevel' in the chroot environement"
77    
78     # Do it
79 agaffney 391 status = GLIUtility.spawn("rc-update add " + script_name + " " + runlevel, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile)
80 codeman 216 if not GLIUtility.exitsuccess(status):
81 codeman 314 raise GLIException("RunlevelAddError", 'fatal', '_add_to_runlevel', "Failure adding " + script_name + " to runlevel " + runlevel + "!")
82     self._logger.log("Added "+script_name+" to runlevel "+runlevel)
83 codeman 201
84 agaffney 322 def _quickpkg_deps(self, package):
85 agaffney 385 # These need to be changed to pull values from the make.conf stuff
86 agaffney 322 PKGDIR = "/usr/portage/packages"
87     PORTAGE_TMPDIR = "/var/tmp"
88 agaffney 324 packages = [word for word in GLIUtility.spawn("emerge -p " + package, chroot=self._chroot_dir, return_output=True)[1].split() if "/" in word]
89     for pkg in packages:
90 agaffney 322 if not GLIUtility.is_file(self._chroot_dir + PKGDIR + "/All/" + pkg.split('/')[1] + ".tbz2"):
91 agaffney 401 ret = GLIUtility.spawn("env PKGDIR=" + self._chroot_dir + PKGDIR + " PORTAGE_TMPDIR=" + self._chroot_dir + PORTAGE_TMPDIR + " quickpkg =" + pkg)
92 agaffney 322 if ret:
93     # This package couldn't be quickpkg'd. This may be an error in the future
94     pass
95    
96 agaffney 385 def _get_packages_to_emerge(self, cmd):
97     # cmd = full command to run ('/usr/portage/scripts/bootstrap.sh --pretend' or 'emerge -p system')
98     return GLIUtility.spawn(cmd + r" | grep -e '\[ebuild' | sed -e 's:\[ebuild .\+ \] ::' -e 's: \[.\+\] ::' -e 's: +$::'", chroot=self._chroot_dir, return_output=True).split("\n")
99    
100 codeman 209 def _emerge(self, package, binary=False, binary_only=False):
101 codeman 314 #Error checking of this function is to be handled by the parent function.
102 agaffney 322 if self._install_profile.get_grp_install():
103     self._quickpkg_deps(package)
104 agaffney 391 return GLIUtility.spawn("emerge -k " + package, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile)
105 codeman 201 else:
106 agaffney 322 if binary_only:
107 agaffney 391 return GLIUtility.spawn("emerge -K " + package, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile)
108 agaffney 322 elif binary:
109 agaffney 391 return GLIUtility.spawn("emerge -k " + package, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile)
110 agaffney 322 else:
111 agaffney 391 return GLIUtility.spawn("emerge " + package, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile)
112 codeman 201
113 codeman 209 def _edit_config(self, filename, newvalues, delimeter='=', quotes_around_value=True):
114 codeman 201 """
115     filename = file to be editted
116     newvlaues = a dictionary of VARIABLE:VALUE pairs
117     """
118 codeman 209 if not GLIUtility.is_file(filename):
119     raise GLIException("NoSuchFileError", 'notice','_edit_config',filename + ' does not exist!')
120 codeman 201
121     f = open(filename)
122     file = f.readlines()
123     f.close()
124    
125     for key in newvalues.keys():
126     regexpr = '^\s*#?\s*' + key + '\s*' + delimeter + '.*$'
127     regexpr = re.compile(regexpr)
128    
129     for i in range(0, len(file)):
130     if regexpr.match(file[i]):
131     if not file[i][0] == '#':
132     file[i] = '#' + file[i]
133    
134     file.append('\n# Added by GLI\n')
135     if quotes_around_value:
136     file.append(key + delimeter + '"' + newvalues[key] + '"\n')
137     else:
138     file.append(key + delimeter + newvalues[key]+'\n')
139    
140     f = open(filename,'w')
141     f.writelines(file)
142     f.flush()
143     f.close()
144 codeman 314 self._logger.log("Edited Config file "+filename)
145 codeman 201
146 samyron 79 def stage1(self):
147     "Stage 1 install -- bootstraping"
148    
149     # If we are doing a stage 1 install, then bootstrap
150     if self._install_profile.get_install_stage() == 1:
151 codeman 314 self._logger.mark()
152     self._logger.log("Starting bootstrap.")
153 agaffney 385 pkgs = self._get_packages_to_emerge("/usr/portage/scripts/bootstrap.sh --pretend")
154 agaffney 391 exitstatus = GLIUtility.spawn("/usr/portage/scripts/bootstrap.sh", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile)
155 samyron 79 if not GLIUtility.exitsuccess(exitstatus):
156 samyron 186 raise GLIException("Stage1Error", 'fatal','stage1', "Bootstrapping failed!")
157 codeman 314 self._logger.log("Bootstrap complete.")
158 agaffney 385
159 samyron 79 def stage2(self):
160     # If we are doing a stage 1 or 2 install, then emerge system
161     if self._install_profile.get_install_stage() in [ 1, 2 ]:
162 codeman 314 self._logger.mark()
163     self._logger.log("Starting emerge system.")
164 agaffney 385 pkgs = self._get_packages_to_emerge("emerge -p system")
165 codeman 201 exitstatus = self._emerge("system")
166 samyron 79 if not GLIUtility.exitsuccess(exitstatus):
167 samyron 186 raise GLIException("Stage2Error", 'fatal','stage2', "Building the system failed!")
168 codeman 314 self._logger.log("Emerge system complete.")
169 agaffney 384
170 agaffney 133 def unpack_stage_tarball(self):
171     if not os.path.isdir(self._chroot_dir):
172     os.makedirs(self._chroot_dir)
173 codeman 215 GLIUtility.fetch_and_unpack_tarball(self._install_profile.get_stage_tarball_uri(), self._chroot_dir, temp_directory=self._chroot_dir, keep_permissions=True)
174 codeman 314 self._logger.log(self._install_profile.get_stage_tarball_uri()+" was unpacked.")
175 agaffney 384
176 agaffney 133 def prepare_chroot(self):
177 codeman 215 # Copy resolv.conf to new env
178     try:
179     shutil.copy("/etc/resolv.conf", self._chroot_dir + "/etc/resolv.conf")
180     except:
181     pass
182     ret = GLIUtility.spawn("mount -t proc none "+self._chroot_dir+"/proc")
183 samyron 79 if not GLIUtility.exitsuccess(ret):
184 codeman 215 raise GLIException("MountError", 'fatal','prepare_chroot','Could not mount /proc')
185 codeman 216 ret = GLIUtility.spawn("mount -o bind /dev " + self._chroot_dir + "/dev")
186     if not GLIUtility.exitsuccess(ret):
187     raise GLIException("MountError", 'fatal','prepare_chroot','Could not mount /dev')
188 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)
189 codeman 314 self._logger.log("Chroot environment ready.")
190 samyron 79 # Set USE flags here
191     # might want to rewrite/use _edit_config from the GLIInstallTemplate
192     # Then you should be done... at least with the preinstall.
193    
194 samyron 102 def install_packages(self):
195     "Will install any extra software!"
196 codeman 201
197 samyron 102 installpackages = self._install_profile.get_install_packages()
198     for package in installpackages:
199 codeman 201 status = self._emerge(package)
200     if not GLIUtility.exitsuccess(status):
201 codeman 318 self._logger.log("Could not emerge " + package + "!")
202     # raise GLIException("InstallPackagesError", 'warning', 'install_packages', "Could not emerge " + package + "!")
203     else:
204     self._logger.log("Emerged package: "+package)
205 samyron 102
206 codeman 361 def set_services(self):
207     "Will set the list of services to runlevel default. This is a temporary solution!"
208    
209     services = self._install_profile.get_services()
210     for service in services:
211     status = self._add_to_runlevel(service)
212     if not GLIUtility.exitsuccess(status):
213     self._logger.log("Could not add " + package + "to startup!")
214     # raise GLIException("InstallPackagesError", 'warning', 'install_packages', "Could not emerge " + package + "!")
215    
216 samyron 102
217     def mount_local_partitions(self):
218     "Mounts all partitions that are on the local machine"
219 codeman 213 #{ 1: { 'end': 1999871, 'format': False, 'mb': 0,
220     #'mountopts': '', 'mountpoint': '', 'start': 63, 'type': 'linux-swap'},
221     #2: { 'end': 240121727, 'format': False, 'mb': 0, 'mountopts': '',
222     #'mountpoint': '', 'start': 1999872, 'type': 'ext3'}}
223 codeman 216
224 codeman 213 parts = self._install_profile.get_partition_tables()
225 codeman 215 parts_to_mount = {}
226 codeman 213 for device in parts:
227     #in parts['/dev/hda']
228     for partition in parts[device]:
229 codeman 214 #print parts[device][partition]
230 codeman 213 mountpoint = parts[device][partition]['mountpoint']
231     mountopts = parts[device][partition]['mountopts']
232     minor = str(parts[device][partition]['minor'])
233     partition_type = parts[device][partition]['type']
234     if mountpoint:
235     if mountopts:
236     mountopts = "-o "+mountopts+" "
237     if partition_type:
238     partition_type = "-t "+partition_type+" "
239 codeman 215 parts_to_mount[mountpoint]= {0: mountopts, 1: partition_type, 2: minor}
240    
241 codeman 213 if partition_type == "linux-swap":
242     ret = GLIUtility.spawn("swapon "+device+minor)
243 agaffney 272 if not GLIUtility.exitsuccess(ret):
244 codeman 318 self._logger.log("ERROR! : Could not activate swap!")
245 codeman 314 # raise GLIException("MountError", 'warning','mount_local_partitions','Could not activate swap')
246 codeman 215 sorted_list = []
247     for key in parts_to_mount.keys(): sorted_list.append(key)
248     sorted_list.sort()
249    
250     for mountpoint in sorted_list:
251     mountopts = parts_to_mount[mountpoint][0]
252     partition_type = parts_to_mount[mountpoint][1]
253     minor = parts_to_mount[mountpoint][2]
254     if not GLIUtility.is_file(self._chroot_dir+mountpoint):
255     exitstatus = GLIUtility.spawn("mkdir -p " + self._chroot_dir + mountpoint)
256     if exitstatus != 0:
257     raise GLIException("MkdirError", 'fatal','mount_local_partitions', "Making the mount point failed!")
258 agaffney 391 ret = GLIUtility.spawn("mount "+partition_type+mountopts+device+minor+" "+self._chroot_dir+mountpoint, display_on_tty8=True, logfile=self._compile_logfile)
259 codeman 215 if not GLIUtility.exitsuccess(ret):
260 codeman 314 raise GLIException("MountError", 'fatal','mount_local_partitions','Could not mount a partition')
261     self._logger.log("Mounted mountpoint:"+mountpoint)
262 samyron 102 def mount_network_shares(self):
263     "Mounts all network shares to the local machine"
264 codeman 226 """
265     <agaffney> it'll be much easier than mount_local_partitions
266 codeman 248 <agaffney> make sure /etc/init.d/portmap is started
267     <agaffney> then mount each one: mount -t nfs -o <mountopts> <host>:<export> <mountpoint>
268 codeman 226 """
269     nfsmounts = self._install_profile.get_network_mounts()
270     for netmount in nfsmounts:
271 agaffney 266 if netmount['type'] == "NFS" or netmount['type'] == "nfs":
272     mountopts = netmount['mountopts']
273 codeman 226 if mountopts:
274     mountopts = "-o "+mountopts
275 agaffney 266 host = netmount['host']
276     export = netmount['export']
277     mountpoint = netmount['mountpoint']
278 codeman 226 if not GLIUtility.is_file(self._chroot_dir+mountpoint):
279     exitstatus = GLIUtility.spawn("mkdir -p " + self._chroot_dir + mountpoint)
280     if exitstatus != 0:
281     raise GLIException("MkdirError", 'fatal','mount_network_shares', "Making the mount point failed!")
282 agaffney 391 ret = GLIUtility.spawn("mount -t nfs "+mountopts+" "+host+":"+export+" "+self._chroot_dir+mountpoint, display_on_tty8=True, logfile=self._compile_logfile)
283 codeman 226 if not GLIUtility.exitsuccess(ret):
284 codeman 314 raise GLIException("MountError", 'fatal','mount_network_shares','Could not mount an NFS partition')
285     self._logger.log("Mounted netmount at mountpoint:"+mountpoint)
286    
287 samyron 102 def fetch_sources_from_cd(self):
288     "Gets sources from CD (required for non-network installation)"
289 codeman 314 #WARNING: There will no longer be sources on the future livecds. this will have to change!
290 codeman 216 if not GLIUtility.is_file(self._chroot_dir+"/usr/portage/distfiles"):
291     exitstatus = GLIUtility.spawn("mkdir -p /usr/portage/distfiles",chroot=self._chroot_dir)
292     if exitstatus != 0:
293     raise GLIException("MkdirError", 'fatal','install_portage_tree',"Making the distfiles directory failed.")
294 agaffney 391 exitstatus = GLIUtility.spawn("cp /mnt/cdrom/distfiles/* "+self._chroot_dir+"/usr/portage/distfiles/", display_on_tty8=True, logfile=self._compile_logfile)
295 codeman 216 if exitstatus != 0:
296     raise GLIException("PortageError", 'fatal','install_portage_tree',"Failed to copy the distfiles to the new system")
297 codeman 314 self._logger.log("Distfiles copied from cd.")
298    
299 samyron 102 def fetch_grp_from_cd(self):
300     "Gets grp binary packages from CD (required for non-network binary installation)"
301 codeman 282 # This will not work until we find out how the new GRP format will function.
302 codeman 204 pass
303 codeman 201
304 samyron 102 def configure_make_conf(self):
305     "Configures make.conf"
306 codeman 201
307 samyron 102 # Get make.conf options
308     options = self._install_profile.get_make_conf()
309    
310     # For each configuration option...
311     for key in options.keys():
312    
313     # Add/Edit it into make.conf
314 codeman 222 self._edit_config(self._chroot_dir + "/etc/make.conf", {key: options[key]})
315 codeman 314 self._logger.log("Make.conf configured")
316 samyron 102
317     def install_portage_tree(self):
318     "Get/update the portage tree"
319    
320     # Check the type of portage tree fetching we'll do
321     # If it is custom, follow the path to the custom tarball and unpack it
322     if self._install_profile.get_portage_tree_sync_type() == "custom":
323    
324     # Get portage tree info
325     portage_tree_snapshot_uri = self._install_profile.get_portage_tree_snapshot_uri()
326 codeman 216 if portage_tree_snapshot_uri:
327     # Fetch and unpack the tarball
328     GLIUtility.fetch_and_unpack_tarball(portage_tree_snapshot_uri, self._chroot_dir + "/usr/", self._chroot_dir + "/")
329     # FIXME TEMPORARY FIX FOR NON-GRP SETTING
330     self.fetch_sources_from_cd()
331 codeman 314 self._logger.log("Portage tree install was custom.")
332 samyron 102 # If the type is webrsync, then run emerge-webrsync
333     elif self._install_profile.get_portage_tree_sync_type() == "webrsync":
334 agaffney 391 exitstatus = GLIUtility.spawn("emerge-webrsync", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile)
335 samyron 102 if exitstatus != 0:
336 samyron 186 raise GLIException("EmergeWebRsyncError", 'fatal','install_portage_tre', "Failed to retrieve portage tree!")
337 codeman 314 self._logger.log("Portage tree sync'd using webrsync")
338 samyron 102 # Otherwise, just run emerge sync
339     else:
340     exitstatus = self._emerge("sync")
341     if exitstatus != 0:
342 samyron 186 raise GLIException("EmergeSyncError", 'fatal','install_portage_tree', "Failed to retrieve portage tree!")
343 codeman 314 self._logger.log("Portage tree sync'd")
344    
345 samyron 102 def set_timezone(self):
346     "Sets the timezone for the new environment"
347     # Set symlink
348 codeman 201 if not os.access(self._chroot_dir + "/etc/localtime", os.W_OK):
349     os.symlink(self._chroot_dir + "/usr/share/zoneinfo/" + self._install_profile.get_time_zone(), self._chroot_dir + "/etc/localtime")
350 samyron 102 if not (self._install_profile.get_time_zone() == "UTC"):
351 codeman 216 self._edit_config(self._chroot_dir + "/etc/rc.conf", {"CLOCK":"local"})
352 codeman 314 self._logger.log("Timezone set.")
353 samyron 102
354     def configure_fstab(self):
355     "Configures fstab"
356     newfstab = ""
357 codeman 216 #partitions = self._install_profile.get_fstab()
358     parts = self._install_profile.get_partition_tables()
359     for device in parts:
360     #in parts['/dev/hda']
361     for partition in parts[device]:
362     #print parts[device][partition]
363     mountpoint = parts[device][partition]['mountpoint']
364     minor = str(parts[device][partition]['minor'])
365     partition_type = parts[device][partition]['type']
366     mountopts = parts[device][partition]['mountopts']
367     if mountpoint:
368     if not GLIUtility.is_file(self._chroot_dir+mountpoint):
369 codeman 217 exitstatus = GLIUtility.spawn("mkdir -p " + self._chroot_dir + mountpoint)
370     if exitstatus != 0:
371     raise GLIException("MkdirError", 'fatal','configure_fstab', "Making the mount point failed!")
372 codeman 216 newfstab += device+minor+"\t "+mountpoint+"\t "+partition_type+"\t "+mountopts+"\t\t "
373     if mountpoint == "/boot":
374     newfstab += "1 2\n"
375     elif mountpoint == "/":
376     newfstab += "0 1\n"
377     else:
378     newfstab += "0 0\n"
379     if partition_type == "linux-swap":
380     newfstab += device+minor+"\t none swap sw 0 0\n"
381 samyron 102 newfstab += "none /proc proc defaults 0 0\n"
382     newfstab += "none /dev/shm tmpfs defaults 0 0\n"
383     if GLIUtility.is_device("/dev/cdroms/cdrom0"):
384     newfstab += "/dev/cdroms/cdrom0 /mnt/cdrom auto noauto,user 0 0\n"
385 agaffney 161
386     for netmount in self._install_profile.get_network_mounts():
387     if netmount['type'] == "nfs":
388     newfstab += netmount['host'] + ":" + netmount['export'] + "\t" + netmount['mountpoint'] + "\tnfs\t" + netmount['mountopts'] + "\t0 0\n"
389 samyron 102
390 codeman 201 file_name = self._chroot_dir + "/etc/fstab"
391 samyron 102 try:
392     shutil.move(file_name, file_name + ".OLDdefault")
393     except:
394     pass
395     f = open(file_name, 'w')
396     f.writelines(newfstab)
397     f.close()
398 codeman 314 self._logger.log("fstab configured.")
399 samyron 102
400     def emerge_kernel_sources(self):
401     "Fetches desired kernel sources"
402 codeman 314 kernel_pkg = self._install_profile.get_kernel_source_pkg()
403 agaffney 401 # if kernel_pkg:
404     if kernel_pkg == "livecd-kernel":
405     PKGDIR = "/usr/portage/packages"
406     PORTAGE_TMPDIR = "/var/tmp/portage"
407     PATH = os.path.abspath(sys.argv[0])
408     ret = GLIUtility.spawn(PATH + '../../misc/mkvardb -p livecd-kernel -c sys-kernel -v 0.1 /boot/kernel-$(uname -r) /boot/initrd-$(uname -r) $(for i in $(find "/lib/modules/$(uname -r)" -type f); do grep --quiet "${i}" /var/db/pkg/*/*/CONTENTS || echo ${i}; done)')
409     ret = GLIUtility.spawn("env PKGDIR=" + self._chroot_dir + PKGDIR + " PORTAGE_TMPDIR=" + self._chroot_dir + PORTAGE_TMPDIR + " quickpkg livecd-kernel")
410     GLIUtility.spawn("emerge -K livecd-kernel", chroot=self._chroot_dir)
411     else:
412 codeman 314 exitstatus = self._emerge(kernel_pkg)
413     if exitstatus != 0:
414     raise GLIException("EmergeKernelSourcesError", 'fatal','emerge_kernel_sources',"Could not retrieve kernel sources!")
415     try:
416     os.stat(self._chroot_dir + "/usr/src/linux")
417     except:
418     kernels = os.listdir(self._chroot_dir+"/usr/src")
419     found_a_kernel = False
420     counter = 0
421     while not found_a_kernel:
422     if kernels[counter][0:6]=="linux-":
423     exitstatus = GLIUtility.spawn("ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux",chroot=self._chroot_dir)
424     if exitstatus != 0:
425     raise GLIException("EmergeKernelSourcesError", 'fatal','emerge_kernel_sources',"Could not make a /usr/src/linux symlink")
426     found_a_kernel = True
427     else:
428     counter = counter + 1
429     self._logger.log("Kernel sources:"+kernel_pkg+" emerged and /usr/src/linux symlinked.")
430 samyron 102
431     def build_kernel(self):
432     "Builds kernel"
433 codeman 314 self._logger.mark()
434     self._logger.log("Starting build_kernel")
435 agaffney 401 # No building necessary if using the LiveCD's kernel/initrd
436     if self._install_profile.get_kernel_source_pkg() == "livecd-kernel": return
437 samyron 102 # Get the uri to the kernel config
438     kernel_config_uri = self._install_profile.get_kernel_config_uri()
439 codeman 282 if kernel_config_uri == "": #use genkernel if no specific config
440 samyron 102
441 codeman 282 exitstatus = self._emerge("genkernel")
442     if exitstatus != 0:
443 codeman 314 raise GLIException("EmergeGenKernelError", 'fatal','build_kernel', "Could not emerge genkernel!")
444     self._logger.log("Genkernel emerged. Beginning kernel compile.")
445 codeman 282 # Null the genkernel_options
446     genkernel_options = ""
447    
448     # If the uri for the kernel config is not null, then
449     if kernel_config_uri != "":
450     GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/root/kernel_config")
451     genkernel_options = genkernel_options + " --kernel-config=/root/kernel_config"
452    
453     # Decide whether to use bootsplash or not
454     if self._install_profile.get_kernel_bootsplash():
455     genkernel_options = genkernel_options + " --bootsplash"
456     else:
457     genkernel_options = genkernel_options + " --no-bootsplash"
458     # Run genkernel in chroot
459     print "genkernel all " + genkernel_options
460 agaffney 391 exitstatus = GLIUtility.spawn("genkernel all " + genkernel_options, chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile)
461 codeman 282 if exitstatus != 0:
462     raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build kernel!")
463 codeman 395
464     exitstatus = self._emerge("hotplug")
465     if exitstatus != 0:
466     raise GLIException("EmergeHotplugError", 'fatal','build_kernel', "Could not emerge hotplug!")
467     self._logger.log("Hotplug emerged.")
468     exitstatus = self._emerge("coldplug")
469     if exitstatus != 0:
470     raise GLIException("EmergeColdplugError", 'fatal','build_kernel', "Could not emerge coldplug!")
471     self._logger.log("Coldplug emerged. Now they should be added to the default runlevel.")
472    
473 codeman 361 self._add_to_runlevel("hotplug")
474     self._add_to_runlevel("coldplug", runlevel="boot")
475 codeman 314 self._logger.log("Genkernel complete.")
476 codeman 282 else: #CUSTOM CONFIG
477     #Copy the kernel .config to the proper location in /usr/src/linux
478     try:
479 codeman 287 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/root/kernel_config")
480 codeman 282 except:
481     raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not copy kernel config!")
482 samyron 102
483 codeman 287 kernel_compile_script = "#!/bin/bash\n"
484     kernel_compile_script += "cp /root/kernel_config /usr/src/linux/.config\n"
485     kernel_compile_script += "cd /usr/src/linux\n"
486     kernel_compile_script += "make \nmake modules_install \n"
487    
488     #Ok now that it's built, copy it to /boot/kernel-* for bootloader code to find it
489     if self._client_configuration.get_architecture_template() == "x86":
490     kernel_compile_script += "cp /usr/src/linux/arch/i386/boot/bzImage /boot/kernel-custom\n"
491     f = open(self._chroot_dir+"/root/kernel_script", 'w')
492     f.writelines(kernel_compile_script)
493     f.close()
494 codeman 282 #Build the kernel
495 codeman 314 exitstatus1 = GLIUtility.spawn("chmod u+x "+self._chroot_dir+"/root/kernel_script")
496 agaffney 391 exitstatus2 = GLIUtility.spawn("/root/kernel_script", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile)
497 codeman 314 if (exitstatus1 != 0) or (exitstatus2 != 0):
498 codeman 282 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build custom kernel!")
499 codeman 287
500 codeman 282 #i'm sure i'm forgetting something here.
501 codeman 288 #cleanup
502     exitstatus = GLIUtility.spawn("rm "+self._chroot_dir+"/root/kernel_script")
503     #it's not important if this fails.
504 codeman 314 self._logger.log("Custom kernel complete")
505    
506 samyron 102 def install_logging_daemon(self):
507     "Installs and sets up logger"
508     # Get loggin daemon info
509     logging_daemon_pkg = self._install_profile.get_logging_daemon_pkg()
510     if logging_daemon_pkg:
511     # Emerge Logging Daemon
512     exitstatus = self._emerge(logging_daemon_pkg)
513     if exitstatus != 0:
514 codeman 318 raise GLIException("LoggingDaemonError", 'fatal','install_logging_daemon', "Could not emerge " + logging_daemon_pkg + "!")
515 samyron 102
516     # Add Logging Daemon to default runlevel
517     self._add_to_runlevel(logging_daemon_pkg)
518 codeman 314 self._logger.log("Logging daemon installed: "+logging_daemon_pkg)
519 samyron 102 def install_cron_daemon(self):
520     "Installs and sets up cron"
521     # Get cron daemon info
522     cron_daemon_pkg = self._install_profile.get_cron_daemon_pkg()
523     if cron_daemon_pkg:
524     # Emerge Cron Daemon
525     exitstatus = self._emerge(cron_daemon_pkg)
526     if exitstatus != 0:
527 codeman 318 raise GLIException("CronDaemonError", 'fatal', 'install_cron_daemon', "Could not emerge " + cron_daemon_pkg + "!")
528 samyron 102
529     # Add Cron Daemon to default runlevel
530     self._add_to_runlevel(cron_daemon_pkg)
531    
532     # If the Cron Daemon is not vixie-cron, run crontab
533     if cron_daemon_pkg != "vixie-cron":
534 codeman 345 exitstatus = GLIUtility.spawn("crontab /etc/crontab", chroot=self._chroot_dir, display_on_tty8=True)
535 samyron 102 if exitstatus != 0:
536 codeman 318 raise GLIException("CronDaemonError", 'fatal', 'install_cron_daemon', "Failure making crontab!")
537 codeman 314 self._logger.log("Cron daemon installed and configured: "+cron_daemon_pkg)
538 samyron 102 def install_filesystem_tools(self):
539     "Installs and sets up fstools"
540     # Get the list of file system tools to be installed
541     filesystem_tools = self._install_profile.get_filesystem_tools_pkgs()
542    
543     # If the fstools var is a str, convert it to a list
544     if type(filesystem_tools) == str:
545     filesystem_tools = [ filesystem_tools ]
546    
547     # For each fstool package in the list, install it
548     for package in filesystem_tools:
549     exitstatus = self._emerge(package)
550     if exitstatus != 0:
551 codeman 318 self._logger.log("ERROR! : Could not emerge " + package + "!")
552     # raise GLIException("FilesystemToolsError", 'warning', 'install_filesystem_tools', "Could not emerge " + package + "!")
553     else:
554     self._logger.log("FileSystemTool "+package+" was emerged successfully.")
555 samyron 102
556     def install_rp_pppoe(self):
557     "Installs rp-pppoe"
558     # If user wants us to install rp-pppoe, then do so
559     if self._install_profile.get_install_rp_pppoe():
560     exitstatus = self._emerge("rp-pppoe")
561     if exitstatus != 0:
562 codeman 318 self._logger.log("ERROR! : Could not emerge rp-pppoe!")
563     # raise GLIException("RP_PPPOEError", 'warning', 'install_rp_pppoe', "Could not emerge rp-pppoe!")
564     else:
565     self._logger.log("rp-pppoe emerged but not set up.")
566 samyron 102 # Should we add a section here to automatically configure rp-pppoe?
567     # I think it should go into the setup_network_post section
568     # What do you guys think?
569    
570     def install_pcmcia_cs(self):
571     "Installs and sets up pcmcia-cs"
572     # If user wants us to install pcmcia-cs, then do so
573     if self._install_profile.get_install_pcmcia_cs():
574     exitstatus = self._emerge("pcmcia-cs")
575     if exitstatus != 0:
576 codeman 318 self._logger.log("ERROR! : Could not emerge pcmcia-cs!")
577     # raise GLIException("PCMCIA_CSError", 'warning', 'install_pcmcia_cs', "Could not emerge pcmcia-cs!")
578 samyron 102
579     # Add pcmcia-cs to the default runlevel
580 codeman 318 else:
581     self._add_to_runlevel(pcmcia)
582     self._logger.log("PCMCIA_CS emerged and configured.")
583 samyron 102
584     def update_config_files(self):
585     "Runs etc-update (overwriting all config files), then re-configures the modified ones"
586     # Run etc-update overwriting all config files
587 codeman 345 status = GLIUtility.spawn('echo "-5" | chroot '+self._chroot_dir+' etc-update', display_on_tty8=True)
588 codeman 218 if not GLIUtility.exitsuccess(status):
589 codeman 318 self._logger.log("ERROR! : Could not update the config files!")
590     # raise GLIException("EtcUpdateError", 'warning', 'update_config_files', "Could not update config files!")
591     else:
592     self.configure_make_conf()
593     self.configure_fstab()
594     self.configure_rc_conf()
595     self._logger.log("Config files updated using etc-update. make.conf/fstab/rc.conf restored.")
596 samyron 102
597     def configure_rc_conf(self):
598     "Configures rc.conf"
599     # Get make.conf options
600     options = self._install_profile.get_rc_conf()
601    
602     # For each configuration option...
603     for key in options.keys():
604    
605     # Add/Edit it into rc.conf
606 codeman 222 self._edit_config(self._chroot_dir + "/etc/rc.conf", {key: options[key]})
607 codeman 314 self._logger.log("rc.conf configured.")
608    
609 samyron 102 def setup_network_post(self):
610     "Sets up the network for the first boot"
611     # Get hostname, domainname and nisdomainname
612     hostname = self._install_profile.get_hostname()
613     domainname = self._install_profile.get_domainname()
614     nisdomainname = self._install_profile.get_nisdomainname()
615    
616     # Write the hostname to the hostname file
617 codeman 201 open(self._chroot_dir + "/etc/hostname", "w").write(hostname + "\n")
618 samyron 102
619     # Write the domainname to the nisdomainname file
620     if domainname:
621 codeman 201 open(self._chroot_dir + "/etc/dnsdomainname", "w").write(domainname + "\n")
622 samyron 102
623     # Write the nisdomainname to the nisdomainname file
624     if nisdomainname:
625 codeman 201 open(self._chroot_dir + "/etc/nisdomainname", "w").write(nisdomainname + "\n")
626 samyron 102
627     #
628     # EDIT THE /ETC/HOSTS FILE
629     #
630    
631     # The address we are editing is 127.0.0.1
632     hosts_ip = "127.0.0.1"
633    
634     # If the hostname is localhost
635     if hostname == "localhost":
636     # If a domainname is set
637     if domainname:
638     hosts_line = hostname + "." + domainname + "\t" + hostname
639     else:
640     hosts_line = hostname
641     # If the hostname is not localhost
642     else:
643     # If a domainname is set
644     if domainname:
645     hosts_line = hostname + "." + domainname + "\t" + hostname + "\tlocalhost"
646     else:
647     hosts_line = "localhost\t" + hostname
648    
649     # Write to file
650 codeman 218 self._edit_config(self._chroot_dir + "/etc/hosts", {hosts_ip: hosts_line}, delimeter='\t', quotes_around_value=False)
651 samyron 102
652     #
653     # SET DEFAULT GATEWAY
654     #
655    
656     # Get default gateway
657     default_gateway = self._install_profile.get_default_gateway()
658    
659     # If the default gateway exists, add it
660     if default_gateway:
661 codeman 359 default_gateway_string = default_gateway[0] + "/" + default_gateway[1]
662     self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"gateway": default_gateway_string})
663 samyron 102
664     #
665     # SET RESOLV INFO
666     #
667    
668     # Get dns servers
669     dns_servers = self._install_profile.get_dns_servers()
670    
671     # Clear the list
672     resolv_output = []
673    
674     # If dns servers are set
675     if dns_servers:
676    
677    
678     # Parse each dns server
679     for dns_server in dns_servers:
680     # Add the server to the output
681     resolv_output.append("nameserver " + dns_server +"\n")
682    
683     # If the domainname is set, then also output it
684     if domainname:
685     resolv_output.append("search " + domainname + "\n")
686    
687 codeman 347 # Output to file
688     resolve_conf = open(self._chroot_dir + "/etc/resolv.conf", "w")
689     resolve_conf.writelines(resolv_output)
690     resolve_conf.close()
691 samyron 102
692     #
693     # PARSE INTERFACES
694     #
695    
696     # Fetch interfaces
697     interfaces = self._install_profile.get_network_interfaces()
698 codeman 347 emerge_dhcp = False
699 samyron 102 # Parse each interface
700     for interface in interfaces.keys():
701    
702     # If we are going to load the network at boot...
703     if interfaces[interface][2]:
704    
705     # Add it to the default runlevel
706 codeman 202 self._add_to_runlevel("net."+interface)
707 samyron 102
708     # Set what kind of interface it is
709     interface_type = interface[:3]
710    
711     # Check to see if there is a startup script for this interface, if there isn't link to the proper script
712     try:
713 codeman 201 os.stat(self._chroot_dir + "/etc/init.d/net." + interface)
714 samyron 102 except:
715 codeman 201 os.symlink(self._chroot_dir + "/etc/init.d/net." + interface_type + "0", self._chroot_dir + "/etc/init.d/net." + interface)
716 samyron 102
717     #
718     # ETHERNET
719     #
720     if interface_type == "eth":
721    
722     #
723     # STATIC IP
724     #
725     # If the post-install device info is not None, then it is a static ip addy
726     if interfaces[interface][1]:
727     ip = interfaces[interface][0]
728     broadcast = interfaces[interface][1]
729     netmask = interfaces[interface][2]
730     # aliases = interfaces[interface][1][3]
731     # alias_ips = []
732     # alias_broadcasts = []
733     # alias_netmasks = []
734    
735     # Write the static ip config to /etc/conf.d/net
736 codeman 217 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"iface_" + interface: ip + " broadcast " + broadcast + " netmask " + netmask})
737 samyron 102
738     # If aliases are set
739     # if aliases:
740    
741     # Parse aliases to format alias info
742     # for alias in aliases:
743     # alias_ips.append(alias[0])
744     # alias_broadcasts.append(alias[1])
745     # alias_netmasks.append(allias[2])
746    
747     # Once the alias info has been gathered, then write it out
748     # Alias ips first
749 codeman 201 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "alias_" + interface, string.join(alias_ips))
750 samyron 102 # Alias broadcasts next
751 codeman 201 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "broadcast_" + interface, string.join(alias_broadcasts))
752 samyron 102 # Alias netmasks last
753 codeman 201 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "netmask_" + interface, string.join(alias_netmasks))
754 samyron 102
755     #
756     # DHCP IP
757     #
758     else:
759 codeman 217 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"iface_" + interface: "dhcp"})
760 codeman 347 emerge_dhcp = True
761 codeman 319 if emerge_dhcp:
762     exitstatus = self._emerge("dhcpcd")
763     if exitstatus != 0:
764     self._logger.log("ERROR! : Could not emerge dhcpcd!")
765     else:
766     self._logger.log("dhcpcd emerged.")
767    
768 samyron 102 def set_root_password(self):
769     "Sets the root password"
770 codeman 346 status = GLIUtility.spawn('echo "root:' + self._install_profile.get_root_pass_hash() + '" | chroot '+self._chroot_dir+' chpasswd -e', quiet=True)
771 codeman 237 if not GLIUtility.exitsuccess(status):
772 codeman 318 raise GLIException("SetRootPasswordError", 'fatal', 'set_root_password', "Failure to set root password!")
773 codeman 314 self._logger.log("Root Password set on the new system.")
774    
775 samyron 102 def set_users(self):
776     "Sets up the new users for the system"
777     # Loop for each user
778     for user in self._install_profile.get_users():
779    
780     # Get values from the tuple
781     username = user[0]
782     password_hash = user[1]
783     groups = user[2]
784     shell = user[3]
785     home_dir = user[4]
786     uid = user[5]
787     comment = user[6]
788    
789     options = [ "-m", "-p " + password_hash ]
790    
791     # If the groups are specified
792     if groups:
793    
794     # If just one group is listed as a string, make it a list
795     if groups == str:
796     groups = [ groups ]
797    
798     # If only 1 group is listed
799     if len(groups) == 1:
800     options.append("-G " + groups[0])
801    
802     # If there is more than one group
803     elif len(groups) > 1:
804     options.append('-G "' + string.join(groups, ",") + '"')
805    
806     # If a shell is specified
807     if shell:
808     options.append("-s " + shell)
809    
810     # If a home dir is specified
811     if home_dir:
812     options.append("-d " + home_dir)
813    
814     # If a UID is specified
815     if uid:
816     options.append("-u " + str(uid))
817    
818     # If a comment is specified
819     if comment:
820     options.append('-c "' + comment + '"')
821    
822     # Add the user
823 agaffney 391 exitstatus = GLIUtility.spawn('useradd ' + string.join(options) + ' ' + username, chroot=self._chroot_dir, logfile=self._compile_logfile, display_on_tty8=True)
824 codeman 237 if not GLIUtility.exitsuccess(exitstatus):
825 codeman 318 self._logger.log("ERROR! : Failure to add user " + username)
826     # raise GLIException("AddUserError", 'warning', 'set_users', "Failure to add user " + username)
827     else:
828     self._logger.log("User "+username+"was added.")
829 codeman 314
830 codeman 213 def install_bootloader(self):
831     "THIS FUNCTION MUST BE DONE BY THE INDIVIDUAL ARCH"
832     pass

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20