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

Contents of /trunk/src/GLIArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 213 - (show annotations) (download) (as text)
Wed Jan 5 07:52:28 2005 UTC (13 years, 4 months ago) by codeman
File MIME type: text/x-python
File size: 31775 byte(s)
added mount_local_partitions

1 """
2 Gentoo Linux Installer
3
4 $Id: GLIArchitectureTemplate.py,v 1.22 2005/01/05 07:52:28 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, os, string, sys, shutil
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
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.do_partitioning, "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.install_portage_tree, "Portage tree voodoo"),
47 (self.prepare_chroot, "Preparing chroot"),
48 (self.stage1, "Performing bootstrap"),
49 (self.stage2, "Performing 'emerge system'"),
50 (self.set_timezone, "Setting timezone"),
51 (self.emerge_kernel_sources, "Emerge kernel sources"),
52 (self.build_kernel, "Building kernel"),
53 (self.install_logging_daemon, "Logger"),
54 (self.install_cron_daemon, "Cron daemon"),
55 (self.install_filesystem_tools, "Installing filesystem tools"),
56 (self.setup_network_post, "Configuring post-install networking"),
57 (self.install_bootloader, "Configuring and installing bootloader"),
58 (self.update_config_files, "Updating config files"),
59 (self.configure_rc_conf, "Updating /etc/rc.conf")
60 ]
61
62
63 def get_install_steps(self):
64 return self._install_steps
65
66 def notify_frontend(self, type, data):
67 self._cc.addNotification(type, data)
68
69 # It is possible to override these methods in each Arch Template.
70 # It might be necessary to do so, if the arch needs something 'weird'.
71
72 def _add_to_runlevel(self, script_name, runlevel="default"):
73 "Adds the script named 'script_name' to the runlevel 'runlevel' in the chroot environement"
74
75 # Do it
76 status = GLIUtility.spawn("rc-update add " + script_name + " " + runlevel, chroot=self._chroot_dir)
77 if not GLIUtility.exit_success(status):
78 raise GLIException("RunlevelAddError", 'warning', '_add_to_runlevel', "Failure adding " + script_name + " to runlevel " + runlevel + "!")
79
80 def _emerge(self, package, binary=False, binary_only=False):
81 if binary_only:
82 return GLIUtility.spawn("emerge -K " + package, display_on_tty8=True, chroot=self._chroot_dir)
83 elif binary:
84 return GLIUtility.spawn("emerge -k " + package, display_on_tty8=True, chroot=self._chroot_dir)
85 else:
86 return GLIUtility.spawn("emerge " + package, display_on_tty8=True, chroot=self._chroot_dir)
87
88 def _edit_config(self, filename, newvalues, delimeter='=', quotes_around_value=True):
89 """
90 filename = file to be editted
91 newvlaues = a dictionary of VARIABLE:VALUE pairs
92 """
93 if not GLIUtility.is_file(filename):
94 raise GLIException("NoSuchFileError", 'notice','_edit_config',filename + ' does not exist!')
95
96 f = open(filename)
97 file = f.readlines()
98 f.close()
99
100 for key in newvalues.keys():
101 regexpr = '^\s*#?\s*' + key + '\s*' + delimeter + '.*$'
102 regexpr = re.compile(regexpr)
103
104 for i in range(0, len(file)):
105 if regexpr.match(file[i]):
106 if not file[i][0] == '#':
107 file[i] = '#' + file[i]
108
109 file.append('\n# Added by GLI\n')
110 if quotes_around_value:
111 file.append(key + delimeter + '"' + newvalues[key] + '"\n')
112 else:
113 file.append(key + delimeter + newvalues[key]+'\n')
114
115 f = open(filename,'w')
116 f.writelines(file)
117 f.flush()
118 f.close()
119
120
121 def stage1(self):
122 "Stage 1 install -- bootstraping"
123
124 # If we are doing a stage 1 install, then bootstrap
125 if self._install_profile.get_install_stage() == 1:
126 exitstatus = GLIUtility.spawn("/usr/portage/scripts/bootstrap.sh", chroot=self._chroot_dir)
127 if not GLIUtility.exitsuccess(exitstatus):
128 raise GLIException("Stage1Error", 'fatal','stage1', "Bootstrapping failed!")
129
130 def stage2(self):
131 # If we are doing a stage 1 or 2 install, then emerge system
132 if self._install_profile.get_install_stage() in [ 1, 2 ]:
133 exitstatus = self._emerge("system")
134 if not GLIUtility.exitsuccess(exitstatus):
135 raise GLIException("Stage2Error", 'fatal','stage2', "Building the system failed!")
136
137 def unpack_stage_tarball(self):
138 if not os.path.isdir(self._chroot_dir):
139 os.makedirs(self._chroot_dir)
140 GLIUtility.fetch_and_unpack_tarball(self._install_profile.get_stage_tarball_uri(), self._chroot_dir, keep_permissions=True)
141
142 def prepare_chroot(self):
143 ret = GLIUtility.spawn("cp -L /etc/resolv.conf /mnt/gentoo/etc/resolv.conf")
144 if not GLIUtility.exitsuccess(ret):
145 raise GLIException("CopyError", 'warning','preinstall','Could not copy resolv.conf!')
146
147 ret = GLIUtility.spawn("mount -t proc none /mnt/gentoo /proc")
148 if not GLIUtility.exitsuccess(ret):
149 raise GLIException("MountError", 'fatal','preinstall','Could not mount /proc')
150
151 # Set USE flags here
152 # might want to rewrite/use _edit_config from the GLIInstallTemplate
153 # Then you should be done... at least with the preinstall.
154
155 def install_packages(self):
156 "Will install any extra software!"
157
158 installpackages = self._install_profile.get_install_packages()
159 for package in installpackages:
160 status = self._emerge(package)
161 if not GLIUtility.exitsuccess(status):
162 raise GLIException("InstallPackagesError", 'warning', 'install_packages', "Could not emerge " + package + "!")
163
164 # **************************************************************************************
165
166
167 def mount_local_partitions(self):
168 "Mounts all partitions that are on the local machine"
169 #{ 1: { 'end': 1999871, 'format': False, 'mb': 0,
170 #'mountopts': '', 'mountpoint': '', 'start': 63, 'type': 'linux-swap'},
171 #2: { 'end': 240121727, 'format': False, 'mb': 0, 'mountopts': '',
172 #'mountpoint': '', 'start': 1999872, 'type': 'ext3'}}
173 #{'/dev/hdz': {1: {'end': 4, 'mb': 0, 'format': False, 'start': 0, 'mountopts': '', 'mountpoint': '', 'type': 'ext2', 'minor': 1}, 2: {'end': 129, 'mb': 0, 'format': False, 'start': 5, 'mountopts': '', 'mountpoint': '', 'type': 'linux-swap', 'minor': 2}, 3: {'end': 12579, 'mb': 0, 'format': False, 'start': 130, 'mountopts': '', 'mountpoint': '', 'type': 'reiserfs', 'minor': 3}, 4: {'end': 24320, 'mb': 0, 'format': False, 'start': 12580, 'mountopts': '', 'mountpoint': '', 'type': 'reiserfs', 'minor': 4}}}
174
175 parts = self._install_profile.get_partition_tables()
176 for device in parts:
177 #in parts['/dev/hda']
178 for partition in parts[device]:
179 print parts[device][partition]
180 mountpoint = parts[device][partition]['mountpoint']
181 mountopts = parts[device][partition]['mountopts']
182 minor = str(parts[device][partition]['minor'])
183 partition_type = parts[device][partition]['type']
184 if mountpoint:
185 if mountopts:
186 mountopts = "-o "+mountopts+" "
187 if partition_type:
188 partition_type = "-t "+partition_type+" "
189 ret = GLIUtility.spawn("mount "+partition_type+mountopts+device+minor+" "+self._chroot_dir+mountpoint)
190 if not GLIUtility.exitsuccess(ret):
191 raise GLIException("MountError", 'fatal','mount_local_partitions','Could not mount a partition')
192 if partition_type == "linux-swap":
193 ret = GLIUtility.spawn("swapon "+device+minor)
194 if not GLIUtility.exitsuccess(ret):
195 raise GLIException("MountError", 'warning','mount_local_partitions','Could not activate swap')
196 def mount_network_shares(self):
197 "Mounts all network shares to the local machine"
198 pass
199
200 def fetch_sources_from_cd(self):
201 "Gets sources from CD (required for non-network installation)"
202 pass
203
204 def fetch_grp_from_cd(self):
205 "Gets grp binary packages from CD (required for non-network binary installation)"
206 pass
207
208 def configure_make_conf(self):
209 "Configures make.conf"
210
211 # Get make.conf options
212 options = self._install_profile.get_make_conf()
213
214 # For each configuration option...
215 for key in options.keys():
216
217 # Add/Edit it into make.conf
218 self._edit_config(self._chroot_dir + "/etc/make.conf", key, options[key])
219
220 def install_portage_tree(self):
221 "Get/update the portage tree"
222
223 # Check the type of portage tree fetching we'll do
224 # If it is custom, follow the path to the custom tarball and unpack it
225 if self._install_profile.get_portage_tree_sync_type() == "custom":
226
227 # Get portage tree info
228 portage_tree_snapshot_uri = self._install_profile.get_portage_tree_snapshot_uri()
229
230 # Fetch and unpack the tarball
231 GLIUtility.fetch_and_unpack_tarball(portage_tree_snapshot_uri, self._chroot_dir + "/usr/", self._chroot_dir + "/")
232 if not GLIUtility.is_file(self._chroot_dir+"/usr/portage/distfiles"):
233 exitstatus = GLIUtility.spawn("mkdir /usr/portage/distfiles",chroot=self._chroot_dir)
234 if exitstatus != 0:
235 raise GLIException("MkdirError", 'fatal','install_portage_tree',"Making the distfiles directory failed.")
236 #!!!!!!!!!!FIXME THIS SHOULD NOT BE HERE
237 exitstatus = GLIUtility.spawn("cp /mnt/cdrom/distfiles/* "+self._chroot_dir+"/usr/portage/distfiles/")
238 if exitstatus != 0:
239 raise GLIException("PortageError", 'fatal','install_portage_tree',"Failed to copy the distfiles to the new system")
240 # If the type is webrsync, then run emerge-webrsync
241 elif self._install_profile.get_portage_tree_sync_type() == "webrsync":
242 exitstatus = GLIUtility.spawn("emerge-webrsync", chroot=self._chroot_dir)
243 if exitstatus != 0:
244 raise GLIException("EmergeWebRsyncError", 'fatal','install_portage_tre', "Failed to retrieve portage tree!")
245
246 # Otherwise, just run emerge sync
247 else:
248 exitstatus = self._emerge("sync")
249 if exitstatus != 0:
250 raise GLIException("EmergeSyncError", 'fatal','install_portage_tree', "Failed to retrieve portage tree!")
251
252 def set_timezone(self):
253 "Sets the timezone for the new environment"
254 # Set symlink
255 if not os.access(self._chroot_dir + "/etc/localtime", os.W_OK):
256 os.symlink(self._chroot_dir + "/usr/share/zoneinfo/" + self._install_profile.get_time_zone(), self._chroot_dir + "/etc/localtime")
257 if not (self._install_profile.get_time_zone() == "UTC"):
258 self._edit_config(self._chroot_dir + "/etc/rc.conf", "CLOCK", "local")
259
260 def configure_fstab(self):
261 "Configures fstab"
262 newfstab = ""
263 partitions = self._install_profile.get_fstab()
264 for partition in partitions:
265 if not GLIUtility.is_file(self._chroot_dir+partition):
266 exitstatus = GLIUtility.spawn("mkdir " + partition, True)
267 if exitstatus != 0:
268 raise GLIException("MkdirError", 'fatal','configure_fstab', "Making the mount point failed!")
269 newfstab += partitions[partition][0] + "\t " + partition + "\t " + partitions[partition][1]
270 newfstab += "\t " + partitions[partition][2] + "\t "
271 if partition == "/boot":
272 newfstab += "1 2\n"
273 elif partition == "/":
274 newfstab += "0 1\n"
275 else:
276 newfstab += "0 0\n"
277 newfstab += "none /proc proc defaults 0 0\n"
278 newfstab += "none /dev/shm tmpfs defaults 0 0\n"
279 if GLIUtility.is_device("/dev/cdroms/cdrom0"):
280 newfstab += "/dev/cdroms/cdrom0 /mnt/cdrom auto noauto,user 0 0\n"
281
282 for netmount in self._install_profile.get_network_mounts():
283 if netmount['type'] == "nfs":
284 newfstab += netmount['host'] + ":" + netmount['export'] + "\t" + netmount['mountpoint'] + "\tnfs\t" + netmount['mountopts'] + "\t0 0\n"
285
286 file_name = self._chroot_dir + "/etc/fstab"
287 try:
288 shutil.move(file_name, file_name + ".OLDdefault")
289 except:
290 pass
291 f = open(file_name, 'w')
292 f.writelines(newfstab)
293 f.close()
294
295
296 def emerge_kernel_sources(self):
297 "Fetches desired kernel sources"
298 exitstatus = self._emerge(self._install_profile.get_kernel_source_pkg())
299 if exitstatus != 0:
300 raise GLIException("EmergeKernelSourcesError", 'warning','emerge_kernel_sources',"Could not retrieve kernel sources!")
301 try:
302 os.stat(self._chroot_dir + "/usr/src/linux")
303 except:
304 kernels = os.listdir(self._chroot_dir+"/usr/src")
305 found_a_kernel = False
306 counter = 0
307 while not found_a_kernel:
308 if kernels[counter][0:6]=="linux-":
309 exitstatus = GLIUtility.spawn("ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux",chroot=self._chroot_dir)
310 found_a_kernel = True
311 else:
312 counter = counter + 1
313
314 def build_kernel(self):
315 "Builds kernel"
316 exitstatus = self._emerge("genkernel")
317 if exitstatus != 0:
318 raise GLIException("EmergeGenKernelError", 'warning','build_kernel', "Could not emerge genkernel!")
319
320 # Null the genkernel_options
321 genkernel_options = ""
322
323 # Get the uri to the kernel config
324 kernel_config_uri = self._install_profile.get_kernel_config_uri()
325
326 # If the uri for the kernel config is not null, then
327 if kernel_config_uri != "":
328 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/root/kernel_config")
329 genkernel_options = genkernel_options + " --kernel-config=/root/kernel_config"
330
331 # Decide whether to use bootsplash or not
332 if self._install_profile.get_kernel_bootsplash():
333 genkernel_options = genkernel_options + " --bootsplash"
334 else:
335 genkernel_options = genkernel_options + " --no-bootsplash"
336
337 # This is code to choose whether or not genekernel will build an initrd or not
338 # Genkernel currently does not support this
339 #if self._install_profile.get_kernel_initrd():
340 # pass
341 #else:
342 # pass
343
344 # Run genkernel in chroot
345 print "genkernel all " + genkernel_options
346 exitstatus = GLIUtility.spawn("genkernel all " + genkernel_options, chroot=self._chroot_dir)
347 if exitstatus != 0:
348 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build kernel!")
349
350 def install_logging_daemon(self):
351 "Installs and sets up logger"
352 # Get loggin daemon info
353 logging_daemon_pkg = self._install_profile.get_logging_daemon_pkg()
354 if logging_daemon_pkg:
355 # Emerge Logging Daemon
356 exitstatus = self._emerge(logging_daemon_pkg)
357 if exitstatus != 0:
358 raise GLIException("LoggingDaemonError", 'warning','install_logging_daemon', "Could not emerge " + logging_daemon_pkg + "!")
359
360 # Add Logging Daemon to default runlevel
361 self._add_to_runlevel(logging_daemon_pkg)
362
363 def install_cron_daemon(self):
364 "Installs and sets up cron"
365 # Get cron daemon info
366 cron_daemon_pkg = self._install_profile.get_cron_daemon_pkg()
367 if cron_daemon_pkg:
368 # Emerge Cron Daemon
369 exitstatus = self._emerge(cron_daemon_pkg)
370 if exitstatus != 0:
371 raise GLIException("CronDaemonError", 'warning', 'install_cron_daemon', "Could not emerge " + cron_daemon_pkg + "!")
372
373 # Add Cron Daemon to default runlevel
374 self._add_to_runlevel(cron_daemon_pkg)
375
376 # If the Cron Daemon is not vixie-cron, run crontab
377 if cron_daemon_pkg != "vixie-cron":
378 exitstatus = GLIUtility.spawn("crontab /etc/crontab", chroot=self._chroot_dir)
379 if exitstatus != 0:
380 raise GLIException("CronDaemonError", 'warning', 'install_cron_daemon', "Failure making crontab!")
381
382 def install_filesystem_tools(self):
383 "Installs and sets up fstools"
384 # Get the list of file system tools to be installed
385 filesystem_tools = self._install_profile.get_filesystem_tools_pkgs()
386
387 # If the fstools var is a str, convert it to a list
388 if type(filesystem_tools) == str:
389 filesystem_tools = [ filesystem_tools ]
390
391 # For each fstool package in the list, install it
392 for package in filesystem_tools:
393 exitstatus = self._emerge(package)
394 if exitstatus != 0:
395 raise GLIException("FilesystemToolsError", 'warning', 'install_filesystem_tools', "Could not emerge " + package + "!")
396
397 def install_rp_pppoe(self):
398 "Installs rp-pppoe"
399 # If user wants us to install rp-pppoe, then do so
400 if self._install_profile.get_install_rp_pppoe():
401 exitstatus = self._emerge("rp-pppoe")
402 if exitstatus != 0:
403 raise GLIException("RP_PPPOEError", 'warning', 'install_rp_pppoe', "Could not emerge rp-pppoe!")
404
405 # Should we add a section here to automatically configure rp-pppoe?
406 # I think it should go into the setup_network_post section
407 # What do you guys think?
408
409 def install_pcmcia_cs(self):
410 "Installs and sets up pcmcia-cs"
411 # If user wants us to install pcmcia-cs, then do so
412 if self._install_profile.get_install_pcmcia_cs():
413 exitstatus = self._emerge("pcmcia-cs")
414 if exitstatus != 0:
415 raise GLIException("PCMCIA_CSError", 'warning', 'install_pcmcia_cs', "Could not emerge pcmcia-cs!")
416
417 # Add pcmcia-cs to the default runlevel
418 self._add_to_runlevel(pcmcia)
419
420 def update_config_files(self):
421 "Runs etc-update (overwriting all config files), then re-configures the modified ones"
422 # Run etc-update overwriting all config files
423 status = GLIUtility.spawn('echo "-5" | etc-update', chroot=self._chroot_dir)
424 if not GLIUtility.exit_success(status):
425 raise GLIException("EtcUpdateError", 'warning', 'update_config_files', "Could not update config files!")
426
427 self.configure_make_conf()
428 self.configure_fstab()
429
430 def configure_rc_conf(self):
431 "Configures rc.conf"
432 # Get make.conf options
433 options = self._install_profile.get_rc_conf()
434
435 # For each configuration option...
436 for key in options.keys():
437
438 # Add/Edit it into rc.conf
439 self._edit_config(self._chroot_dir + "/etc/rc.conf", key, options[key])
440
441 def setup_network_post(self):
442 "Sets up the network for the first boot"
443 # Get hostname, domainname and nisdomainname
444 hostname = self._install_profile.get_hostname()
445 domainname = self._install_profile.get_domainname()
446 nisdomainname = self._install_profile.get_nisdomainname()
447
448 # Write the hostname to the hostname file
449 open(self._chroot_dir + "/etc/hostname", "w").write(hostname + "\n")
450
451 # Write the domainname to the nisdomainname file
452 if domainname:
453 open(self._chroot_dir + "/etc/dnsdomainname", "w").write(domainname + "\n")
454
455 # Write the nisdomainname to the nisdomainname file
456 if nisdomainname:
457 open(self._chroot_dir + "/etc/nisdomainname", "w").write(nisdomainname + "\n")
458
459 #
460 # EDIT THE /ETC/HOSTS FILE
461 #
462
463 # The address we are editing is 127.0.0.1
464 hosts_ip = "127.0.0.1"
465
466 # If the hostname is localhost
467 if hostname == "localhost":
468 # If a domainname is set
469 if domainname:
470 hosts_line = hostname + "." + domainname + "\t" + hostname
471 else:
472 hosts_line = hostname
473 # If the hostname is not localhost
474 else:
475 # If a domainname is set
476 if domainname:
477 hosts_line = hostname + "." + domainname + "\t" + hostname + "\tlocalhost"
478 else:
479 hosts_line = "localhost\t" + hostname
480
481 # Write to file
482 self._edit_config(self._chroot_dir + "/etc/hosts", hosts_ip, hosts_line, True, '\t', False)
483
484 #
485 # SET DEFAULT GATEWAY
486 #
487
488 # Get default gateway
489 default_gateway = self._install_profile.get_default_gateway()
490
491 # If the default gateway exists, add it
492 if default_gateway:
493 self._edit_config(self._chroot_dir + "/etc/conf.d/net", "gateway", default_gateway)
494
495 #
496 # SET RESOLV INFO
497 #
498
499 # Get dns servers
500 dns_servers = self._install_profile.get_dns_servers()
501
502 # Clear the list
503 resolv_output = []
504
505 # If dns servers are set
506 if dns_servers:
507
508
509 # Parse each dns server
510 for dns_server in dns_servers:
511 # Add the server to the output
512 resolv_output.append("nameserver " + dns_server +"\n")
513
514 # If the domainname is set, then also output it
515 if domainname:
516 resolv_output.append("search " + domainname + "\n")
517
518 # Output to file
519 resolve_conf = open(self._chroot_dir + "/etc/resolv.conf", "w")
520 resolve_conf.writelines(resolv_output)
521 resolve_conf.close()
522
523 #
524 # PARSE INTERFACES
525 #
526
527 # Fetch interfaces
528 interfaces = self._install_profile.get_network_interfaces()
529
530 # Parse each interface
531 for interface in interfaces.keys():
532
533 # If we are going to load the network at boot...
534 if interfaces[interface][2]:
535
536 # Add it to the default runlevel
537 self._add_to_runlevel("net."+interface)
538
539 # Set what kind of interface it is
540 interface_type = interface[:3]
541
542 # Check to see if there is a startup script for this interface, if there isn't link to the proper script
543 try:
544 os.stat(self._chroot_dir + "/etc/init.d/net." + interface)
545 except:
546 os.symlink(self._chroot_dir + "/etc/init.d/net." + interface_type + "0", self._chroot_dir + "/etc/init.d/net." + interface)
547
548 #
549 # ETHERNET
550 #
551 if interface_type == "eth":
552
553 #
554 # STATIC IP
555 #
556 # If the post-install device info is not None, then it is a static ip addy
557 if interfaces[interface][1]:
558 ip = interfaces[interface][0]
559 broadcast = interfaces[interface][1]
560 netmask = interfaces[interface][2]
561 # aliases = interfaces[interface][1][3]
562 # alias_ips = []
563 # alias_broadcasts = []
564 # alias_netmasks = []
565
566 # Write the static ip config to /etc/conf.d/net
567 self._edit_config(self._chroot_dir + "/etc/conf.d/net", "iface_" + interface, ip + " broadcast " + broadcast + " netmask " + netmask)
568
569 # If aliases are set
570 # if aliases:
571
572 # Parse aliases to format alias info
573 # for alias in aliases:
574 # alias_ips.append(alias[0])
575 # alias_broadcasts.append(alias[1])
576 # alias_netmasks.append(allias[2])
577
578 # Once the alias info has been gathered, then write it out
579 # Alias ips first
580 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "alias_" + interface, string.join(alias_ips))
581 # Alias broadcasts next
582 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "broadcast_" + interface, string.join(alias_broadcasts))
583 # Alias netmasks last
584 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "netmask_" + interface, string.join(alias_netmasks))
585
586 #
587 # DHCP IP
588 #
589 else:
590 self._edit_config(self._chroot_dir + "/etc/conf.d/net", "iface_" + interface, "dhcp")
591
592 def set_root_password(self):
593 "Sets the root password"
594 status = GLIUtility.spawn('echo "root:' + self._install_profile.get_root_pass_hash() + '" | chpasswd -e', chroot=self._chroot_dir)
595 if not GLIUtility.exit_success(status):
596 raise GLIException("SetRootPasswordError", 'warning', 'set_root_password', "Failure to set root password!")
597
598 def set_users(self):
599 "Sets up the new users for the system"
600 # Loop for each user
601 for user in self._install_profile.get_users():
602
603 # Get values from the tuple
604 username = user[0]
605 password_hash = user[1]
606 groups = user[2]
607 shell = user[3]
608 home_dir = user[4]
609 uid = user[5]
610 comment = user[6]
611
612 options = [ "-m", "-p " + password_hash ]
613
614 # If the groups are specified
615 if groups:
616
617 # If just one group is listed as a string, make it a list
618 if groups == str:
619 groups = [ groups ]
620
621 # If only 1 group is listed
622 if len(groups) == 1:
623 options.append("-G " + groups[0])
624
625 # If there is more than one group
626 elif len(groups) > 1:
627 options.append('-G "' + string.join(groups, ",") + '"')
628
629 # If a shell is specified
630 if shell:
631 options.append("-s " + shell)
632
633 # If a home dir is specified
634 if home_dir:
635 options.append("-d " + home_dir)
636
637 # If a UID is specified
638 if uid:
639 options.append("-u " + str(uid))
640
641 # If a comment is specified
642 if comment:
643 options.append('-c "' + comment + '"')
644
645 # Add the user
646 exitstatus = GLIUtility.spawn('useradd ' + string.join(options) + ' ' + username, chroot=self._chroot_dir)
647 if not GLIUtility.exit_success(exitstatus):
648 raise GLIException("AddUserError", 'warning', 'set_users', "Failure to add user " + username)
649
650 def install_bootloader(self):
651 "THIS FUNCTION MUST BE DONE BY THE INDIVIDUAL ARCH"
652 pass
653
654 def _cylinders_to_sectors(self, minor, start, end, sectors_in_cylinder):
655 cylinders = int(end) - int(start) + 1
656 total_sectors = cylinders * int(sectors_in_cylinder)
657 start_sector = int(start) * sectors_in_cylinder
658 end_sector = start_sector + total_sectors - 1
659 if int(minor) == 1 and start_sector == 0: start_sector = 63
660 return (start_sector, end_sector)
661
662 def _sectors_to_megabytes(self, sectors, sector_bytes=512):
663 return float((float(sectors) * sector_bytes)/ float(1024*1024))
664
665 def _sectors_to_bytes(self, sectors, sector_bytes=512):
666 return (int(sectors) * sector_bytes)
667
668 def _run_parted_command(self, device, cmd):
669 parted_output = commands.getoutput("parted -s " + device + " " + cmd)
670 print "parted -s " + device + " " + cmd
671
672 def _add_partition(self, device, start, end, type, fs):
673 start = self._sectors_to_megabytes(start)
674 end = self._sectors_to_megabytes(end)
675 self._run_parted_command(device, "mkpart " + type + " " + fs + " " + str(start) + " " + str(end))
676 if type == "ntfs":
677 pass
678 elif type == "ext2" or type == "ext3":
679 pass
680 else:
681 pass
682
683 def do_partitioning(self):
684 import GLIStorageDevice, parted, pprint
685
686 devices_old = {}
687 parts_old = {}
688 parts_new = self._install_profile.get_partition_tables()
689 drives = GLIStorageDevice.detect_devices()
690 drives.sort()
691 for drive in drives:
692 devices_old[drive] = GLIStorageDevice.Device(drive)
693 devices_old[drive].set_partitions_from_disk()
694 for part in devices_old.keys(): parts_old[part] = devices_old[part].get_install_profile_structure()
695
696 pp = pprint.PrettyPrinter(indent=4)
697 pp.pprint(parts_old)
698 pp.pprint(parts_new)
699
700 for dev in parts_old.keys():
701 parts_active = []
702 parts_lba = []
703 print "\nProcessing " + dev + "..."
704 parted_dev = parted.PedDevice.get(dev)
705 parted_disk = parted.PedDisk.new(parted_dev)
706 last_partition_touched = 0
707 sectors_in_cylinder = devices_old[dev]._sectors_in_cylinder
708 # First pass to delete old partitions that aren't resized
709 for part in parts_old[dev]:
710 oldpart = parts_old[dev][part]
711 old_start, old_end = self._cylinders_to_sectors(part, oldpart['start'], oldpart['end'], sectors_in_cylinder)
712 matchingminor = 0
713 for new_part in parts_new[dev]:
714 tmppart = parts_new[dev][new_part]
715 new_start, new_end = self._cylinders_to_sectors(new_part, tmppart['start'], tmppart['end'], sectors_in_cylinder)
716 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) == int(oldpart['end']):
717 matchingminor = new_part
718 print " Deleting old minor " + str(part) + " to be recreated later"
719 self._run_parted_command(dev, "rm " + str(part))
720 break
721 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
722 matchingminor = new_part
723 print " Ignoring old minor " + str(part) + " to resize later"
724 break
725 if not matchingminor:
726 print " No match found...deleting partition " + str(part)
727 self._run_parted_command(dev, "rm " + str(part))
728 else:
729 if parted_disk.get_partition(part).get_flag(1): # Active/boot
730 print " Partition " + str(part) + " was active...noted"
731 parts_active.append(int(matchingminor))
732 if parted_disk.get_partition(part).get_flag(7): # LBA
733 print " Partition " + str(part) + " was LBA...noted"
734 parts_lba.append(int(matchingminor))
735 # Second pass to resize old partitions that need to be resized
736 print " Second pass..."
737 for part in parts_old[dev]:
738 oldpart = parts_old[dev][part]
739 old_start, old_end = self._cylinders_to_sectors(part, oldpart['start'], oldpart['end'], sectors_in_cylinder)
740 for new_part in parts_new[dev]:
741 tmppart = parts_new[dev][new_part]
742 new_start, new_end = self._cylinders_to_sectors(new_part, tmppart['start'], tmppart['end'], sectors_in_cylinder)
743 if int(tmppart['start']) == int(oldpart['start']) and tmppart['format'] == False and tmppart['type'] == oldpart['type'] and int(tmppart['end']) != int(oldpart['end']):
744 print " Resizing old minor " + str(part) + " from " + str(oldpart['start']) + "-" + str(oldpart['end'])+ " to " + str(tmppart['start']) + "-" + str(tmppart['end'])
745 type = tmppart['type']
746 device = dev
747 minor = part
748 start = int(new_start)
749 end = int(new_end)
750 if type == "ext2" or type == "ext3":
751 total_sectors = end - start + 1
752 commands.getstatus("resize2fs " + device + str(minor) + " " + str(total_sectors) + "s")
753 print "resize2fs " + device + str(minor) + " " + str(total_sectors) + "s"
754 elif type == "ntfs":
755 total_sectors = end - start + 1
756 total_bytes = int(self._sectors_to_bytes(total_sectors))
757 commands.getstatus("ntfsresize --size " + str(total_bytes) + " " + device + str(minor))
758 print "ntfsresize --size " + str(total_bytes) + " " + device + str(minor)
759 else:
760 start = float(self._sectors_to_megabytes(start))
761 end = float(self._sectors_to_megabytes(end))
762 self._run_parted_command(device, "resize " + str(minor) + " " + str(start) + " " + str(end))
763 print " Deleting old minor " + str(part) + " to be recreated in 3rd pass"
764 self._run_parted_command(dev, "rm " + str(part))
765 break
766 # Third pass to create new partition table
767 print " Third pass..."
768 for part in parts_new[dev]:
769 newpart = parts_new[dev][part]
770 new_start, new_end = self._cylinders_to_sectors(part, newpart['start'], newpart['end'], sectors_in_cylinder)
771 if newpart['type'] == "extended":
772 print " Adding extended partition from " + str(newpart['start']) + " to " + str(newpart['end'])
773 self._add_partition(dev, new_start, new_end, "extended", "")
774 elif int(part) < 5:
775 print " Adding primary partition from " + str(newpart['start']) + " to " + str(newpart['end'])
776 self._add_partition(dev, new_start, new_end, "primary", newpart['type'])
777 elif int(part) > 4:
778 print " Adding logical partition from " + str(newpart['start']) + " to " + str(newpart['end'])
779 self._add_partition(dev, new_start, new_end, "logical", newpart['type'])
780 if int(part) in parts_active and not newpart['format']:
781 print " Partition was previously active...setting"
782 self._run_parted_command(dev, "set " + str(part) + " boot on")
783 if int(part) in parts_lba and not newpart['format']:
784 print " Partition was previously LBA...setting"
785 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