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

Contents of /trunk/src/GLIInstallProfile.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 635 - (show annotations) (download) (as text)
Thu Jun 9 23:13:57 2005 UTC (15 years, 5 months ago) by agaffney
File MIME type: text/x-python
File size: 57581 byte(s)
Apply latest long/mkfsopts patch from robbat2

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

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.20