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

Contents of /trunk/src/GLIArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 391 - (show annotations) (download) (as text)
Tue Mar 22 02:41:14 2005 UTC (12 years, 9 months ago) by agaffney
File MIME type: text/x-python
File size: 34450 byte(s)
added logfile parameter to spawn() calls

1 """
2 Gentoo Linux Installer
3
4 $Id: GLIArchitectureTemplate.py,v 1.58 2005/03/22 02:41:14 agaffney Exp $
5 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 import GLIUtility, GLILogger, os, string, sys, shutil, re
16 from GLIException import *
17
18 class ArchitectureTemplate:
19 def __init__(self,configuration=None, install_profile=None, client_controller=None):
20 self._client_configuration = configuration
21 self._install_profile = install_profile
22 self._cc = client_controller
23
24 # 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 self._chroot_dir = self._client_configuration.get_root_mount_point()
28 self._logger = GLILogger.Logger(self._client_configuration.get_log_file())
29 self._compile_logfile = "/tmp/compile_output.log"
30
31 # 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 self._install_steps = [
41 (self.partition, "Partition"),
42 (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 (self.prepare_chroot, "Preparing chroot"),
47 (self.install_portage_tree, "Portage tree voodoo"),
48 (self.stage1, "Performing bootstrap"),
49 (self.stage2, "Performing 'emerge system'"),
50 (self.set_root_password, "Set the root password"),
51 (self.set_timezone, "Setting timezone"),
52 (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 (self.configure_rc_conf, "Updating /etc/rc.conf"),
61 (self.set_services, "Setting up services for startup"),
62 (self.set_users, "Add additional users.")
63 ]
64
65
66 def get_install_steps(self):
67 return self._install_steps
68
69 def notify_frontend(self, type, data):
70 self._cc.addNotification(type, data)
71
72 # 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 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 status = GLIUtility.spawn("rc-update add " + script_name + " " + runlevel, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile)
80 if not GLIUtility.exitsuccess(status):
81 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
84 def _quickpkg_deps(self, package):
85 # These need to be changed to pull values from the make.conf stuff
86 PKGDIR = "/usr/portage/packages"
87 PORTAGE_TMPDIR = "/var/tmp"
88 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 if not GLIUtility.is_file(self._chroot_dir + PKGDIR + "/All/" + pkg.split('/')[1] + ".tbz2"):
91 ret = GLIUtility.spawn("env PKGDIR=" + self._chroot_dir + PKGDIR + " PORTAGE_TMPDIR=" + self._chroot_dir + PORTAGE_TMPDIR + " quickpkg =" + pkg, chroot=self._chroot_dir)
92 if ret:
93 # This package couldn't be quickpkg'd. This may be an error in the future
94 pass
95
96 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 def _emerge(self, package, binary=False, binary_only=False):
101 #Error checking of this function is to be handled by the parent function.
102 if self._install_profile.get_grp_install():
103 self._quickpkg_deps(package)
104 return GLIUtility.spawn("emerge -k " + package, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile)
105 else:
106 if binary_only:
107 return GLIUtility.spawn("emerge -K " + package, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile)
108 elif binary:
109 return GLIUtility.spawn("emerge -k " + package, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile)
110 else:
111 return GLIUtility.spawn("emerge " + package, display_on_tty8=True, chroot=self._chroot_dir, logfile=self._compile_logfile)
112
113 def _edit_config(self, filename, newvalues, delimeter='=', quotes_around_value=True):
114 """
115 filename = file to be editted
116 newvlaues = a dictionary of VARIABLE:VALUE pairs
117 """
118 if not GLIUtility.is_file(filename):
119 raise GLIException("NoSuchFileError", 'notice','_edit_config',filename + ' does not exist!')
120
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 self._logger.log("Edited Config file "+filename)
145
146 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 self._logger.mark()
152 self._logger.log("Starting bootstrap.")
153 pkgs = self._get_packages_to_emerge("/usr/portage/scripts/bootstrap.sh --pretend")
154 exitstatus = GLIUtility.spawn("/usr/portage/scripts/bootstrap.sh", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile)
155 if not GLIUtility.exitsuccess(exitstatus):
156 raise GLIException("Stage1Error", 'fatal','stage1', "Bootstrapping failed!")
157 self._logger.log("Bootstrap complete.")
158
159 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 self._logger.mark()
163 self._logger.log("Starting emerge system.")
164 pkgs = self._get_packages_to_emerge("emerge -p system")
165 exitstatus = self._emerge("system")
166 if not GLIUtility.exitsuccess(exitstatus):
167 raise GLIException("Stage2Error", 'fatal','stage2', "Building the system failed!")
168 self._logger.log("Emerge system complete.")
169
170 def unpack_stage_tarball(self):
171 if not os.path.isdir(self._chroot_dir):
172 os.makedirs(self._chroot_dir)
173 GLIUtility.fetch_and_unpack_tarball(self._install_profile.get_stage_tarball_uri(), self._chroot_dir, temp_directory=self._chroot_dir, keep_permissions=True)
174 self._logger.log(self._install_profile.get_stage_tarball_uri()+" was unpacked.")
175
176 def prepare_chroot(self):
177 # 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 if not GLIUtility.exitsuccess(ret):
184 raise GLIException("MountError", 'fatal','prepare_chroot','Could not mount /proc')
185 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 GLIUtility.spawn("mv " + self._compile_logfile + " " + self._chroot_dir + self._compile_logfile + " && ln -s " + self._chroot_dir + self._compile_logfile + " " + self._compile_logfile)
189 self._logger.log("Chroot environment ready.")
190 # 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 def install_packages(self):
195 "Will install any extra software!"
196
197 installpackages = self._install_profile.get_install_packages()
198 for package in installpackages:
199 status = self._emerge(package)
200 if not GLIUtility.exitsuccess(status):
201 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
206 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
217 def mount_local_partitions(self):
218 "Mounts all partitions that are on the local machine"
219 #{ 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
224 parts = self._install_profile.get_partition_tables()
225 parts_to_mount = {}
226 for device in parts:
227 #in parts['/dev/hda']
228 for partition in parts[device]:
229 #print parts[device][partition]
230 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 parts_to_mount[mountpoint]= {0: mountopts, 1: partition_type, 2: minor}
240
241 if partition_type == "linux-swap":
242 ret = GLIUtility.spawn("swapon "+device+minor)
243 if not GLIUtility.exitsuccess(ret):
244 self._logger.log("ERROR! : Could not activate swap!")
245 # raise GLIException("MountError", 'warning','mount_local_partitions','Could not activate swap')
246 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 ret = GLIUtility.spawn("mount "+partition_type+mountopts+device+minor+" "+self._chroot_dir+mountpoint, display_on_tty8=True, logfile=self._compile_logfile)
259 if not GLIUtility.exitsuccess(ret):
260 raise GLIException("MountError", 'fatal','mount_local_partitions','Could not mount a partition')
261 self._logger.log("Mounted mountpoint:"+mountpoint)
262 def mount_network_shares(self):
263 "Mounts all network shares to the local machine"
264 """
265 <agaffney> it'll be much easier than mount_local_partitions
266 <agaffney> make sure /etc/init.d/portmap is started
267 <agaffney> then mount each one: mount -t nfs -o <mountopts> <host>:<export> <mountpoint>
268 """
269 nfsmounts = self._install_profile.get_network_mounts()
270 for netmount in nfsmounts:
271 if netmount['type'] == "NFS" or netmount['type'] == "nfs":
272 mountopts = netmount['mountopts']
273 if mountopts:
274 mountopts = "-o "+mountopts
275 host = netmount['host']
276 export = netmount['export']
277 mountpoint = netmount['mountpoint']
278 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 ret = GLIUtility.spawn("mount -t nfs "+mountopts+" "+host+":"+export+" "+self._chroot_dir+mountpoint, display_on_tty8=True, logfile=self._compile_logfile)
283 if not GLIUtility.exitsuccess(ret):
284 raise GLIException("MountError", 'fatal','mount_network_shares','Could not mount an NFS partition')
285 self._logger.log("Mounted netmount at mountpoint:"+mountpoint)
286
287 def fetch_sources_from_cd(self):
288 "Gets sources from CD (required for non-network installation)"
289 #WARNING: There will no longer be sources on the future livecds. this will have to change!
290 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 exitstatus = GLIUtility.spawn("cp /mnt/cdrom/distfiles/* "+self._chroot_dir+"/usr/portage/distfiles/", display_on_tty8=True, logfile=self._compile_logfile)
295 if exitstatus != 0:
296 raise GLIException("PortageError", 'fatal','install_portage_tree',"Failed to copy the distfiles to the new system")
297 self._logger.log("Distfiles copied from cd.")
298
299 def fetch_grp_from_cd(self):
300 "Gets grp binary packages from CD (required for non-network binary installation)"
301 # This will not work until we find out how the new GRP format will function.
302 pass
303
304 def configure_make_conf(self):
305 "Configures make.conf"
306
307 # 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 self._edit_config(self._chroot_dir + "/etc/make.conf", {key: options[key]})
315 self._logger.log("Make.conf configured")
316
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 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 self._logger.log("Portage tree install was custom.")
332 # If the type is webrsync, then run emerge-webrsync
333 elif self._install_profile.get_portage_tree_sync_type() == "webrsync":
334 exitstatus = GLIUtility.spawn("emerge-webrsync", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile)
335 if exitstatus != 0:
336 raise GLIException("EmergeWebRsyncError", 'fatal','install_portage_tre', "Failed to retrieve portage tree!")
337 self._logger.log("Portage tree sync'd using webrsync")
338 # Otherwise, just run emerge sync
339 else:
340 exitstatus = self._emerge("sync")
341 if exitstatus != 0:
342 raise GLIException("EmergeSyncError", 'fatal','install_portage_tree', "Failed to retrieve portage tree!")
343 self._logger.log("Portage tree sync'd")
344
345 def set_timezone(self):
346 "Sets the timezone for the new environment"
347 # Set symlink
348 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 if not (self._install_profile.get_time_zone() == "UTC"):
351 self._edit_config(self._chroot_dir + "/etc/rc.conf", {"CLOCK":"local"})
352 self._logger.log("Timezone set.")
353
354 def configure_fstab(self):
355 "Configures fstab"
356 newfstab = ""
357 #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 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 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 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
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
390 file_name = self._chroot_dir + "/etc/fstab"
391 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 self._logger.log("fstab configured.")
399
400 def emerge_kernel_sources(self):
401 "Fetches desired kernel sources"
402 kernel_pkg = self._install_profile.get_kernel_source_pkg()
403 if kernel_pkg:
404 exitstatus = self._emerge(kernel_pkg)
405 if exitstatus != 0:
406 raise GLIException("EmergeKernelSourcesError", 'fatal','emerge_kernel_sources',"Could not retrieve kernel sources!")
407 try:
408 os.stat(self._chroot_dir + "/usr/src/linux")
409 except:
410 kernels = os.listdir(self._chroot_dir+"/usr/src")
411 found_a_kernel = False
412 counter = 0
413 while not found_a_kernel:
414 if kernels[counter][0:6]=="linux-":
415 exitstatus = GLIUtility.spawn("ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux",chroot=self._chroot_dir)
416 if exitstatus != 0:
417 raise GLIException("EmergeKernelSourcesError", 'fatal','emerge_kernel_sources',"Could not make a /usr/src/linux symlink")
418 found_a_kernel = True
419 else:
420 counter = counter + 1
421 self._logger.log("Kernel sources:"+kernel_pkg+" emerged and /usr/src/linux symlinked.")
422
423 def build_kernel(self):
424 "Builds kernel"
425 self._logger.mark()
426 self._logger.log("Starting build_kernel")
427 # Get the uri to the kernel config
428 kernel_config_uri = self._install_profile.get_kernel_config_uri()
429 if kernel_config_uri == "": #use genkernel if no specific config
430
431 exitstatus = self._emerge("genkernel")
432 if exitstatus != 0:
433 raise GLIException("EmergeGenKernelError", 'fatal','build_kernel', "Could not emerge genkernel!")
434 self._logger.log("Genkernel emerged. Beginning kernel compile.")
435 # Null the genkernel_options
436 genkernel_options = ""
437
438 # If the uri for the kernel config is not null, then
439 if kernel_config_uri != "":
440 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/root/kernel_config")
441 genkernel_options = genkernel_options + " --kernel-config=/root/kernel_config"
442
443 # Decide whether to use bootsplash or not
444 if self._install_profile.get_kernel_bootsplash():
445 genkernel_options = genkernel_options + " --bootsplash"
446 else:
447 genkernel_options = genkernel_options + " --no-bootsplash"
448 # Run genkernel in chroot
449 print "genkernel all " + genkernel_options
450 exitstatus = GLIUtility.spawn("genkernel all " + genkernel_options, chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile)
451 if exitstatus != 0:
452 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build kernel!")
453 self._add_to_runlevel("hotplug")
454 self._add_to_runlevel("coldplug", runlevel="boot")
455 self._logger.log("Genkernel complete.")
456 else: #CUSTOM CONFIG
457 #Copy the kernel .config to the proper location in /usr/src/linux
458 try:
459 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/root/kernel_config")
460 except:
461 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not copy kernel config!")
462
463 kernel_compile_script = "#!/bin/bash\n"
464 kernel_compile_script += "cp /root/kernel_config /usr/src/linux/.config\n"
465 kernel_compile_script += "cd /usr/src/linux\n"
466 kernel_compile_script += "make \nmake modules_install \n"
467
468 #Ok now that it's built, copy it to /boot/kernel-* for bootloader code to find it
469 if self._client_configuration.get_architecture_template() == "x86":
470 kernel_compile_script += "cp /usr/src/linux/arch/i386/boot/bzImage /boot/kernel-custom\n"
471 f = open(self._chroot_dir+"/root/kernel_script", 'w')
472 f.writelines(kernel_compile_script)
473 f.close()
474 #Build the kernel
475 exitstatus1 = GLIUtility.spawn("chmod u+x "+self._chroot_dir+"/root/kernel_script")
476 exitstatus2 = GLIUtility.spawn("/root/kernel_script", chroot=self._chroot_dir, display_on_tty8=True, logfile=self._compile_logfile)
477 if (exitstatus1 != 0) or (exitstatus2 != 0):
478 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build custom kernel!")
479
480 #i'm sure i'm forgetting something here.
481 #cleanup
482 exitstatus = GLIUtility.spawn("rm "+self._chroot_dir+"/root/kernel_script")
483 #it's not important if this fails.
484 self._logger.log("Custom kernel complete")
485
486 def install_logging_daemon(self):
487 "Installs and sets up logger"
488 # Get loggin daemon info
489 logging_daemon_pkg = self._install_profile.get_logging_daemon_pkg()
490 if logging_daemon_pkg:
491 # Emerge Logging Daemon
492 exitstatus = self._emerge(logging_daemon_pkg)
493 if exitstatus != 0:
494 raise GLIException("LoggingDaemonError", 'fatal','install_logging_daemon', "Could not emerge " + logging_daemon_pkg + "!")
495
496 # Add Logging Daemon to default runlevel
497 self._add_to_runlevel(logging_daemon_pkg)
498 self._logger.log("Logging daemon installed: "+logging_daemon_pkg)
499 def install_cron_daemon(self):
500 "Installs and sets up cron"
501 # Get cron daemon info
502 cron_daemon_pkg = self._install_profile.get_cron_daemon_pkg()
503 if cron_daemon_pkg:
504 # Emerge Cron Daemon
505 exitstatus = self._emerge(cron_daemon_pkg)
506 if exitstatus != 0:
507 raise GLIException("CronDaemonError", 'fatal', 'install_cron_daemon', "Could not emerge " + cron_daemon_pkg + "!")
508
509 # Add Cron Daemon to default runlevel
510 self._add_to_runlevel(cron_daemon_pkg)
511
512 # If the Cron Daemon is not vixie-cron, run crontab
513 if cron_daemon_pkg != "vixie-cron":
514 exitstatus = GLIUtility.spawn("crontab /etc/crontab", chroot=self._chroot_dir, display_on_tty8=True)
515 if exitstatus != 0:
516 raise GLIException("CronDaemonError", 'fatal', 'install_cron_daemon', "Failure making crontab!")
517 self._logger.log("Cron daemon installed and configured: "+cron_daemon_pkg)
518 def install_filesystem_tools(self):
519 "Installs and sets up fstools"
520 # Get the list of file system tools to be installed
521 filesystem_tools = self._install_profile.get_filesystem_tools_pkgs()
522
523 # If the fstools var is a str, convert it to a list
524 if type(filesystem_tools) == str:
525 filesystem_tools = [ filesystem_tools ]
526
527 # For each fstool package in the list, install it
528 for package in filesystem_tools:
529 exitstatus = self._emerge(package)
530 if exitstatus != 0:
531 self._logger.log("ERROR! : Could not emerge " + package + "!")
532 # raise GLIException("FilesystemToolsError", 'warning', 'install_filesystem_tools', "Could not emerge " + package + "!")
533 else:
534 self._logger.log("FileSystemTool "+package+" was emerged successfully.")
535
536 def install_rp_pppoe(self):
537 "Installs rp-pppoe"
538 # If user wants us to install rp-pppoe, then do so
539 if self._install_profile.get_install_rp_pppoe():
540 exitstatus = self._emerge("rp-pppoe")
541 if exitstatus != 0:
542 self._logger.log("ERROR! : Could not emerge rp-pppoe!")
543 # raise GLIException("RP_PPPOEError", 'warning', 'install_rp_pppoe', "Could not emerge rp-pppoe!")
544 else:
545 self._logger.log("rp-pppoe emerged but not set up.")
546 # Should we add a section here to automatically configure rp-pppoe?
547 # I think it should go into the setup_network_post section
548 # What do you guys think?
549
550 def install_pcmcia_cs(self):
551 "Installs and sets up pcmcia-cs"
552 # If user wants us to install pcmcia-cs, then do so
553 if self._install_profile.get_install_pcmcia_cs():
554 exitstatus = self._emerge("pcmcia-cs")
555 if exitstatus != 0:
556 self._logger.log("ERROR! : Could not emerge pcmcia-cs!")
557 # raise GLIException("PCMCIA_CSError", 'warning', 'install_pcmcia_cs', "Could not emerge pcmcia-cs!")
558
559 # Add pcmcia-cs to the default runlevel
560 else:
561 self._add_to_runlevel(pcmcia)
562 self._logger.log("PCMCIA_CS emerged and configured.")
563
564 def update_config_files(self):
565 "Runs etc-update (overwriting all config files), then re-configures the modified ones"
566 # Run etc-update overwriting all config files
567 status = GLIUtility.spawn('echo "-5" | chroot '+self._chroot_dir+' etc-update', display_on_tty8=True)
568 if not GLIUtility.exitsuccess(status):
569 self._logger.log("ERROR! : Could not update the config files!")
570 # raise GLIException("EtcUpdateError", 'warning', 'update_config_files', "Could not update config files!")
571 else:
572 self.configure_make_conf()
573 self.configure_fstab()
574 self.configure_rc_conf()
575 self._logger.log("Config files updated using etc-update. make.conf/fstab/rc.conf restored.")
576
577 def configure_rc_conf(self):
578 "Configures rc.conf"
579 # Get make.conf options
580 options = self._install_profile.get_rc_conf()
581
582 # For each configuration option...
583 for key in options.keys():
584
585 # Add/Edit it into rc.conf
586 self._edit_config(self._chroot_dir + "/etc/rc.conf", {key: options[key]})
587 self._logger.log("rc.conf configured.")
588
589 def setup_network_post(self):
590 "Sets up the network for the first boot"
591 # Get hostname, domainname and nisdomainname
592 hostname = self._install_profile.get_hostname()
593 domainname = self._install_profile.get_domainname()
594 nisdomainname = self._install_profile.get_nisdomainname()
595
596 # Write the hostname to the hostname file
597 open(self._chroot_dir + "/etc/hostname", "w").write(hostname + "\n")
598
599 # Write the domainname to the nisdomainname file
600 if domainname:
601 open(self._chroot_dir + "/etc/dnsdomainname", "w").write(domainname + "\n")
602
603 # Write the nisdomainname to the nisdomainname file
604 if nisdomainname:
605 open(self._chroot_dir + "/etc/nisdomainname", "w").write(nisdomainname + "\n")
606
607 #
608 # EDIT THE /ETC/HOSTS FILE
609 #
610
611 # The address we are editing is 127.0.0.1
612 hosts_ip = "127.0.0.1"
613
614 # If the hostname is localhost
615 if hostname == "localhost":
616 # If a domainname is set
617 if domainname:
618 hosts_line = hostname + "." + domainname + "\t" + hostname
619 else:
620 hosts_line = hostname
621 # If the hostname is not localhost
622 else:
623 # If a domainname is set
624 if domainname:
625 hosts_line = hostname + "." + domainname + "\t" + hostname + "\tlocalhost"
626 else:
627 hosts_line = "localhost\t" + hostname
628
629 # Write to file
630 self._edit_config(self._chroot_dir + "/etc/hosts", {hosts_ip: hosts_line}, delimeter='\t', quotes_around_value=False)
631
632 #
633 # SET DEFAULT GATEWAY
634 #
635
636 # Get default gateway
637 default_gateway = self._install_profile.get_default_gateway()
638
639 # If the default gateway exists, add it
640 if default_gateway:
641 default_gateway_string = default_gateway[0] + "/" + default_gateway[1]
642 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"gateway": default_gateway_string})
643
644 #
645 # SET RESOLV INFO
646 #
647
648 # Get dns servers
649 dns_servers = self._install_profile.get_dns_servers()
650
651 # Clear the list
652 resolv_output = []
653
654 # If dns servers are set
655 if dns_servers:
656
657
658 # Parse each dns server
659 for dns_server in dns_servers:
660 # Add the server to the output
661 resolv_output.append("nameserver " + dns_server +"\n")
662
663 # If the domainname is set, then also output it
664 if domainname:
665 resolv_output.append("search " + domainname + "\n")
666
667 # Output to file
668 resolve_conf = open(self._chroot_dir + "/etc/resolv.conf", "w")
669 resolve_conf.writelines(resolv_output)
670 resolve_conf.close()
671
672 #
673 # PARSE INTERFACES
674 #
675
676 # Fetch interfaces
677 interfaces = self._install_profile.get_network_interfaces()
678 emerge_dhcp = False
679 # Parse each interface
680 for interface in interfaces.keys():
681
682 # If we are going to load the network at boot...
683 if interfaces[interface][2]:
684
685 # Add it to the default runlevel
686 self._add_to_runlevel("net."+interface)
687
688 # Set what kind of interface it is
689 interface_type = interface[:3]
690
691 # Check to see if there is a startup script for this interface, if there isn't link to the proper script
692 try:
693 os.stat(self._chroot_dir + "/etc/init.d/net." + interface)
694 except:
695 os.symlink(self._chroot_dir + "/etc/init.d/net." + interface_type + "0", self._chroot_dir + "/etc/init.d/net." + interface)
696
697 #
698 # ETHERNET
699 #
700 if interface_type == "eth":
701
702 #
703 # STATIC IP
704 #
705 # If the post-install device info is not None, then it is a static ip addy
706 if interfaces[interface][1]:
707 ip = interfaces[interface][0]
708 broadcast = interfaces[interface][1]
709 netmask = interfaces[interface][2]
710 # aliases = interfaces[interface][1][3]
711 # alias_ips = []
712 # alias_broadcasts = []
713 # alias_netmasks = []
714
715 # Write the static ip config to /etc/conf.d/net
716 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"iface_" + interface: ip + " broadcast " + broadcast + " netmask " + netmask})
717
718 # If aliases are set
719 # if aliases:
720
721 # Parse aliases to format alias info
722 # for alias in aliases:
723 # alias_ips.append(alias[0])
724 # alias_broadcasts.append(alias[1])
725 # alias_netmasks.append(allias[2])
726
727 # Once the alias info has been gathered, then write it out
728 # Alias ips first
729 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "alias_" + interface, string.join(alias_ips))
730 # Alias broadcasts next
731 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "broadcast_" + interface, string.join(alias_broadcasts))
732 # Alias netmasks last
733 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "netmask_" + interface, string.join(alias_netmasks))
734
735 #
736 # DHCP IP
737 #
738 else:
739 self._edit_config(self._chroot_dir + "/etc/conf.d/net", {"iface_" + interface: "dhcp"})
740 emerge_dhcp = True
741 if emerge_dhcp:
742 exitstatus = self._emerge("dhcpcd")
743 if exitstatus != 0:
744 self._logger.log("ERROR! : Could not emerge dhcpcd!")
745 else:
746 self._logger.log("dhcpcd emerged.")
747
748 def set_root_password(self):
749 "Sets the root password"
750 status = GLIUtility.spawn('echo "root:' + self._install_profile.get_root_pass_hash() + '" | chroot '+self._chroot_dir+' chpasswd -e', quiet=True)
751 if not GLIUtility.exitsuccess(status):
752 raise GLIException("SetRootPasswordError", 'fatal', 'set_root_password', "Failure to set root password!")
753 self._logger.log("Root Password set on the new system.")
754
755 def set_users(self):
756 "Sets up the new users for the system"
757 # Loop for each user
758 for user in self._install_profile.get_users():
759
760 # Get values from the tuple
761 username = user[0]
762 password_hash = user[1]
763 groups = user[2]
764 shell = user[3]
765 home_dir = user[4]
766 uid = user[5]
767 comment = user[6]
768
769 options = [ "-m", "-p " + password_hash ]
770
771 # If the groups are specified
772 if groups:
773
774 # If just one group is listed as a string, make it a list
775 if groups == str:
776 groups = [ groups ]
777
778 # If only 1 group is listed
779 if len(groups) == 1:
780 options.append("-G " + groups[0])
781
782 # If there is more than one group
783 elif len(groups) > 1:
784 options.append('-G "' + string.join(groups, ",") + '"')
785
786 # If a shell is specified
787 if shell:
788 options.append("-s " + shell)
789
790 # If a home dir is specified
791 if home_dir:
792 options.append("-d " + home_dir)
793
794 # If a UID is specified
795 if uid:
796 options.append("-u " + str(uid))
797
798 # If a comment is specified
799 if comment:
800 options.append('-c "' + comment + '"')
801
802 # Add the user
803 exitstatus = GLIUtility.spawn('useradd ' + string.join(options) + ' ' + username, chroot=self._chroot_dir, logfile=self._compile_logfile, display_on_tty8=True)
804 if not GLIUtility.exitsuccess(exitstatus):
805 self._logger.log("ERROR! : Failure to add user " + username)
806 # raise GLIException("AddUserError", 'warning', 'set_users', "Failure to add user " + username)
807 else:
808 self._logger.log("User "+username+"was added.")
809
810 def install_bootloader(self):
811 "THIS FUNCTION MUST BE DONE BY THE INDIVIDUAL ARCH"
812 pass

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20