1 |
gordonr |
1.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 |