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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 202 - (hide annotations) (download) (as text)
Tue Jan 4 22:20:25 2005 UTC (13 years, 7 months ago) by codeman
Original Path: trunk/src/GLIArchitectureTemplate.py
File MIME type: text/x-python
File size: 29798 byte(s)
oops forgot to click save

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