# this is the prototypical class for workstation, server, and kickstart # installs # # The interface to BaseInstallClass is *public* -- ISVs/OEMs can customize the # install by creating a new derived type of this class. # putting these here is a bit of a hack, but we can't switch between # newtfsedit and gnomefsedit right now, so we have to put up with this FSEDIT_CLEAR_LINUX = (1 << 1) FSEDIT_CLEAR_ALL = (1 << 2) FSEDIT_USE_EXISTING = (1 << 3) import gettext_rh, os, iutil import string from xf86config import XF86Config from translate import _ from instdata import InstallData class BaseInstallClass: # default to not being hidden hidden = 0 pixmap = None # don't select this class by default default = 0 # don't force text mode forceTextMode = 0 # by default, place this under the "install" category; it gets it's # own toplevel category otherwise parentClass = ( _("Install"), "install.png" ) # we can use a different install data class installDataClass = InstallData def postAction(self, rootPath, serial): pass def setLiloInformation(self, location, linear = 1, appendLine = None): # this throws an exception if there is a problem ["mbr", "partition", None].index(location) self.lilo = (location, linear, appendLine) def setClearParts(self, clear, warningText = None): self.clearParts = clear # XXX hack for install help text in GUI mode if clear == FSEDIT_CLEAR_LINUX: self.clearType = "wkst" if clear == FSEDIT_CLEAR_ALL: self.clearType = "svr" self.clearPartText = warningText def getClearParts(self): return self.clearParts def getLiloInformation(self): return self.lilo def getFstab(self): return self.fstab def addRaidEntry(self, mntPoint, raidDev, level, devices): # throw an exception for bad raid levels [ 0, 1, 5 ].index(level) for device in devices: found = 0 for (otherMountPoint, sizespc, (devX, partX, primOnlyX), typespecX, fsoptsX) in self.partitions: if otherMountPoint == device: found = 1 # check prexisting partions specified in ks.cfg with --usepart if not found: for (otherMountPoint, (devX, fstypeX, reformatX)) in self.fstab: if otherMountPoint == device: found = 1 if not found: raise ValueError, "unknown raid device %s" % (device,) if mntPoint[0] != '/' and mntPoint != 'swap': raise ValueError, "bad raid mount point %s" % (mntPoint,) if raidDev[0:2] != "md": raise ValueError, "bad raid device point %s" % (raidDev,) if level == 5 and len(devices) < 3: raise ValueError, "raid 5 arrays require at least 3 devices" if len(devices) < 2: raise ValueError, "raid arrays require at least 2 devices" self.raidList.append(mntPoint, raidDev, level, devices) def addNewPartition(self, mntPoint, sizespec, locspec, typespec, fsopts=None): (device, part, primOnly) = locspec if not device: device = "" if mntPoint[0] != '/' and mntPoint != 'swap' and \ mntPoint[0:5] != "raid.": raise TypeError, "bad mount point for partitioning: %s" % \ (mntPoint,) self.partitions.append((mntPoint, sizespec, (device, part, primOnly),typespec, fsopts)) def addToFstab(self, mntpoint, dev, fstype = "ext2" , reformat = 1): self.fstab.append((mntpoint, (dev, fstype, reformat))) def setSteps(self, dispatch): dispatch.setStepList( "language", "keyboard", "mouse", "welcome", "installtype", "partition", "partitiondone", "bootloader", "network", "firewall", "languagesupport", "timezone", "accounts", "authentication", "readcomps", "package-selection", "handleX11pkgs", "checkdeps", "dependencies", "videocard", "monitor", "xcustom", "confirminstall", "enablefilesystems", "install", "installpackages", "writeconfig", "instbootloader", "writexconfig", "writeksconfig", "bootdisk", "complete" ) if iutil.getArch() == "alpha" or iutil.getArch() == "ia64": dispatch.skipStep("bootdisk") # This is called after the hdlist is read in. def setPackageSelection(self, hdlist): pass # This is called after the comps is read in (after setPackageSelection()). # It can both select groups, change the default selection for groups, and # change which groups are hidden. def setGroupSelection(self, comps): pass # this is a utility function designed to be called from setGroupSelection() # it hides all of the groups not in the "groups" list def showGroups(self, comps, groups): groupSet = {} for group in groups: if type(group) == type("a"): groupSet[group] = None else: (group, val) = group groupSet[group] = val for comp in comps: if groupSet.has_key(comp.name): comp.hidden = 0 # do nothing if groupSet[comp.name] == None if groupSet[comp.name] == 1: comp.select() elif groupSet[comp.name] == 0: comp.unselect(0) else: comp.hidden = 1 def getMakeBootdisk(self): return self.makeBootdisk def setMakeBootdisk(self, state): self.makeBootdisk = state def setZeroMbr(self, state): self.zeroMbr = state def setEarlySwapOn(self, state = 0): self.earlySwapOn = state def setDesktop(self, desktop): self.desktop = desktop def getDesktop(self): return self.desktop def setKeyboard(self, id, kb): id.keyboard.set(kb) # XXX #xkb = todo.keyboard.getXKB () #if xkb: #apply (todo.x.setKeyboard, xkb) ## hack - apply to instclass preset if present as well #if (todo.instClass.x): #apply (todo.instClass.x.setKeyboard, xkb) def setHostname(self, id, hostname): id.network.setHostname(hostname); def setTimezoneInfo(self, id, timezone, asUtc = 0, asArc = 0): id.timezone.setTimezoneInfo(timezone, asUtc, asArc) def setRootPassword(self, id, pw, isCrypted = 0): id.rootPassword.set(pw, isCrypted) def setAuthentication(self, id, useShadow, useMd5, useNIS = 0, nisDomain = "", nisBroadcast = 0, nisServer = "", useLdap = 0, useLdapauth = 0, ldapServer = "", ldapBasedn = "", useKrb5 = 0, krb5Realm = "", krb5Kdc = "", krb5Admin = "", useHesiod = 0, hesiodLhs = "", hesiodRhs = ""): id.auth.useShadow = useShadow id.auth.useMD5 = useMd5 id.auth.useNIS = useNIS id.auth.nisDomain = nisDomain id.auth.nisuseBroadcast = nisBroadcast id.auth.nisServer = nisServer id.auth.useLdap = useLdap id.auth.useLdapauth = useLdapauth id.auth.ldapServer = ldapServer id.auth.ldapBasedn = ldapBasedn id.auth.useKrb5 = useKrb5 id.auth.krb5Realm = krb5Realm id.auth.krb5Kdc = krb5Kdc id.auth.krb5Admin = krb5Admin id.auth.useHesiod = useHesiod id.auth.hesiodLhs = hesiodLhs id.auth.hesiodRhs = hesiodRhs def setNetwork(self, id, bootProto, ip, netmask, gateway, nameserver, device = None): if bootProto: id.network.gateway = gateway id.network.primaryNS = nameserver devices = id.network.available () if (devices and bootProto): if not device: list = devices.keys () list.sort() device = list[0] dev = devices[device] dev.set (("bootproto", bootProto)) dev.set (("onboot", "yes")) if bootProto == "static": if (ip): dev.set (("ipaddr", ip)) if (netmask): dev.set (("netmask", netmask)) def setLanguageSupport(self, id, langlist): if len (langlist) == 0: id.langSupport.setSupported(id.langSupport.getAllSupported()) else: newlist = [] for lang in langlist: newlist.append(id.langSupport.getLangNameByNick(lang)) id.langSupport.setSupported(newlist) def setLanguageDefault(self, id, default): id.langSupport.setDefault(id.langSupport.getLangNameByNick(default)) def setLanguage(self, id, lang): instLangName = id.instLanguage.getLangNameByNick(lang) id.instLanguage.setRuntimeLanguage(instLangName) def setDesktop(self, id, desktop): id.desktop.setDefaultDesktop (desktop) def setFirewall(self, id, enable = -1, policy = 1, trusts = [], ports = "", dhcp = 0, ssh = 0, telnet = 0, smtp = 0, http = 0, ftp = 0): id.firewall.enabled = enable id.firewall.policy = policy id.firewall.trustdevs = trusts id.firewall.portlist = ports id.firewall.dhcp = dhcp id.firewall.ssh = ssh id.firewall.telnet = telnet id.firewall.smtp = smtp id.firewall.http = http id.firewall.ftp = ftp def configureX(self, id, server = None, card = None, videoRam = None, monitorName = None, hsync = None, vsync = None, resolution = None, depth = None, noProbe = 0, startX = 0): import videocard import monitor # XXX they could have sensitive hardware, but we need this info =\ videohw = videocard.VideoCardInfo() if videohw: id.setVideoCard(videohw) if (not noProbe): monitorhw = monitor.MonitorInfo() if monitorhw: id.setMonitor(monitorhw) if id.videocard and not id.videocard.primaryCard().getXServer(): if (card != None): vc = id.videocard.locateVidcardByName(card) elif (server != None): vc = id.videocard.locateVidcardByServer(server) else: raise RuntimeError, "Could not probe video card and no fallback specified" id.videocard.setVidcard(vc) if videoRam in id.videocard.possible_ram_sizes(): id.videocard.primaryCard().setVideoRam(videoRam) if (id.monitor.getMonitorID() != "Unprobed monitor") and monitorName: (model, eisa, vert, horiz) = id.monitor.lookupMonitor(monitorName) id.monitor.setSpecs(horiz, vert, id=model, name=model) elif hsync and vsync: id.monitor.setSpecs(hsync, vsync) else: raise RuntimeError, "Could not probe monitor and no fallback specified" if startX: id.desktop.setDefaultRunLevel(5) else: id.desktop.setDefaultRunLevel(3) import xf86config xcfg = xf86config.XF86Config(id.videocard, id.monitor, id.mouse) available = xcfg.availableModes() if resolution and depth: if depth not in id.videocard.possible_depths(): raise RuntimeError, "Invalid depth specified" # XXX should we fallback to our "best possible" here? if resolution not in available[depth]: raise RuntimeError, "Selected resolution and bitdepth not possible with video ram detected. Perhaps you need to specify video ram" else: if len(available) == 1: depth = "8" elif len(available) >= 2: depth = "16" if "1024x768" in available[depth]: resolution = "1024x768" elif "800x600" in available[depth]: resolution = "800x600" else: resolution = "640x480" xcfg.setManualModes( { depth: [ resolution ] } ) id.setXconfig(xcfg) def setMouse(self, id, mouseType, device = None, emulThree = -1): import mouse # blindly trust what we're told mouse = mouse.Mouse(skipProbe = 1) mouseName = mouse.mouseToMouse()[mouseType] mouse.set(mouseName, emulThree, device) id.setMouse(mouse) def setInstallData(self, id): id.reset() id.instClass = self # Classes should call these on __init__ to set up install data #id.setKeyboard() #id.setLanguage() #id.setNetwork() #id.setFirewall() #id.setLanguageSupport() #id.setLanguageDefault() #id.setTimezone() #id.setRootPassword() #id.setAuthentication() #id.setHostname() #id.setDesktop() #id.setMouse() # These are callbacks used to let classes configure packages #id.setPackageSelection() #id.setGroupSelection() def __init__(self, expert): pass # we need to be able to differentiate between this and custom class DefaultInstall(BaseInstallClass): def __init__(self, expert): BaseInstallClass.__init__(self, expert) allClasses = [] allClasses_hidden = [] # returns ( className, classObject, classLogo ) tuples def availableClasses(showHidden=0): global allClasses global allClasses_hidden if not showHidden: if allClasses: return allClasses else: if allClasses_hidden: return allClasses_hidden if os.access("installclasses", os.R_OK): path = "installclasses" else: path = "/usr/lib/anaconda/installclasses" files = os.listdir(path) done = {} list = [] for file in files: if file[0] == '.': continue if len (file) < 4: continue if file[-3:] != ".py" and file[-4:-1] != ".py": continue mainName = string.split(file, ".")[0] if done.has_key(mainName): continue done[mainName] = 1 obj = None name = None cmd = "import %s\nif %s.__dict__.has_key('InstallClass'): obj = %s.InstallClass\n" % (mainName, mainName, mainName) exec(cmd) if obj: if obj.__dict__.has_key('sortPriority'): sortOrder = obj.sortPriority else: sortOrder = 0 if obj.__dict__.has_key('arch'): if obj.arch != iutil.getArch (): obj.hidden = 1 if obj.hidden == 0 or showHidden == 1: list.append(((obj.name, obj, obj.pixmap), sortOrder)) list.sort(ordering) for (item, priority) in list: if showHidden: allClasses_hidden.append(item) else: allClasses.append(item) if showHidden: return allClasses_hidden else: return allClasses def ordering(first, second): ((name1, obj, logo), priority1) = first ((name2, obj, logo), priority2) = second if priority1 < priority2: return -1 elif priority1 > priority2: return 1 if name1 < name2: return -1 elif name1 > name2: return 1 return 0 def requireDisplayMode(): return None