/[smeserver]/cdrom.image/updates/kickstart.py
ViewVC logotype

Annotation of /cdrom.image/updates/kickstart.py

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (hide annotations) (download) (as text)
Wed Apr 5 21:11:51 2006 UTC (18 years, 8 months ago) by slords
Branch: MAIN
Changes since 1.3: +2 -2 lines
Content type: text/x-python
Cleanup

1 slords 1.1 #
2     # kickstart.py: kickstart install support
3     #
4     # Copyright 1999-2004 Red Hat, Inc.
5     #
6     # This software may be freely redistributed under the terms of the GNU
7     # library public license.
8     #
9     # You should have received a copy of the GNU Library Public License
10     # along with this program; if not, write to the Free Software
11     # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
12     #
13    
14     import iutil
15     import isys
16     import os
17     from installclass import BaseInstallClass
18     from partitioning import *
19     from autopart import *
20     from fsset import *
21     from flags import flags
22     from constants import *
23     import sys
24     import raid
25     import string
26     import partRequests
27     import urllib2
28     import lvm
29    
30     from rhpl.translate import _
31     from rhpl.log import log
32    
33     KS_MISSING_PROMPT = 0
34     KS_MISSING_IGNORE = 1
35    
36     class KickstartError(Exception):
37     def __init__(self, val = ""):
38     self.value = val
39    
40     def __str__ (self):
41     return self.value
42    
43     class KickstartValueError(KickstartError):
44     def __init__(self, val = ""):
45     self.value = val
46    
47     def __str__ (self):
48     return self.value
49    
50     class KSAppendException(KickstartError):
51     def __init__(self, s=""):
52     self.str = s
53    
54     def __str__(self):
55     return self.str
56    
57     class Script:
58     def __repr__(self):
59     str = ("(s: '%s' i: %s c: %d)") % \
60     (self.script, self.interp, self.inChroot)
61     return string.replace(str, "\n", "|")
62    
63     def __init__(self, script, interp, inChroot, logfile = None):
64     self.script = script
65     self.interp = interp
66     self.inChroot = inChroot
67     self.logfile = logfile
68    
69     def run(self, chroot, serial):
70     scriptRoot = "/"
71     if self.inChroot:
72     scriptRoot = chroot
73    
74     path = scriptRoot + "/tmp/ks-script"
75    
76     f = open(path, "w")
77     f.write(self.script)
78     f.close()
79     os.chmod(path, 0700)
80    
81     if self.logfile is not None:
82     messages = self.logfile
83     elif serial:
84     messages = "/tmp/ks-script.log"
85     else:
86     messages = "/dev/tty3"
87    
88     rc = iutil.execWithRedirect(self.interp,
89     [self.interp,"/tmp/ks-script"],
90     stdout = messages, stderr = messages,
91     root = scriptRoot)
92    
93     if rc != 0:
94     log("WARNING - Error code %s encountered running a kickstart %%pre/%%post script", rc)
95    
96     os.unlink(path)
97    
98     class KickstartBase(BaseInstallClass):
99     name = "kickstart"
100 slords 1.4
101 slords 1.3 def postAction(self, rootPath, serial, intf):
102     win = intf.waitWindow(_("Post Install Script"),
103     _("The post installation script is running..."))
104    
105     script = ( "/sbin/syslogd &\n"
106     "sleep 2\n"
107     "/sbin/e-smith/signal-event post-install\n" )
108     s = Script(script, interp="/bin/sh", inChroot=1)
109     log("%s", s)
110     s.run(rootPath, serial)
111     win.pop()
112 slords 1.4
113 slords 1.1 log("Running kickstart %%post script(s)")
114     for script in self.postScripts:
115     script.run(rootPath, serial)
116     log("All kickstart %%post script(s) have been run")
117    
118     def doRootPw(self, id, args):
119     (args, extra) = isys.getopt(args, '', [ 'iscrypted' ])
120    
121     isCrypted = 0
122     for n in args:
123     (str, arg) = n
124     if (str == '--iscrypted'):
125     isCrypted = 1
126    
127     if len(extra) != 1:
128     raise KickstartValueError, "a single argument is expected to rootPw"
129    
130     self.setRootPassword(id, extra[0], isCrypted = isCrypted)
131     self.skipSteps.append("accounts")
132    
133     def doFirewall(self, id, args):
134     (args, extra) = isys.getopt(args, '',
135     [ 'dhcp', 'ssh', 'telnet', 'smtp', 'http', 'ftp', 'enabled',
136     'enable', 'port=', 'high', 'medium', 'disabled', 'disable',
137     'trust=' ])
138    
139     enable = -1
140     trusts = []
141     ports = []
142    
143     for n in args:
144     (str, arg) = n
145     if str == '--ssh':
146     ports.append("22:tcp")
147     elif str == '--telnet':
148     ports.append("23:tcp")
149     elif str == '--smtp':
150     ports.append("25:tcp")
151     elif str == '--http':
152     ports.extend(["80:tcp", "443:tcp"])
153     elif str == '--ftp':
154     ports.append("21:tcp")
155     elif str == '--high' or str == '--medium':
156     log("used deprecated firewall option: %s" %(str[2:],))
157     enable = 1
158     elif str == '--enabled' or str == "--enable":
159     enable = 1
160     elif str == '--disabled' or str == "--disable":
161     enable = 0
162     elif str == '--trust':
163     trusts.append(arg)
164     elif str == '--port':
165     theports = arg.split(",")
166     for p in theports:
167     p = p.strip()
168     if p.find(":") == -1:
169     p = "%s:tcp" %(p,)
170     ports.append(p)
171    
172     self.setFirewall(id, enable, trusts, ports)
173    
174     def doSELinux(self, id, args):
175     (args, extra) = isys.getopt(args, '',
176     [ 'disabled', 'enforcing',
177     'permissive' ] )
178    
179     sel = 2
180    
181     for n in args:
182     (str, arg) = n
183     if str == "--disabled":
184     sel = 0
185     elif str == "--permissive":
186     sel = 1
187     elif str == "--enforcing":
188     sel = 2
189    
190     self.setSELinux(id, sel)
191    
192     def doZFCP(self, id, args):
193     (args, extra) = isys.getopt(args, '',
194     ["devnum", "scsiid", "wwpn", "scsilun",
195     "fcplun"])
196    
197     devnum = None
198     scsiid = None
199     wwpn = None
200     scsilun = None
201     fcplun = None
202    
203     for n in args:
204     (str, arg) = n
205     if str == "--devnum":
206     devnum = id.zfcp.sanitizeDeviceInput(arg)
207     elif str == "--scsid":
208     scsiid = id.zfcp.sanitizeHexInput(arg)
209     elif str == "--wwpn":
210     wwpn = id.zfcp.sanitizeHexInput(arg)
211     elif str == "--scsilun":
212     scsilun = id.zfcp.sanitizeHexInput(arg)
213     elif str == "--fcplun":
214     fcplun = id.zfcp.sanitizeFCPLInput(arg)
215    
216     if id.zfcp.checkValidDevice(devnum) == -1:
217     raise KickstartValueError, "Invalid devnum specified"
218     if id.zfcp.checkValidID(scsiid) == -1:
219     raise KickstartValueError, "Invalid scsiid specified"
220     if id.zfcp.checkValid64BitHex(wwpn) == -1:
221     raise KickstartValueError, "Invalid wwpn specified"
222     if id.zfcp.checkValidID(scsilun) == -1:
223     raise KickstartValueError, "Invalid scsilun specified"
224     if id.zfcp.checkValid64BitHex(fcplun) == -1:
225     raise KickstartValueError, "Invalid fcplun specified"
226    
227     if ((devnum is None) or (scsiid is None) or (wwpn is None)
228     or (scsilun is None) or (fcplun is None)):
229     raise KickstartError, "ZFCP config must specify all of devnum, scsiid, wwpn, scsilun, and fcplun"
230    
231     self.setZFCP(id, devnum, scsiid, wwpn, scsilun, fcplun)
232     self.skipSteps.append("zfcpconfig")
233    
234     def doAuthconfig(self, id, args):
235     (args, extra) = isys.getopt(args, '',
236     [ 'useshadow', 'enableshadow',
237     'enablemd5',
238     'enablenis', 'nisdomain=', 'nisserver=',
239     'enableldap', 'enableldapauth', 'ldapserver=', 'ldapbasedn=',
240     'enableldaptls',
241     'enablekrb5', 'krb5realm=', 'krb5kdc=', 'krb5adminserver=',
242     'enablehesiod', 'hesiodlhs=', 'hesiodrhs=',
243     'enablesmbauth', 'smbservers=', 'smbworkgroup=',
244     'enablecache'])
245    
246     useShadow = 0
247    
248     useMd5 = 0
249    
250     useNis = 0
251     nisServer = ""
252     nisDomain = ""
253     nisBroadcast = 0
254    
255     useLdap = 0
256     useLdapauth = 0
257     useLdaptls = 0
258     ldapServer = ""
259     ldapBasedn = ""
260    
261     useKrb5 = 0
262     krb5Realm = ""
263     krb5Kdc = ""
264     krb5Admin = ""
265    
266     useHesiod = 0
267     hesiodLhs = ""
268     hesiodRhs = ""
269    
270     useSamba = 0
271     smbServers = ""
272     smbWorkgroup = ""
273    
274     enableCache = 0
275    
276     for n in args:
277     (str, arg) = n
278     if (str == '--enablenis'):
279     useNis = 1
280     elif (str == '--useshadow') or (str == '--enableshadow'):
281     useShadow = 1
282     elif (str == '--enablemd5'):
283     useMd5 = 1
284     elif (str == '--nisserver'):
285     nisServer = arg
286     elif (str == '--nisdomain'):
287     nisDomain = arg
288     elif (str == '--enableldap'):
289     useLdap = 1
290     elif (str == '--enableldapauth'):
291     useLdapauth = 1
292     elif (str == '--ldapserver'):
293     ldapServer = arg
294     elif (str == '--ldapbasedn'):
295     ldapBasedn = arg
296     elif (str == '--enableldaptls'):
297     useLdaptls = 1
298     elif (str == '--enablekrb5'):
299     useKrb5 = 1
300     elif (str == '--krb5realm'):
301     krb5Realm = arg
302     elif (str == '--krb5kdc'):
303     krb5Kdc = arg
304     elif (str == '--krb5adminserver'):
305     krb5Admin = arg
306     elif (str == '--enablehesiod'):
307     useHesiod = 1
308     elif (str == '--hesiodlhs'):
309     hesiodLhs = arg
310     elif (str == '--hesiodrhs'):
311     hesiodRhs = arg
312     elif (str == '--enablesmbauth'):
313     useSamba = 1
314     elif (str == '--smbservers'):
315     smbServers = arg
316     elif (str == '--smbworkgroup'):
317     smbWorkgroup = arg
318     elif (str == '--enablecache'):
319     enableCache = 1
320    
321    
322     if useNis and not nisServer: nisBroadcast = 1
323    
324     self.setAuthentication(id, useShadow, useMd5,
325     useNis, nisDomain, nisBroadcast, nisServer,
326     useLdap, useLdapauth, ldapServer,
327     ldapBasedn, useLdaptls,
328     useKrb5, krb5Realm, krb5Kdc, krb5Admin,
329     useHesiod, hesiodLhs, hesiodRhs,
330     useSamba, smbServers, smbWorkgroup,
331     enableCache)
332    
333     self.skipSteps.append("authentication")
334    
335     def doBootloader (self, id, args, useLilo = 0):
336     (args, extra) = isys.getopt(args, '',
337     [ 'append=', 'location=', 'useLilo', 'lba32',
338     'password=', 'md5pass=', 'linear', 'nolinear',
339     'upgrade', 'driveorder='])
340    
341     validLocations = [ "mbr", "partition", "none", "boot" ]
342     appendLine = ""
343     location = "mbr"
344     password = None
345     md5pass = None
346     forceLBA = 0
347     linear = 1
348     upgrade = 0
349     driveorder = []
350    
351     for n in args:
352     (str, arg) = n
353     if str == '--append':
354     appendLine = arg
355     elif str == '--location':
356     location = arg
357     elif str == '--useLilo':
358     # log("used deprecated option --useLilo, ignoring")
359     useLilo = 1
360     elif str == '--linear':
361     linear = 1
362     elif str == '--nolinear':
363     linear = 0
364     elif str == '--lba32':
365     forceLBA = 1
366     elif str == '--password':
367     password = arg
368     elif str == '--md5pass':
369     md5pass = arg
370     elif str == '--upgrade':
371     upgrade = 1
372     elif str == '--driveorder':
373     driveorder = string.split(arg, ',')
374    
375     if location not in validLocations:
376     raise KickstartValueError, "mbr, partition, or none expected for bootloader command"
377     if location == "none":
378     location = None
379     elif location == "partition":
380     location = "boot"
381    
382     if upgrade and not id.upgrade.get():
383     raise KickstartError, "Selected upgrade mode for bootloader but not doing an upgrade"
384    
385     if upgrade:
386     id.bootloader.kickstart = 1
387     id.bootloader.doUpgradeOnly = 1
388    
389     if location is None:
390     self.skipSteps.append("bootloadersetup")
391     self.skipSteps.append("instbootloader")
392     else:
393     self.showSteps.append("bootloadersetup")
394     self.setBootloader(id, useLilo, location, linear, forceLBA,
395     password, md5pass, appendLine, driveorder)
396    
397     self.skipSteps.append("upgbootloader")
398     self.skipSteps.append("bootloader")
399     self.skipSteps.append("bootloaderadvanced")
400    
401     def doLilo (self, id, args):
402     self.doBootloader(id, args, useLilo = 1)
403    
404     def doFirstboot(self, id, args):
405     (args, extra) = isys.getopt(args, '',
406     ['reconfig', 'enable', 'enabled',
407     'disable', 'disabled'])
408    
409     fb = FIRSTBOOT_SKIP
410    
411     for n in args:
412     (str, arg) = n
413     if str == '--reconfig':
414     fb = FIRSTBOOT_RECONFIG
415     elif str == '--enable' or str == "--enabled":
416     fb = FIRSTBOOT_DEFAULT
417     elif str == '--disable' or str == "--disabled":
418     fb = FIRSTBOOT_SKIP
419    
420     id.firstboot = fb
421    
422    
423     def doLiloCheck (self, id, args):
424     drives = isys.hardDriveDict ().keys()
425     drives.sort(isys.compareDrives)
426     device = drives[0]
427     isys.makeDevInode(device, '/tmp/' + device)
428     fd = os.open('/tmp/' + device, os.O_RDONLY)
429     os.unlink('/tmp/' + device)
430     block = os.read(fd, 512)
431     os.close(fd)
432     if block[6:10] == "LILO":
433     sys.exit(0)
434    
435     def doTimezone(self, id, args):
436     (args, extra) = isys.getopt(args, '',
437     [ 'utc' ])
438    
439     isUtc = 0
440    
441     for n in args:
442     (str, arg) = n
443     if str == '--utc':
444     isUtc = 1
445    
446     self.setTimezoneInfo(id, extra[0], asUtc = isUtc)
447    
448     self.skipSteps.append("timezone")
449    
450    
451     def doXconfig(self, id, args):
452     (args, extra) = isys.getopt(args, '',
453     [ 'server=', 'card=', 'videoram=',
454     'monitor=', 'hsync=', 'vsync=',
455     'resolution=', 'depth=',
456     'startxonboot', 'noprobe', 'defaultdesktop=' ])
457    
458     if extra:
459     raise KickstartValueError, "unexpected arguments to xconfig command"
460    
461     server = None
462     card = None
463     videoRam = None
464     monitor = None
465     hsync = None
466     vsync = None
467     resolution = None
468     depth = None
469     noProbe = 0
470     startX = 0
471     defaultdesktop = ""
472    
473     for n in args:
474     (str, arg) = n
475     if (str == "--noprobe"):
476     noProbe = 1
477     elif (str == "--server"):
478     server = arg
479     elif (str == "--card"):
480     card = arg
481     elif (str == "--videoram"):
482     videoRam = arg
483     elif (str == "--monitor"):
484     monitor = arg
485     elif (str == "--hsync"):
486     hsync = arg
487     elif (str == "--vsync"):
488     vsync = arg
489     elif (str == "--resolution"):
490     resolution = arg
491     elif (str == "--depth"):
492     depth = string.atoi(arg)
493     elif (str == "--startxonboot"):
494     startX = 1
495     elif (str == "--defaultdesktop"):
496     defaultdesktop = arg
497    
498     self.configureX(id, server, card, videoRam, monitor, hsync, vsync,
499     resolution, depth, noProbe, startX)
500     self.setDesktop(id, defaultdesktop)
501    
502     self.skipSteps.append("videocard")
503     self.skipSteps.append("monitor")
504     self.skipSteps.append("xcustom")
505     self.skipSteps.append("handleX11pkgs")
506     self.skipSteps.append("checkmonitorok")
507     self.skipSteps.append("setsanex")
508    
509     def doMonitor(self, id, args):
510     (args, extra) = isys.getopt(args, '',
511     [ 'monitor=', 'hsync=', 'vsync=' ])
512    
513     if extra:
514     raise KickstartValueError, "unexpected arguments to monitor command"
515    
516     monitor = None
517     hsync = None
518     vsync = None
519    
520     for n in args:
521     (str, arg) = n
522     if (str == "--monitor"):
523     monitor = arg
524     elif (str == "--hsync"):
525     hsync = arg
526     elif (str == "--vsync"):
527     vsync = arg
528    
529     self.skipSteps.append("monitor")
530     self.skipSteps.append("checkmonitorok")
531    
532     self.setMonitor(id, hsync = hsync, vsync = vsync,
533     monitorName = monitor)
534    
535     def doUpgrade(self, id, args):
536     self.installType = "upgrade"
537     id.upgrade.set(1)
538    
539     def doNetwork(self, id, args):
540     # nodns is only used by the loader
541     (args, extra) = isys.getopt(args, '',
542     [ 'bootproto=', 'ip=', 'netmask=', 'gateway=', 'nameserver=',
543     'nodns', 'device=', 'hostname=', 'ethtool=', 'onboot=',
544     'dhcpclass=', 'essid=', 'wepkey=', 'notksdevice'])
545     bootProto = "dhcp"
546     ip = None
547     netmask = ""
548     gateway = ""
549     nameserver = ""
550     hostname = ""
551     ethtool = ""
552     essid = ""
553     wepkey = ""
554     onboot = 1
555     device = None
556     dhcpclass = None
557     for n in args:
558     (str, arg) = n
559     if str == "--bootproto":
560     bootProto = arg
561     elif str == "--ip":
562     ip = arg
563     elif str == "--netmask":
564     netmask = arg
565     elif str == "--gateway":
566     gateway = arg
567     elif str == "--nameserver":
568     nameserver = arg
569     elif str == "--device":
570     device = arg
571     elif str == "--hostname":
572     hostname = arg
573     elif str== "--ethtool":
574     ethtool = arg
575     elif str == "--essid":
576     essid = arg
577     elif str == "--wepkey":
578     wepkey = arg
579     elif str== "--onboot":
580     if arg == 'no':
581     onboot = 0
582     else:
583     onboot = 1
584     elif str == "--class":
585     dhcpclass = arg
586    
587     self.setNetwork(id, bootProto, ip, netmask, ethtool, device=device, onboot=onboot, dhcpclass=dhcpclass, essid=essid, wepkey=wepkey)
588     if hostname != "":
589     self.setHostname(id, hostname, override = 1)
590     if nameserver != "":
591     self.setNameserver(id, nameserver)
592     if gateway != "":
593     self.setGateway(id, gateway)
594    
595     def doLang(self, id, args):
596     self.setLanguage(id, args[0])
597     self.skipSteps.append("language")
598    
599     def doLangSupport (self, id, args):
600     (args, extra) = isys.getopt(args, '', [ 'default=' ])
601     deflang = "en_US.UTF-8"
602     if args:
603     deflang = args[0][1]
604     else:
605     # if they specified no default we default to en_US if
606     # they installed support for more than one lang, otherwise
607     # we default to the one language they specified support for
608     if extra is None:
609     deflang = "en_US.UTF-8"
610     elif len(extra) >= 1:
611     deflang = extra[0]
612     else:
613     deflang = "en_US.UTF-8"
614    
615     self.setLanguageDefault (id, deflang)
616     self.setLanguageSupport(id, extra)
617    
618     self.skipSteps.append("languagesupport")
619    
620     def doKeyboard(self, id, args):
621     self.setKeyboard(id, args[0])
622     id.keyboard.beenset = 1
623     self.skipSteps.append("keyboard")
624    
625     def doZeroMbr(self, id, args):
626     self.setZeroMbr(id, 1)
627    
628     def doMouse(self, id, args):
629     #Don't do anything with mice anymore
630     return
631    
632     ## (args, extra) = isys.getopt(args, '', [ 'device=', 'emulthree' ])
633     ## mouseType = "none"
634     ## device = None
635     ## emulThree = 0
636    
637     ## for n in args:
638     ## (str, arg) = n
639     ## if str == "--device":
640     ## device = arg
641     ## elif str == "--emulthree":
642     ## emulThree = 1
643    
644     ## if extra:
645     ## mouseType = extra[0]
646    
647     ## if mouseType != "none":
648     ## self.setMouse(id, mouseType, device, emulThree)
649    
650     ## self.skipSteps.append("mouse")
651    
652     def doReboot(self, id, args):
653     self.skipSteps.append("complete")
654    
655     def doSkipX(self, id, args):
656     self.skipSteps.append("checkmonitorok")
657     self.skipSteps.append("setsanex")
658     self.skipSteps.append("videocard")
659     self.skipSteps.append("monitor")
660     self.skipSteps.append("xcustom")
661     self.skipSteps.append("handleX11pkgs")
662     self.skipSteps.append("writexconfig")
663     if id.xsetup is not None:
664     id.xsetup.skipx = 1
665    
666     def doInteractive(self, id, args):
667     self.interactive = 1
668    
669     def doAutoStep(self, id, args):
670     flags.autostep = 1
671     flags.autoscreenshot = 0
672    
673     (xargs, xtra) = isys.getopt(args, '', ['autoscreenshot'])
674     for n in xargs:
675     (str, arg) = n
676     if str == "--autoscreenshot":
677     flags.autoscreenshot = 1
678    
679    
680     # read the kickstart config... if parsePre is set, only parse
681     # the %pre, otherwise ignore the %pre. assume we're starting in where
682     def readKickstart(self, id, file, parsePre = 0, where = "commands"):
683     handlers = {
684     "auth" : self.doAuthconfig ,
685     "authconfig" : self.doAuthconfig ,
686     "autopart" : self.doAutoPart ,
687     "cdrom" : None ,
688     "clearpart" : self.doClearPart ,
689     "ignoredisk" : self.doIgnoreDisk ,
690     "device" : None ,
691     "deviceprobe" : None ,
692     "driverdisk" : None ,
693     "firewall" : self.doFirewall ,
694     "selinux" : self.doSELinux ,
695     "harddrive" : None ,
696     "install" : None ,
697     "keyboard" : self.doKeyboard ,
698     "lang" : self.doLang ,
699     "langsupport" : self.doLangSupport ,
700     "lilo" : self.doLilo ,
701     "bootloader" : self.doBootloader ,
702     "lilocheck" : self.doLiloCheck ,
703     "mouse" : self.doMouse ,
704     "network" : self.doNetwork ,
705     "nfs" : None ,
706     "part" : self.definePartition ,
707     "partition" : self.definePartition ,
708     "raid" : self.defineRaid ,
709     "volgroup" : self.defineVolumeGroup,
710     "logvol" : self.defineLogicalVolume,
711     "reboot" : self.doReboot ,
712     "poweroff" : self.doReboot ,
713     "halt" : self.doReboot ,
714     "shutdown" : self.doReboot ,
715     "rootpw" : self.doRootPw ,
716     "skipx" : self.doSkipX ,
717     "text" : None ,
718     "graphical" : None ,
719     "cmdline" : None ,
720     "timezone" : self.doTimezone ,
721     "url" : None ,
722     "upgrade" : self.doUpgrade ,
723     "xconfig" : self.doXconfig ,
724     "monitor" : self.doMonitor ,
725     "xdisplay" : None ,
726     "zerombr" : self.doZeroMbr ,
727     "interactive" : self.doInteractive ,
728     "autostep" : self.doAutoStep ,
729     "firstboot" : self.doFirstboot ,
730     "vnc" : None ,
731     }
732    
733     packages = []
734     groups = []
735     excludedPackages = []
736    
737     script = ""
738     scriptInterp = "/bin/sh"
739     scriptLog = None
740     if where == "pre" or where == "traceback":
741     scriptChroot = 0
742     else:
743     scriptChroot = 1
744    
745     for n in open(file).readlines():
746     args = isys.parseArgv(n)
747    
748     # don't eliminate white space or comments from scripts
749     if where not in ["pre", "post", "traceback"]:
750     if not args or args[0][0] == '#': continue
751    
752     if args and (args[0] in ["%pre", "%post", "%traceback"]):
753     if ((where =="pre" and parsePre) or
754     (where in ["post", "traceback"] and not parsePre)):
755     s = Script(script, scriptInterp, scriptChroot, scriptLog)
756     if where == "pre":
757     self.preScripts.append(s)
758     elif where == "post":
759     self.postScripts.append(s)
760     else:
761     self.tracebackScripts.append(s)
762    
763     where = args[0][1:]
764     args = isys.parseArgv(n)
765    
766     script = ""
767     scriptInterp = "/bin/sh"
768     scriptLog = None
769     if where == "pre" or where == "traceback":
770     scriptChroot = 0
771     else:
772     scriptChroot = 1
773    
774     argList = [ 'interpreter=', "log=", "logfile=" ]
775     if where == "post":
776     argList.append('nochroot')
777    
778     (args, extra) = isys.getopt(args, '', argList)
779     for n in args:
780     (str, arg) = n
781    
782     if str == "--nochroot":
783     scriptChroot = 0
784     elif str == "--interpreter":
785     scriptInterp = arg
786     elif str == "--log" or str == "--logfile":
787     scriptLog = arg
788    
789     elif args and args[0] == "%include" and not parsePre:
790     if len(args) < 2:
791     raise KickstartError, "Invalid %include line"
792     else:
793     # read in the included file and set our where appropriately
794     where = self.readKickstart(id, args[1], where = where)
795     elif args and args[0] == "%packages":
796     if ((where =="pre" and parsePre) or
797     (where in ["post", "traceback"] and not parsePre)):
798     s = Script(script, scriptInterp, scriptChroot, scriptLog)
799     if where == "pre":
800     self.preScripts.append(s)
801     elif where == "post":
802     self.postScripts.append(s)
803     else:
804     self.tracebackScripts.append(s)
805    
806     # if we're parsing the %pre, we don't need to continue
807     if parsePre:
808     continue
809    
810     if len(args) > 1:
811     for arg in args[1:]:
812     if arg == "--resolvedeps":
813     id.handleDeps = RESOLVE_DEPS
814     elif arg == "--ignoredeps":
815     id.handleDeps = IGNORE_DEPS
816     elif arg == "--excludedocs":
817     id.excludeDocs = 1
818     elif arg == "--ignoremissing":
819     self.handleMissing = KS_MISSING_IGNORE
820     elif arg == "--nobase":
821     self.addBase = 0
822    
823     where = "packages"
824     self.skipSteps.append("package-selection")
825     else:
826     # if we're parsing the %pre and not in the pre, continue
827     if parsePre and where != "pre":
828     continue
829     elif where == "packages":
830     #Scan for comments in package list...drop off
831     #everything after "#" mark
832     try:
833     ind = string.index(n, "#")
834     n = n[:ind]
835     except:
836     #No "#" found in line
837     pass
838    
839     if n[0] == '@':
840     n = n[1:]
841     n = string.strip (n)
842     groups.append(n)
843     elif n[0] == '-':
844     n = n[1:]
845     n = string.strip(n)
846     excludedPackages.append(n)
847     else:
848     n = string.strip (n)
849     packages.append(n)
850     elif where == "commands":
851     if handlers.has_key(args[0]):
852     if handlers[args[0]] is not None:
853     handlers[args[0]](id, args[1:])
854     else:
855     # unrecognized command
856     raise KickstartError, "Unrecognized ks command: %s\nOn the line: %s" % (args[0], n)
857     elif where in ["pre", "post", "traceback"]:
858     script = script + n
859     else:
860     raise KickstartError, "I'm lost in kickstart"
861    
862     self.groupList.extend(groups)
863     self.packageList.extend(packages)
864     self.excludedList.extend(excludedPackages)
865    
866     # test to see if they specified to clear partitions and also
867     # tried to --onpart on a logical partition
868     #
869     # XXX
870     #
871     #if iutil.getArch() == 'i386' and self.fstab:
872     #clear = self.getClearParts()
873     #if clear == FSEDIT_CLEAR_LINUX or clear == FSEDIT_CLEAR_ALL:
874     #for (mntpoint, (dev, fstype, reformat)) in self.fstab:
875     #if int(dev[-1:]) > 4:
876     #raise RuntimeError, "Clearpart and --onpart on non-primary partition %s not allowed" % dev
877    
878     if ((where =="pre" and parsePre) or
879     (where in ["post", "traceback"] and not parsePre)):
880     s = Script(script, scriptInterp, scriptChroot, scriptLog)
881     if where == "pre":
882     self.preScripts.append(s)
883     elif where == "post":
884     self.postScripts.append(s)
885     else:
886     self.tracebackScripts.append(s)
887    
888     return where
889    
890     def doClearPart(self, id, args):
891     type = CLEARPART_TYPE_NONE
892     drives = None
893     initAll = 0
894    
895     (args, extra) = isys.getopt(args, '', [ 'linux', 'all', 'drives=',
896     'initlabel', 'none'])
897    
898     for n in args:
899     (str, arg) = n
900     if str == '--linux':
901     type = CLEARPART_TYPE_LINUX
902     elif str == '--all':
903     type = CLEARPART_TYPE_ALL
904     elif str == '--drives':
905     drives = string.split(arg, ',')
906     elif str == '--initlabel':
907     initAll = 1
908     elif str == '--none':
909     type = CLEARPART_TYPE_NONE
910    
911     self.setClearParts(id, type, drives, initAll = initAll)
912    
913     # this adds a partition to the autopartition list replacing anything
914     # else with this mountpoint so that you can use autopart and override /
915     def addPartRequest(self, partitions, request):
916     if not request.mountpoint:
917     partitions.autoPartitionRequests.append(request)
918     return
919    
920     for req in partitions.autoPartitionRequests:
921     if req.mountpoint and req.mountpoint == request.mountpoint:
922     partitions.autoPartitionRequests.remove(req)
923     break
924     partitions.autoPartitionRequests.append(request)
925    
926     def doAutoPart(self, id, args):
927     # sets up default autopartitioning. use clearpart separately
928     # if you want it
929     self.setDefaultPartitioning(id, doClear = 0)
930    
931     id.partitions.isKickstart = 1
932    
933     self.skipSteps.append("partition")
934     self.skipSteps.append("partitionmethod")
935     self.skipSteps.append("partitionmethodsetup")
936     self.skipSteps.append("fdisk")
937     self.skipSteps.append("autopartition")
938     self.skipSteps.append("zfcpconfig")
939    
940     def defineLogicalVolume(self, id, args):
941     (args, extra) = isys.getopt(args, '', [ 'vgname=',
942     'size=',
943     'name=',
944     'fstype=',
945     'percent=',
946     'maxsize=',
947     'grow',
948     'recommended',
949     'noformat',
950     'useexisting'])
951    
952     mountpoint = None
953     vgname = None
954     size = None
955     name = None
956     fstype = None
957     percent = None
958     grow = 0
959     maxSizeMB = 0
960     format = 1
961     recommended = None
962     preexist = 0
963    
964     for n in args:
965     (str, arg) = n
966     if str == '--vgname':
967     vgname = arg
968     elif str == '--size':
969     size = int(arg)
970     elif str == '--name':
971     name = arg
972     elif str == '--fstype':
973     fstype = arg
974     elif str == '--percent':
975     percent = int(arg)
976     elif str == '--maxsize':
977     maxSizeMB = int(arg)
978     elif str == '--grow':
979     grow = 1
980     elif str == '--recommended':
981     recommended = 1
982     elif str == "--noformat":
983     format = 0
984     preexist = 1
985     elif str == "--useexisting":
986     preexist = 1
987    
988     if extra[0] == 'swap':
989     filesystem = fileSystemTypeGet('swap')
990     mountpoint = None
991     if recommended:
992     (size, maxSizeMB) = iutil.swapSuggestion()
993     grow = 1
994     else:
995     if fstype:
996     filesystem = fileSystemTypeGet(fstype)
997     else:
998     filesystem = fileSystemTypeGetDefault()
999    
1000     mountpoint = extra[0]
1001    
1002     # sanity check mountpoint
1003     if mountpoint is not None and mountpoint[0] != '/':
1004     raise KickstartError, "The mount point \"%s\" is not valid." % (mountpoint,)
1005    
1006     if not vgname:
1007     raise KickstartError, "Must specify the volume group for the logical volume to be in"
1008     if not size and not percent and not preexist:
1009     raise KickstartError, "Must specify the size of a logical volume"
1010     if percent and percent <= 0 or percent > 100:
1011     raise KickstartValueError, "Logical Volume percentage must be between 0 and 100 percent"
1012    
1013     if not name:
1014     raise KickstartError, "Must specify a logical volume name"
1015    
1016     vgid = self.ksVGMapping[vgname]
1017     for areq in id.partitions.autoPartitionRequests:
1018     if areq.type == REQUEST_LV:
1019     if areq.volumeGroup == vgid and areq.logicalVolumeName == name:
1020     raise KickstartValueError, "Logical volume name %s already used in volume group %s" % (name,vgname)
1021    
1022     if not self.ksVGMapping.has_key(vgname):
1023     raise KickstartValueError, "Logical volume specifies a non-existent volume group"
1024    
1025     request = partRequests.LogicalVolumeRequestSpec(filesystem,
1026     format = format,
1027     mountpoint = mountpoint,
1028     size = size,
1029     percent = percent,
1030     volgroup = vgid,
1031     lvname = name,
1032     grow = grow,
1033     maxSizeMB=maxSizeMB,
1034     preexist = preexist)
1035     self.addPartRequest(id.partitions, request)
1036    
1037    
1038     def defineVolumeGroup(self, id, args):
1039     (args, extra) = isys.getopt(args, '', ['noformat','useexisting',
1040     'pesize='])
1041    
1042     preexist = 0
1043     format = 1
1044     pesize = 32768
1045    
1046     vgname = extra[0]
1047    
1048     for n in args:
1049     (str, arg) = n
1050     if str == '--noformat' or str == '--useexisting':
1051     preexist = 1
1052     format = 0
1053     elif str == "--pesize":
1054     pesize = int(arg)
1055    
1056     pvs = []
1057     # get the unique ids of each of the physical volumes
1058     for pv in extra[1:]:
1059     if pv not in self.ksPVMapping.keys():
1060     raise KickstartError, "Tried to use an undefined partition in Volume Group specification"
1061     pvs.append(self.ksPVMapping[pv])
1062    
1063     if len(pvs) == 0 and not preexist:
1064     raise KickstartError, "Volume group defined without any physical volumes"
1065    
1066     if pesize not in lvm.getPossiblePhysicalExtents(floor=1024):
1067     raise KickstartError, "Volume group specified invalid pesize: %d" %(pesize,)
1068    
1069     # get a sort of hackish id
1070     uniqueID = self.ksID
1071     self.ksVGMapping[extra[0]] = uniqueID
1072     self.ksID = self.ksID + 1
1073    
1074     request = partRequests.VolumeGroupRequestSpec(vgname = vgname,
1075     physvols = pvs,
1076     preexist = preexist,
1077     format = format,
1078     pesize = pesize)
1079     request.uniqueID = uniqueID
1080     self.addPartRequest(id.partitions, request)
1081    
1082     def defineRaid(self, id, args):
1083     (args, extra) = isys.getopt(args, '', [ 'level=', 'device=',
1084     'spares=', 'fstype=',
1085     'noformat', 'useexisting'] )
1086    
1087     level = None
1088     raidDev = None
1089     spares = 0
1090     fstype = None
1091     format = 1
1092     uniqueID = None
1093     preexist = 0
1094    
1095     for n in args:
1096     (str, arg) = n
1097     if str == '--level':
1098     level = arg
1099     elif str == "--device":
1100     raidDev = arg
1101     if raidDev[0:2] == "md":
1102     raidDev = raidDev[2:]
1103     raidDev = int(raidDev)
1104     elif str == "--spares":
1105     spares = int(arg)
1106     elif str == "--noformat":
1107     format = 0
1108     preexist = 1
1109     elif str == "--useexisting":
1110     preexist = 1
1111     elif str == "--fstype":
1112     fstype = arg
1113    
1114     if extra[0] == 'swap':
1115     filesystem = fileSystemTypeGet('swap')
1116     mountpoint = None
1117     elif extra[0].startswith("pv."):
1118     filesystem = fileSystemTypeGet("physical volume (LVM)")
1119     mountpoint = None
1120    
1121     if self.ksPVMapping.has_key(extra[0]):
1122     raise KickstartError, "Defined PV partition %s multiple times" % (extra[0],)
1123    
1124     # get a sort of hackish id
1125     uniqueID = self.ksID
1126     self.ksPVMapping[extra[0]] = uniqueID
1127     self.ksID = self.ksID + 1
1128     else:
1129     if fstype:
1130     filesystem = fileSystemTypeGet(fstype)
1131     else:
1132     filesystem = fileSystemTypeGetDefault()
1133    
1134     mountpoint = extra[0]
1135    
1136     # sanity check mountpoint
1137     if mountpoint is not None and mountpoint[0] != '/':
1138     raise KickstartError, "The mount point \"%s\" is not valid." % (mountpoint,)
1139    
1140     raidmems = []
1141     # get the unique ids of each of the raid members
1142     for member in extra[1:]:
1143     if member not in self.ksRaidMapping.keys():
1144     raise KickstartError, "Tried to use an undefined partition in RAID specification"
1145     if member in self.ksUsedMembers:
1146     raise KickstartError, "Tried to use the RAID member %s in two or more RAID specifications" % (member,)
1147    
1148     raidmems.append(self.ksRaidMapping[member])
1149     self.ksUsedMembers.append(member)
1150    
1151     # XXX this shouldn't have to happen =\
1152     if raid.isRaid0(level):
1153     level = "RAID0"
1154     elif raid.isRaid1(level):
1155     level = "RAID1"
1156     elif raid.isRaid5(level):
1157     level = "RAID5"
1158     elif raid.isRaid6(level):
1159     level = "RAID6"
1160    
1161     if not level and preexist == 0:
1162     raise KickstartValueError, "RAID Partition defined without RAID level"
1163     if len(raidmems) == 0 and preexist == 0:
1164     raise KickstartValueError, "RAID Partition defined without any RAID members"
1165    
1166     request = partRequests.RaidRequestSpec(filesystem,
1167     mountpoint = mountpoint,
1168     raidmembers = raidmems,
1169     raidlevel = level,
1170     raidspares = spares,
1171     format = format,
1172     raidminor = raidDev,
1173     preexist = preexist)
1174    
1175     if uniqueID:
1176     request.uniqueID = uniqueID
1177     if preexist and raidDev is not None:
1178     request.device = "md%s" %(raidDev,)
1179    
1180     self.addPartRequest(id.partitions, request)
1181    
1182    
1183     def definePartition(self, id, args):
1184     # we set up partition requests (whee!)
1185     size = None
1186     grow = None
1187     maxSize = None
1188     disk = None
1189     onPart = None
1190     fsopts = None
1191     type = None
1192     primOnly = None
1193     format = 1
1194     fstype = None
1195     mountpoint = None
1196     uniqueID = None
1197     start = None
1198     end = None
1199     badblocks = None
1200     recommended = None
1201    
1202     (args, extra) = isys.getopt(args, '', [ 'size=', 'maxsize=',
1203     'grow', 'onpart=', 'ondisk=',
1204     'bytes-per-inode=', 'usepart=',
1205     'type=', 'fstype=', 'asprimary',
1206     'noformat', 'start=', 'end=',
1207     'badblocks', 'recommended',
1208     'ondrive=', 'onbiosdisk=' ])
1209    
1210     for n in args:
1211     (str, arg) = n
1212     if str == '--size':
1213     size = int(arg)
1214     elif str == '--maxsize':
1215     maxSize = int(arg)
1216     elif str == '--grow':
1217     grow = 1
1218     elif str == '--onpart' or str == '--usepart':
1219     onPart = arg
1220     elif str == '--ondisk' or str == '--ondrive':
1221     disk = arg
1222     elif str == '--onbiosdisk':
1223     disk = isys.doGetBiosDisk(arg)
1224     if disk is None:
1225     raise KickstartValueError, "Specified BIOS disk %s cannot be determined" %(arg,)
1226     elif str == '--bytes-per-inode':
1227     fsopts = ['-i', arg]
1228     # XXX this doesn't do anything right now
1229     elif str == '--type':
1230     type = int(arg)
1231     elif str == "--active":
1232     active = 1
1233     elif str == "--asprimary":
1234     primOnly = 1
1235     elif str == "--noformat":
1236     format = 0
1237     elif str == "--fstype":
1238     fstype = arg
1239     elif str == "--start":
1240     start = int(arg)
1241     elif str == "--end":
1242     end = int(arg)
1243     elif str == "--badblocks":
1244     # no longer support badblocks checking
1245     log("WARNING: --badblocks specified but is no longer supported")
1246     elif str == "--recommended":
1247     recommended = 1
1248    
1249     if len(extra) != 1:
1250     raise KickstartValueError, "partition command requires one anonymous argument"
1251    
1252     if extra[0] == 'swap':
1253     filesystem = fileSystemTypeGet('swap')
1254     mountpoint = None
1255     if recommended:
1256     (size, maxSize) = iutil.swapSuggestion()
1257     grow = 1
1258     # if people want to specify no mountpoint for some reason, let them
1259     # this is really needed for pSeries boot partitions :(
1260     elif extra[0] == 'None':
1261     mountpoint = None
1262     if fstype:
1263     filesystem = fileSystemTypeGet(fstype)
1264     else:
1265     filesystem = fileSystemTypeGetDefault()
1266     elif extra[0] == 'prepboot':
1267     filesystem = fileSystemTypeGet("PPC PReP Boot")
1268     mountpoint = None
1269     elif extra[0].startswith("raid."):
1270     filesystem = fileSystemTypeGet("software RAID")
1271    
1272     if self.ksRaidMapping.has_key(extra[0]):
1273     raise KickstartError, "Defined RAID partition %s multiple times" % (extra[0],)
1274    
1275     # get a sort of hackish id
1276     uniqueID = self.ksID
1277     self.ksRaidMapping[extra[0]] = uniqueID
1278     self.ksID = self.ksID + 1
1279     elif extra[0].startswith("pv."):
1280     filesystem = fileSystemTypeGet("physical volume (LVM)")
1281    
1282     if self.ksPVMapping.has_key(extra[0]):
1283     raise KickstartError, "Defined PV partition %s multiple times" % (extra[0],)
1284    
1285     # get a sort of hackish id
1286     uniqueID = self.ksID
1287     self.ksPVMapping[extra[0]] = uniqueID
1288     self.ksID = self.ksID + 1
1289     # XXX should we let people not do this for some reason?
1290     elif extra[0] == "/boot/efi":
1291     filesystem = fileSystemTypeGet("vfat")
1292     mountpoint = extra[0]
1293     else:
1294     if fstype:
1295     filesystem = fileSystemTypeGet(fstype)
1296     mountpoint = extra[0]
1297     else:
1298     filesystem = fileSystemTypeGetDefault()
1299     mountpoint = extra[0]
1300    
1301     if (size is None) and (not start and not end) and (not onPart):
1302     raise KickstartValueError, "partition command requires a size specification"
1303     if start and not disk:
1304     raise KickstartValueError, "partition command with start cylinder requires a drive specification"
1305     if disk and disk not in isys.hardDriveDict().keys():
1306     raise KickstartValueError, "specified disk %s in partition command which does not exist" %(disk,)
1307    
1308     # XXX bytes per inode is the only per fs option at the moment
1309     # and we can assume that it works like this since it only works
1310     # with ext[23]
1311     if fsopts:
1312     filesystem.extraFormatArgs.extend(fsopts)
1313    
1314     request = partRequests.PartitionSpec(filesystem,
1315     mountpoint = mountpoint,
1316     format = 1)
1317    
1318     if size is not None:
1319     request.size = size
1320     if start:
1321     request.start = start
1322     if end:
1323     request.end = end
1324     if grow:
1325     request.grow = 1
1326     if maxSize:
1327     request.maxSizeMB = maxSize
1328     if disk:
1329     request.drive = [ disk ]
1330     if primOnly:
1331     request.primary = 1
1332     if not format:
1333     request.format = 0
1334     if uniqueID:
1335     request.uniqueID = uniqueID
1336     if badblocks:
1337     request.badblocks = badblocks
1338     if onPart:
1339     # strip spurious /dev
1340     if onPart.startswith("/dev/"):
1341     onPart = onPart[5:]
1342     request.device = onPart
1343     for areq in id.partitions.autoPartitionRequests:
1344     if areq.device is not None and areq.device == onPart:
1345     raise KickstartValueError, "Partition %s already used" %(onPart,)
1346    
1347     self.addPartRequest(id.partitions, request)
1348     id.partitions.isKickstart = 1
1349    
1350     self.skipSteps.append("partition")
1351     self.skipSteps.append("partitionmethod")
1352     self.skipSteps.append("partitionmethodsetup")
1353     self.skipSteps.append("fdisk")
1354     self.skipSteps.append("autopartition")
1355     self.skipSteps.append("zfcpconfig")
1356    
1357     def doIgnoreDisk(self, id, args):
1358     # add disks to ignore list
1359     drives = []
1360     (args, extra) = isys.getopt(args, '', [ 'drives=' ])
1361    
1362     for n in args:
1363     (str, arg) = n
1364     if str == '--drives':
1365     drives = string.split(arg, ',')
1366    
1367     self.setIgnoredDisks(id, drives)
1368    
1369     def setSteps(self, dispatch):
1370     if self.installType == "upgrade":
1371 slords 1.3 from upgradeclass import InstallClass
1372 slords 1.1 theUpgradeclass = InstallClass(0)
1373     theUpgradeclass.setSteps(dispatch)
1374    
1375     # we have no way to specify migrating yet
1376     dispatch.skipStep("upgrademigfind")
1377     dispatch.skipStep("upgrademigratefs")
1378     dispatch.skipStep("upgradecontinue")
1379     dispatch.skipStep("findinstall", permanent = 1)
1380     dispatch.skipStep("language")
1381     dispatch.skipStep("keyboard")
1382     # dispatch.skipStep("mouse")
1383     dispatch.skipStep("welcome")
1384     dispatch.skipStep("betanag")
1385     dispatch.skipStep("installtype")
1386     else:
1387     BaseInstallClass.setSteps(self, dispatch)
1388     dispatch.skipStep("findrootparts")
1389    
1390     if self.interactive or flags.autostep:
1391     dispatch.skipStep("installtype")
1392     dispatch.skipStep("partitionmethod")
1393     dispatch.skipStep("partitionmethodsetup")
1394     dispatch.skipStep("fdisk")
1395     dispatch.skipStep("autopartition")
1396     dispatch.skipStep("bootdisk")
1397    
1398     # because these steps depend on the monitor being probed
1399     # properly, and will stop you if you have an unprobed monitor,
1400     # we should skip them for autostep
1401     if flags.autostep:
1402     dispatch.skipStep("checkmonitorok")
1403     dispatch.skipStep("monitor")
1404     return
1405    
1406     dispatch.skipStep("bootdisk")
1407     dispatch.skipStep("welcome")
1408     dispatch.skipStep("betanag")
1409     dispatch.skipStep("confirminstall")
1410     dispatch.skipStep("confirmupgrade")
1411     dispatch.skipStep("network")
1412     dispatch.skipStep("installtype")
1413    
1414     # skipping firewall by default, disabled by default
1415     dispatch.skipStep("firewall")
1416    
1417     for n in self.skipSteps:
1418     dispatch.skipStep(n)
1419     for n in self.showSteps:
1420     dispatch.skipStep(n, skip = 0)
1421    
1422     def setInstallData(self, id, intf = None):
1423     BaseInstallClass.setInstallData(self, id)
1424    
1425     self.setEarlySwapOn(1)
1426     self.postScripts = []
1427     self.preScripts = []
1428     self.tracebackScripts = []
1429    
1430     self.installType = "install"
1431     self.id = id
1432     self.id.firstboot = FIRSTBOOT_SKIP
1433    
1434     # parse the %pre
1435     try:
1436     self.readKickstart(id, self.file, parsePre = 1)
1437     except KickstartError, e:
1438     raise KickstartError, e
1439    
1440     log("Running kickstart %%pre script(s)")
1441     for script in self.preScripts:
1442     script.run("/", self.serial)
1443     log("All kickstart %%pre script(s) have been run")
1444    
1445     # now read the kickstart file for real
1446     try:
1447     self.readKickstart(id, self.file)
1448     except KickstartError, e:
1449     log("Exception parsing ks.cfg: %s" %(e,))
1450     if intf is None:
1451     raise KickstartError, e
1452     else:
1453     intf.kickstartErrorWindow(e.__str__())
1454    
1455     def runTracebackScripts(self):
1456     log("Running kickstart %%traceback script(s)")
1457     for script in self.tracebackScripts:
1458     script.run("/", self.serial)
1459    
1460     # Note that this assumes setGroupSelection() is called before
1461     # setPackageSelection()
1462     def setPackageSelection(self, hdlist, intf):
1463     for n in self.packageList:
1464    
1465     # allow arch:name syntax
1466 slords 1.3 if n.find(".") != -1:
1467 slords 1.1 fields = n.split(".")
1468     name = string.join(fields[:-1], ".")
1469     arch = fields[-1]
1470     found = 0
1471     if hdlist.pkgnames.has_key(name):
1472     pkgs = hdlist.pkgnames[name]
1473     for (nevra, parch) in pkgs:
1474     if parch == arch:
1475     hdlist.pkgs[nevra].select()
1476     found = 1
1477     continue
1478     if found:
1479     continue
1480    
1481     if hdlist.has_key(n):
1482     hdlist[n].select()
1483     continue
1484    
1485     if self.handleMissing == KS_MISSING_IGNORE:
1486     log("package %s doesn't exist, ignoring" %(n,))
1487     continue
1488    
1489    
1490     rc = intf.messageWindow(_("Missing Package"),
1491     _("You have specified that the "
1492     "package '%s' should be installed. "
1493     "This package does not exist. "
1494     "Would you like to continue or "
1495     "abort your installation?") %(n,),
1496     type="custom",
1497     custom_buttons=[_("_Abort"),
1498     _("_Continue")])
1499     if rc == 0:
1500     sys.exit(1)
1501     else:
1502     pass
1503    
1504    
1505     def setGroupSelection(self, grpset, intf):
1506     grpset.unselectAll()
1507    
1508     if self.addBase:
1509     grpset.selectGroup("base")
1510     for n in self.groupList:
1511     try:
1512     grpset.selectGroup(n)
1513     except KeyError:
1514     if self.handleMissing == KS_MISSING_IGNORE:
1515     log("group %s doesn't exist, ignoring" %(n,))
1516     else:
1517     rc = intf.messageWindow(_("Missing Group"),
1518     _("You have specified that the "
1519     "group '%s' should be installed. "
1520     "This group does not exist. "
1521     "Would you like to continue or "
1522     "abort your installation?")
1523     %(n,),
1524     type="custom",
1525     custom_buttons=[_("_Abort"),
1526     _("_Continue")])
1527     if rc == 0:
1528     sys.exit(1)
1529     else:
1530     pass
1531    
1532     for n in self.excludedList:
1533     # allow arch:name syntax
1534 slords 1.3 if n.find(".") != -1:
1535 slords 1.1 fields = n.split(".")
1536     name = string.join(fields[:-1], ".")
1537     arch = fields[-1]
1538     if grpset.hdrlist.pkgnames.has_key(name):
1539     pkgs = grpset.hdrlist.pkgnames[name]
1540     for (nevra, parch) in pkgs:
1541     if parch == arch:
1542     grpset.hdrlist.pkgs[nevra].unselect(isManual = 1)
1543     continue
1544    
1545     if grpset.hdrlist.has_key(n):
1546     grpset.hdrlist[n].unselect(isManual = 1)
1547     else:
1548     log("%s does not exist, can't exclude" %(n,))
1549    
1550    
1551     def __init__(self, file, serial):
1552     self.serial = serial
1553     self.file = file
1554     self.skipSteps = []
1555     self.showSteps = []
1556     self.interactive = 0
1557     self.addBase = 1
1558     self.packageList = []
1559     self.groupList = []
1560     self.excludedList = []
1561     self.ksRaidMapping = {}
1562     self.ksUsedMembers = []
1563     self.ksPVMapping = {}
1564     self.ksVGMapping = {}
1565     # XXX hack to give us a starting point for RAID, LVM, etc unique IDs.
1566     self.ksID = 100000
1567    
1568     # how to handle missing packages
1569     self.handleMissing = KS_MISSING_PROMPT
1570    
1571     BaseInstallClass.__init__(self, 0)
1572    
1573     def Kickstart(file, serial):
1574    
1575     f = open(file, "r")
1576     lines = f.readlines()
1577     f.close()
1578    
1579     passedLines = []
1580     while lines:
1581     l = lines[0]
1582     lines = lines[1:]
1583     if l == "%installclass\n":
1584     break
1585     passedLines.append(l)
1586    
1587     if lines:
1588     newKsFile = file + ".new"
1589     f = open(newKsFile, "w")
1590     f.writelines(passedLines)
1591     f.close()
1592    
1593     f = open('/tmp/ksclass.py', "w")
1594     f.writelines(lines)
1595     f.close()
1596    
1597     oldPath = sys.path
1598     sys.path.append('/tmp')
1599    
1600     from ksclass import CustomKickstart
1601     os.unlink("/tmp/ksclass.py")
1602    
1603     ksClass = CustomKickstart(newKsFile, serial)
1604     os.unlink(newKsFile)
1605     else:
1606     ksClass = KickstartBase(file, serial)
1607    
1608     return ksClass
1609    
1610    
1611     # see if any vnc parameters are specified in the kickstart file
1612     def parseKickstartVNC(ksfile):
1613     try:
1614     f = open(ksfile, "r")
1615     except:
1616     raise KSAppendException("Unable to open ks file %s" % (ksfile,))
1617    
1618     lines = f.readlines()
1619     f.close()
1620    
1621     usevnc = 0
1622     vnchost = None
1623     vncport = None
1624     vncpasswd = None
1625     for l in lines:
1626     args = isys.parseArgv(l)
1627    
1628     if args:
1629     if args[0] in ("%pre", "%post", "%traceback", "%packages"):
1630     break
1631    
1632     if args[0] != 'vnc':
1633     continue
1634     else:
1635     continue
1636    
1637     idx = 1
1638     while idx < len(args):
1639     if args[idx] == "--password":
1640     try:
1641     vncpasswd = args[idx+1]
1642     except:
1643     raise KickstartError, "Missing argument to vnc --password option"
1644     idx += 2
1645     elif args[idx] == "--connect":
1646     try:
1647     connectspec = args[idx+1]
1648     except:
1649     raise KickstartError, "Missing argument to vnc --connect option"
1650     cargs = string.split(connectspec, ":")
1651     vnchost = cargs[0]
1652     if len(cargs) > 1:
1653     if len(cargs[1]) > 0:
1654     vncport = cargs[1]
1655    
1656     idx += 2
1657     else:
1658     raise KickstartError, "Unknown vnc option %s" % (args[idx],)
1659    
1660     usevnc = 1
1661     break
1662    
1663     return (usevnc, vncpasswd, vnchost, vncport)
1664    
1665     #
1666     # look through ksfile and if it contains a line:
1667     #
1668     # %ksappend <url>
1669     #
1670     # pull <url> down and append to /tmp/ks.cfg. This is run before we actually
1671     # parse the complete kickstart file.
1672     #
1673     # Main use is to have the ks.cfg you send to the loader by minimal, and then
1674     # use %ksappend to pull via https anything private (like passwords, etc) in
1675     # the second stage.
1676     #
1677     def pullRemainingKickstartConfig(ksfile):
1678     try:
1679     f = open(ksfile, "r")
1680     except:
1681     raise KSAppendException("Unable to open ks file %s" % (ksfile,))
1682    
1683     lines = f.readlines()
1684     f.close()
1685    
1686     url = None
1687     for l in lines:
1688     ll = l.strip()
1689     if string.find(ll, "%ksappend") == -1:
1690     continue
1691    
1692     try:
1693     (xxx, ksurl) = string.split(ll, ' ')
1694     except:
1695     raise KSAppendException("Illegal url for %%ksappend - %s" % (ll,))
1696    
1697     log("Attempting to pull second part of ks.cfg from url %s" % (ksurl,))
1698    
1699     try:
1700     url = urllib2.urlopen(ksurl)
1701     except urllib2.HTTPError, e:
1702     raise KSAppendException("IOError: %s:%s" % (e.code, e.msg))
1703     except urllib2.URLError, e:
1704     raise KSAppendException("IOError: -1:%s" % (e.reason,))
1705     else:
1706     # sanity check result - sometimes FTP doesnt
1707     # catch a file is missing
1708     try:
1709     clen = url.info()['content-length']
1710     except Exception, e:
1711     clen = 0
1712    
1713     if clen < 1:
1714     raise KSAppendException("IOError: -1:File not found")
1715    
1716     break
1717    
1718     # if we got something then rewrite /tmp/ks.cfg with new information
1719     if url is not None:
1720     os.rename("/tmp/ks.cfg", "/tmp/ks.cfg-part1")
1721    
1722     # insert contents of original /tmp/ks.cfg w/o %ksappend line
1723     f = open("/tmp/ks.cfg", 'w+')
1724     for l in lines:
1725     ll = l.strip()
1726     if string.find(ll, "%ksappend") != -1:
1727     continue
1728     f.write(l)
1729    
1730     # now write part we just grabbed
1731     f.write(url.read())
1732     f.close()
1733    
1734     # close up url and we're done
1735     url.close()
1736    
1737     return None
1738    

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed