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

Contents of /trunk/src/GLIArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 131 - (show annotations) (download) (as text)
Tue Nov 16 07:07:59 2004 UTC (14 years, 1 month ago) by agaffney
File MIME type: text/x-python
File size: 35294 byte(s)
new size passed to ntfsresize in bytes instead of KiB

1 """
2 Gentoo Linux Installer
3
4 $Id: GLIArchitectureTemplate.py,v 1.12 2004/11/16 07:07:59 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
16 from signal import SIGUSR1
17 from GLIException import *
18 # Until I switch my partition code to GLIUtility.spawn()
19 import commands
20
21 class ArchitectureTemplate:
22
23 def __init__(self,configuration=None, install_profile=None, client_controller=None):
24 self._configuration = configuration
25 self._install_profile = install_profile
26 self._cc = client_controller
27
28 # This will get used a lot, so it's probably
29 # better to store it in a variable than to call
30 # this method 100000 times.
31 self._chroot_dir = self._configuration.get_root_mount_point()
32
33 # These must be filled in by the subclass. _steps is a list of
34 # functions, that will carry out the installation. They must be
35 # in order.
36 #
37 # For example, self._steps might be: [preinstall, stage1, stage2, stage3, postinstall],
38 # where each entry is a function (with no arguments) that carries out the desired actions.
39 # Of course, steps will be different depending on the install_profile
40
41 self._steps = []
42 self._architecture_name = "generic"
43
44 def _depends(self, depends):
45 # Type checking
46 if type(depends) not in [ list, str, tuple ]:
47 raise "Dependencies must be a string or a list of strings"
48
49 # If it is a string, change it to a list for parsing
50 if type(depends) == str:
51 depends = [ depends ]
52
53 # Parse dependencies
54 for dependency in depends:
55 # If the dependency has not been satisfied, check to see if 'ignore' has been turned on
56 if not dependency in self._client_configuration.install_steps_completed:
57
58 #If ignore is on, just print a warning
59 if self._install_profile.get_ignore_install_step_depends():
60 print "Warning: You chose to ignore install step dependencies. The " + dependency + " was not met. Ignoring."
61 #If ignore is off, then raise exception
62 else:
63 raise "InstallTemplateError", "Install step dependency not met!"
64
65 # It is possible to override these methods in each Arch Template.
66 # It might be necessary to do so, if the arch needs something 'weird'.
67
68 def stage1(self):
69 "Stage 1 install -- bootstraping"
70 # Dependency checking
71 self._depends("preinstall")
72
73 # If we are doing a stage 1 install, then bootstrap
74 if self._install_profile.get_install_stage() == 1:
75 exitstatus = GLIUtility.spawn("/usr/portage/scripts/bootstrap.sh", True)
76 if not GLIUtility.exitsuccess(exitstatus):
77 raise Stage1Error('fatal','stage1', "Bootstrapping failed!")
78
79 self._configuration.add_install_steps_completed("stage1")
80
81 def stage2(self):
82 # Dependency checking
83 self._depends("stage1")
84
85 # If we are doing a stage 1 or 2 install, then emerge system
86 if self._install_profile.get_install_stage() in [ 1, 2 ]:
87 exitstatus = GLIUtility.emerge("system")
88 if not GLIUtility.exitsuccess(exitstatus):
89 raise Stage2Error('fatal','stage2', "Building the system failed!")
90
91 self._configuration.add_install_steps_completed("stage2")
92
93 def preinstall(self):
94 if not os.path.isdir(self._configuration.get_root_mount_point()):
95 os.makedirs(self._configuration.get_root_mount_point())
96
97 # Fetch and unpack the stage tarball here.
98 GLIUtility.fetch_and_unpack_tarball(self._install_profile.get_stage_tarball_uri(), self._configuration.get_root_mount_point(),keep_permissions=True)
99
100 ret = GLIUtility.spawn("cp -L /etc/resolv.conf /mnt/gentoo/etc/resolv.conf",True)
101 if not GLIUtility.exitsuccess(ret):
102 raise CopyError('warning','preinstall','Could not copy resolv.conf!',True)
103
104 ret = GLIUtility.spawn("mount -t proc none /mnt/gentoo /proc")
105 if not GLIUtility.exitsuccess(ret):
106 raise MountError('fatal','preinstall','Could not mount /proc')
107
108 # Set USE flags here
109 # might want to rewrite/use _edit_config from the GLIInstallTemplate
110 # Then you should be done... at least with the preinstall.
111
112 def notify_frontend(self):
113 os.kill(os.getpid(), SIGUSR1)
114
115 def install_packages(self):
116 "Will install any extra software!"
117 # Dependency checking
118 self._depends("emerge system")
119 installpackages = self._install_profile.get_install_packages()
120 for package in installpackages:
121 status = GLIUtility.emerge(package)
122 if not GLIUtility.exit_success(status):
123 raise "InstallPackagesError", "Could not emerge " + package + "!"
124
125 # This is part of the interface... subclasses MUST
126 # provide these methods filled in.
127 def stage3(self):
128 # This should probably start with building the kernel,
129 # that might be the only thing this actually needs
130 # to do.
131 pass
132
133 def postinstall(self):
134 pass
135
136 def partition(self):
137 pass
138
139 # **************************************************************************************
140
141 def _add_to_runlevel(self, script_name, runlevel="default"):
142 "Adds the script named 'script_name' to the runlevel 'runlevel' in the chroot environement"
143
144 # Do it
145 status = GLIUtility._run("rc-update add " + script_name + " " + runlevel, chroot=self._chroot_dir)
146 if not GLIUtility.exit_success(status):
147 raise "RunlevelAddError", "Failure adding " + script_name + " to runlevel " + runlevel + "!"
148
149 def mount_local_partitions(self):
150 "Mounts all partitions that are on the local machine"
151 # Dependency checking
152 self._depends("partition_local_drives")
153
154 def mount_network_shares(self):
155 "Mounts all network shares to the local machine"
156 # Dependency checking
157 self._depends([ "setup_network_pre", "mount_local_partitions" ])
158
159 def fetch_sources_from_cd(self):
160 "Gets sources from CD (required for non-network installation)"
161 # Dependency checking
162 self._depends("unpack_tarball")
163
164 def fetch_grp_from_cd(self):
165 "Gets grp binary packages from CD (required for non-network binary installation)"
166 # Dependency checking
167 self._depends("unpack_tarball")
168
169 def configure_make_conf(self):
170 "Configures make.conf"
171 # Dependency checking
172 self._depends("prepare_chroot")
173
174 # Get make.conf options
175 options = self._install_profile.get_make_conf()
176
177 # For each configuration option...
178 for key in options.keys():
179
180 # Add/Edit it into make.conf
181 GLIUtility.edit_config(self._chroot_dir + "/etc/make.conf", key, options[key])
182
183 def install_portage_tree(self):
184 "Get/update the portage tree"
185 # Dependency checking
186 self._depends("prepare_chroot")
187
188 # Check the type of portage tree fetching we'll do
189 # If it is custom, follow the path to the custom tarball and unpack it
190 if self._install_profile.get_portage_tree_sync_type() == "custom":
191
192 # Get portage tree info
193 portage_tree_snapshot_uri = self._install_profile.get_portage_tree_snapshot_uri()
194
195 # Fetch and unpack the tarball
196 self._fetch_and_unpack_tarball(portage_tree_snapshot_uri, self._client_configuration.get_root_mount_point() + "/usr/", self._client_configuration.get_root_mount_point() + "/")
197 if not GLIUtility.is_file(self._client_configuration.get_root_mount_point()+"/usr/portage/distfiles"):
198 exitstatus = self._run("mkdir /usr/portage/distfiles",True)
199 if exitstatus != 0:
200 raise "MkdirError","Making the distfiles directory failed."
201 exitstatus = self._run("cp /mnt/cdrom/distfiles/* "+self._client_configuration.get_root_mount_point()+"/usr/portage/distfiles/")
202 if exitstatus != 0:
203 raise "PortageError","Failed to copy the distfiles to the new system"
204 # If the type is webrsync, then run emerge-webrsync
205 elif self._install_profile.get_portage_tree_sync_type() == "webrsync":
206 exitstatus = self._run("emerge-webrsync", True)
207 if exitstatus != 0:
208 raise "EmergeWebRsyncError", "Failed to retrieve portage tree!"
209
210 # Otherwise, just run emerge sync
211 else:
212 exitstatus = self._emerge("sync")
213 if exitstatus != 0:
214 raise "EmergeSyncError", "Failed to retrieve portage tree!"
215
216 def set_timezone(self):
217 "Sets the timezone for the new environment"
218
219 # Dependency checking
220 self._depends("unpack_tarball")
221 #self._process_desc("Setting the timezone")
222
223 # Set symlink
224 if not os.access(self._client_configuration.get_root_mount_point() + "/etc/localtime", os.W_OK):
225 os.symlink(self._client_configuration.get_root_mount_point() + "/usr/share/zoneinfo/" + self._install_profile.get_time_zone(), self._client_configuration.get_root_mount_point() + "/etc/localtime")
226 if not (self._install_profile.get_time_zone() == "UTC"):
227 self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/rc.conf", "CLOCK", "local")
228
229 def configure_fstab(self):
230 "Configures fstab"
231 # Dependency checking
232 self._depends("unpack_tarball")
233 newfstab = ""
234 partitions = self._install_profile.get_fstab()
235 for partition in partitions:
236 if not GLIUtility.is_file(self._client_configuration.get_root_mount_point()+partition):
237 exitstatus = self._run("mkdir " + partition, True)
238 if exitstatus != 0:
239 raise "MkdirError", "Making the mount point failed!"
240 newfstab += partitions[partition][0] + "\t " + partition + "\t " + partitions[partition][1]
241 newfstab += "\t " + partitions[partition][2] + "\t "
242 if partition == "/boot":
243 newfstab += "1 2\n"
244 elif partition == "/":
245 newfstab += "0 1\n"
246 else:
247 newfstab += "0 0\n"
248 newfstab += "none /proc proc defaults 0 0\n"
249 newfstab += "none /dev/shm tmpfs defaults 0 0\n"
250 if GLIUtility.is_device("/dev/cdroms/cdrom0"):
251 newfstab += "/dev/cdroms/cdrom0 /mnt/cdrom auto noauto,user 0 0\n"
252
253 file_name = self._client_configuration.get_root_mount_point() + "/etc/fstab"
254 try:
255 shutil.move(file_name, file_name + ".OLDdefault")
256 except:
257 pass
258 f = open(file_name, 'w')
259 f.writelines(newfstab)
260 f.close()
261
262
263 def emerge_kernel_sources(self):
264 "Fetches desired kernel sources"
265 # Dependency checking
266 self._depends("emerge_system")
267 exitstatus = self._emerge(self._install_profile.get_kernel_source_pkg())
268 if exitstatus != 0:
269 raise "EmergeKernelSourcesError", "Could not retrieve kernel sources!"
270 try:
271 os.stat(self._client_configuration.get_root_mount_point() + "/usr/src/linux")
272 except:
273 kernels = os.listdir(self._client_configuration.get_root_mount_point()+"/usr/src")
274 found_a_kernel = False
275 counter = 0
276 while not found_a_kernel:
277 if kernels[counter][0:6]=="linux-":
278 exitstatus = self._run("ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux",True)
279 found_a_kernel = True
280 else:
281 counter = counter + 1
282
283 def build_kernel(self):
284 "Builds kernel"
285 # Dependency checking
286 self._depends("emerge_kernel_sources")
287
288 exitstatus = self._emerge("genkernel")
289 if exitstatus != 0:
290 raise "EmergeGenKernelError", "Could not emerge genkernel!"
291
292
293 # Null the genkernel_options
294 genkernel_options = ""
295
296 # Get the uri to the kernel config
297 kernel_config_uri = self._install_profile.get_kernel_config_uri()
298
299 # If the uri for the kernel config is not null, then
300 if kernel_config_uri != "":
301 self._get_uri(kernel_config_uri, self._client_configuration.get_root_mount_point() + "/root/kernel_config")
302 genkernel_options = genkernel_options + " --kernel-config=/root/kernel_config"
303
304 # Decide whether to use bootsplash or not
305 if self._install_profile.get_kernel_bootsplash():
306 genkernel_options = genkernel_options + " --bootsplash"
307 else:
308 genkernel_options = genkernel_options + " --no-bootsplash"
309
310 # This is code to choose whether or not genekernel will build an initrd or not
311 # Genkernel currently does not support this
312 #if self._install_profile.get_kernel_initrd():
313 # pass
314 #else:
315 # pass
316
317 # Run genkernel in chroot
318 print "genkernel all " + genkernel_options
319 exitstatus = self._run("genkernel all " + genkernel_options, True)
320 if exitstatus != 0:
321 raise "KernelBuildError", "Could not build kernel!"
322
323 def install_logging_daemon(self):
324 "Installs and sets up logger"
325 # Dependency checking
326 self._depends("emerge_system")
327
328 # Get loggin daemon info
329 logging_daemon_pkg = self._install_profile.get_logging_daemon_pkg()
330 if logging_daemon_pkg:
331 # Emerge Logging Daemon
332 exitstatus = self._emerge(logging_daemon_pkg)
333 if exitstatus != 0:
334 raise "LoggingDaemonError", "Could not emerge " + logging_daemon_pkg + "!"
335
336 # Add Logging Daemon to default runlevel
337 self._add_to_runlevel(logging_daemon_pkg)
338
339 def install_cron_daemon(self):
340 "Installs and sets up cron"
341 # Dependency checking
342 self._depends("emerge_system")
343
344 # Get cron daemon info
345 cron_daemon_pkg = self._install_profile.get_cron_daemon_pkg()
346 if cron_daemon_pkg:
347 # Emerge Cron Daemon
348 exitstatus = self._emerge(cron_daemon_pkg)
349 if exitstatus != 0:
350 raise "CronDaemonError", "Could not emerge " + cron_daemon_pkg + "!"
351
352 # Add Cron Daemon to default runlevel
353 self._add_to_runlevel(cron_daemon_pkg)
354
355 # If the Cron Daemon is not vixie-cron, run crontab
356 if cron_daemon_pkg != "vixie-cron":
357 exitstatus = self._run("crontab /etc/crontab", True)
358 if exitstatus != 0:
359 raise "CronDaemonError", "Failure making crontab!"
360
361 def install_filesystem_tools(self):
362 "Installs and sets up fstools"
363 # Dependency checking
364 self._depends("emerge_system")
365
366 # Get the list of file system tools to be installed
367 filesystem_tools = self._install_profile.get_filesystem_tools_pkgs()
368
369 # If the fstools var is a str, convert it to a list
370 if type(filesystem_tools) == str:
371 filesystem_tools = [ filesystem_tools ]
372
373 # For each fstool package in the list, install it
374 for package in filesystem_tools:
375 exitstatus = self._emerge(package)
376 if exitstatus != 0:
377 raise "FilesystemToolsError", "Could not emerge " + package + "!"
378
379 def install_rp_pppoe(self):
380 "Installs rp-pppoe"
381 # Dependency checking
382 self._depends("emerge_system")
383
384 # If user wants us to install rp-pppoe, then do so
385 if self._install_profile.get_install_rp_pppoe():
386 exitstatus = self._emerge("rp-pppoe")
387 if exitstatus != 0:
388 raise "RP-PPPOEError", "Could not emerge rp-pppoe!"
389
390 # Should we add a section here to automatically configure rp-pppoe?
391 # I think it should go into the setup_network_post section
392 # What do you guys think?
393
394 def install_pcmcia_cs(self):
395 "Installs and sets up pcmcia-cs"
396 # Dependency checking
397 self._depends("build_kernel")
398
399 # If user wants us to install pcmcia-cs, then do so
400 if self._install_profile.get_install_pcmcia_cs():
401 exitstatus = self._emerge("pcmcia-cs")
402 if exitstatus != 0:
403 raise "PCMCIA-CSError", "Could not emerge pcmcia-cs!"
404
405 # Add pcmcia-cs to the default runlevel
406 exitstatus = self._run("rc-update add pcmcia default", True)
407 if exitstatus != 0:
408 raise "PCMCIA-CSError", "Could not add pcmcia-cs to the default runlevel!"
409
410 def install_bootloader(self):
411 "Installs and configures bootloader"
412 #
413 # THIS IS ARCHITECTURE DEPENDANT!!!
414 # This is the x86 way.. it uses grub
415 # Dependency checking
416 self._depends("build_kernel")
417
418 if self._install_profile.get_boot_loader_pkg():
419 exitstatus = self._emerge(self._install_profile.get_boot_loader_pkg())
420 if exitstatus != 0:
421 raise "BootLoaderEmergeError", "Could not emerge bootloader!"
422 else:
423 pass
424
425 boot_device = ""
426 boot_minor = ""
427 root_device = ""
428 root_minor = ""
429 grub_root_minor = ""
430 grub_boot_minor = ""
431 grub_boot_drive = ""
432 grub_root_drive = ""
433 minornum = 0
434 #Assign root to the root mount point to make lines more readable
435 root = self._client_configuration.get_root_mount_point()
436 file_name = root + "/boot/grub/bootdevice"
437 file_name1 = root + "/boot/grub/rootdevice"
438 file_name2 = root + "/boot/grub/device.map"
439 file_name3 = root + "/boot/grub/kernel_name"
440 foundboot = False
441 partitions = self._install_profile.get_fstab()
442 for partition in partitions:
443 #if find a /boot then stop.. else we'll take a / and overwrite with a /boot if we find it too.
444 if (partition == "/boot"):
445 #try to get the drive LETTER from /dev/hdc1 8th character
446 boot_minor = partitions[partition][0][8]
447 grub_boot_minor = str(int(boot_minor) - 1)
448 boot_device = partitions[partition][0][0:8]
449 foundboot = True
450 if ( (partition == "/") and (not foundboot) ):
451 boot_minor = partitions[partition][0][8]
452 grub_boot_minor = str(int(boot_minor) - 1)
453 boot_device = partitions[partition][0][0:8]
454 #Foundboot IS STILL FALSE
455 if partition == "/":
456 root_minor = partitions[partition][0][8]
457 grub_root_minor = str(int(root_minor) - 1)
458 root_device = partitions[partition][0][0:8]
459
460 exitstatus0 = self._run("ls -l " + boot_device + " > " + file_name)
461 exitstatus1 = self._run("ls -l " + root_device + " > " + file_name1)
462 exitstatus2 = self._run("echo quit | "+ root+"/sbin/grub --device-map="+file_name2)
463 exitstatus3 = self._run("ls "+root+"/boot/kernel-* > "+file_name3)
464 exitstatus4 = self._run("ls "+root+"/boot/initrd-* >> "+file_name3)
465 if (exitstatus0 != 0) or (exitstatus1 != 0) or (exitstatus2 != 0) or (exitstatus3 != 0) or (exitstatus4 != 0):
466 raise "Bootloadererror", "Error in one of THE FOUR run commands"
467
468 """
469 read the device map. sample looks like this:
470 (fd0) /dev/floppy/0
471 (hd0) /dev/ide/host2/bus0/target0/lun0/disc
472 (hd1) /dev/ide/host0/bus0/target0/lun0/disc
473 (hd2) /dev/ide/host0/bus0/target1/lun0/disc
474 """
475 e = open(file_name) #Looking for the boot device
476 ls_output = e.readlines()
477 e.close()
478 # looks like lr-xr-xr-x 1 root root 32 Oct 1 16:09 /dev/hda -> ide/host0/bus0/target0/lun0/disc
479 ls_output = ls_output[0].split(">")[-1]
480 ls_output = ls_output[1:]
481
482 eb = open(file_name1) #Looking for the root device
483 ls_outputb = eb.readlines()
484 eb.close()
485 ls_outputb = ls_outputb[0].split(">")[-1]
486 ls_outputb = ls_outputb[1:]
487
488 # Search for the key
489 f = open(file_name2)
490 file = f.readlines()
491 f.close()
492 for i in range(len(file)):
493 if file[i][11:] == ls_output:
494 #eurika we found the drivenum
495 grub_boot_drive = file[i][1:4]
496 if file[i][11:] == ls_outputb:
497 grub_root_drive = file[i][1:4]
498 if (not grub_root_drive) or (not grub_boot_drive):
499 raise "BootloaderError","Couldn't find the drive num in the list from the device.map"
500
501 g = open(file_name3)
502 kernel_name = g.readlines()
503 g.close()
504 if not kernel_name[0]:
505 raise "BootloaderError","Error: We have no kernel in /boot to put in the grub.conf file!"
506 kernel_name = map(string.strip, kernel_name)
507 kernel_name[0] = kernel_name[0].split(root)[1]
508 kernel_name[1] = kernel_name[1].split(root)[1]
509 #-------------------------------------------------------------
510 #OK, now that we have all the info, let's build that grub.conf
511 newgrubconf = ""
512 newgrubconf += "default 0\ntimeout 30\n"
513 if foundboot: #we have a /boot
514 newgrubconf += "splashimage=(" + grub_boot_drive + "," + grub_boot_minor + ")/grub/splash.xpm.gz\n"
515 else: #we have / and /boot needs to be included
516 newgrubconf += "splashimage=(" + grub_boot_drive + "," + grub_boot_minor + ")/boot/grub/splash.xpm.gz\n"
517
518 newgrubconf += "title=Gentoo Linux\n"
519 newgrubconf += "root (" + grub_boot_drive + "," + grub_boot_minor + ")\n"
520 if foundboot:
521 newgrubconf += "kernel " + kernel_name[0][5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
522 newgrubconf += root_device + root_minor + "\n"
523 newgrubconf += "initrd " + kernel_name[1][5:] + "\n"
524 else:
525 newgrubconf += "kernel /boot" + kernel_name[0][5:] + " root=/dev/ram0 init=/linuxrc ramdisk=8192 real_root="
526 newgrubconf += root_device + root_minor + "\n"
527 newgrubconf += "initrd /boot" + kernel_name[1][5:] + "\n"
528
529 #-------------------------------------------------------------
530 #OK, now that the file is built. Install grub.
531 #cp /proc/mounts /etc/mtab
532 #grub-install --root-directory=/boot /dev/hda
533 #shutil.copy("/proc/mounts",root +"/etc/mtab")
534 grubinstallstring = "echo -en 'root ("+grub_boot_drive + "," + grub_boot_minor + ")\n"
535 if not self._install_profile.get_boot_loader_mbr():
536 grubinstallstring +="setup ("+grub_boot_drive + "," + grub_boot_minor + ")\n"
537 else:
538 grubinstallstring +="setup ("+grub_boot_drive+")\n"
539 grubinstallstring += "quit\n' | "+root+"/sbin/grub"
540 print grubinstallstring
541 exitstatus = self._run(grubinstallstring,True)
542 if exitstatus != 0:
543 raise "GrubInstallError", "Could not install grub!"
544
545 #now make the grub.conf file
546 file_name = root + "/boot/grub/grub.conf"
547 try:
548 shutil.move(file_name, file_name + ".OLDdefault")
549 except:
550 pass
551 f = open(file_name, 'w')
552 f.writelines(newgrubconf)
553 f.close()
554
555 def update_config_files(self):
556 "Runs etc-update (overwriting all config files), then re-configures the modified ones"
557 # Dependency checking
558 self._depends("emerge_system")
559
560 # Run etc-update overwriting all config files
561 status = GLIUtility.spawn('echo "-5" | etc-update', chroot=self._chroot_dir)
562 if not GLIUtility.exit_success(status):
563 raise "EtcUpdateError", "Could not update config files!"
564
565 self.configure_make_conf()
566 self.configure_fstab()
567
568 def configure_rc_conf(self):
569 "Configures rc.conf"
570 # Dependency checking
571 self._depends("update_config_files")
572
573 # Get make.conf options
574 options = self._install_profile.get_rc_conf()
575
576 # For each configuration option...
577 for key in options.keys():
578
579 # Add/Edit it into rc.conf
580 self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/rc.conf", key, option[key])
581
582 def setup_network_post(self):
583 "Sets up the network for the first boot"
584 # Dependency checking
585 self._depends("unpack_tarball")
586
587 # Get hostname, domainname and nisdomainname
588 hostname = self._install_profile.get_hostname()
589 domainname = self._install_profile.get_domainname()
590 nisdomainname = self._install_profile.get_nisdomainname()
591
592 # Write the hostname to the hostname file
593 open(self._client_configuration.get_root_mount_point() + "/etc/hostname", "w").write(hostname + "\n")
594
595 # Write the domainname to the nisdomainname file
596 if domainname:
597 open(self._client_configuration.get_root_mount_point() + "/etc/dnsdomainname", "w").write(domainname + "\n")
598
599 # Write the nisdomainname to the nisdomainname file
600 if nisdomainname:
601 open(self._client_configuration.get_root_mount_point() + "/etc/nisdomainname", "w").write(nisdomainname + "\n")
602
603 #
604 # EDIT THE /ETC/HOSTS FILE
605 #
606
607 # The address we are editing is 127.0.0.1
608 hosts_ip = "127.0.0.1"
609
610 # If the hostname is localhost
611 if hostname == "localhost":
612 # If a domainname is set
613 if domainname:
614 hosts_line = hostname + "." + domainname + "\t" + hostname
615 else:
616 hosts_line = hostname
617 # If the hostname is not localhost
618 else:
619 # If a domainname is set
620 if domainname:
621 hosts_line = hostname + "." + domainname + "\t" + hostname + "\tlocalhost"
622 else:
623 hosts_line = "localhost\t" + hostname
624
625 # Write to file
626 self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/hosts", hosts_ip, hosts_line, True, '\t', False)
627
628 #
629 # SET DEFAULT GATEWAY
630 #
631
632 # Get default gateway
633 default_gateway = self._install_profile.get_default_gateway()
634
635 # If the default gateway exists, add it
636 if default_gateway:
637 self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "gateway", default_gateway)
638
639 #
640 # SET RESOLV INFO
641 #
642
643 # Get dns servers
644 dns_servers = self._install_profile.get_dns_servers()
645
646 # Clear the list
647 resolv_output = []
648
649 # If dns servers are set
650 if dns_servers:
651
652
653 # Parse each dns server
654 for dns_server in dns_servers:
655 # Add the server to the output
656 resolv_output.append("nameserver " + dns_server +"\n")
657
658 # If the domainname is set, then also output it
659 if domainname:
660 resolv_output.append("search " + domainname + "\n")
661
662 # Output to file
663 resolve_conf = open(self._client_configuration.get_root_mount_point() + "/etc/resolv.conf", "w")
664 resolve_conf.writelines(resolv_output)
665 resolve_conf.close()
666
667 #
668 # PARSE INTERFACES
669 #
670
671 # Fetch interfaces
672 interfaces = self._install_profile.get_network_interfaces()
673
674 # Parse each interface
675 for interface in interfaces.keys():
676
677 # If we are going to load the network at boot...
678 if interfaces[interface][2]:
679
680 # Add it to the default runlevel
681 exitstatus = self._run("rc-update add net." + interface + " default", True)
682 if exitstatus != 0:
683 raise "NetStartupError", "Cannot add interface " + interface + " to the default runlevel!"
684
685 # Set what kind of interface it is
686 interface_type = interface[:3]
687
688 # Check to see if there is a startup script for this interface, if there isn't link to the proper script
689 try:
690 os.stat(self._client_configuration.get_root_mount_point() + "/etc/init.d/net." + interface)
691 except:
692 os.symlink(self._client_configuration.get_root_mount_point() + "/etc/init.d/net." + interface_type + "0", self._client_configuration.get_root_mount_point() + "/etc/init.d/net." + interface)
693
694 #
695 # ETHERNET
696 #
697 if interface_type == "eth":
698
699 #
700 # STATIC IP
701 #
702 # If the post-install device info is not None, then it is a static ip addy
703 if interfaces[interface][1]:
704 ip = interfaces[interface][0]
705 broadcast = interfaces[interface][1]
706 netmask = interfaces[interface][2]
707 # aliases = interfaces[interface][1][3]
708 # alias_ips = []
709 # alias_broadcasts = []
710 # alias_netmasks = []
711
712 # Write the static ip config to /etc/conf.d/net
713 self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "iface_" + interface, ip + " broadcast " + broadcast + " netmask " + netmask)
714
715 # If aliases are set
716 # if aliases:
717
718 # Parse aliases to format alias info
719 # for alias in aliases:
720 # alias_ips.append(alias[0])
721 # alias_broadcasts.append(alias[1])
722 # alias_netmasks.append(allias[2])
723
724 # Once the alias info has been gathered, then write it out
725 # Alias ips first
726 # self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "alias_" + interface, string.join(alias_ips))
727 # Alias broadcasts next
728 # self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "broadcast_" + interface, string.join(alias_broadcasts))
729 # Alias netmasks last
730 # self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "netmask_" + interface, string.join(alias_netmasks))
731
732 #
733 # DHCP IP
734 #
735 else:
736 self._edit_config(self._client_configuration.get_root_mount_point() + "/etc/conf.d/net", "iface_" + interface, "dhcp")
737
738 def set_root_password(self):
739 "Sets the root password"
740 # Dependency checking
741 self._depends("emerge_system")
742
743 status = GLIUtility.spawn('echo "root:' + self._install_profile.get_root_pass_hash() + '" | chpasswd -e', chroot=self._chroot_dir)
744 if not GLIUtility.exit_success(status):
745 raise "SetRootPasswordError", "Failure to set root password!"
746
747 def set_users(self):
748 "Sets up the new users for the system"
749 # Dependency checking
750 self._depends("emerge_system")
751
752 # Loop for each user
753 for user in self._install_profile.get_users():
754
755 # Get values from the tuple
756 username = user[0]
757 password_hash = user[1]
758 groups = user[2]
759 shell = user[3]
760 home_dir = user[4]
761 uid = user[5]
762 comment = user[6]
763
764 options = [ "-m", "-p " + password_hash ]
765
766 # If the groups are specified
767 if groups:
768
769 # If just one group is listed as a string, make it a list
770 if groups == str:
771 groups = [ groups ]
772
773 # If only 1 group is listed
774 if len(groups) == 1:
775 options.append("-G " + groups[0])
776
777 # If there is more than one group
778 elif len(groups) > 1:
779 options.append('-G "' + string.join(groups, ",") + '"')
780
781 # If a shell is specified
782 if shell:
783 options.append("-s " + shell)
784
785 # If a home dir is specified
786 if home_dir:
787 options.append("-d " + home_dir)
788
789 # If a UID is specified
790 if uid:
791 options.append("-u " + str(uid))
792
793 # If a comment is specified
794 if comment:
795 options.append('-c "' + comment + '"')
796
797 # Add the user
798 exitstatus = GLIUtility.spawn('useradd ' + string.join(options) + ' ' + username, chroot=self._chroot_dir)
799 if not GLIUtility.exit_success(exitstatus):
800 raise "AddUserError", "Failure to add user " + username
801
802 def _cylinders_to_sectors(self, minor, start, end, sectors_in_cylinder):
803 cylinders = int(end) - int(start) + 1
804 total_sectors = cylinders * int(sectors_in_cylinder)
805 start_sector = int(start) * sectors_in_cylinder
806 end_sector = start_sector + total_sectors - 1
807 if int(minor) == 1 and start_sector == 0: start_sector = 63
808 return (start_sector, end_sector)
809
810 def _sectors_to_megabytes(self, sectors, sector_bytes=512):
811 return float((float(sectors) * sector_bytes)/ float(1024*1024))
812
813 def _sectors_to_bytes(self, sectors, sector_bytes=512):
814 return (int(sectors) * sector_bytes)
815
816 def _run_parted_command(self, device, cmd):
817 parted_output = commands.getoutput("parted -s " + device + " " + cmd)
818 print "parted -s " + device + " " + cmd
819
820 def _add_partition(self, device, start, end, type, fs):
821 start = self._sectors_to_megabytes(start)
822 end = self._sectors_to_megabytes(end)
823 self._run_parted_command(device, "mkpart " + type + " " + fs + " " + str(start) + " " + str(end))
824 if type == "ntfs":
825 pass
826 elif type == "ext2" or type == "ext3":
827 pass
828 else:
829 pass
830
831 def do_partitioning(self):
832 import GLIStorageDevice, parted, pprint
833
834 devices_old = {}
835 parts_old = {}
836 parts_new = self._install_profile.get_partition_tables()
837 drives = GLIStorageDevice.detect_devices()
838 drives.sort()
839 for drive in drives:
840 devices_old[drive] = GLIStorageDevice.Device(drive)
841 devices_old[drive].set_partitions_from_disk()
842 for part in devices_old.keys(): parts_old[part] = devices_old[part].get_install_profile_structure()
843
844 pp = pprint.PrettyPrinter(indent=4)
845 pp.pprint(parts_old)
846 pp.pprint(parts_new)
847
848 for dev in parts_old.keys():
849 parts_active = []
850 parts_lba = []
851 print "\nProcessing " + dev + "..."
852 parted_dev = parted.PedDevice.get(dev)
853 parted_disk = parted.PedDisk.new(parted_dev)
854 last_partition_touched = 0
855 sectors_in_cylinder = devices_old[dev]._sectors_in_cylinder
856 # First pass to delete old partitions that aren't resized
857 for part in parts_old[dev]:
858 oldpart = parts_old[dev][part]
859 old_start, old_end = self._cylinders_to_sectors(part, oldpart['start'], oldpart['end'], sectors_in_cylinder)
860 matchingminor = 0
861 for new_part in parts_new[dev]:
862 tmppart = parts_new[dev][new_part]
863 new_start, new_end = self._cylinders_to_sectors(new_part, tmppart['start'], tmppart['end'], sectors_in_cylinder)
864 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) == int(oldpart['end']):
865 matchingminor = new_part
866 print " Deleting old minor " + str(part) + " to be recreated later"
867 self._run_parted_command(dev, "rm " + str(part))
868 break
869 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
870 matchingminor = new_part
871 print " Ignoring old minor " + str(part) + " to resize later"
872 break
873 if not matchingminor:
874 print " No match found...deleting partition " + str(part)
875 self._run_parted_command(dev, "rm " + str(part))
876 else:
877 if parted_disk.get_partition(part).get_flag(1): # Active/boot
878 print " Partition " + str(part) + " was active...noted"
879 parts_active.append(int(matchingminor))
880 if parted_disk.get_partition(part).get_flag(7): # LBA
881 print " Partition " + str(part) + " was LBA...noted"
882 parts_lba.append(int(matchingminor))
883 # Second pass to resize old partitions that need to be resized
884 print " Second pass..."
885 for part in parts_old[dev]:
886 oldpart = parts_old[dev][part]
887 old_start, old_end = self._cylinders_to_sectors(part, oldpart['start'], oldpart['end'], sectors_in_cylinder)
888 for new_part in parts_new[dev]:
889 tmppart = parts_new[dev][new_part]
890 new_start, new_end = self._cylinders_to_sectors(new_part, tmppart['start'], tmppart['end'], sectors_in_cylinder)
891 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
892 print " Resizing old minor " + str(part) + " from " + str(oldpart['start']) + "-" + str(oldpart['end'])+ " to " + str(tmppart['start']) + "-" + str(tmppart['end'])
893 type = tmppart['type']
894 device = dev
895 minor = part
896 start = int(new_start)
897 end = int(new_end)
898 if type == "ext2" or type == "ext3":
899 total_sectors = end - start + 1
900 commands.getstatus("resize2fs " + device + str(minor) + " " + str(total_sectors) + "s")
901 print "resize2fs " + device + str(minor) + " " + str(total_sectors) + "s"
902 elif type == "ntfs":
903 total_sectors = end - start + 1
904 total_bytes = int(self._sectors_to_bytes(total_sectors))
905 commands.getstatus("ntfsresize --size " + str(total_bytes) + " " + device + str(minor))
906 print "ntfsresize --size " + str(total_bytes) + " " + device + str(minor)
907 else:
908 start = float(self._sectors_to_megabytes(start))
909 end = float(self._sectors_to_megabytes(end))
910 self._run_parted_command(device, "resize " + str(minor) + " " + str(start) + " " + str(end))
911 print " Deleting old minor " + str(part) + " to be recreated in 3rd pass"
912 self._run_parted_command(dev, "rm " + str(part))
913 break
914 # Third pass to create new partition table
915 print " Third pass..."
916 for part in parts_new[dev]:
917 newpart = parts_new[dev][part]
918 new_start, new_end = self._cylinders_to_sectors(part, newpart['start'], newpart['end'], sectors_in_cylinder)
919 if newpart['type'] == "extended":
920 print " Adding extended partition from " + str(newpart['start']) + " to " + str(newpart['end'])
921 self._add_partition(dev, new_start, new_end, "extended", "")
922 elif int(part) < 5:
923 print " Adding primary partition from " + str(newpart['start']) + " to " + str(newpart['end'])
924 self._add_partition(dev, new_start, new_end, "primary", newpart['type'])
925 elif int(part) > 4:
926 print " Adding logical partition from " + str(newpart['start']) + " to " + str(newpart['end'])
927 self._add_partition(dev, new_start, new_end, "logical", newpart['type'])
928 if int(part) in parts_active and not newpart['format']:
929 print " Partition was previously active...setting"
930 self._run_parted_command(dev, "set " + str(part) + " boot on")
931 if int(part) in parts_lba and not newpart['format']:
932 print " Partition was previously LBA...setting"
933 self._run_parted_command(dev, "set " + str(part) + " lba on")

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20