0q3 059B59B$S39BN _Gأ'26,G|A C '39B3 39B39B39BA39B59B59B AEA59B59B 7 Af |@59B59B : j @59Bj @> 5@59B 5@B A~@59B59BE A~@59B~@H * ~@59B~@L Af |@59B59BO ?59B?S >@59B>@W ~>@59B~>@[ :@59B:@Z !"#$%&'()*+,_ A~@59B59BMb ~@59B~@NOPQf ~@59B~@RSTj A~@59B59BUm A~@59B~@Vp * ~@59B~@WXYt A~@59B59BZw ~@59B~@[\{ ~@59B~@]^ ~@59B~@_ F$a0G0  aaafF aF aG( # # installpath_gui.py: screen for selecting which installclass to use. # # Copyright 2000-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import installclass import gtk import gui from pixmapRadioButtonGroup_gui import pixmapRadioButtonGroup from iw_gui import InstallWindow from flags import flags from rhpl.translate import _, N_ #CJS added so to log from rhpl.log import log UPGRADE = 0 INSTALL = 1 CUSTOM = 2 WORKSTATION_GNOME = 3 WORKSTATION_KDE = 4 SERVER = 5 class InstallPathWindow (InstallWindow): installTypes = installclass.availableClasses() htmlTag = "instpath" windowTitle = N_("Installation Type") def getNext(self): # Hack to let backing out of upgrades work properly #if self.flags.setupFilesystems() and self.id.fstab: #self.id.fstab.turnOffSwap() selection = None for (name, object, pixmap) in self.installTypes: if name == self.currentClassName: selection = object if not isinstance (self.id.instClass, selection): c = selection(self.flags.expert) c.setSteps(self.dispatch) c.setInstallData(self.id) needNewDruid = 1 def optionToggled(self, widget, name): if widget.get_active(): self.currentClassName = name def createInstallTypeOption(self): r = pixmapRadioButtonGroup() for (name, object, pixmap) in self.installTypes: descr = object.description r.addEntry(name, _(name), pixmap=self.ics.readPixmap(pixmap), descr=_(descr)) return r # InstallPathWindow tag="instpath" def getScreen(self, dispatch, id, method, intf): self.id = id self.intf = intf self.flags = flags self.method = method self.dispatch = dispatch vbox = gtk.VBox (gtk.FALSE, 10) vbox.set_border_width (8) self.r = self.createInstallTypeOption() b = self.r.render() self.r.setToggleCallback(self.optionToggled) # figure out current class as well as default defaultClass = None currentClass = None firstClass = None for (name, object, pixmap) in self.installTypes: if firstClass is None: firstClass = object if isinstance(id.instClass, object): currentClass = object if object.default: defaultClass = object if currentClass is None: if defaultClass is not None: self.currentClassName = defaultClass.name else: self.currentClassName = firstClass.name else: self.currentClassName = currentClass.name self.r.setCurrent(self.currentClassName) # CJS Added for scrolling log("making scrolledwin now") scrolledwin = gtk.ScrolledWindow () scrolledwin.set_border_width(4) # scrolledwin.set_usize(-1,475) scrolledwin.set_size_request(300,475) scrolledwin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) scrolledwin.add_with_viewport(b) scrolledwin.show() log("scrolledwin show just done") # CJS added end box = gtk.VBox (gtk.FALSE) # box.pack_start(b, gtk.FALSE) box.pack_start(scrolledwin, gtk.FALSE) vbox.pack_start (box, gtk.FALSE) return vbox # # congrats_gui.py: install/upgrade complete screen. # # Copyright 2000-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import gtk import gui from iw_gui import * from rhpl.translate import _, N_ from constants import * import iutil class CongratulationWindow (InstallWindow): windowTitle = N_("Congratulations") def __init__ (self, ics): InstallWindow.__init__(self, ics) ics.setPrevEnabled(gtk.FALSE) ics.setNextButton(gtk.STOCK_QUIT, _("_Exit")) ics.setHelpButtonEnabled(gtk.FALSE) ics.setHelpEnabled(gtk.FALSE) ics.setGrabNext(1) def getNext(self): # XXX - copy any screenshots over gui.copyScreenshots() # CongratulationWindow tag=NA def getScreen (self): self.ics.setHelpEnabled (gtk.FALSE) hbox = gtk.HBox (gtk.FALSE, 5) pix = self.ics.readPixmap ("done.png") if pix: a = gtk.Alignment () a.add (pix) a.set (0.5, 0.5, 1.0, 1.0) a.set_size_request(200, -1) hbox.pack_start (a, gtk.FALSE, gtk.FALSE, 36) bootstr = productName if iutil.getArch() == "s390": floppystr = "" else: floppystr = _("Remove any installation media (diskettes or " "CD-ROMs) used during the installation process " "and press to reboot your system." "\n\n") #CJS Changed out the RedHat stuff and put in Fermi stuff label = gui.WrappingLabel( _("Congratulations, the installation is complete.\n\n" "%s" "Thanks for installing %s \n" ) %(floppystr, bootstr)) # label = gui.WrappingLabel( # _("Congratulations, the installation is complete.\n\n" # "%s" # "%s" # "For information on Errata (updates and bug fixes), visit:\n" # "\thttp://www.redhat.com/errata/\n\n" # "For information on automatic updates through Red Hat " # "Network, visit:\n" # "\thttp://rhn.redhat.com/\n\n" # "For information on using and configuring the system, visit:\n" # "\thttp://www.redhat.com/docs/\n" # "\thttp://www.redhat.com/apps/support/\n\n" # "To register the product for support, visit:\n" # "\thttp://www.redhat.com/apps/activate/\n\n") % (floppystr, # bootstr,)) hbox.pack_start (label, gtk.TRUE, gtk.TRUE) return hbox  . ..comps_ custom.pngذ^:k;[{vIh }suf<*ܔ%'e2s>y}4HSc#^y>t4vnY_~V݇-?#/ #>-Ax&v~ÿ.cML] W5 _^^̟g7.g'>&6BE2GKDjqZ'S{|?aiGm[ O8^jsX Pox9xQn}6M s'9J#K.o6]֊97+2 W߼xJHG<V߻{WGE=?ۧ|^a;}o2/s>$/Uzԣk*}WnLĵ p}З*>k/I_> :,⯭Zg*Zox"_A5Doqmo&gMܱ,/Q/ypNs4sKMp>vN~.>o̶f #]SI`;>, zN쇨q?ml 3Z{gJVYI;He?8 ؓGwIp?]Y*`ō|x:ɒZ| yxN} IS{"9:ϯ3#h]Y*??@_<}>ЗL=O_Wo }ӷkm#Iߧ/w]E&lHxA OZb3FyBD My ...5OH~(x O!=Jtlpz*#D ֤wR ?kFPWf&:Y?tWiY뫠 4 ~[SbbUbu *?=)u:>P瓓}dU~YPkcB3-n=,kڳ'_F_b ʙp]㩗QH K,x> ]>f^'`"?€Q#e/\3Kg};/Va/c]0P ޣ!uƋ?{YT k׳ˡ/J)x7<dQӗ_>կDz+$=uOh-ПH6At^%OY/xdxwwj];4)> bݩ_ZUq ?ʥmO2rn3bx{~*ի3]a-W=]Hm.Ԇ^ڶFkcF[|T?:ӥ/ 4poH?DE"޹4֯57mK-> usuuLn"Zo;c>BhG!?jwii< 5 /6wI}OX oN O~΍2 BÑLR|2~vؗ"K? ~UpZRz7}\>fX9 +o޸]U_ZO,Y#7Q}wj?axޒ=vp giOTۯ uU\-t)#|TH2֯ o«7 '+g޿eO7{ctC~*31U2t?6j3'ЯS}'P姾q殷_>PNG  IHDR00WbKGD pHYs  @AtIME +' IDATx}p?w{/ !@" h^xR"X3Rg3e|3uP[;m鴖:3ڱe$:HE hx$&$'0 pk$/3}fv{><}v7fMΘ1C "/E0c 6sLdYn#Ix`0HUUդx \QQPYY9.R)v;LzPUUR[[KMM `N$Kszu˒%Ktb2ZXVb~",#2EEEL&±oD"'^׋눢$If"Nb``H$fCeN'dJx_xYTT1͓P}ݧoܸł$IL& 96 EQp\$S0-;w:u/x2 /*`ʕhD86v;Ns?ć9SQv(TU5d4 ߏ,8i0r~;mڴ$IVs-dE;v粫H>p8~V 6mvLi%%%y;,ˣf}e#0HLsDLaa!$z_.\FXgV5xRLEQrM)Em6vEk^{gyt:f!vȲ9qSo{i=>d:nzp?k׮@E ZaI0dYE~Kf({ul|~n7mmmڵ(s ,:::p444L?q+O l1᷿'} @<' ;ٰa[lviHA)++>/g)j6Zf88$IB4Xz5'O$ Bkk+fժU[ 8S /[ZFG㚬F(^0o<ꨮ!IM:(NSRd_|B .rOR^^ ʡChkkxBAE Ԍ>MP={uV#5 `ȨMZŋu], ,˙(nDPUi fT[?83VGy\5 OF1|<#Ѣ77ܭq˵cr"pW=p.ǗL:I*Bu"Aɤ Y4X,fCUUVn ;(yfV+dr?W܄RbL&Css3g,[̆ IX,f1LqٌnP=rJJʸ59" =^\\L*"(u]l68X:ppwsV.,C,3R$#I6 UUI tuu r:a˱d2$d*gTU%N^<ȶm>OYحCYr9i=vh?D?]{#Ӌ r&z9pȲL4EUUt]paJKKQU>~?@'N 2DD"Aww7lmU`e3hjjB IPUY1̈́B!blE^^l/^FMMMҥKI&J8rle4JikkΩmǿ 4▹MW;w$H$4 C:&"2,%hC8Ƀ}1Yb&9suJ2 CCC$ cb/G݈a r'OpCZ0(bٌ DQJJJ(//J נI4wϺcW sR*gIjnn֯j顣T*e H$E"w6=:a7xH_ PI455fBn^m=gϥxZI~wr}˖-TVV*`t6rKH$믽_~02H&Ϗഀ B477{q`n汲[,ZPŬg"R)^~ ,y̆ovl6D`0H__xx<>l75dӏXLXL&||u;SC|t,ȒkۂQhd2SAAxs豉L2E_f _=. MH$F- ! hmmeWr䓏n9  &UnNA8C/"?ݖR}̙o*wcǎq TU5|x*;nEXmV슃]oL<CQ1.˃d6 = F ȫB cUqy pL1 =ESOC yw0H. ?hP#D`=]|7'<;C^Ϭ[)]/ꊯ# .|vkw'R0=&Ip||qc>ڕ7ERzS%8o "LȲ֎:z}Ň4%_6.m_.ɸtW͐JIENDB` . ..installpath_text.pycomplete_text.pywelcome_text.py4` 7~"l;&S#W6v>Gq&od8GY>y$MJYG'^Ț<g4o}}p]挲&ο} GEp-SW:mU~~|eJl}=5rѾ]dr{sȒܞ̵sTxER JK]욉~ռ:Fo?`ZG@㛡ÿ\2|h}'7xG8P ֗0>C6KDeкP"l_c(q7TKodIM#Ϸ :?x}.UjM { o|mXOK՛  &V{Ӊ X ʃo՗ π}F=lX>6+LW4_?JPc=I*~/EJC^Oݝ=,qu$ gRC$~bޟ Z"^6ܠϓױIo[rb{yJa"O)kE?"ٝt˟&=8"܏  # X"NZ`0ә)B]iGc/'ЯvwX~DnCPh7Z o̵^/c>2?H+vY6i?\Gc ZlcN9~naڝԟNsD=ו?c"7C)'VY~s3Tjb8BX< _4?U~%E/o^7# # installpath_text: text mode installation type selection dialog # # Copyright 2001-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # from snack import * from constants_text import * from rhpl.translate import _ from flags import flags import installclass class InstallPathWindow: def __call__ (self, screen, dispatch, id, method, intf): classes = installclass.availableClasses() choices = [] default = 0 i = 0 orig = None for (name, object, icon) in classes: choices.append(_(name)) if isinstance(id.instClass, object): orig = i elif object.default: default = i i = i + 1 if orig != None: default = orig # CJS # (button, choice) = ListboxChoiceWindow(screen, _("Installation Type"), # _("What type of system would you like to install?"), # choices, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], # width = 40, default = default, help = "installpath") (button, choice) = ListboxChoiceWindow(screen, _("Installation Type"), _("What type of system would you like to install?"), choices, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], width = 40, default = default, help = "installpath", scroll = 1 , height = 11 ) # CJS if button == TEXT_BACK_CHECK: return INSTALL_BACK if (choice != orig): (name, objectClass, logo) = classes[choice] c = objectClass(flags.expert) c.setSteps(dispatch) c.setInstallData(id) return INSTALL_OK # # complete_text.py: text mode congratulations windows # # Copyright 2001-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # from snack import * from constants_text import * from rhpl.translate import _ from constants import * import iutil class FinishedWindow: def __call__ (self, screen): bootstr = "" if iutil.getArch() == "s390": floppystr = _("Press to end the installation process.\n\n") bottomstr = _(" to exit") else: floppystr = _("Remove any installation media (diskettes or " "CD-ROMs) used during the installation process " "and press to reboot your system." "\n\n") bottomstr = _(" to reboot") screen.pushHelpLine (string.center(bottomstr, screen.width)) rc = ButtonChoiceWindow (screen, _("Complete"), _("Congratulations, your %s installation is " "complete.\n\n" "%s" "%s" ) % (productName, floppystr, bootstr), [ _("OK") ], help = "finished", width=60) return INSTALL_OK # # welcome_text.py: text mode welcome window # # Copyright 2001-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # from snack import * from constants_text import * from rhpl.translate import _ from constants import * import os class WelcomeWindow: def __call__(self, screen, configFileData): rc = ButtonChoiceWindow(screen, _("%s") % (productName,), _("Welcome to %s!\n\n") % (productName), buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], width = 50, help = "welcome") if rc == TEXT_BACK_CHECK: return INSTALL_BACK return INSTALL_OK # # packages.py: package management - mainly package installation # # Erik Troan # Matt Wilson # Michael Fulbright # Jeremy Katz # # Copyright 2001-2003 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import iutil import isys import rpm import os import timer import time import sys import string import pcmcia import language import fsset import kudzu from flags import flags from product import * from constants import * from syslogd import syslog from hdrlist import PKGTYPE_MANDATORY, PKGTYPE_DEFAULT, DependencyChecker from installmethod import FileCopyException from rhpl.log import log from rhpl.translate import _ import rhpl.arch def queryUpgradeContinue(intf, dir): if dir == DISPATCH_FORWARD: return rc = intf.messageWindow(_("Proceed with upgrade?"), _("The file systems of the Linux installation " "you have chosen to upgrade have already been " "mounted. You cannot go back past this point. " "\n\n") + _( "Would you like to continue with the upgrade?"), type = "yesno") if rc == 0: sys.exit(0) return DISPATCH_FORWARD def doPostAction(id, instPath): id.instClass.postAction(instPath, flags.serial) def firstbootConfiguration(id, instPath): if id.firstboot == FIRSTBOOT_RECONFIG: f = open(instPath + '/etc/reconfigSys', 'w+') f.close() elif id.firstboot == FIRSTBOOT_SKIP: f = open(instPath + '/etc/sysconfig/firstboot', 'w+') f.write('RUN_FIRSTBOOT=NO') f.close() return def writeConfiguration(id, instPath): log("Writing main configuration") if not flags.test: id.write(instPath) def writeKSConfiguration(id, instPath): log("Writing autokickstart file") if not flags.test: fn = instPath + "/root/anaconda-ks.cfg" else: fn = "/tmp/anaconda-ks.cfg" id.writeKS(fn) def writeXConfiguration(id, instPath): testmode = flags.test # comment out to test if testmode: return # end code to comment to test # uncomment to test writing X config in test mode # try: # os.mkdir("/tmp/etc") # except: # pass # try: # os.mkdir("/tmp/etc/X11") # except: # pass # instPath = '/' # end code for test writing if id.xsetup.skipx: return xserver = id.videocard.primaryCard().getXServer() if not xserver: return log("Writing X configuration") if not testmode: fn = instPath if os.access (instPath + "/etc/X11/X", os.R_OK): os.rename (instPath + "/etc/X11/X", instPath + "/etc/X11/X.rpmsave") try: os.unlink (instPath + "/etc/X11/X") except OSError: pass os.symlink ("../../usr/X11R6/bin/" + xserver, instPath + "/etc/X11/X") else: fn = "/tmp/" id.xsetup.write(fn+"/etc/X11", id.mouse, id.keyboard) id.desktop.write(instPath) def readPackages(intf, method, id): if id.grpset: grpset = id.grpset hdrlist = id.grpset.hdrlist doselect = 0 else: grpset = None hdrlist = None doselect = 1 while hdrlist is None: w = intf.waitWindow(_("Reading"), _("Reading package information...")) try: hdrlist = method.readHeaders() except FileCopyException: w.pop() method.unmountCD() intf.messageWindow(_("Error"), _("Unable to read header list. This may be " "due to a missing file or bad media. " "Press to try again.")) continue w.pop() while grpset is None: try: grpset = method.readComps(hdrlist) except FileCopyException: method.unmountCD() intf.messageWindow(_("Error"), _("Unable to read comps file. This may be " "due to a missing file or bad media. " "Press to try again.")) continue while iutil.getArch() == "ia64": try: method.mergeFullHeaders(hdrlist) break except FileCopyException: method.unmountCD() intf.messageWindow(_("Error"), _("Unable to merge header list. This may be " "due to a missing file or bad media. " "Press to try again.")) # this is a crappy hack, but I don't want bug reports from these people if (iutil.getArch() == "i386") and (not grpset.hdrlist.has_key("kernel")): intf.messageWindow(_("Error"), _("You are trying to install on a machine " "which isn't supported by this release of " "%s.") %(productName,), type="custom", custom_icon="error", custom_buttons=[_("_Exit")]) sys.exit(0) id.grpset = grpset if doselect: id.instClass.setGroupSelection(grpset, intf) id.instClass.setPackageSelection(hdrlist, intf) def handleX11Packages(dir, intf, disp, id, instPath): if dir == DISPATCH_BACK: return # skip X setup if it is not being installed if (not id.grpset.hdrlist.has_key('XFree86') or not id.grpset.hdrlist['XFree86'].isSelected()): disp.skipStep("videocard") disp.skipStep("monitor") disp.skipStep("xcustom") disp.skipStep("writexconfig") id.xsetup.skipx = 1 elif disp.stepInSkipList("videocard"): # if X is being installed, but videocard step skipped # need to turn it back on disp.skipStep("videocard", skip=0) disp.skipStep("monitor", skip=0) disp.skipStep("xcustom", skip=0) disp.skipStep("writexconfig", skip=0) id.xsetup.skipx = 0 # set default runlevel based on packages gnomeSelected = (id.grpset.hdrlist.has_key('gnome-session') and id.grpset.hdrlist['gnome-session'].isSelected()) kdeSelected = (id.grpset.hdrlist.has_key('kdebase') and id.grpset.hdrlist['kdebase'].isSelected()) if gnomeSelected: id.desktop.setDefaultDesktop("GNOME") elif kdeSelected: id.desktop.setDefaultDesktop("KDE") if gnomeSelected or kdeSelected: id.desktop.setDefaultRunLevel(5) def getAnacondaTS(instPath = None): if instPath: ts = rpm.TransactionSet(instPath) else: ts = rpm.TransactionSet() ts.setVSFlags(~(rpm.RPMVSF_NORSA|rpm.RPMVSF_NODSA)) ts.setFlags(rpm.RPMTRANS_FLAG_ANACONDA) # set color if needed. FIXME: why isn't this the default :/ if (rhpl.arch.canonArch.startswith("ppc64") or rhpl.arch.canonArch in ("s390x", "sparc64", "x86_64", "ia64")): ts.setColor(3) return ts def checkDependencies(dir, intf, disp, id, instPath): if dir == DISPATCH_BACK: return win = intf.waitWindow(_("Dependency Check"), _("Checking dependencies in packages selected for installation...")) # FIXME: we really don't need to build up a ts more than once # granted, this is better than before still if id.upgrade.get(): ts = getAnacondaTS(instPath) how = "u" else: ts = getAnacondaTS() how = "i" # set the rpm log file to /dev/null so that we don't segfault f = open("/dev/null", "w+") rpm.setLogFile(f) ts.scriptFd = f.fileno() for p in id.grpset.hdrlist.pkgs.values(): if p.isSelected(): ts.addInstall(p.hdr, p.hdr, how) depcheck = DependencyChecker(id.grpset, how) id.dependencies = ts.check(depcheck.callback) win.pop() if depcheck.added and id.handleDeps == CHECK_DEPS: disp.skipStep("dependencies", skip = 0) log("FIXME: had dependency problems. resolved them without informing the user") disp.skipStep("dependencies") else: disp.skipStep("dependencies") return # FIXME: I BROKE IT # this is kind of hackish, but makes kickstart happy if id.handleDeps == CHECK_DEPS: pass elif id.handleDeps == IGNORE_DEPS: id.comps.selectDepCause(id.dependencies) id.comps.unselectDeps(id.dependencies) elif id.handleDeps == RESOLVE_DEPS: id.comps.selectDepCause(id.dependencies) id.comps.selectDeps(id.dependencies) class InstallCallback: def cb(self, what, amount, total, h, (param)): # first time here means we should pop the window telling # user to wait until we get here if not self.beenCalled: self.beenCalled = 1 self.initWindow.pop() if (what == rpm.RPMCALLBACK_TRANS_START): # step 6 is the bulk of the transaction set # processing time if amount == 6: self.progressWindow = \ self.progressWindowClass (_("Processing"), _("Preparing to install..."), total) try: self.incr = total / 10 except: pass if (what == rpm.RPMCALLBACK_TRANS_PROGRESS): if self.progressWindow and amount > self.lastprogress + self.incr: self.progressWindow.set (amount) self.lastprogress = amount if (what == rpm.RPMCALLBACK_TRANS_STOP and self.progressWindow): self.progressWindow.pop () if (what == rpm.RPMCALLBACK_INST_OPEN_FILE): # We don't want to start the timer until we get to the first # file. self.pkgTimer.start() self.progress.setPackage(h) self.progress.setPackageScale(0, 1) self.instLog.write (self.modeText % (h[rpm.RPMTAG_NAME], h[rpm.RPMTAG_VERSION], h[rpm.RPMTAG_RELEASE], h[rpm.RPMTAG_ARCH])) self.instLog.flush () self.rpmFD = -1 self.size = h[rpm.RPMTAG_SIZE] while self.rpmFD < 0: try: fn = self.method.getFilename(h, self.pkgTimer) self.rpmFD = os.open(fn, os.O_RDONLY) # Make sure this package seems valid try: hdr = self.ts.hdrFromFdno(self.rpmFD) os.lseek(self.rpmFD, 0, 0) # if we don't have a valid package, throw an error if not hdr: raise SystemError except: try: os.close(self.rpmFD) except: pass self.rpmFD = -1 raise FileCopyException except: self.method.unmountCD() self.messageWindow(_("Error"), _("The package %s-%s-%s cannot be opened. This is due " "to a missing file or perhaps a corrupt package. " "If you are installing from CD media this usually " "means the CD media is corrupt, or the CD drive is " "unable to read the media.\n\n" "Press to try again.") % (h['name'], h['version'], h['release'])) fn = self.method.unlinkFilename(fn) return self.rpmFD elif (what == rpm.RPMCALLBACK_INST_PROGRESS): # RPM returns strange values sometimes if amount > total: amount = total if not total or total == 0 or total == "0": total = amount self.progress.setPackageScale(amount, total) elif (what == rpm.RPMCALLBACK_INST_CLOSE_FILE): os.close (self.rpmFD) self.progress.completePackage(h, self.pkgTimer) self.progress.processEvents() el-./0123456789:;<=>?@ABCDEFGHIJKLif ((what == rpm.RPMCALLBACK_UNPACK_ERROR) or (what == rpm.RPMCALLBACK_CPIO_ERROR)): # we may want to make this error more fine-grained at some # point pkg = "%s-%s-%s" % (h[rpm.RPMTAG_NAME], h[rpm.RPMTAG_VERSION], h[rpm.RPMTAG_RELEASE]) self.messageWindow(_("Error Installing Package"), _("There was an error installing %s. This " "can indicate media failure, lack of disk " "space, and/or hardware problems. This is " "a fatal error and your install will be " "aborted. Please verify your media and try " "your install again.\n\n" "Press the OK button to reboot " "your system.") % (pkg,)) sys.exit(0) else: pass self.progress.processEvents() def __init__(self, messageWindow, progress, pkgTimer, method, progressWindowClass, instLog, modeText, ts): self.messageWindow = messageWindow self.progress = progress self.pkgTimer = pkgTimer self.method = method self.progressWindowClass = progressWindowClass self.progressWindow = None self.lastprogress = 0 self.incr = 20 self.instLog = instLog self.modeText = modeText self.beenCalled = 0 self.initWindow = None self.ts = ts def sortPackages(first, second): # install packages in cd order (cd tag is 1000002) one = None two = None if first[1000003] != None: one = first[1000003] if second[1000003] != None: two = second[1000003] if one == None or two == None: one = 0 two = 0 if first[1000002] != None: one = first[1000002] if second[1000002] != None: two = second[1000002] if one < two: return -1 elif one > two: return 1 elif (string.lower(first[rpm.RPMTAG_NAME]) < string.lower(second[rpm.RPMTAG_NAME])): return -1 elif (string.lower(first[rpm.RPMTAG_NAME]) > string.lower(second[rpm.RPMTAG_NAME])): return 1 return 0 class rpmErrorClass: def cb(self): self.f.write (rpm.errorString () + "\n") def __init__(self, f): self.f = f def doMigrateFilesystems(dir, thefsset, diskset, upgrade, instPath): if dir == DISPATCH_BACK: return DISPATCH_NOOP if thefsset.haveMigratedFilesystems(): return DISPATCH_NOOP thefsset.migrateFilesystems (instPath) def turnOnFilesystems(dir, thefsset, diskset, partitions, upgrade, instPath): if dir == DISPATCH_BACK: log("unmounting filesystems") thefsset.umountFilesystems(instPath) return if flags.setupFilesystems: if not upgrade.get(): partitions.doMetaDeletes(diskset) thefsset.setActive(diskset) if not thefsset.isActive(): diskset.savePartitions () thefsset.checkBadblocks(instPath) thefsset.createLogicalVolumes(instPath) thefsset.formatSwap(instPath) thefsset.turnOnSwap(instPath) thefsset.makeFilesystems (instPath) log("mounting filesystems") thefsset.mountFilesystems (instPath) def setupTimezone(timezone, upgrade, instPath, dir): # we don't need this on an upgrade or going backwards if upgrade.get() or (dir == DISPATCH_BACK): return os.environ["TZ"] = timezone.tz tzfile = "/usr/share/zoneinfo/" + timezone.tz if not os.access(tzfile, os.R_OK): log("unable to set timezone") else: try: iutil.copyFile(tzfile, "/etc/localtime") except OSError, (errno, msg): log("Error copying timezone (from %s): %s" %(tzfile, msg)) if iutil.getArch() == "s390": return args = [ "/usr/sbin/hwclock", "--hctosys" ] if timezone.utc: args.append("-u") elif timezone.arc: args.append("-a") try: iutil.execWithRedirect(args[0], args, stdin = None, stdout = "/dev/tty5", stderr = "/dev/tty5") except RuntimeError: log("Failed to set clock") def doPreInstall(method, id, intf, instPath, dir): if dir == DISPATCH_BACK: return arch = iutil.getArch () # this is a crappy hack, but I don't want bug reports from these people if (arch == "i386") and (not id.grpset.hdrlist.has_key("kernel")): intf.messageWindow(_("Error"), _("You are trying to install on a machine " "which isn't supported by this release of " "%s.") %(productName,), type="custom", custom_icon="error", custom_buttons=[_("_Exit")]) sys.exit(0) # shorthand upgrade = id.upgrade.get() def select(hdrlist, name): if hdrlist.has_key(name): hdrlist[name].select(isManual = 1) if not upgrade: # this is NICE and LATE. It lets kickstart/server/workstation # installs detect this properly if arch == "s390": if (string.find(os.uname()[2], "tape") > -1): select(id.grpset.hdrlist, 'kernel-tape') elif arch == "ppc" and iutil.getPPCMachine() == "pSeries": select(id.grpset.hdrlist, 'kernel-pseries') elif arch == "ppc" and iutil.getPPCMachine() == "iSeries": select(id.grpset.hdrlist, "kernel-iseries") if isys.smpAvailable() or isys.htavailable(): select(id.grpset.hdrlist, 'kernel-smp') ##################### HACK HACK, for kernel-module-smp packages ... jaroslaw.polok@cern.ch if id.grpset.hdrlist['kernel-module-openafs-2.4.21-15.EL.cern'].isSelected(): select(id.grpset.hdrlist, 'kernel-module-openafs-2.4.21-15.EL.cernsmp') if id.grpset.hdrlist['kernel-module-xfs-2.4.21-15.EL.cern'].isSelected(): select(id.grpset.hdrlist, 'kernel-module-xfs-2.4.21-15.EL.cernsmp') if id.grpset.hdrlist['kernel-module-bcm5700-2.4.21-15.EL.cern'].isSelected(): select(id.grpset.hdrlist, 'kernel-module-bcm5700-2.4.21-15.EL.cernsmp') if iutil.needsEnterpriseKernel(): select(id.grpset.hdrlist, "kernel-bigmem") if isys.summitavailable(): select(id.grpset.hdrlist, "kernel-summit") # we *always* need a kernel installed select(id.grpset.hdrlist, 'kernel') # if NIS is configured, install ypbind and dependencies: if id.auth.useNIS: select(id.grpset.hdrlist, 'ypbind') select(id.grpset.hdrlist, 'yp-tools') select(id.grpset.hdrlist, 'portmap') if id.auth.useLdap: select(id.grpset.hdrlist, 'nss_ldap') select(id.grpset.hdrlist, 'openldap') select(id.grpset.hdrlist, 'perl') if id.auth.useKrb5: select(id.grpset.hdrlist, 'pam_krb5') select(id.grpset.hdrlist, 'krb5-workstation') select(id.grpset.hdrlist, 'krbafs') select(id.grpset.hdrlist, 'krb5-libs') if id.auth.useSamba: select(id.grpset.hdrlist, 'pam_smb') if iutil.getArch() == "i386" and id.bootloader.useGrubVal == 0: select(id.grpset.hdrlist, 'lilo') elif iutil.getArch() == "i386" and id.bootloader.useGrubVal == 1: select(id.grpset.hdrlist, 'grub') elif iutil.getArch() == "s390": select(id.grpset.hdrlist, 's390utils') elif iutil.getArch() == "ppc": select(id.grpset.hdrlist, 'yaboot') elif iutil.getArch() == "ia64": select(id.grpset.hdrlist, 'elilo') if pcmcia.pcicType(): select(id.grpset.hdrlist, 'kernel-pcmcia-cs') if flags.test: return # make sure that all comps that include other comps are # selected (i.e. - recurse down the selected comps and turn # on the children while 1: try: method.mergeFullHeaders(id.grpset.hdrlist) except FileCopyException: method.unmountCD() intf.messageWindow(_("Error"), _("Unable to merge header list. This may be " "due to a missing file or bad media. " "Press to try again.")) else: break if upgrade: # An old mtab can cause confusion (esp if loop devices are # in it) f = open(instPath + "/etc/mtab", "w+") f.close() if method.systemMounted (id.fsset, instPath): id.fsset.umountFilesystems(instPath) return DISPATCH_BACK for i in ( '/var', '/var/lib', '/var/lib/rpm', '/tmp', '/dev', '/etc', '/etc/sysconfig', '/etc/sysconfig/network-scripts', '/etc/X11', '/root', '/var/tmp', '/etc/rpm' ): try: os.mkdir(instPath + i) except os.error, (errno, msg): pass # log("Error making directory %s: %s" % (i, msg)) if flags.setupFilesystems: # setup /etc/rpm/platform for the post-install environment iutil.writeRpmPlatform(instPath) try: # FIXME: making the /var/lib/rpm symlink here is a hack to # workaround db->close() errors from rpm iutil.mkdirChain("/var/lib") iutil.mkdirChain("/var/spool") for path in ("/var/tmp", "/var/lib/rpm","/var/spool/anaconda-updates"): if os.path.exists(path) and not os.path.islink(path): iutil.rmrf(path) if not os.path.islink(path): os.symlink("/mnt/sysimage/%s" %(path,), "%s" %(path,)) else: log("%s already exists as a symlink to %s" %(path, os.readlink(path),)) except Exception, e: # how this could happen isn't entirely clear; log it in case # it does and causes problems later log("error creating symlink, continuing anyway: %s" %(e,)) # try to copy the comps package. if it doesn't work, don't worry about it try: id.compspkg = method.copyFileToTemp("RedHat/base/comps.rpm") except: log("Unable to copy comps package") id.compspkg = None # write out the fstab if not upgrade: id.fsset.write(instPath) # rootpath mode doesn't have this file around if os.access("/tmp/modules.conf", os.R_OK): iutil.copyFile("/tmp/modules.conf", instPath + "/etc/modules.conf") # make a /etc/mtab so mkinitrd can handle certain hw (usb) correctly f = open(instPath + "/etc/mtab", "w+") f.write(id.fsset.mtab()) f.close() # we need to cache packages that are "updates" if we're doing a cd # install. we write them to under /var since that's where up2date # will end up putting updates try: method.cacheUpdates(instPath, id.grpset.hdrlist, intf) except Exception, e: log("Problem caching updates: %s" %(e,)) # delay writing migrate adjusted fstab till later, in case # rpm transaction set determines they don't have enough space to upgrade # else: # id.fsset.migratewrite(instPath) def doInstall(method, id, intf, instPath): if flags.test: return # set up dependency white outs import whiteout upgrade = id.upgrade.get() ts = getAnacondaTS(instPath) total = 0 totalSize = 0 if upgrade: how = "u" else: how = "i" rpm.addMacro("__dbi_htconfig", "hash nofsync %{__dbi_other} %{__dbi_perms}") l = [] for p in id.grpset.hdrlist.values(): if p.isSelected(): l.append(p) l.sort(sortPackages) progress = intf.progressWindow(_("Processing"), _("Preparing RPM transaction..."), len(l)) # this is kind of a hack, but has to be done so we can have a chance # with broken triggers if upgrade and len(id.upgradeRemove) > 0: # simple rpm callback since erasure doesn't need anything def install_callback(what, bytes, total, h, user): pass for pkg in id.upgradeRemove: ts.addErase(pkg) # if we hit problems, it's not like there's anything we can # do about it ts.run(install_callback, 0) # new transaction set ts.closeDB() del ts ts = getAnacondaTS(instPath) # we don't want to try to remove things more than once (#84221) id.upgradeRemove = [] i = 0 updcount = 0 updintv = len(l) / 25 for p in l: ts.addInstall(p.hdr, p.hdr, how) total = total + 1 totalSize = totalSize + (p[rpm.RPMTAG_SIZE] / 1024) i = i + 1 # HACK - dont overload progress bar with useless requests updcount = updcount + 1 if updcount > updintv: progress.set(i) updcount = 0 progress.pop() depcheck = DependencyChecker(id.grpset) if not id.grpset.hdrlist.preordered(): log ("WARNING: not all packages in hdlist had order tag") # have to call ts.check before ts.order() to set up the alIndex ts.check(depcheck.callback) ts.order() else: ts.check(depcheck.callback) if upgrade: logname = '/root/upgrade.log' else: logname = '/root/install.log' instLogName = instPath + logname try: iutil.rmrf (instLogName) except OSError: pass instLog = open(instLogName, "w+") syslogname = "%s%s.syslog" % (instPath, logname) try: iutil.rmrf (syslogname) except OSError: pass syslog.start (instPath, syslogname) if id.compspkg is not None: num = i + 1 else: num = i if upgrade: instLog.write(_("Upgrading %s packages\n\n") % (num,)) else: instLog.write(_("Installing %s packages\n\n") % (num,)) ts.scriptFd = instLog.fileno () rpm.setLogFile(instLog) # the transaction set dup()s the file descriptor and will close the # dup'd when we go out of scope if upgrade: modeText = _("Upgrading %s-%s-%s.%s.\n") else: modeText = _("Installing %s-%s-%s.%s.\n") errors = rpmErrorClass(instLog) pkgTimer = timer.Timer(start = 0) id.instProgress.setSizes(total, totalSize) id.instProgress.processEvents() cb = InstallCallback(intf.messageWindow, id.instProgress, pkgTimer, method, intf.progressWindow, instLog, modeText, ts) # write out migrate adjusted fstab so kernel RPM can get initrd right if upgrade: id.fsset.migratewrite(instPath) if id.upgradeDeps: instLog.write(_("\n\nThe following packages were automatically\n" "selected to be installed:" "\n" "%s" "\n\n") % (id.upgradeDeps,)) cb.initWindow = intf.waitWindow(_("Install Starting"), _("Starting install process, this may take several minutes...")) ts.setProbFilter(~rpm.RPMPROB_FILTER_DISKSPACE) problems = ts.run(cb.cb, 0) if problems: # restore old fstab if we did anything for migrating if upgrade: id.fsset.restoreMigratedFstab(instPath) spaceneeded = {} nodeneeded = {} size = 12 for (descr, (type, mount, need)) in problems: log("(%s, (%s, %s, %s))" %(descr, type, mount, need)) if mount and mount.startswith(instPath): mount = mount[len(instPath):] if not mount: mount = '/' if type == rpm.RPMPROB_DISKSPACE: if spaceneeded.has_key (mount) and spaceneeded[mount] < need: spaceneeded[mount] = need else: spaceneeded[mount] = need elif type == nodeprob: if nodeneeded.has_key (mount) and nodeneeded[mount] < need: nodeneeded[mount] = need else: nodeneeded[mount] = need else: if descr is None: descr = "no description" log ("WARNING: unhandled problem returned from " "transaction set type %d (%s)", type, descr) probs = "" if spaceneeded: probs = probs + _("You don't appear to have enough disk space " "to install the packages you've selected. " "You need more space on the following " "file systems:\n\n") probs = probs + ("%-15s %s\n") % (_("Mount Point"), _("Space Needed")) for (mount, need) in spaceneeded.items (): log("(%s, %s)" %(mount, need)) if need > (1024*1024): need = (need + 1024 * 1024 - 1) / (1024 * 1024) suffix = "M" else: need = (need + 1023) / 1024 suffix = "k" prob = "%-15s %d %c\n" % (mount, need, suffix) probs = probs + prob if nodeneeded: if probs: probs = probs + '\n' probs = probs + _("You don't appear to have enough file nodes " "to install the packages you've selected. " "You need more file nodes on the following " "file systems:\n\n") probs = probs + ("%-15s %s\n") % (_("Mount Point"), _("Nodes Needed")) for (mount, need) in nodeneeded.items (): prob = "%-15s %d\n" % (mount, need) probs = probs + prob if len(probs) == 0: probs = ("ERROR: NO! An unexpected problem has occurred with " "your transaction set. Please see tty3 for more " "information") intf.messageWindow (_("Disk Space"), probs) ts.closeDB() del ts instLog.close() syslog.stop() method.systemUnmounted () return DISPATCH_BACK # This should close the RPM database so that you can # do RPM ops in the chroot in a %post ks script ts.closeDB() del ts # make sure the window gets popped (#82862) if not cb.beenCalled: cb.initWindow.pop() method.filesDone () # rpm environment files go bye-bye for file in ["__db.001", "__db.002", "__db.003"]: try: os.unlink("%s/var/lib/rpm/%s" %(instPath, file)) except Exception, e: log("failed to unlink /var/lib/rpm/%s: %s" %(file,e)) # FIXME: remove the /var/lib/rpm symlink that keeps us from having # db->close error messages shown. I don't really like this though :( try: os.unlink("/var/lib/rpm") except Exception, e: log("failed to unlink /var/lib/rpm: %s" %(e,)) if upgrade: instLog.write(_("\n\nThe following packages were available in " "this version but NOT upgraded:\n")) lines = [] for p in id.grpset.hdrlist.values(): if not p.isSelected(): lines.append("%s-%s-%s.%s.rpm\n" % (p.hdr[rpm.RPMTAG_NAME], p.hdr[rpm.RPMTAG_VERSION], p.hdr[rpm.RPMTAG_RELEASE], p.hdr[rpm.RPMTAG_ARCH])) lines.sort() for line in lines: instLog.write(line) instLog.close () id.instProgress = None def doPostInstall(method, id, intf, instPath): if flags.test: return w = intf.progressWindow(_("Post Install"), _("Performing post install configuration..."), 6) upgrade = id.upgrade.get() arch = iutil.getArch () if upgrade: logname = '/root/upgrade.log' else: logname = '/root/install.log' instLogName = instPath + logname instLog = open(instLogName, "a") try: if not upgrade: w.set(1) copyExtraModules(instPath, id.grpset, id.extraModules) w.set(2) # pcmcia is supported only on i386 at the moment if arch == "i386": pcmcia.createPcmciaConfig( instPath + "/etc/sysconfig/pcmcia") # we need to write out the network bits before kudzu runs # to avoid getting devices in the wrong order (#102276) id.network.write(instPath) w.set(3) # blah. If we're on a serial mouse, and we have X, we need to # close the mouse device, then run kudzu, then open it again. # turn it off mousedev = None # XXX currently Bad Things (X async reply) happen when doing # Mouse Magic on Sparc (Mach64, specificly) # The s390 doesn't even have a mouse! if os.environ.get('DISPLAY') == ':1' and arch != 'sparc': try: import xmouse mousedev = xmouse.get()[0] except RuntimeError: pass if mousedev: try: os.rename (mousedev, "/dev/disablemouse") except OSError: pass try: xmouse.reopen() except RuntimeError: pass if arch != "s390": # we need to unmount usbdevfs before mounting it usbWasMounted = iutil.isUSBDevFSMounted() if usbWasMounted: isys.umount('/proc/bus/usb', removeDir = 0) # see if unmount suceeded, if not pretent it isnt mounted # because we're screwed anywyas if system is going to # lock up if iutil.isUSBDevFSMounted(): usbWasMounted = 0 unmountUSB = 0 try: isys.mount('/usbdevfs', instPath+'/proc/bus/usb', 'usbdevfs') unmountUSB = 1 except: log("Mount of /proc/bus/usb in chroot failed") pass argv = [ "/usr/sbin/kudzu", "-q" ] if id.grpset.hdrlist.has_key("kernel"): ver = "%s-%s" %(id.grpset.hdrlist["kernel"][rpm.RPMTAG_VERSION], id.grpset.hdrlist["kernel"][rpm.RPMTAG_RELEASE]) argv.extend(["-k", ver]) devnull = os.open("/dev/null", os.O_RDWR) iutil.execWithRedirect(argv[0], argv, root = instPath, stdout = devnull) # turn it back on if mousedev: try: os.rename ("/dev/disablemouse", mousedev) except OSError: pass try: xmouse.reopen() except RuntimeError: pass if unmountUSB: try: isys.umount(instPath + '/proc/bus/usb', removeDir = 0) except SystemError: # if we fail to unmount, then we should just not # try to remount it. this protects us from random # suckage usbWasMounted = 0 if usbWasMounted: isys.mount('/usbdevfs', '/proc/bus/usb', 'usbdevfs') w.set(4) if upgrade and id.dbpath is not None: # remove the old rpmdb try: iutil.rmrf (id.dbpath) except OSError: pass if upgrade: # needed for prior systems which were not xinetd based migrateXinetd(instPath, instLogName) w.set(5) # FIXME: hack to install the comps package if (id.compspkg is not None and os.access(id.compspkg, os.R_OK)): log("found the comps package") try: # ugly hack path = id.compspkg.split("/mnt/sysimage")[1] args = ["/bin/rpm", "-Uvh", path] rc = iutil.execWithRedirect(args[0], args, stdout = "/dev/tty5", stderr = "/dev/tty5", root = instPath) ts = rpm.TransactionSet() ts.setVSFlags(~(rpm.RPMVSF_NORSA|rpm.RPMVSF_NODSA)) ts.closeDB() fd = os.open(id.compspkg, os.O_RDONLY) h = ts.hdrFromFdno(fd) os.close(fd) if upgrade: text = _("Upgrading %s-%s-%s.%s.\n") else: text = _("Installing %s-%s-%s.%s.\n") instLog.write(text % (h['name'], h['version'], h['release'], h['arch'])) os.unlink(id.compspkg) del ts except Exception, e: log("comps.rpm failed to install: %s" %(e,)) try: os.unlink(id.compspkg) except: pass else: log("no comps package found") w.set(6) finally: pass # XXX hack - we should really write a proper /etc/lvmtab. but for now # just create the lvmtab if they have /sbin/vgscan and some VGs if (os.access(instPath + "/sbin/vgscan", os.X_OK) and os.access(instPath + "/proc/lvm", os.R_OK) and len(os.listdir("/proc/lvm/VGs")) > 0): rc = iutil.execWithRedirect("/sbin/vgscan", ["vgscan", "-v"], stdout = "/dev/tty5", stderr = "/dev/tty5", root = instPath, searchPath = 1) # write out info on install method used try: if id.methodstr is not None: if os.access (instPath + "/etc/sysconfig/installinfo", os.R_OK): os.rename (instPath + "/etc/sysconfig/installinfo", instPath + "/etc/sysconfig/installinfo.rpmsave") f = open(instPath + "/etc/sysconfig/installinfo", "w+") f.write("INSTALLMETHOD=%s\n" % (string.split(id.methodstr, ':')[0],)) try: ii = open("/tmp/isoinfo", "r") il = ii.readlines() ii.close() for line in il: f.write(line) except: pass f.close() else: log("methodstr not set for some reason") except: log("Failed to write out installinfo") w.pop () sys.stdout.flush() syslog.stop() def migrateXinetd(instPath, instLog): if not os.access (instPath + "/usr/sbin/inetdconvert", os.X_OK): return if not os.access (instPath + "/etc/inetd.conf.rpmsave", os.R_OK): return argv = [ "/usr/sbin/inetdconvert", "--convertremaining", "--inetdfile", "/etc/inetd.conf.rpmsave" ] logfile = os.open (instLog, os.O_APPEND) iutil.execWithRedirect(argv[0], argv, root = instPath, stdout = logfile, stderr = logfile) os.close(logfile) def copyExtraModules(instPath, grpset, extraModules): kernelVersions = grpset.kernelVersionList() foundModule = 0 try: f = open("/etc/arch") arch = f.readline().strip() del f except IOError: arch = os.uname()[2] for (path, name) in extraModules: if not path: path = "/modules.cgz" pattern = "" names = "" for (n, tag) in kernelVersions: if tag == "up": pkg = "kernel" else: pkg = "kernel-%s" %(tag,) arch = grpset.hdrlist[pkg][rpm.RPMTAG_ARCH] # version 1 path pattern = pattern + " %s/%s/%s.o " % (n, arch, name) # version 0 path pattern = pattern + " %s/%s.o " % (n, name) names = names + " %s.o" % (name,) command = ("cd %s/lib/modules; gunzip < %s | " "%s/bin/cpio --quiet -iumd %s" % (instPath, path, instPath, pattern)) log("running: '%s'" % (command, )) os.system(command) for (n, tag) in kernelVersions: if tag == "up": pkg = "kernel" else: pkg = "kernel-%s" %(tag,) toDir = "%s/lib/modules/%s/updates" % \ (instPath, n) to = "%s/%s.o" % (toDir, name) if (os.path.isdir("%s/lib/modules/%s" %(instPath, n)) and not os.path.isdir("%s/lib/modules/%s/updates" %(instPath, n))): os.mkdir("%s/lib/modules/%s/updates" %(instPath, n)) if not os.path.isdir(toDir): continue arch = grpset.hdrlist[pkg][rpm.RPMTAG_ARCH] for p in ("%s/%s.o" %(arch, name), "%s.o" %(name,)): fromFile = "%s/lib/modules/%s/%s" % (instPath, n, p) if (os.access(fromFile, os.R_OK)): log("moving %s to %s" % (fromFile, to)) os.rename(fromFile, to) # the file might not have been owned by root in the cgz os.chown(to, 0, 0) foundModule = 1 else: log("missing DD module %s (this may be okay)" % fromFile) if foundModule == 1: for (n, tag) in kernelVersions: recreateInitrd(n, instPath) #Recreate initrd for use when driver disks add modules def recreateInitrd (kernelTag, instRoot): log("recreating initrd for %s" % (kernelTag,)) iutil.execWithRedirect("/sbin/new-kernel-pkg", [ "/sbin/new-kernel-pkg", "--mkinitrd", "--depmod", "--install", kernelTag ], stdout = None, stderr = None, searchPath = 1, root = instRoot) # XXX Deprecated. Is this ever called anymore? def depmodModules(comps, instPath): kernelVersions = comps.kernelVersionList() for (version, tag) in kernelVersions: iutil.execWithRedirect ("/sbin/depmod", [ "/sbin/depmod", "-a", version, "-F", "/boot/System.map-" + version ], root = instPath, stderr = '/dev/null') def betaNagScreen(intf, dir): publicBetas = { "Red Hat Linux": "Red Hat Linux Public Beta", "Red Hat Enterprise Linux": "Red Hat Enterprise Linux Public Beta" } if dir == DISPATCH_BACK: return DISPATCH_NOOP fileagainst = None for (key, val) in publicBetas.items(): if productName.startswith(key): fileagainst = val if fileagainst is None: fileagainst = "%s Beta" %(productName,) while 1: rc = intf.messageWindow( _("Warning! This is a beta!"), _("Thank you for downloading this " "%s Beta release.\n\n" "This is not a final " "release and is not intended for use " "on production systems. The purpose of " "this release is to collect feedback " "from testers, and it is not suitable " "for day to day usage.\n\n" "To report feedback, please visit:\n\n" " http://bugzilla.redhat.com/bugzilla\n\n" "and file a report against '%s'.\n" %(productName, fileagainst)), type="custom", custom_icon="warning", custom_buttons=[_("_Exit"), _("_Install BETA")]) if not rc: rc = intf.messageWindow( _("Rebooting System"), _("Your system will now be rebooted..."), type="custom", custom_icon="warning", custom_buttons=[_("_Back"), _("_Reboot")]) if rc: sys.exit(0) else: break # FIXME: this is a kind of poor way to do this, but it will work for now def selectLanguageSupportGroups(grpset, langSupport): sup = langSupport.supported if len(sup) == 0: sup = langSupport.getAllSupported() for group in grpset.groups.values(): xmlgrp = grpset.compsxml.groups[group.basename] langs = [] for name in sup: try: lang = langSupport.langInfoByName[name][0] langs.extend(language.expandLangs(lang)) except: continue if group.langonly is not None and group.langonly in langs: group.select() for package in xmlgrp.pkgConditionals.keys(): req = xmlgrp.pkgConditionals[package] if not grpset.hdrlist.has_key(package): log("Missing %s which is in a langsupport conditional" %(package,)) continue # add to the deps in the dependencies structure for the # package. this should take care of whenever we're # selected grpset.hdrlist[req].addDeps([package], main = 0) if grpset.hdrlist[req].isSelected(): grpset.hdrlist[package].select() sys.stdout.flush() grpset.hdrlist[package].usecount += grpset.hdrlist[req].usecount - 1 group.selectDeps([package], uses = grpset.hdrlist[req].usecount)  . ..installpath_gui.pycongrats_gui.py,7} ^?ge031_KyR#6[|mOp/}__* EQ?M!?"0F>뙨_!~1LUyPy!@GIҬm??@U%綾( 72)/ۿ b>H//<& [Wb?&^/f ^nqkzVҽul|.G&deTaa}zQ=$E'{ }ëG=/y%A*ʞDuؽdOۺ׻Cq%?5kׯ/&셢'2jp#?ƓxP%8kcv^BQx ߈i">np_6~ ~9??w(;IJdɈV6K7dyuBK&ˠKi^ğ(2#'|+џ_%/~p4ԟ gWD9kTwc= q$#t=-y,2D+٠/~O9_&.tLp_7n_{6?o?V΢l Uگ lqZQg#Z*[gi4ra|M'R;0>Lf̫'Pv؃϶Rɷ1_ b7'^<5-_s/~-L.%c"qHoe%z η<# # installpath_gui.py: screen for selecting which installclass to use. # # Copyright 2000-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import installclass import gtk import gui from pixmapRadioButtonGroup_gui import pixmapRadioButtonGroup from iw_gui import InstallWindow from flags import flags from rhpl.translate import _, N_ #CJS added so to log from rhpl.log import log UPGRADE = 0 INSTALL = 1 CUSTOM = 2 WORKSTATION_GNOME = 3 WORKSTATION_KDE = 4 SERVER = 5 class InstallPathWindow (InstallWindow): installTypes = installclass.availableClasses() htmlTag = "instpath" windowTitle = N_("Installation Type") def getNext(self): # Hack to let backing out of upgrades work properly #if self.flags.setupFilesystems() and self.id.fstab: #self.id.fstab.turnOffSwap() selection = None for (name, object, pixmap) in self.installTypes: if name == self.currentClassName: selection = object if not isinstance (self.id.instClass, selection): c = selection(self.flags.expert) c.setSteps(self.dispatch) c.setInstallData(self.id) needNewDruid = 1 def optionToggled(self, widget, name): if widget.get_active(): self.currentClassName = name def createInstallTypeOption(self): r = pixmapRadioButtonGroup() for (name, object, pixmap) in self.installTypes: descr = object.description r.addEntry(name, _(name), pixmap=self.ics.readPixmap(pixmap), descr=_(descr)) return r # InstallPathWindow tag="instpath" def getScreen(self, dispatch, id, method, intf): self.id = id self.intf = intf self.flags = flags self.method = method self.dispatch = dispatch vbox = gtk.VBox (gtk.FALSE, 10) vbox.set_border_width (8) self.r = self.createInstallTypeOption() b = self.r.render() self.r.setToggleCallback(self.optionToggled) # figure out current class as well as default defaultClass = None currentClass = None firstClass = None for (name, object, pixmap) in self.installTypes: if firstClass is None: firstClass = object if isinstance(id.instClass, object): currentClass = object if object.default: defaultClass = object if currentClass is None: if defaultClass is not None: self.currentClassName = defaultClass.name else: self.currentClassName = firstClass.name else: self.currentClassName = currentClass.name self.r.setCurrent(self.currentClassName) # CJS Added for scrolling log("making scrolledwin now") scrolledwin = gtk.ScrolledWindow () scrolledwin.set_border_width(4) # scrolledwin.set_usize(-1,475) scrolledwin.set_size_request(300,475) scrolledwin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) scrolledwin.add_with_viewport(b) scrolledwin.show() log("scrolledwin show just done") # CJS added end box = gtk.VBox (gtk.FALSE) # box.pack_start(b, gtk.FALSE) box.pack_start(scrolledwin, gtk.FALSE) vbox.pack_start (box, gtk.FALSE) return vbox # # congrats_gui.py: install/upgrade complete screen. # # Copyright 2000-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import gtk import gui from iw_gui import * from rhpl.translate import _, N_ from constants import * import iutil class CongratulationWindow (InstallWindow): windowTitle = N_("Congratulations") def __init__ (self, ics): InstallWindow.__init__(self, ics) ics.setPrevEnabled(gtk.FALSE) ics.setNextButton(gtk.STOCK_QUIT, _("_Exit")) ics.setHelpButtonEnabled(gtk.FALSE) ics.setHelpEnabled(gtk.FALSE) ics.setGrabNext(1) def getNext(self): # XXX - copy any screenshots over gui.copyScreenshots() # CongratulationWindow tag=NA def getScreen (self): self.ics.setHelpEnabled (gtk.FALSE) hbox = gtk.HBox (gtk.FALSE, 5) pix = self.ics.readPixmap ("done.png") if pix: a = gtk.Alignment () a.add (pix) a.set (0.5, 0.5, 1.0, 1.0) a.set_size_request(200, -1) hbox.pack_start (a, gtk.FALSE, gtk.FALSE, 36) bootstr = productName if iutil.getArch() == "s390": floppystr = "" else: floppystr = _("Remove any installation media (diskettes or " "CD-ROMs) used during the installation process " "and press to reboot your system." "\n\n") #CJS Changed out the RedHat stuff and put in Fermi stuff label = gui.WrappingLabel( _("Congratulations, the installation is complete.\n\n" "%s" "Thanks for installing %s \n" ) %(floppystr, bootstr)) # label = gui.WrappingLabel( # _("Congratulations, the installation is complete.\n\n" # "%s" # "%s" # "For information on Errata (updates and bug fixes), visit:\n" # "\thttp://www.redhat.com/errata/\n\n" # "For information on automatic updates through Red Hat " # "Network, visit:\n" # "\thttp://rhn.redhat.com/\n\n" # "For information on using and configuring the system, visit:\n" # "\thttp://www.redhat.com/docs/\n" # "\thttp://www.redhat.com/apps/support/\n\n" # "To register the product for support, visit:\n" # "\thttp://www.redhat.com/apps/activate/\n\n") % (floppystr, # bootstr,)) hbox.pack_start (label, gtk.TRUE, gtk.TRUE) return hbox  . ..comps custom.pngj:^j[.5K.5n~Ycv1 I̗@O!)^VKBX8<;3K`bF5~_i^8$U/4Wo:q|akK}ofZ lwPmR "sy<\v>E~=M119ޯ/Lz2~6 }@C~&z@IXBInh4Hps7oǫb>/V~_}? ν"kO`Vuq_Z?dy61b>jVo +~I!ħ@{%垲t?e/Sm ]o:$csx6/+Wۺ:{ 7Şl҆-W9DXڈ;"gUi˂hR<䤜2&s<#x{69ΞU;}q=BV 4DkR ܀TvƗ/֏%SX0A ...'=Y}”O_ǵ[}/X^ч@_;F;#*xO_[:г4Hl|cX!g䏑x Ɓo6`}ڎZY+'֧<_l\nkwiXȕĨz}of/{*gY~SNSunSii,aRjc65x=ς~OVGy&z{"_#/j\r+Se@":3?`JGA܅L$jCxP;[OM%xBHyN>_^jkj8ީpۊ$椯>ƿ3P*<╱lK=|RS|]qЉCE /aKkjod1IIq| {R|s>cT #s$m#_(l)? μ16A~O?5ŋsj!]dϫHv>jyO@ &/>ҾKp<}v7fMΘ1C "/E0c 6sLdYn#Ix`0HUUդx \QQPYY9.R)v;LzPUUR[[KMM `N$Kszu˒%Ktb2ZXVb~",#2EEEL&±oD"'^׋눢$If"Nb``H$fCeN'dJx_xYTT1͓P}ݧoܸł$IL& 96 EQp\$S0-;w:u/x2 /*`ʕhD86v;Ns?ć9SQv(TU5d4 ߏ,8i0r~;mڴ$IVs-dE;v粫H>p8~V 6mvLi%%%y;,ˣf}e#0HLsDLaa!$z_.\FXgV5xRLEQrM)Em6vEk^{gyt:f!vȲ9qSo{i=>d:nzp?k׮@E ZaI0dYE~Kf({ul|~n7mmmڵ(s ,:::p444L?q+O l1᷿'} @<' ;ٰa[lviHA)++>/g)j6Zf88$IB4Xz5'O$ Bkk+fժU[ 8S /[ZFG㚬F(^0o<ꨮ!IM:(NSRd_|B .rOR^^ ʡChkkxBAE Ԍ>MP={uV#5 `ȨMZŋu], ,˙(nDPUi fT[?83VGy\5 OF1|<#Ѣ77ܭq˵cr"pW=p.ǗL:I*Bu"Aɤ Y4X,fCUUVn ;(yfV+dr?W܄RbL&Css3g,[̆ IX,f1LqٌnP=rJJʸ59" =^\\L*"(u]l68X:ppwsV.,C,3R$#I6 UUI tuu r:a˱d2$d*gTU%N^<ȶm>OYحCYr9i=vh?D?]{#Ӌ r&z9pȲL4EUUt]paJKKQU>~?@'N 2DD"Aww7lmU`e3hjjB IPUY1̈́B!blE^^l/^FMMMҥKI&J8rle4JikkΩmǿ 4▹MW;w$H$4 C:&"2,%hC8Ƀ}1Yb&9suJ2 CCC$ cb/G݈a r'OpCZ0(bٌ DQJJJ(//J נI4wϺcW sR*gIjnn֯j顣T*e H$E"w6=:a7xH_ PI455fBn^m=gϥxZI~wr}˖-TVV*`t6rKH$믽_~02H&Ϗഀ B477{q`n汲[,ZPŬg"R)^~ ,y̆ovl6D`0H__xx<>l75dӏXLXL&||u;SC|t,ȒkۂQhd2SAAxs豉L2E_f _=. MH$F- ! hmmeWr䓏n9  &UnNA8C/"?ݖR}̙o*wcǎq TU5|x*;nEXmV슃]oL<CQ1.˃d6 = F ȫB cUqy pL1 =ESOC yw0H. ?hP#D`=]|7'<;C^Ϭ[)]/ꊯ# .|vkw'R0=&Ip||qc>ڕ7ERzS%8o "LȲ֎:z}Ň4%_6.m_.ɸtW͐JIENDB` . ..installpath_text.pymcomplete_text.py welcome_text.py>Sx׃O擿>|?嶮#kcjk$%焏6[O#2; ʉzFΧph'Abg0 ٟ&pᡱzoZ`9QD~?3j ?{5~Gwtj n݋@G?EESw1 57pz_5"݆iG1?3ײC,ʛo=Vz[Z?6.k5 /轨] J -~h.Lsm]XLWޏW^ca< ?GœĈ&#Tm RďD<+k?eR"K7\Sz6b$y6Y gs j| %{G㵿/sk5 N}>gey.[/wSyCe߱O7 ~F0)Ck?`}?lŻ1?~YHS_O폝S6F~Xg@U+\0BGiLQV?"YъF3~u¿ghO'o|Cs7ޏ]#3o/tp/#>TWoz+ẋ_?>[}J^(Ddu.OErk)FD|%c~*ߠ# # installpath_text: text mode installation type selection dialog # # Copyright 2001-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # from snack import * from constants_text import * from rhpl.translate import _ from flags import flags import installclass class InstallPathWindow: def __call__ (self, screen, dispatch, id, method, intf): classes = installclass.availableClasses() choices = [] default = 0 i = 0 orig = None for (name, object, icon) in classes: choices.append(_(name)) if isinstance(id.instClass, object): orig = i elif object.default: default = i i = i + 1 if orig != None: default = orig # CJS # (button, choice) = ListboxChoiceWindow(screen, _("Installation Type"), # _("What type of system would you like to install?"), # choices, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], # width = 40, default = default, help = "installpath") (button, choice) = ListboxChoiceWindow(screen, _("Installation Type"), _("What type of system would you like to install?"), choices, [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], width = 40, default = default, help = "installpath", scroll = 1 , height = 11 ) # CJS if button == TEXT_BACK_CHECK: return INSTALL_BACK if (choice != orig): (name, objectClass, logo) = classes[choice] c = objectClass(flags.expert) c.setSteps(dispatch) c.setInstallData(id) return INSTALL_OK # # complete_text.py: text mode congratulations windows # # Copyright 2001-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # from snack import * from constants_text import * from rhpl.translate import _ from constants import * import iutil class FinishedWindow: def __call__ (self, screen): bootstr = "" if iutil.getArch() == "s390": floppystr = _("Press to end the installation process.\n\n") bottomstr = _(" to exit") else: floppystr = _("Remove any installation media (diskettes or " "CD-ROMs) used during the installation process " "and press to reboot your system." "\n\n") bottomstr = _(" to reboot") screen.pushHelpLine (string.center(bottomstr, screen.width)) rc = ButtonChoiceWindow (screen, _("Complete"), _("Congratulations, your %s installation is " "complete.\n\n" "%s" "%s" ) % (productName, floppystr, bootstr), [ _("OK") ], help = "finished", width=60) return INSTALL_OK # # welcome_text.py: text mode welcome window # # Copyright 2001-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # from snack import * from constants_text import * from rhpl.translate import _ from constants import * import os class WelcomeWindow: def __call__(self, screen, configFileData): rc = ButtonChoiceWindow(screen, _("%s") % (productName,), _("Welcome to %s!\n\n") % (productName), buttons = [TEXT_OK_BUTTON, TEXT_BACK_BUTTON], width = 50, help = "welcome") if rc == TEXT_BACK_CHECK: return INSTALL_BACK return INSTALL_OK # # hdrlist.py: header list and group set management. # Parts from old anaconda/comps.py # # Erik Troan # Matt Wilson # Michael Fulbright # Jeremy Katz # # Copyright 2001-2003 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import rpm import os,sys,time from rhpl.log import log from rhpl.translate import _, N_ import rhpl.comps import rhpl.arch import language ON = 1 MANUAL_ON = 2 DEP_ON = 3 OFF = -1 MANUAL_OFF = -2 MANUAL_NONE = 0 ON_STATES = (ON, MANUAL_ON, DEP_ON) OFF_STATES = (OFF, MANUAL_OFF) PKGTYPE_MANDATORY = 0 PKGTYPE_DEFAULT = 1 PKGTYPE_OPTIONAL = 2 EVERYTHING_DESCRIPTION = _("This group includes all the packages available. " "Note that there are substantially more packages " "than just the ones in all the other package " "groups on this page.") # CJS the GFS was excluded as it needs configuration to not complain # CJS ksh93 is excluded because it has some of the same files as pdksh # CJS up2date* is excluded as it causes firstboot to not work # CJS rhn-applet has a dependency on up2date # CJS *openafs* because it needs configuration and it has kernel modules EverythingExclude = {'kernel' : None, 'kernel-BOOT' : None, 'kernel-smp' : None, 'kernel-bigmem' : None, 'kernel-summit' : None, 'kernel-enterprise' : None, 'kernel-tape' : None, 'kernel-BOOTtape' : None, 'kernel-pseries': None, 'kernel-iseries': None, 'kernel-bigmem-unsupported': None, 'kernel-hugemem': None, 'kernel-hugemem-unsupported': None, 'GFS': None, 'GFS-devel': None, 'GFS-modules': None, 'GFS-modules-smp': None, 'GFS-modules-hugemem': None,'ksh93': None, 'up2date': None, 'up2date-gnome': None, 'up2date-update': None, 'rhn-applet': None, 'openafs': None, 'openafs-client': None, 'openafs-compat': None, 'openafs-devel': None, 'openafs-firstboot': None, 'openafs-kernel-source': None, 'openafs-kpasswd': None, 'openafs-krb5': None, 'openafs-server': None, 'SL_afs_no_dynroot': None, 'SL_startgnome_afs': None, 'SL_startkde_afs': None, 'kernel-module-openafs-2.4.21-32.0.1.EL': None, 'kernel-module-openafs-2.4.21-32.0.1.ELsmp': None } def showMem(): f = open("/proc/self/status", "r") lines = f.readlines() f.close() for line in lines: if line.startswith("VmSize:"): vmsize = line.split(":")[1].strip() if line.startswith("VmRSS:"): vmrss = line.split(":")[1].strip() print vmsize, vmrss def nevra(hdr): "Convenience function to return the NEVRA in canonical form for a header." if hdr[rpm.RPMTAG_EPOCH]: epoch = hdr[rpm.RPMTAG_EPOCH] else: epoch = "0" return "%s-%s:%s-%s.%s" %(hdr[rpm.RPMTAG_NAME], epoch, hdr[rpm.RPMTAG_VERSION], hdr[rpm.RPMTAG_RELEASE], hdr[rpm.RPMTAG_ARCH]) def getLangs(): if os.environ.has_key("LANG"): langs = language.expandLangs(os.environ["LANG"]) else: langs = [] return langs # poor heuristic for figuring out the best of two packages with the same # name. it sucks, but it's the best we've got right now. # basically, we generally prefer the shorter name with some special-case # caveats. def betterPackageForProvides(h1, h2): # make sure we don't try to return a bogus arch if h1 is not None and rhpl.arch.score(h1['arch']) == 0: h1 = None if h2 is not None and rhpl.arch.score(h2['arch']) == 0: h2 = None # if one is none, return the other if h2 is None: return h1 if h1 is None: return h2 # if we're already being installed, then we're clearly the superior # answer if h1.isSelected(): return h1 if h2.isSelected(): return h2 # sendmail is preferred over postfix if h1['name'] == "sendmail" and h2['name'] == "postfix": return h1 if h2['name'] == "sendmail" and h1['name'] == "postfix": return h2 # we generally prefer non-devel over devel if h1['name'].endswith("-devel") and not h2["name"].endswith("-devel"): return h2 if h2['name'].endswith("-devel") and not h1["name"].endswith("-devel"): return h1 # else, shorter name wins # this handles glibc-debug, kernel-*, kde2-compat, etc if len(h1['name']) < len(h2['name']): return h1 if len(h2['name']) < len(h1['name']): return h2 # compare versions, newer version is better cmp = rpm.versionCompare(h1.hdr, h2.hdr) if cmp < 0: return h2 elif cmp > 0: return h1 # same package names, which is a better arch? score1 = rhpl.arch.score(h1['arch']) score2 = rhpl.arch.score(h2['arch']) if (score1 < score2): return h1 elif (score2 < score1): return h2 # okay, there's no convincing difference. just go with the first return h1 cached = {} # returns the best nevra in hdrlist to match dep # FIXME: doesn't care about EVR right now -- the tree is assumed to be # sane and dep is just the name def depMatch(dep, hdrlist): # ignore rpmlib if dep.startswith("rpmlib("): return None # try to see if it just exists first elif hdrlist.has_key(dep): return nevra(hdrlist[dep]) elif cached.has_key(dep): return cached[dep] # next, see if its a file dep elif dep[0] == "/": hdr = None for h in hdrlist.pkgs.values(): l = [] for f in h.hdr.fiFromHeader(): l.append(f[0]) if (dep in l): hdr = betterPackageForProvides(h, hdr) if hdr is not None: # cache all binaries from this package. helps with, eg, coreutils for f in hdr.hdr.fiFromHeader(): if f[0].find("bin") != -1: cached[f[0]] = nevra(hdr) cached[dep] = nevra(hdr) return nevra(hdr) # else: # need to do this even on file deps too because they could be virtual # provides such as /usr/sbin/sendmail or /usr/bin/lpr. if 1: hdr = None for h in hdrlist.pkgs.values(): if (dep in h[rpm.RPMTAG_PROVIDENAME]): hdr = betterPackageForProvides(h, hdr) if hdr is not None: cached[dep] = nevra(hdr) return nevra(hdr) return None class DependencyChecker: def __init__(self, grpset, how = "i"): self.grpset = grpset self.added = [] self.unknown = [] self.how = how # FIXME: this is the simple stupid version. it doesn't actually handle # paying attention to EVR. def callback(self, ts, tag, name, evr, flags): if tag == rpm.RPMTAG_REQUIRENAME: pkgnevra = depMatch(name, self.grpset.hdrlist) if pkgnevra and self.grpset.hdrlist.has_key(pkgnevra): hdr = self.grpset.hdrlist[pkgnevra] else: hdr = None if hdr is not None and not hdr.isSelected(): if evr: nevr = "%s-%s" %(name, evr) else: nevr = name log("using %s to satisfy %s" %(nevra(hdr), nevr)) ts.addInstall(hdr.hdr, hdr.hdr, self.how) hdr.select(isDep = 1) self.added.append(nevra(hdr.hdr)) return -1 return 1 class Package: def __init__(self, hdr): self.hdr = hdr self.usecount = 0 self.manual_state = MANUAL_NONE self.dependencies = [] self.depsFound = 0 self.name = self.hdr[rpm.RPMTAG_NAME] def getState(self): return (self.usecount, self.manual_state) def setState(self, state): (self.usecount, self.manual_state) = state def addDeps(self, deps, main = 1): self.dependencies.extend(deps) # FIXME: this is a hack so that adding deps for lang support stuff # doesn't set depsFound if main: self.depsFound = 1 def select(self, isManual = 0, isDep = 0): self.usecount = self.usecount + 1 if isManual: if self.manual_state == MANUAL_NONE: self.manual_state = MANUAL_ON elif self.manual_state == MANUAL_OFF: self.manual_state = MANUAL_NONE if isDep: self.manual_state = DEP_ON def unselect(self, isManual = 0): self.usecount = self.usecount - 1 if isManual: if self.manual_state == MANUAL_NONE: self.manual_state = MANUAL_OFF elif self.manual_state == MANUAL_ON: self.manual_state = MANUAL_NONE # DEBUG if self.usecount < 0: log("WARNING: usecount for %s dropped below 0 (%d)" %(nevra(self.hdr),self.usecount)) # if we've been manually turned on or off, follow that # otherwise, if the usecount is > 0, then we're selected def isSelected(self): if self.manual_state == MANUAL_ON or self.manual_state == DEP_ON: return 1 elif self.manual_state == MANUAL_OFF: return 0 elif self.usecount > 0: return 1 else: return 0 def keys(self): return self.hdr.keys() def __getitem__(self, item): return self.hdr[item] def __repr__(self): return "%s" %(self.nevra(),) def getDescription(self): return self.hdr[rpm.RPMTAG_SUMMARY] def nevra(self): return nevra(self.hdr) class HeaderList: def __init__(self, hdlist): self.hdlist = hdlist self.pkgs = {} self.pkgnames = {} for h in hdlist: nevrastr = nevra(h) name = h['name'] if self.pkgs.has_key(nevra): log("Have more than one copy of %s, skipping" %(nevrastr,)) continue self.pkgs[nevrastr] = Package(h) if self.pkgnames.has_key(name): self.pkgnames[name].append( (nevrastr, h['arch']) ) else: self.pkgnames[name] = [ (nevrastr, h['arch']) ] self.hasFullHeaders = None def has_key(self, item): if self.pkgs.has_key(item): return 1 elif self.getBestNevra(item): return 1 return 0 def keys(self): return self.pkgnames.keys() def values(self): return self.pkgs.values() # this is definite crack rock, but it allows us to avoid tripling # our memory usage :( # reads an hdlist2 file and merges the header information we split out # (things like file lists) def mergeFullHeaders(self, file): if self.hasFullHeaders is not None: return fd = os.open(file, os.O_RDONLY) rpm.mergeHeaderListFromFD(self.hdlist, fd, 1000004) os.close(fd) self.hasFullHeaders = 1 def preordered(self): preordered = 1 for h in self.pkgs.values(): if h.isSelected() and h[1000003] == None: preordered = 0 return preordered # get the best nevra for the package name. # FIXME: surely this can be made faster/less complicated # doing scoring everytime seems like it might be overkill # then again, it shouldn't be called *that* often so it might not matter def getBestNevra(self, item, prefArch = None): bestscore = 0 bestpkg = None if not self.pkgnames.has_kmnopqrstuvwxyz{|}~ey(item): return None # the best nevra is going to be defined by being 1) the best match # for the primary arch (eg, x86_64 on AMD64, ppc on pSeries) and # if that fails, fall back to the canonical (which could be the same) # This will allow us to get the best package by name for both # system packages and kernel while not getting the secondary arch # glibc. if prefArch is not None: arches = (prefArch, ) elif rhpl.arch.getBaseArch() != rhpl.arch.canonArch: arches = (rhpl.arch.getBaseArch(), rhpl.arch.canonArch) else: arches = (rhpl.arch.canonArch, ) for basearch in arches: for (nevra, arch) in self.pkgnames[item]: score = rhpl.arch.archDifference(basearch, arch) if not score: continue # get the "best" version if bestpkg is not None: cmp = rpm.versionCompare(self.pkgs[nevra].hdr, self.pkgs[bestpkg].hdr) if cmp < 0: continue elif cmp > 0: bestscore = score bestpkg = nevra continue if (bestscore == 0) or (score < bestscore): bestpkg = nevra bestscore = score if bestpkg is not None: return bestpkg return bestpkg # FIXME: surely this can be made faster/less complicated # doing scoring everytime seems like it might be overkill # then again, it shouldn't be called *that* often so it might not matter def __getitem__(self, item): if self.pkgs.has_key(item): return self.pkgs[item] # explict nevra not specified -- see what we can do pkg = self.getBestNevra(item) if pkg is None: raise KeyError, "No such package %s" %(item,) return self.pkgs[pkg] class HeaderListFromFile (HeaderList): def __init__(self, path): hdlist = rpm.readHeaderListFromFile(path) HeaderList.__init__(self, hdlist) class Group: def __init__(self, grpset, xmlgrp): self.id = xmlgrp.id self.basename = xmlgrp.name # We want to have translated name/descriptions self.name = None self.description = None for lang in getLangs(): if (self.name is None and xmlgrp.translated_name.has_key(lang)): self.name = xmlgrp.translated_name[lang] if (self.description is None and xmlgrp.translated_description.has_key(lang)): self.description = xmlgrp.translated_description[lang] # fall back to english if they're not set and try to see if the # translation is in the anaconda.po (eg, Everything) if self.name is None: self.name = _(xmlgrp.name) if self.description is None: self.description = xmlgrp.description # obviously enough, hidden components aren't shown self.hidden = not xmlgrp.user_visible # whether or not a group should be enabled by default. only # really matters for custom installs self.default = xmlgrp.default # if it's a biarch group and we're not a biarch-arch, be hidden and off if xmlgrp.biarchonly and rhpl.arch.getMultiArchInfo() is None: self.hidden = 1 self.default = 0 # figure out the preferred arch. if this isn't a biarch group, # fall back to the normal picking. if its a biarch group and we # are a biarch arch, use the information we've got if xmlgrp.biarchonly and rhpl.arch.getMultiArchInfo() is not None: (comp, best, biarch) = rhpl.arch.getMultiArchInfo() pref = biarch else: pref = None # FIXME: this is a hack to handle language support groups self.langonly = xmlgrp.langonly # FIXME: do we really want to keep this? needed to select packages self.grpset = grpset hdrlist = grpset.hdrlist # refcount/manual state just like with packages self.usecount = 0 self.manual_state = MANUAL_NONE # included groups (ie groups that are required if we're selected) self.groupreqs = [] self.packages = {} for (pkg, (type, name)) in xmlgrp.packages.items(): if hdrlist.pkgs.has_key(pkg): pkgnevra = pkg else: pkgnevra = hdrlist.getBestNevra(pkg, prefArch = pref) if pkgnevra is None: log("%s references package %s which doesn't exist" %(self.id, pkg)) continue self.packages[pkgnevra] = self.makePackageDict(pkgnevra, type) # if we don't have any packages, make it hidden to avoid confusion if len(self.packages.keys()) == 0: self.hidden = 1 def getState(self): return (self.usecount, self.manual_state) def setState(self, state): (self.usecount, self.manual_state) = state def addGroupRequires(self, grpid): if grpid not in self.groupreqs: self.groupreqs.append(grpid) def addMetaPkg(self, metapkginfo): (type, id) = metapkginfo if id in self.packages.keys(): log("already have %s in %s" %(id, self.id)) return self.packages[id] = self.makePackageDict(id, type, isMeta = 1) # dict of package info. nevra and type are obvious # state is one of the ON/OFF states def makePackageDict(self, pkgnevra, type, installed = 0, isMeta = 0): if type == u'mandatory': pkgtype = PKGTYPE_MANDATORY elif type == u'default': pkgtype = PKGTYPE_DEFAULT elif type == u'optional': pkgtype = PKGTYPE_OPTIONAL else: log("Invalid package type of %s for %s in %s; defaulting to " "optional" % (type, pkgnevra, self.id)) pkgtype = PKGTYPE_OPTIONAL return { "nevra": pkgnevra, "type": pkgtype, "state": installed, "meta": isMeta } # FIXME: this doesn't seem like the right place for it, but ... :/ def selectDeps(self, pkgs, uses = 1): checked = [] while len(pkgs) > 0: tocheck = pkgs pkgs = [] for pkgnevra in tocheck: if pkgnevra in checked: continue pkg = self.grpset.hdrlist[pkgnevra] # this is a little bit complicated. we don't want to keep # the deps in the comps file (because that gets ugly with biarch) # but we also don't want to have to resolve every time # (it's slow!). so, we cache the first time through if pkg.depsFound == 0: deps = pkg[rpm.RPMTAG_REQUIRENAME] thisone = [] for dep in deps: # hey wait, this is me! if ((pkg[rpm.RPMTAG_PROVIDENAME] is not None) and (dep in pkg[rpm.RPMTAG_PROVIDENAME])): continue for f in pkg.hdr.fiFromHeader(): if f[0] == dep: continue # ignore rpmlib stuff if dep.startswith("rpmlib("): continue p = depMatch(dep, self.grpset.hdrlist) # don't care about self referential deps if p == pkg.nevra(): continue if p in checked or p in tocheck or p in pkgs: continue if p is None: # log("ERROR: unable to resolve dep %s" %(dep,)) continue self.grpset.hdrlist[p].select() # FIXME: this is a hack so we can make sure the # usecount is bumped high enough for # langsupport packages self.grpset.hdrlist[p].usecount += uses - 1 pkgs.append(p) thisone.append(p) pkg.addDeps(thisone) else: deps = pkg.dependencies for dep in deps: # if we've already checked for this package, don't worry if dep in checked or dep in tocheck or dep in pkgs: continue # hmm, not in the header list. we can't do much but # hope for the best if not self.grpset.hdrlist.has_key(dep): log("Package %s requires %s which we don't have" %(tocheck, dep)) continue self.grpset.hdrlist[dep].select() # FIXME: this is a hack so we can make sure the usecount # is bumped high enough for langsupport packages self.grpset.hdrlist[dep].usecount += uses - 1 pkgs.append(dep) checked.append(pkgnevra) # FIXME: this doesn't seem like the right place for it, but ... :/ def unselectDeps(self, pkgs): checked = [] while len(pkgs) > 0: tocheck = pkgs pkgs = [] for pkgnevra in tocheck: pkg = self.grpset.hdrlist[pkgnevra] deps = pkg.dependencies for dep in deps: # if we've already checked for this package, don't worry if dep in checked or dep in tocheck or dep in pkgs: continue # hmm, not in the header list. we can't do much but # hope for the best if not self.grpset.hdrlist.has_key(dep): log("Package %s requires %s which we don't have" %(tocheck, dep)) continue self.grpset.hdrlist[dep].unselect() pkgs.append(dep) checked.append(pkgnevra) # forInclude is whether this group is an include from a previous # asMeta means that we should include the members of the group, # but not this one (useful for Workstation Common, etc) def select(self, forInclude = 0, asMeta = 0, selectOptional = 0): hdrlist = self.grpset.hdrlist # if we're being selected as a meta group, then just select # the members. otherwise, we end up in weirdo states if asMeta: for grpid in self.groupreqs: self.grpset.groups[grpid].select(forInclude = 0) return # update the usecount. if this is manual, change the state if needed # if we were already previously selected, we don't need to bump up # refcounts (which makes things faster) self.usecount = self.usecount + 1 if not forInclude: self.manual_state = MANUAL_ON for grpid in self.groupreqs: self.grpset.groups[grpid].select(forInclude = 1) if self.usecount > 1: return selected = [] for (pkgnevra, pkg) in self.packages.items(): # if it's not optional, we should turn it on if pkg["type"] == PKGTYPE_OPTIONAL and not selectOptional: continue pkg["state"] = ON if pkg["meta"] == 0: hdrlist[pkgnevra].select() selected.append(pkgnevra) self.selectDeps([pkgnevra]) else: self.grpset.groups[pkgnevra].select(forInclude = 1) # manual package selection def selectPackage(self, pkgnevra): pkg = self.packages[pkgnevra] if pkg["state"] in ON_STATES: return pkg["state"] = ON if pkg["meta"] == 0: self.grpset.hdrlist[pkgnevra].select() self.selectDeps([pkgnevra]) else: self.grpset.groups[pkgnevra].select(forInclude = 1) def unselect(self, forInclude = 0): hdrlist = self.grpset.hdrlist # update the usecount. if this is manual, change the state if needed # if we were already previously selected, we don't need to bump up # refcounts (which makes things faster) self.usecount = self.usecount - 1 if not forInclude: self.manual_state = MANUAL_OFF if self.usecount < 0: log("WARNING: usecount for %s < 0 (%d)" %(self.id, self.usecount)) for grpid in self.groupreqs: self.grpset.groups[grpid].unselect(forInclude = 1) if self.usecount > 0: return selected = [] for pkg in self.packages.values(): pkgnevra = pkg["nevra"] if pkg["state"] not in ON_STATES: continue pkg["state"] = OFF if pkg["meta"] == 0: hdrlist[pkgnevra].unselect() selected.append(pkgnevra) self.unselectDeps([pkgnevra]) else: self.grpset.groups[pkgnevra].unselect(forInclude = 1) def unselectPackage(self, pkgnevra): pkg = self.packages[pkgnevra] if pkg["state"] not in ON_STATES: return pkg["state"] = OFF if pkg["meta"] == 0: self.grpset.hdrlist[pkgnevra].unselect() self.unselectDeps([pkgnevra]) else: self.grpset.groups[pkgnevra].unselect(forInclude = 1) def isSelected(self, justManual = 0): if justManual: if self.manual_state == MANUAL_ON: return 1 else: return 0 return (self.usecount > 0) def packageInfo(self): ret = {} for pkg in self.packages.values(): ret[pkg["nevra"]] = (pkg["type"], pkg["state"]) return ret # FIXME: remove this def includesPackage(self, pkg): pkgnevra = nevra(pkg) if self.packages.has_key(pkgnevra): return 1 # make sure it's not in this group for deps tocheck = self.packages.keys() checked = [] while len(tocheck) > 0: pkgs = tocheck tocheck = [] for p in pkgs: if pkgnevra in self.grpset.hdrlist[p].dependencies: return 1 checked.append(p) for m in self.grpset.hdrlist[p].dependencies: if m not in checked and m not in tocheck: tocheck.append(m) return 0 def getDescription(self): return self.description class GroupSet: def __init__(self, compsxml, hdrlist): self.hdrlist = hdrlist self.compsxml = compsxml self.groups = {} for xmlgrp in compsxml.groups.values(): group = Group(self, xmlgrp) self.groups[xmlgrp.id] = group # build up an Everything group everything = rhpl.comps.Group(self.compsxml) everything.name = N_("Everything") everything.id = "everything" everything.description = EVERYTHING_DESCRIPTION multiarch = rhpl.arch.getMultiArchInfo() if multiarch is not None: (comp, best, biarch) = multiarch for pkgname in hdrlist.pkgnames.keys(): if EverythingExclude.has_key(pkgname): continue mainnevra = hdrlist.getBestNevra(pkgname, prefArch = None) if mainnevra is None: continue everything.packages[mainnevra] = (u"mandatory", mainnevra) if multiarch is not None: # get the main and the biarch version of this package # for everything group secnevra = hdrlist.getBestNevra(pkgname, prefArch = biarch) if mainnevra != secnevra and secnevra is not None: everything.packages[secnevra] = (u"mandatory", secnevra) self.compsxml.groups["Everything"] = everything self.groups["everything"] = Group(self, everything) # have to do includes and metagroups in a second pass so that # we can make sure the group is defined. for xmlgrp in compsxml.groups.values(): group = self.groups[xmlgrp.id] for id in xmlgrp.groups.keys(): if not self.groups.has_key(id): log("%s references component %s which doesn't exist" %(xmlgrp.id, id)) continue group.addGroupRequires(id) for id in xmlgrp.metapkgs.keys(): if not self.groups.has_key(id): log("%s references component %s which doesn't exist" %(xmlgrp.id, id)) continue group.addMetaPkg(xmlgrp.metapkgs[id]) def selectGroup(self, group, asMeta = 0, missingOk = 0): if self.groups.has_key(group): self.groups[group].select(asMeta = asMeta) return for grp in self.compsxml.groups.values(): if (grp.name == group) and self.groups.has_key(grp.id): self.groups[grp.id].select(asMeta = asMeta) return if missingOk: return raise KeyError, "No such group %s" %(group,) def unselectAll(self): # force everything to be in an off state for group in self.groups.values(): group.usecount = 0 group.manual_state = MANUAL_NONE for pkg in self.hdrlist.pkgs.values(): pkg.usecount = 0 pkg.manual_state = MANUAL_NONE def getSelectionState(self): grpst = [] for group in self.groups.values(): grpst.append((group, group.getState())) pkgst = [] for pkg in self.hdrlist.values(): pkgst.append((pkg, pkg.getState())) return (grpst, pkgst) def setSelectionState(self, state): (grpst, pkgst) = state for (grp, state) in grpst: grp.setState(state) for (pkg,state) in pkgst: pkg.setState(state) def size(self): size = 0 for pkg in self.hdrlist.values(): if pkg.isSelected(): size = size + (pkg[rpm.RPMTAG_SIZE] / 1024) return size / 1024 def sizeStr(self): megs = self.size() if (megs >= 1000): big = megs / 1000 little = megs % 1000 return "%d,%03dM" % (big, little) return "%dM" % (megs) def kernelVersionList(self): kernelVersions = [] # nick is used to generate the lilo name for (ktag, nick) in [ ('kernel-summit', 'summit'), ('kernel-bigmem', 'bigmem'), ('kernel-hugemem', 'hugemem'), ('kernel-smp', 'smp'), ('kernel-tape', 'tape'), ('kernel-pseries', ''), ('kernel-iseries', '') ]: tag = ktag.split('-')[1] if (self.hdrlist.has_key(ktag) and self.hdrlist[ktag].isSelected()): version = (self.hdrlist[ktag][rpm.RPMTAG_VERSION] + "-" + self.hdrlist[ktag][rpm.RPMTAG_RELEASE] + tag) kernelVersions.append((version, nick)) if (self.hdrlist.has_key('kernel') and self.hdrlist['kernel'].isSelected()): version = (self.hdrlist['kernel'][rpm.RPMTAG_VERSION] + "-" + self.hdrlist['kernel'][rpm.RPMTAG_RELEASE]) kernelVersions.append((version, 'up')) return kernelVersions def groupSetFromCompsFile(filename, hdrlist, doSelect = 1): import urllib2 tries = 0 while tries < 5: try: file = urllib2.urlopen(filename) except urllib2.HTTPError, e: log("HTTPError: %s occurred getting %s", filename, e) except urllib2.URLError, e: log("URLError: %s occurred getting %s", filename, e) except IOError, (errnum, msg): log("IOError %s occurred getting %s: %s", filename, errnum, str(msg)) except IOError, (errnum, msg): log("OSError %s occurred getting %s: %s", filename, errnum, str(msg)) else: break time.sleep(5) tries = tries + 1 compsxml = rhpl.comps.Comps(file) file.close() grpset = GroupSet(compsxml, hdrlist) # precache provides of base and core. saves us about 10% time-wise for groupname in [ "base", "core" ]: if not grpset.groups.has_key(groupname): continue for pnevra in grpset.groups[groupname].packages.keys(): for prov in grpset.hdrlist[pnevra][rpm.RPMTAG_PROVIDENAME]: cached[prov] = pnevra if doSelect: for group in grpset.groups.values(): if group.default: group.select() return grpset def getGroupDescription(group): if group.id == "everything": return _("This group includes all the packages available. Note that " "there are substantially more packages than just the ones " "in all the other package groups on this page.") elif group.id == "base": return _("Choose this group to get the minimal possible set of " "packages. Useful for creating small router/firewall " "boxes, for example.") return group.description # this is a temporary way to set order of packages def orderPackageGroups(grpset): compsParents = grpset.compsxml.hierarchy.order compsHierarchy = grpset.compsxml.hierarchy grpids = [] for grp in grpset.groups.values(): grpids.append(grp.id) ignorelst = [] retlist = [] retdict = {} if os.environ.has_key("LANG"): langs = language.expandLangs(os.environ["LANG"]) else: langs = [] for key in compsParents: # get the translated name myname = None if not compsHierarchy.translations.has_key(key): myname = key else: for lang in langs: if compsHierarchy.translations[key].has_key(lang): myname = compsHierarchy.translations[key][lang] break if myname is None: myname = key retlist.append(myname) retdict[myname] = [] compslist = compsHierarchy[key] for grp in compslist: if grp in grpids: thecomp = grpset.groups[grp] ignorelst.append(grp) retdict[myname].append(thecomp) miscgrp = _("Miscellaneous") for grp in grpids: if grp in ignorelst: continue thecomp = grpset.groups[grp] if miscgrp not in retlist: retlist.append(miscgrp) retdict[miscgrp] = [thecomp] else: retdict[miscgrp].append(thecomp) return (retlist, retdict) if __name__ == "__main__": tree = "/mnt/redhat/test/katzj2/i386/i386/" def simpleInstallCallback(what, amount, total, h, (param)): global rpmfd if (what == rpm.RPMCALLBACK_TRANS_START): # step 6 is the bulk of the transaction set # processing time if amount == 6: print "Preparing to install..." if (what == rpm.RPMCALLBACK_TRANS_PROGRESS): pass if (what == rpm.RPMCALLBACK_TRANS_STOP): pass if (what == rpm.RPMCALLBACK_INST_OPEN_FILE): print "Installing %s" %(nevra(h),) rpmfd = os.open("%s/RedHat/RPMS/%s-%s-%s.%s.rpm" %(tree, h['name'], h['version'], h['release'], h['arch']), os.O_RDONLY) return rpmfd elif (what == rpm.RPMCALLBACK_INST_PROGRESS): pass elif (what == rpm.RPMCALLBACK_INST_CLOSE_FILE): os.close (rpmfd) elif ((what == rpm.RPMCALLBACK_UNPACK_ERROR) or (what == rpm.RPMCALLBACK_CPIO_ERROR)): print "ERROR!" sys.exit(0) else: pass def packageSort(first, second): one = first[1000002] two = second[1000002] if one < two: return -1 elif one > two: return 1 return 0 fd = os.open(tree + "/RedHat/base/hdlist", os.O_RDONLY) hdrs = rpm.readHeaderListFromFD(fd) os.close(fd) showMem() # fd = os.open(tree + "/RedHat/base/hdlist2", os.O_RDONLY) # rpm.mergeHeaderListFromFD(hdrs, fd, 1000004) # os.close(fd) showMem() f = open(tree + "/RedHat/base/comps.xml", "r") comps = rhpl.comps.Comps(f) f.close() showMem() hdrlist = HeaderList(hdrs) hdrlist.mergeFullHeaders(tree + "/RedHat/base/hdlist2") showMem() groups = GroupSet(comps, hdrlist) showMem() ts = rpm.TransactionSet("/tmp/testinstall") ts.setVSFlags(-1) ts.setFlags(rpm.RPMTRANS_FLAG_ANACONDA) showMem() l = [] groups.groups["base"].select() groups.hdrlist["evolution"].select() for hdr in groups.hdrlist.pkgs.values(): if hdr.isSelected(): l.append(hdr) print "going to install %s" %(nevra(hdr),) depcheck = DependencyChecker(groups) l.sort(packageSort) for h in l: ts.addInstall(h.hdr, h.hdr, "i") foo = ts.check(depcheck.callback) print depcheck.added sys.exit(0) ts.run(simpleInstallCallback, 0) #!/usr/bin/python2.2 # # anaconda: The Red Hat Linux Installation program # # (in alphabetical order...) # # Brent Fox # Mike Fulbright # Jakub Jelinek # Jeremy Katz # Erik Troan # Matt Wilson # # ... And many others # # Copyright 1999-2003 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # This toplevel file is a little messy at the moment... import sys, os # keep up with process ID of miniwm if we start it miniwm_pid = None # helper function to duplicate diagnostic output def dup_log(format, *args): if args: sys.stdout.write ("%s\n" % (format % args)) else: sys.stdout.write ("%s\n" % format) apply(log, (format,) + args) # start miniWM def startMiniWM(root='/'): childpid = os.fork() if not childpid: if os.access("./mini-wm", os.X_OK): cmd = "./mini-wm" elif os.access(root + "/usr/bin/mini-wm", os.X_OK): cmd = root + "/usr/bin/mini-wm" else: return None args = [cmd, '--display', ':1'] os.execv(args[0], args) sys.exit (1) return childpid # startup vnc X server def startVNCServer(vncpassword=None, root='/', vncconnecthost=None, vncconnectport=None): def set_vnc_password(root, passwd, passwd_file): (pid, fd) = os.forkpty() if not pid: os.execv(root + "/usr/bin/vncpasswd", [root + "/usr/bin/vncpasswd", passwd_file]) sys.exit(1) # read password prompt os.read(fd, 1000) # write password os.write(fd, passwd + "\n") # read challenge again, and newline os.read(fd, 1000) os.read(fd, 1000) # write password again os.write(fd, passwd + "\n") # read remaining output os.read(fd, 1000) # wait for status try: (pid, status) = os.waitpid(pid, 0) except OSError, (errno, msg): print __name__, "waitpid:", msg return status dup_log(_("Starting VNC...")) # figure out host info connxinfo = None srvname = None try: import network # try to load /tmp/netinfo and see if we can sniff out network info netinfo = network.Network() srvname = None if netinfo.hostname != "localhost.localdomain": srvname = "%s" % (netinfo.hostname,) else: for dev in netinfo.netdevices.keys(): try: ip = isys.getIPAddress(dev) log("ip of %s is %s" %(dev, ip)) except Exception, e: log("Got an exception trying to get the ip addr of %s: " "%s" %(dev, e)) continue if ip == '127.0.0.1' or ip is None: continue srvname = ip break if srvname is not None: connxinfo = "%s:1" % (srvname,) except: log("Unable to determine VNC server network info") # figure out product info if srvname is not None: desktopname = _("%s %s installation on host %s") % (product.productName, product.productVersion, srvname) else: desktopname = _("%s %s installation") % (product.productName, product.productVersion) vncpid = os.fork() if not vncpid: args = [ root + "/usr/bin/Xvnc", ":1", "-nevershared", "-depth", "16", "-geometry", "800x600", "IdleTimeout=0", "-auth", "/dev/null" "DisconnectClients=false", "desktop=%s" % (desktopname,)] # set passwd if necessary if vncpassword is not None: try: rc = set_vnc_password(root, vncpassword, "/tmp/vncpasswd_file") except Exception, e: dup_log("Unknown exception setting vnc password.") log("Exception was: %s" %(e,)) rc = 1 if rc: dup_log(_("Unable to set vnc password - using no password!")) dup_log(_("Make sure your password is at least 6 characters in length.")) else: args = args + ["-rfbauth", "/tmp/vncpasswd_file"] else: # needed if no password specified args = args + ["SecurityTypes=None",] tmplogFile = "/tmp/vncserver.log" try: err = os.open(tmplogFile, os.O_RDWR | os.O_CREAT) if err < 0: sys.stderr.write("error opening %s\n", tmplogFile) else: os.dup2(err, 2) os.close(err) except: # oh well pass os.execv(args[0], args) sys.exit (1) if vncpassword is None: dup_log(_("\n\nWARNING!!! VNC server running with NO PASSWORD!\n" "You can use the vncpassword= boot option\n" "if you would like to secure the server.\n\n")) dup_log(_("The VNC server now running.")) if vncconnecthost is not None: dup_log("Attempting to connect to vnc client on host %s..." % (vncconnecthost,)) hostarg = vncconnecthost if vncconnectport is not None: hostarg = hostarg + ":" + vncconnectport argv = ["/usr/bin/vncconfig", "-display", ":1", "-connect", hostarg] ntries = 0 while 1: output=iutil.execWithCapture(argv[0], argv, catchfd=2) outfields = string.split(string.strip(output), ' ') if outfields[0] == "connecting" and outfields[-1] == "failed": ntries += 1 if ntries > 50: dup_log("Giving up attempting to connect after 50 tries!\n") if connxinfo is not None: dup_log("Please manually connect your vnc client to %s to begin the install." % (connxinfo,)) else: dup_log("Please manually connect your vnc client to begin the install.") break dup_log(output) dup_log("Will try to connect again in 15 seconds...") time.sleep(15) continue else: dup_log("Connected!") break else: if connxinfo is not None: dup_log("Please connect to %s to begin the install..." % (connxinfo,)) else: dup_log("Please connect to begin the install...") os.environ["DISPLAY"]=":1" doStartupX11Actions() # function to handle X startup special issues for anaconda def doStartupX11Actions(): global miniwm_pid # now start up mini-wm try: miniwm_pid = startMiniWM() log("Started mini-wm") except: miniwm_pid = None log("Unable to start mini-wm") # test to setup dpi # cant do this if miniwm didnt run because otherwise when # we open and close an X connection in the xutils calls # the X server will exit since this is the first X # connection (if miniwm isnt running) if miniwm_pid is not None: import xutils try: if xutils.screenWidth() > 640: dpi = "96" else: dpi = "75" xutils.setRootResource('Xcursor.size', '24') xutils.setRootResource('Xcursor.theme', 'Bluecurve') xutils.setRootResource('Xcursor.theme_core', 'true') xutils.setRootResource('Xft.antialias', '1') xutils.setRootResource('Xft.dpi', dpi) xutils.setRootResource('Xft.hinting', '1') xutils.setRootResource('Xft.hintstyle', 'hintslight') xutils.setRootResource('Xft.rgba', 'none') except: sys.stderr.write("X SERVER STARTED, THEN FAILED"); raise RuntimeError, "X server failed to start" def doShutdownX11Actions(): global miniwm_pid if miniwm_pid is not None: try: os.kill(miniwm_pid, 15) os.waitpid(miniwm_pid, 0) except: pass def setupRhplUpdates(): try: os.mkdir("/tmp/updates") except: pass try: os.mkdir("/tmp/updates/rhpl") except: pass if os.access("/mnt/source/RHupdates/rhpl", os.X_OK): for f in os.listdir("/mnt/source/RHupdates/rhpl"): os.symlink("/mnt/source/RHupdates/rhpl/%s" %(f,), "/tmp/updates/rhpl/%s" %(f,)) if os.access("/usr/lib64/python2.2/site-packages/rhpl", os.X_OK): libdir = "lib64" else: libdir = "lib" for f in os.listdir("/usr/%s/python2.2/site-packages/rhpl" %(libdir,)): if os.access("/tmp/updates/rhpl/%s" %(f,), os.R_OK): continue elif f.endswith(".pyc") and os.access("/tmp/updates/rhpl/%s" %(f[:-1],), os.R_OK): # dont copy .pyc files we are replacing with updates continue os.symlink("/usr/%s/python2.2/site-packages/rhpl/%s" %(libdir, f), "/tmp/updates/rhpl/%s" %(f,)) # For anaconda in test mode if (os.path.exists('isys')): sys.path.append('isys') sys.path.append('textw') sys.path.append('iw') else: #CJS check for textw and iw patches for both the nfs and cdrom patch area if (os.path.exists('/mnt/source/RHupdates/textw')): sys.path.append('/mnt/source/RHupdates/textw') if (os.path.exists('/mnt/source/RHupdates/iw')): sys.path.append('/mnt/source/RHupdates/iw') if (os.path.exists('/tmp/updates/textw')): sys.path.append('/tmp/updates/textw') if (os.path.exists('/tmp/updates/iw')): sys.path.append('/tmp/updates/iw') #CJS end sys.path.append('/usr/lib/anaconda') sys.path.append('/usr/lib/anaconda/textw') sys.path.append('/usr/lib/anaconda/iw') if (os.path.exists('booty')): sys.path.append('booty') sys.path.append('booty/edd') else: sys.path.append('/usr/lib/booty') sys.path.append('/usr/share/redhat-config-keyboard') try: import updates_disk_hook except ImportError: pass # pull this in to get product name and versioning import product # do this early to keep our import footprint as small as possible # Python passed my path as argv[0]! # if sys.argv[0][-7:] == "syslogd": if len(sys.argv) > 1: if sys.argv[1] == "--syslogd": from syslogd import Syslogd root = sys.argv[2] output = sys.argv[3] syslog = Syslogd (root, open (output, "a")) # this never returns #CJS need to parse cmdline to determine where to install from cmdline = open("/proc/cmdline", "r").read() loc = cmdline.find("site=") if loc > 0 : stuff = cmdline[loc + 5:] loc2 = stuff.find(" ") loc3 = stuff[:loc2].find("/") if (loc3 > 0): product.productSite = stuff[:loc2] else: product.productSite = product.productSiteDir + "/" + stuff[:loc2] # #CJS now look for RHupdates so that each group can have their own anaconda stuff if (os.path.exists("/mnt/source/" + product.productSite + "/RHupdates")): sys.path.append("/mnt/source" + product.productSite + "/RHupdates") if (os.path.exists("/mnt/source/" + product.productSite + "/RHupdates/iw")): sys.path.append("/mnt/source/" + product.productSite + "/RHupdates/iw") if (os.path.exists("/mnt/source/" + product.productSite + "/RHupdates/textw")): sys.path.append("/mnt/source/" + product.productSite + "/RHupdates/textw") #CJS end of parse cmdline and fix up stuff depending on it # this handles setting up RHupdates for rhpl to minimize the set needed if (os.access("/mnt/source/RHupdates/rhpl", os.X_OK) or os.access("/tmp/updates/rhpl", os.X_OK)): setupRhplUpdates() import signal, traceback, string, isys, iutil, time from exception import handleException import dispatch from flags import flags from anaconda_log import anaconda_log from rhpl.log import log from rhpl.translate import _, textdomain, addPoPath if os.path.isdir("/mnt/source/RHupdates/po"): log("adding RHupdates/po") addPoPath("/mnt/source/RHupdates/po") if os.path.isdir("/tmp/updates/po"): log("adding /tmp/updates/po") addPoPath("/tmp/updates/po") textdomain("anaconda") # reset python's default SIGINT handler signal.signal(signal.SIGINT, signal.SIG_DFL) # Silly GNOME stuff if os.environ.has_key('HOME'): os.environ['XAUTHORITY'] = os.environ['HOME'] + '/.Xauthority' os.environ['HOME'] = '/tmp' os.environ['LC_NUMERIC'] = 'C' if os.environ.has_key ("ANACONDAARGS"): theargs = string.split (os.environ["ANACONDAARGS"]) else: theargs = sys.argv[1:] # we can't let the LD_PRELOAD hang around because it will leak into # rpm %post and the like. ick :/ if os.environ.has_key("LD_PRELOAD"): del os.environ["LD_PRELOAD"] # we need to do this really early so we make sure its done before rpm # is imported iutil.writeRpmPlatform() try: (args, extra) = isys.getopt(theargs, 'CGTRxtdr:fm:', [ 'text', 'test', 'debug', 'nofallback', 'method=', 'rootpath=', 'pcic=', "overhead=", 'testpath=', 'mountfs', 'traceonly', 'kickstart=', 'lang=', 'keymap=', 'kbdtype=', 'module=', 'class=', 'expert', 'serial', 'lowres', 'nofb', 'rescue', 'nomount', 'autostep', 'resolution=', 'skipddc', 'vnc', 'vncconnect=', 'vnc=', 'cmdline', 'headless']) except TypeError, msg: sys.stderr.write("Error %s\n:" % msg) sys.exit(-1) if extra: sys.stderr.write("Unexpected arguments: %s\n" % extra) sys.exit(-1) # Save the arguments in case we need to reexec anaconda for kon os.environ["ANACONDAARGS"] = string.join(sys.argv[1:]) # remove the arguments - gnome_init doesn't understand them savedargs = sys.argv[1:] sys.argv = sys.argv[:1] sys.argc = 1 # Parameters for the main anaconda routine # rootPath = '/mnt/sysimage' # where to instal packages extraModules = [] # kernel modules to use display_mode = 'g' # try GUI by default debug = 0 # start up pdb immediately traceOnly = 0 # don't run, just list modules we use nofallback = 0 # if GUI mode fails, exit rescue = 0 # run in rescue mode rescue_nomount = 0 # don't automatically mount device in rescue runres = '800x600' # resolution to run the GUI install in skipddc = 0 # if true skip ddcprobe (locks some machines) instClass = None # the install class to use progmode = 'install' # 'rescue', or 'install' method = None # URL representation of install method logFile = None # may be a file object or a file name # should we ever try to probe for X stuff? this will give us a convenient # out eventually to circumvent all probing and just fall back to text mode # on hardware where we break things if we probe isHeadless = 0 # probing for hardware on an s390 seems silly... if iutil.getArch() == "s390": isHeadless = 1 # # xcfg - xserver info (?) # mousehw - mouseinfo info # videohw - videocard info # monitorhw - monitor info # lang - language to use for install/machine default # keymap - kbd map # xcfg = None monitorhw = None videohw = None mousehw = None lang = None method = None keymap = None kbdtype = None progmode = None customClass = None kbd = None ksfile = None vncpassword = None vncconnecthost = None vncconnectport = None # # parse off command line arguments # for n in args: (str, arg) = n if (str == '--class'): customClass = arg elif (str == '-d' or str == '--debug'): debug = 1 elif (str == '--expert'): flags.expert = 1 elif (str == '--keymap'): keymap = arg elif (str == '--kickstart'): from kickstart import Kickstart ksfile = arg instClass = Kickstart(ksfile, flags.serial) elif (str == '--lang'): lang = arg elif (str == '--lowres'): runres = '640x480' elif (str == '-m' or str == '--method'): method = arg if method[0] == '@': # ftp installs pass the password via a file in /tmp so # ps doesn't show it filename = method[1:] method = open(filename, "r").readline() method = method[:len(method) - 1] os.unlink(filename) elif (str == '--module'): (path, name) = string.split(arg, ":") extraModules.append((path, name)) elif (str == '--nofallback'): nofallback = 1 elif (str == "--nomount"): rescue_nomount = 1 elif (str == '--rescue'): progmode = 'rescue' elif (str == '--resolution'): # run native X server at specified resolution, ignore fb runres = arg elif (str == "--skipddc"): skipddc = 1 elif (str == "--autostep"): flags.autostep = 1 elif (str == '-r' or str == '--rootpath'): rootPath = arg flags.setupFilesystems = 0 logFile = sys.stderr elif (str == '--traceonly'): traceOnly = 1 elif (str == '--serial'): flags.serial = 1 elif (str == '-t' or str == '--test'): flags.test = 1 flags.setupFilesystems = 0 logFile = "/tmp/anaconda-debug.log" elif (str == '-T' or str == '--text'): display_mode = 't' elif (str == "-C" or str == "--cmdline"): display_mode = 'c' elif (str == '--kbdtype'): kbdtype = arg elif (str == '--headless'): isHeadless = 1 elif (str == '--vnc'): flags.usevnc = 1 # see if there is a vnc password file try: pfile = open("/tmp/vncpassword.dat", "r") vncpassword=pfile.readline().strip() pfile.close() os.unlink("/tmp/vncpassword.dat") except: vncpassword=None pass # check length of vnc password if vncpassword is not None and len(vncpassword) < 6: from snack import * screen = SnackScreen() ButtonChoiceWindow(screen, _('VNC Password Error'), _('You need to specify a vnc password of at least 6 characters long.\n\n' 'Press to reboot your system.\n'), buttons = (_("OK"),)) screen.finish() sys.exit(0) elif (str == '--vncconnect'): cargs = string.split(arg, ":") vncconnecthost = cargs[0] if len(cargs) > 1: if len(cargs[1]) > 0: vncconnectport = cargs[1] log("product.productSite is %s " % product.productSite) log("product.productDefault is %s " % product.productDefault) # # must specify install, rescue mode # if (progmode == 'rescue'): if (not method): sys.stderr.write('--method required for rescue mode\n') sys.exit(1) import rescue, instdata, configFileData anaconda_log.open (logFile) log.handler=anaconda_log configFile = configFileData.configFileData() configFileData = configFile.getConfigData() id = instdata.InstallData([], "fd0", configFileData, method) rescue.runRescue(rootPath, not rescue_nomount, id) # shouldn't get back here sys.exit(1) else: if (not method): sys.stderr.write('no install method specified\n') sys.exit(1) anaconda_log.open (logFile) log.handler = anaconda_log # # Here we have a hook to pull in second half of kickstart file via https # if desired. # if ksfile is not None: from kickstart import pullRemainingKickstartConfig, KSAppendException from kickstart import parseKickstartVNC try: rc=pullRemainingKickstartConfig(ksfile) except KSAppendException, msg: rc = msg except: rc = _("Unknown Error") if rc is not None: dup_log(_("Error pulling second part of kickstart config: %s!") % (rc,)) sys.exit(1) # now see if they enabled vnc via the kickstart file. Note that command # line options for password, connect host and port override values in # kickstart file (ksusevnc, ksvncpasswd, ksvnchost, ksvncport) = parseKickstartVNC(ksfile) if ksusevnc: flags.usevnc = 1 if vncpassword == None: vncpassword = ksvncpasswd if vncconnecthost == None: vncconnecthost = ksvnchost if vncconnectport == None: vncconnectport = ksvncport if (debug): import pdb pdb.set_trace() # let people be stupid ## # don't let folks do anything stupid on !s390 ## if (not flags.test and os.getpid() > 90 and flags.setupFilesystems and ## not iutil.getArch() == "s390"): ## sys.stderr.write( ## "You're running me on a live system! that's incredibly stupid.\n") ## sys.exit(1) import isys import instdata import floppy if not isHeadless: import xsetup import rhpl.xhwstate as xhwstate import rhpl.keyboard as keyboard # handle traceonly and exit if traceOnly: if display_mode == 'g': sys.stderr.write("traceonly is only supported for text mode\n") sys.exit(0) # prints a list of all the modules imported from text import InstallInterface from text import stepToClasses import pdb import warnings import image import harddrive import urlinstall import mimetools import mimetypes import syslogd import installclass import re import rescue import configFileData import kickstart import whiteout import findpackageset import libxml2 import cmdline installclass.availableClasses() if display_mode == 't': for step in stepToClasses.keys(): if stepToClasses[step]: (mod, klass) = stepToClasses[step] exec "import %s" % mod for module in sys.__dict__['modules'].keys (): if module not in [ "__builtin__", "__main__" ]: foo = repr (sys.__dict__['modules'][module]) bar = string.split (foo, "'") if len (bar) > 3: print bar[3] sys.exit(0) # # override display mode if machine cannot nicely run X # if (not flags.test): if (iutil.memInstalled() < isys.MIN_GUI_RAM): dup_log(_("You do not have enough RAM to use the graphical " "installer. Starting text mode.")) display_mode = 't' time.sleep(2) if iutil.memInstalled() < isys.MIN_RAM: from snack import * screen = SnackScreen() ButtonChoiceWindow(screen, _('Fatal Error'), _('You do not have enough RAM to install Red Hat ' 'Linux on this machine.\n' '\n' 'Press to reboot your system.\n'), buttons = (_("OK"),)) screen.finish() sys.exit(0) # # handle class passed from loader # if customClass: import installclass classes = installclass.availableClasses(showHidden=1) for (className, objectClass, logo) in classes: if className == customClass: instClass = objectClass(flags.expert) if not instClass: sys.stderr.write("installation class %s not available\n" % customClass) sys.stderr.write("\navailable classes:\n") for (className, objectClass, logo) in classes: sys.stderr.write("\t%s\n" % className) sys.exit(1) # # if no instClass declared by user figure it out based on other cmdline args # if not instClass: from installclass import DefaultInstall, availableClasses instClass = DefaultInstall(flags.expert) if len(availableClasses(showHidden = 1)) < 2: (cname, cobject, clogo) = availableClasses(showHidden = 1)[0] log("%s is only installclass, using it" %(cname,)) instClass = cobject(flags.expert) # this lets install classes force text mode instlls if instClass.forceTextMode: dup_log(_("Install class forcing text mode installation")) display_mode = 't' # # find out what video hardware is available to run installer # # XXX kind of hacky - need to remember if we're running on an existing # X display later to avoid some initilization steps if os.environ.has_key('DISPLAY') and display_mode == 'g': x_already_set = 1 else: x_already_set = 0 if not isHeadless: # # Probe what is available for X and setup a hardware state # # try to probe interesting hw import rhpl.xserver as xserver skipddcprobe = (skipddc or (x_already_set and flags.test)) skipmouseprobe = not (not os.environ.has_key('DISPLAY') or flags.setupFilesystems) (videohw, monitorhw, mousehw) = xserver.probeHW(skipDDCProbe=skipddcprobe, skipMouseProbe = skipmouseprobe) # if the len(videocards) is zero, then let's assume we're isHeadless if len(videohw.videocards) == 0: print _("No video hardware found, assuming headless") videohw = None monitorhw = None mousehw = None isHeadless = 1 else: # setup a X hw state for use later with configuration. try: xcfg = xhwstate.XF86HardwareState(defcard=videohw, defmon=monitorhw) except Exception, e: print _("Unable to instantiate a X hardware state object.") xcfg = None else: videohw = None monitorhw = None mousehw = None xcfg = None # keyboard kbd = keyboard.Keyboard() if keymap: kbd.set(keymap) # # delay to let use see status of attempt to probe hw # time.sleep(3) # # now determine if we're going to run in GUI or TUI mode # if (display_mode == 'g' and method and (method.startswith('ftp://') or method.startswith('http://') or method.startswith('hd://') or method.startswith('oldhd://'))): dup_log(_("Graphical installation not available for %s installs. " "Starting text mode.") % (string.split(method, ':')[0],)) display_mode = 't' time.sleep(2) if not isHeadless: # if no mouse we force text mode mousedev = mousehw.get() if ksfile is None and not flags.usevnc and display_mode == 'g' and mousedev[0] == "No - mouse": # ask for the mouse type import rhpl.mouse as mouse if mouse.mouseWindow(mousehw) == 0: dup_log(_("No mouse was detected. A mouse is required for " "graphical installation. Starting text mode.")) display_mode = 't' time.sleep(2) else: dup_log(_("Using mouse type: %s"), mousehw.shortDescription()) else: # s390/iSeries checks if display_mode == 'g' and not (os.environ.has_key('DISPLAY') or flags.usevnc): dup_log("DISPLAY variable not set. Starting text mode!") display_mode = 't' time.sleep(2) # if they want us to use VNC do that now if display_mode == 'g' and flags.usevnc: # dont run vncpassword if in test mode if flags.test: vncpassword = None startVNCServer(vncpassword=vncpassword, vncconnecthost=vncconnecthost, vncconnectport=vncconnectport) if display_mode == 'g' and not os.environ.has_key('DISPLAY'): import rhpl.monitor as monitor # if no monitor probed lets guess based on runres hsync = monitorhw.getMonitorHorizSync() vsync = monitorhw.getMonitorVertSync() res_supported = monitor.monitor_supports_mode(hsync, vsync, runres) if not res_supported: import rhpl.guesslcd as guesslcd (hsync, vsync) = guesslcd.getSyncForRes(runres) monitorhw.setSpecs(hsync, vsync) # XXX - need to fix # # messy hack for how rhpl.xhwstate works # current it wants to use probed values which we dont have so we'll # fake them hsync = monitorhw.getMonitorHorizSync() vsync = monitorhw.getMonitorVertSync() monitorhw.orig_monHoriz = hsync monitorhw.orig_monVert = vsync # make sure we can write log to ramfs if os.access("/tmp/ramfs", os.W_OK): xlogfile = "/tmp/ramfs/X.log" else: xlogfile = None xsetup_failed = xserver.startXServer(videohw, monitorhw, mousehw, kbd, runres, xStartedCB=doStartupX11Actions, xQuitCB=doShutdownX11Actions, logfile=xlogfile) if xsetup_failed: dup_log(" X startup failed, falling back to text mode") display_mode = 't' time.sleep(2) # # read in anaconda configuration file # import configFileData configFile = configFileData.configFileData() configFileData = configFile.getConfigData() # setup links required for all install types for i in ( "services", "protocol", "nsswitch.conf", "joe"): try: os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i) except: pass # # setup links required by graphical mode if installing and verify display mode # if (display_mode == 'g'): if not flags.test and flags.setupFilesystems: for i in ( "imrc", "im_palette.pal", "gtk-2.0", "pango", "fonts", "fb.modes"): try: if os.path.exists("/mnt/runtime/etc/%s" %(i,)): os.symlink ("../mnt/runtime/etc/" + i, "/etc/" + i) except: pass # display splash screen if nofallback: from splashscreen import splashScreenShow splashScreenShow(configFileData) from gui import InstallInterface else: try: from splashscreen import splashScreenShow splashScreenShow(configFileData) from gui import InstallInterface except Exception, e: # if we're not going to really go into GUI mode, we need to get # back to vc1 where the text install is going to pop up. if not x_already_set: isys.vtActivate (1) dup_log("GUI installer startup failed, falling back to text mode.") display_mode = 't' if 'DISPLAY' in os.environ.keys(): del os.environ['DISPLAY'] time.sleep(2) if (display_mode == 't'): from text import InstallInterface if (display_mode == 'c'): from cmdline import InstallInterface # go ahead and set up the interface intf = InstallInterface () # imports after setting up the path if method: if method.startswith('cdrom://'): from image import CdromInstallMethod methodobj = CdromInstallMethod(method[8:], intf.messageWindow, intf.progressWindow, rootPath) elif method.startswith('nfs:/'): from image import NfsInstallMethod methodobj = NfsInstallMethod(method[5:], rootPath) elif method.startswith('nfsiso:/'): from image import NfsIsoInstallMethod methodobj = NfsIsoInstallMethod(method[8:], intf.messageWindow, rootPath) elif method.startswith('ftp://') or method.startswith('http://'): from urlinstall import UrlInstallMethod methodobj = UrlInstallMethod(method, rootPath) elif method.startswith('hd://'): tmpmethod = method[5:] i = string.index(tmpmethod, ":") drive = tmpmethod[0:i] tmpmethod = tmpmethod[i+1:] i = string.index(tmpmethod, "/") type = tmpmethod[0:i] dir = tmpmethod[i+1:] from harddrive import HardDriveInstallMethod methodobj = HardDriveInstallMethod(drive, type, dir, intf.messageWindow, rootPath) elif method.startswith('oldhd://'): tmpmethod = method[8:] i = string.index(tmpmethod, ":") drive = tmpmethod[0:i] tmpmethod = tmpmethod[i+1:] i = string.index(tmpmethod, "/") type = tmpmethod[0:i] dir = tmpmethod[i+1:] from harddrive import OldHardDriveInstallMethod methodobj = OldHardDriveInstallMethod(drive, type, dir, rootPath) else: print "unknown install method:", method sys.exit(1) floppyDevice = floppy.probeFloppyDevice() # create device nodes for detected devices if we're not running in test mode if not flags.test and flags.setupFilesystems: iutil.makeDriveDeviceNodes() id = instClass.installDataClass(extraModules, floppyDevice, configFileData, method) id.x_already_set = x_already_set if mousehw: id.setMouse(mousehw) if videohw: id.setVideoCard(videohw) if monitorhw: id.setMonitor(monitorhw) # # not sure what to do here - somehow we didnt detect anything # if xcfg is None and not isHeadless: try: xcfg = xhwstate.XF86HardwareState() except Exception, e: print _("Unable to instantiate a X hardware state object.") xcfg = None if xcfg is not None: # # XXX - hack - here we want to enforce frame buffer requirement on ppc # pick 640x480x8bpp cause that is what frame buffer inits to # when the machine reboots if iutil.getArch() == "ppc": cardname = "Framebuffer driver (generic)" xcfg.set_videocard_card(cardname) xcfg.set_videocard_name(cardname) xcfg.set_colordepth(8) xcfg.set_resolution("640x480") xsetup = xsetup.XSetup(xcfg) id.setXSetup(xsetup) if kbd: id.setKeyboard(kbd) instClass.setInstallData(id) dispatch = dispatch.Dispatcher(intf, id, methodobj, rootPath) if lang: dispatch.skipStep("language", permanent = 1) instClass.setLanguage(id, lang) if keymap: dispatch.skipStep("keyboard", permanent = 1) instClass.setKeyboard(id, keymap) # set up the headless case if isHeadless == 1: id.setHeadless(isHeadless) instClass.setAsHeadless(dispatch, isHeadless) instClass.setSteps(dispatch) # We shouldn't need this again # XXX #del id # # XXX This is surely broken # #if iutil.getArch() == "sparc": # import kudzu # mice = kudzu.probe (kudzu.CLASS_MOUSE, kudzu.BUS_UNSPEC, kudzu.PROBE_ONE); # if mice: # (mouseDev, driver, descr) = mice[0] # if mouseDev == 'sunmouse': # instClass.addToSkipList("mouse") # instClass.setMouseType("Sun - Mouse", "sunmouse") # comment out the next line to make exceptions non-fatal sys.excepthook = lambda type, value, tb, dispatch=dispatch, intf=intf: handleException(dispatch, intf, (type, value, tb)) try: intf.run(id, dispatch, configFileData) except SystemExit, code: intf.shutdown() except: handleException(dispatch, intf, sys.exc_info()) del intf # # gui.py - Graphical front end for anaconda # # Matt Wilson # Michael Fulbright # # Copyright 1999-2003 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import os import iutil import string import isys import sys import parted import gtk import htmlbuffer import rpm import kudzu from language import expandLangs from splashscreen import splashScreenPop from flags import flags from constants import * from rhpl.log import log from rhpl.translate import _, N_ from product import * rpm.addMacro("_i18ndomains", "redhat-dist") isys.bind_textdomain_codeset("redhat-dist", "UTF-8") StayOnScreen = "stayOnScreen" mainWindow = None stepToClass = { "language" : ("language_gui", "LanguageWindow"), "keyboard" : ("keyboard_gui", "KeyboardWindow"), "mouse" : ("mouse_gui", "MouseWindow"), "welcome" : ("welcome_gui", "WelcomeWindow"), "installtype" : ("installpath_gui", "InstallPathWindow"), "partitionmethod" : ("partmethod_gui", "PartitionMethodWindow"), "partition" : ("partition_gui", "PartitionWindow"), "autopartition" : ("partition_gui", "AutoPartitionWindow"), "findinstall" : ("examine_gui", "UpgradeExamineWindow"), "addswap" : ("upgrade_swap_gui", "UpgradeSwapWindow"), "upgrademigratefs" : ("upgrade_migratefs_gui", "UpgradeMigrateFSWindow"), "fdisk" : ("fdisk_gui", "FDiskWindow"), "bootloader": ("bootloader_main_gui", "MainBootloaderWindow"), "bootloaderadvanced": ("bootloader_advanced_gui", "AdvancedBootloaderWindow"), "upgbootloader": ("upgrade_bootloader_gui", "UpgradeBootloaderWindow"), "network" : ("network_gui", "NetworkWindow"), "firewall" : ("firewall_gui", "FirewallWindow"), "languagesupport" : ("language_support_gui", "LanguageSupportWindow"), "timezone" : ("timezone_gui", "TimezoneWindow"), "accounts" : ("account_gui", "AccountWindow"), "authentication" : ("auth_gui", "AuthWindow"), "desktopchoice": ("desktop_choice_gui", "DesktopChoiceWindow"), "package-selection" : ("package_gui", "PackageSelectionWindow"), "indivpackage" : ("package_gui", "IndividualPackageSelectionWindow"), "dependencies" : ("dependencies_gui", "UnresolvedDependenciesWindow"), "videocard" : ("xconfig_gui", "XConfigWindow"), "monitor" : ("xconfig_gui", "MonitorWindow"), "xcustom" : ("xconfig_gui", "XCustomWindow"), "confirminstall" : ("confirm_gui", "InstallConfirmWindow"), "confirmupgrade" : ("confirm_gui", "UpgradeConfirmWindow"), "finishxconfig" : None, "install" : ("progress_gui", "InstallProgressWindow"), "bootdisk" : ("bootdisk_gui", "BootdiskWindow"), "complete" : ("congrats_gui", "CongratulationWindow"), } if iutil.getArch() == 'sparc': stepToClass["bootloader"] = ("silo_gui", "SiloWindow") elif iutil.getArch() == 's390': stepToClass["bootloader"] = ("zipl_gui", "ZiplWindow") # # Stuff for screenshots # screenshotDir = None screenshotIndex = 0 def copyScreenshots(): global screenshotIndex global screenshotDir # see if any screenshots taken if screenshotIndex == 0: return destDir = "/mnt/sysimage/root/anaconda-screenshots" if not os.access(destDir, os.R_OK): try: os.mkdir(destDir, 0750) except: window = MessageWindow("Error Saving Screenshot", _("An error occurred copying the " "screenshots over."), type="warning") return # copy all png's over for f in os.listdir(screenshotDir): (path, fname) = os.path.split(f) (b, ext) = os.path.splitext(f) if ext == ".png": iutil.copyFile(screenshotDir + '/' + f, destDir + '/' + fname) window = MessageWindow(_("Screenshots Copied"), _("The screenshots have been saved into the " "directory:\n\n" "\t/root/anaconda-screenshots/\n\n" "You can access these when you reboot and " "login as root.")) def takeScreenShot(): global screenshotIndex global screenshotDir if screenshotDir is None: screenshotDir = "/tmp/ramfs/anaconda-screenshots" if not os.access(screenshotDir, os.R_OK): try: os.mkdir(screenshotDir) except: screenshotDir = None return try: screenshot = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, gtk.FALSE, 8, gtk.gdk.screen_width(), gtk.gdk.screen_height()) screenshot.get_from_drawable(gtk.gdk.get_default_root_window(), gtk.gdk.colormap_get_system(), 0, 0, 0, 0, gtk.gdk.screen_width(), gtk.gdk.screen_height()) if screenshot: while (1): sname = "screenshot-%04d.png" % ( screenshotIndex,) if not os.access(screenshotDir + '/' + sname, os.R_OK): break screenshotIndex = screenshotIndex + 1 if screenshotIndex > 9999: log("Too many screenshots!") return screenshot.save (screenshotDir + '/' + sname, "png") screenshotIndex = screenshotIndex + 1 window = MessageWindow(_("Saving Screenshot"), _("A screenshot named '%s' has been saved.") % (sname,) , type="ok") except: window = MessageWindow(_("Error Saving Screenshot"), _("An error occurred while saving " "the screenshot. If this occurred " "during package installation, you may need " "to try several times for it to succeed."), type="warning") def handleShiftPrintScrnRelease (window, event): if (event.keyval == gtk.keysyms.Print and event.state & gtk.gdk.SHIFT_MASK): takeScreenShot() # # HACK to make treeview work # def setupTreeViewFixupIdleHandler(view, store): id = {} id["id"] = gtk.idle_add(scrollToIdleHandler, (view, store, id)) def scrollToIdleHandler((view, store, iddict)): if not view or not store or not iddict: return try: id = iddict["id"] except: return selection = view.get_selection() if not selection: return model, iter = selection.get_selected() if not iter: return path = store.get_path(iter) col = view.get_column(0) view.scroll_to_cell(path, col, gtk.TRUE, 0.5, 0.5) if id: gtk.idle_remove(id) # setup globals def processEvents(): gtk.gdk.flush() while gtk.events_pending(): gtk.main_iteration(gtk.FALSE) def partedExceptionWindow(exc): # if our only option is to cancel, let us handle the exception # in our code and avoid popping up the exception window here. if exc.options == parted.EXCEPTION_CANCEL: return parted.EXCEPTION_UNHANDLED print exc.type_string print exc.message print exc.options win = gtk.Dialog(exc.type_string, mainWindow, gtk.DIALOG_MODAL) addFrame(win) win.set_position(gtk.WIN_POS_CENTER) label = WrappingLabel(exc.message) win.vbox.pack_start (label) numButtons = 0 buttonToAction = {} exflags = ((parted.EXCEPTION_FIX, N_("Fix")), (parted.EXCEPTION_YES, N_("Yes")), (parted.EXCEPTION_NO, N_("No")), (parted.EXCEPTION_OK, N_("OK")), (parted.EXCEPTION_RETRY, N_("Retry")), (parted.EXCEPTION_IGNORE, N_("Ignore")), (parted.EXCEPTION_CANCEL, N_("Cancel"))) for flag, string in exflags: if exc.options & flag: win.add_button(_(string), flag) win.show_all() rc = win.run() win.destroy() return rc def widgetExpander(widget, growTo=None): widget.connect("size-allocate", growToParent, growTo) def growToParent(widget, rect, growTo=None): return if not widget.parent: return ignore = widget.__dict__.get("ignoreEvents") if not ignore: if growTo: x, y, width, height = growTo.get_allocation() widget.set_size_request(width, -1) else: widget.set_size_request(rect.width, -1) widget.ignoreEvents = 1 else: widget.ignoreEvents = 0 _busyCursor = 0 def setCursorToBusy(process=1): root = gtk.gdk.get_default_root_window() cursor = gtk.gdk.Cursor(gtk.gdk.WATCH) root.set_cursor(cursor) if process: processEvents() def setCursorToNormal(): root = gtk.gdk.get_default_root_window() cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) root.set_cursor(cursor) def rootPushBusyCursor(process=1): global _busyCursor _busyCursor += 1 if _busyCursor > 0: setCursorToBusy(process) def rootPopBusyCursor(): global _busyCursor _busyCursor -= 1 if _busyCursor <= 0: setCursorToNormal() def getBusyCursorStatus(): global _busyCursor return _busyCursor class MnemonicLabel(gtk.Label): def __init__(self, text=""): gtk.Label.__init__(self, "") self.set_text_with_mnemonic(text) class WrappingLabel(gtk.Label): def __init__(self, label=""): gtk.Label.__init__(self, label) self.set_line_wrap(gtk.TRUE) self.ignoreEvents = 0 # self.set_size_request(-1, 1) widgetExpander(self) def titleBarMousePressCB(widget, event, data): if event.type & gtk.gdk.BUTTON_PRESS: data["state"] = 1 data["button"] = event.button data["deltax"] = event.x data["deltay"] = event.y def titleBarMouseReleaseCB(widget, event, data): if data["state"] and event.button == data["button"]: data["state"] = 0 data["button"] = 0 data["deltax"] = 0 data["deltay"] = 0 def titleBarMotionEventCB(widget, event, data): if data["state"]: newx = event.x_root-data["deltax"] newy = event.y_root-data["deltay"] if newx < 0: newx = 0 if newy < 0: newy = 0 (w, h) = data["window"].get_size() if (newx+w) > gtk.gdk.screen_width(): newx = gtk.gdk.screen_width() - w if (newy+20) > (gtk.gdk.screen_height()): newy = gtk.gdk.screen_height() - 20 data["window"].move(newx, newy) def addFrame(dialog, title=None): contents = dialog.get_children()[0] dialog.remove(contents) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_OUT) box = gtk.VBox() try: if title is None: title = dialog.get_title() if title: data = {} data["state"] = 0 data["button"] = 0 data["deltax"] = 0 data["deltay"] = 0 data["window"] = dialog eventBox = gtk.EventBox() eventBox.connect("button-press-event", titleBarMousePressCB, data) eventBox.connect("button-release-event", titleBarMouseReleaseCB, data) eventBox.connect("motion-notify-event", titleBarMotionEventCB,data) titleBox = gtk.HBox(gtk.FALSE, 5) eventBox.add(titleBox) eventBox.modify_bg(gtk.STATE_NORMAL, eventBox.rc_get_style().bg[gtk.STATE_SELECTED]) titlelbl = gtk.Label("") titlelbl.set_markup(""+_(title)+"") titlelbl.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse ("white")) titlelbl.set_property("ypad", 4) titleBox.pack_start(titlelbl) box.pack_start(eventBox, gtk.FALSE, gtk.FALSE) except: pass frame2=gtk.Frame() frame2.set_shadow_type(gtk.SHADOW_NONE) frame2.set_border_width(4) frame2.add(contents) box.pack_start(frame2, gtk.TRUE, gtk.TRUE, padding=5) frame.add(box) frame.show() dialog.add(frame) # make screen shots work dialog.connect ("key-release-event", handleShiftPrintScrnRelease) class WaitWindow: def __init__(self, title, text): self.window = gtk.Window(gtk.WINDOW_POPUP) self.window.set_title(title) self.window.set_position(gtk.WIN_POS_CENTER) self.window.set_modal(gtk.TRUE) label = WrappingLabel(text) box = gtk.Frame() box.set_border_width(10) box.add(label) box.set_shadow_type(gtk.SHADOW_NONE) frame = gtk.Frame () frame.set_shadow_type(gtk.SHADOW_OUT) frame.add (box) self.window.add(frame) self.window.show_all() rootPushBusyCursor() def pop(self): self.window.destroy() rootPopBusyCursor() class ProgressWindow: def __init__(self, title, text, total): self.window = gtk.Window (gtk.WINDOW_POPUP) self.window.set_title (title) self.window.set_position (gtk.WIN_POS_CENTER) self.window.set_modal (gtk.TRUE) box = gtk.VBox (gtk.FALSE, 5) box.set_border_width (10) label = WrappingLabel (text) label.set_alignment (0.0, 0.5) box.pack_start (label, gtk.FALSE) self.total = total self.progress = gtk.ProgressBar () box.pack_start (self.progress, gtk.TRUE) frame = gtk.Frame () frame.set_shadow_type (gtk.SHADOW_OUT) frame.add (box) self.window.add (frame) self.window.show_all () rootPushBusyCursor() def set (self, amount): # only update widget if we've changed by 5% curval = self.progress.get_fraction() newval = float (amount) / self.total if newval < 0.998: if (newval - curval) < 0.05 and newval > curval: return self.progress.set_fraction (newval) processEvents () def pop(self): self.window.destroy () rootPopBusyCursor() class ExceptionWindow: def __init__ (self, text): try: floppyDevices = 0 for dev in kudzu.probe(kudzu.CLASS_FLOPPY, kudzu.BUS_UNSPEC, kudzu.PROBE_ALL): if not dev.detached: floppyDevices = floppyDevices + 1 except: floppyDevices = 0 win = gtk.Dialog("Exception Occured", mainWindow, gtk.DIALOG_MODAL) win.add_button("_Debug", 0) if floppyDevices > 0 or DEBUG: win.add_button("_Save to floppy", 1) win.add_button('gtk-ok', 2) buffer = gtk.TextBuffer(None) buffer.set_text(text) textbox = gtk.TextView() textbox.set_buffer(buffer) textbox.set_property("editable", gtk.FALSE) textbox.set_property("cursor_visible", gtk.FALSE) sw = gtk.ScrolledWindow () sw.add (textbox) sw.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) hbox = gtk.HBox (gtk.FALSE) ## file = pixmap_file('gnome-warning.png') ## if file: ## hbox.pack_start (GnomePixmap (file), gtk.FALSE) if floppyDevices > 0: info = WrappingLabel(exceptionText) else: info = WrappingLabel(exceptionTextNoFloppy) info.set_size_request (400, -1) hbox.pack_start (sw, gtk.TRUE) win.vbox.pack_start (info, gtk.FALSE) win.vbox.pack_start (hbox, gtk.TRUE) win.set_size_request (500, 300) win.set_position (gtk.WIN_POS_CENTER) addFrame(win) win.show_all () self.window = win self.rc = self.window.run () # self.window.destroy() def getrc (self): # I did it this way for future expantion # 0 is debug if self.rc == 0: try: # switch to VC1 so we can debug isys.vtActivate (1) except SystemError: pass return 1 # 1 is save if self.rc == 1: return 2 # 2 is OK elif self.rc == 2: return 0 class MessageWindow: def getrc (self): return self.rc def __init__ (self, title, text, type="ok", default=None, custom_buttons=None, custom_icon=None): if flags.autostep: self.rc = 1 return self.rc = None docustom = 0 if type == 'ok': buttons = gtk.BUTTONS_OK style = gtk.MESSAGE_INFO elif type == 'warning': buttons = gtk.BUTTONS_OK style = gtk.MESSAGE_WARNING elif type == 'okcancel': buttons = gtk.BUTTONS_OK_CANCEL style = gtk.MESSAGE_WARNING elif type == 'yesno': buttons = gtk.BUTTONS_YES_NO style = gtk.MESSAGE_QUESTION elif type == 'custom': docustom = 1 buttons = gtk.BUTTONS_NONE style = gtk.MESSAGE_QUESTION if custom_icon == "warning": style = gtk.MESSAGE_WARNING elif custom_icon == "question": style = gtk.MESSAGE_QUESTION elif custom_icon == "error": style = gtk.MESSAGE_ERROR elif custom_icon == "info": style = gtk.MESSAGE_INFO dialog = gtk.MessageDialog(mainWindow, 0, style, buttons, text) if docustom: rid=0 for button in custom_buttons: if button == _("Cancel"): tbutton = "gtk-cancel" else: tbutton = button widget = dialog.add_button(tbutton, rid) rid = rid + 1 defaultchoice = rid - 1 else: if default == "no": defaultchoice = 0 elif default == "yes" or default == "ok": defaultchoice = 1 else: defaultchoice = 0 addFrame(dialog, title=title) dialog.set_position (gtk.WIN_POS_CENTER) dialog.set_default_response(defaultchoice) dialog.show_all () # XXX - Messy - turn off busy cursor if necessary busycursor = getBusyCursorStatus() setCursorToNormal() rc = dialog.run() if rc == gtk.RESPONSE_OK or rc == gtk.RESPONSE_YES: self.rc = 1 elif (rc == gtk.RESPONSE_CANCEL or rc == gtk.RESPONSE_NO or rc == gtk.RESPONSE_CLOSE): self.rc = 0 elif rc == gtk.RESPONSE_DELETE_EVENT: self.rc = 0 else: self.rc = rc dialog.destroy() # restore busy cursor if busycursor: setCursorToBusy() class InstallInterface: def __init__ (self): # figure out if we want to run interface at 800x600 or 640x480 if gtk.gdk.screen_width() >= 800: self.runres = "800x600" else: self.runres = "640x480" def __del__ (self): pass def shutdown (self): pass def setPackageProgressWindow (self, ppw): self.ppw = ppw def waitWindow (self, title, text): return WaitWindow (title, text) def progressWindow (self, title, text, total): return ProgressWindow (title, text, total) def packageProgressWindow (self, total, totalSize): self.ppw.setSizes (total, totalSize) return self.ppw def messageWindow(self, title, text, type="ok", default = None, custom_buttons=None, custom_icon=None): rc = MessageWindow (title, text, type, default, custom_buttons, custom_icon).getrc() return rc def exceptionWindow(self, title, text): print text win = ExceptionWindow (text) return win.getrc () def dumpWindow(self): window = MessageWindow("Save Crash Dump", _("Please insert a floppy now. All contents " "of the disk will be erased, so please " "choose your diskette carefully."), "okcancel") rc = window.getrc() return not rc def getBootdisk (self): return None def run(self, id, dispatch, configFileData): ## from xkb import XKB ## kb = XKB() self.dispatch = dispatch # XXX users complain when the keypad doesn't work for input. ## if 0 and flags.setupFilesystems: ## try: ## kb.setMouseKeys (1) ## except SystemError: ## pass # XXX x_already_set is a hack if id.keyboard and not id.x_already_set: id.keyboard.activate() ## info = id.keyboard.getXKB() ## if info: ## (rules, model, layout, variant, options) = info ## kb.setRule (model, layout, variant, "complete") id.fsset.registerMessageWindow(self.messageWindow) id.fsset.registerProgressWindow(self.progressWindow) id.fsset.registerWaitWindow(self.waitWindow) parted.exception_set_handler(partedExceptionWindow) lang = id.instLanguage.getCurrent() lang = id.instLanguage.getLangNick(lang) self.icw = InstallControlWindow (self, self.dispatch, lang) self.icw.run (self.runres, configFileData) class TextViewBrowser(gtk.TextView): def __init__(self): self.hadj = None self.vadj = None gtk.TextView.__init__(self) self.set_property('editable', gtk.FALSE) self.set_property('cursor_visible', gtk.FALSE) self.set_left_margin(10) self.set_wrap_mode(gtk.WRAP_WORD) self.connect('move-cursor', self.moveCursor) self.connect('set-scroll-adjustments', self.cacheAdjustments) def swallowFocus(self, *args): self.emit_stop_by_name('focus-in-event') def cacheAdjustments(self, view, hadj, vadj): self.hadj = hadj self.vadj = vadj def moveCursor(self, view, step, count, extend_selection): if step == gtk.MOVEMENT_DISPLAY_LINES: if count == -1 and self.vadj != None: self.vadj.value = max(self.vadj.value - self.vadj.step_increment, self.vadj.lower) self.vadj.value_changed() elif count == 1 and self.vadj != None: self.vadj.value = min(self.vadj.value + self.vadj.step_increment - 1, self.vadj.upper - self.vadj.page_increment - 1) self.vadj.value_changed() elif step == gtk.MOVEMENT_PAGES: if count == -1 and self.vadj != None: self.vadj.value = max(self.vadj.value - self.vadj.page_increment, self.vadj.lower) self.vadj.value_changed() elif count == 1 and self.vadj != None: self.vadj.value = min(self.vadj.value + self.vadj.page_increment - 1, self.vadj.upper - self.vadj.page_increment - 1) self.vadj.value_changed() self.emit_stop_by_name ('move-cursor') class InstallControlWindow: def setLanguage (self, locale): #gtk_set_locale () #gtk_rc_init () #gtk_rc_reparse_all () self.langSearchPath = expandLangs(locale) + ['C'] ## found = 0 ## for l in self.langSearchPath: ## if os.access ("/etc/gtk/gtkrc." + l, os.R_OK): ## rc_parse("/etc/gtk/gtkrc." + l) ## found = 1 ## if not found: ## rc_parse("/etc/gtk/gtkrc") ## #_gtk_nuke_rc_mtimes () ## gtk_rc_reparse_all () if not self.__dict__.has_key('window'): return self.reloadRcQueued = 1 self.updateStockButtons() self.helpFrame.set_label (_("Online Help")) self.installFrame.set_label (_("Language Selection")) self.loadReleaseNotes() self.refreshHelp(recreate = 1) def prevClicked (self, *args): try: self.currentWindow.getPrev () except StayOnScreen: return self.dispatch.gotoPrev() self.dir = -1 self.setScreen () def nextClicked (self, *args): try: rc = self.currentWindow.getNext () except StayOnScreen: return self.dispatch.gotoNext() self.dir = 1 self.setScreen () def helpClicked (self, widget, simulated=0): self.hbox.remove (widget) if widget == self.hideHelpButton: self.bin.remove (self.table) self.installFrame.reparent (self.bin) self.showHelpButton.show () self.showHelpButton.set_state (gtk.STATE_NORMAL) self.hbox.pack_start (self.showHelpButton, gtk.FALSE) self.hbox.reorder_child (self.showHelpButton, 0) self.showHelpButton.grab_focus() self.displayHelp = gtk.FALSE else: self.bin.remove (self.installFrame) self.table.attach (self.installFrame, 1, 3, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND) self.bin.add (self.table) self.refreshHelp() self.hideHelpButton.show () self.showHelpButton.set_state (gtk.STATE_NORMAL) self.hbox.pack_start (self.hideHelpButton, gtk.FALSE) self.hbox.reorder_child (self.hideHelpButton, 0) self.hideHelpButton.grab_focus() self.displayHelp = gtk.TRUE def debugClicked (self, *args): try: # switch to VC1 so we can debug isys.vtActivate (1) except SystemError: pass import pdb try: pdb.set_trace() except: sys.exit(-1) try: # switch back isys.vtActivate (7) except SystemError: pass def refreshHelp(self, recreate = 0): buffer = htmlbuffer.HTMLBuffer() ics = self.currentWindow.getICS() buffer.feed(ics.getHTML(self.langSearchPath)) textbuffer = buffer.get_buffer() if recreate == 0: self.help.set_buffer(textbuffer) else: self.help_sw.remove(self.help) self.help = TextViewBrowser() self.help_sw.add(self.help) self.help.set_buffer(textbuffer) self.help.show() # scroll to the top. Do this with a mark so it's done in the idle loop iter = textbuffer.get_iter_at_offset(0) mark = textbuffer.create_mark("top", iter, gtk.FALSE) self.help.scroll_to_mark(mark, 0.0, gtk.FALSE, 0.0, 0.0) def relnotes_closed (self, *args): self.textWin.destroy() # # XXX - disabling this behavior for now due to bug where if you pop up # release notes during package selection, then close it after # package selection is done and install has moved to next screen, # the stockButtons get their state screwed up # # for (icon, name, text, func) in self.stockButtons: # if self.__dict__.has_key(name): # self.__dict__[name].set_sensitive(self.relnotes_buttonstate[name]) return def releaseClicked (self, widget): self.textWin = gtk.Dialog(parent=mainWindow, flags=gtk.DIALOG_MODAL) # # XXX - disabling this behavior for now due to bug where if you pop up # release notes during package selection, then close it after # package selection is done and install has moved to next screen, # the stockButtons get their state screwed up # self.relnotes_buttonstate={} # for (icon, name, text, func) in self.stockButtons: # if self.__dict__.has_key(name): # self.relnotes_buttonstate[name] = self.__dict__[name].get_property("sensitive") # self.__dict__[name].set_sensitive(gtk.FALSE) table = gtk.Table(3, 3, gtk.FALSE) self.textWin.vbox.pack_start(table) self.textWin.add_button('gtk-close', gtk.RESPONSE_NONE) self.textWin.connect("response", self.relnotes_closed) vbox1 = gtk.VBox () vbox1.set_border_width (10) frame = gtk.Frame (_("Release Notes")) frame.add(vbox1) frame.set_label_align (0.5, 0.5) frame.set_shadow_type (gtk.SHADOW_NONE) self.textWin.set_position (gtk.WIN_POS_CENTER) if self.releaseNotesBuffer: text = TextViewBrowser() text.set_buffer(self.releaseNotesBuffer) sw = gtk.ScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) sw.set_shadow_type(gtk.SHADOW_IN) sw.add(text) vbox1.pack_start(sw) a = gtk.Alignment (0, 0, 1.0, 1.0) a.add (frame) self.textWin.set_default_size (635, 393) self.textWin.set_size_request (635, 393) self.textWin.set_position (gtk.WIN_POS_CENTER) table.attach (a, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 5, 5) self.textWin.set_border_width(0) addFrame(self.textWin, _("Release Notes")) self.textWin.show_all() else: self.textWin.set_position (gtk.WIN_POS_CENTER) label = gtk.Label(_("Unable to load file!")) table.attach (label, 1, 2, 1, 2, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 5, 5) self.textWin.set_border_width(0) addFrame(self.textWin) self.textWin.show_all() def loadReleaseNotes(self): langList = self.langSearchPath + [ "" ] sourcepath = self.dispatch.method.getSourcePath() suffixList = [] for lang in langList: if lang: suffixList.append("-%s.html" % (lang,)) suffixList.append(".%s" % (lang,)) else: suffixList.append(".html") suffixList.append("") for suffix in suffixList: fn = "%s/RELEASE-NOTES%s" % (sourcepath, suffix) if os.access(fn, os.R_OK): file = open(fn, "r") if suffix.endswith('.html'): buffer = htmlbuffer.HTMLBuffer() buffer.feed(file.read()) self.releaseNotesBuffer = buffer.get_buffer() else: buffer = gtk.TextBuffer(None) buffer.set_text(file.read()) self.releaseNotesBuffer = buffer file.close() return buffer = gtk.TextBuffer(None) buffer.set_text(_("Release notes are missing.\n")) self.releaseNotesBuffer = buffer def handleRenderCallback(self): self.currentWindow.renderCallback() if flags.autostep: self.nextClicked() else: gtk.idle_remove(self.handle) def setScreen (self): (step, args) = self.dispatch.currentStep() if step is None: gtk.mainquit() return if not stepToClass[step]: if self.dir == 1: return self.nextClicked() else: return self.prevClicked() (file, className) = stepToClass[step] newScreenClass = None s = "from %s import %s; newScreenClass = %s" % (file, className, className) while 1: try: exec s break except ImportError, e: print e win = MessageWindow(_("Error!"), _("An error occurred when attempting " "to load an installer interface " "component.\n\nclassName = %s") % (className,), type="custom", custom_icon="warning", custom_buttons=[_("_Exit"), _("_Retry")]) if not win.getrc(): MessageWindow(_("Rebooting System"), _("Your system will now be rebooted..."), type="custom", custom_icon="warning", custom_buttons=[_("_Reboot")]) sys.exit(0) ics = InstallControlState (self) ics.setPrevEnabled(self.dispatch.canGoBack()) self.destroyCurrentWindow() self.currentWindow = newScreenClass(ics) new_screen = apply(self.currentWindow.getScreen, args) if not new_screen: return self.update (ics) self.installFrame.set_label(ics.getTitle ()) self.installFrame.add(new_screen) self.installFrame.show_all() self.handle = gtk.idle_add(self.handleRenderCallback) if self.reloadRcQueued: self.window.reset_rc_styles() self.reloadRcQueued = 0 if self.displayHelp: self.refreshHelp() def destroyCurrentWindow(self): children = self.installFrame.get_children () if children: child = children[0] self.installFrame.remove (child) child.destroy () self.currentWindow = None def update (self, ics): self.installFrame.set_label (ics.getTitle ()) prevButton = self.prevButtonStock nextButton = self.nextButtonStock if ics.getNextButton(): (icon, text) = ics.getNextButton() button = gtk.Button() box = gtk.HBox(gtk.FALSE, 0) image = gtk.Image() image.set_from_stock(icon, gtk.ICON_SIZE_BUTTON) box.pack_start(image, gtk.FALSE, gtk.FALSE) label = gtk.Label(_(text)) label.set_property("use-underline", gtk.TRUE) box.pack_start(label, gtk.TRUE, gtk.TRUE) button.add(box) button.connect("clicked", self.nextClicked) button.show_all() button.label = label nextButton = button children = self.buttonBox.get_children() if not nextButton in children and self.nextButtonStock in children: pos = children.index(self.nextButtonStock) self.buttonBox.remove(self.nextButtonStock) self.buttonBox.pack_end(nextButton) self.buttonBox.reorder_child(nextButton, pos) self.nextButtonStock = nextButton prevButton.set_sensitive (ics.getPrevEnabled ()) nextButton.set_sensitive (ics.getNextEnabled ()) self.hideHelpButton.set_sensitive (ics.getHelpButtonEnabled ()) self.showHelpButton.set_sensitive (ics.getHelpButtonEnabled ()) if ics.getHelpEnabled () == gtk.FALSE: if self.displayHelp: self.helpClicked (self.hideHelpButton, 1) elif ics.getHelpEnabled () == gtk.TRUE: if not self.displayHelp: self.helpClicked (self.showHelpButton, 1) if (ics.getGrabNext ()): nextButton.grab_focus () def __init__ (self, ii, dispatch, locale): self.prevButtonStock = None self.nextButtonStock = None self.releaseButton = None self.showHelpButton = None self.hideHelpButton = None self.debugButton = None self.stockButtons = (('gtk-go-back', "prevButtonStock", N_("_Back"), self.prevClicked), ('gtk-go-forward', "nextButtonStock", N_("_Next"), self.nextClicked), ('gtk-new', "releaseButton", N_("_Release Notes"), self.releaseClicked), ('gtk-help', "showHelpButton", N_("Show _Help"), self.helpClicked), ('gtk-help', "hideHelpButton", N_("Hide _Help"), self.helpClicked), ('gtk-execute', 'debugButton', N_("_Debug"), self.debugClicked)) self.reloadRcQueued = 0 self.ii = ii self.dispatch = dispatch self.setLanguage(locale) self.handle = None def keyRelease (self, window, event): if ((event.keyval == gtk.keysyms.KP_Delete or event.keyval == gtk.keysyms.Delete) and (event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK))): gtk.mainquit() os._exit(0) # XXX hack: remove me when the accelerators work again. elif (event.keyval == gtk.keysyms.F12 and self.currentWindow.getICS().getNextEnabled()): self.nextClicked() elif (event.keyval == gtk.keysyms.Print and event.state & gtk.gdk.SHIFT_MASK): takeScreenShot() def buildStockButtons(self): for (icon, item, text, action) in self.stockButtons: button = gtk.Button() box = gtk.HBox(gtk.FALSE, 0) image = gtk.Image() image.set_from_stock(icon, gtk.ICON_SIZE_BUTTON) box.pack_start(image, gtk.FALSE, gtk.FALSE) label = gtk.Label(_(text)) label.set_property("use-underline", gtk.TRUE) box.pack_start(label, gtk.TRUE, gtk.TRUE) button.add(box) button.connect("clicked", action) button.show_all() button.label = label self.__dict__[item] = button def updateStockButtons(self): for (icon, item, text, action) in self.stockButtons: button = self.__dict__[item] for child in button.get_children(): button.remove(child) # FIXME: this is cut and pasted from above; make a nicer # function that knows how to replace the contents in the # button for a future release box = gtk.HBox(gtk.FALSE, 0) image = gtk.Image() image.set_from_stock(icon, gtk.ICON_SIZE_BUTTON) box.pack_start(image, gtk.FALSE, gtk.FALSE) label = gtk.Label(_(text)) label.set_property("use-underline", gtk.TRUE) box.pack_start(label, gtk.TRUE, gtk.TRUE) button.add(box) button.show_all() button.label = label button.queue_resize() def findPixmap(self, file): for path in ("/mnt/source/" + productSite + "/RHupdates/pixmaps/", "/mnt/source/" + productSite + "/RHupdates/", "/tmp/updates/pixmaps/", "/tmp/updates/", "/mnt/source/RHupdates/pixmaps/", "/mnt/source/RHupdates/", "/tmp/product/pixmaps/", "/tmp/product/", "/usr/share/anaconda/pixmaps/", "pixmaps/", "/usr/share/pixmaps/", "/usr/share/anaconda/", ""): fn = path + file if os.access(fn, os.R_OK): return fn return None def setup_window (self, runres): self.window = gtk.Window () global mainWindow mainWindow = self.window self.window.set_events (gtk.gdk.KEY_RELEASE_MASK) if runres == '640x480': self.window.set_default_size (640, 480) self.window.set_size_request (640, 480) else: self.window.set_default_size (800, 600) self.window.set_size_request (800, 600) self.window.set_border_width (10) title = _("%s Installer") % (productName,) if os.environ["DISPLAY"][:1] != ':': # from gnome.zvt import * # zvtwin = gtk.Window () # shtitle = _("Red Hat Linux Install Shell") try: f = open ("/tmp/netinfo", "r") except: pass else: lines = f.readlines () f.close () for line in lines: netinf = string.splitfields (line, '=') if netinf[0] == "HOSTNAME": title = _("%s Installer on %s") % (productName, string.strip (netinf[1])) # shtitle = _("Red Hat Linux Install Shell on %s") % string.strip (netinf[1]) break # zvtwin.set_title (shtitle) # zvt = ZvtTerm (80, 24) # if zvt.forkpty() == 0: # os.execv ("/bin/sh", [ "/bin/sh" ]) # zvt.show () # zvtwin.add (zvt) # zvtwin.show_all () self.window.set_title (title) self.window.set_position (gtk.WIN_POS_CENTER) self.window.set_border_width(0) vbox = gtk.VBox (gtk.FALSE, 10) image = self.configFileData["TitleBar"] pixbuf = None # Create header at the top of the installer if runres != '640x480': fn = self.findPixmap(image) if not fn: log("unable to load %s", image) else : pixbuf = gtk.gdk.pixbuf_new_from_file(fn) if pixbuf: p = gtk.Image() p.set_from_pixbuf(pixbuf) a = gtk.Alignment() a.set(0.5, 0.5, 1.0, 1.0) a.add(p) vbox.pack_start(a, gtk.FALSE, gtk.TRUE, 0) else: print _("Unable to load title bar") self.loadReleaseNotes() vbox.set_spacing(0) self.buttonBox = gtk.HButtonBox () self.buttonBox.set_layout (gtk.BUTTONBOX_END) self.buttonBox.set_spacing (30) self.buildStockButtons() group = gtk.AccelGroup() self.window.add_accel_group(group) self.nextButtonStock.add_accelerator('clicked', group, gtk.keysyms.F12, gtk.gdk.RELEASE_MASK, 0); # set up ctrl+alt+delete handler self.window.connect ("key-release-event", self.keyRelease) if DEBUG: self.buttonBox.add (self.debugButton) self.buttonBox.add (self.prevButtonStock) self.buttonBox.add (self.nextButtonStock) self.hbox = gtk.HBox () self.hbox.set_border_width(5) self.hbox.pack_start (self.hideHelpButton, gtk.FALSE) self.hbox.set_spacing (25) self.hbox.pack_start (self.releaseButton, gtk.FALSE) self.hbox.pack_start (self.buttonBox) vbox.pack_end (self.hbox, gtk.FALSE) self.help = TextViewBrowser() self.displayHelp = gtk.TRUE self.helpState = gtk.TRUE self.helpFrame = gtk.Frame (_("Online Help")) self.box = gtk.VBox (gtk.FALSE, 0) self.box.set_spacing(0) self.help_sw = gtk.ScrolledWindow() self.help_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.help_sw.set_shadow_type(gtk.SHADOW_IN) self.help_sw.add(self.help) self.box.pack_start(self.help_sw, gtk.TRUE) self.helpFrame.add (self.box) table = gtk.Table (1, 3, gtk.TRUE) table.attach (self.helpFrame, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND) self.installFrame = gtk.Frame () self.windowList = [] #self.setStateList (self.steps, 0) self.setScreen () table.attach (self.installFrame, 1, 3, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND) table.set_col_spacing (0, 5) self.bin = gtk.Frame () self.bin.set_shadow_type (gtk.SHADOW_NONE) self.bin.add (table) vbox.pack_end (self.bin, gtk.TRUE, gtk.TRUE) self.table = table self.window.add (vbox) # Popup the ICW and wait for it to wake us back up self.window.show_all () splashScreenPop() def busyCursorPush(self): rootPushBusyCursor() def busyCursorPop(self): rootPopBusyCursor() def run (self, runres, configFileData): self.configFileData = configFileData self.setup_window(runres) gtk.main() class InstallControlState: def __init__ (self, cw): self.searchPath = ("/mnt/source/RHupdates", "./", "/usr/share/anaconda/") self.cw = cw self.prevEnabled = 1 self.nextEnabled = 1 self.nextButtonInfo = None self.helpButtonEnabled = gtk.TRUE self.title = _("Install Window") self.html = "" self.htmlFile = None self.nextButton = 'gtk-next' self.prevButton = 'gtk-prev' self.nextButtonLabel = None self.prevButtonLabel = None # Values other than gtk.TRUE or gtk.FALSE don't change the help setting self.helpEnabled = 3 self.grabNext = 0 def setTitle (self, title): self.title = title self.cw.update (self) def getTitle (self): return self.title def setPrevEnabled (self, value): if value == self.prevEnabled: return self.prevEnabled = value self.cw.update (self) def getPrevEnabled (self): return self.prevEnabled def setNextEnabled (self, value): if value != self.nextEnabled: self.nextEnabled = value self.cw.update (self) def getNextEnabled (self): return self.nextEnabled def setHelpButtonEnabled (self, value): if value == self.helpButtonEnabled: return self.helpButtonEnabled = value self.cw.update (self) def getHelpButtonEnabled (self): return self.helpButtonEnabled def findPixmap(self, file): for path in ("/mnt/source/" + productSite + "/RHupdates/pixmaps/", "/mnt/source/" + productSite + "/RHupdates/", "/tmp/updates/pixmaps/", "/tmp/updates/", "/mnt/source/RHupdates/pixmaps/", "/mnt/source/RHupdates/", "/tmp/product/pixmaps/", "/tmp/product/", "/usr/share/anaconda/pixmaps/", "pixmaps/", "/usr/share/pixmaps/", "/usr/share/anaconda/", ""): fn = path + file if os.access(fn, os.R_OK): return fn return None def readPixmap (self, file, height = None, width = None): fn = self.findPixmap(file) if not fn: log("unable to load %s", file) return None try: pixbuf = gtk.gdk.pixbuf_new_from_file(fn) except RuntimeError, msg: log("unable to read %s: %s", file, msg) return None if (height is not None and width is not None and height != pixbuf.get_height() and width != pixbuf.get_width()): sclpix = pixbuf.scale_simple(height, width, gtk.gdk.INTERP_BILINEAR) p = gtk.Image() p.set_from_pixbuf(sclpix) else: source = gtk.IconSource() source.set_pixbuf(pixbuf) source.set_size(gtk.ICON_SIZE_DIALOG) source.set_size_wildcarded(gtk.FALSE) iconset = gtk.IconSet() iconset.add_source(source) p = gtk.image_new_from_icon_set(iconset, gtk.ICON_SIZE_DIALOG) return p def readPixmapDithered(self, file, height = None, width = None): fn = self.findPixmap(file) if not fn: log("unable to load %s", file) return None try: pixbuf = gtk.gdk.pixbuf_new_from_file(fn) except RuntimeError, msg: log("unable to read %s: %s", file, msg) return None if (height is not None and width is not None and height != pixbuf.get_height() and width != pixbuf.get_width()): pixbuf = pixbuf.scale_simple(height, width, gtk.gdk.INTERP_BILINEAR) (pixmap, mask) = pixbuf.render_pixmap_and_mask() pixbuf.render_to_drawable(pixmap, gtk.gdk.GC(pixmap), 0, 0, 0, 0, pixbuf.get_width(), pixbuf.get_height(), gtk.gdk.RGB_DITHER_MAX, 0, 0) p = gtk.Image() p.set_from_pixmap(pixmap, mask) return p def readHTML (self, file): self.htmlFile = file def setHTML (self, text): self.html = text self.cw.update (self) def getHTML (self, langPath): text = None if self.htmlFile: file = self.htmlFile if self.cw.configFileData.has_key("helptag"): helpTag = "-%s" % (self.cw.configFileData["helptag"],) else: helpTag = "" arch = "-%s" % (iutil.getArch(),) tags = [ "%s%s" % (helpTag, arch), "%s" % (helpTag,), "%s" % (arch,), "" ] found = 0 for path in self.searchPath: if found: break for lang in langPath + ['C']: if found: break for tag in tags: try: text = open("%s/help/%s/s1-help-screens-%s%s.html" % (path, lang, file, tag)).read () found = 1 break except IOError: continue if text: break if text: text = text.replace("@RHL@", productName) text = text.replace("@RHLVER@", productVersion) return text print "Unable to read %s help text" % (file,) return self.html def setScreenPrev (self): self.cw.prevClicked () def setScreenNext (self): self.cw.nextClicked () def setHelpEnabled (self, value): self.helpEnabled = value self.cw.update (self) def getHelpEnabled (self): return self.helpEnabled def setGrabNext (self, value): self.grabNext = value self.cw.update (self) def getGrabNext (self): return self.grabNext def getICW (self): return self.cw def setNextButton(self, icon, text): self.nextButtonInfo = (icon, text) def getNextButton(self): return self.nextButtonInfo # # installmethod.py - Base class for install methods # # Copyright 1999-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import os import string from hdrlist import groupSetFromCompsFile import isys import iutil import shutil from rhpl.log import log from rhpl.translate import _ import product class FileCopyException(Exception): def __init__(self, s = ""): self.args = s class InstallMethod: # find best match from several locations for a file def findBestFileMatch(self, treebase, file): # look in /tmp/updates first log("looking for %s in %s", file, treebase) rc = None tryloc = ["/tmp/updates"] if treebase is not None: tryloc.append(treebase + "/RHupdates") tryloc.append(treebase + "/" + product.productSite + "/base") tryloc.append(treebase + "/" + product.productDefault + "/base") # tryloc.append(treebase + "/RedHat/base") for pre in tryloc: tmpname = pre + "/" + file log("looking for %s ", tmpname) if os.access(tmpname, os.R_OK): log("Using file://%s", tmpname) return "file://%s" %(tmpname,) log("Unable to find %s", file) return None def protectedPartitions(self): return None def readCompsViaMethod(self, hdlist): pass def readComps(self, hdlist): # see if there is a comps in PYTHONPATH, otherwise fall thru # to method dependent location path = None if os.environ.has_key('PYTHONPATH'): for f in string.split(os.environ['PYTHONPATH'], ":"): if os.access (f+"/comps", os.X_OK): path = f+"/comps" break if path: return groupSetFromCompsFile(path, hdlist) else: return self.readCompsViaMethod(hdlist) pass def getTempPath(self): root = self.rootPath pathlist = [ "/var/tmp", "/tmp", "/." ] tmppath = None for p in pathlist: if (os.access(root + p, os.X_OK)): tmppath = root + p + "/" break if tmppath is None: log("Unable to find temp path, going to use ramfs path") return "/tmp/" return tmppath def getFilename(self, h, timer): pass def readHeaders(self): pass def systemUnmounted(self): pass def systemMounted(self, fstab, mntPoint): pass def isUpdateRPM(self, hdr): if (1000005 in hdr.keys()) and (hdr[1000005] is not None): return 1 return 0 def cacheUpdates(self, chroot, hdlist, intf): if self.needUpdateCache == 0: log("not caching updates") return log("going to cache updates") size = 0 num = 0 for h in hdlist.values(): if h.isSelected() and self.isUpdateRPM(h): log("%s is selected, size is %s" %(h.nevra(), h[1000001])) size += h[1000001] # FILESIZE_TAG num += 1 # make sure it looks like we have space + a fudge factor if (size / 1024.0 / 1024.0) > (isys.fsSpaceAvailable("/mnt/sysimage/var") + 50): log("only %s free on var and want %s, not caching updates" %(isys.fsSpaceAvailable("/mnt/sysimage/var"), size)) return if num == 0: return if intf: win = intf.progressWindow(_("Copying Files"), _("Transferring updated packages"), num) iutil.mkdirChain(chroot + "/var/spool/anaconda-updates") num = 0 for h in hdlist.values(): if h.isSelected() and self.isUpdateRPM(h): # path = "/RedHat/Updates/" path = "/" + product.productSite + "/Updates/" shutil.copy(self.tree + path + h[1000000], "%s/var/spool/anaconda-updates/%s" % (chroot, h[1000000])) num += 1 if intf: win.set(num) if intf: win.pop() self.updatesCopied = 1 def filesDone(self): pass def unlinkFilename(self, fullName): pass def __init__(self, rootpath): self.rootPath = rootpath self.needUpdateCache = 0 self.updatesCopied = 0 try: f = open("/proc/cmdline") line = f.readline() if string.find(line, " cacheupdates") != -1: self.needUpdateCache = 1 f.close() except: pass def getSourcePath(self): pass def unmountCD(self): pass def ejectCD(self): pass # this handles any cleanup needed for the method. it occurs *very* late # (ie immediately before the congratulations screen). main use right now # is ejecting the cdrom def doMethodComplete(method): method.ejectCD() # # image.py - Install method for disk image installs (CD & NFS) # # Copyright 1999-2003 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # from hdrlist import groupSetFromCompsFile, HeaderListFromFile from installmethod import InstallMethod, FileCopyException import iutil import os import isys import time import stat import kudzu import string import shutil from constants import * from rhpl.log import log from rhpl.translate import _ import product # this sucks, but we want to consider s390x as s390x in here but generally # don't. *sigh* if os.uname()[4] == "s390x": _arch = "s390x" else: _arch = iutil.getArch() class ImageInstallMethod(InstallMethod): def readCompsViaMethod(self, hdlist): fname = self.findBestFileMatch(self.tree, 'comps.xml') if fname is None: raise FileCopyException return groupSetFromCompsFile(fname, hdlist) def getFilename(self, h, timer): if self.isUpdateRPM(h) and self.updatesCopied == 1: log ("going to use cached package for %s" %(h[1000000],)) return "/var/spool/anaconda-updates/" + h[1000000] if self.currentIso is not None and self.currentIso != h[1000002]: log("switching from iso %s to %s for %s-%s-%s.%s" %(self.currentIso, h[1000002], h['name'], h['version'], h['release'], h['arch'])) self.currentIso = h[1000002] #CJS changed if self.isUpdateRPM(h): # path = "/RedHat/Updates/" path = "/" + product.productSite + "/Updates/" else: # path = "/RedHat/RPMS/" path = "/" + product.productDefault + "/RPMS/" return self.tree + path + h[1000000] #CJS changed def readHeaders(self): # if not os.access(self.tree + "/RedHat/base/hdlist", os.R_OK): # raise FileCopyException # return HeaderListFromFile(self.tree + "/RedHat/base/hdlist") log("self.tree is %s, productSite is %s" % (self.tree,product.productSite)) if not os.access(self.tree + "/" + product.productSite + "/base/hdlist", os.R_OK): raise FileCopyException return HeaderListFromFile(self.tree + "/" + product.productSite + "/base/hdlist") #CJS changed def mergeFullHeaders(self, hdlist): # if not os.access(self.tree + "/RedHat/base/hdlist2", os.R_OK): # raise FileCopyException # hdlist.mergeFullHeaders(self.tree + "/RedHat/base/hdlist2") if not os.access(self.tree + "/" + product.productSite + "/base/hdlist2", os.R_OK): raise FileCopyException hdlist.mergeFullHeaders(self.tree + "/" + product.productSite + "/base/hdlist2") def getSourcePath(self): return self.tree def copyFileToTemp(self, filename): tmppath = self.getTempPath() path = tmppath + os.path.basename(filename) shutil.copy(self.tree + "/" + filename, path) return path def __init__(self, tree, rootPath): InstallMethod.__init__(self, rootPath) self.tree = tree self.currentIso = None #CJS added for informational log("product.productSite is %s" % product.productSite) log("product.productDefault is %s" % product.productDefault) class CdromInstallMethod(ImageInstallMethod): def unmountCD(self): done = 0 while done == 0: try: isys.umount("/mnt/source") self.currentDisc = [] break except: self.messageWindow(_("Error"), _("An error occurred unmounting the CD. " "Please make sure you're not accessing " "%s from the shell on tty2 " "and then click OK to retry.") % ("/mnt/source",)) def ejectCD(self): log("ejecting CD") # make /tmp/cdrom again so cd gets ejected isys.makeDevInode(self.device, "/tmp/cdrom") try: isys.ejectCdrom("/tmp/cdrom", makeDevice = 0) except Exception, e: log("eject failed %s" % (e,)) pass def systemUnmounted(self): if self.loopbackFile: isys.makeDevInode("loop0", "/tmp/loop") # isys.lochangefd("/tmp/loop", # "%s/RedHat/base/stage2.img" % self.tree) isys.lochangefd("/tmp/loop", "%s/%s/base/stage2.img" % (self.tree, product.productDefault)) self.loopbackFile = None def systemMounted(self, fsset, chroot): self.loopbackFile = "%s%s%s" % (chroot, fsset.filesystemSpace(chroot)[0][0], "/rhinstall-stage2.img") try: # iutil.copyFile("%s/RedHat/base/stage2.img" % self.tree, # self.loopbackFile, # (self.progressWindow, _("Copying File"), # _("Transferring install image to hard drive..."))) #CJS more changes for cdrom install iutil.copyFile("%s/%s/base/stage2.img" % (self.tree, product.productDefault ) , self.loopbackFile, (self.progressWindow, _("Copying File"), _("Transferring install image to hard drive..."))) except: self.messageWindow(_("Error"), _("An error occurred transferring the install image " "to your hard drive. You are probably out of disk " "space.")) os.unlink(self.loopbackFile) return 1 isys.makeDevInode("loop0", "/tmp/loop") isys.lochangefd("/tmp/loop", self.loopbackFile) def getFilename(self, h, timer): if self.isUpdateRPM(h) and self.updatesCopied == 1: log ("going to use cached package for %s" %(h[1000000],)) return "/var/spool/anaconda-updates/" + h[1000000] if h[1000002] == None: log ("header for %s has no disc location tag, assuming it's" "on the current CD", h[1000000]) elif h[1000002] not in self.currentDisc: timer.stop() log("switching from iso %s to %s for %s-%s-%s.%s" %(self.currentDisc, h[1000002], h['name'], h['version'], h['release'], h['arch'])) if os.access("/mnt/source/.discinfo", os.R_OK): f = open("/mnt/source/.discinfo") timestamp = f.readline().strip() f.close() else: timestamp = self.timestamp if self.timestamp is None: self.timestamp = timestamp needed = h[1000002] # if self.currentDisc is empty, then we shouldn't have anything # mounted. double-check by trying to unmount, but we don't want # to get into a loop of trying to unmount forever. if # self.currentDisc is set, then it should still be mounted and # we want to loop until it unmounts successfully if not self.currentDisc: try: isys.umount("/mnt/source") except: pass else: self.unmountCD() done = 0 cdlist = [] for (dev, something, descript) in \ kudzu.probe(kudzu.CLASS_CDROM, kudzu.BUS_UNSPEC, 0): cdlist.append(dev) for dev in cdlist: try: if not isys.mount(dev, "/mnt/source", fstype = "iso9660", readOnly = 1): if os.access("/mnt/source/.discinfo", os.R_OK): f = open("/mnt/source/.discinfo") newStamp = f.readline().strip() try: descr = f.readline().strip() except: descr = None try: arch = f.readline().strip() except: arch = None try: discNum = getDiscNums(f.readline().strip()) except: discNum = [ 0 ] f.close() if (newStamp == timestamp and arch == _arch and needed in discNum): done = 1 self.currentDisc = discNum if not done: isys.umount("/mnt/source") except: pass if done: break if not done: isys.ejectCdrom(self.device) while not done: self.messageWindow(_("Change CDROM"), _("Please insert disc %d to continue.") % needed) try: if isys.mount(self.device, "/mnt/source", fstype = "iso9660", readOnly = 1): time.sleep(3) isys.mount(self.device, "/mnt/source", fstype = "iso9660", readOnly = 1) if os.access("/mnt/source/.discinfo", os.R_OK): f = open("/mnt/source/.discinfo") newStamp = f.readline().strip() try: descr = f.readline().strip() except: descr = None try: arch = f.readline().strip() except: arch = None try: discNum = getDiscNums(f.readline().strip()) except: discNum = [ 0 ] f.close() if (newStamp == timestamp and arch == _arch and needed in discNum): done = 1 self.currentDisc = discNum # make /tmp/cdrom again so cd gets ejected isys.makeDevInode(self.device, "/tmp/cdrom") if not done: self.messageWindow(_("Wrong CDROM"), _("That's not the correct %s CDROM.") % (productName,)) isys.umount("/mnt/source") isys.ejectCdrom(self.device) except: self.messageWindow(_("Error"), _("The CDROM could not be mounted.")) timer.start() # if we haven't read a timestamp yet, let's try to get one if (self.timestamp is None and os.access("/mnt/source/.discinfo", os.R_OK)): try: f = open("/mnt/source/.discinfo") self.timestamp = f.readline().strip() f.close() except: pass tmppath = self.getTempPath() tries = 0 # FIXME: should retry a few times then prompt for new cd #CJS for cdrom while tries < 5: try: if self.isUpdateRPM(h): # path = "/RedHat/Updates/" path = "/" + product.productSite + "/Updates/" else: # path = "/RedHat/RPMS/" path = "/" + product.productDefault + "/RPMS/" shutil.copy(self.tree + path + h[1000000], tmppath + h[1000000]) except IOError, (errnum, msg): log("IOError %s occurred copying %s: %s", errnum, h[1000000], str(msg)) time.sleep(5) else: break tries = tries + 1 if tries >= 5: raise FileCopyException return tmppath + h[1000000] def unlinkFilename(self, fullName): os.remove(fullName) def filesDone(self): # we're trying to unmount the CD here. if it fails, oh well, # they'll reboot soon enough I guess :) try: isys.umount("/mnt/source") except: log("unable to unmount source in filesDone") if not self.loopbackFile: return try: # this isn't the exact right place, but it's close enough os.unlink(self.loopbackFile) except SystemError: pass def __init__(self, url, messageWindow, progressWindow, rootPath): (self.device, tree) = string.split(url, ":", 1) if not tree.startswith("/"): tree = "/%s" %(tree,) self.messageWindow = messageWindow self.progressWindow = progressWindow self.loopbackFile = None # figure out which disc is in. if we fail for any reason, # assume it's just disc1. if os.access("/mnt/source/.discinfo", os.R_OK): try: f = open("/mnt/source/.discinfo") self.timestamp = f.readline().strip() f.readline() # descr f.readline() # arch self.currentDisc = getDiscNums(f.readline().strip()) f.close() except: self.currentDisc = [ 1 ] self.timestamp = None else: self.currentDisc = [ 1 ] ImageInstallMethod.__init__(self, tree, rootPath) self.needUpdateCache = 1 class NfsInstallMethod(ImageInstallMethod): def __init__(self, tree, rootPath): ImageInstallMethod.__init__(self, tree, rootPath) def getDiscNums(line): # get the disc numbers for this disc nums = line.split(",") discNums = [] for num in nums: discNums.append(int(num)) return discNums def findIsoImages(path, messageWindow): files = os.listdir(path) arch = _arch discImages = {} for file in files: what = path + '/' + file if not isys.isIsoImage(what): continue isys.makeDevInode("loop2", "/tmp/loop2") try: isys.losetup("/tmp/loop2", what, readOnly = 1) except SystemError: continue try: isys.mount("loop2", "/mnt/cdimage", fstype = "iso9660", readOnly = 1) for num in range(1, 10): if os.access("/mnt/cdimage/.discinfo", os.R_OK): f = open("/mnt/cdimage/.discinfo") try: f.readline() # skip timestamp f.readline() # skip release description discArch = string.strip(f.readline()) # read architecture discNum = getDiscNums(f.readline().strip()) except: discArch = None discNum = [ 0 ] f.close() if num not in discNum or discArch != arch: continue # if it's disc1, it needs to have RedHat/base/stage2.img if (num == 1 and not # os.access("/mnt/cdimage/RedHat/base/stage2.img", # os.R_OK)): os.access("/mnt/cdimage/" + product.productDefault + "/base/stage2.img", os.R_OK)): continue # warn user if images appears to be wrong size if os.stat(what)[stat.ST_SIZE] % 2048: rc = messageWindow(_("Warning"), "The ISO image %s has a size which is not " "a multiple of 2048 bytes. This may mean " "it was corrupted on transfer to this computer." "\n\nPress OK to continue (but installation will " "probably fail), or Cancel to exit the " "installer (RECOMMENDED). " % file, type = "okcancel") if rc: import sys sys.exit(0) discImages[num] = file isys.umount("/mnt/cdimage") except SystemError: pass isys.makeDevInode("loop2", '/tmp/' + "loop2") isys.unlosetup("/tmp/loop2") return discImages class NfsIsoInstallMethod(NfsInstallMethod): def getFilename(self, h, timer): if self.imageMounted != h[1000002]: log("switching from iso %s to %s for %s-%s-%s.%s" %(self.imageMounted, h[1000002], h['name'], h['version'], h['release'], h['arch'])) self.umountImage() self.mountImage(h[1000002]) if self.isUpdateRPM(h): # path = "/RedHat/Updates/" path = "/" + product.productSite + "/Updates/" else: # path = "/RedHat/RPMS/" path = "/" + product.productDefault + "/RPMS/" return self.mntPoint + path + h[1000000] def umountImage(self): if self.imageMounted: isys.umount(self.mntPoint) isys.makeDevInode("loop3", "/tmp/loop3") isys.unlosetup("/tmp/loop3") self.mntPoint = None self.imageMounted = 0 def mountImage(self, cdNum): if (self.imageMounted): raise SystemError, "trying to mount already-mounted iso image!" isoImage = self.isoPath + '/' + self.discImages[cdNum] isys.makeDevInode("loop3", "/tmp/loop3") isys.losetup("/tmp/loop3", isoImage, readOnly = 1) isys.mount("loop3", "/tmp/isomedia", fstype = 'iso9660', readOnly = 1); self.mntPoint = "/tmp/isomedia/" self.imageMounted = cdNum def filesDone(self): # if we can't unmount the cd image, we really don't care much # let them go along and don't complain try: self.umountImage() except: log("unable to unmount iimage in filesDone") pass def __init__(self, tree, messageWindow, rootPath): self.imageMounted = None self.isoPath = tree # the tree points to the directory that holds the iso images # even though we already have the main one mounted once, it's # easiest to just mount it again so that we can treat all of the # images the same way -- we use loop3 for everything self.discImages = findIsoImages(tree, messageWindow) self.mountImage(1) ImageInstallMethod.__init__(self, self.mntPoint, rootPath) # # splashscreen.py: a quick splashscreen window that displays during ipl # # Matt Wilson # # Copyright 2001-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import os os.environ["PYGTK_DISABLE_THREADS"] = "1" os.environ["GNOME_DISABLE_CRASH_DIALOG"] = "1" import gtk from flags import flags from rhpl.translate import cat from rhpl.log import log import product # for GTK+ 2.0 cat.setunicode(1) splashwindow = None def splashScreenShow(configFileData): #set the background to a dark gray if flags.setupFilesystems: path = ("/usr/X11R6/bin/xsetroot",) args = ("-solid", "gray45") child = os.fork() if (child == 0): os.execv(path[0], path + args) try: pid, status = os.waitpid(child, 0) except OSError, (errno, msg): print __name__, "waitpid:", msg root = gtk.gdk.get_default_root_window() cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR) root.set_cursor(cursor) def findPixmap(file): for path in ("/mnt/source/" + product.productSite + "/RHupdates/pixmaps/", "/mnt/source/" + product.productSite + "/RHupdates/", "/tmp/updates/pixmaps/", "/tmp/updates/", "/mnt/source/RHupdates/pixmaps/", "/mnt/source/RHupdates/", "/tmp/product/pixmaps/", "/tmp/product/", "/usr/share/anaconda/pixmaps/", "pixmaps/", "/usr/share/pixmaps/", "/usr/share/anaconda/", ""): fn = path + file log("Looking for %s in splash findPixmap", fn) if os.access(fn, os.R_OK): return fn return None def load_image(file): p = gtk.Image() log("going to try to load %s", file) fn = findPixmap(file) if fn: log("We found fn it is %s", fn) pixbuf = gtk.gdk.pixbuf_new_from_file(fn) else: log("We didnt find fn we are using %s", file) pixbuf = gtk.gdk.pixbuf_new_from_file(file) if pixbuf: (pixmap, mask) = pixbuf.render_pixmap_and_mask() pixbuf.render_to_drawable(pixmap, gtk.gdk.GC(pixmap), 0, 0, 0, 0, pixbuf.get_width(), pixbuf.get_height(), gtk.gdk.RGB_DITHER_MAX, 0, 0) p.set_from_pixmap(pixmap, mask) return p global splashwindow width = gtk.gdk.screen_width() p = None # If the xserver is running at 800x600 res or higher, use the # 800x600 splash screen. if width >= 800: image = configFileData["Splashscreen"] p = load_image(image) else: p = load_image('pixmaps/first-lowres.png') if p: splashwindow = gtk.Window() splashwindow.set_position(gtk.WIN_POS_CENTER) box = gtk.EventBox() box.modify_bg(gtk.STATE_NORMAL, box.get_style().white) box.add(p) splashwindow.add(box) box.show_all() splashwindow.show_now() gtk.gdk.flush() while gtk.events_pending(): gtk.main_iteration(gtk.FALSE) def splashScreenPop(): global splashwindow if splashwindow: splashwindow.destroy() # # packages.py: package management - mainly package installation # # Erik Troan # Matt Wilson # Michael Fulbright # Jeremy Katz # # Copyright 2001-2003 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # import iutil import isys import rpm import os import timer import time import sys import string import pcmcia import language import fsset import kudzu from flags import flags from product import * from constants import * from syslogd import syslog from hdrlist import PKGTYPE_MANDATORY, PKGTYPE_DEFAULT, DependencyChecker from installmethod import FileCopyException from rhpl.log import log from rhpl.translate import _ import rhpl.arch def queryUpgradeContinue(intf, dir): if dir == DISPATCH_FORWARD: return rc = intf.messageWindow(_("Proceed with upgrade?"), _("The file systems of the Linux installation " "you have chosen to upgrade have already been " "mounted. You cannot go back past this point. " "\n\n") + _( "Would you like to continue with the upgrade?"), type = "yesno") if rc == 0: sys.exit(0) return DISPATCH_FORWARD def doPostAction(id, instPath): id.instClass.postAction(instPath, flags.serial) def firstbootConfiguration(id, instPath): if id.firstboot == FIRSTBOOT_RECONFIG: f = open(instPath + '/etc/reconfigSys', 'w+') f.close() elif id.firstboot == FIRSTBOOT_SKIP: f = open(instPath + '/etc/sysconfig/firstboot', 'w+') f.write('RUN_FIRSTBOOT=NO') f.close() return def writeConfiguration(id, instPath): log("Writing main configuration") if not flags.test: id.write(instPath) def writeKSConfiguration(id, instPath): log("Writing autokickstart file") if not flags.test: fn = instPath + "/root/anaconda-ks.cfg" else: fn = "/tmp/anaconda-ks.cfg" id.writeKS(fn) def writeXConfiguration(id, instPath): testmode = flags.test # comment out to test if testmode: return # end code to comment to test # uncomment to test writing X config in test mode # try: # os.mkdir("/tmp/etc") # except: # pass # try: # os.mkdir("/tmp/etc/X11") # except: # pass # instPath = '/' # end code for test writing if id.xsetup.skipx: return xserver = id.videocard.primaryCard().getXServer() if not xserver: return log("Writing X configuration") if not testmode: fn = instPath if os.access (instPath + "/etc/X11/X", os.R_OK): os.rename (instPath + "/etc/X11/X", instPath + "/etc/X11/X.rpmsave") try: os.unlink (instPath + "/etc/X11/X") except OSError: pass os.symlink ("../../usr/X11R6/bin/" + xserver, instPath + "/etc/X11/X") else: fn = "/tmp/" id.xsetup.write(fn+"/etc/X11", id.mouse, id.keyboard) id.desktop.write(instPath) def readPackages(intf, method, id): if id.grpset: grpset = id.grpset hdrlist = id.grpset.hdrlist doselect = 0 else: grpset = None hdrlist = None doselect = 1 while hdrlist is None: w = intf.waitWindow(_("Reading"), _("Reading package information...")) try: hdrlist = method.readHeaders() except FileCopyException: w.pop() method.unmountCD() intf.messageWindow(_("Error"), _("Unable to read header list. This may be " "due to a missing file or bad media. " "Press to try again.")) continue w.pop() while grpset is None: try: grpset = method.readComps(hdrlist) except FileCopyException: method.unmountCD() intf.messageWindow(_("Error"), _("Unable to read comps file. This may be " "due to a missing file or bad media. " "Press to try again.")) continue while iutil.getArch() == "ia64": try: method.mergeFullHeaders(hdrlist) break except FileCopyException: method.unmountCD() intf.messageWindow(_("Error"), _("Unable to merge header list. This may be " "due to a missing file or bad media. " "Press to try again.")) # this is a crappy hack, but I don't want bug reports from these people if (iutil.getArch() == "i386") and (not grpset.hdrlist.has_key("kernel")): intf.messageWindow(_("Error"), _("You are trying to install on a machine " "which isn't supported by this release of " "%s.") %(productName,), type="custom", custom_icon="error", custom_buttons=[_("_Exit")]) sys.exit(0) id.grpset = grpset if doselect: id.instClass.setGroupSelection(grpset, intf) id.instClass.setPackageSelection(hdrlist, intf) def handleX11Packages(dir, intf, disp, id, instPath): if dir == DISPATCH_BACK: return # skip X setup if it is not being installed if (not id.grpset.hdrlist.has_key('XFree86') or not id.grpset.hdrlist['XFree86'].isSelected()): disp.skipStep("videocard") disp.skipStep("monitor") disp.skipStep("xcustom") disp.skipStep("writexconfig") id.xsetup.skipx = 1 elif disp.stepInSkipList("videocard"): # if X is being installed, but videocard step skipped # need to turn it back on disp.skipStep("videocard", skip=0) disp.skipStep("monitor", skip=0) disp.skipStep("xcustom", skip=0) disp.skipStep("writexconfig", skip=0) id.xsetup.skipx = 0 # set default runlevel based on packages gnomeSelected = (id.grpset.hdrlist.has_key('gnome-session') and id.grpset.hdrlist['gnome-session'].isSelected()) kdeSelected = (id.grpset.hdrlist.has_key('kdebase') and id.grpset.hdrlist['kdebase'].isSelected()) if gnomeSelected: id.desktop.setDefaultDesktop("GNOME") elif kdeSelected: id.desktop.setDefaultDesktop("KDE") if gnomeSelected or kdeSelected: id.desktop.setDefaultRunLevel(5) def getAnacondaTS(instPath = None): if instPath: ts = rpm.TransactionSet(instPath) else: ts = rpm.TransactionSet() ts.setVSFlags(~(rpm.RPMVSF_NORSA|rpm.RPMVSF_NODSA)) ts.setFlags(rpm.RPMTRANS_FLAG_ANACONDA) # set color if needed. FIXME: why isn't this the default :/ if (rhpl.arch.canonArch.startswith("ppc64") or rhpl.arch.canonArch in ("s390x", "sparc64", "x86_64", "ia64")): ts.setColor(3) return ts def checkDependencies(dir, intf, disp, id, instPath): if dir == DISPATCH_BACK: return win = intf.waitWindow(_("Dependency Check"), _("Checking dependencies in packages selected for installation...")) # FIXME: we really don't need to build up a ts more than once # granted, this is better than before still if id.upgrade.get(): ts = getAnacondaTS(instPath) how = "u" else: ts = getAnacondaTS() how = "i" # set the rpm log file to /dev/null so that we don't segfault f = open("/dev/null", "w+") rpm.setLogFile(f) ts.scriptFd = f.fileno() for p in id.grpset.hdrlist.pkgs.values(): if p.isSelected(): ts.addInstall(p.hdr, p.hdr, how) depcheck = DependencyChecker(id.grpset, how) id.dependencies = ts.check(depcheck.callback) win.pop() if depcheck.added and id.handleDeps == CHECK_DEPS: disp.skipStep("dependencies", skip = 0) log("had unresolved dependencies, resolved.") disp.skipStep("dependencies") else: disp.skipStep("dependencies") return # FIXME: I BROKE IT # this is kind of hackish, but makes kickstart happy if id.handleDeps == CHECK_DEPS: pass elif id.handleDeps == IGNORE_DEPS: id.comps.selectDepCause(id.dependencies) id.comps.unselectDeps(id.dependencies) elif id.handleDeps == RESOLVE_DEPS: id.comps.selectDepCause(id.dependencies) id.comps.selectDeps(id.dependencies) class InstallCallback: def cb(self, what, amount, total, h, (param)): # first time here means we should pop the window telling # user to wait until we get here if not self.beenCalled: self.beenCalled = 1 self.initWindow.pop() if (what == rpm.RPMCALLBACK_TRANS_START): # step 6 is the bulk of the transaction set # processing time if amount == 6: self.progressWindow = \ self.progressWindowClass (_("Processing"), _("Preparing to install..."), total) try: self.incr = total / 10 except: pass if (what == rpm.RPMCALLBACK_TRANS_PROGRESS): if self.progressWindow and amount > self.lastprogress + self.incr: self.progressWindow.set (amount) self.lastprogress = amount if (what == rpm.RPMCALLBACK_TRANS_STOP and self.progressWindow): self.progressWindow.pop () if (what == rpm.RPMCALLBACK_INST_OPEN_FILE): # We don't want to start the timer until we get to the first # file. self.pkgTimer.start() self.progress.setPackage(h) self.progress.setPackageScale(0, 1) self.instLog.write (self.modeText % (h[rpm.RPMTAG_NAME], h[rpm.RPMTAG_VERSION], h[rpm.RPMTAG_RELEASE], h[rpm.RPMTAG_ARCH])) self.instLog.flush () self.rpmFD = -1 self.size = h[rpm.RPMTAG_SIZE] while self.rpmFD < 0: try: fn = self.method.getFilename(h, self.pkgTimer) self.rpmFD = os.open(fn, os.O_RDONLY) # Make sure this package seems valid try: hdr = self.ts.hdrFromFdno(self.rpmFD) os.lseek(self.rpmFD, 0, 0) # if we don't have a valid package, throw an error if not hdr: raise SystemError except: try: os.close(self.rpmFD) except: pass self.rpmFD = -1 raise FileCopyException except Exception, e: log("exception was: %s" %(e,)) self.method.unmountCD() self.messageWindow(_("Error"), _("The package %s-%s-%s cannot be opened. This is due " "to a missing file or perhaps a corrupt package. " "If you are installing from CD media this usually " "means the CD media is corrupt, or the CD drive is " "unable to read the media.\n\n" "Press to try again.") % (h['name'], h['version'], h['release'])) fn = self.method.unlinkFilename(fn) return self.rpmFD elif (what == rpm.RPMCALLBACK_INST_PROGRESS): # RPM returns strange values sometimes if amount > total: amount = total if not total or total == 0 or total == "0": total = amount self.progress.setPackageScale(amount, total) elif (what == rpm.RPMCALLBACK_INST_CLOSE_FILE): os.close (self.rpmFD) self.progress.completePackage(h, self.pkgTimer) self.progre      !"#ss.processEvents() elif ((what == rpm.RPMCALLBACK_UNPACK_ERROR) or (what == rpm.RPMCALLBACK_CPIO_ERROR)): # we may want to make this error more fine-grained at some # point pkg = "%s-%s-%s" % (h[rpm.RPMTAG_NAME], h[rpm.RPMTAG_VERSION], h[rpm.RPMTAG_RELEASE]) self.messageWindow(_("Error Installing Package"), _("There was an error installing %s. This " "can indicate media failure, lack of disk " "space, and/or hardware problems. This is " "a fatal error and your install will be " "aborted. Please verify your media and try " "your install again.\n\n" "Press the OK button to reboot " "your system.") % (pkg,)) sys.exit(0) else: pass self.progress.processEvents() def __init__(self, messageWindow, progress, pkgTimer, method, progressWindowClass, instLog, modeText, ts): self.messageWindow = messageWindow self.progress = progress self.pkgTimer = pkgTimer self.method = method self.progressWindowClass = progressWindowClass self.progressWindow = None self.lastprogress = 0 self.incr = 20 self.instLog = instLog self.modeText = modeText self.beenCalled = 0 self.initWindow = None self.ts = ts def sortPackages(first, second): # install packages in cd order (cd tag is 1000002) one = None two = None if first[1000003] != None: one = first[1000003] if second[1000003] != None: two = second[1000003] if one == None or two == None: one = 0 two = 0 if first[1000002] != None: one = first[1000002] if second[1000002] != None: two = second[1000002] if one < two: return -1 elif one > two: return 1 elif (string.lower(first[rpm.RPMTAG_NAME]) < string.lower(second[rpm.RPMTAG_NAME])): return -1 elif (string.lower(first[rpm.RPMTAG_NAME]) > string.lower(second[rpm.RPMTAG_NAME])): return 1 return 0 class rpmErrorClass: def cb(self): self.f.write (rpm.errorString () + "\n") def __init__(self, f): self.f = f def doMigrateFilesystems(dir, thefsset, diskset, upgrade, instPath): if dir == DISPATCH_BACK: return DISPATCH_NOOP if thefsset.haveMigratedFilesystems(): return DISPATCH_NOOP thefsset.migrateFilesystems (instPath) def turnOnFilesystems(dir, thefsset, diskset, partitions, upgrade, instPath): if dir == DISPATCH_BACK: log("unmounting filesystems") thefsset.umountFilesystems(instPath) return if flags.setupFilesystems: if not upgrade.get(): partitions.doMetaDeletes(diskset) thefsset.setActive(diskset) if not thefsset.isActive(): diskset.savePartitions () thefsset.checkBadblocks(instPath) thefsset.createLogicalVolumes(instPath) thefsset.formatSwap(instPath) thefsset.turnOnSwap(instPath) thefsset.makeFilesystems (instPath) log("mounting filesystems") thefsset.mountFilesystems (instPath) def setupTimezone(timezone, upgrade, instPath, dir): # we don't need this on an upgrade or going backwards if upgrade.get() or (dir == DISPATCH_BACK): return os.environ["TZ"] = timezone.tz tzfile = "/usr/share/zoneinfo/" + timezone.tz if not os.access(tzfile, os.R_OK): log("unable to set timezone") else: try: iutil.copyFile(tzfile, "/etc/localtime") except OSError, (errno, msg): log("Error copying timezone (from %s): %s" %(tzfile, msg)) if iutil.getArch() == "s390": return args = [ "/usr/sbin/hwclock", "--hctosys" ] if timezone.utc: args.append("-u") elif timezone.arc: args.append("-a") try: iutil.execWithRedirect(args[0], args, stdin = None, stdout = "/dev/tty5", stderr = "/dev/tty5") except RuntimeError: log("Failed to set clock") def doPreInstall(method, id, intf, instPath, dir): if dir == DISPATCH_BACK: return arch = iutil.getArch () # this is a crappy hack, but I don't want bug reports from these people if (arch == "i386") and (not id.grpset.hdrlist.has_key("kernel")): intf.messageWindow(_("Error"), _("You are trying to install on a machine " "which isn't supported by this release of " "%s.") %(productName,), type="custom", custom_icon="error", custom_buttons=[_("_Exit")]) sys.exit(0) # shorthand upgrade = id.upgrade.get() def select(hdrlist, name): if hdrlist.has_key(name): hdrlist[name].select(isManual = 1) if not upgrade: # this is NICE and LATE. It lets kickstart/server/workstation # installs detect this properly if arch == "s390": if (string.find(os.uname()[2], "tape") > -1): select(id.grpset.hdrlist, 'kernel-tape') elif arch == "ppc" and iutil.getPPCMachine() == "pSeries": select(id.grpset.hdrlist, 'kernel-pseries') elif arch == "ppc" and iutil.getPPCMachine() == "iSeries": select(id.grpset.hdrlist, "kernel-iseries") if (isys.smpAvailable() or isys.htavailable()) and not rhpl.arch.canonArch == "ia32e": select(id.grpset.hdrlist, 'kernel-smp') if id.grpset.hdrlist['kernel-unsupported'].isSelected(): select(id.grpset.hdrlist, 'kernel-smp-unsupported') ## Hook up our kernel-module-XXX packages - jaroslaw.polok@cern.ch if id.grpset.hdrlist['kernel-module-openafs-2.4.21-32.0.1.EL'].isSelected(): select(id.grpset.hdrlist, 'kernel-module-openafs-2.4.21-32.0.1.ELsmp') if iutil.needsEnterpriseKernel(): select(id.grpset.hdrlist, "kernel-bigmem") if isys.summitavailable(): select(id.grpset.hdrlist, "kernel-summit") # we *always* need a kernel installed select(id.grpset.hdrlist, 'kernel') # if NIS is configured, install ypbind and dependencies: if id.auth.useNIS: select(id.grpset.hdrlist, 'ypbind') select(id.grpset.hdrlist, 'yp-tools') select(id.grpset.hdrlist, 'portmap') if id.auth.useLdap: select(id.grpset.hdrlist, 'nss_ldap') select(id.grpset.hdrlist, 'openldap') select(id.grpset.hdrlist, 'perl') if id.auth.useKrb5: select(id.grpset.hdrlist, 'pam_krb5') select(id.grpset.hdrlist, 'krb5-workstation') select(id.grpset.hdrlist, 'krbafs') select(id.grpset.hdrlist, 'krb5-libs') if id.auth.useSamba: select(id.grpset.hdrlist, 'pam_smb') if iutil.getArch() == "i386" and id.bootloader.useGrubVal == 0: select(id.grpset.hdrlist, 'lilo') elif iutil.getArch() == "i386" and id.bootloader.useGrubVal == 1: select(id.grpset.hdrlist, 'grub') elif iutil.getArch() == "s390": select(id.grpset.hdrlist, 's390utils') elif iutil.getArch() == "ppc": select(id.grpset.hdrlist, 'yaboot') elif iutil.getArch() == "ia64": select(id.grpset.hdrlist, 'elilo') if pcmcia.pcicType(): select(id.grpset.hdrlist, 'kernel-pcmcia-cs') if flags.test: return # make sure that all comps that include other comps are # selected (i.e. - recurse down the selected comps and turn # on the children while 1: try: method.mergeFullHeaders(id.grpset.hdrlist) except FileCopyException: method.unmountCD() intf.messageWindow(_("Error"), _("Unable to merge header list. This may be " "due to a missing file or bad media. " "Press to try again.")) else: break if upgrade: # An old mtab can cause confusion (esp if loop devices are # in it) f = open(instPath + "/etc/mtab", "w+") f.close() if method.systemMounted (id.fsset, instPath): id.fsset.umountFilesystems(instPath) return DISPATCH_BACK for i in ( '/var', '/var/lib', '/var/lib/rpm', '/tmp', '/dev', '/etc', '/etc/sysconfig', '/etc/sysconfig/network-scripts', '/etc/X11', '/root', '/var/tmp', '/etc/rpm' ): try: os.mkdir(instPath + i) except os.error, (errno, msg): pass # log("Error making directory %s: %s" % (i, msg)) if flags.setupFilesystems: # setup /etc/rpm/platform for the post-install environment iutil.writeRpmPlatform(instPath) try: # FIXME: making the /var/lib/rpm symlink here is a hack to # workaround db->close() errors from rpm iutil.mkdirChain("/var/lib") iutil.mkdirChain("/var/spool") for path in ("/var/tmp", "/var/lib/rpm","/var/spool/anaconda-updates"): if os.path.exists(path) and not os.path.islink(path): iutil.rmrf(path) if not os.path.islink(path): os.symlink("/mnt/sysimage/%s" %(path,), "%s" %(path,)) else: log("%s already exists as a symlink to %s" %(path, os.readlink(path),)) except Exception, e: # how this could happen isn't entirely clear; log it in case # it does and causes problems later log("error creating symlink, continuing anyway: %s" %(e,)) # try to copy the comps package. if it doesn't work, don't worry about it if (product.productDefault == product.productSite) : tmparea = productDefault + "/base/comps.rpm" else: tmparea = productSite + "/base/comps.rpm" try: id.compspkg = method.copyFileToTemp(tmparea) except: log("Unable to copy comps package") id.compspkg = None # write out the fstab if not upgrade: id.fsset.write(instPath) # rootpath mode doesn't have this file around if os.access("/tmp/modules.conf", os.R_OK): iutil.copyFile("/tmp/modules.conf", instPath + "/etc/modules.conf") # make a /etc/mtab so mkinitrd can handle certain hw (usb) correctly f = open(instPath + "/etc/mtab", "w+") f.write(id.fsset.mtab()) f.close() # we need to cache packages that are "updates" if we're doing a cd # install. we write them to under /var since that's where up2date # will end up putting updates try: method.cacheUpdates(instPath, id.grpset.hdrlist, intf) except Exception, e: log("Problem caching updates: %s" %(e,)) # delay writing migrate adjusted fstab till later, in case # rpm transaction set determines they don't have enough space to upgrade # else: # id.fsset.migratewrite(instPath) def doInstall(method, id, intf, instPath): if flags.test: return # set up dependency white outs import whiteout upgrade = id.upgrade.get() ts = getAnacondaTS(instPath) total = 0 totalSize = 0 if upgrade: how = "u" else: how = "i" rpm.addMacro("__dbi_htconfig", "hash nofsync %{__dbi_other} %{__dbi_perms}") if id.excludeDocs: rpm.addMacro("_excludedocs", "1") l = [] for p in id.grpset.hdrlist.values(): if p.isSelected(): l.append(p) l.sort(sortPackages) progress = intf.progressWindow(_("Processing"), _("Preparing RPM transaction..."), len(l)) # this is kind of a hack, but has to be done so we can have a chance # with broken triggers if upgrade and len(id.upgradeRemove) > 0: # simple rpm callback since erasure doesn't need anything def install_callback(what, bytes, total, h, user): pass for pkg in id.upgradeRemove: ts.addErase(pkg) # if we hit problems, it's not like there's anything we can # do about it ts.run(install_callback, 0) # new transaction set ts.closeDB() del ts ts = getAnacondaTS(instPath) # we don't want to try to remove things more than once (#84221) id.upgradeRemove = [] i = 0 updcount = 0 updintv = len(l) / 25 for p in l: ts.addInstall(p.hdr, p.hdr, how) total = total + 1 totalSize = totalSize + (p[rpm.RPMTAG_SIZE] / 1024) i = i + 1 # HACK - dont overload progress bar with useless requests updcount = updcount + 1 if updcount > updintv: progress.set(i) updcount = 0 progress.pop() depcheck = DependencyChecker(id.grpset) if not id.grpset.hdrlist.preordered(): log ("WARNING: not all packages in hdlist had order tag") # have to call ts.check before ts.order() to set up the alIndex ts.check(depcheck.callback) ts.order() else: ts.check(depcheck.callback) if upgrade: logname = '/root/upgrade.log' else: logname = '/root/install.log' instLogName = instPath + logname try: iutil.rmrf (instLogName) except OSError: pass instLog = open(instLogName, "w+") syslogname = "%s%s.syslog" % (instPath, logname) try: iutil.rmrf (syslogname) except OSError: pass syslog.start (instPath, syslogname) if id.compspkg is not None: num = i + 1 else: num = i if upgrade: instLog.write(_("Upgrading %s packages\n\n") % (num,)) else: instLog.write(_("Installing %s packages\n\n") % (num,)) ts.scriptFd = instLog.fileno () rpm.setLogFile(instLog) # the transaction set dup()s the file descriptor and will close the # dup'd when we go out of scope if upgrade: modeText = _("Upgrading %s-%s-%s.%s.\n") else: modeText = _("Installing %s-%s-%s.%s.\n") errors = rpmErrorClass(instLog) pkgTimer = timer.Timer(start = 0) id.instProgress.setSizes(total, totalSize) id.instProgress.processEvents() cb = InstallCallback(intf.messageWindow, id.instProgress, pkgTimer, method, intf.progressWindow, instLog, modeText, ts) # write out migrate adjusted fstab so kernel RPM can get initrd right if upgrade: id.fsset.migratewrite(instPath) if id.upgradeDeps: instLog.write(_("\n\nThe following packages were automatically\n" "selected to be installed:" "\n" "%s" "\n\n") % (id.upgradeDeps,)) cb.initWindow = intf.waitWindow(_("Install Starting"), _("Starting install process, this may take several minutes...")) ts.setProbFilter(~rpm.RPMPROB_FILTER_DISKSPACE) problems = ts.run(cb.cb, 0) if problems: # restore old fstab if we did anything for migrating if upgrade: id.fsset.restoreMigratedFstab(instPath) spaceneeded = {} nodeneeded = {} size = 12 for (descr, (type, mount, need)) in problems: log("(%s, (%s, %s, %s))" %(descr, type, mount, need)) if mount and mount.startswith(instPath): mount = mount[len(instPath):] if not mount: mount = '/' if type == rpm.RPMPROB_DISKSPACE: if spaceneeded.has_key (mount) and spaceneeded[mount] < need: spaceneeded[mount] = need else: spaceneeded[mount] = need elif type == nodeprob: if nodeneeded.has_key (mount) and nodeneeded[mount] < need: nodeneeded[mount] = need else: nodeneeded[mount] = need else: if descr is None: descr = "no description" log ("WARNING: unhandled problem returned from " "transaction set type %d (%s)", type, descr) probs = "" if spaceneeded: probs = probs + _("You don't appear to have enough disk space " "to install the packages you've selected. " "You need more space on the following " "file systems:\n\n") probs = probs + ("%-15s %s\n") % (_("Mount Point"), _("Space Needed")) for (mount, need) in spaceneeded.items (): log("(%s, %s)" %(mount, need)) if need > (1024*1024): need = (need + 1024 * 1024 - 1) / (1024 * 1024) suffix = "M" else: need = (need + 1023) / 1024 suffix = "k" prob = "%-15s %d %c\n" % (mount, need, suffix) probs = probs + prob if nodeneeded: if probs: probs = probs + '\n' probs = probs + _("You don't appear to have enough file nodes " "to install the packages you've selected. " "You need more file nodes on the following " "file systems:\n\n") probs = probs + ("%-15s %s\n") % (_("Mount Point"), _("Nodes Needed")) for (mount, need) in nodeneeded.items (): prob = "%-15s %d\n" % (mount, need) probs = probs + prob if len(probs) == 0: probs = ("ERROR: NO! An unexpected problem has occurred with " "your transaction set. Please see tty3 for more " "information") intf.messageWindow (_("Disk Space"), probs) ts.closeDB() del ts instLog.close() syslog.stop() method.systemUnmounted () return DISPATCH_BACK # This should close the RPM database so that you can # do RPM ops in the chroot in a %post ks script ts.closeDB() del ts # make sure the window gets popped (#82862) if not cb.beenCalled: cb.initWindow.pop() method.filesDone () # rpm environment files go bye-bye for file in ["__db.001", "__db.002", "__db.003"]: try: os.unlink("%s/var/lib/rpm/%s" %(instPath, file)) except Exception, e: log("failed to unlink /var/lib/rpm/%s: %s" %(file,e)) # FIXME: remove the /var/lib/rpm symlink that keeps us from having # db->close error messages shown. I don't really like this though :( try: os.unlink("/var/lib/rpm") except Exception, e: log("failed to unlink /var/lib/rpm: %s" %(e,)) if upgrade: instLog.write(_("\n\nThe following packages were available in " "this version but NOT upgraded:\n")) lines = [] for p in id.grpset.hdrlist.values(): if not p.isSelected(): lines.append("%s-%s-%s.%s.rpm\n" % (p.hdr[rpm.RPMTAG_NAME], p.hdr[rpm.RPMTAG_VERSION], p.hdr[rpm.RPMTAG_RELEASE], p.hdr[rpm.RPMTAG_ARCH])) lines.sort() for line in lines: instLog.write(line) instLog.close () if id.grpset.hdrlist.has_key("rhgb") and id.grpset.hdrlist["rhgb"].isSelected() and os.access("/tmp/product/.userhgb", os.R_OK): log("rhgb installed, adding to boot loader config") id.bootloader.args.append("rhgb quiet") id.instProgress = None def doPostInstall(method, id, intf, instPath): if flags.test: return w = intf.progressWindow(_("Post Install"), _("Performing post install configuration..."), 6) upgrade = id.upgrade.get() arch = iutil.getArch () if upgrade: logname = '/root/upgrade.log' else: logname = '/root/install.log' instLogName = instPath + logname instLog = open(instLogName, "a") try: if not upgrade: w.set(1) copyExtraModules(instPath, id.grpset, id.extraModules) w.set(2) # pcmcia is supported only on i386 at the moment if arch == "i386": pcmcia.createPcmciaConfig( instPath + "/etc/sysconfig/pcmcia") # we need to write out the network bits before kudzu runs # to avoid getting devices in the wrong order (#102276) id.network.write(instPath) w.set(3) # blah. If we're on a serial mouse, and we have X, we need to # close the mouse device, then run kudzu, then open it again. # turn it off mousedev = None # XXX currently Bad Things (X async reply) happen when doing # Mouse Magic on Sparc (Mach64, specificly) # The s390 doesn't even have a mouse! if os.environ.get('DISPLAY') == ':1' and arch != 'sparc': try: import xmouse mousedev = xmouse.get()[0] except RuntimeError: pass if mousedev: try: os.rename (mousedev, "/dev/disablemouse") except OSError: pass try: xmouse.reopen() except RuntimeError: pass if arch != "s390": # we need to unmount usbdevfs before mounting it usbWasMounted = iutil.isUSBDevFSMounted() if usbWasMounted: isys.umount('/proc/bus/usb', removeDir = 0) # see if unmount suceeded, if not pretent it isnt mounted # because we're screwed anywyas if system is going to # lock up if iutil.isUSBDevFSMounted(): usbWasMounted = 0 unmountUSB = 0 try: isys.mount('/usbdevfs', instPath+'/proc/bus/usb', 'usbdevfs') unmountUSB = 1 except: log("Mount of /proc/bus/usb in chroot failed") pass argv = [ "/usr/sbin/kudzu", "-q" ] if id.grpset.hdrlist.has_key("kernel"): ver = "%s-%s" %(id.grpset.hdrlist["kernel"][rpm.RPMTAG_VERSION], id.grpset.hdrlist["kernel"][rpm.RPMTAG_RELEASE]) argv.extend(["-k", ver]) devnull = os.open("/dev/null", os.O_RDWR) iutil.execWithRedirect(argv[0], argv, root = instPath, stdout = devnull) # turn it back on if mousedev: try: os.rename ("/dev/disablemouse", mousedev) except OSError: pass try: xmouse.reopen() except RuntimeError: pass if unmountUSB: try: isys.umount(instPath + '/proc/bus/usb', removeDir = 0) except SystemError: # if we fail to unmount, then we should just not # try to remount it. this protects us from random # suckage usbWasMounted = 0 if usbWasMounted: isys.mount('/usbdevfs', '/proc/bus/usb', 'usbdevfs') w.set(4) if upgrade and id.dbpath is not None: # remove the old rpmdb try: iutil.rmrf (id.dbpath) except OSError: pass if upgrade: # needed for prior systems which were not xinetd based migrateXinetd(instPath, instLogName) w.set(5) # FIXME: hack to install the comps package if (id.compspkg is not None and os.access(id.compspkg, os.R_OK)): log("found the comps package") try: # ugly hack path = id.compspkg.split("/mnt/sysimage")[1] args = ["/bin/rpm", "-Uvh", path] rc = iutil.execWithRedirect(args[0], args, stdout = "/dev/tty5", stderr = "/dev/tty5", root = instPath) ts = rpm.TransactionSet() ts.setVSFlags(~(rpm.RPMVSF_NORSA|rpm.RPMVSF_NODSA)) ts.closeDB() fd = os.open(id.compspkg, os.O_RDONLY) h = ts.hdrFromFdno(fd) os.close(fd) if upgrade: text = _("Upgrading %s-%s-%s.%s.\n") else: text = _("Installing %s-%s-%s.%s.\n") instLog.write(text % (h['name'], h['version'], h['release'], h['arch'])) os.unlink(id.compspkg) del ts except Exception, e: log("comps.rpm failed to install: %s" %(e,)) try: os.unlink(id.compspkg) except: pass else: log("no comps package found") w.set(6) finally: pass # XXX hack - we should really write a proper /etc/lvmtab. but for now # just create the lvmtab if they have /sbin/vgscan and some VGs if (os.access(instPath + "/sbin/vgscan", os.X_OK) and os.access(instPath + "/proc/lvm", os.R_OK) and len(os.listdir("/proc/lvm/VGs")) > 0): rc = iutil.execWithRedirect("/sbin/vgscan", ["vgscan", "-v"], stdout = "/dev/tty5", stderr = "/dev/tty5", root = instPath, searchPath = 1) # write out info on install method used try: if id.methodstr is not None: if os.access (instPath + "/etc/sysconfig/installinfo", os.R_OK): os.rename (instPath + "/etc/sysconfig/installinfo", instPath + "/etc/sysconfig/installinfo.rpmsave") f = open(instPath + "/etc/sysconfig/installinfo", "w+") f.write("INSTALLMETHOD=%s\n" % (string.split(id.methodstr, ':')[0],)) try: ii = open("/tmp/isoinfo", "r") il = ii.readlines() ii.close() for line in il: f.write(line) except: pass f.close() else: log("methodstr not set for some reason") except: log("Failed to write out installinfo") w.pop () sys.stdout.flush() syslog.stop() def migrateXinetd(instPath, instLog): if not os.access (instPath + "/usr/sbin/inetdconvert", os.X_OK): return if not os.access (instPath + "/etc/inetd.conf.rpmsave", os.R_OK): return argv = [ "/usr/sbin/inetdconvert", "--convertremaining", "--inetdfile", "/etc/inetd.conf.rpmsave" ] logfile = os.open (instLog, os.O_APPEND) iutil.execWithRedirect(argv[0], argv, root = instPath, stdout = logfile, stderr = logfile) os.close(logfile) def copyExtraModules(instPath, grpset, extraModules): kernelVersions = grpset.kernelVersionList() foundModule = 0 try: f = open("/etc/arch") arch = f.readline().strip() del f except IOError: arch = os.uname()[2] for (path, name) in extraModules: if not path: path = "/modules.cgz" pattern = "" names = "" for (n, tag) in kernelVersions: if tag == "up": pkg = "kernel" else: pkg = "kernel-%s" %(tag,) arch = grpset.hdrlist[pkg][rpm.RPMTAG_ARCH] # version 1 path pattern = pattern + " %s/%s/%s.o " % (n, arch, name) # version 0 path pattern = pattern + " %s/%s.o " % (n, name) names = names + " %s.o" % (name,) command = ("cd %s/lib/modules; gunzip < %s | " "%s/bin/cpio --quiet -iumd %s" % (instPath, path, instPath, pattern)) log("running: '%s'" % (command, )) os.system(command) for (n, tag) in kernelVersions: if tag == "up": pkg = "kernel" else: pkg = "kernel-%s" %(tag,) toDir = "%s/lib/modules/%s/updates" % \ (instPath, n) to = "%s/%s.o" % (toDir, name) if (os.path.isdir("%s/lib/modules/%s" %(instPath, n)) and not os.path.isdir("%s/lib/modules/%s/updates" %(instPath, n))): os.mkdir("%s/lib/modules/%s/updates" %(instPath, n)) if not os.path.isdir(toDir): continue arch = grpset.hdrlist[pkg][rpm.RPMTAG_ARCH] for p in ("%s/%s.o" %(arch, name), "%s.o" %(name,)): fromFile = "%s/lib/modules/%s/%s" % (instPath, n, p) if (os.access(fromFile, os.R_OK)): log("moving %s to %s" % (fromFile, to)) os.rename(fromFile, to) # the file might not have been owned by root in the cgz os.chown(to, 0, 0) foundModule = 1 else: log("missing DD module %s (this may be okay)" % fromFile) if foundModule == 1: for (n, tag) in kernelVersions: recreateInitrd(n, instPath) #Recreate initrd for use when driver disks add modules def recreateInitrd (kernelTag, instRoot): log("recreating initrd for %s" % (kernelTag,)) iutil.execWithRedirect("/sbin/new-kernel-pkg", [ "/sbin/new-kernel-pkg", "--mkinitrd", "--depmod", "--install", kernelTag ], stdout = None, stderr = None, searchPath = 1, root = instRoot) # XXX Deprecated. Is this ever called anymore? def depmodModules(comps, instPath): kernelVersions = comps.kernelVersionList() for (version, tag) in kernelVersions: iutil.execWithRedirect ("/sbin/depmod", [ "/sbin/depmod", "-a", version, "-F", "/boot/System.map-" + version ], root = instPath, stderr = '/dev/null') def betaNagScreen(intf, dir): publicBetas = { "Red Hat Linux": "Red Hat Linux Public Beta", "Red Hat Enterprise Linux": "Red Hat Enterprise Linux Public Beta" } if dir == DISPATCH_BACK: return DISPATCH_NOOP fileagainst = None for (key, val) in publicBetas.items(): if productName.startswith(key): fileagainst = val if fileagainst is None: fileagainst = "%s Beta" %(productName,) while 1: rc = intf.messageWindow( _("Warning! This is a beta!"), _("Thank you for downloading this " "%s Beta release.\n\n" "This is not a final " "release and is not intended for use " "on production systems. The purpose of " "this release is to collect feedback " "from testers, and it is not suitable " "for day to day usage.\n\n" "To report feedback, please visit:\n\n" " http://bugzilla.redhat.com/bugzilla\n\n" "and file a report against '%s'.\n" %(productName, fileagainst)), type="custom", custom_icon="warning", custom_buttons=[_("_Exit"), _("_Install BETA")]) if not rc: rc = intf.messageWindow( _("Rebooting System"), _("Your system will now be rebooted..."), type="custom", custom_icon="warning", custom_buttons=[_("_Back"), _("_Reboot")]) if rc: sys.exit(0) else: break # FIXME: this is a kind of poor way to do this, but it will work for now def selectLanguageSupportGroups(grpset, langSupport): sup = langSupport.supported if len(sup) == 0: sup = langSupport.getAllSupported() for group in grpset.groups.values(): xmlgrp = grpset.compsxml.groups[group.basename] langs = [] for name in sup: try: lang = langSupport.langInfoByName[name][0] langs.extend(language.expandLangs(lang)) except: continue if group.langonly is not None and group.langonly in langs: group.select() for package in xmlgrp.pkgConditionals.keys(): req = xmlgrp.pkgConditionals[package] if not grpset.hdrlist.has_key(package): log("Missing %s which is in a langsupport conditional" %(package,)) continue # add to the deps in the dependencies structure for the # package. this should take care of whenever we're # selected grpset.hdrlist[req].addDeps([package], main = 0) if grpset.hdrlist[req].isSelected(): grpset.hdrlist[package].select() sys.stdout.flush() grpset.hdrlist[package].usecount += grpset.hdrlist[req].usecount - 1 group.selectDeps([package], uses = grpset.hdrlist[req].usecount) # # product.py: product identification string # # Copyright 2003 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import os if os.access("/tmp/product/.buildstamp", os.R_OK): path = "/tmp/product/.buildstamp" elif os.access("/.buildstamp", os.R_OK): path = "/.buildstamp" else: path = None if path is None: productName = "anaconda" productVersion = "bluesky" productSite = "SL" productDefault = "SL" else: f = open(path, "r") lines = f.readlines() if len(lines) < 4: productName = "SL" productVersion = "3.0.1" productDefault = "SL" productSite = "SL" productSiteDir = "sites" else: productName = lines[1][:-1] productVersion = lines[2][:-1] productDefault = lines[3][:-1] productSite = lines[4][:-1] productSiteDir = lines[5][:-1] # # urlinstall.py - URL based install source method # # Erik Troan # # Copyright 1999-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # from hdrlist import groupSetFromCompsFile, HeaderList from installmethod import InstallMethod, FileCopyException import os import rpm import time import urllib2 import string import struct import socket # we import these explicitly because urllib loads them dynamically, which # stinks -- and we need to have them imported for the --traceonly option import ftplib import httplib import StringIO from rhpl.log import log import product FILENAME = 1000000 DISCNUM = 1000002 def urlretrieve(location, file): """Downloads from location and saves to file.""" try: url = urllib2.urlopen(location) except urllib2.HTTPError, e: raise IOError(e.code, e.msg) except urllib2.URLError, e: raise IOError(-1, e.reason) f = open(file, 'w+') f.write(url.read()) f.close() url.close() class UrlInstallMethod(InstallMethod): def readCompsViaMethod(self, hdlist): fname = self.findBestFileMatch(None, 'comps.xml') # if not local then assume its on host if fname is None: if (product.productDefault == product.productSite) : fname = self.baseUrl + "/" + product.productDefault + "/base/comps.xml" else: fname = self.baseUrl + "/" + product.productSite + "/base/comps.xml" log("Comps not in update dirs, using %s",fname) return groupSetFromCompsFile(fname, hdlist) def getFilename(self, h, timer): tmppath = self.getTempPath() # h doubles as a filename -- gross if type("/") == type(h): fullPath = self.baseUrl + "/" + h else: if self.multiDiscs: base = "%s/disc%d" % (self.pkgUrl, h[DISCNUM]) else: base = self.pkgUrl if self.isUpdateRPM(h): # path = "/RedHat/Updates/" path = "/" + product.productSite + "/Updates/" else: # path = "/RedHat/RPMS/" path = "/" + product.productDefault + "/RPMS/" fullPath = base + path + h[FILENAME] file = tmppath + os.path.basename(fullPath) tries = 0 while tries < 5: try: urlretrieve(fullPath, file) except IOError, (errnum, msg): log("IOError %s occurred getting %s: %s" %(errnum, fullPath, str(msg))) time.sleep(5) else: break tries = tries + 1 if tries >= 5: raise FileCopyException return file def copyFileToTemp(self, filename): tmppath = self.getTempPath() if self.multiDiscs: base = "%s/disc1" % (self.pkgUrl,) else: base = self.pkgUrl fullPath = base + "/" + filename file = tmppath + "/" + os.path.basename(fullPath) tries = 0 while tries < 5: try: urlretrieve(fullPath, file) except IOError, (errnum, msg): log("IOError %s occurred getting %s: %s", errnum, fullPath, str(msg)) time.sleep(5) else: break tries = tries + 1 if tries >= 5: raise FileCopyException return file def unlinkFilename(self, fullName): os.remove(fullName) def readHeaders(self): tries = 0 while tries < 5: if (product.productDefault == product.productSite) : hdurl = self.baseUrl + "/" + product.productDefault + "/base/hdlist" else: log("product.productSiteDir is %s", product.productSiteDir) log("product.productSite is %s ", product.productSite) hdurl = self.baseUrl + "/" + product.productSite + "/base/hdlist" try: url = urllib2.urlopen(hdurl) except urllib2.HTTPError, e: log("HTTPError: %s occurred getting %s", hdurl, e) except urllib2.URLError, e: log("URLError: %s occurred getting %s", hdurl, e) except IOError, (errnum, msg): log("IOError %s occurred getting %s: %s", errnum, hdurl, msg) else: break time.sleep(5) tries = tries + 1 if tries >= 5: raise FileCopyException raw = url.read(16) if raw is None or len(raw) < 1: raise TypeError, "header list is empty!" hl = [] while (raw and len(raw)>0): info = struct.unpack("iiii", raw) magic1 = socket.ntohl(info[0]) & 0xffffffff if (magic1 != 0x8eade801 or info[1]): raise TypeError, "bad magic in header" il = socket.ntohl(info[2]) dl = socket.ntohl(info[3]) totalSize = il * 16 + dl; hdrString = raw[8:] + url.read(totalSize) hdr = rpm.headerLoad(hdrString) hl.append(hdr) raw = url.read(16) return HeaderList(hl) def mergeFullHeaders(self, hdlist): if (product.productDefault == product.productSite) : fn = self.getFilename("/" + product.productDefault + "/base/hdlist2", None) else: fn = self.getFilename("/" + product.productSite + "/base/hdlist2", None) hdlist.mergeFullHeaders(fn) os.unlink(fn) def __init__(self, url, rootPath): InstallMethod.__init__(self, rootPath) if url.startswith("ftp"): isFtp = 1 else: isFtp = 0 # build up the url. this is tricky so that we can replace # the first instance of // with /%3F to do absolute URLs right i = string.index(url, '://') + 3 self.baseUrl = url[:i] rem = url[i:] i = string.index(rem, '/') + 1 self.baseUrl = self.baseUrl + rem[:i] rem = rem[i:] # encoding fun so that we can handle absolute paths if rem.startswith("/") and isFtp: rem = "%2F" + rem[1:] self.baseUrl = self.baseUrl + rem if self.baseUrl[-1] == "/": self.baseUrl = self.baseUrl[:-1] # self.baseUrl points at the path which contains the 'RedHat' # directory with the hdlist. if self.baseUrl[-6:] == "/disc1": self.multiDiscs = 1 self.pkgUrl = self.baseUrl[:-6] else: self.multiDiscs = 0 self.pkgUrl = self.baseUrl # # text.py - text mode frontend to anaconda # # Erik Troan # Matt Wilson # # Copyright 1999-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # from snack import * import sys import os import isys import iutil import time import signal import parted import string import kudzu from language import expandLangs from flags import flags from constants_text import * from constants import * from rhpl.log import log from rhpl.translate import _, cat, N_ stepToClasses = { "language" : ("language_text", "LanguageWindow"), "keyboard" : ("keyboard_text", "KeyboardWindow"), "mouse" : ("mouse_text", ("MouseWindow", "MouseDeviceWindow")), "welcome" : ("welcome_text", "WelcomeWindow"), "installtype" : ("installpath_text", "InstallPathWindow"), "autopartition" : ("partition_text", "AutoPartitionWindow"), "custom-upgrade" : ("upgrade_text", "UpgradeExamineWindow"), "addswap" : ("upgrade_text", "UpgradeSwapWindow"), "upgrademigratefs" : ("upgrade_text", "UpgradeMigrateFSWindow"), "fdisk" : ("fdisk_text", "fdiskPartitionWindow"), "partitionmethod" : ("partmethod_text", ("PartitionMethod")), "partition": ("partition_text", ("PartitionWindow")), "findinstall" : ("upgrade_text", "UpgradeExamineWindow"), "addswap" : ("upgrade_text", "UpgradeSwapWindow"), "upgbootloader": ("upgrade_bootloader_text", "UpgradeBootloaderWindow"), "bootloader" : ("bootloader_text", ("BootloaderChoiceWindow", "BootloaderAppendWindow", "BootloaderPasswordWindow")), "bootloaderadvanced" : ("bootloader_text", ("BootloaderImagesWindow", "BootloaderLocationWindow")), "network" : ("network_text", ("NetworkDeviceWindow", "NetworkGlobalWindow", "HostnameWindow")), "firewall" : ("firewall_text", "FirewallWindow"), "languagesupport" : ("language_text", ("LanguageSupportWindow", "LanguageDefaultWindow")), "timezone" : ("timezone_text", "TimezoneWindow"), "accounts" : ("userauth_text", "RootPasswordWindow"), "authentication" : ("userauth_text", ("AuthConfigWindow")), "desktopchoice": ("desktop_choice_text", "DesktopChoiceWindow"), "package-selection" : ("packages_text", "PackageGroupWindow"), "indivpackage" : ("packages_text", ("IndividualPackageWindow")), "dependencies" : ("packages_text", "PackageDepWindow"), "videocard" : ("xconfig_text", "XConfigWindowCard"), "monitor" : ("xconfig_text", "MonitorWindow"), "xcustom" : ("xconfig_text", "XCustomWindow"), "confirminstall" : ("confirm_text", "BeginInstallWindow"), "confirmupgrade" : ("confirm_text", "BeginUpgradeWindow"), "install" : ("progress_text", "setupForInstall"), "bootdisk" : ("bootdisk_text", ("BootDiskWindow")), "complete" : ("complete_text", "FinishedWindow"), } if iutil.getArch() == 'sparc': stepToClasses["bootloader"] = ("silo_text", ("SiloAppendWindow", "SiloWindow" "SiloImagesWindow")) if iutil.getArch() == 's390': stepToClasses["bootloader"] = ("zipl_text", ( "ZiplWindow")) class InstallWindow: def __call__ (self, screen): raise RuntimeError, "Unimplemented screen" class WaitWindow: def pop(self): self.screen.popWindow() self.screen.refresh() def __init__(self, screen, title, text): self.screen = screen width = 40 if (len(text) < width): width = len(text) t = TextboxReflowed(width, text) g = GridForm(self.screen, title, 1, 1) g.add(t, 0, 0) g.draw() self.screen.refresh() class OkCancelWindow: def getrc(self): return self.rc def __init__(self, screen, title, text): rc = ButtonChoiceWindow(screen, title, text, buttons=[TEXT_OK_BUTTON, _("Cancel")]) if rc == string.lower(_("Cancel")): self.rc = 1 else: self.rc = 0 class ProgressWindow: def pop(self): self.screen.popWindow() self.screen.refresh() del self.scale self.scale = None def set(self, amount): self.scale.set(amount) self.screen.refresh() def __init__(self, screen, title, text, total): self.screen = screen width = 55 if (len(text) > width): width = len(text) t = TextboxReflowed(width, text) g = GridForm(self.screen, title, 1, 2) g.add(t, 0, 0, (0, 0, 0, 1), anchorLeft=1) self.scale = Scale(width, total) g.add(self.scale, 0, 1) g.draw() self.screen.refresh() class InstallInterface: def helpWindow(self, screen, key): lang = self.instLanguage.getCurrent() lang = self.instLanguage.getLangNick(lang) self.langSearchPath = expandLangs(lang) + ['C'] if key == "helponhelp": if self.showingHelpOnHelp: return None else: self.showingHelpOnHelp = 1 try: f = None if self.configFileData.has_key("helptag"): helpTag = "-%s" % (self.configFileData["helptag"],) else: helpTag = "" arch = "-%s" % (iutil.getArch(),) tags = [ "%s%s" % (helpTag, arch), "%s" % (helpTag,), "%s" % (arch,), "" ] # XXX # # HelpWindow can't get to the langauge found = 0 for path in ("./text-", "/mnt/source/RHupdates/", "/usr/share/anaconda/"): if found: break for lang in self.langSearchPath: for tag in tags: fn = "%shelp/%s/s1-help-screens-%s%s.txt" \ % (path, lang, key, tag) try: f = open(fn) except IOError, msg: continue found = 1 break if not f: ButtonChoiceWindow(screen, _("Help not available"), _("No help is available for this " "step of the install."), buttons=[TEXT_OK_BUTTON]) return None lines = f.readlines() for l in lines: l = l.replace("@RHL@", productName) l = l.replace("@RHLVER@", productVersion) while not string.strip(l[0]): l = l[1:] title = string.strip(l[0]) l = l[1:] while not string.strip(l[0]): l = l[1:] f.close() height = 10 scroll = 1 if len(l) < height: height = len(l) scroll = 0 width = len(title) + 6 stream = "" for line in l: line = string.strip(line) stream = stream + line + "\n" if len(line) > width: width = len(line) bb = ButtonBar(screen, [TEXT_OK_BUTTON]) t = Textbox(width, height, stream, scroll=scroll) g = GridFormHelp(screen, title, "helponhelp", 1, 2) g.add(t, 0, 0, padding=(0, 0, 0, 1)) g.add(bb, 0, 1, growx=1) g.runOnce() self.showingHelpOnHelp = 0 except: import traceback (type, value, tb) = sys.exc_info() from string import joinfields list = traceback.format_exception(type, value, tb) text = joinfields(list, "") rc = self.exceptionWindow(_("Exception Occurred"), text) if rc: import pdb pdb.post_mortem(tb) os._exit(1) def progressWindow(self, title, text, total): return ProgressWindow(self.screen, title, text, total) def messageWindow(self, title, text, type="ok", default = None, custom_icon=None, custom_buttons=[]): if type == "ok": ButtonChoiceWindow(self.screen, title, text, buttons=[TEXT_OK_BUTTON]) elif type == "yesno": if default and default == "no": btnlist = [TEXT_NO_BUTTON, TEXT_YES_BUTTON] else: btnlist = [TEXT_YES_BUTTON, TEXT_NO_BUTTON] rc = ButtonChoiceWindow(self.screen, title, text, buttons=btnlist) if rc == "yes": return 1 else: return 0 elif type == "custom": tmpbut = [] for but in custom_buttons: tmpbut.append(string.replace(but,"_","")) rc = ButtonChoiceWindow(self.screen, title, text, width=60, buttons=tmpbut) idx = 0 for b in tmpbut: if string.lower(b) == rc: return idx != 0 idx = idx + 1 return 0 else: return OkCancelWindow(self.screen, title, text) def dumpWindow(self): rc = ButtonChoiceWindow(self.screen, _("Save Crash Dump"), _("Please insert a floppy now. All contents of the disk " "will be erased, so please choose your diskette carefully."), [TEXT_OK_BUTTON, _("Cancel")]) if rc == string.lower(_("Cancel")): return 1 return 0 def exceptionWindow(self, title, text): try: floppyDevices = 0 for dev in kudzu.probe(kudzu.CLASS_FLOPPY, kudzu.BUS_UNSPEC, kudzu.PROBE_ALL): if not dev.detached: floppyDevices = floppyDevices + 1 except: floppyDevices = 0 if floppyDevices > 0 or DEBUG: ugh = "%s\n\n" % (exceptionText,) buttons=[TEXT_OK_BUTTON, _("Save"), _("Debug")] else: ugh = "%s\n\n" % (exceptionTextNoFloppy,) buttons=[TEXT_OK_BUTTON, _("Debug")] rc = ButtonChoiceWindow(self.screen, title, ugh + text, buttons) if rc == string.lower(_("Debug")): return 1 elif rc == string.lower(_("Save")): return 2 return None def partedExceptionWindow(self, exc): # if our only option is to cancel, let us handle the exception # in our code and avoid popping up the exception window here. if exc.options == parted.EXCEPTION_CANCEL: return parted.EXCEPTION_UNHANDLED buttons = [] buttonToAction = {} flags = ((parted.EXCEPTION_FIX, N_("Fix")), (parted.EXCEPTION_YES, N_("Yes")), (parted.EXCEPTION_NO, N_("No")), (parted.EXCEPTION_OK, N_("OK")), (parted.EXCEPTION_RETRY, N_("Retry")), (parted.EXCEPTION_IGNORE, N_("Ignore")), (parted.EXCEPTION_CANCEL, N_("Cancel"))) for flag, errorstring in flags: if exc.options & flag: buttons.append(_(errorstring)) buttonToAction[string.lower(_(errorstring))] = flag rc = None while not buttonToAction.has_key(rc): rc = ButtonChoiceWindow(self.screen, exc.type_string, exc.message, buttons=buttons) return buttonToAction[rc] def waitWindow(self, title, text): return WaitWindow(self.screen, title, text) def drawFrame(self): self.welcomeText = _("%s ") % (productName,) self.screen.drawRootText (0, 0, self.welcomeText) self.screen.drawRootText (len(_(self.welcomeText)), 0, (self.screen.width - len(_(self.welcomeText))) * " ") if (os.access("/usr/share/anaconda/help/C/s1-help-screens-lang.txt", os.R_OK)): self.screen.pushHelpLine(_(" for help | between elements | selects | next screen")) else: self.screen.pushHelpLine(_(" / between elements | selects | next screen")) def setScreen(self, screen): self.screen = screen def shutdown(self): self.screen.finish() self.screen = None def __init__(self): signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGTSTP, signal.SIG_IGN) self.screen = None self.showingHelpOnHelp = 0 def __del__(self): if self.screen: s:;<=elf.screen.finish() def run(self, id, dispatch, configFileData): # set up for CJK text mode if needed if (flags.setupFilesystems and (id.instLanguage.getFontFile(id.instLanguage.getCurrent()) == "bterm") and not isys.isPsudoTTY(0) and not flags.serial): log("starting bterm") try: rc = isys.startBterm() time.sleep(1) except Exception, e: log("got an exception starting bterm: %s" %(e,)) self.screen = SnackScreen() self.configFileData = configFileData self.screen.helpCallback(self.helpWindow) # uncomment this line to make the installer quit on # handy for quick debugging. # self.screen.suspendCallback(killSelf, self.screen) # uncomment this line to drop into the python debugger on # --VERY handy-- if DEBUG or flags.test: self.screen.suspendCallback(debugSelf, self.screen) if flags.serial or isys.isPsudoTTY(0) or isys.isVioConsole(): self.screen.suspendCallback(spawnShell, self.screen) # clear out the old root text by writing spaces in the blank # area on the right side of the screen #self.screen.drawRootText (len(_(self.welcomeText)), 0, #(self.screen.width - len(_(self.welcomeText))) * " ") #self.screen.drawRootText (0 - len(_(step[0])), 0, _(step[0])) langname = id.instLanguage.getCurrent() lang = id.instLanguage.getLangNick(langname) self.langSearchPath = expandLangs(lang) + ['C'] self.instLanguage = id.instLanguage # draw the frame after setting up the fallback self.drawFrame() # draw the frame after setting up the fallback self.drawFrame() id.fsset.registerMessageWindow(self.messageWindow) id.fsset.registerProgressWindow(self.progressWindow) id.fsset.registerWaitWindow(self.waitWindow) parted.exception_set_handler(self.partedExceptionWindow) lastrc = INSTALL_OK (step, args) = dispatch.currentStep() while step: (file, classNames) = stepToClasses[step] if type(classNames) != type(()): classNames = (classNames,) if lastrc == INSTALL_OK: step = 0 else: step = len(classNames) - 1 while step >= 0 and step < len(classNames): # reget the args. they could change (especially direction) (foo, args) = dispatch.currentStep() nextWindow = None s = "from %s import %s; nextWindow = %s" % \ (file, classNames[step], classNames[step]) exec s win = nextWindow() #log("TUI running step %s (class %s, file %s)" % #(step, file, classNames)) rc = apply(win, (self.screen, ) + args) if rc == INSTALL_NOOP: rc = lastrc if rc == INSTALL_BACK: step = step - 1 dispatch.dir = DISPATCH_BACK elif rc == INSTALL_OK: step = step + 1 dispatch.dir = DISPATCH_FORWARD lastrc = rc if step == -1: if not dispatch.canGoBack(): ButtonChoiceWindow(self.screen, _("Cancelled"), _("I can't go to the previous step " "from here. You will have to try " "again."), buttons=[_("OK")]) dispatch.gotoPrev() else: dispatch.gotoNext() (step, args) = dispatch.currentStep() self.screen.finish() def killSelf(screen): screen.finish() os._exit(0) def debugSelf(screen): screen.suspend() import pdb try: pdb.set_trace() except: sys.exit(-1) screen.resume() def spawnShell(screen): screen.suspend() print "\n\nType to return to the install program.\n" iutil.execWithRedirect("/bin/sh", ["-/bin/sh"]) time.sleep(5) screen.resume()