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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 214 - (hide annotations) (download) (as text)
Wed Jan 5 08:26:42 2005 UTC (13 years, 7 months ago) by codeman
Original Path: trunk/src/GLIArchitectureTemplate.py
File MIME type: text/x-python
File size: 32053 byte(s)
changes to mount_local_partitions

1 samyron 79 """
2     Gentoo Linux Installer
3    
4 codeman 214 $Id: GLIArchitectureTemplate.py,v 1.23 2005/01/05 08:26:42 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 codeman 209 import GLIUtility, os, string, sys, shutil
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 agaffney 108 def __init__(self,configuration=None, install_profile=None, client_controller=None):
22 codeman 200 self._client_configuration = configuration
23 samyron 79 self._install_profile = install_profile
24 agaffney 108 self._cc = client_controller
25 samyron 79
26 samyron 102 # 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 codeman 200 self._chroot_dir = self._client_configuration.get_root_mount_point()
30 samyron 102
31 samyron 79 # 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 agaffney 136 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 codeman 200
62 samyron 79
63 agaffney 136 def get_install_steps(self):
64     return self._install_steps
65    
66 codeman 201 def notify_frontend(self, type, data):
67     self._cc.addNotification(type, data)
68    
69 samyron 79 # 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 codeman 201 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 codeman 209 def _emerge(self, package, binary=False, binary_only=False):
81 codeman 201 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 codeman 209 def _edit_config(self, filename, newvalues, delimeter='=', quotes_around_value=True):
89 codeman 201 """
90     filename = file to be editted
91     newvlaues = a dictionary of VARIABLE:VALUE pairs
92     """
93 codeman 209 if not GLIUtility.is_file(filename):
94     raise GLIException("NoSuchFileError", 'notice','_edit_config',filename + ' does not exist!')
95 codeman 201
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 samyron 79 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 codeman 201 exitstatus = GLIUtility.spawn("/usr/portage/scripts/bootstrap.sh", chroot=self._chroot_dir)
127 samyron 79 if not GLIUtility.exitsuccess(exitstatus):
128 samyron 186 raise GLIException("Stage1Error", 'fatal','stage1', "Bootstrapping failed!")
129 codeman 201
130 samyron 79 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 codeman 201 exitstatus = self._emerge("system")
134 samyron 79 if not GLIUtility.exitsuccess(exitstatus):
135 samyron 186 raise GLIException("Stage2Error", 'fatal','stage2', "Building the system failed!")
136 samyron 79
137 agaffney 133 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 samyron 79
142 agaffney 133 def prepare_chroot(self):
143 codeman 201 ret = GLIUtility.spawn("cp -L /etc/resolv.conf /mnt/gentoo/etc/resolv.conf")
144 samyron 79 if not GLIUtility.exitsuccess(ret):
145 codeman 201 raise GLIException("CopyError", 'warning','preinstall','Could not copy resolv.conf!')
146 samyron 79
147 samyron 86 ret = GLIUtility.spawn("mount -t proc none /mnt/gentoo /proc")
148 samyron 79 if not GLIUtility.exitsuccess(ret):
149 samyron 186 raise GLIException("MountError", 'fatal','preinstall','Could not mount /proc')
150 samyron 79
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 samyron 102 def install_packages(self):
156     "Will install any extra software!"
157 codeman 201
158 samyron 102 installpackages = self._install_profile.get_install_packages()
159     for package in installpackages:
160 codeman 201 status = self._emerge(package)
161     if not GLIUtility.exitsuccess(status):
162 samyron 186 raise GLIException("InstallPackagesError", 'warning', 'install_packages', "Could not emerge " + package + "!")
163 samyron 102
164     # **************************************************************************************
165    
166    
167     def mount_local_partitions(self):
168     "Mounts all partitions that are on the local machine"
169 codeman 213 #{ 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 codeman 214 #print parts[device][partition]
180 codeman 213 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 codeman 214 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 codeman 213 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 samyron 102 def mount_network_shares(self):
201     "Mounts all network shares to the local machine"
202 codeman 204 pass
203 codeman 201
204 samyron 102 def fetch_sources_from_cd(self):
205     "Gets sources from CD (required for non-network installation)"
206 codeman 204 pass
207 samyron 102
208     def fetch_grp_from_cd(self):
209     "Gets grp binary packages from CD (required for non-network binary installation)"
210 codeman 204 pass
211 codeman 201
212 samyron 102 def configure_make_conf(self):
213     "Configures make.conf"
214 codeman 201
215 samyron 102 # 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 codeman 201 self._edit_config(self._chroot_dir + "/etc/make.conf", key, options[key])
223 samyron 102
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 codeman 201 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 samyron 102 if exitstatus != 0:
239 samyron 186 raise GLIException("MkdirError", 'fatal','install_portage_tree',"Making the distfiles directory failed.")
240 codeman 201 #!!!!!!!!!!FIXME THIS SHOULD NOT BE HERE
241     exitstatus = GLIUtility.spawn("cp /mnt/cdrom/distfiles/* "+self._chroot_dir+"/usr/portage/distfiles/")
242 samyron 102 if exitstatus != 0:
243 samyron 186 raise GLIException("PortageError", 'fatal','install_portage_tree',"Failed to copy the distfiles to the new system")
244 samyron 102 # If the type is webrsync, then run emerge-webrsync
245     elif self._install_profile.get_portage_tree_sync_type() == "webrsync":
246 codeman 201 exitstatus = GLIUtility.spawn("emerge-webrsync", chroot=self._chroot_dir)
247 samyron 102 if exitstatus != 0:
248 samyron 186 raise GLIException("EmergeWebRsyncError", 'fatal','install_portage_tre', "Failed to retrieve portage tree!")
249 samyron 102
250     # Otherwise, just run emerge sync
251     else:
252     exitstatus = self._emerge("sync")
253     if exitstatus != 0:
254 samyron 186 raise GLIException("EmergeSyncError", 'fatal','install_portage_tree', "Failed to retrieve portage tree!")
255 samyron 102
256     def set_timezone(self):
257     "Sets the timezone for the new environment"
258     # Set symlink
259 codeman 201 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 samyron 102 if not (self._install_profile.get_time_zone() == "UTC"):
262 codeman 201 self._edit_config(self._chroot_dir + "/etc/rc.conf", "CLOCK", "local")
263 samyron 102
264     def configure_fstab(self):
265     "Configures fstab"
266     newfstab = ""
267     partitions = self._install_profile.get_fstab()
268     for partition in partitions:
269 codeman 201 if not GLIUtility.is_file(self._chroot_dir+partition):
270 codeman 214 exitstatus = GLIUtility.spawn("mkdir " + self._chroot_dir + partition)
271 samyron 102 if exitstatus != 0:
272 samyron 186 raise GLIException("MkdirError", 'fatal','configure_fstab', "Making the mount point failed!")
273 samyron 102 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 agaffney 161
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 samyron 102
290 codeman 201 file_name = self._chroot_dir + "/etc/fstab"
291 samyron 102 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 samyron 186 raise GLIException("EmergeKernelSourcesError", 'warning','emerge_kernel_sources',"Could not retrieve kernel sources!")
305 samyron 102 try:
306 codeman 201 os.stat(self._chroot_dir + "/usr/src/linux")
307 samyron 102 except:
308 codeman 201 kernels = os.listdir(self._chroot_dir+"/usr/src")
309 samyron 102 found_a_kernel = False
310     counter = 0
311     while not found_a_kernel:
312     if kernels[counter][0:6]=="linux-":
313 codeman 201 exitstatus = GLIUtility.spawn("ln -s /usr/src/"+kernels[counter]+ " /usr/src/linux",chroot=self._chroot_dir)
314 samyron 102 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 samyron 186 raise GLIException("EmergeGenKernelError", 'warning','build_kernel', "Could not emerge genkernel!")
323 samyron 102
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 codeman 201 GLIUtility.get_uri(kernel_config_uri, self._chroot_dir + "/root/kernel_config")
333 samyron 102 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 codeman 201 exitstatus = GLIUtility.spawn("genkernel all " + genkernel_options, chroot=self._chroot_dir)
351 samyron 102 if exitstatus != 0:
352 samyron 186 raise GLIException("KernelBuildError", 'fatal', 'build_kernel', "Could not build kernel!")
353 samyron 102
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 samyron 186 raise GLIException("LoggingDaemonError", 'warning','install_logging_daemon', "Could not emerge " + logging_daemon_pkg + "!")
363 samyron 102
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 samyron 186 raise GLIException("CronDaemonError", 'warning', 'install_cron_daemon', "Could not emerge " + cron_daemon_pkg + "!")
376 samyron 102
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 codeman 201 exitstatus = GLIUtility.spawn("crontab /etc/crontab", chroot=self._chroot_dir)
383 samyron 102 if exitstatus != 0:
384 samyron 186 raise GLIException("CronDaemonError", 'warning', 'install_cron_daemon', "Failure making crontab!")
385 samyron 102
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 samyron 186 raise GLIException("FilesystemToolsError", 'warning', 'install_filesystem_tools', "Could not emerge " + package + "!")
400 samyron 102
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 samyron 186 raise GLIException("RP_PPPOEError", 'warning', 'install_rp_pppoe', "Could not emerge rp-pppoe!")
408 samyron 102
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 samyron 186 raise GLIException("PCMCIA_CSError", 'warning', 'install_pcmcia_cs', "Could not emerge pcmcia-cs!")
420 samyron 102
421     # Add pcmcia-cs to the default runlevel
422 codeman 201 self._add_to_runlevel(pcmcia)
423 samyron 102
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 samyron 186 raise GLIException("EtcUpdateError", 'warning', 'update_config_files', "Could not update config files!")
430 samyron 102
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 codeman 209 self._edit_config(self._chroot_dir + "/etc/rc.conf", key, options[key])
444 samyron 102
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 codeman 201 open(self._chroot_dir + "/etc/hostname", "w").write(hostname + "\n")
454 samyron 102
455     # Write the domainname to the nisdomainname file
456     if domainname:
457 codeman 201 open(self._chroot_dir + "/etc/dnsdomainname", "w").write(domainname + "\n")
458 samyron 102
459     # Write the nisdomainname to the nisdomainname file
460     if nisdomainname:
461 codeman 201 open(self._chroot_dir + "/etc/nisdomainname", "w").write(nisdomainname + "\n")
462 samyron 102
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 codeman 201 self._edit_config(self._chroot_dir + "/etc/hosts", hosts_ip, hosts_line, True, '\t', False)
487 samyron 102
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 codeman 201 self._edit_config(self._chroot_dir + "/etc/conf.d/net", "gateway", default_gateway)
498 samyron 102
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 codeman 201 resolve_conf = open(self._chroot_dir + "/etc/resolv.conf", "w")
524 samyron 102 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 codeman 202 self._add_to_runlevel("net."+interface)
542 samyron 102
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 codeman 201 os.stat(self._chroot_dir + "/etc/init.d/net." + interface)
549 samyron 102 except:
550 codeman 201 os.symlink(self._chroot_dir + "/etc/init.d/net." + interface_type + "0", self._chroot_dir + "/etc/init.d/net." + interface)
551 samyron 102
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 codeman 201 self._edit_config(self._chroot_dir + "/etc/conf.d/net", "iface_" + interface, ip + " broadcast " + broadcast + " netmask " + netmask)
572 samyron 102
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 codeman 201 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "alias_" + interface, string.join(alias_ips))
585 samyron 102 # Alias broadcasts next
586 codeman 201 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "broadcast_" + interface, string.join(alias_broadcasts))
587 samyron 102 # Alias netmasks last
588 codeman 201 # self._edit_config(self._chroot_dir + "/etc/conf.d/net", "netmask_" + interface, string.join(alias_netmasks))
589 samyron 102
590     #
591     # DHCP IP
592     #
593     else:
594 codeman 201 self._edit_config(self._chroot_dir + "/etc/conf.d/net", "iface_" + interface, "dhcp")
595 samyron 102
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 samyron 186 raise GLIException("SetRootPasswordError", 'warning', 'set_root_password', "Failure to set root password!")
601 samyron 102
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 samyron 186 raise GLIException("AddUserError", 'warning', 'set_users', "Failure to add user " + username)
653 agaffney 111
654 codeman 213 def install_bootloader(self):
655     "THIS FUNCTION MUST BE DONE BY THE INDIVIDUAL ARCH"
656     pass
657    
658 agaffney 126 def _cylinders_to_sectors(self, minor, start, end, sectors_in_cylinder):
659 agaffney 127 cylinders = int(end) - int(start) + 1
660     total_sectors = cylinders * int(sectors_in_cylinder)
661     start_sector = int(start) * sectors_in_cylinder
662 agaffney 111 end_sector = start_sector + total_sectors - 1
663 agaffney 127 if int(minor) == 1 and start_sector == 0: start_sector = 63
664 agaffney 111 return (start_sector, end_sector)
665    
666 agaffney 126 def _sectors_to_megabytes(self, sectors, sector_bytes=512):
667 agaffney 111 return float((float(sectors) * sector_bytes)/ float(1024*1024))
668    
669 agaffney 131 def _sectors_to_bytes(self, sectors, sector_bytes=512):
670     return (int(sectors) * sector_bytes)
671 agaffney 111
672 agaffney 126 def _run_parted_command(self, device, cmd):
673 agaffney 127 parted_output = commands.getoutput("parted -s " + device + " " + cmd)
674 agaffney 111 print "parted -s " + device + " " + cmd
675    
676 agaffney 126 def _add_partition(self, device, start, end, type, fs):
677 agaffney 118 start = self._sectors_to_megabytes(start)
678     end = self._sectors_to_megabytes(end)
679 agaffney 127 self._run_parted_command(device, "mkpart " + type + " " + fs + " " + str(start) + " " + str(end))
680 agaffney 117 if type == "ntfs":
681     pass
682     elif type == "ext2" or type == "ext3":
683     pass
684     else:
685     pass
686 agaffney 111
687     def do_partitioning(self):
688 agaffney 127 import GLIStorageDevice, parted, pprint
689 agaffney 111
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 agaffney 127 pp = pprint.PrettyPrinter(indent=4)
701     pp.pprint(parts_old)
702     pp.pprint(parts_new)
703    
704 agaffney 111 for dev in parts_old.keys():
705     parts_active = []
706 agaffney 123 parts_lba = []
707 agaffney 111 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 agaffney 118 old_start, old_end = self._cylinders_to_sectors(part, oldpart['start'], oldpart['end'], sectors_in_cylinder)
716 agaffney 111 matchingminor = 0
717     for new_part in parts_new[dev]:
718     tmppart = parts_new[dev][new_part]
719 agaffney 118 new_start, new_end = self._cylinders_to_sectors(new_part, tmppart['start'], tmppart['end'], sectors_in_cylinder)
720 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']):
721 agaffney 111 matchingminor = new_part
722     print " Deleting old minor " + str(part) + " to be recreated later"
723 agaffney 118 self._run_parted_command(dev, "rm " + str(part))
724 agaffney 111 break
725 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']):
726 agaffney 111 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 agaffney 118 self._run_parted_command(dev, "rm " + str(part))
732 agaffney 111 else:
733 agaffney 123 if parted_disk.get_partition(part).get_flag(1): # Active/boot
734 agaffney 111 print " Partition " + str(part) + " was active...noted"
735 agaffney 127 parts_active.append(int(matchingminor))
736 agaffney 123 if parted_disk.get_partition(part).get_flag(7): # LBA
737     print " Partition " + str(part) + " was LBA...noted"
738 agaffney 127 parts_lba.append(int(matchingminor))
739 agaffney 111 # 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 agaffney 118 old_start, old_end = self._cylinders_to_sectors(part, oldpart['start'], oldpart['end'], sectors_in_cylinder)
744 agaffney 111 for new_part in parts_new[dev]:
745     tmppart = parts_new[dev][new_part]
746 agaffney 118 new_start, new_end = self._cylinders_to_sectors(new_part, tmppart['start'], tmppart['end'], sectors_in_cylinder)
747 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']):
748 agaffney 111 print " Resizing old minor " + str(part) + " from " + str(oldpart['start']) + "-" + str(oldpart['end'])+ " to " + str(tmppart['start']) + "-" + str(tmppart['end'])
749 agaffney 118 type = tmppart['type']
750     device = dev
751     minor = part
752 agaffney 127 start = int(new_start)
753     end = int(new_end)
754 agaffney 118 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 agaffney 131 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 agaffney 118 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 agaffney 111 print " Deleting old minor " + str(part) + " to be recreated in 3rd pass"
768 agaffney 118 self._run_parted_command(dev, "rm " + str(part))
769 agaffney 111 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 agaffney 118 new_start, new_end = self._cylinders_to_sectors(part, newpart['start'], newpart['end'], sectors_in_cylinder)
775 agaffney 111 if newpart['type'] == "extended":
776     print " Adding extended partition from " + str(newpart['start']) + " to " + str(newpart['end'])
777 agaffney 127 self._add_partition(dev, new_start, new_end, "extended", "")
778     elif int(part) < 5:
779 agaffney 111 print " Adding primary partition from " + str(newpart['start']) + " to " + str(newpart['end'])
780 agaffney 127 self._add_partition(dev, new_start, new_end, "primary", newpart['type'])
781     elif int(part) > 4:
782 agaffney 111 print " Adding logical partition from " + str(newpart['start']) + " to " + str(newpart['end'])
783 agaffney 127 self._add_partition(dev, new_start, new_end, "logical", newpart['type'])
784     if int(part) in parts_active and not newpart['format']:
785 agaffney 111 print " Partition was previously active...setting"
786 agaffney 118 self._run_parted_command(dev, "set " + str(part) + " boot on")
787 agaffney 127 if int(part) in parts_lba and not newpart['format']:
788 agaffney 123 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