1 |
# this is the prototypical class for workstation, server, and kickstart |
2 |
# installs |
3 |
# |
4 |
# The interface to BaseInstallClass is *public* -- ISVs/OEMs can customize the |
5 |
# install by creating a new derived type of this class. |
6 |
# |
7 |
# Copyright 1999-2004 Red Hat, Inc. |
8 |
# |
9 |
# This software may be freely redistributed under the terms of the GNU |
10 |
# library public license. |
11 |
# |
12 |
# You should have received a copy of the GNU Library Public License |
13 |
# along with this program; if not, write to the Free Software |
14 |
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
15 |
# |
16 |
|
17 |
import os, sys, iutil |
18 |
import string |
19 |
import language |
20 |
|
21 |
from instdata import InstallData |
22 |
from partitioning import * |
23 |
from autopart import getAutopartitionBoot, autoCreatePartitionRequests, autoCreateLVMPartitionRequests |
24 |
|
25 |
from rhpl.log import log |
26 |
from rhpl.translate import _, N_ |
27 |
|
28 |
from constants import BETANAG |
29 |
|
30 |
class BaseInstallClass: |
31 |
# default to not being hidden |
32 |
hidden = 0 |
33 |
pixmap = None |
34 |
showMinimal = 1 |
35 |
showLoginChoice = 0 |
36 |
description = None |
37 |
name = "base" |
38 |
pkgstext = "" |
39 |
# default to showing the upgrade option |
40 |
showUpgrade = 1 |
41 |
|
42 |
# pkgstext = _("\tDesktop shell (GNOME)\n" |
43 |
# "\tOffice suite (OpenOffice)\n" |
44 |
# "\tWeb browser (Mozilla) \n" |
45 |
# "\tEmail (Evolution)\n" |
46 |
# "\tInstant messaging\n" |
47 |
# "\tSound and video applications\n" |
48 |
# "\tGames\n" |
49 |
# "\tSoftware Development Tools\n" |
50 |
# "\tAdministration Tools\n") |
51 |
|
52 |
|
53 |
# don't select this class by default |
54 |
default = 0 |
55 |
|
56 |
# don't force text mode |
57 |
forceTextMode = 0 |
58 |
|
59 |
# by default, place this under the "install" category; it gets it's |
60 |
# own toplevel category otherwise |
61 |
parentClass = ( _("Install on System"), "install.png" ) |
62 |
|
63 |
# we can use a different install data class |
64 |
installDataClass = InstallData |
65 |
|
66 |
def postAction(self, rootPath, serial): |
67 |
pass |
68 |
|
69 |
def setBootloader(self, id, useLilo=0, location=None, linear=1, |
70 |
forceLBA=0, password=None, md5pass=None, |
71 |
appendLine="", driveorder = []): |
72 |
if useLilo: |
73 |
id.bootloader.useGrubVal = 0 |
74 |
if appendLine: |
75 |
id.bootloader.args.set(appendLine) |
76 |
id.bootloader.setForceLBA(forceLBA) |
77 |
id.bootloader.useLinear = linear |
78 |
if password: |
79 |
id.bootloader.setPassword(password, isCrypted = 0) |
80 |
if md5pass: |
81 |
id.bootloader.setPassword(md5pass) |
82 |
if location != None: |
83 |
id.bootloader.defaultDevice = location |
84 |
else: |
85 |
id.bootloader.defaultDevice = -1 |
86 |
|
87 |
# XXX throw out drives specified that don't exist. anything else |
88 |
# seems silly |
89 |
if driveorder and len(driveorder) > 0: |
90 |
new = [] |
91 |
for drive in driveorder: |
92 |
if drive in id.bootloader.drivelist: |
93 |
new.append(drive) |
94 |
else: |
95 |
log("requested drive %s in boot drive order doesn't " |
96 |
"exist" %(drive,)) |
97 |
id.bootloader.drivelist = new |
98 |
|
99 |
def setIgnoredDisks(self, id, drives): |
100 |
diskset = id.diskset |
101 |
for drive in drives: |
102 |
if not drive in diskset.skippedDisks: |
103 |
diskset.skippedDisks.append(drive) |
104 |
|
105 |
def setClearParts(self, id, clear, drives = None, warningText = None, |
106 |
initAll = 0): |
107 |
id.partitions.autoClearPartType = clear |
108 |
id.partitions.autoClearPartDrives = drives |
109 |
if initAll: |
110 |
id.partitions.reinitializeDisks = initAll |
111 |
# XXX hack for install help text in GUI mode |
112 |
if clear == CLEARPART_TYPE_LINUX: |
113 |
self.clearType = "wkst" |
114 |
if clear == CLEARPART_TYPE_ALL: |
115 |
self.clearType = "svr" |
116 |
self.clearPartText = warningText |
117 |
|
118 |
def setSteps(self, dispatch): |
119 |
dispatch.setStepList( |
120 |
"language", |
121 |
"keyboard", |
122 |
# "checkmonitorok", |
123 |
# "monitor", |
124 |
# "setsanex", |
125 |
"welcome", |
126 |
"findrootparts", |
127 |
"betanag", |
128 |
"installtype", |
129 |
"zfcpconfig", |
130 |
"partitionmethod", |
131 |
"partitionobjinit", |
132 |
"partitionmethodsetup", |
133 |
"autopartition", |
134 |
"autopartitionexecute", |
135 |
"fdisk", |
136 |
"partition", |
137 |
"partitiondone", |
138 |
"bootloadersetup", |
139 |
"bootloader", |
140 |
"networkdevicecheck", |
141 |
"network", |
142 |
"firewall", |
143 |
"languagesupport", |
144 |
"timezone", |
145 |
"accounts", |
146 |
"readcomps", |
147 |
"selectlangpackages", |
148 |
"package-selection", |
149 |
"handleX11pkgs", |
150 |
"checkdeps", |
151 |
"dependencies", |
152 |
"confirminstall", |
153 |
"install", |
154 |
"enablefilesystems", |
155 |
"migratefilesystems", |
156 |
"setuptime", |
157 |
"preinstallconfig", |
158 |
"installpackages", |
159 |
"postinstallconfig", |
160 |
"writeconfig", |
161 |
"firstboot", |
162 |
"instbootloader", |
163 |
"dopostaction", |
164 |
"writexconfig", |
165 |
"writeksconfig", |
166 |
"bootdisk", |
167 |
"methodcomplete", |
168 |
"copylogs", |
169 |
"setfilecon", |
170 |
"complete" |
171 |
) |
172 |
|
173 |
if not BETANAG: |
174 |
dispatch.skipStep("betanag", permanent=1) |
175 |
|
176 |
if iutil.getArch() != "s390": |
177 |
dispatch.skipStep("zfcpconfig") |
178 |
|
179 |
if iutil.getArch() != "i386" or 1: |
180 |
dispatch.skipStep("bootdisk") |
181 |
|
182 |
# see if we need to write out a rescue boot floppy |
183 |
if iutil.getArch() == "i386": |
184 |
import floppy |
185 |
if not floppy.hasFloppyDevice(): |
186 |
dispatch.skipStep("bootdisk") |
187 |
|
188 |
if iutil.getArch() != "i386" and iutil.getArch() != "x86_64": |
189 |
dispatch.skipStep("bootloader") |
190 |
|
191 |
# allow install classes to turn off the upgrade |
192 |
if self.showUpgrade == 0: |
193 |
dispatch.skipStep("findrootparts", skip = 1) |
194 |
|
195 |
# 'noupgrade' can be used on the command line to force not looking |
196 |
# for partitions to upgrade. useful in some cases... |
197 |
cmdline = open("/proc/cmdline", "r").read() |
198 |
cmdline = cmdline.split() |
199 |
if "noupgrade" in cmdline: |
200 |
dispatch.skipStep("findrootparts", skip = 1) |
201 |
|
202 |
# upgrade will also always force looking for an upgrade. |
203 |
if "upgrade" in cmdline: |
204 |
dispatch.skipStep("findrootparts", skip = 0) |
205 |
|
206 |
# if there's only one install class, it doesn't make much sense |
207 |
# to show it |
208 |
if len(availableClasses()) < 2: |
209 |
dispatch.skipStep("installtype", permanent=1) |
210 |
|
211 |
# called from anaconda so that we can skip steps in the headless case |
212 |
# in a perfect world, the steps would be able to figure this out |
213 |
# themselves by looking at instdata.headless. but c'est la vie. |
214 |
def setAsHeadless(self, dispatch, isHeadless = 0): |
215 |
if isHeadless == 0: |
216 |
pass |
217 |
else: |
218 |
dispatch.skipStep("keyboard", permanent = 1) |
219 |
# dispatch.skipStep("mouse", permanent = 1) |
220 |
dispatch.skipStep("handleX11pkgs", permanent = 1) |
221 |
dispatch.skipStep("videocard", permanent = 1) |
222 |
dispatch.skipStep("monitor", permanent = 1) |
223 |
dispatch.skipStep("xcustom", permanent = 1) |
224 |
dispatch.skipStep("writexconfig", permanent = 1) |
225 |
|
226 |
# This is called after the hdlist is read in. |
227 |
def setPackageSelection(self, hdlist, intf): |
228 |
pass |
229 |
|
230 |
# This is called after the comps is read in (after setPackageSelection()). |
231 |
# It can both select groups, change the default selection for groups, and |
232 |
# change which groups are hidden. |
233 |
def setGroupSelection(self, grpset, intf): |
234 |
pass |
235 |
|
236 |
def setZFCP(self, id, devnum, scsiid, wwpn, scsilun, fcplun): |
237 |
id.zfcp.fcpdevices.append( (devnum, scsiid, wwpn, scsilun, fcplun) ) |
238 |
|
239 |
def getMakeBootdisk(self): |
240 |
return self.makeBootdisk |
241 |
|
242 |
def setMakeBootdisk(self, state): |
243 |
self.makeBootdisk = state |
244 |
|
245 |
def setZeroMbr(self, id, zeroMbr): |
246 |
id.partitions.zeroMbr = zeroMbr |
247 |
|
248 |
def setEarlySwapOn(self, state = 0): |
249 |
self.earlySwapOn = state |
250 |
|
251 |
def setKeyboard(self, id, kb): |
252 |
id.keyboard.set(kb) |
253 |
|
254 |
# activate the keyboard changes |
255 |
# id.keyboard.activate() |
256 |
|
257 |
# XXX |
258 |
#apply (todo.x.setKeyboard, xkb) |
259 |
|
260 |
## hack - apply to instclass preset if present as well |
261 |
#if (todo.instClass.x): |
262 |
#apply (todo.instClass.x.setKeyboard, xkb) |
263 |
|
264 |
def setHostname(self, id, hostname, override = 0): |
265 |
id.network.setHostname(hostname); |
266 |
id.network.overrideDHCPhostname = override |
267 |
|
268 |
def setNameserver(self, id, nameserver): |
269 |
id.network.setDNS(nameserver) |
270 |
|
271 |
def setGateway(self, id, gateway): |
272 |
id.network.setGateway(gateway) |
273 |
|
274 |
def setTimezoneInfo(self, id, timezone, asUtc = 0, asArc = 0): |
275 |
id.timezone.setTimezoneInfo(timezone, asUtc, asArc) |
276 |
|
277 |
def setRootPassword(self, id, pw, isCrypted = 0): |
278 |
id.rootPassword.set(pw, isCrypted) |
279 |
|
280 |
def setAuthentication(self, id, useShadow, useMd5, |
281 |
useNIS = 0, nisDomain = "", nisBroadcast = 0, |
282 |
nisServer = "", |
283 |
useLdap = 0, useLdapauth = 0, ldapServer = "", |
284 |
ldapBasedn = "", useldapTls = 0, |
285 |
useKrb5 = 0, krb5Realm = "", krb5Kdc = "", |
286 |
krb5Admin = "", |
287 |
useHesiod = 0, hesiodLhs = "", hesiodRhs = "", |
288 |
useSamba = 0, sambaServer= "", sambaWorkgroup = "", |
289 |
enableCache = 0): |
290 |
|
291 |
id.auth.useShadow = useShadow |
292 |
id.auth.useMD5 = useMd5 |
293 |
|
294 |
id.auth.useNIS = useNIS |
295 |
id.auth.nisDomain = nisDomain |
296 |
id.auth.nisuseBroadcast = nisBroadcast |
297 |
id.auth.nisServer = nisServer |
298 |
|
299 |
id.auth.useLdap = useLdap |
300 |
id.auth.useLdapauth = useLdapauth |
301 |
id.auth.ldapServer = ldapServer |
302 |
id.auth.ldapBasedn = ldapBasedn |
303 |
id.auth.ldapTLS = useldapTls |
304 |
|
305 |
id.auth.useKrb5 = useKrb5 |
306 |
id.auth.krb5Realm = krb5Realm |
307 |
id.auth.krb5Kdc = krb5Kdc |
308 |
id.auth.krb5Admin = krb5Admin |
309 |
|
310 |
id.auth.useHesiod = useHesiod |
311 |
id.auth.hesiodLhs = hesiodLhs |
312 |
id.auth.hesiodRhs = hesiodRhs |
313 |
|
314 |
id.auth.useSamba = useSamba |
315 |
id.auth.sambaServer = sambaServer |
316 |
id.auth.sambaWorkgroup = sambaWorkgroup |
317 |
|
318 |
id.auth.enableCache = enableCache |
319 |
|
320 |
def setNetwork(self, id, bootProto, ip, netmask, ethtool, device = None, onboot = 1, dhcpclass = None, essid = None, wepkey = None): |
321 |
if bootProto: |
322 |
devices = id.network.available () |
323 |
if (devices and bootProto): |
324 |
if not device: |
325 |
list = devices.keys () |
326 |
list.sort() |
327 |
device = list[0] |
328 |
dev = devices[device] |
329 |
dev.set (("bootproto", bootProto)) |
330 |
dev.set (("dhcpclass", dhcpclass)) |
331 |
if onboot: |
332 |
dev.set (("onboot", "yes")) |
333 |
else: |
334 |
dev.set (("onboot", "no")) |
335 |
if bootProto == "static": |
336 |
if (ip): |
337 |
dev.set (("ipaddr", ip)) |
338 |
if (netmask): |
339 |
dev.set (("netmask", netmask)) |
340 |
if ethtool: |
341 |
dev.set (("ethtool_opts", ethtool)) |
342 |
if isys.isWireless(device): |
343 |
if essid: |
344 |
dev.set(("essid", essid)) |
345 |
if wepkey: |
346 |
dev.set(("wepkey", wepkey)) |
347 |
|
348 |
def setLanguageSupport(self, id, langlist): |
349 |
if len (langlist) == 0: |
350 |
id.langSupport.setSupported(id.langSupport.getAllSupported()) |
351 |
else: |
352 |
newlist = [] |
353 |
for lang in langlist: |
354 |
newlist.append(id.langSupport.getLangNameByNick(lang)) |
355 |
|
356 |
default = id.langSupport.getDefault() |
357 |
if default not in newlist: |
358 |
newlist.append(default) |
359 |
|
360 |
id.langSupport.setSupported(newlist) |
361 |
|
362 |
def setLanguageDefault(self, id, default): |
363 |
id.langSupport.setDefault(id.langSupport.getLangNameByNick(default)) |
364 |
|
365 |
def setLanguage(self, id, lang): |
366 |
instLangName = id.instLanguage.getLangNameByNick(lang) |
367 |
id.instLanguage.setRuntimeLanguage(instLangName) |
368 |
|
369 |
def setDesktop(self, id, desktop): |
370 |
id.desktop.setDefaultDesktop (desktop) |
371 |
|
372 |
def setSELinux(self, id, sel): |
373 |
id.security.setSELinux(sel) |
374 |
|
375 |
def setZFCP(self, id, fcpdev): |
376 |
id.zfcp.fcpdevices = fcpdev |
377 |
|
378 |
def setFirewall(self, id, enable = 1, trusts = [], ports = []): |
379 |
id.firewall.enabled = enable |
380 |
id.firewall.trustdevs = trusts |
381 |
# this is a little ugly, but we want to let setting a service |
382 |
# like --ssh enable the service in case they're doing an interactive |
383 |
# kickstart install |
384 |
for port in ports: |
385 |
found = 0 |
386 |
for s in id.firewall.services: |
387 |
p = s.get_ports() |
388 |
# don't worry about the ones that are more than one, |
389 |
# this is really for legacy use only |
390 |
if len(p) > 1: |
391 |
continue |
392 |
if p[0] == port: |
393 |
s.set_enabled(1) |
394 |
found = 1 |
395 |
break |
396 |
|
397 |
if not found: |
398 |
id.firewall.portlist.append(port) |
399 |
|
400 |
def setMiscXSettings(self, id, depth = None, resolution = None, |
401 |
desktop = None, runlevel = None): |
402 |
|
403 |
if depth: |
404 |
availableDepths = id.xsetup.xhwstate.available_color_depths() |
405 |
if depth not in availableDepths: |
406 |
log("Requested depth %s not available, falling back to %s" |
407 |
%(depth, availableDepths[-1])) |
408 |
depth = availableDepths[-1] |
409 |
id.xsetup.xhwstate.set_colordepth(depth) |
410 |
|
411 |
if resolution: |
412 |
availableRes = id.xsetup.xhwstate.available_resolutions() |
413 |
if resolution not in availableRes: |
414 |
log("Requested resolution %s is not supported, falling " |
415 |
"back to %s. To avoid this you may need to specify the " |
416 |
"videocard and monitor specs on the xconfig ks " |
417 |
"directive if they were not probed correctly." |
418 |
%(resolution, availableRes[-1])) |
419 |
resolution = availableRes[-1] |
420 |
id.xsetup.xhwstate.set_resolution(resolution) |
421 |
|
422 |
if not resolution and not depth: |
423 |
# choose a sane default |
424 |
log("resolution and depth not specified, trying to be sane") |
425 |
id.xsetup.xhwstate.choose_sane_default() |
426 |
|
427 |
if desktop is not None: |
428 |
id.desktop.setDefaultDesktop(desktop) |
429 |
if runlevel is not None: |
430 |
id.desktop.setDefaultRunLevel(runlevel) |
431 |
|
432 |
def setMonitor(self, id, hsync = None, vsync = None, monitorName = None): |
433 |
if monitorName: |
434 |
usemon = monitorName |
435 |
elif id.monitor.getMonitorID() != "Unprobed Monitor": |
436 |
usemon = id.monitor.getMonitorName() |
437 |
else: |
438 |
usemon = None |
439 |
|
440 |
setmonitor = 0 |
441 |
if usemon: |
442 |
monname = usemon |
443 |
try: |
444 |
(model, eisa, vert, horiz) = id.monitor.lookupMonitorByName(usemon) |
445 |
if id.monitor.getMonitorID() != "DDCPROBED": |
446 |
useid = model |
447 |
else: |
448 |
useid = "DDCPROBED" |
449 |
|
450 |
if not vsync: |
451 |
vsync = vert |
452 |
if not hsync: |
453 |
hsync = horiz |
454 |
|
455 |
id.monitor.setSpecs(hsync, vsync, id=useid, name=model) |
456 |
setmonitor = 1 |
457 |
except: |
458 |
log("Couldnt lookup monitor type %s." % usemon) |
459 |
pass |
460 |
else: |
461 |
monname = "Unprobed Monitor" |
462 |
|
463 |
if not setmonitor and hsync and vsync: |
464 |
id.monitor.setSpecs(hsync, vsync) |
465 |
setmonitor = 1 |
466 |
|
467 |
if not setmonitor: |
468 |
# fall back to standard VGA |
469 |
log("Could not probe monitor, and no fallback specified.") |
470 |
log("Falling back to Generic VGA monitor") |
471 |
|
472 |
try: |
473 |
hsync = "31.5-37.9" |
474 |
vsync = "50.0-61.0" |
475 |
monname = "Unprobed Monitor" |
476 |
id.monitor.setSpecs(hsync, vsync) |
477 |
except: |
478 |
raise RuntimeError, "Could not probe monitor and fallback failed." |
479 |
|
480 |
# shove into hw state object, force it to recompute available modes |
481 |
id.xsetup.xhwstate.monitor = id.monitor |
482 |
id.xsetup.xhwstate.set_monitor_name(monname) |
483 |
id.xsetup.xhwstate.set_hsync(hsync) |
484 |
id.xsetup.xhwstate.set_vsync(vsync) |
485 |
id.xsetup.xhwstate.recalc_mode() |
486 |
|
487 |
def setVideoCard(self, id, server = None, card = None, videoRam = None): |
488 |
# oh suck. if on ppc, bail because nothing other than fbdev is |
489 |
# going to work all that well |
490 |
if iutil.getArch() == "ppc": |
491 |
return |
492 |
|
493 |
primary = id.videocard.primaryCard() |
494 |
|
495 |
if card: |
496 |
db = id.videocard.cardsDB() |
497 |
if db.has_key(card): |
498 |
vcdata = db[card] |
499 |
primary.setCardData(vcdata) |
500 |
primary.setDevID(vcdata["NAME"]) |
501 |
primary.setDescription(vcdata["NAME"]) |
502 |
|
503 |
id.xsetup.xhwstate.set_videocard_name(vcdata["NAME"]) |
504 |
id.xsetup.xhwstate.set_videocard_card(vcdata["NAME"]) |
505 |
else: |
506 |
raise RuntimeError, "Unknown videocard specified: %s" %(card,) |
507 |
|
508 |
if videoRam: |
509 |
# FIXME: this required casting is ugly |
510 |
id.videocard.primaryCard().setVideoRam(str(videoRam)) |
511 |
id.xsetup.xhwstate.set_videocard_ram(int(videoRam)) |
512 |
|
513 |
if server is not None: |
514 |
log("unable to really do anything with server right now") |
515 |
|
516 |
|
517 |
def configureX(self, id, server = None, card = None, videoRam = None, monitorName = None, hsync = None, vsync = None, resolution = None, depth = None, noProbe = 0, startX = 0): |
518 |
self.setVideoCard(id, server, card, videoRam) |
519 |
self.setMonitor(id, hsync, vsync, monitorName) |
520 |
|
521 |
if startX: |
522 |
rl = 5 |
523 |
else: |
524 |
rl = 3 |
525 |
self.setMiscXSettings(id, depth, resolution, runlevel = rl) |
526 |
|
527 |
def setMouse(self, id, mouseType, device = None, emulThree = -1): |
528 |
import rhpl.mouse as mouse |
529 |
|
530 |
# blindly trust what we're told |
531 |
mouse = mouse.Mouse(skipProbe = 1) |
532 |
mouseName = mouse.mouseToMouse()[mouseType] |
533 |
mouse.set(mouseName, emulThree, device) |
534 |
id.setMouse(mouse) |
535 |
|
536 |
def setDefaultPartitioning(self, partitions, clear = CLEARPART_TYPE_LINUX, |
537 |
doClear = 1): |
538 |
autorequests = [ ("/", None, 1024, None, 1, 1, 1) ] |
539 |
|
540 |
bootreq = getAutopartitionBoot() |
541 |
if bootreq: |
542 |
autorequests.extend(bootreq) |
543 |
|
544 |
(minswap, maxswap) = iutil.swapSuggestion() |
545 |
autorequests.append((None, "swap", minswap, maxswap, 1, 1, 1)) |
546 |
|
547 |
if doClear: |
548 |
partitions.autoClearPartType = clear |
549 |
partitions.autoClearPartDrives = [] |
550 |
partitions.autoPartitionRequests = autoCreateLVMPartitionRequests(autorequests) |
551 |
|
552 |
|
553 |
def setInstallData(self, id, intf = None): |
554 |
id.reset() |
555 |
id.instClass = self |
556 |
|
557 |
# Classes should call these on __init__ to set up install data |
558 |
#id.setKeyboard() |
559 |
#id.setLanguage() |
560 |
#id.setNetwork() |
561 |
#id.setFirewall() |
562 |
#id.setLanguageSupport() |
563 |
#id.setLanguageDefault() |
564 |
#id.setTimezone() |
565 |
#id.setRootPassword() |
566 |
#id.setAuthentication() |
567 |
#id.setHostname() |
568 |
#id.setDesktop() |
569 |
#id.setMouse() |
570 |
|
571 |
# These are callbacks used to let classes configure packages |
572 |
#id.setPackageSelection() |
573 |
#id.setGroupSelection() |
574 |
|
575 |
def __init__(self, expert): |
576 |
pass |
577 |
|
578 |
# we need to be able to differentiate between this and custom |
579 |
class DefaultInstall(BaseInstallClass): |
580 |
def __init__(self, expert): |
581 |
BaseInstallClass.__init__(self, expert) |
582 |
|
583 |
allClasses = [] |
584 |
allClasses_hidden = [] |
585 |
|
586 |
# returns ( className, classObject, classLogo ) tuples |
587 |
def availableClasses(showHidden=0): |
588 |
global allClasses |
589 |
global allClasses_hidden |
590 |
|
591 |
if not showHidden: |
592 |
if allClasses: return allClasses |
593 |
else: |
594 |
if allClasses_hidden: return allClasses_hidden |
595 |
|
596 |
if os.access("installclasses", os.R_OK): |
597 |
path = "installclasses" |
598 |
elif os.access("/tmp/product/installclasses", os.R_OK): |
599 |
path = "/tmp/product/installclasses" |
600 |
else: |
601 |
path = "/usr/lib/anaconda/installclasses" |
602 |
|
603 |
# append the location of installclasses to the python path so we |
604 |
# can import them |
605 |
sys.path.append(path) |
606 |
|
607 |
files = os.listdir(path) |
608 |
done = {} |
609 |
list = [] |
610 |
for file in files: |
611 |
if file[0] == '.': continue |
612 |
if len (file) < 4: |
613 |
continue |
614 |
if file[-3:] != ".py" and file[-4:-1] != ".py": |
615 |
continue |
616 |
mainName = string.split(file, ".")[0] |
617 |
if done.has_key(mainName): continue |
618 |
done[mainName] = 1 |
619 |
|
620 |
obj = None |
621 |
cmd = "import %s\nif %s.__dict__.has_key('InstallClass'): obj = %s.InstallClass\n" % (mainName, mainName, mainName) |
622 |
exec(cmd) |
623 |
|
624 |
if obj: |
625 |
if obj.__dict__.has_key('sortPriority'): |
626 |
sortOrder = obj.sortPriority |
627 |
else: |
628 |
sortOrder = 0 |
629 |
|
630 |
if obj.__dict__.has_key('arch'): |
631 |
if obj.arch != iutil.getArch (): |
632 |
obj.hidden = 1 |
633 |
|
634 |
if obj.hidden == 0 or showHidden == 1: |
635 |
list.append(((obj.name, obj, obj.pixmap), sortOrder)) |
636 |
|
637 |
list.sort(ordering) |
638 |
for (item, priority) in list: |
639 |
if showHidden: |
640 |
allClasses_hidden.append(item) |
641 |
else: |
642 |
allClasses.append(item) |
643 |
|
644 |
if showHidden: |
645 |
return allClasses_hidden |
646 |
else: |
647 |
return allClasses |
648 |
|
649 |
def ordering(first, second): |
650 |
((name1, obj, logo), priority1) = first |
651 |
((name2, obj, logo), priority2) = second |
652 |
|
653 |
if priority1 < priority2: |
654 |
return -1 |
655 |
elif priority1 > priority2: |
656 |
return 1 |
657 |
|
658 |
if name1 < name2: |
659 |
return -1 |
660 |
elif name1 > name2: |
661 |
return 1 |
662 |
|
663 |
return 0 |
664 |
|
665 |
|
666 |
def requireDisplayMode(): |
667 |
return None |