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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 346 - (show annotations) (download) (as text)
Tue Mar 1 17:29:19 2005 UTC (13 years, 7 months ago) by codeman
Original Path: trunk/src/GLIArchitectureTemplate.py
File MIME type: text/x-python
File size: 32732 byte(s)
more true -> True typos

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

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20