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

Contents of /trunk/src/GLIInstallProfile.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1291 - (hide annotations) (download) (as text)
Fri Feb 10 02:01:58 2006 UTC (14 years, 8 months ago) by agaffney
File MIME type: text/x-python
File size: 67197 byte(s)
  src/GLIPortage.py:
  use tar to transfer files from image dir to /mnt/gentoo instead of 'cp -a'
  src/GLIStorageDevice.py,src/GLIInstallProfile.py,src/templates/x86AT.py:
  'resized' flag

1 npmccallum 32 """
2 codeman 851 # Copyright 1999-2005 Gentoo Foundation
3     # This source code is distributed under the terms of version 2 of the GNU
4     # General Public License as published by the Free Software Foundation, a copy
5     # of which can be found in the main directory of this project.
6 npmccallum 32 Gentoo Linux Installer
7    
8 agaffney 1291 $Id: GLIInstallProfile.py,v 1.84 2006/02/10 02:01:58 agaffney Exp $
9 npmccallum 32
10     The GLI module contains all classes used in the Gentoo Linux Installer (or GLI).
11 codeman 594 The InstallProfile contains all information related to the new system to be
12     installed.
13    
14     PROCEDURE TO ADD NEW VARIABLES:
15     1. Add a handler to the list. If the variable has children make sure you do it right.
16     Look at the existing structure to get an idea.
17     2. Create a section for the two or three functions.
18     3. Create the get_variable_name and set_variable_name functions.
19     Ensure the set function has correct error checking.
20     4. If a simple value, add to the list in the general serialize() function.
21     If more complex add a serialize_variable_name to the list of special cases.
22     Then add the serialize_variable_name function to the section for the variable.
23 npmccallum 32 """
24    
25     import string
26     import xml.sax
27     import os
28     import GLIUtility
29 samyron 88 import SimpleXMLParser
30 codeman 593 import xml.dom.minidom
31 agaffney 596 import GLIStorageDevice
32 samyron 88 from GLIException import *
33 npmccallum 32
34 agaffney 510 ##
35     # This class contains all the settings used during the install
36 samyron 88 class InstallProfile:
37 npmccallum 32 """
38     An object representation of a profile.
39     InstallProfile is an object representation of a parsed installation
40     profile file.
41     """
42    
43 agaffney 509 ##
44 codeman 594 # Initializes all variables to default values and adds handlers.
45 esammer 51 def __init__(self):
46 samyron 88
47 esammer 51 # Configuration information - profile data
48 codeman 594 # All variables must be declared here with a default value to ensure
49     # the XML will correctly serialize.
50 codeman 754 self._cron_daemon_pkg = "vixie-cron"
51     self._logging_daemon_pkg = "syslog-ng"
52 codeman 1077 self._boot_device = ""
53 esammer 51 self._boot_loader_mbr = True
54     self._boot_loader_pkg = ""
55 samyron 57 self._kernel_modules = []
56 esammer 51 self._kernel_config_uri = ""
57 codeman 985 self._kernel_build_method = "genkernel"
58 agaffney 461 self._bootloader_kernel_args = ""
59 codeman 194 self._kernel_initrd = True
60 esammer 51 self._kernel_bootsplash = False
61 codeman 985 self._kernel_source_pkg = "livecd-kernel"
62 esammer 51 self._users = []
63     self._root_pass_hash = ""
64 codeman 625 self._time_zone = "UTC"
65 codeman 361 self._stage_tarball_uri = ""
66 codeman 985 self._install_stage = 3
67 esammer 51 self._portage_tree_sync_type = "sync"
68 codeman 361 self._portage_tree_snapshot_uri = ""
69 esammer 51 self._domainname = "localdomain"
70     self._hostname = "localhost"
71 agaffney 528 self._http_proxy = ""
72     self._ftp_proxy = ""
73     self._rsync_proxy = ""
74 esammer 51 self._nisdomainname = ""
75     self._partition_tables = {}
76 agaffney 160 self._network_mounts = []
77 robbat2 680 self._temp_partition_table = {} # temp
78 esammer 51 self._network_interfaces = {}
79     self._make_conf = {}
80 agaffney 716 # self._rc_conf = {}
81 esammer 51 self._install_rp_pppoe = False
82     self._filesystem_tools = ()
83     self._install_pcmcia_cs = False
84 samyron 68 self._dns_servers = ()
85 samyron 88 self._default_gateway = ()
86 samyron 89 self._install_packages = ()
87 codeman 222 self._services = ()
88 robbat2 650 self._mta_pkg = ""
89 codeman 222 self._grp_install = False
90 agaffney 525 self._post_install_script_uri = ""
91 agaffney 716 self._etc_files = {}
92     self._temp_etc_file = {}
93 agaffney 755 self._dynamic_stage3 = False
94 codeman 907 self._install_distcc = False
95 codeman 594 self.xmldoc = ""
96 npmccallum 32
97 codeman 594 # Parser handler calls. For each XML attribute and children of that attribute, a handler is needed.
98 agaffney 596 self._parser = SimpleXMLParser.SimpleXMLParser()
99     self._parser.addHandler('gli-profile/bootloader', self.set_boot_loader_pkg)
100 codeman 1082 self._parser.addHandler('gli-profile/boot-device', self.set_boot_device)
101 agaffney 596 self._parser.addHandler('gli-profile/bootloader-kernel-args', self.set_bootloader_kernel_args)
102     self._parser.addHandler('gli-profile/bootloader-mbr', self.set_boot_loader_mbr)
103     self._parser.addHandler('gli-profile/cron-daemon', self.set_cron_daemon_pkg)
104     self._parser.addHandler('gli-profile/default-gateway', self.set_default_gateway)
105     self._parser.addHandler('gli-profile/dns-servers', self.set_dns_servers)
106     self._parser.addHandler('gli-profile/domainname', self.set_domainname)
107 agaffney 755 self._parser.addHandler('gli-profile/dynamic-stage3', self.set_dynamic_stage3)
108 agaffney 716 self._parser.addHandler('gli-profile/etc-files/file', self.add_etc_files_file, call_on_null=True)
109     self._parser.addHandler('gli-profile/etc-files/file/entry', self.add_etc_files_file_entry, call_on_null=True)
110 agaffney 596 self._parser.addHandler('gli-profile/ftp-proxy', self.set_ftp_proxy)
111     self._parser.addHandler('gli-profile/grp-install', self.set_grp_install)
112     self._parser.addHandler('gli-profile/hostname', self.set_hostname)
113     self._parser.addHandler('gli-profile/http-proxy', self.set_http_proxy)
114 codeman 907 self._parser.addHandler('gli-profile/install-distcc', self.set_install_distcc)
115 agaffney 596 self._parser.addHandler('gli-profile/install-packages', self.set_install_packages)
116     self._parser.addHandler('gli-profile/install-pcmcia-cs', self.set_install_pcmcia_cs)
117     self._parser.addHandler('gli-profile/install-rp-pppoe', self.set_install_rp_pppoe)
118     self._parser.addHandler('gli-profile/install-stage', self.set_install_stage)
119     self._parser.addHandler('gli-profile/kernel-bootsplash', self.set_kernel_bootsplash)
120 robbat2 679 self._parser.addHandler('gli-profile/kernel-build-method', self.set_kernel_build_method)
121 agaffney 596 self._parser.addHandler('gli-profile/kernel-config', self.set_kernel_config_uri)
122     self._parser.addHandler('gli-profile/kernel-initrd', self.set_kernel_initrd)
123     self._parser.addHandler('gli-profile/kernel-modules/module', self.add_kernel_module)
124     self._parser.addHandler('gli-profile/kernel-source', self.set_kernel_source_pkg)
125     self._parser.addHandler('gli-profile/logging-daemon', self.set_logging_daemon_pkg)
126 agaffney 716 # self._parser.addHandler('gli-profile/make-conf/variable', self.make_conf_add_var)
127 robbat2 650 self._parser.addHandler('gli-profile/mta', self.set_mta_pkg)
128 agaffney 596 self._parser.addHandler('gli-profile/network-interfaces/device', self.add_network_interface)
129     self._parser.addHandler('gli-profile/network-mounts/netmount', self.add_netmount, call_on_null=True)
130     self._parser.addHandler('gli-profile/nisdomainname', self.set_nisdomainname)
131     self._parser.addHandler('gli-profile/partitions/device', self.add_partitions_device, call_on_null=True)
132     self._parser.addHandler('gli-profile/partitions/device/partition', self.add_partitions_device_partition, call_on_null=True)
133     self._parser.addHandler('gli-profile/portage-snapshot', self.set_portage_tree_snapshot_uri)
134     self._parser.addHandler('gli-profile/portage-tree-sync', self.set_portage_tree_sync_type)
135     self._parser.addHandler('gli-profile/post-install-script-uri', self.set_post_install_script_uri)
136 agaffney 716 # self._parser.addHandler('gli-profile/rc-conf/variable', self.rc_conf_add_var)
137 agaffney 596 self._parser.addHandler('gli-profile/root-pass-hash', self.set_root_pass_hash)
138     self._parser.addHandler('gli-profile/rsync-proxy', self.set_rsync_proxy)
139     self._parser.addHandler('gli-profile/services', self.set_services)
140     self._parser.addHandler('gli-profile/stage-tarball', self.set_stage_tarball_uri)
141     self._parser.addHandler('gli-profile/time-zone', self.set_time_zone)
142     self._parser.addHandler('gli-profile/users/user', self.add_user)
143 codeman 594
144 agaffney 509 ##
145 codeman 594 # Parses the given filename populating the client_configuration.
146 agaffney 509 # @param filename Parameter description
147 samyron 88 def parse(self, filename):
148     self._parser.parse(filename)
149 npmccallum 32
150 agaffney 509 ##
151 codeman 594 # This method serializes the configuration data and output a nice XML document.
152     # NOTE: this method currently does not serialize: _partition_tables or _kernel_modules
153     def serialize(self):
154 codeman 1082 xmltab = { 'boot-device': self.get_boot_device,
155     'bootloader': self.get_boot_loader_pkg,
156 codeman 594 'bootloader-mbr': self.get_boot_loader_mbr,
157     'bootloader-kernel-args': self.get_bootloader_kernel_args,
158     'cron-daemon': self.get_cron_daemon_pkg,
159     'domainname': self.get_domainname,
160 agaffney 755 'dynamic-stage3': self.get_dynamic_stage3,
161 codeman 594 'ftp-proxy': self.get_ftp_proxy,
162     'grp-install': self.get_grp_install,
163     'hostname': self.get_hostname,
164     'http-proxy': self.get_http_proxy,
165 codeman 907 'install-distcc': self.get_install_distcc,
166 codeman 594 'install-pcmcia-cs': self.get_install_pcmcia_cs,
167     'install-rp-pppoe': self.get_install_rp_pppoe,
168     'install-stage': self.get_install_stage,
169     'kernel-bootsplash': self.get_kernel_bootsplash,
170 robbat2 679 'kernel-build-method': self.get_kernel_build_method,
171 codeman 594 'kernel-config': self.get_kernel_config_uri,
172     'kernel-initrd': self.get_kernel_initrd,
173     'kernel-source': self.get_kernel_source_pkg,
174     'logging-daemon': self.get_logging_daemon_pkg,
175 robbat2 653 'mta': self.get_mta_pkg,
176 codeman 594 'nisdomainname': self.get_nisdomainname,
177     'portage-snapshot': self.get_portage_tree_snapshot_uri,
178     'portage-tree-sync': self.get_portage_tree_sync_type,
179     'post-install-script-uri': self.get_post_install_script_uri,
180     'root-pass-hash': self.get_root_pass_hash,
181     'rsync-proxy': self.get_rsync_proxy,
182     'stage-tarball': self.get_stage_tarball_uri,
183     'time-zone': self.get_time_zone,
184     }
185 agaffney 596 self.xmldoc = "<?xml version=\"1.0\"?>"
186     self.xmldoc += "<gli-profile>"
187 npmccallum 32
188 codeman 594 # Normal cases
189     for key in xmltab.keys():
190 agaffney 596 self.xmldoc += "<%s>%s</%s>" % (key, xmltab[key](), key)
191 npmccallum 32
192 codeman 594 # Special cases
193     self.serialize_default_gateway()
194     self.serialize_dns_servers()
195     self.serialize_install_packages()
196     self.serialize_kernel_modules()
197 agaffney 716 # self.serialize_make_conf()
198 codeman 594 self.serialize_network_interfaces()
199     self.serialize_network_mounts()
200     self.serialize_partition_tables()
201 agaffney 716 # self.serialize_rc_conf()
202 codeman 594 self.serialize_services()
203     self.serialize_users()
204 agaffney 716 self.serialize_etc_files()
205 codeman 593
206 agaffney 596 self.xmldoc += "</gli-profile>"
207 codeman 593
208 agaffney 596 dom = xml.dom.minidom.parseString(self.xmldoc)
209 codeman 594 return dom.toprettyxml()
210    
211     ############################################################################
212     ############################################################################
213 codeman 1077 #### Boot Device Selection
214    
215     ##
216     # boot_device is a string to decide which device to install the bootloader to
217     # @param xml_path Used internally by the XML parser. Should be None when calling directly
218     # @param boot_loader_pkg boot device with full /dev
219     # @param xml_attr not used here
220    
221     def set_boot_device(self, xml_path, boot_device, xml_attr):
222     #check data type
223     if type(boot_device) != str:
224     raise GLIException("BootDevice", 'fatal', 'set_boot_device', "Input must be type 'string'!")
225     self._boot_device = boot_device
226    
227     ##
228     # returns boot_device
229     def get_boot_device(self):
230     return self._boot_device
231    
232     ############################################################################
233 codeman 594 #### Bootloader Package Selection
234 codeman 593
235 agaffney 509 ##
236 codeman 594 # boot_loader_pkg is a string to decide which boot loader to install. (ie. 'grub')
237     # @param xml_path Used internally by the XML parser. Should be None when calling directly
238     # @param boot_loader_pkg bootloader package name (like grub or lilo)
239     # @param xml_attr not used here
240     def set_boot_loader_pkg(self, xml_path, boot_loader_pkg, xml_attr):
241     # Check data type
242     if type(boot_loader_pkg) != str:
243     raise GLIException("BootLoaderPKG", 'fatal', 'set_boot_loader_pkg', "Input must be type 'string'!")
244     self._boot_loader_pkg = boot_loader_pkg
245 npmccallum 32
246 agaffney 509 ##
247 codeman 594 # returns boot_loader_pkg
248     def get_boot_loader_pkg(self):
249     return self._boot_loader_pkg
250    
251     ############################################################################
252     #### Bootloader Kernel Arguments
253    
254     ##
255     # FIXME: agaffney, what error checking needs to be done here?
256     # kernel_args are the arguments to pass the kernel at boot from the bootloader.
257 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
258 codeman 594 # @param bootloader_kernel_args FIXME no idea.
259     # @param xml_attr not used here.
260     def set_bootloader_kernel_args(self, xml_path, bootloader_kernel_args, xml_attr):
261     self._bootloader_kernel_args = bootloader_kernel_args
262 npmccallum 32
263 agaffney 509 ##
264 codeman 594 # Returns kernel arguments
265     def get_bootloader_kernel_args(self):
266     return self._bootloader_kernel_args
267    
268     ############################################################################
269     #### Bootloader Installation to MBR
270 npmccallum 32
271 agaffney 509 ##
272 codeman 594 # boot_loader_mbr is a bool. True installs boot loader to MBR.
273     # False installs boot loader to the boot or root partition.
274 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
275 codeman 594 # @param boot_loader_mbr
276 agaffney 509 # @param xml_attr Parameter description
277 samyron 88 def set_boot_loader_mbr(self, xml_path, boot_loader_mbr, xml_attr):
278 npmccallum 32 # Check data type
279     if type(boot_loader_mbr) != bool:
280 samyron 37 if type(boot_loader_mbr) == str:
281     boot_loader_mbr = GLIUtility.strtobool(boot_loader_mbr)
282     else:
283 samyron 189 raise GLIException("BootLoaderMBRError", 'fatal', 'set_boot_loader_mbr', "Input must be type 'bool'!")
284 npmccallum 32 self._boot_loader_mbr = boot_loader_mbr
285    
286 agaffney 509 ##
287 codeman 594 # returns boot_loader_mbr
288     def get_boot_loader_mbr(self):
289     return self._boot_loader_mbr
290 npmccallum 32
291 codeman 594 ############################################################################
292     #### Cron Daemon Package
293    
294 agaffney 509 ##
295 codeman 594 # cron_daemon_pkg is a string to determine which cron daemon to install and configure (ie. 'vixie-cron')
296 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
297 codeman 594 # @param cron_daemon_pkg package name
298     # @param xml_attr Not used here.
299     def set_cron_daemon_pkg(self, xml_path, cron_daemon_pkg, xml_attr):
300 npmccallum 32 # Check data type
301 codeman 594 if type(cron_daemon_pkg) != str:
302     raise GLIException("CronDaemonPKGError", 'fatal', 'set_cron_daemon_pkg', "Input must be type 'string'!")
303     self._cron_daemon_pkg = cron_daemon_pkg
304 npmccallum 32
305 agaffney 509 ##
306 codeman 594 # Returns the cron daemon pkg name
307     def get_cron_daemon_pkg(self):
308     return self._cron_daemon_pkg
309 npmccallum 32
310 codeman 594 ############################################################################
311     #### Network Gateway
312    
313 agaffney 509 ##
314 codeman 594 # Set the default gateway for the post-installed system.
315     # The format of the input is: <default-gateway interface="interface name">ip of gateway</default-gateway>
316     # It saves this information in the following format: (<interface>, <ip of gateway>)
317 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
318 codeman 594 # @param gateway gateway ip address
319 agaffney 509 # @param xml_attr Parameter description
320 codeman 594 def set_default_gateway(self, xml_path, gateway, xml_attr):
321     if not GLIUtility.is_realstring(gateway):
322     raise GLIException('DefaultGatewayError', 'fatal', 'set_default_gateway', "The gateway must be a non-empty string!")
323     if not 'interface' in xml_attr.keys():
324     raise GLIException('DefaultGatewayError', 'fatal', 'set_default_gateway', 'No interface information specified!')
325 samyron 57
326 codeman 594 interface = str(xml_attr['interface'])
327 samyron 57
328 codeman 594 if not GLIUtility.is_eth_device(interface):
329     raise GLIException('DefaultGatewayError', 'fatal', 'set_default_gateway', "Invalid device!")
330     if not GLIUtility.is_ip(gateway):
331     raise GLIException("DefaultGateway", 'fatal', 'set_default_gateway', "The IP Provided is not valid!")
332     self._default_gateway = (interface, gateway)
333    
334 agaffney 509 ##
335 codeman 594 # Returns the default gateway
336     def get_default_gateway(self):
337     return self._default_gateway
338 npmccallum 32
339 agaffney 509 ##
340 codeman 594 # Serializes default_gateway
341     def serialize_default_gateway(self):
342     if self.get_default_gateway() != ():
343     gw = self.get_default_gateway()
344 agaffney 596 self.xmldoc += "<default-gateway interface=\"%s\">%s</default-gateway>" % (gw[0], gw[1])
345 npmccallum 32
346 codeman 594
347     ############################################################################
348     #### DNS Servers
349    
350 agaffney 509 ##
351 codeman 594 # Set the DNS servers for the post-installed system.
352 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
353 codeman 594 # @param dns_servers a tuple or space-separated list of dns servers
354 agaffney 509 # @param xml_attr Parameter description
355 codeman 594 def set_dns_servers(self, xml_path, dns_servers, xml_attr):
356     if type(dns_servers) == tuple:
357     dns_servers = dns_servers[0:3]
358     elif type(dns_servers) == str:
359     dns_servers = string.split(dns_servers)
360     else:
361     raise GLIException("DnsServersError", 'fatal', 'set_dns_servers', "Invalid input!")
362 npmccallum 32
363 codeman 594 for server in dns_servers:
364     if not GLIUtility.is_ip(server):
365     raise GLIException("DnsServersError", 'fatal', 'set_dns_servers', server + " must be a valid IP address!")
366 npmccallum 32
367 codeman 594 self._dns_servers = dns_servers
368 npmccallum 32
369 agaffney 509 ##
370 codeman 594 # This returns a tuple of the form: (<nameserver 1>, <nameserver 2>, <nameserver 3>)
371     def get_dns_servers(self):
372     return self._dns_servers
373    
374 agaffney 509 ##
375 codeman 594 # Serializes DNS Servers
376     def serialize_dns_servers(self):
377     if self.get_dns_servers() != ():
378 agaffney 596 self.xmldoc += "<dns-servers>"
379     self.xmldoc += string.join(self.get_dns_servers(), ' ')
380     self.xmldoc += "</dns-servers>"
381 codeman 594
382     ############################################################################
383     #### Domainname
384    
385     ##
386     # domainname is a string containing the domainname for the new system. (ie. 'mydomain.com'; NOT FQDN)
387 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
388 codeman 594 # @param domainname string of the domain name
389     # @param xml_attr not used here
390     def set_domainname(self, xml_path, domainname, xml_attr):
391     # Check type
392     if type(domainname) != str:
393     raise GLIException("DomainnameError", 'fatal', 'set_domainname', "Must be a string!")
394     self._domainname = domainname
395 agaffney 457
396 agaffney 509 ##
397 codeman 594 # Returns domainname
398     def get_domainname(self):
399     return self._domainname
400 codeman 777
401     ###################################################################
402 agaffney 717 ##
403 agaffney 755 # Set whether or not to build the stage3 from the LiveCD
404     # @param xml_path Used internally by the XML parser. Should be None when calling directly
405     # @param dynamic_stage3 True/False
406     # @param xml_attr not used here
407     def set_dynamic_stage3(self, xml_path, dynamic_stage3, xml_attr):
408 codeman 777 if type(dynamic_stage3) != bool:
409     if type(dynamic_stage3) == str:
410     self._dynamic_stage3 = GLIUtility.strtobool(dynamic_stage3)
411     else:
412     raise GLIException("DynamicStage3", 'fatal', 'set_dynamic_stage3', "Input must be type 'bool'!")
413     else:
414     self._dynamic_stage3 = dynamic_stage3
415 agaffney 755
416     ##
417     # Returns whether or not to build the stage3 from the LiveCD
418     def get_dynamic_stage3(self):
419     return self._dynamic_stage3
420    
421     ##
422 agaffney 717 # Used internally for XML parsing...adds an entry to a file
423     # @param xml_path Used internally by the XML parser. Should be None when calling directly
424     # @param value uhh...the value
425     # @param attr used for XML parsing
426 agaffney 716 def add_etc_files_file_entry(self, xml_path, value, attr):
427     if 'name' in attr.getNames():
428     if not self._temp_etc_file:
429     self._temp_etc_file = {}
430     self._temp_etc_file[attr['name']] = value
431     else:
432     if not self._temp_etc_file:
433     self._temp_etc_file = []
434     self._temp_etc_file.append(value)
435    
436 agaffney 717 ##
437     # Used internally for XML parsing...adds a file
438     # @param xml_path Used internally by the XML parser. Should be None when calling directly
439     # @param unused this should be obvious
440     # @param attr used for XML parsing
441 agaffney 716 def add_etc_files_file(self, xml_path, unused, attr):
442     self._etc_files[attr['name']] = self._temp_etc_file
443     self._temp_etc_file = None
444    
445 agaffney 717 ##
446     # Returns etc_files structure
447 agaffney 716 def get_etc_files(self):
448     return self._etc_files
449    
450 agaffney 717 ##
451     # Replaces etc_files structure with one passed in
452     # @param etc_files new etc_files structure
453 agaffney 716 def set_etc_files(self, etc_files):
454     self._etc_files = etc_files
455    
456 agaffney 717 ##
457     # Serializes the etc_files structure
458 agaffney 716 def serialize_etc_files(self):
459     self.xmldoc += "<etc-files>"
460     for etc_file in self._etc_files:
461     self.xmldoc += "<file name=\"%s\">" % etc_file
462     for entry in self._etc_files[etc_file]:
463     self.xmldoc += "<entry"
464     if isinstance(self._etc_files[etc_file], dict):
465     self.xmldoc += " name=\"%s\">%s" % (entry, self._etc_files[etc_file][entry])
466     else:
467     self.xmldoc += ">%s" % entry
468     self.xmldoc += "</entry>"
469     self.xmldoc += "</file>"
470     self.xmldoc += "</etc-files>"
471    
472 codeman 870
473 codeman 594 ############################################################################
474     #### FTP Proxy
475 npmccallum 32
476 agaffney 509 ##
477 codeman 594 # FTP proxy is a uri containing a proxy if needed for ftp traffic. (ie. 'ftp://myhost.mydomain:myport')
478     # @param xml_path Used internally by the XML parser. Should be None when calling directly
479     # @param ftp_proxy ftp proxy address
480     # @param xml_attr not used here
481     def set_ftp_proxy(self, xml_path, ftp_proxy, xml_attr):
482     # Check type
483 agaffney 1153 if ftp_proxy and not GLIUtility.is_uri(ftp_proxy):
484 codeman 594 raise GLIException("FTPProxyError", 'fatal', 'set_ftp_proxy', "Must be a uri!")
485     self._ftp_proxy = ftp_proxy
486 npmccallum 32
487 agaffney 509 ##
488 codeman 594 # Returns FTP proxy
489     def get_ftp_proxy(self):
490     return self._ftp_proxy
491    
492     ############################################################################
493     #### GRP Install
494    
495     ##
496     # grp_install is a bool. True installs GRP. False doesn't.
497 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
498 codeman 594 # @param grp_install boolean
499 agaffney 509 # @param xml_attr Parameter description
500 codeman 594 def set_grp_install(self, xml_path, grp_install, xml_attr):
501     # Check data type
502     if type(grp_install) != bool:
503     if type(grp_install) == str:
504     grp_install = GLIUtility.strtobool(grp_install)
505 samyron 37 else:
506 codeman 594 raise GLIException("GRPInstall", 'fatal', 'set_grp_install', "Input must be type 'bool'!")
507     self._grp_install = grp_install
508 npmccallum 32
509 agaffney 509 ##
510 codeman 594 # returns grp_install
511     def get_grp_install(self):
512     return self._grp_install
513 npmccallum 32
514 codeman 594 ############################################################################
515     #### Hostname
516    
517 agaffney 509 ##
518 codeman 594 # Hostname is a string containing the hostname for the new system. (ie. 'myhost'; NOT 'myhost.mydomain.com')
519 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
520 codeman 594 # @param hostname string of hostname
521     # @param xml_attr not used here.
522     def set_hostname(self, xml_path, hostname, xml_attr):
523 npmccallum 32 # Check type
524 codeman 594 if type(hostname) != str:
525     raise GLIException("HostnameError", 'fatal', 'set_hostname', "Must be a string!")
526     self._hostname = hostname
527 npmccallum 32
528 agaffney 509 ##
529 codeman 594 # Returns hostname
530     def get_hostname(self):
531     return self._hostname
532 npmccallum 32
533 codeman 594 ############################################################################
534     #### HTTP Proxy
535    
536 agaffney 509 ##
537 codeman 594 # HTTP proxy is a URI containing a proxy if needed for http traffic. (ie. 'http://myhost.mydomain:myport')
538 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
539 codeman 594 # @param http_proxy http proxy address
540     # @param xml_attr not used here
541     def set_http_proxy(self, xml_path, http_proxy, xml_attr):
542     # Check type
543 agaffney 1153 if http_proxy and not GLIUtility.is_uri(http_proxy):
544 codeman 594 raise GLIException("HTTPProxyError", 'fatal', 'set_http_proxy', "Must be a uri!")
545     self._http_proxy = http_proxy
546 npmccallum 32
547 codeman 594 ##
548     # Returns HTTP proxy
549     def get_http_proxy(self):
550     return self._http_proxy
551 samyron 37
552 codeman 594 ############################################################################
553 codeman 907 #### Install Distcc
554    
555     ##
556     # This tells the installer whether or not to install the distcc package
557     # @param xml_path Used internally by the XML parser. Should be None when calling directly
558     # @param install_distcc boolean
559     # @param xml_attr Parameter description
560     def set_install_distcc(self, xml_path, install_distcc, xml_attr):
561     if type(install_distcc) != bool:
562     if type(install_distcc) == str:
563     install_distcc = GLIUtility.strtobool(install_distcc)
564     else:
565     raise GLIException("InstallDistcc", 'fatal', 'set_install_distcc', "Input must be type 'bool'!")
566    
567     self._install_distcc = install_distcc
568    
569     ##
570     # Returns the boolean _install_distcc
571     def get_install_distcc(self):
572     return self._install_distcc
573    
574     ############################################################################
575 codeman 1073 #### Install Package List
576     ##
577     # Returns the list of packages to include in the Extra Packages screens.
578     def get_install_package_list(self):
579     install_package_list = {
580     'Desktop': ("Popular Desktop Applications",
581 codeman 1284 {"bittorrent": "tool for distributing files via a distributed network of nodes",
582     "evolution": "A GNOME groupware application, a Microsoft Outlook workalike",
583     "gaim": "GTK Instant Messenger client",
584 codeman 1073 "gftp": "Gnome based FTP Client",
585 codeman 1284 "gimp": "GNU Image Manipulation Program",
586     "inkscape": "A SVG based generic vector-drawing program",
587     "koffice": "An integrated office suite for KDE, the K Desktop Environment",
588 codeman 1073 "mozilla": "The Mozilla Web Browser",
589     "mozilla-firefox": "The Mozilla Firefox Web Browser",
590     "mozilla-thunderbird": "Thunderbird Mail Client",
591     "mplayer": "Media Player for Linux",
592     "openoffice": "OpenOffice.org, a full office productivity suite.",
593     "openoffice-bin": "Same as OpenOffice but a binary package (no compiling!)",
594     "realplayer": "Real Media Player",
595 codeman 1284 "rhythmbox": "Music management and playback software for GNOME",
596     "vlc": "VLC media player - Video player and streamer",
597 codeman 1073 "xchat": "Graphical IRC Client",
598 codeman 1284 "xine-ui": "Xine movie player",
599 codeman 1073 "xmms": "X MultiMedia System" }),
600     'Servers': ("Applications often found on servers.",
601     {"apache": "Apache Web Server",
602 codeman 1284 "cups": "The Common Unix Printing System",
603     "exim": "A highly configurable, drop-in replacement for sendmail",
604 codeman 1073 "iptables": "Linux kernel (2.4+) firewall, NAT and packet mangling tools",
605 codeman 1284 "mod_php": "Apache module for PHP",
606     "mysql": "A fast, multi-threaded, multi-user SQL database server",
607     "postfix": "A fast and secure drop-in replacement for sendmail",
608     "postgresql": "sophisticated Object-Relational DBMS",
609 codeman 1073 "proftpd": "ProFTP Server",
610     "samba": "SAMBA client/server programs for UNIX",
611 codeman 1284 "sendmail": "Widely-used Mail Transport Agent (MTA)",
612 codeman 1073 "traceroute": "Utility to trace the route of IP packets" }),
613     'X11': ("Window managers and X selection.",
614 codeman 1284 {"xorg-x11": "An X11 implementation maintained by the X.Org Foundation",
615 codeman 1073 "gnome": "The Gnome Desktop Environment",
616     "kde": "The K Desktop Environment",
617     "blackbox": "A small, fast, full-featured window manager for X",
618     "enlightenment": "Enlightenment Window Manager",
619     "fluxbox": "Fluxbox is an X11 window manager featuring tabs and an iconbar",
620     "xfce4": "XFCE Desktop Environment" }),
621     'Misc': ("Miscellaneous Applications you may want.",
622 codeman 1284 {"emacs": "An incredibly powerful, extensible text editor",
623     "ethereal": "A commercial-quality network protocol analyzer",
624     "gkrellm": "Single process stack of various system monitors",
625     "gvim": "GUI version of the Vim text editor",
626     "keychain": "ssh-agent manager",
627 codeman 1073 "logrotate": "Rotates, compresses, and mails system logs",
628 codeman 1284 "ntp": "Network Time Protocol suite/programs",
629     "rdesktop": "A Remote Desktop Protocol Client",
630 codeman 1073 "slocate": "Secure way to index and quickly search for files on your system",
631 codeman 1284 "ufed": "Gentoo Linux USE flags editor",
632     "vim": "Vim, an improved vi-style text editor" }),
633 codeman 1073 'Recommended': ("Applications recommended by the GLI Team.",
634     {"anjuta": "A versatile IDE for GNOME",
635     "chkrootkit": "a tool to locally check for signs of a rootkit",
636     "crack-attack": "Addictive OpenGL-based block game",
637 codeman 1284 "gnupg": "The GNU Privacy Guard, a GPL pgp replacement",
638     "net-snmp": "Software for generating and retrieving SNMP data",
639 codeman 1073 "netcat": "the network swiss army knife",
640     "nmap": "A utility for network exploration or security auditing",
641 codeman 1284 "screen": "full-screen window manager that multiplexes between several processes",
642     "xpdf": "An X Viewer for PDF Files" })
643 codeman 1073 }
644     return install_package_list
645    
646     ############################################################################
647 codeman 594 #### Install Packages
648 npmccallum 32
649 codeman 594 ##
650     # Sets up the list of packages to be installed for the new system.
651     # @param xml_path Used internally by the XML parser. Should be None when calling directly
652     # @param install_packages The space-separated list of packages to install.
653     # @param xml_attr Parameter description
654     def set_install_packages(self, xml_path, install_packages, xml_attr):
655     if type(install_packages) == str:
656     install_packages = string.split(install_packages)
657 npmccallum 32 else:
658 codeman 594 raise GLIException("InstallPackagesError", 'fatal', 'set_install_packages', "Invalid input!")
659 npmccallum 32
660 codeman 594 for install_package in install_packages:
661     if not GLIUtility.is_realstring(install_package):
662     raise GLIException("InstallPackagesError", 'fatal', 'set_install_packages', install_package + " must be a valid string!")
663     self._install_packages = install_packages
664 npmccallum 32
665 agaffney 509 ##
666 codeman 594 # This returns a list of the packages
667     def get_install_packages(self):
668     return self._install_packages
669    
670 agaffney 509 ##
671 codeman 594 # Serializes install_packages
672     def serialize_install_packages(self):
673     if self.get_install_packages() != ():
674 agaffney 596 self.xmldoc += "<install-packages>"
675     self.xmldoc += string.join(self.get_install_packages(), ' ')
676     self.xmldoc += "</install-packages>"
677 npmccallum 32
678 codeman 594 ############################################################################
679     #### PCMCIA-CS
680 npmccallum 32
681 agaffney 509 ##
682 codeman 594 # This tells the installer whether or not to install the pcmcia_cs package
683 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
684 codeman 594 # @param install_pcmcia boolean
685 agaffney 509 # @param xml_attr Parameter description
686 codeman 594 def set_install_pcmcia_cs(self, xml_path, install_pcmcia, xml_attr):
687     if type(install_pcmcia) != bool:
688     if type(install_pcmcia) == str:
689     install_pcmcia = GLIUtility.strtobool(install_pcmcia)
690     else:
691     raise GLIException("InstallPcmciaCS", 'fatal', 'set_install_pcmcia_cs', "Input must be type 'bool'!")
692 npmccallum 32
693 codeman 594 self._install_pcmcia_cs = install_pcmcia
694 npmccallum 32
695 agaffney 509 ##
696 codeman 594 # Returns the boolean _install_pcmcia_cs
697     def get_install_pcmcia_cs(self):
698     return self._install_pcmcia_cs
699 npmccallum 32
700 codeman 594 ############################################################################
701     #### RP-PPPoE Installation
702 npmccallum 32
703 agaffney 509 ##
704 codeman 594 # Tell the installer whether or not to install the rp-pppoe package
705 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
706 codeman 594 # @param install_rp_pppoe boolean
707 agaffney 509 # @param xml_attr Parameter description
708 codeman 594 def set_install_rp_pppoe(self, xml_path, install_rp_pppoe, xml_attr):
709     if type(install_rp_pppoe) != bool:
710     if type(install_rp_pppoe) == str:
711     install_rp_pppoe = GLIUtility.strtobool(install_rp_pppoe)
712     else:
713     raise GLIException("InstallRP_PPPOE", 'fatal', 'set_install_rp_pppoe', "Invalid input!")
714 npmccallum 32
715 codeman 594 self._install_rp_pppoe = install_rp_pppoe
716 npmccallum 32
717 agaffney 509 ##
718 codeman 594 # Return the boolean value of _install_rp_pppoe
719     def get_install_rp_pppoe(self):
720     return self._install_rp_pppoe
721 npmccallum 32
722 codeman 594 ############################################################################
723     #### Install Stage
724    
725 agaffney 509 ##
726 codeman 594 # install_stage is a integer to define which stage install to use. Appropriate stages are 1-3.
727 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
728 codeman 594 # @param install_stage install stage number
729     # @param xml_attr not used here.
730 samyron 88 def set_install_stage(self, xml_path, install_stage, xml_attr):
731 npmccallum 32 # Check type
732     if type(install_stage) != int:
733 samyron 37 if type(install_stage) == str:
734     install_stage = int(install_stage)
735 samyron 155 else:
736 samyron 189 raise GLIException("InstallStageError", 'fatal', 'set_install_stage', "Must be an integer!")
737 npmccallum 32
738     # Check for stage bounds
739     if 0 < install_stage < 4:
740     self._install_stage = install_stage
741     else:
742 samyron 189 raise GLIException("InstallStageError", 'fatal', 'set_install_stage', "install_stage must be 1-3!")
743 npmccallum 32
744 agaffney 509 ##
745 codeman 594 # Returns install_stage
746     def get_install_stage(self):
747     return self._install_stage
748 npmccallum 32
749 codeman 594 ############################################################################
750     #### Kernel Bootsplash Option
751    
752 agaffney 509 ##
753 codeman 594 # kernel_bootsplash is a bool to determine whether or not to install bootsplash into the kernel.
754     # True builds in bootsplash support to the initrd.
755     # WARNING: kernel_source_pkg must contain a kernel with bootsplash support or the bootsplash will not appear.
756     # If you set this to true, it will build an initrd kernel even if you chose false for kernel_initrd!
757 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
758 codeman 594 # @param kernel_bootsplash boolean
759     # @param xml_attr not used here.
760     def set_kernel_bootsplash(self, xml_path, kernel_bootsplash, xml_attr):
761     # Check type
762     if type(kernel_bootsplash) != bool:
763     if type(kernel_bootsplash) == str:
764     kernel_bootsplash = GLIUtility.strtobool(kernel_bootsplash)
765     else:
766     raise GLIException("KernelBootsplashError", 'fatal', 'set_kernel_bootsplash', "Must be a bool!")
767 npmccallum 32
768 codeman 594 self._kernel_bootsplash = kernel_bootsplash
769    
770     ##
771     # Returns kernel_bootsplash
772     def get_kernel_bootsplash(self):
773     return self._kernel_bootsplash
774 robbat2 679
775     ############################################################################
776     #### Kernel Build Method
777    
778     ##
779     # kernel_build_method is a string specifying what build method you wish to use for the kernel.
780     # Can also be a http:// or ftp:// path.
781     # @param xml_path Used internally by the XML parser. Should be None when calling directly
782     # @param kernel_build_method URI of kernel .config file
783     # @param xml_attr not used here.
784     def set_kernel_build_method(self, xml_path, kernel_build_method, xml_attr):
785     # Check type
786     if type(kernel_build_method) != str:
787     raise GLIException("KernelBuildMethodError", 'fatal', 'set_kernel_build_method', "Must be a string!")
788    
789     self._kernel_build_method = kernel_build_method
790    
791     ##
792     # Returns kernel_build_method
793     def get_kernel_build_method(self):
794     return self._kernel_build_method
795 codeman 594
796     ############################################################################
797     #### Kernel Configuration URI
798    
799     ##
800     # kernel_config_uri is a string that is the path to the kernel config file you wish to use.
801     # Can also be a http:// or ftp:// path.
802     # @param xml_path Used internally by the XML parser. Should be None when calling directly
803     # @param kernel_config_uri URI of kernel .config file
804     # @param xml_attr not used here.
805     def set_kernel_config_uri(self, xml_path, kernel_config_uri, xml_attr):
806 npmccallum 32 # Check type
807 codeman 594 if type(kernel_config_uri) != str:
808     raise GLIException("KernelConfigURIError", 'fatal', 'set_kernel_config_uri', "Must be a string!")
809 npmccallum 32
810 codeman 594 # Check validity (now done in the FE)
811     #if not (kernel_config_uri):
812     # raise GLIException("KernelConfigURIError", 'fatal', 'set_kernel_config_uri', "Empty Kernel URI!")
813 samyron 37
814 codeman 594 self._kernel_config_uri = kernel_config_uri
815 samyron 37
816 agaffney 509 ##
817 codeman 594 # Returns kernel_config_uri
818     def get_kernel_config_uri(self):
819     return self._kernel_config_uri
820 npmccallum 32
821 codeman 594 ############################################################################
822     #### Kernel Initrd Option
823    
824 agaffney 509 ##
825 codeman 594 # kernel_initrd is a bool to determine whether or not to build an initrd kernel. False builds a non-initrd kernel.
826     # (overwritten by kernel_bootsplash; needs genkernel non-initrd support not yet present)
827 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
828 codeman 594 # @param kernel_initrd boolean
829     # @param xml_attr not used here
830     def set_kernel_initrd(self, xml_path, kernel_initrd, xml_attr):
831 npmccallum 32 # Check type
832 codeman 594 if type(kernel_initrd) != bool:
833     if type(kernel_initrd) == str:
834     kernel_initrd = GLIUtility.strtobool(kernel_initrd)
835     else:
836     raise GLIException("KernelInitRDError", 'fatal', 'set_kernel_initrd', "Must be a bool!")
837 npmccallum 32
838 codeman 594 self._kernel_initrd = kernel_initrd
839 npmccallum 32
840 agaffney 509 ##
841 codeman 594 # Returns kernel_initrd
842     def get_kernel_initrd(self):
843     return self._kernel_initrd
844 npmccallum 32
845 codeman 594 ############################################################################
846     #### Kernel Modules
847    
848 agaffney 509 ##
849 codeman 594 # Add a kernel module to the list of kernel modules
850 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
851 codeman 594 # @param kernel_module string of a module name
852     # @param xml_attr not used here
853     def add_kernel_module(self, xml_path, kernel_module, xml_attr):
854     if type(kernel_module) != str:
855     raise GLIException("KernelModuleError", 'fatal', 'add_kernel_module', "The kernel module must be a string!")
856     self._kernel_modules.append(kernel_module)
857 npmccallum 32
858 codeman 594 ##
859     # "kernel_modules is a tuple of strings containing names of modules to automatically load at boot time. (ie. '( 'ide-scsi', )')"
860     # @param kernel_modules Parameter description
861     def set_kernel_modules(self, kernel_modules):
862 npmccallum 32 # Check type
863 codeman 594 if type(kernel_modules) != tuple:
864     raise GLIException("KernelModulesError", 'fatal', 'set_kernel_modules', "Must be a tuple!")
865 npmccallum 32
866 codeman 594 self._kernel_modules = []
867    
868     # Check tuple data type
869     for module in kernel_modules:
870     self._kernel_modules.append(module)
871 npmccallum 32
872 agaffney 509 ##
873 codeman 594 # Returns kernel_modules
874     def get_kernel_modules(self):
875     return self._kernel_modules
876    
877     ##
878     # Serializes kernel modules
879     def serialize_kernel_modules(self):
880     if self.get_kernel_modules() != []:
881     kernel_modules = self.get_kernel_modules()
882 agaffney 596 self.xmldoc += "<kernel-modules>";
883 codeman 594 for module in kernel_modules:
884 agaffney 596 self.xmldoc += "<module>%s</module>" % module
885     self.xmldoc += "</kernel-modules>";
886 npmccallum 32
887 codeman 594 ############################################################################
888     #### Kernel Sources
889    
890 agaffney 509 ##
891 codeman 594 # kernel_source_pkg is a string to define which kernel source to use. (ie. 'gentoo-sources')
892 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
893 codeman 594 # @param kernel_source_pkg package name of the kernel sources to be emerged
894     # @param xml_attr not used here.
895     def set_kernel_source_pkg(self, xml_path, kernel_source_pkg, xml_attr):
896 npmccallum 32 # Check type
897 codeman 594 if type(kernel_source_pkg) != str:
898     raise GLIException("KernelSourcePKGError", 'fatal', 'set_kernel_source_pkg', "Must be a string!")
899     self._kernel_source_pkg = kernel_source_pkg
900 npmccallum 32
901 agaffney 509 ##
902 codeman 594 # Returns kernel_source_pkg
903     def get_kernel_source_pkg(self):
904     return self._kernel_source_pkg
905    
906     ############################################################################
907     #### Logging Daemon Package
908    
909 agaffney 528 ##
910 codeman 594 # logging_daemon_pkg is a string to determine which logging daemon to install and configure (ie. 'sysklogd')
911 agaffney 528 # @param xml_path Used internally by the XML parser. Should be None when calling directly
912 codeman 594 # @param logging_daemon_pkg package name of logging daemon to be emerged
913 agaffney 528 # @param xml_attr Parameter description
914 codeman 594 def set_logging_daemon_pkg(self, xml_path, logging_daemon_pkg, xml_attr):
915     # Check data type
916     if type(logging_daemon_pkg) != str:
917     raise GLIException("LoggingDaemonPKGError", 'fatal', 'set_logging_daemon_pkg', "Input must be type 'string'!")
918     self._logging_daemon_pkg = logging_daemon_pkg
919    
920     ##
921     # Returns logging daemon pkg name
922     def get_logging_daemon_pkg(self):
923     return self._logging_daemon_pkg
924 agaffney 528
925 codeman 594 ############################################################################
926     #### /etc/make.conf Configuration
927 agaffney 528
928 codeman 594 ##
929     # Adds a variable to the new system make.conf
930     # @param xml_path Used internally by the XML parser. Should be None when calling directly
931     # @param data a string that is the value of the variable name.
932     # @param attr an xml attribute that contains the name of the variable
933     # OR attr is a variable name, like 'USE'. This makes it easier for front-end designers.
934     def make_conf_add_var(self, xml_path, data, attr):
935 agaffney 716 if 'name' not in attr.keys():
936     raise GLIException("MakeConfError", 'fatal', 'make_conf_add_var', "Every value needs to have a variable name!")
937 agaffney 528
938 agaffney 716 varName = attr['name']
939     if not "make.conf" in self._etc_files:
940     self._etc_files['make.conf'] = {}
941     self._make_conf[str(varName)] = str(data)
942 agaffney 528
943     ##
944 codeman 594 # make_conf is a dictionary that will be set to _make_conf
945     # There is no checking that needs to be done, so please sure sure that the make_conf dictionary
946     # that is passed in is valid.
947     # @param make_conf a dictionary that will be set to _make_conf
948     def set_make_conf(self, make_conf):
949 agaffney 716 self._etc_files['make.conf'] = make_conf
950 agaffney 528
951     ##
952 codeman 594 # Return a dictionary of the make.conf
953     def get_make_conf(self):
954 agaffney 721 if "make.conf" in self._etc_files:
955     return self._etc_files['make.conf']
956     else:
957     return {}
958 codeman 594
959     ##
960 agaffney 717 # Serializes make.conf (no longer used)
961 codeman 594 def serialize_make_conf(self):
962     if self.get_make_conf() != {}:
963 agaffney 596 self.xmldoc += "<make-conf>"
964 codeman 594
965 robbat2 679 # keys should always be in the same order!
966 codeman 594 make_conf = self.get_make_conf()
967 robbat2 679 make_conf_keys = make_conf.keys()
968     make_conf_keys.sort()
969    
970     for var in make_conf_keys:
971 agaffney 596 self.xmldoc += "<variable name=\"%s\">%s</variable>" % (var, make_conf[var])
972 codeman 594
973 agaffney 596 self.xmldoc += "</make-conf>"
974 codeman 594
975     ############################################################################
976     #### MTA Selection
977    
978     ##
979     # Sets the intended MTA package
980 agaffney 528 # @param xml_path Used internally by the XML parser. Should be None when calling directly
981 codeman 594 # @param mta package name of mta
982 agaffney 528 # @param xml_attr Parameter description
983 robbat2 650 def set_mta_pkg(self, xml_path, mta_pkg, xml_attr):
984     if type(mta_pkg) != str:
985     raise GLIException("MTAError", 'fatal', 'set_mta_pkg', "The MTA must be a string!")
986     self._mta_pkg = mta_pkg
987 agaffney 528
988 codeman 594 ##
989     # returns the MTA
990 robbat2 650 def get_mta_pkg(self):
991     return self._mta_pkg
992 codeman 594
993     ############################################################################
994     #### Network Interface Selection
995    
996     ##
997     # This adds an ethernet device to the _network_interfaces dictionary.
998     # The format of this dictionary is:
999     # { <eth_device> : (options tuple), ... }
1000     #
1001     # eth_device can be a valid ethernet device eth0, eth1, wlan*... OR
1002     # it can be a valid MAC address.
1003     #
1004     # The format of the options tuple is for a static IP:
1005     # ( <ip address>, <broadcast>, <netmask> )
1006     #
1007     # For DHCP, the format of the options tuple is:
1008     # ( 'dhcp', <dhcp options>, None )
1009     #
1010     # We keep the None as a placeholder, to not break anything that uses this
1011     # in other parts of the installer.
1012     #
1013     # Aliases are no longer needed in the tuple because they can be treated like
1014     # an individual interface. GLIUtility.is_eth_device will recognize
1015     # @param xml_path Used internally by the XML parser. Should be None when calling directly
1016     # @param device the type and name of the device
1017     # @param attr should be dhcp or a tuple of the ip addresses.
1018     def add_network_interface(self, xml_path, device, attr):
1019     options = None
1020     ip = broadcast = netmask = dhcp_options = None
1021     dhcp = True
1022    
1023     if type(device) != str:
1024     raise GLIException("NetworkInterfacesError", 'fatal', 'add_network_interface', "Invalid or unimplimented device type (" + device + ")!")
1025    
1026     if not GLIUtility.is_eth_device(device):
1027     device = GLIUtility.format_mac(device)
1028     if not GLIUtility.is_mac(device):
1029     raise GLIException("NetworkInterfacesError", 'fatal', 'add_network_interface', "Invalid or unimplimented device type (" + device + ")!")
1030    
1031     if type(attr) == tuple:
1032     ip = attr[0]
1033 allanonjl 667 dhcp_options = broadcast = attr[1]
1034 codeman 594 netmask = attr[2]
1035     if ip != 'dhcp':
1036     dhcp = False
1037     else:
1038     for attrName in attr.keys():
1039     if attrName == 'ip':
1040     ip = str(attr[attrName])
1041     elif attrName == 'broadcast':
1042     broadcast = str(attr[attrName])
1043     elif attrName == 'netmask':
1044     netmask = str(attr[attrName])
1045     elif attrName == 'options':
1046     dhcp_options = str(attr[attrName])
1047    
1048     if ip != 'dhcp' and ip != None:
1049     dhcp = False
1050    
1051     if not dhcp:
1052     if not GLIUtility.is_ip(ip):
1053     raise GLIException("NetworkInterfacesError", 'fatal', 'add_network_interface', "The ip address you specified for " + device + " is not valid!")
1054     if not GLIUtility.is_ip(broadcast):
1055     raise GLIException("NetworkInterfacesError", 'fatal', 'add_network_interface', "The broadcast address you specified for " + device + " is not valid!")
1056     if not GLIUtility.is_ip(netmask):
1057     raise GLIException("NetworkInterfacesError", 'fatal', 'add_network_interface', "The netmask address you specified for " + device + " is not valid!")
1058     options = (ip, broadcast, netmask)
1059     else:
1060     options = ('dhcp', dhcp_options, None)
1061    
1062     self._network_interfaces[device] = options
1063    
1064     ##
1065     # This method sets the network interfaces diction to network_interfaces.
1066     # This method uses the function add_network_interfaces to do all of the real work.
1067     # @param network_interfaces a dict with all the networking info. see add_ for specification.
1068     def set_network_interfaces(self, network_interfaces):
1069 agaffney 528 # Check type
1070 codeman 594 if type(network_interfaces) != dict:
1071     raise GLIException("NetworkInterfacesError", 'fatal', 'set_network_interfaces', "Must be a dictionary!")
1072 agaffney 528
1073 codeman 594 self._network_interfaces = {}
1074     for device in network_interfaces:
1075     self.add_network_interface(None, device, network_interfaces[device])
1076 agaffney 528
1077     ##
1078 codeman 594 # Returns network_interfaces
1079     def get_network_interfaces(self):
1080     return self._network_interfaces
1081    
1082     ##
1083     # Serialize Network Interfaces
1084     def serialize_network_interfaces(self):
1085     if self.get_network_interfaces() != {}:
1086 agaffney 596 self.xmldoc += "<network-interfaces>"
1087 codeman 594 interfaces = self.get_network_interfaces()
1088     for iface in interfaces:
1089     if interfaces[iface][0] == 'dhcp':
1090     attrs = "ip=\"dhcp\""
1091     if interfaces[iface][1] != None:
1092     dhcp_options = "options=\"%s\"" % interfaces[iface][1]
1093     attrs = attrs + " " + dhcp_options
1094 agaffney 596 self.xmldoc += "<device %s>%s</device>" % (attrs, iface)
1095 codeman 594 else:
1096 agaffney 596 self.xmldoc += "<device ip=\"%s\" broadcast=\"%s\" netmask=\"%s\">%s</device>" % (interfaces[iface][0], interfaces[iface][1], interfaces[iface][2], iface)
1097     self.xmldoc += "</network-interfaces>"
1098 agaffney 528
1099 codeman 594 ############################################################################
1100     #### Network Mounts
1101    
1102 agaffney 528 ##
1103 codeman 594 # FIXME: agaffney: Brief description of function
1104 agaffney 528 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1105 codeman 594 # @param unused Parameter description
1106     # @param attr Parameter description
1107     def add_netmount(self, xml_path, unused, attr):
1108     netmount_entry = {'export': '', 'host': '', 'mountopts': '', 'mountpoint': '', 'type': ''}
1109     if type(attr) == tuple:
1110     netmount_entry['export'] = attr[0]
1111     netmount_entry['host'] = attr[1]
1112     netmount_entry['mountopts'] = attr[2]
1113     netmount_entry['mountpoint'] = attr[3]
1114     netmount_entry['type'] = attr[4]
1115     else:
1116     if "export" in attr.getNames():
1117     for attrName in attr.getNames():
1118     netmount_entry[attrName] = str(attr.getValue(attrName))
1119     self._network_mounts.append(netmount_entry)
1120 agaffney 528
1121 codeman 594 ##
1122     # Sets Network Mounts given a netmounts found probably in the config file. Not sure if used.
1123     # @param netmounts Parameter description
1124     def set_network_mounts(self, netmounts):
1125     self._network_mounts = netmounts
1126 agaffney 528
1127     ##
1128 codeman 594 # Returns the network mounts.
1129     def get_network_mounts(self):
1130     return self._network_mounts
1131    
1132     ##
1133     # Serializes network mounts
1134     def serialize_network_mounts(self):
1135     if self.get_network_mounts() != {}:
1136     netmounts = self.get_network_mounts()
1137 agaffney 596 self.xmldoc += "<network-mounts>"
1138 codeman 594 for mount in netmounts:
1139 agaffney 596 self.xmldoc += "<netmount host=\"%s\" export=\"%s\" type=\"%s\" mountpoint=\"%s\" mountopts=\"%s\" />" % (mount['host'], mount['export'], mount['type'], mount['mountpoint'], mount['mountopts'])
1140     self.xmldoc += "</network-mounts>"
1141 codeman 594
1142     ############################################################################
1143     #### NIS Domain Name
1144 npmccallum 32
1145 agaffney 509 ##
1146 codeman 594 # nisdomainname is a string containing the NIS domainname for the new system.
1147 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1148 codeman 594 # @param nisdomainname the name. is a string.
1149     # @param xml_attr not used here
1150 samyron 88 def set_nisdomainname(self, xml_path, nisdomainname, xml_attr):
1151 npmccallum 32 # Check type
1152     if type(nisdomainname) != str:
1153 samyron 189 raise GLIException("NISDomainnameError", 'fatal', 'set_nisdomainname', "Must be a string!")
1154 npmccallum 32
1155     self._nisdomainname = nisdomainname
1156 codeman 594
1157 agaffney 509 ##
1158 codeman 594 # Returns nisdomainname
1159     def get_nisdomainname(self):
1160     return self._nisdomainname
1161 npmccallum 32
1162 codeman 594 ############################################################################
1163     #### Partitioning
1164    
1165 agaffney 509 ##
1166 codeman 594 # FIXME: agaffney
1167     # @param xml_path Used internally by the XML parser. Should be None when calling directly
1168     # @param unused Parameter description
1169     # @param attr Parameter description
1170     def add_partitions_device(self, xml_path, unused, attr):
1171     devnode = None
1172     if type(attr) == tuple:
1173     devnode = attr[0]
1174 agaffney 596 disklabel = attr[1]
1175 codeman 594 else:
1176     if "devnode" in attr.getNames():
1177     devnode = str(attr.getValue("devnode"))
1178 agaffney 596 if "disklabel" in attr.getNames():
1179     disklabel = str(attr.getValue("disklabel"))
1180     else:
1181 agaffney 691 disklabel = ""
1182 codeman 594 self._partition_current_device = devnode
1183 agaffney 596 self._partition_tables[devnode] = GLIStorageDevice.Device(devnode)
1184     self._partition_tables[devnode].set_disklabel(disklabel)
1185     # Add code to import self._temp_partition_table into the Device object
1186     self._partition_tables[devnode].set_partitions_from_install_profile_structure(self._temp_partition_table)
1187 codeman 594 self._temp_partition_table = {}
1188 robbat2 680
1189 codeman 594
1190     ##
1191     # FIXME: agaffney
1192     # @param xml_path Used internally by the XML parser. Should be None when calling directly
1193     # @param unused Parameter description
1194     # @param attr Parameter description
1195     def add_partitions_device_partition(self, xml_path, unused, attr):
1196     part_entry = {'end': 0, 'format': None, 'mb': 0, 'minor': 0, 'mountopts': '', 'mountpoint': '', 'origminor': '', 'start': 0, 'type': ''}
1197 agaffney 631 # if type(attr) == tuple:
1198     # part_entry['end'] = attr[0]
1199     # part_entry['format'] = attr[1]
1200     # part_entry['mb'] = attr[2]
1201     # part_entry['minor'] = attr[3]
1202     # part_entry['mountopts'] = attr[4]
1203     # part_entry['mountpoint'] = attr[5]
1204     # part_entry['origminor'] = attr[6]
1205     # part_entry['start'] = attr[7]
1206     # part_entry['type'] = attr[8]
1207     # else:
1208     if "minor" in attr.getNames():
1209     for attrName in attr.getNames():
1210     part_entry[attrName] = str(attr.getValue(attrName))
1211 codeman 594 if type(part_entry['format']) == str: part_entry['format'] = GLIUtility.strtobool(part_entry['format'])
1212 agaffney 1291 if type(part_entry['resized']) == str: part_entry['resized'] = GLIUtility.strtobool(part_entry['resized'])
1213 agaffney 635 # if GLIUtility.is_numeric(part_entry['end']): part_entry['end'] = long(part_entry['end'])
1214     # if GLIUtility.is_numeric(part_entry['start']): part_entry['start'] = long(part_entry['start'])
1215     if GLIUtility.is_numeric(part_entry['mb']): part_entry['mb'] = long(part_entry['mb'])
1216 agaffney 724 if GLIUtility.is_numeric(part_entry['minor']):
1217     if part_entry['type'] == "free":
1218     part_entry['minor'] = float(part_entry['minor'])
1219     else:
1220     part_entry['minor'] = int(part_entry['minor'])
1221 codeman 594 if GLIUtility.is_numeric(part_entry['origminor']): part_entry['origminor'] = int(part_entry['origminor'])
1222     self._temp_partition_table[part_entry['minor']] = part_entry
1223    
1224     ############################################################################
1225     #### Partition Tables
1226    
1227     ##
1228     # Sets the partition Tables
1229     # @param partition_tables multilevel dictionary described below.
1230 npmccallum 32 def set_partition_tables(self, partition_tables):
1231     """
1232     Sets the partition tables. A partition is a multi level dictionary in the following format:
1233     { <device (local)>: <partition table>, <device (nfs)>: <mount point> }
1234    
1235     <device (local)> is a string containing the path to the local file. (ie. '/dev/hda')
1236     <device (nfs)> is a string containing the ip address of the nfs mount. (ie. '192.168.1.2')
1237    
1238     <partition table> is a dictionary in the following format:
1239 samyron 94 { <minor>: { 'mb': <size in mb>, 'type': <type>, 'mountpoint': <mount point>, 'start': <start cylinder>,
1240     'end': <end cylinder>, 'mountopts': <mount options>, 'format': <format> } }
1241 npmccallum 32
1242 samyron 94 ie. partition_tables['/dev/hda'][1] would return { 'mb': 0, 'type': 'ext3', 'mountpoint': '/boot', 'start': 12345,
1243     'end': 34567, 'mountopts': 'auto', format: 'False' }
1244 npmccallum 32
1245     Types are as follows:
1246 samyron 94 string: <device>, <mount point>, <mount options>, <type>
1247     integer: <minor>, <size in mb>, <start cylinder>, <end cylinder>
1248     boolean: <format>
1249 npmccallum 32
1250     Current <type> options include:
1251 samyron 94 ext2, ext3, reiserfs, xfs, jfs, linux-swap, extended, others?
1252 npmccallum 32
1253     There will be a method in the partitioning code to make sure that the current parition_tables can actually be implemented.
1254     Should we call that function to test the culpability of our potential partitioning scheme?
1255     Should we create a method in the Controller to take raw variables and put them in the proper structure?
1256     Are all filesystems supported by all arches?
1257     """
1258    
1259 agaffney 596 # All the sanity checks are being commented out until I can fix them for the GLIStorageDevice stuff
1260     """
1261 npmccallum 32 if type(partition_tables) != dict:
1262 samyron 189 raise GLIException("PartitionTableError", 'fatal', 'set_partition_tables', "Invalid data type! partition_tables is a dict...")
1263 npmccallum 32
1264     for device in partition_tables:
1265    
1266     # If the device is a valid local device...
1267 samyron 37 if GLIUtility.is_device(device):
1268 npmccallum 32
1269     # We should check to make sure device is in /proc/partitions
1270     # If it is in /proc/partitions, it is a partitionable device
1271    
1272     # ... then loop through each minor to check data
1273     for minor in partition_tables[device]:
1274    
1275     # Make sure that the <minor> is an integer or can be converted to one
1276     try:
1277     int(minor)
1278     except:
1279 samyron 189 raise GLIException("ParitionTableError", 'fatal', 'set_partition_tables', "The minor you specified (" + minor + ") is not an integer!")
1280 npmccallum 32
1281     # Make sure that a minor number is valid
1282     if minor < 1:
1283 samyron 189 raise GLIException("ParitionTableError", 'fatal', 'set_partition_tables', "The minor you specified (" + minor + ") is not a valid minor!")
1284 npmccallum 32
1285     # Make sure that <size>, <type> and <mount point> are all set
1286 samyron 94 #if len(partition_tables[device][minor]) != 3:
1287 samyron 189 # raise GLIException("ParitionTableError", 'fatal', 'set_partition_tables', "The number of attributes for minor " + minor + " is incorrect!")
1288 samyron 94 #
1289 npmccallum 32 # Make sure that the <size> is an integer or can be converted to one
1290 samyron 94 #try:
1291     # int(partition_tables[device][minor][0])
1292     #except:
1293 samyron 189 # raise GLIException("ParitionTableError", 'fatal', 'set_partition_tables', "The size you specified (" + partition_tables[device][minor][0] + ") is not an integer!")
1294 npmccallum 32
1295     # Else, if the device is a valid remote device (hostname or ip)
1296 samyron 37 elif GLIUtility.is_ip(device) or GLIUtility.is_hostname(device):
1297 npmccallum 32
1298 samyron 95 pass
1299 npmccallum 32 # Make sure that only the mount point is set
1300 samyron 95 # if type(partition_tables[device]) != str:
1301 samyron 189 # raise GLIException("ParitionTableError", 'fatal', 'set_partition_tables', "Invalid mount point for nfs mount (device: " + device + ")!")
1302 npmccallum 32
1303     # If the device is not a local or remote device, then it is invalid
1304     else:
1305 samyron 189 raise GLIException("PartitionTableError", 'fatal', 'set_partition_tables', "The device you specified (" + device + ") is not valid!")
1306 agaffney 596 """
1307 npmccallum 32
1308     # If all the tests clear, then set the variable
1309     self._partition_tables = partition_tables
1310    
1311 agaffney 509 ##
1312 codeman 594 # Returns partition_tables
1313     def get_partition_tables(self):
1314     return self._partition_tables
1315 samyron 55
1316 agaffney 509 ##
1317 codeman 594 # Serializes partition tables
1318     def serialize_partition_tables(self):
1319 samyron 94 if self.get_partition_tables() != {}:
1320     partitions = self.get_partition_tables()
1321 agaffney 596 self.xmldoc += "<partitions>";
1322 samyron 94 for device in partitions.keys():
1323 agaffney 596 self.xmldoc += "<device devnode=\"%s\" disklabel=\"%s\">" % (device, partitions[device].get_disklabel())
1324     ips = partitions[device].get_install_profile_structure()
1325     for minor in ips:
1326     part = ips[minor]
1327 agaffney 1291 self.xmldoc += "<partition minor=\"%s\" origminor=\"%s\" mb=\"%s\" type=\"%s\" mountpoint=\"%s\" mountopts=\"%s\" format=\"%s\" mkfsopts=\"%s\" resized=\"%s\" />" % (str(minor), str(part['origminor']), str(part['mb']), str(part['type']), str(part['mountpoint']), str(part['mountopts']), str(part['format']), str(part['mkfsopts']), str(part['resized']))
1328 agaffney 596 self.xmldoc += "</device>"
1329     self.xmldoc += "</partitions>"
1330 samyron 94
1331 codeman 594 ############################################################################
1332     #### Portage Snapshot URI
1333 agaffney 160
1334 agaffney 509 ##
1335 codeman 594 # portage_tree_snapshot_uri is a string defining the path to a portage tree
1336     # snapshot. (ie. 'file:///mnt/cdrom/snapshots/portage-*.tar.bz2')
1337 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1338 codeman 594 # @param portage_tree_snapshot_uri URI of the portage tree shapshot location
1339     # @param xml_attr not used here
1340     def set_portage_tree_snapshot_uri(self, xml_path, portage_tree_snapshot_uri, xml_attr):
1341     # Check type
1342     if type(portage_tree_snapshot_uri) != str:
1343     raise GLIException("PortageTreeSnapshotURIError", 'fatal', 'set_portage_tree_snapshot_uri', "Must be a string!")
1344 samyron 37
1345 codeman 594 self._portage_tree_snapshot_uri = portage_tree_snapshot_uri
1346 samyron 37
1347 agaffney 509 ##
1348 codeman 594 # Returns portage_tree_snapshot_uri
1349     def get_portage_tree_snapshot_uri(self):
1350     return self._portage_tree_snapshot_uri
1351    
1352     ############################################################################
1353     #### Portage Tree Sync Type
1354 samyron 37
1355 codeman 594 ##
1356     # Sets the sync type to be used by portage
1357     # @param xml_path Used internally by the XML parser. Should be None when calling directly
1358     # @param portage_tree_sync string with sync type
1359     # @param xml_attr not used here
1360     def set_portage_tree_sync_type(self, xml_path, portage_tree_sync, xml_attr):
1361     # Check type
1362     if type(portage_tree_sync) != str:
1363     raise GLIException("PortageTreeSyncError", 'fatal', 'set_portage_tree_sync_type', "Must be a string!")
1364 samyron 37
1365 codeman 594 if string.lower(portage_tree_sync) not in ('sync', 'webrsync', 'custom', 'snapshot', 'none'):
1366     raise GLIException("PortageTreeSyncError", 'fatal', 'set_portage_tree_sync_type', "Invalid Input!")
1367 samyron 37
1368 codeman 594 self._portage_tree_sync_type = string.lower(portage_tree_sync)
1369    
1370 agaffney 509 ##
1371 codeman 594 # Returns portage_tree_sync
1372     def get_portage_tree_sync_type(self):
1373     return self._portage_tree_sync_type
1374 samyron 37
1375 codeman 594 ############################################################################
1376     #### Post-Install Script URI
1377    
1378 agaffney 509 ##
1379 codeman 594 # Sets the URI for the post install script
1380 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1381 codeman 594 # @param post_install_script_uri the URI
1382     # @param xml_attr Parameter description
1383     def set_post_install_script_uri(self, xml_path, post_install_script_uri, xml_attr):
1384     self._post_install_script_uri = post_install_script_uri
1385    
1386     ##
1387     # Returns the URI for the post install script
1388     def get_post_install_script_uri(self):
1389     return self._post_install_script_uri
1390    
1391     ############################################################################
1392     #### /etc/rc.conf Configuration
1393    
1394     ##
1395     # Adds a variable set for the new system rc.conf
1396     # @param xml_path Used internally by the XML parser. Should be None when calling directly
1397     # @param data a string that is the value of the variable name.
1398     # @param attr an xml attribute that contains the name of the variable
1399 samyron 88 def rc_conf_add_var(self, xml_path, data, attr):
1400     if 'name' not in attr.keys():
1401 samyron 189 raise GLIException("RCConfError", 'fatal', 'rc_conf_add_var', "Every value needs to have a variable name!")
1402 samyron 37
1403 samyron 88 varName = attr['name']
1404 agaffney 716 if not "rc.conf" in self._etc_files:
1405     self._etc_files['rc.conf'] = {}
1406     self._etc_files[str(varName)] = str(data)
1407 samyron 37
1408 agaffney 509 ##
1409 codeman 594 # rc_conf is a dictionary that will be set to _rc_conf
1410     # There is no checking that needs to be done, so please sure sure that the rc_conf dictionary
1411     # that is passed in is valid.Brief description of function
1412     # @param rc_conf dictionary in the format specified above.
1413 samyron 37 def set_rc_conf(self, rc_conf):
1414 agaffney 716 self._etc_files['rc.conf'] = rc_conf
1415 samyron 37
1416 agaffney 509 ##
1417 codeman 594 # Return a dictionary of the make.conf
1418 samyron 37 def get_rc_conf(self):
1419 agaffney 716 if "rc.conf" in self._etc_files:
1420     return self._etc_files['rc.conf']
1421     else:
1422     return {}
1423 codeman 594
1424 agaffney 509 ##
1425 agaffney 717 # Serializes rc.conf (no longer used)
1426 codeman 594 def serialize_rc_conf(self):
1427     if self.get_rc_conf() != {}:
1428 agaffney 596 self.xmldoc += "<rc-conf>"
1429 samyron 37
1430 codeman 594 rc_conf = self.get_rc_conf()
1431     for var in rc_conf:
1432 agaffney 596 self.xmldoc += "<variable name=\"%s\">%s</variable>" % (var, rc_conf[var])
1433 samyron 37
1434 agaffney 596 self.xmldoc += "</rc-conf>"
1435 samyron 37
1436 codeman 594 ############################################################################
1437     #### Root Password Hash
1438 samyron 37
1439 agaffney 509 ##
1440 codeman 594 # root_pass_hash is a string containing an md5 password hash to be assinged as the password for the root user.
1441 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1442 codeman 594 # @param root_pass_hash Parameter description
1443 agaffney 509 # @param xml_attr Parameter description
1444 codeman 594 def set_root_pass_hash(self, xml_path, root_pass_hash, xml_attr):
1445     # Check type
1446     if type(root_pass_hash) != str:
1447     raise GLIException("RootPassHashError", 'fatal', 'set_root_pass_hash', "Must be a string!")
1448     self._root_pass_hash = root_pass_hash
1449 samyron 37
1450 agaffney 509 ##
1451 codeman 594 # Returns root_pass_hash
1452     def get_root_pass_hash(self):
1453     return self._root_pass_hash
1454 samyron 37
1455 codeman 594 ############################################################################
1456     #### RSYNC Proxy
1457 samyron 37
1458 agaffney 509 ##
1459 codeman 594 # RSYNC proxy is a uri containing a proxy if needed for rsync traffic. (ie. 'rsync://myhost.mydomain:myport')
1460 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1461 codeman 594 # @param rsync_proxy the proxy address
1462     # @param xml_attr not used here
1463     def set_rsync_proxy(self, xml_path, rsync_proxy, xml_attr):
1464     # Check type
1465 agaffney 1153 if rsync_proxy and not GLIUtility.is_uri(rsync_proxy):
1466 codeman 594 raise GLIException("RSYNCProxyError", 'fatal', 'set_rsync_proxy', "Must be a uri!")
1467     self._rsync_proxy = rsync_proxy
1468 samyron 50
1469 agaffney 509 ##
1470 codeman 594 # Returns RSYNC proxy
1471     def get_rsync_proxy(self):
1472     return self._rsync_proxy
1473 samyron 37
1474 codeman 594 ############################################################################
1475     #### Services
1476    
1477 agaffney 509 ##
1478 robbat2 743 # Set the services to be started on bootup. Services should be
1479     # seperated by ','. WARNING: This used to be ' ' instead!
1480 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1481 codeman 747 # @param services comma-separated list of services
1482 agaffney 509 # @param xml_attr Parameter description
1483 codeman 594 def set_services(self, xml_path, services, xml_attr):
1484     if type(services) == str:
1485 codeman 711 services = services.split(',')
1486 codeman 594 else:
1487     raise GLIException("ServicesError", 'fatal', 'set_services', "Invalid input!")
1488 samyron 88
1489 codeman 594 for service in services:
1490     if not GLIUtility.is_realstring(service):
1491     raise GLIException("ServicesError", 'fatal', 'set_services', service + " must be a valid string!")
1492     self._services = services
1493 samyron 37
1494 codeman 594 ##
1495     # This returns a list of the packages:
1496     def get_services(self):
1497     return self._services
1498    
1499     ##
1500     # Serializes services
1501     def serialize_services(self):
1502     if self.get_services() != ():
1503 agaffney 596 self.xmldoc += "<services>"
1504 robbat2 743 self.xmldoc += string.join(self.get_services(), ',')
1505 agaffney 596 self.xmldoc += "</services>"
1506 samyron 37
1507 codeman 594 ############################################################################
1508     #### Stage Tarball URI
1509 samyron 37
1510 agaffney 509 ##
1511 codeman 594 # stage_tarball_uri is a string that is the full path to the tarball you
1512     # wish to use. (ie. 'file:///path/to/mytarball.tar.bz2')
1513 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1514 codeman 594 # @param stage_tarball_uri string of URI for stage tarball location.
1515     # @param xml_attr not used here.
1516     def set_stage_tarball_uri(self, xml_path, stage_tarball_uri, xml_attr):
1517     # Check type
1518     if type(stage_tarball_uri) != str:
1519     raise GLIException("StageTarballURIError", 'fatal', 'set_stage_tarball_uri', "Must be a string!")
1520 samyron 89
1521 codeman 594 # Check validity (now done in the FE)
1522     #if not stage_tarball_uri:
1523     # raise GLIException("CustomStage3TarballURIError", 'fatal', 'set_stage_tarball_uri', "Empty URI!")
1524 samyron 89
1525 codeman 594 self._stage_tarball_uri = stage_tarball_uri
1526 samyron 89
1527 agaffney 509 ##
1528 codeman 594 # Returns stage_tarball_uri
1529     def get_stage_tarball_uri(self):
1530     return self._stage_tarball_uri
1531 codeman 560
1532 codeman 594 ############################################################################
1533     #### Timezone
1534 codeman 560
1535 codeman 594 ##
1536     # time_zone is a string defining the time zone to use.
1537     # Time zones are found in /usr/share/zoneinfo/. Syntax is 'UTC' or 'US/Eastern'.
1538     # @param xml_path Used internally by the XML parser. Should be None when calling directly
1539     # @param time_zone string of the intended timezone
1540     # @param xml_attr not used here.
1541     def set_time_zone(self, xml_path, time_zone, xml_attr):
1542     # Check type
1543     if type(time_zone) != str:
1544     raise GLIException("TimeZoneError", 'fatal', 'set_time_zone', "Must be a string!")
1545     self._time_zone = time_zone
1546 codeman 560
1547 agaffney 509 ##
1548 codeman 594 # Returns time_zone
1549     def get_time_zone(self):
1550     return self._time_zone
1551 codeman 560
1552 codeman 594 ############################################################################
1553     #### Users
1554    
1555 codeman 560 ##
1556 codeman 594 # Adds a user to the list of users
1557 agaffney 510 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1558 codeman 594 # @param username name of user to be added
1559     # @param attr=None parameters for the user.
1560     def add_user(self, xml_path, username, attr=None):
1561 samyron 89 """
1562 codeman 594 This will take a username (that is a string) and a set of attributes and it will verify everything is valid
1563     and convert it into a 7-tuple set. Then it adds this tuple into the users list.
1564     username and hash are manditory. All other attributes are optional. Or this method will
1565     take a 7-tuple set, verify it's correctness and then append it to the _users list.
1566     All items are strings except <uid>, which is an integer, and groups, which is a tuple.
1567 samyron 89
1568 codeman 594 The finished tuples look like this:
1569     ( <user name>, <password hash>, (<tuple of groups>), <shell>, <home directory>, <user id>, <user comment> )
1570 samyron 89
1571 codeman 594 """
1572     hash = ''
1573     shell = None
1574     groups = None
1575     shell = None
1576     homedir = None
1577     uid = None
1578     comment = None
1579 samyron 89
1580 codeman 594 if type(username) == tuple:
1581     if len(username) != 7:
1582     raise GLIException("UserError", 'fatal', 'add_user', "Wrong format for user tuple!")
1583 samyron 94
1584 codeman 594 username_tmp = username[0]
1585     hash = username[1]
1586     groups = username[2]
1587     shell = username[3]
1588     homedir = username[4]
1589     uid = username[5]
1590     comment = username[6]
1591     username = username_tmp
1592 samyron 94
1593 codeman 594 if type(groups) != tuple:
1594     if groups != None:
1595     groups = tuple(groups.split(','))
1596 samyron 94 else:
1597 codeman 594 for attrName in attr.keys():
1598     if attrName == 'groups':
1599     groups = tuple(str(attr[attrName]).split(','))
1600     elif attrName == 'shell':
1601     shell = str(attr[attrName])
1602     elif attrName == 'hash':
1603     hash = str(attr[attrName])
1604     elif attrName == 'homedir':
1605     homedir = str(attr[attrName])
1606     elif attrName == 'uid':
1607     if attr[attrName]:
1608     uid = int(attr[attrName])
1609     elif attrName == 'comment':
1610     comment = str(attr[attrName])
1611 samyron 100
1612 codeman 594 allowable_nonalphnum_characters = '_-'
1613 samyron 100
1614 codeman 594 if not GLIUtility.is_realstring(username):
1615     raise GLIException("UserError", 'fatal', 'add_user', "username must be a non-empty string")
1616 samyron 100
1617 codeman 594 if username[0] not in (string.lowercase + string.uppercase):
1618     raise GLIException("UsersError", 'fatal', 'add_user', "A username must start with a letter!")
1619 agaffney 160
1620 codeman 594 for x in username:
1621     if x not in (string.lowercase + string.uppercase + string.digits + allowable_nonalphnum_characters):
1622     raise GLIException("UsersError", 'fatal', 'add_user', "A username must contain only letters, numbers, or these symbols: " + allowable_nonalphnum_characters)
1623 agaffney 160
1624 codeman 594 for user in self._users:
1625     if username == user[0]:
1626     raise GLIException("UserError", 'fatal', 'add_user', "This username already exists!")
1627 agaffney 160
1628 codeman 594 if (hash == None) or (hash == ''):
1629     raise GLIException("UserError", 'fatal', 'add_user', "A password hash must be given for every user!")
1630 codeman 222
1631 codeman 594 self._users.append((username,hash,groups,shell,homedir,uid,comment))
1632 codeman 222
1633 codeman 594 ##
1634     # Remove "username" from the _users list.
1635     # @param username name of user to be removed
1636     def remove_user(self, username):
1637     for user in self._users:
1638     if username == user[0]:
1639     self._users.remove(user)
1640     break
1641 codeman 222
1642 agaffney 509 ##
1643 codeman 594 # users is a tuple(user) of tuple's. This sets _users to this set of tuples.
1644     # @param users a tuple(user) of tuple's.
1645     def set_users(self, users):
1646     self._users = []
1647     if users != None:
1648     for user in users:
1649     self._users.append(user)
1650 codeman 222
1651 agaffney 509 ##
1652 codeman 594 # Returns users
1653     def get_users(self):
1654     return self._users
1655 codeman 222
1656 agaffney 525 ##
1657 codeman 594 # Serializes users
1658     def serialize_users(self):
1659     if self.get_users() != []:
1660 agaffney 596 self.xmldoc += "<users>"
1661 codeman 594 users = self.get_users()
1662     for user in users:
1663     attrstr = ""
1664     username = user[0]
1665 agaffney 525
1666 codeman 594 if user[1] != None:
1667     attrstr += "hash=\"%s\" " % user[1]
1668     if user[2] != None:
1669     attrstr += "groups=\"%s\" " % string.join(user[2],',')
1670     if user[3] != None:
1671     attrstr += "shell=\"%s\" " % user[3]
1672     if user[4] != None:
1673     attrstr += "homedir=\"%s\" " % user[4]
1674     if user[5] != None:
1675     attrstr += "uid=\"%s\" " % user[5]
1676     if user[6] != None:
1677     attrstr += "comment=\"%s\" " % user[6]
1678    
1679 agaffney 596 self.xmldoc += "<user %s>%s</user>" % (string.strip(attrstr), username)
1680     self.xmldoc += "</users>"

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20