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

Contents of /trunk/src/GLIInstallProfile.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1284 - (show annotations) (download) (as text)
Wed Feb 8 19:58:44 2006 UTC (12 years, 7 months ago) by codeman
File MIME type: text/x-python
File size: 67050 byte(s)
added more packages to extra_packages list in IP

1 """
2 # 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 Gentoo Linux Installer
7
8 $Id: GLIInstallProfile.py,v 1.83 2006/02/08 19:58:44 codeman Exp $
9
10 The GLI module contains all classes used in the Gentoo Linux Installer (or GLI).
11 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 """
24
25 import string
26 import xml.sax
27 import os
28 import GLIUtility
29 import SimpleXMLParser
30 import xml.dom.minidom
31 import GLIStorageDevice
32 from GLIException import *
33
34 ##
35 # This class contains all the settings used during the install
36 class InstallProfile:
37 """
38 An object representation of a profile.
39 InstallProfile is an object representation of a parsed installation
40 profile file.
41 """
42
43 ##
44 # Initializes all variables to default values and adds handlers.
45 def __init__(self):
46
47 # Configuration information - profile data
48 # All variables must be declared here with a default value to ensure
49 # the XML will correctly serialize.
50 self._cron_daemon_pkg = "vixie-cron"
51 self._logging_daemon_pkg = "syslog-ng"
52 self._boot_device = ""
53 self._boot_loader_mbr = True
54 self._boot_loader_pkg = ""
55 self._kernel_modules = []
56 self._kernel_config_uri = ""
57 self._kernel_build_method = "genkernel"
58 self._bootloader_kernel_args = ""
59 self._kernel_initrd = True
60 self._kernel_bootsplash = False
61 self._kernel_source_pkg = "livecd-kernel"
62 self._users = []
63 self._root_pass_hash = ""
64 self._time_zone = "UTC"
65 self._stage_tarball_uri = ""
66 self._install_stage = 3
67 self._portage_tree_sync_type = "sync"
68 self._portage_tree_snapshot_uri = ""
69 self._domainname = "localdomain"
70 self._hostname = "localhost"
71 self._http_proxy = ""
72 self._ftp_proxy = ""
73 self._rsync_proxy = ""
74 self._nisdomainname = ""
75 self._partition_tables = {}
76 self._network_mounts = []
77 self._temp_partition_table = {} # temp
78 self._network_interfaces = {}
79 self._make_conf = {}
80 # self._rc_conf = {}
81 self._install_rp_pppoe = False
82 self._filesystem_tools = ()
83 self._install_pcmcia_cs = False
84 self._dns_servers = ()
85 self._default_gateway = ()
86 self._install_packages = ()
87 self._services = ()
88 self._mta_pkg = ""
89 self._grp_install = False
90 self._post_install_script_uri = ""
91 self._etc_files = {}
92 self._temp_etc_file = {}
93 self._dynamic_stage3 = False
94 self._install_distcc = False
95 self.xmldoc = ""
96
97 # Parser handler calls. For each XML attribute and children of that attribute, a handler is needed.
98 self._parser = SimpleXMLParser.SimpleXMLParser()
99 self._parser.addHandler('gli-profile/bootloader', self.set_boot_loader_pkg)
100 self._parser.addHandler('gli-profile/boot-device', self.set_boot_device)
101 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 self._parser.addHandler('gli-profile/dynamic-stage3', self.set_dynamic_stage3)
108 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 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 self._parser.addHandler('gli-profile/install-distcc', self.set_install_distcc)
115 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 self._parser.addHandler('gli-profile/kernel-build-method', self.set_kernel_build_method)
121 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 # self._parser.addHandler('gli-profile/make-conf/variable', self.make_conf_add_var)
127 self._parser.addHandler('gli-profile/mta', self.set_mta_pkg)
128 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 # self._parser.addHandler('gli-profile/rc-conf/variable', self.rc_conf_add_var)
137 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
144 ##
145 # Parses the given filename populating the client_configuration.
146 # @param filename Parameter description
147 def parse(self, filename):
148 self._parser.parse(filename)
149
150 ##
151 # 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 xmltab = { 'boot-device': self.get_boot_device,
155 'bootloader': self.get_boot_loader_pkg,
156 '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 'dynamic-stage3': self.get_dynamic_stage3,
161 '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 'install-distcc': self.get_install_distcc,
166 '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 'kernel-build-method': self.get_kernel_build_method,
171 '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 'mta': self.get_mta_pkg,
176 '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 self.xmldoc = "<?xml version=\"1.0\"?>"
186 self.xmldoc += "<gli-profile>"
187
188 # Normal cases
189 for key in xmltab.keys():
190 self.xmldoc += "<%s>%s</%s>" % (key, xmltab[key](), key)
191
192 # Special cases
193 self.serialize_default_gateway()
194 self.serialize_dns_servers()
195 self.serialize_install_packages()
196 self.serialize_kernel_modules()
197 # self.serialize_make_conf()
198 self.serialize_network_interfaces()
199 self.serialize_network_mounts()
200 self.serialize_partition_tables()
201 # self.serialize_rc_conf()
202 self.serialize_services()
203 self.serialize_users()
204 self.serialize_etc_files()
205
206 self.xmldoc += "</gli-profile>"
207
208 dom = xml.dom.minidom.parseString(self.xmldoc)
209 return dom.toprettyxml()
210
211 ############################################################################
212 ############################################################################
213 #### 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 #### Bootloader Package Selection
234
235 ##
236 # 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
246 ##
247 # 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 # @param xml_path Used internally by the XML parser. Should be None when calling directly
258 # @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
263 ##
264 # Returns kernel arguments
265 def get_bootloader_kernel_args(self):
266 return self._bootloader_kernel_args
267
268 ############################################################################
269 #### Bootloader Installation to MBR
270
271 ##
272 # boot_loader_mbr is a bool. True installs boot loader to MBR.
273 # False installs boot loader to the boot or root partition.
274 # @param xml_path Used internally by the XML parser. Should be None when calling directly
275 # @param boot_loader_mbr
276 # @param xml_attr Parameter description
277 def set_boot_loader_mbr(self, xml_path, boot_loader_mbr, xml_attr):
278 # Check data type
279 if type(boot_loader_mbr) != bool:
280 if type(boot_loader_mbr) == str:
281 boot_loader_mbr = GLIUtility.strtobool(boot_loader_mbr)
282 else:
283 raise GLIException("BootLoaderMBRError", 'fatal', 'set_boot_loader_mbr', "Input must be type 'bool'!")
284 self._boot_loader_mbr = boot_loader_mbr
285
286 ##
287 # returns boot_loader_mbr
288 def get_boot_loader_mbr(self):
289 return self._boot_loader_mbr
290
291 ############################################################################
292 #### Cron Daemon Package
293
294 ##
295 # cron_daemon_pkg is a string to determine which cron daemon to install and configure (ie. 'vixie-cron')
296 # @param xml_path Used internally by the XML parser. Should be None when calling directly
297 # @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 # Check data type
301 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
305 ##
306 # Returns the cron daemon pkg name
307 def get_cron_daemon_pkg(self):
308 return self._cron_daemon_pkg
309
310 ############################################################################
311 #### Network Gateway
312
313 ##
314 # 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 # @param xml_path Used internally by the XML parser. Should be None when calling directly
318 # @param gateway gateway ip address
319 # @param xml_attr Parameter description
320 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
326 interface = str(xml_attr['interface'])
327
328 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 ##
335 # Returns the default gateway
336 def get_default_gateway(self):
337 return self._default_gateway
338
339 ##
340 # Serializes default_gateway
341 def serialize_default_gateway(self):
342 if self.get_default_gateway() != ():
343 gw = self.get_default_gateway()
344 self.xmldoc += "<default-gateway interface=\"%s\">%s</default-gateway>" % (gw[0], gw[1])
345
346
347 ############################################################################
348 #### DNS Servers
349
350 ##
351 # Set the DNS servers for the post-installed system.
352 # @param xml_path Used internally by the XML parser. Should be None when calling directly
353 # @param dns_servers a tuple or space-separated list of dns servers
354 # @param xml_attr Parameter description
355 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
363 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
367 self._dns_servers = dns_servers
368
369 ##
370 # 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 ##
375 # Serializes DNS Servers
376 def serialize_dns_servers(self):
377 if self.get_dns_servers() != ():
378 self.xmldoc += "<dns-servers>"
379 self.xmldoc += string.join(self.get_dns_servers(), ' ')
380 self.xmldoc += "</dns-servers>"
381
382 ############################################################################
383 #### Domainname
384
385 ##
386 # domainname is a string containing the domainname for the new system. (ie. 'mydomain.com'; NOT FQDN)
387 # @param xml_path Used internally by the XML parser. Should be None when calling directly
388 # @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
396 ##
397 # Returns domainname
398 def get_domainname(self):
399 return self._domainname
400
401 ###################################################################
402 ##
403 # 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 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
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 # 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 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 ##
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 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 ##
446 # Returns etc_files structure
447 def get_etc_files(self):
448 return self._etc_files
449
450 ##
451 # Replaces etc_files structure with one passed in
452 # @param etc_files new etc_files structure
453 def set_etc_files(self, etc_files):
454 self._etc_files = etc_files
455
456 ##
457 # Serializes the etc_files structure
458 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
473 ############################################################################
474 #### FTP Proxy
475
476 ##
477 # 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 if ftp_proxy and not GLIUtility.is_uri(ftp_proxy):
484 raise GLIException("FTPProxyError", 'fatal', 'set_ftp_proxy', "Must be a uri!")
485 self._ftp_proxy = ftp_proxy
486
487 ##
488 # 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 # @param xml_path Used internally by the XML parser. Should be None when calling directly
498 # @param grp_install boolean
499 # @param xml_attr Parameter description
500 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 else:
506 raise GLIException("GRPInstall", 'fatal', 'set_grp_install', "Input must be type 'bool'!")
507 self._grp_install = grp_install
508
509 ##
510 # returns grp_install
511 def get_grp_install(self):
512 return self._grp_install
513
514 ############################################################################
515 #### Hostname
516
517 ##
518 # Hostname is a string containing the hostname for the new system. (ie. 'myhost'; NOT 'myhost.mydomain.com')
519 # @param xml_path Used internally by the XML parser. Should be None when calling directly
520 # @param hostname string of hostname
521 # @param xml_attr not used here.
522 def set_hostname(self, xml_path, hostname, xml_attr):
523 # Check type
524 if type(hostname) != str:
525 raise GLIException("HostnameError", 'fatal', 'set_hostname', "Must be a string!")
526 self._hostname = hostname
527
528 ##
529 # Returns hostname
530 def get_hostname(self):
531 return self._hostname
532
533 ############################################################################
534 #### HTTP Proxy
535
536 ##
537 # HTTP proxy is a URI containing a proxy if needed for http traffic. (ie. 'http://myhost.mydomain:myport')
538 # @param xml_path Used internally by the XML parser. Should be None when calling directly
539 # @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 if http_proxy and not GLIUtility.is_uri(http_proxy):
544 raise GLIException("HTTPProxyError", 'fatal', 'set_http_proxy', "Must be a uri!")
545 self._http_proxy = http_proxy
546
547 ##
548 # Returns HTTP proxy
549 def get_http_proxy(self):
550 return self._http_proxy
551
552 ############################################################################
553 #### 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 #### 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 {"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 "gftp": "Gnome based FTP Client",
585 "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 "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 "rhythmbox": "Music management and playback software for GNOME",
596 "vlc": "VLC media player - Video player and streamer",
597 "xchat": "Graphical IRC Client",
598 "xine-ui": "Xine movie player",
599 "xmms": "X MultiMedia System" }),
600 'Servers': ("Applications often found on servers.",
601 {"apache": "Apache Web Server",
602 "cups": "The Common Unix Printing System",
603 "exim": "A highly configurable, drop-in replacement for sendmail",
604 "iptables": "Linux kernel (2.4+) firewall, NAT and packet mangling tools",
605 "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 "proftpd": "ProFTP Server",
610 "samba": "SAMBA client/server programs for UNIX",
611 "sendmail": "Widely-used Mail Transport Agent (MTA)",
612 "traceroute": "Utility to trace the route of IP packets" }),
613 'X11': ("Window managers and X selection.",
614 {"xorg-x11": "An X11 implementation maintained by the X.Org Foundation",
615 "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 {"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 "logrotate": "Rotates, compresses, and mails system logs",
628 "ntp": "Network Time Protocol suite/programs",
629 "rdesktop": "A Remote Desktop Protocol Client",
630 "slocate": "Secure way to index and quickly search for files on your system",
631 "ufed": "Gentoo Linux USE flags editor",
632 "vim": "Vim, an improved vi-style text editor" }),
633 '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 "gnupg": "The GNU Privacy Guard, a GPL pgp replacement",
638 "net-snmp": "Software for generating and retrieving SNMP data",
639 "netcat": "the network swiss army knife",
640 "nmap": "A utility for network exploration or security auditing",
641 "screen": "full-screen window manager that multiplexes between several processes",
642 "xpdf": "An X Viewer for PDF Files" })
643 }
644 return install_package_list
645
646 ############################################################################
647 #### Install Packages
648
649 ##
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 else:
658 raise GLIException("InstallPackagesError", 'fatal', 'set_install_packages', "Invalid input!")
659
660 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
665 ##
666 # This returns a list of the packages
667 def get_install_packages(self):
668 return self._install_packages
669
670 ##
671 # Serializes install_packages
672 def serialize_install_packages(self):
673 if self.get_install_packages() != ():
674 self.xmldoc += "<install-packages>"
675 self.xmldoc += string.join(self.get_install_packages(), ' ')
676 self.xmldoc += "</install-packages>"
677
678 ############################################################################
679 #### PCMCIA-CS
680
681 ##
682 # This tells the installer whether or not to install the pcmcia_cs package
683 # @param xml_path Used internally by the XML parser. Should be None when calling directly
684 # @param install_pcmcia boolean
685 # @param xml_attr Parameter description
686 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
693 self._install_pcmcia_cs = install_pcmcia
694
695 ##
696 # Returns the boolean _install_pcmcia_cs
697 def get_install_pcmcia_cs(self):
698 return self._install_pcmcia_cs
699
700 ############################################################################
701 #### RP-PPPoE Installation
702
703 ##
704 # Tell the installer whether or not to install the rp-pppoe package
705 # @param xml_path Used internally by the XML parser. Should be None when calling directly
706 # @param install_rp_pppoe boolean
707 # @param xml_attr Parameter description
708 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
715 self._install_rp_pppoe = install_rp_pppoe
716
717 ##
718 # Return the boolean value of _install_rp_pppoe
719 def get_install_rp_pppoe(self):
720 return self._install_rp_pppoe
721
722 ############################################################################
723 #### Install Stage
724
725 ##
726 # install_stage is a integer to define which stage install to use. Appropriate stages are 1-3.
727 # @param xml_path Used internally by the XML parser. Should be None when calling directly
728 # @param install_stage install stage number
729 # @param xml_attr not used here.
730 def set_install_stage(self, xml_path, install_stage, xml_attr):
731 # Check type
732 if type(install_stage) != int:
733 if type(install_stage) == str:
734 install_stage = int(install_stage)
735 else:
736 raise GLIException("InstallStageError", 'fatal', 'set_install_stage', "Must be an integer!")
737
738 # Check for stage bounds
739 if 0 < install_stage < 4:
740 self._install_stage = install_stage
741 else:
742 raise GLIException("InstallStageError", 'fatal', 'set_install_stage', "install_stage must be 1-3!")
743
744 ##
745 # Returns install_stage
746 def get_install_stage(self):
747 return self._install_stage
748
749 ############################################################################
750 #### Kernel Bootsplash Option
751
752 ##
753 # 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 # @param xml_path Used internally by the XML parser. Should be None when calling directly
758 # @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
768 self._kernel_bootsplash = kernel_bootsplash
769
770 ##
771 # Returns kernel_bootsplash
772 def get_kernel_bootsplash(self):
773 return self._kernel_bootsplash
774
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
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 # Check type
807 if type(kernel_config_uri) != str:
808 raise GLIException("KernelConfigURIError", 'fatal', 'set_kernel_config_uri', "Must be a string!")
809
810 # 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
814 self._kernel_config_uri = kernel_config_uri
815
816 ##
817 # Returns kernel_config_uri
818 def get_kernel_config_uri(self):
819 return self._kernel_config_uri
820
821 ############################################################################
822 #### Kernel Initrd Option
823
824 ##
825 # 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 # @param xml_path Used internally by the XML parser. Should be None when calling directly
828 # @param kernel_initrd boolean
829 # @param xml_attr not used here
830 def set_kernel_initrd(self, xml_path, kernel_initrd, xml_attr):
831 # Check type
832 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
838 self._kernel_initrd = kernel_initrd
839
840 ##
841 # Returns kernel_initrd
842 def get_kernel_initrd(self):
843 return self._kernel_initrd
844
845 ############################################################################
846 #### Kernel Modules
847
848 ##
849 # Add a kernel module to the list of kernel modules
850 # @param xml_path Used internally by the XML parser. Should be None when calling directly
851 # @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
858 ##
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 # Check type
863 if type(kernel_modules) != tuple:
864 raise GLIException("KernelModulesError", 'fatal', 'set_kernel_modules', "Must be a tuple!")
865
866 self._kernel_modules = []
867
868 # Check tuple data type
869 for module in kernel_modules:
870 self._kernel_modules.append(module)
871
872 ##
873 # 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 self.xmldoc += "<kernel-modules>";
883 for module in kernel_modules:
884 self.xmldoc += "<module>%s</module>" % module
885 self.xmldoc += "</kernel-modules>";
886
887 ############################################################################
888 #### Kernel Sources
889
890 ##
891 # kernel_source_pkg is a string to define which kernel source to use. (ie. 'gentoo-sources')
892 # @param xml_path Used internally by the XML parser. Should be None when calling directly
893 # @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 # Check type
897 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
901 ##
902 # 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 ##
910 # logging_daemon_pkg is a string to determine which logging daemon to install and configure (ie. 'sysklogd')
911 # @param xml_path Used internally by the XML parser. Should be None when calling directly
912 # @param logging_daemon_pkg package name of logging daemon to be emerged
913 # @param xml_attr Parameter description
914 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
925 ############################################################################
926 #### /etc/make.conf Configuration
927
928 ##
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 if 'name' not in attr.keys():
936 raise GLIException("MakeConfError", 'fatal', 'make_conf_add_var', "Every value needs to have a variable name!")
937
938 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
943 ##
944 # 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 self._etc_files['make.conf'] = make_conf
950
951 ##
952 # Return a dictionary of the make.conf
953 def get_make_conf(self):
954 if "make.conf" in self._etc_files:
955 return self._etc_files['make.conf']
956 else:
957 return {}
958
959 ##
960 # Serializes make.conf (no longer used)
961 def serialize_make_conf(self):
962 if self.get_make_conf() != {}:
963 self.xmldoc += "<make-conf>"
964
965 # keys should always be in the same order!
966 make_conf = self.get_make_conf()
967 make_conf_keys = make_conf.keys()
968 make_conf_keys.sort()
969
970 for var in make_conf_keys:
971 self.xmldoc += "<variable name=\"%s\">%s</variable>" % (var, make_conf[var])
972
973 self.xmldoc += "</make-conf>"
974
975 ############################################################################
976 #### MTA Selection
977
978 ##
979 # Sets the intended MTA package
980 # @param xml_path Used internally by the XML parser. Should be None when calling directly
981 # @param mta package name of mta
982 # @param xml_attr Parameter description
983 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
988 ##
989 # returns the MTA
990 def get_mta_pkg(self):
991 return self._mta_pkg
992
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 dhcp_options = broadcast = attr[1]
1034 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 # Check type
1070 if type(network_interfaces) != dict:
1071 raise GLIException("NetworkInterfacesError", 'fatal', 'set_network_interfaces', "Must be a dictionary!")
1072
1073 self._network_interfaces = {}
1074 for device in network_interfaces:
1075 self.add_network_interface(None, device, network_interfaces[device])
1076
1077 ##
1078 # 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 self.xmldoc += "<network-interfaces>"
1087 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 self.xmldoc += "<device %s>%s</device>" % (attrs, iface)
1095 else:
1096 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
1099 ############################################################################
1100 #### Network Mounts
1101
1102 ##
1103 # FIXME: agaffney: Brief description of function
1104 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1105 # @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
1121 ##
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
1127 ##
1128 # 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 self.xmldoc += "<network-mounts>"
1138 for mount in netmounts:
1139 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
1142 ############################################################################
1143 #### NIS Domain Name
1144
1145 ##
1146 # nisdomainname is a string containing the NIS domainname for the new system.
1147 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1148 # @param nisdomainname the name. is a string.
1149 # @param xml_attr not used here
1150 def set_nisdomainname(self, xml_path, nisdomainname, xml_attr):
1151 # Check type
1152 if type(nisdomainname) != str:
1153 raise GLIException("NISDomainnameError", 'fatal', 'set_nisdomainname', "Must be a string!")
1154
1155 self._nisdomainname = nisdomainname
1156
1157 ##
1158 # Returns nisdomainname
1159 def get_nisdomainname(self):
1160 return self._nisdomainname
1161
1162 ############################################################################
1163 #### Partitioning
1164
1165 ##
1166 # 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 disklabel = attr[1]
1175 else:
1176 if "devnode" in attr.getNames():
1177 devnode = str(attr.getValue("devnode"))
1178 if "disklabel" in attr.getNames():
1179 disklabel = str(attr.getValue("disklabel"))
1180 else:
1181 disklabel = ""
1182 self._partition_current_device = devnode
1183 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 self._temp_partition_table = {}
1188
1189
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 # 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 if type(part_entry['format']) == str: part_entry['format'] = GLIUtility.strtobool(part_entry['format'])
1212 # if GLIUtility.is_numeric(part_entry['end']): part_entry['end'] = long(part_entry['end'])
1213 # if GLIUtility.is_numeric(part_entry['start']): part_entry['start'] = long(part_entry['start'])
1214 if GLIUtility.is_numeric(part_entry['mb']): part_entry['mb'] = long(part_entry['mb'])
1215 if GLIUtility.is_numeric(part_entry['minor']):
1216 if part_entry['type'] == "free":
1217 part_entry['minor'] = float(part_entry['minor'])
1218 else:
1219 part_entry['minor'] = int(part_entry['minor'])
1220 if GLIUtility.is_numeric(part_entry['origminor']): part_entry['origminor'] = int(part_entry['origminor'])
1221 self._temp_partition_table[part_entry['minor']] = part_entry
1222
1223 ############################################################################
1224 #### Partition Tables
1225
1226 ##
1227 # Sets the partition Tables
1228 # @param partition_tables multilevel dictionary described below.
1229 def set_partition_tables(self, partition_tables):
1230 """
1231 Sets the partition tables. A partition is a multi level dictionary in the following format:
1232 { <device (local)>: <partition table>, <device (nfs)>: <mount point> }
1233
1234 <device (local)> is a string containing the path to the local file. (ie. '/dev/hda')
1235 <device (nfs)> is a string containing the ip address of the nfs mount. (ie. '192.168.1.2')
1236
1237 <partition table> is a dictionary in the following format:
1238 { <minor>: { 'mb': <size in mb>, 'type': <type>, 'mountpoint': <mount point>, 'start': <start cylinder>,
1239 'end': <end cylinder>, 'mountopts': <mount options>, 'format': <format> } }
1240
1241 ie. partition_tables['/dev/hda'][1] would return { 'mb': 0, 'type': 'ext3', 'mountpoint': '/boot', 'start': 12345,
1242 'end': 34567, 'mountopts': 'auto', format: 'False' }
1243
1244 Types are as follows:
1245 string: <device>, <mount point>, <mount options>, <type>
1246 integer: <minor>, <size in mb>, <start cylinder>, <end cylinder>
1247 boolean: <format>
1248
1249 Current <type> options include:
1250 ext2, ext3, reiserfs, xfs, jfs, linux-swap, extended, others?
1251
1252 There will be a method in the partitioning code to make sure that the current parition_tables can actually be implemented.
1253 Should we call that function to test the culpability of our potential partitioning scheme?
1254 Should we create a method in the Controller to take raw variables and put them in the proper structure?
1255 Are all filesystems supported by all arches?
1256 """
1257
1258 # All the sanity checks are being commented out until I can fix them for the GLIStorageDevice stuff
1259 """
1260 if type(partition_tables) != dict:
1261 raise GLIException("PartitionTableError", 'fatal', 'set_partition_tables', "Invalid data type! partition_tables is a dict...")
1262
1263 for device in partition_tables:
1264
1265 # If the device is a valid local device...
1266 if GLIUtility.is_device(device):
1267
1268 # We should check to make sure device is in /proc/partitions
1269 # If it is in /proc/partitions, it is a partitionable device
1270
1271 # ... then loop through each minor to check data
1272 for minor in partition_tables[device]:
1273
1274 # Make sure that the <minor> is an integer or can be converted to one
1275 try:
1276 int(minor)
1277 except:
1278 raise GLIException("ParitionTableError", 'fatal', 'set_partition_tables', "The minor you specified (" + minor + ") is not an integer!")
1279
1280 # Make sure that a minor number is valid
1281 if minor < 1:
1282 raise GLIException("ParitionTableError", 'fatal', 'set_partition_tables', "The minor you specified (" + minor + ") is not a valid minor!")
1283
1284 # Make sure that <size>, <type> and <mount point> are all set
1285 #if len(partition_tables[device][minor]) != 3:
1286 # raise GLIException("ParitionTableError", 'fatal', 'set_partition_tables', "The number of attributes for minor " + minor + " is incorrect!")
1287 #
1288 # Make sure that the <size> is an integer or can be converted to one
1289 #try:
1290 # int(partition_tables[device][minor][0])
1291 #except:
1292 # raise GLIException("ParitionTableError", 'fatal', 'set_partition_tables', "The size you specified (" + partition_tables[device][minor][0] + ") is not an integer!")
1293
1294 # Else, if the device is a valid remote device (hostname or ip)
1295 elif GLIUtility.is_ip(device) or GLIUtility.is_hostname(device):
1296
1297 pass
1298 # Make sure that only the mount point is set
1299 # if type(partition_tables[device]) != str:
1300 # raise GLIException("ParitionTableError", 'fatal', 'set_partition_tables', "Invalid mount point for nfs mount (device: " + device + ")!")
1301
1302 # If the device is not a local or remote device, then it is invalid
1303 else:
1304 raise GLIException("PartitionTableError", 'fatal', 'set_partition_tables', "The device you specified (" + device + ") is not valid!")
1305 """
1306
1307 # If all the tests clear, then set the variable
1308 self._partition_tables = partition_tables
1309
1310 ##
1311 # Returns partition_tables
1312 def get_partition_tables(self):
1313 return self._partition_tables
1314
1315 ##
1316 # Serializes partition tables
1317 def serialize_partition_tables(self):
1318 if self.get_partition_tables() != {}:
1319 partitions = self.get_partition_tables()
1320 self.xmldoc += "<partitions>";
1321 for device in partitions.keys():
1322 self.xmldoc += "<device devnode=\"%s\" disklabel=\"%s\">" % (device, partitions[device].get_disklabel())
1323 ips = partitions[device].get_install_profile_structure()
1324 for minor in ips:
1325 part = ips[minor]
1326 self.xmldoc += "<partition minor=\"%s\" origminor=\"%s\" mb=\"%s\" type=\"%s\" mountpoint=\"%s\" mountopts=\"%s\" format=\"%s\" mkfsopts=\"%s\" />" % (str(minor), str(part['origminor']), str(part['mb']), str(part['type']), str(part['mountpoint']), str(part['mountopts']), str(part['format']), str(part['mkfsopts']))
1327 self.xmldoc += "</device>"
1328 self.xmldoc += "</partitions>"
1329
1330 ############################################################################
1331 #### Portage Snapshot URI
1332
1333 ##
1334 # portage_tree_snapshot_uri is a string defining the path to a portage tree
1335 # snapshot. (ie. 'file:///mnt/cdrom/snapshots/portage-*.tar.bz2')
1336 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1337 # @param portage_tree_snapshot_uri URI of the portage tree shapshot location
1338 # @param xml_attr not used here
1339 def set_portage_tree_snapshot_uri(self, xml_path, portage_tree_snapshot_uri, xml_attr):
1340 # Check type
1341 if type(portage_tree_snapshot_uri) != str:
1342 raise GLIException("PortageTreeSnapshotURIError", 'fatal', 'set_portage_tree_snapshot_uri', "Must be a string!")
1343
1344 self._portage_tree_snapshot_uri = portage_tree_snapshot_uri
1345
1346 ##
1347 # Returns portage_tree_snapshot_uri
1348 def get_portage_tree_snapshot_uri(self):
1349 return self._portage_tree_snapshot_uri
1350
1351 ############################################################################
1352 #### Portage Tree Sync Type
1353
1354 ##
1355 # Sets the sync type to be used by portage
1356 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1357 # @param portage_tree_sync string with sync type
1358 # @param xml_attr not used here
1359 def set_portage_tree_sync_type(self, xml_path, portage_tree_sync, xml_attr):
1360 # Check type
1361 if type(portage_tree_sync) != str:
1362 raise GLIException("PortageTreeSyncError", 'fatal', 'set_portage_tree_sync_type', "Must be a string!")
1363
1364 if string.lower(portage_tree_sync) not in ('sync', 'webrsync', 'custom', 'snapshot', 'none'):
1365 raise GLIException("PortageTreeSyncError", 'fatal', 'set_portage_tree_sync_type', "Invalid Input!")
1366
1367 self._portage_tree_sync_type = string.lower(portage_tree_sync)
1368
1369 ##
1370 # Returns portage_tree_sync
1371 def get_portage_tree_sync_type(self):
1372 return self._portage_tree_sync_type
1373
1374 ############################################################################
1375 #### Post-Install Script URI
1376
1377 ##
1378 # Sets the URI for the post install script
1379 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1380 # @param post_install_script_uri the URI
1381 # @param xml_attr Parameter description
1382 def set_post_install_script_uri(self, xml_path, post_install_script_uri, xml_attr):
1383 self._post_install_script_uri = post_install_script_uri
1384
1385 ##
1386 # Returns the URI for the post install script
1387 def get_post_install_script_uri(self):
1388 return self._post_install_script_uri
1389
1390 ############################################################################
1391 #### /etc/rc.conf Configuration
1392
1393 ##
1394 # Adds a variable set for the new system rc.conf
1395 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1396 # @param data a string that is the value of the variable name.
1397 # @param attr an xml attribute that contains the name of the variable
1398 def rc_conf_add_var(self, xml_path, data, attr):
1399 if 'name' not in attr.keys():
1400 raise GLIException("RCConfError", 'fatal', 'rc_conf_add_var', "Every value needs to have a variable name!")
1401
1402 varName = attr['name']
1403 if not "rc.conf" in self._etc_files:
1404 self._etc_files['rc.conf'] = {}
1405 self._etc_files[str(varName)] = str(data)
1406
1407 ##
1408 # rc_conf is a dictionary that will be set to _rc_conf
1409 # There is no checking that needs to be done, so please sure sure that the rc_conf dictionary
1410 # that is passed in is valid.Brief description of function
1411 # @param rc_conf dictionary in the format specified above.
1412 def set_rc_conf(self, rc_conf):
1413 self._etc_files['rc.conf'] = rc_conf
1414
1415 ##
1416 # Return a dictionary of the make.conf
1417 def get_rc_conf(self):
1418 if "rc.conf" in self._etc_files:
1419 return self._etc_files['rc.conf']
1420 else:
1421 return {}
1422
1423 ##
1424 # Serializes rc.conf (no longer used)
1425 def serialize_rc_conf(self):
1426 if self.get_rc_conf() != {}:
1427 self.xmldoc += "<rc-conf>"
1428
1429 rc_conf = self.get_rc_conf()
1430 for var in rc_conf:
1431 self.xmldoc += "<variable name=\"%s\">%s</variable>" % (var, rc_conf[var])
1432
1433 self.xmldoc += "</rc-conf>"
1434
1435 ############################################################################
1436 #### Root Password Hash
1437
1438 ##
1439 # root_pass_hash is a string containing an md5 password hash to be assinged as the password for the root user.
1440 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1441 # @param root_pass_hash Parameter description
1442 # @param xml_attr Parameter description
1443 def set_root_pass_hash(self, xml_path, root_pass_hash, xml_attr):
1444 # Check type
1445 if type(root_pass_hash) != str:
1446 raise GLIException("RootPassHashError", 'fatal', 'set_root_pass_hash', "Must be a string!")
1447 self._root_pass_hash = root_pass_hash
1448
1449 ##
1450 # Returns root_pass_hash
1451 def get_root_pass_hash(self):
1452 return self._root_pass_hash
1453
1454 ############################################################################
1455 #### RSYNC Proxy
1456
1457 ##
1458 # RSYNC proxy is a uri containing a proxy if needed for rsync traffic. (ie. 'rsync://myhost.mydomain:myport')
1459 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1460 # @param rsync_proxy the proxy address
1461 # @param xml_attr not used here
1462 def set_rsync_proxy(self, xml_path, rsync_proxy, xml_attr):
1463 # Check type
1464 if rsync_proxy and not GLIUtility.is_uri(rsync_proxy):
1465 raise GLIException("RSYNCProxyError", 'fatal', 'set_rsync_proxy', "Must be a uri!")
1466 self._rsync_proxy = rsync_proxy
1467
1468 ##
1469 # Returns RSYNC proxy
1470 def get_rsync_proxy(self):
1471 return self._rsync_proxy
1472
1473 ############################################################################
1474 #### Services
1475
1476 ##
1477 # Set the services to be started on bootup. Services should be
1478 # seperated by ','. WARNING: This used to be ' ' instead!
1479 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1480 # @param services comma-separated list of services
1481 # @param xml_attr Parameter description
1482 def set_services(self, xml_path, services, xml_attr):
1483 if type(services) == str:
1484 services = services.split(',')
1485 else:
1486 raise GLIException("ServicesError", 'fatal', 'set_services', "Invalid input!")
1487
1488 for service in services:
1489 if not GLIUtility.is_realstring(service):
1490 raise GLIException("ServicesError", 'fatal', 'set_services', service + " must be a valid string!")
1491 self._services = services
1492
1493 ##
1494 # This returns a list of the packages:
1495 def get_services(self):
1496 return self._services
1497
1498 ##
1499 # Serializes services
1500 def serialize_services(self):
1501 if self.get_services() != ():
1502 self.xmldoc += "<services>"
1503 self.xmldoc += string.join(self.get_services(), ',')
1504 self.xmldoc += "</services>"
1505
1506 ############################################################################
1507 #### Stage Tarball URI
1508
1509 ##
1510 # stage_tarball_uri is a string that is the full path to the tarball you
1511 # wish to use. (ie. 'file:///path/to/mytarball.tar.bz2')
1512 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1513 # @param stage_tarball_uri string of URI for stage tarball location.
1514 # @param xml_attr not used here.
1515 def set_stage_tarball_uri(self, xml_path, stage_tarball_uri, xml_attr):
1516 # Check type
1517 if type(stage_tarball_uri) != str:
1518 raise GLIException("StageTarballURIError", 'fatal', 'set_stage_tarball_uri', "Must be a string!")
1519
1520 # Check validity (now done in the FE)
1521 #if not stage_tarball_uri:
1522 # raise GLIException("CustomStage3TarballURIError", 'fatal', 'set_stage_tarball_uri', "Empty URI!")
1523
1524 self._stage_tarball_uri = stage_tarball_uri
1525
1526 ##
1527 # Returns stage_tarball_uri
1528 def get_stage_tarball_uri(self):
1529 return self._stage_tarball_uri
1530
1531 ############################################################################
1532 #### Timezone
1533
1534 ##
1535 # time_zone is a string defining the time zone to use.
1536 # Time zones are found in /usr/share/zoneinfo/. Syntax is 'UTC' or 'US/Eastern'.
1537 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1538 # @param time_zone string of the intended timezone
1539 # @param xml_attr not used here.
1540 def set_time_zone(self, xml_path, time_zone, xml_attr):
1541 # Check type
1542 if type(time_zone) != str:
1543 raise GLIException("TimeZoneError", 'fatal', 'set_time_zone', "Must be a string!")
1544 self._time_zone = time_zone
1545
1546 ##
1547 # Returns time_zone
1548 def get_time_zone(self):
1549 return self._time_zone
1550
1551 ############################################################################
1552 #### Users
1553
1554 ##
1555 # Adds a user to the list of users
1556 # @param xml_path Used internally by the XML parser. Should be None when calling directly
1557 # @param username name of user to be added
1558 # @param attr=None parameters for the user.
1559 def add_user(self, xml_path, username, attr=None):
1560 """
1561 This will take a username (that is a string) and a set of attributes and it will verify everything is valid
1562 and convert it into a 7-tuple set. Then it adds this tuple into the users list.
1563 username and hash are manditory. All other attributes are optional. Or this method will
1564 take a 7-tuple set, verify it's correctness and then append it to the _users list.
1565 All items are strings except <uid>, which is an integer, and groups, which is a tuple.
1566
1567 The finished tuples look like this:
1568 ( <user name>, <password hash>, (<tuple of groups>), <shell>, <home directory>, <user id>, <user comment> )
1569
1570 """
1571 hash = ''
1572 shell = None
1573 groups = None
1574 shell = None
1575 homedir = None
1576 uid = None
1577 comment = None
1578
1579 if type(username) == tuple:
1580 if len(username) != 7:
1581 raise GLIException("UserError", 'fatal', 'add_user', "Wrong format for user tuple!")
1582
1583 username_tmp = username[0]
1584 hash = username[1]
1585 groups = username[2]
1586 shell = username[3]
1587 homedir = username[4]
1588 uid = username[5]
1589 comment = username[6]
1590 username = username_tmp
1591
1592 if type(groups) != tuple:
1593 if groups != None:
1594 groups = tuple(groups.split(','))
1595 else:
1596 for attrName in attr.keys():
1597 if attrName == 'groups':
1598 groups = tuple(str(attr[attrName]).split(','))
1599 elif attrName == 'shell':
1600 shell = str(attr[attrName])
1601 elif attrName == 'hash':
1602 hash = str(attr[attrName])
1603 elif attrName == 'homedir':
1604 homedir = str(attr[attrName])
1605 elif attrName == 'uid':
1606 if attr[attrName]:
1607 uid = int(attr[attrName])
1608 elif attrName == 'comment':
1609 comment = str(attr[attrName])
1610
1611 allowable_nonalphnum_characters = '_-'
1612
1613 if not GLIUtility.is_realstring(username):
1614 raise GLIException("UserError", 'fatal', 'add_user', "username must be a non-empty string")
1615
1616 if username[0] not in (string.lowercase + string.uppercase):
1617 raise GLIException("UsersError", 'fatal', 'add_user', "A username must start with a letter!")
1618
1619 for x in username:
1620 if x not in (string.lowercase + string.uppercase + string.digits + allowable_nonalphnum_characters):
1621 raise GLIException("UsersError", 'fatal', 'add_user', "A username must contain only letters, numbers, or these symbols: " + allowable_nonalphnum_characters)
1622
1623 for user in self._users:
1624 if username == user[0]:
1625 raise GLIException("UserError", 'fatal', 'add_user', "This username already exists!")
1626
1627 if (hash == None) or (hash == ''):
1628 raise GLIException("UserError", 'fatal', 'add_user', "A password hash must be given for every user!")
1629
1630 self._users.append((username,hash,groups,shell,homedir,uid,comment))
1631
1632 ##
1633 # Remove "username" from the _users list.
1634 # @param username name of user to be removed
1635 def remove_user(self, username):
1636 for user in self._users:
1637 if username == user[0]:
1638 self._users.remove(user)
1639 break
1640
1641 ##
1642 # users is a tuple(user) of tuple's. This sets _users to this set of tuples.
1643 # @param users a tuple(user) of tuple's.
1644 def set_users(self, users):
1645 self._users = []
1646 if users != None:
1647 for user in users:
1648 self._users.append(user)
1649
1650 ##
1651 # Returns users
1652 def get_users(self):
1653 return self._users
1654
1655 ##
1656 # Serializes users
1657 def serialize_users(self):
1658 if self.get_users() != []:
1659 self.xmldoc += "<users>"
1660 users = self.get_users()
1661 for user in users:
1662 attrstr = ""
1663 username = user[0]
1664
1665 if user[1] != None:
1666 attrstr += "hash=\"%s\" " % user[1]
1667 if user[2] != None:
1668 attrstr += "groups=\"%s\" " % string.join(user[2],',')
1669 if user[3] != None:
1670 attrstr += "shell=\"%s\" " % user[3]
1671 if user[4] != None:
1672 attrstr += "homedir=\"%s\" " % user[4]
1673 if user[5] != None:
1674 attrstr += "uid=\"%s\" " % user[5]
1675 if user[6] != None:
1676 attrstr += "comment=\"%s\" " % user[6]
1677
1678 self.xmldoc += "<user %s>%s</user>" % (string.strip(attrstr), username)
1679 self.xmldoc += "</users>"

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20