/[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.1 - (hide annotations) (download) (as text)
Sat Jul 30 07:28:39 2005 UTC (19 years, 4 months ago) by slords
Branch: MAIN
Content type: text/x-python
First major pass as anaconda installer
- Install/Upgrade detection working
- Only screens we want are being displayed
- Raid/LVM partitioning all done for installer
- Except for post-install (run, status) install is done
- TODO: post-install script isn't running
- TODO: post-upgrade script isn't working
- TODO: raid migration for upgrades
- TODO: status message for post-{install,upgrade}

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

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