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

Contents of /trunk/src/GLIArchitectureTemplate.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 214 - (show annotations) (download) (as text)
Wed Jan 5 08:26:42 2005 UTC (13 years, 9 months ago) by codeman
File MIME type: text/x-python
File size: 32053 byte(s)
changes to mount_local_partitions

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