1 |
slords |
1.1 |
# |
2 |
|
|
# packages.py: package management - mainly package installation |
3 |
|
|
# |
4 |
|
|
# Erik Troan <ewt@redhat.com> |
5 |
|
|
# Matt Wilson <msw@redhat.com> |
6 |
|
|
# Michael Fulbright <msf@redhat.com> |
7 |
|
|
# Jeremy Katz <katzj@redhat.com> |
8 |
|
|
# |
9 |
|
|
# Copyright 2001-2003 Red Hat, Inc. |
10 |
|
|
# |
11 |
|
|
# This software may be freely redistributed under the terms of the GNU |
12 |
|
|
# library public license. |
13 |
|
|
# |
14 |
|
|
# You should have received a copy of the GNU Library Public License |
15 |
|
|
# along with this program; if not, write to the Free Software |
16 |
|
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
17 |
|
|
# |
18 |
|
|
|
19 |
|
|
import iutil |
20 |
|
|
import isys |
21 |
|
|
import rpm |
22 |
|
|
import hdrlist |
23 |
|
|
import os |
24 |
|
|
import timer |
25 |
|
|
import time |
26 |
|
|
import sys |
27 |
|
|
import string |
28 |
|
|
import pcmcia |
29 |
|
|
import language |
30 |
|
|
import fsset |
31 |
|
|
import kudzu |
32 |
|
|
from flags import flags |
33 |
|
|
from product import * |
34 |
|
|
from constants import * |
35 |
|
|
from syslogd import syslog |
36 |
|
|
from hdrlist import PKGTYPE_MANDATORY, PKGTYPE_DEFAULT, DependencyChecker |
37 |
|
|
from installmethod import FileCopyException |
38 |
|
|
|
39 |
|
|
from rhpl.log import log |
40 |
|
|
from rhpl.translate import _ |
41 |
|
|
import rhpl.arch |
42 |
|
|
|
43 |
|
|
def queryUpgradeContinue(intf, dir): |
44 |
|
|
if dir == DISPATCH_FORWARD: |
45 |
|
|
return |
46 |
|
|
|
47 |
|
|
rc = intf.messageWindow(_("Proceed with upgrade?"), |
48 |
|
|
_("The file systems of the Linux installation " |
49 |
|
|
"you have chosen to upgrade have already been " |
50 |
|
|
"mounted. You cannot go back past this point. " |
51 |
|
|
"\n\n") + |
52 |
|
|
_( "Would you like to continue with the upgrade?"), |
53 |
|
|
type = "yesno") |
54 |
|
|
if rc == 0: |
55 |
|
|
sys.exit(0) |
56 |
|
|
return DISPATCH_FORWARD |
57 |
|
|
|
58 |
|
|
def doPostAction(id, instPath): |
59 |
|
|
id.instClass.postAction(instPath, flags.serial) |
60 |
|
|
|
61 |
|
|
def firstbootConfiguration(id, instPath): |
62 |
|
|
if id.firstboot == FIRSTBOOT_RECONFIG: |
63 |
|
|
f = open(instPath + '/etc/reconfigSys', 'w+') |
64 |
|
|
f.close() |
65 |
|
|
elif id.firstboot == FIRSTBOOT_SKIP: |
66 |
|
|
f = open(instPath + '/etc/sysconfig/firstboot', 'w+') |
67 |
|
|
f.write('RUN_FIRSTBOOT=NO') |
68 |
|
|
f.close() |
69 |
|
|
|
70 |
|
|
return |
71 |
|
|
|
72 |
|
|
|
73 |
|
|
def writeConfiguration(id, instPath): |
74 |
|
|
log("Writing main configuration") |
75 |
|
|
if not flags.test: |
76 |
|
|
id.write(instPath) |
77 |
|
|
|
78 |
|
|
def writeKSConfiguration(id, instPath): |
79 |
|
|
log("Writing autokickstart file") |
80 |
|
|
if not flags.test: |
81 |
|
|
fn = instPath + "/root/anaconda-ks.cfg" |
82 |
|
|
else: |
83 |
|
|
fn = "/tmp/anaconda-ks.cfg" |
84 |
|
|
|
85 |
|
|
id.writeKS(fn) |
86 |
|
|
|
87 |
|
|
def copyAnacondaLogs(instPath): |
88 |
|
|
log("Copying anaconda logs") |
89 |
|
|
for (fn, dest) in (("/tmp/anaconda.log", "anaconda.log"), |
90 |
|
|
("/tmp/syslog", "anaconda.syslog"), |
91 |
|
|
("/tmp/ramfs/X.log", "anaconda.xlog")): |
92 |
|
|
if os.access(fn, os.R_OK): |
93 |
|
|
try: |
94 |
|
|
iutil.copyFile(fn, "%s/var/log/%s" %(instPath, dest)) |
95 |
|
|
os.chmod("%s/var/log/%s" %(instPath, dest), 0600) |
96 |
|
|
except: |
97 |
|
|
pass |
98 |
|
|
|
99 |
|
|
def writeXConfiguration(id, instPath): |
100 |
|
|
testmode = flags.test |
101 |
|
|
|
102 |
|
|
# comment out to test |
103 |
|
|
if testmode: |
104 |
|
|
return |
105 |
|
|
# end code to comment to test |
106 |
|
|
# uncomment to test writing X config in test mode |
107 |
|
|
# try: |
108 |
|
|
# os.mkdir("/tmp/etc") |
109 |
|
|
# except: |
110 |
|
|
# pass |
111 |
|
|
# try: |
112 |
|
|
# os.mkdir("/tmp/etc/X11") |
113 |
|
|
# except: |
114 |
|
|
# pass |
115 |
|
|
# instPath = '/' |
116 |
|
|
# end code for test writing |
117 |
|
|
|
118 |
|
|
if id.xsetup.skipx: |
119 |
|
|
return |
120 |
|
|
|
121 |
|
|
xserver = id.videocard.primaryCard().getXServer() |
122 |
|
|
if not xserver: |
123 |
|
|
return |
124 |
|
|
|
125 |
|
|
log("Writing X configuration") |
126 |
|
|
if not testmode: |
127 |
|
|
fn = instPath |
128 |
|
|
|
129 |
|
|
if os.access (instPath + "/etc/X11/X", os.R_OK): |
130 |
|
|
os.rename (instPath + "/etc/X11/X", |
131 |
|
|
instPath + "/etc/X11/X.rpmsave") |
132 |
|
|
|
133 |
|
|
try: |
134 |
|
|
os.unlink (instPath + "/etc/X11/X") |
135 |
|
|
except OSError: |
136 |
|
|
pass |
137 |
|
|
|
138 |
|
|
os.symlink ("../../usr/X11R6/bin/" + xserver, |
139 |
|
|
instPath + "/etc/X11/X") |
140 |
|
|
else: |
141 |
|
|
fn = "/tmp/" |
142 |
|
|
|
143 |
|
|
id.xsetup.write(fn+"/etc/X11", id.mouse, id.keyboard) |
144 |
|
|
id.desktop.write(instPath) |
145 |
|
|
|
146 |
|
|
def readPackages(intf, method, id): |
147 |
|
|
if id.grpset: |
148 |
|
|
grpset = id.grpset |
149 |
|
|
hdrlist = id.grpset.hdrlist |
150 |
|
|
doselect = 0 |
151 |
|
|
else: |
152 |
|
|
grpset = None |
153 |
|
|
hdrlist = None |
154 |
|
|
doselect = 1 |
155 |
|
|
|
156 |
|
|
while hdrlist is None: |
157 |
|
|
w = intf.waitWindow(_("Reading"), _("Reading package information...")) |
158 |
|
|
try: |
159 |
|
|
hdrlist = method.readHeaders() |
160 |
|
|
except FileCopyException: |
161 |
|
|
w.pop() |
162 |
|
|
method.unmountCD() |
163 |
|
|
intf.messageWindow(_("Error"), |
164 |
|
|
_("Unable to read header list. This may be " |
165 |
|
|
"due to a missing file or bad media. " |
166 |
|
|
"Press <return> to try again.")) |
167 |
|
|
continue |
168 |
|
|
|
169 |
|
|
w.pop() |
170 |
|
|
|
171 |
|
|
while grpset is None: |
172 |
|
|
try: |
173 |
|
|
grpset = method.readComps(hdrlist) |
174 |
|
|
except FileCopyException: |
175 |
|
|
method.unmountCD() |
176 |
|
|
intf.messageWindow(_("Error"), |
177 |
|
|
_("Unable to read comps file. This may be " |
178 |
|
|
"due to a missing file or bad media. " |
179 |
|
|
"Press <return> to try again.")) |
180 |
|
|
continue |
181 |
|
|
|
182 |
|
|
# people make bad tree copies all the time. let's just mandate that |
183 |
|
|
# the Core group has to exist in the comps file else we complain |
184 |
|
|
if not grpset.groups.has_key("core"): |
185 |
|
|
intf.messageWindow(_("Error"), |
186 |
|
|
_("The comps file in your installation tree is " |
187 |
|
|
"missing critical groups. Please ensure that " |
188 |
|
|
"your install tree has been correctly " |
189 |
|
|
"generated."), |
190 |
|
|
type="custom", custom_icon="error", |
191 |
|
|
custom_buttons=[_("_Exit")]) |
192 |
|
|
sys.exit(0) |
193 |
|
|
|
194 |
|
|
while iutil.getArch() == "ia64": |
195 |
|
|
try: |
196 |
|
|
method.mergeFullHeaders(hdrlist) |
197 |
|
|
break |
198 |
|
|
except FileCopyException: |
199 |
|
|
method.unmountCD() |
200 |
|
|
intf.messageWindow(_("Error"), |
201 |
|
|
_("Unable to merge header list. This may be " |
202 |
|
|
"due to a missing file or bad media. " |
203 |
|
|
"Press <return> to try again.")) |
204 |
|
|
|
205 |
|
|
# this is a crappy hack, but I don't want bug reports from these people |
206 |
|
|
if (iutil.getArch() == "i386") and (not grpset.hdrlist.has_key("kernel")): |
207 |
|
|
intf.messageWindow(_("Error"), |
208 |
|
|
_("You are trying to install on a machine " |
209 |
|
|
"which isn't supported by this release of " |
210 |
|
|
"%s.") %(productName,), |
211 |
|
|
type="custom", custom_icon="error", |
212 |
|
|
custom_buttons=[_("_Exit")]) |
213 |
|
|
sys.exit(0) |
214 |
|
|
|
215 |
|
|
id.grpset = grpset |
216 |
|
|
|
217 |
|
|
if doselect: |
218 |
|
|
id.instClass.setGroupSelection(grpset, intf) |
219 |
|
|
id.instClass.setPackageSelection(hdrlist, intf) |
220 |
|
|
|
221 |
|
|
def handleX11Packages(dir, intf, disp, id, instPath): |
222 |
|
|
|
223 |
|
|
if dir == DISPATCH_BACK: |
224 |
|
|
return |
225 |
|
|
|
226 |
|
|
# skip X setup if it is not being installed |
227 |
|
|
# |
228 |
|
|
# uncomment this block if you want X configuration to be presented |
229 |
|
|
# |
230 |
|
|
# START BLOCK |
231 |
|
|
# if (not id.grpset.hdrlist.has_key('XFree86') or |
232 |
|
|
# not id.grpset.hdrlist['XFree86'].isSelected()): |
233 |
|
|
# disp.skipStep("videocard") |
234 |
|
|
# disp.skipStep("monitor") |
235 |
|
|
# disp.skipStep("xcustom") |
236 |
|
|
# disp.skipStep("writexconfig") |
237 |
|
|
# id.xsetup.skipx = 1 |
238 |
|
|
# elif disp.stepInSkipList("videocard"): |
239 |
|
|
# # if X is being installed, but videocard step skipped |
240 |
|
|
# # need to turn it back on |
241 |
|
|
# disp.skipStep("videocard", skip=0) |
242 |
|
|
# disp.skipStep("monitor", skip=0) |
243 |
|
|
# disp.skipStep("xcustom", skip=0) |
244 |
|
|
# disp.skipStep("writexconfig", skip=0) |
245 |
|
|
# id.xsetup.skipx = 0 |
246 |
|
|
# END BLOCK |
247 |
|
|
|
248 |
|
|
# set default runlevel based on packages |
249 |
|
|
gnomeSelected = (id.grpset.hdrlist.has_key('gnome-session') |
250 |
|
|
and id.grpset.hdrlist['gnome-session'].isSelected()) |
251 |
|
|
gdmSelected = (id.grpset.hdrlist.has_key('gdm') |
252 |
|
|
and id.grpset.hdrlist['gdm'].isSelected()) |
253 |
|
|
kdeSelected = (id.grpset.hdrlist.has_key('kdebase') |
254 |
|
|
and id.grpset.hdrlist['kdebase'].isSelected()) |
255 |
|
|
xinstalled = ((id.grpset.hdrlist.has_key('xorg-x11') |
256 |
|
|
and id.grpset.hdrlist['xorg-x11'].isSelected()) or |
257 |
|
|
(id.grpset.hdrlist.has_key('XFree86') |
258 |
|
|
and id.grpset.hdrlist['XFree86'].isSelected())) |
259 |
|
|
|
260 |
|
|
if gnomeSelected: |
261 |
|
|
id.desktop.setDefaultDesktop("GNOME") |
262 |
|
|
elif kdeSelected: |
263 |
|
|
id.desktop.setDefaultDesktop("KDE") |
264 |
|
|
|
265 |
|
|
if (gdmSelected or kdeSelected) and (xinstalled) and (not flags.serial) and (not flags.virtpconsole): |
266 |
|
|
id.desktop.setDefaultRunLevel(5) |
267 |
|
|
else: |
268 |
|
|
id.desktop.setDefaultRunLevel(3) |
269 |
|
|
|
270 |
|
|
# verifies that monitor is not Unprobed, and if so we can skip monitor question |
271 |
|
|
def checkMonitorOK(monitor, dispatch): |
272 |
|
|
rc = 0 |
273 |
|
|
if monitor is not None: |
274 |
|
|
if monitor.getMonitorID() != "Unprobed Monitor": |
275 |
|
|
rc = 1 |
276 |
|
|
|
277 |
|
|
dispatch.skipStep("monitor", skip=rc) |
278 |
|
|
|
279 |
|
|
# sets a reasonable default for X settings. |
280 |
|
|
def setSaneXSettings(xsetup): |
281 |
|
|
if xsetup is not None and xsetup.xhwstate is not None: |
282 |
|
|
if not xsetup.imposed_sane_default: |
283 |
|
|
# XXX HACK see if we have a user specified LCD display |
284 |
|
|
import re |
285 |
|
|
|
286 |
|
|
regx = re.compile("LCD Panel .*x.*") |
287 |
|
|
monid = xsetup.xhwstate.monitor.getMonitorID() |
288 |
|
|
lcdres = None |
289 |
|
|
if regx.match(monid): |
290 |
|
|
for testres in ["640x480", "800x600", "1024x480", "1024x768", |
291 |
|
|
"1280x960", "1280x1024", "1400x1050", |
292 |
|
|
"1600x1200"]: |
293 |
|
|
if string.find(monid, testres) != -1: |
294 |
|
|
lcdres = testres |
295 |
|
|
break |
296 |
|
|
|
297 |
|
|
if lcdres is not None: |
298 |
|
|
xsetup.xhwstate.set_resolution(lcdres) |
299 |
|
|
else: |
300 |
|
|
xsetup.xhwstate.choose_sane_default() |
301 |
|
|
xsetup.imposed_sane_default = 1 |
302 |
|
|
|
303 |
|
|
def getAnacondaTS(instPath = None): |
304 |
|
|
if instPath: |
305 |
|
|
ts = rpm.TransactionSet(instPath) |
306 |
|
|
else: |
307 |
|
|
ts = rpm.TransactionSet() |
308 |
|
|
ts.setVSFlags(~(rpm.RPMVSF_NORSA|rpm.RPMVSF_NODSA)) |
309 |
|
|
ts.setFlags(rpm.RPMTRANS_FLAG_ANACONDA) |
310 |
|
|
|
311 |
|
|
# set color if needed. FIXME: why isn't this the default :/ |
312 |
|
|
if (rhpl.arch.canonArch.startswith("ppc64") or |
313 |
|
|
rhpl.arch.canonArch in ("s390x", "sparc64", "x86_64", "ia64")): |
314 |
|
|
ts.setColor(3) |
315 |
|
|
|
316 |
|
|
return ts |
317 |
|
|
|
318 |
|
|
def checkDependencies(dir, intf, disp, id, instPath): |
319 |
|
|
if dir == DISPATCH_BACK: |
320 |
|
|
return |
321 |
|
|
|
322 |
|
|
win = intf.waitWindow(_("Dependency Check"), |
323 |
|
|
_("Checking dependencies in packages selected for installation...")) |
324 |
|
|
|
325 |
|
|
# FIXME: we really don't need to build up a ts more than once |
326 |
|
|
# granted, this is better than before still |
327 |
|
|
if id.upgrade.get(): |
328 |
|
|
ts = getAnacondaTS(instPath) |
329 |
|
|
how = "u" |
330 |
|
|
else: |
331 |
|
|
ts = getAnacondaTS() |
332 |
|
|
how = "i" |
333 |
|
|
|
334 |
|
|
# set the rpm log file to /dev/null so that we don't segfault |
335 |
|
|
f = open("/dev/null", "w+") |
336 |
|
|
rpm.setLogFile(f) |
337 |
|
|
ts.scriptFd = f.fileno() |
338 |
|
|
|
339 |
|
|
for p in id.grpset.hdrlist.pkgs.values(): |
340 |
|
|
if p.isSelected(): |
341 |
|
|
ts.addInstall(p.hdr, p.hdr, how) |
342 |
|
|
depcheck = DependencyChecker(id.grpset, how) |
343 |
|
|
id.dependencies = ts.check(depcheck.callback) |
344 |
|
|
|
345 |
|
|
win.pop() |
346 |
|
|
|
347 |
|
|
if depcheck.added and id.handleDeps == CHECK_DEPS: |
348 |
|
|
disp.skipStep("dependencies", skip = 0) |
349 |
|
|
log("had unresolved dependencies, resolved.") |
350 |
|
|
disp.skipStep("dependencies") |
351 |
|
|
else: |
352 |
|
|
disp.skipStep("dependencies") |
353 |
|
|
|
354 |
|
|
return |
355 |
|
|
# FIXME: I BROKE IT |
356 |
|
|
# this is kind of hackish, but makes kickstart happy |
357 |
|
|
if id.handleDeps == CHECK_DEPS: |
358 |
|
|
pass |
359 |
|
|
elif id.handleDeps == IGNORE_DEPS: |
360 |
|
|
id.comps.selectDepCause(id.dependencies) |
361 |
|
|
id.comps.unselectDeps(id.dependencies) |
362 |
|
|
elif id.handleDeps == RESOLVE_DEPS: |
363 |
|
|
id.comps.selectDepCause(id.dependencies) |
364 |
|
|
id.comps.selectDeps(id.dependencies) |
365 |
|
|
|
366 |
|
|
class InstallCallback: |
367 |
|
|
def packageDownloadCB(self, state, amount): |
368 |
|
|
self.progress.setPackageStatus(state, amount) |
369 |
|
|
|
370 |
|
|
def cb(self, what, amount, total, h, (param)): |
371 |
|
|
# first time here means we should pop the window telling |
372 |
|
|
# user to wait until we get here |
373 |
|
|
if not self.beenCalled: |
374 |
|
|
self.beenCalled = 1 |
375 |
|
|
self.initWindow.pop() |
376 |
|
|
|
377 |
|
|
if (what == rpm.RPMCALLBACK_TRANS_START): |
378 |
|
|
# step 6 is the bulk of the transaction set |
379 |
|
|
# processing time |
380 |
|
|
if amount == 6: |
381 |
|
|
self.progressWindow = \ |
382 |
|
|
self.progressWindowClass (_("Processing"), |
383 |
|
|
_("Preparing to install..."), |
384 |
|
|
total) |
385 |
|
|
try: |
386 |
|
|
self.incr = total / 10 |
387 |
|
|
except: |
388 |
|
|
pass |
389 |
|
|
if (what == rpm.RPMCALLBACK_TRANS_PROGRESS): |
390 |
|
|
if self.progressWindow and amount > self.lastprogress + self.incr: |
391 |
|
|
self.progressWindow.set (amount) |
392 |
|
|
self.lastprogress = amount |
393 |
|
|
|
394 |
|
|
if (what == rpm.RPMCALLBACK_TRANS_STOP and self.progressWindow): |
395 |
|
|
self.progressWindow.pop () |
396 |
|
|
|
397 |
|
|
if (what == rpm.RPMCALLBACK_INST_OPEN_FILE): |
398 |
|
|
# We don't want to start the timer until we get to the first |
399 |
|
|
# file. |
400 |
|
|
self.pkgTimer.start() |
401 |
|
|
|
402 |
|
|
self.progress.setPackage(h) |
403 |
|
|
self.progress.setPackageScale(0, 1) |
404 |
|
|
self.instLog.write (self.modeText % (hdrlist.nevra(h))) |
405 |
|
|
self.instLog.flush () |
406 |
|
|
|
407 |
|
|
self.rpmFD = -1 |
408 |
|
|
self.size = h[rpm.RPMTAG_SIZE] |
409 |
|
|
|
410 |
|
|
while self.rpmFD < 0: |
411 |
|
|
try: |
412 |
|
|
fn = self.method.getRPMFilename(h, self.pkgTimer, |
413 |
|
|
callback=self.packageDownloadCB) |
414 |
|
|
self.rpmFD = os.open(fn, os.O_RDONLY) |
415 |
|
|
|
416 |
|
|
# Make sure this package seems valid |
417 |
|
|
try: |
418 |
|
|
hdr = self.ts.hdrFromFdno(self.rpmFD) |
419 |
|
|
os.lseek(self.rpmFD, 0, 0) |
420 |
|
|
|
421 |
|
|
# if we don't have a valid package, throw an error |
422 |
|
|
if not hdr: |
423 |
|
|
raise SystemError |
424 |
|
|
|
425 |
|
|
except: |
426 |
|
|
try: |
427 |
|
|
os.close(self.rpmFD) |
428 |
|
|
except: |
429 |
|
|
pass |
430 |
|
|
self.rpmFD = -1 |
431 |
|
|
raise FileCopyException |
432 |
|
|
except Exception, e: |
433 |
|
|
log("exception was %s for %s-%s-%s" %(e, h['name'], |
434 |
|
|
h['version'], |
435 |
|
|
h['release'])) |
436 |
|
|
|
437 |
|
|
self.method.unmountCD() |
438 |
|
|
self.messageWindow(_("Error"), |
439 |
|
|
_("The package %s-%s-%s cannot be opened. This is due " |
440 |
|
|
"to a missing file or perhaps a corrupt package. " |
441 |
|
|
"If you are installing from CD media this usually " |
442 |
|
|
"means the CD media is corrupt, or the CD drive is " |
443 |
|
|
"unable to read the media.\n\n" |
444 |
|
|
"Press <return> to try again.") % (h['name'], |
445 |
|
|
h['version'], |
446 |
|
|
h['release'])) |
447 |
|
|
self.progress.setPackageStatus(_("Installing..."), None) |
448 |
|
|
fn = self.method.unlinkFilename(fn) |
449 |
|
|
return self.rpmFD |
450 |
|
|
elif (what == rpm.RPMCALLBACK_INST_PROGRESS): |
451 |
|
|
# RPM returns strange values sometimes |
452 |
|
|
if amount > total: |
453 |
|
|
amount = total |
454 |
|
|
if not total or total == 0 or total == "0": |
455 |
|
|
total = amount |
456 |
|
|
self.progress.setPackageScale(amount, total) |
457 |
|
|
elif (what == rpm.RPMCALLBACK_INST_CLOSE_FILE): |
458 |
|
|
os.close (self.rpmFD) |
459 |
|
|
self.progress.completePackage(h, self.pkgTimer) |
460 |
|
|
self.progress.processEvents() |
461 |
|
|
elif ((what == rpm.RPMCALLBACK_UNPACK_ERROR) or |
462 |
|
|
(what == rpm.RPMCALLBACK_CPIO_ERROR)): |
463 |
|
|
# we may want to make this error more fine-grained at some |
464 |
|
|
# point |
465 |
|
|
pkg = "%s-%s-%s" % (h[rpm.RPMTAG_NAME], |
466 |
|
|
h[rpm.RPMTAG_VERSION], |
467 |
|
|
h[rpm.RPMTAG_RELEASE]) |
468 |
|
|
self.messageWindow(_("Error Installing Package"), |
469 |
|
|
_("There was an error installing %s. This " |
470 |
|
|
"can indicate media failure, lack of disk " |
471 |
|
|
"space, and/or hardware problems. This is " |
472 |
|
|
"a fatal error and your install will be " |
473 |
|
|
"aborted. Please verify your media and try " |
474 |
|
|
"your install again.\n\n" |
475 |
|
|
"Press the OK button to reboot " |
476 |
|
|
"your system.") % (pkg,)) |
477 |
|
|
sys.exit(0) |
478 |
|
|
else: |
479 |
|
|
pass |
480 |
|
|
|
481 |
|
|
self.progress.processEvents() |
482 |
|
|
|
483 |
|
|
def __init__(self, messageWindow, progress, pkgTimer, method, |
484 |
|
|
progressWindowClass, instLog, modeText, ts): |
485 |
|
|
self.messageWindow = messageWindow |
486 |
|
|
self.progress = progress |
487 |
|
|
self.pkgTimer = pkgTimer |
488 |
|
|
self.method = method |
489 |
|
|
self.progressWindowClass = progressWindowClass |
490 |
|
|
self.progressWindow = None |
491 |
|
|
self.lastprogress = 0 |
492 |
|
|
self.incr = 20 |
493 |
|
|
self.instLog = instLog |
494 |
|
|
self.modeText = modeText |
495 |
|
|
self.beenCalled = 0 |
496 |
|
|
self.initWindow = None |
497 |
|
|
self.ts = ts |
498 |
|
|
|
499 |
|
|
def sortPackages(first, second): |
500 |
|
|
# install packages in cd order (cd tag is 1000002) |
501 |
|
|
one = None |
502 |
|
|
two = None |
503 |
|
|
|
504 |
|
|
if first[1000003] != None: |
505 |
|
|
one = first[1000003] |
506 |
|
|
|
507 |
|
|
if second[1000003] != None: |
508 |
|
|
two = second[1000003] |
509 |
|
|
|
510 |
|
|
if one == None or two == None: |
511 |
|
|
one = 0 |
512 |
|
|
two = 0 |
513 |
|
|
if first[1000002] != None: |
514 |
|
|
one = first[1000002] |
515 |
|
|
|
516 |
|
|
if second[1000002] != None: |
517 |
|
|
two = second[1000002] |
518 |
|
|
|
519 |
|
|
if one < two: |
520 |
|
|
return -1 |
521 |
|
|
elif one > two: |
522 |
|
|
return 1 |
523 |
|
|
elif (string.lower(first[rpm.RPMTAG_NAME]) |
524 |
|
|
< string.lower(second[rpm.RPMTAG_NAME])): |
525 |
|
|
return -1 |
526 |
|
|
elif (string.lower(first[rpm.RPMTAG_NAME]) |
527 |
|
|
> string.lower(second[rpm.RPMTAG_NAME])): |
528 |
|
|
return 1 |
529 |
|
|
|
530 |
|
|
return 0 |
531 |
|
|
|
532 |
|
|
class rpmErrorClass: |
533 |
|
|
|
534 |
|
|
def cb(self): |
535 |
|
|
self.f.write (rpm.errorString () + "\n") |
536 |
|
|
|
537 |
|
|
def __init__(self, f): |
538 |
|
|
self.f = f |
539 |
|
|
|
540 |
|
|
def doMigrateFilesystems(dir, thefsset, diskset, upgrade, instPath): |
541 |
|
|
if dir == DISPATCH_BACK: |
542 |
|
|
return DISPATCH_NOOP |
543 |
|
|
|
544 |
|
|
if thefsset.haveMigratedFilesystems(): |
545 |
|
|
return DISPATCH_NOOP |
546 |
|
|
|
547 |
|
|
thefsset.migrateFilesystems (instPath) |
548 |
|
|
|
549 |
|
|
# if we're upgrading, we may need to do lvm device node hackery |
550 |
|
|
if upgrade.get(): |
551 |
|
|
thefsset.makeLVMNodes(instPath, trylvm1 = 1) |
552 |
|
|
|
553 |
|
|
|
554 |
|
|
def turnOnFilesystems(dir, thefsset, diskset, partitions, upgrade, instPath): |
555 |
|
|
if dir == DISPATCH_BACK: |
556 |
|
|
log("unmounting filesystems") |
557 |
|
|
thefsset.umountFilesystems(instPath) |
558 |
|
|
return |
559 |
|
|
|
560 |
|
|
if flags.setupFilesystems: |
561 |
|
|
if not upgrade.get(): |
562 |
|
|
partitions.doMetaDeletes(diskset) |
563 |
|
|
thefsset.setActive(diskset) |
564 |
|
|
if not thefsset.isActive(): |
565 |
|
|
diskset.savePartitions () |
566 |
|
|
thefsset.checkBadblocks(instPath) |
567 |
|
|
if not thefsset.volumesCreated: |
568 |
|
|
thefsset.createLogicalVolumes(instPath) |
569 |
|
|
thefsset.formatSwap(instPath) |
570 |
|
|
thefsset.turnOnSwap(instPath) |
571 |
|
|
thefsset.makeFilesystems (instPath) |
572 |
|
|
thefsset.mountFilesystems (instPath) |
573 |
|
|
|
574 |
|
|
def setupTimezone(timezone, upgrade, instPath, dir): |
575 |
|
|
# we don't need this on an upgrade or going backwards |
576 |
|
|
if upgrade.get() or (dir == DISPATCH_BACK): |
577 |
|
|
return |
578 |
|
|
|
579 |
|
|
# dont do this in test mode! |
580 |
|
|
if flags.test: |
581 |
|
|
return |
582 |
|
|
|
583 |
|
|
os.environ["TZ"] = timezone.tz |
584 |
|
|
tzfile = "/usr/share/zoneinfo/" + timezone.tz |
585 |
|
|
if not os.access(tzfile, os.R_OK): |
586 |
|
|
log("unable to set timezone") |
587 |
|
|
else: |
588 |
|
|
try: |
589 |
|
|
iutil.copyFile(tzfile, "/etc/localtime") |
590 |
|
|
except OSError, (errno, msg): |
591 |
|
|
log("Error copying timezone (from %s): %s" %(tzfile, msg)) |
592 |
|
|
|
593 |
|
|
if iutil.getArch() == "s390": |
594 |
|
|
return |
595 |
|
|
args = [ "/usr/sbin/hwclock", "--hctosys" ] |
596 |
|
|
if timezone.utc: |
597 |
|
|
args.append("-u") |
598 |
|
|
elif timezone.arc: |
599 |
|
|
args.append("-a") |
600 |
|
|
|
601 |
|
|
try: |
602 |
|
|
iutil.execWithRedirect(args[0], args, stdin = None, |
603 |
|
|
stdout = "/dev/tty5", stderr = "/dev/tty5") |
604 |
|
|
except RuntimeError: |
605 |
|
|
log("Failed to set clock") |
606 |
|
|
|
607 |
|
|
|
608 |
|
|
|
609 |
|
|
def doPreInstall(method, id, intf, instPath, dir): |
610 |
|
|
if dir == DISPATCH_BACK: |
611 |
|
|
for d in ("/selinux", "/dev"): |
612 |
|
|
try: |
613 |
|
|
isys.umount(instPath + d, removeDir = 0) |
614 |
|
|
except Exception, e: |
615 |
|
|
log("unable to unmount %s: %s" %(d, e)) |
616 |
|
|
return |
617 |
|
|
|
618 |
|
|
arch = iutil.getArch () |
619 |
|
|
|
620 |
|
|
# this is a crappy hack, but I don't want bug reports from these people |
621 |
|
|
if (arch == "i386") and (not id.grpset.hdrlist.has_key("kernel")): |
622 |
|
|
intf.messageWindow(_("Error"), |
623 |
|
|
_("You are trying to install on a machine " |
624 |
|
|
"which isn't supported by this release of " |
625 |
|
|
"%s.") %(productName,), |
626 |
|
|
type="custom", custom_icon="error", |
627 |
|
|
custom_buttons=[_("_Exit")]) |
628 |
|
|
sys.exit(0) |
629 |
|
|
|
630 |
|
|
# shorthand |
631 |
|
|
upgrade = id.upgrade.get() |
632 |
|
|
|
633 |
|
|
def select(hdrlist, name): |
634 |
|
|
if hdrlist.has_key(name): |
635 |
|
|
hdrlist[name].select(isManual = 1) |
636 |
|
|
return 1 |
637 |
|
|
return 0 |
638 |
|
|
|
639 |
|
|
def selected(hdrlist, name): |
640 |
|
|
if hdrlist.has_key(name) and hdrlist[name].isSelected(): |
641 |
|
|
return 1 |
642 |
|
|
return 0 |
643 |
|
|
|
644 |
|
|
if not upgrade: |
645 |
|
|
foundkernel = 0 |
646 |
|
|
if isys.smpAvailable() or isys.htavailable(): |
647 |
|
|
if select(id.grpset.hdrlist, 'kernel-smp'): |
648 |
|
|
foundkernel = 1 |
649 |
|
|
if selected(id.grpset.hdrlist, "gcc"): |
650 |
|
|
select(id.grpset.hdrlist, "kernel-smp-devel") |
651 |
|
|
|
652 |
|
|
if iutil.needsEnterpriseKernel(): |
653 |
|
|
if select(id.grpset.hdrlist, "kernel-bigmem"): |
654 |
|
|
foundkernel = 1 |
655 |
|
|
|
656 |
|
|
if isys.summitavailable(): |
657 |
|
|
if select(id.grpset.hdrlist, "kernel-summit"): |
658 |
|
|
foundkernel = 1 |
659 |
|
|
|
660 |
|
|
if foundkernel == 0: |
661 |
|
|
# we *always* need to have some sort of kernel installed |
662 |
|
|
select(id.grpset.hdrlist, 'kernel') |
663 |
|
|
if selected(id.grpset.hdrlist, "gcc"): |
664 |
|
|
select(id.grpset.hdrlist, "kernel-devel") |
665 |
|
|
|
666 |
|
|
# if NIS is configured, install ypbind and dependencies: |
667 |
|
|
if id.auth.useNIS: |
668 |
|
|
select(id.grpset.hdrlist, 'ypbind') |
669 |
|
|
select(id.grpset.hdrlist, 'yp-tools') |
670 |
|
|
select(id.grpset.hdrlist, 'portmap') |
671 |
|
|
|
672 |
|
|
if id.auth.useLdap: |
673 |
|
|
select(id.grpset.hdrlist, 'nss_ldap') |
674 |
|
|
select(id.grpset.hdrlist, 'openldap') |
675 |
|
|
select(id.grpset.hdrlist, 'perl') |
676 |
|
|
|
677 |
|
|
if id.auth.useKrb5: |
678 |
|
|
select(id.grpset.hdrlist, 'pam_krb5') |
679 |
|
|
select(id.grpset.hdrlist, 'krb5-workstation') |
680 |
|
|
select(id.grpset.hdrlist, 'krbafs') |
681 |
|
|
select(id.grpset.hdrlist, 'krb5-libs') |
682 |
|
|
|
683 |
|
|
if id.auth.useSamba: |
684 |
|
|
select(id.grpset.hdrlist, 'pam_smb') |
685 |
|
|
|
686 |
|
|
if iutil.getArch() == "i386" and id.bootloader.useGrubVal == 0: |
687 |
|
|
select(id.grpset.hdrlist, 'lilo') |
688 |
|
|
elif iutil.getArch() == "i386" and id.bootloader.useGrubVal == 1: |
689 |
|
|
select(id.grpset.hdrlist, 'grub') |
690 |
|
|
elif iutil.getArch() == "s390": |
691 |
|
|
select(id.grpset.hdrlist, 's390utils') |
692 |
|
|
elif iutil.getArch() == "ppc": |
693 |
|
|
select(id.grpset.hdrlist, 'yaboot') |
694 |
|
|
elif iutil.getArch() == "ia64": |
695 |
|
|
select(id.grpset.hdrlist, 'elilo') |
696 |
|
|
|
697 |
|
|
if pcmcia.pcicType(): |
698 |
|
|
select(id.grpset.hdrlist, 'pcmcia-cs') |
699 |
|
|
|
700 |
|
|
for entry in id.fsset.entries: |
701 |
|
|
for pkg in entry.fsystem.getNeededPackages(): |
702 |
|
|
if select(id.grpset.hdrlist, pkg): |
703 |
|
|
log("Needed %s for %s" %(pkg, entry.getMountPoint())) |
704 |
|
|
|
705 |
|
|
if flags.test: |
706 |
|
|
return |
707 |
|
|
|
708 |
|
|
# make sure that all comps that include other comps are |
709 |
|
|
# selected (i.e. - recurse down the selected comps and turn |
710 |
|
|
# on the children |
711 |
|
|
while 1: |
712 |
|
|
try: |
713 |
|
|
method.mergeFullHeaders(id.grpset.hdrlist) |
714 |
|
|
except FileCopyException: |
715 |
|
|
method.unmountCD() |
716 |
|
|
intf.messageWindow(_("Error"), |
717 |
|
|
_("Unable to merge header list. This may be " |
718 |
|
|
"due to a missing file or bad media. " |
719 |
|
|
"Press <return> to try again.")) |
720 |
|
|
else: |
721 |
|
|
break |
722 |
|
|
|
723 |
|
|
if upgrade: |
724 |
|
|
# An old mtab can cause confusion (esp if loop devices are |
725 |
|
|
# in it) |
726 |
|
|
f = open(instPath + "/etc/mtab", "w+") |
727 |
|
|
f.close() |
728 |
|
|
|
729 |
|
|
# we really started writing modprobe.conf out before things were |
730 |
|
|
# all completely ready. so now we need to nuke old modprobe.conf's |
731 |
|
|
# if you're upgrading from a 2.4 dist so that we can get the |
732 |
|
|
# transition right |
733 |
|
|
if (os.path.exists(instPath + "/etc/modules.conf") and |
734 |
|
|
os.path.exists(instPath + "/etc/modprobe.conf") and |
735 |
|
|
not os.path.exists(instPath + "/etc/modprobe.conf.anacbak")): |
736 |
|
|
log("renaming old modprobe.conf -> modprobe.conf.anacbak") |
737 |
|
|
os.rename(instPath + "/etc/modprobe.conf", |
738 |
|
|
instPath + "/etc/modprobe.conf.anacbak") |
739 |
|
|
|
740 |
|
|
|
741 |
|
|
if method.systemMounted (id.fsset, instPath): |
742 |
|
|
id.fsset.umountFilesystems(instPath) |
743 |
|
|
return DISPATCH_BACK |
744 |
|
|
|
745 |
|
|
for i in ( '/var', '/var/lib', '/var/lib/rpm', '/tmp', '/dev', '/etc', |
746 |
|
|
'/etc/sysconfig', '/etc/sysconfig/network-scripts', |
747 |
|
|
'/etc/X11', '/root', '/var/tmp', '/etc/rpm' ): |
748 |
|
|
try: |
749 |
|
|
os.mkdir(instPath + i) |
750 |
|
|
except os.error, (errno, msg): |
751 |
|
|
pass |
752 |
|
|
# log("Error making directory %s: %s" % (i, msg)) |
753 |
|
|
|
754 |
|
|
|
755 |
|
|
if flags.setupFilesystems: |
756 |
|
|
# setup /etc/rpm/platform for the post-install environment |
757 |
|
|
iutil.writeRpmPlatform(instPath) |
758 |
|
|
|
759 |
|
|
try: |
760 |
|
|
# FIXME: making the /var/lib/rpm symlink here is a hack to |
761 |
|
|
# workaround db->close() errors from rpm |
762 |
|
|
iutil.mkdirChain("/var/lib") |
763 |
|
|
for path in ("/var/tmp", "/var/lib/rpm"): |
764 |
|
|
if os.path.exists(path) and not os.path.islink(path): |
765 |
|
|
iutil.rmrf(path) |
766 |
|
|
if not os.path.islink(path): |
767 |
|
|
os.symlink("/mnt/sysimage/%s" %(path,), "%s" %(path,)) |
768 |
|
|
else: |
769 |
|
|
log("%s already exists as a symlink to %s" %(path, os.readlink(path),)) |
770 |
|
|
except Exception, e: |
771 |
|
|
# how this could happen isn't entirely clear; log it in case |
772 |
|
|
# it does and causes problems later |
773 |
|
|
log("error creating symlink, continuing anyway: %s" %(e,)) |
774 |
|
|
|
775 |
|
|
# SELinux hackery (#121369) |
776 |
|
|
if flags.selinux: |
777 |
|
|
try: |
778 |
|
|
os.mkdir(instPath + "/selinux") |
779 |
|
|
except Exception, e: |
780 |
|
|
pass |
781 |
|
|
try: |
782 |
|
|
isys.mount("/selinux", instPath + "/selinux", "selinuxfs") |
783 |
|
|
except Exception, e: |
784 |
|
|
log("error mounting selinuxfs: %s" %(e,)) |
785 |
|
|
|
786 |
|
|
# we need to have a /dev during install and now that udev is |
787 |
|
|
# handling /dev, it gets to be more fun. so just bind mount the |
788 |
|
|
# installer /dev |
789 |
|
|
if not id.grpset.hdrlist.has_key("dev"): |
790 |
|
|
log("no dev package, going to bind mount /dev") |
791 |
|
|
isys.mount("/dev", "/mnt/sysimage/dev", bindMount = 1) |
792 |
|
|
|
793 |
|
|
# try to copy the comps package. if it doesn't work, don't worry about it |
794 |
|
|
try: |
795 |
|
|
id.compspkg = method.copyFileToTemp("%s/base/comps.rpm" % (productPath,)) |
796 |
|
|
except: |
797 |
|
|
log("Unable to copy comps package") |
798 |
|
|
id.compspkg = None |
799 |
|
|
|
800 |
|
|
# write out the fstab |
801 |
|
|
if not upgrade: |
802 |
|
|
id.fsset.write(instPath) |
803 |
|
|
# rootpath mode doesn't have this file around |
804 |
|
|
if os.access("/tmp/modprobe.conf", os.R_OK): |
805 |
|
|
iutil.copyFile("/tmp/modprobe.conf", |
806 |
|
|
instPath + "/etc/modprobe.conf") |
807 |
|
|
if os.access("/tmp/zfcp.conf", os.R_OK): |
808 |
|
|
iutil.copyFile("/tmp/zfcp.conf", |
809 |
|
|
instPath + "/etc/zfcp.conf") |
810 |
|
|
|
811 |
|
|
# make a /etc/mtab so mkinitrd can handle certain hw (usb) correctly |
812 |
|
|
f = open(instPath + "/etc/mtab", "w+") |
813 |
|
|
f.write(id.fsset.mtab()) |
814 |
|
|
f.close() |
815 |
|
|
|
816 |
|
|
# delay writing migrate adjusted fstab till later, in case |
817 |
|
|
# rpm transaction set determines they don't have enough space to upgrade |
818 |
|
|
# else: |
819 |
|
|
# id.fsset.migratewrite(instPath) |
820 |
|
|
|
821 |
|
|
def doInstall(method, id, intf, instPath): |
822 |
|
|
if flags.test: |
823 |
|
|
return |
824 |
|
|
|
825 |
|
|
# set up dependency white outs |
826 |
|
|
import whiteout |
827 |
|
|
|
828 |
|
|
upgrade = id.upgrade.get() |
829 |
|
|
ts = getAnacondaTS(instPath) |
830 |
|
|
|
831 |
|
|
total = 0 |
832 |
|
|
totalSize = 0 |
833 |
|
|
totalFiles = 0 |
834 |
|
|
|
835 |
|
|
if upgrade: |
836 |
|
|
how = "u" |
837 |
|
|
else: |
838 |
|
|
how = "i" |
839 |
|
|
rpm.addMacro("__dbi_htconfig", "hash nofsync %{__dbi_other} %{__dbi_perms}") |
840 |
|
|
|
841 |
|
|
if id.excludeDocs: |
842 |
|
|
rpm.addMacro("_excludedocs", "1") |
843 |
|
|
|
844 |
|
|
l = [] |
845 |
|
|
|
846 |
|
|
for p in id.grpset.hdrlist.values(): |
847 |
|
|
if p.isSelected(): |
848 |
|
|
l.append(p) |
849 |
|
|
l.sort(sortPackages) |
850 |
|
|
|
851 |
|
|
progress = intf.progressWindow(_("Processing"), |
852 |
|
|
_("Preparing RPM transaction..."), |
853 |
|
|
len(l)) |
854 |
|
|
|
855 |
|
|
|
856 |
|
|
# this is kind of a hack, but has to be done so we can have a chance |
857 |
|
|
# with broken triggers |
858 |
|
|
if upgrade and len(id.upgradeRemove) > 0: |
859 |
|
|
# simple rpm callback since erasure doesn't need anything |
860 |
|
|
def install_callback(what, bytes, total, h, user): |
861 |
|
|
pass |
862 |
|
|
|
863 |
|
|
for pkg in id.upgradeRemove: |
864 |
|
|
ts.addErase(pkg) |
865 |
|
|
|
866 |
|
|
# if we hit problems, it's not like there's anything we can |
867 |
|
|
# do about it |
868 |
|
|
ts.run(install_callback, 0) |
869 |
|
|
|
870 |
|
|
# new transaction set |
871 |
|
|
ts.closeDB() |
872 |
|
|
del ts |
873 |
|
|
ts = getAnacondaTS(instPath) |
874 |
|
|
|
875 |
|
|
# we don't want to try to remove things more than once (#84221) |
876 |
|
|
id.upgradeRemove = [] |
877 |
|
|
|
878 |
|
|
i = 0 |
879 |
|
|
updcount = 0 |
880 |
|
|
updintv = len(l) / 25 |
881 |
|
|
for p in l: |
882 |
|
|
ts.addInstall(p.hdr, p.hdr, how) |
883 |
|
|
total = total + 1 |
884 |
|
|
totalSize = totalSize + (p[rpm.RPMTAG_SIZE] / 1024) |
885 |
|
|
totalFiles = totalFiles + len(p[rpm.RPMTAG_BASENAMES]) |
886 |
|
|
i = i + 1 |
887 |
|
|
|
888 |
|
|
# HACK - dont overload progress bar with useless requests |
889 |
|
|
updcount = updcount + 1 |
890 |
|
|
if updcount > updintv: |
891 |
|
|
progress.set(i) |
892 |
|
|
updcount = 0 |
893 |
|
|
|
894 |
|
|
progress.pop() |
895 |
|
|
|
896 |
|
|
depcheck = DependencyChecker(id.grpset) |
897 |
|
|
if not id.grpset.hdrlist.preordered(): |
898 |
|
|
log ("WARNING: not all packages in hdlist had order tag") |
899 |
|
|
# have to call ts.check before ts.order() to set up the alIndex |
900 |
|
|
ts.check(depcheck.callback) |
901 |
|
|
ts.order() |
902 |
|
|
else: |
903 |
|
|
ts.check(depcheck.callback) |
904 |
|
|
|
905 |
|
|
if upgrade: |
906 |
|
|
logname = '/root/upgrade.log' |
907 |
|
|
else: |
908 |
|
|
logname = '/root/install.log' |
909 |
|
|
|
910 |
|
|
instLogName = instPath + logname |
911 |
|
|
try: |
912 |
|
|
iutil.rmrf (instLogName) |
913 |
|
|
except OSError: |
914 |
|
|
pass |
915 |
|
|
|
916 |
|
|
instLog = open(instLogName, "w+") |
917 |
|
|
|
918 |
|
|
# dont start syslogd if we arent creating filesystems |
919 |
|
|
if flags.setupFilesystems: |
920 |
|
|
syslogname = "%s%s.syslog" % (instPath, logname) |
921 |
|
|
try: |
922 |
|
|
iutil.rmrf (syslogname) |
923 |
|
|
except OSError: |
924 |
|
|
pass |
925 |
|
|
syslog.start (instPath, syslogname) |
926 |
|
|
else: |
927 |
|
|
syslogname = None |
928 |
|
|
|
929 |
|
|
if id.compspkg is not None: |
930 |
|
|
num = i + 1 |
931 |
|
|
else: |
932 |
|
|
num = i |
933 |
|
|
|
934 |
|
|
if upgrade: |
935 |
|
|
instLog.write(_("Upgrading %s packages\n\n") % (num,)) |
936 |
|
|
else: |
937 |
|
|
instLog.write(_("Installing %s packages\n\n") % (num,)) |
938 |
|
|
|
939 |
|
|
ts.scriptFd = instLog.fileno () |
940 |
|
|
rpm.setLogFile(instLog) |
941 |
|
|
# the transaction set dup()s the file descriptor and will close the |
942 |
|
|
# dup'd when we go out of scope |
943 |
|
|
|
944 |
|
|
if upgrade: |
945 |
|
|
modeText = _("Upgrading %s\n") |
946 |
|
|
else: |
947 |
|
|
modeText = _("Installing %s\n") |
948 |
|
|
|
949 |
|
|
errors = rpmErrorClass(instLog) |
950 |
|
|
pkgTimer = timer.Timer(start = 0) |
951 |
|
|
|
952 |
|
|
id.instProgress.setSizes(total, totalSize, totalFiles) |
953 |
|
|
id.instProgress.processEvents() |
954 |
|
|
|
955 |
|
|
cb = InstallCallback(intf.messageWindow, id.instProgress, pkgTimer, |
956 |
|
|
method, intf.progressWindow, instLog, modeText, |
957 |
|
|
ts) |
958 |
|
|
|
959 |
|
|
# write out migrate adjusted fstab so kernel RPM can get initrd right |
960 |
|
|
if upgrade: |
961 |
|
|
id.fsset.migratewrite(instPath) |
962 |
|
|
if id.upgradeDeps: |
963 |
|
|
instLog.write(_("\n\nThe following packages were automatically\n" |
964 |
|
|
"selected to be installed:" |
965 |
|
|
"\n" |
966 |
|
|
"%s" |
967 |
|
|
"\n\n") % (id.upgradeDeps,)) |
968 |
|
|
|
969 |
|
|
cb.initWindow = intf.waitWindow(_("Install Starting"), |
970 |
|
|
_("Starting install process, this may take several minutes...")) |
971 |
|
|
|
972 |
|
|
ts.setProbFilter(~rpm.RPMPROB_FILTER_DISKSPACE) |
973 |
|
|
problems = ts.run(cb.cb, 0) |
974 |
|
|
|
975 |
|
|
if problems: |
976 |
|
|
# restore old fstab if we did anything for migrating |
977 |
|
|
if upgrade: |
978 |
|
|
id.fsset.restoreMigratedFstab(instPath) |
979 |
|
|
|
980 |
|
|
spaceneeded = {} |
981 |
|
|
nodeneeded = {} |
982 |
|
|
size = 12 |
983 |
|
|
|
984 |
|
|
for (descr, (type, mount, need)) in problems: |
985 |
|
|
log("(%s, (%s, %s, %s))" %(descr, type, mount, need)) |
986 |
|
|
if mount and mount.startswith(instPath): |
987 |
|
|
mount = mount[len(instPath):] |
988 |
|
|
if not mount: |
989 |
|
|
mount = '/' |
990 |
|
|
|
991 |
|
|
if type == rpm.RPMPROB_DISKSPACE: |
992 |
|
|
if spaceneeded.has_key (mount) and spaceneeded[mount] < need: |
993 |
|
|
spaceneeded[mount] = need |
994 |
|
|
else: |
995 |
|
|
spaceneeded[mount] = need |
996 |
|
|
elif type == nodeprob: |
997 |
|
|
if nodeneeded.has_key (mount) and nodeneeded[mount] < need: |
998 |
|
|
nodeneeded[mount] = need |
999 |
|
|
else: |
1000 |
|
|
nodeneeded[mount] = need |
1001 |
|
|
else: |
1002 |
|
|
if descr is None: |
1003 |
|
|
descr = "no description" |
1004 |
|
|
log ("WARNING: unhandled problem returned from " |
1005 |
|
|
"transaction set type %d (%s)", |
1006 |
|
|
type, descr) |
1007 |
|
|
|
1008 |
|
|
probs = "" |
1009 |
|
|
if spaceneeded: |
1010 |
|
|
probs = probs + _("You don't appear to have enough disk space " |
1011 |
|
|
"to install the packages you've selected. " |
1012 |
|
|
"You need more space on the following " |
1013 |
|
|
"file systems:\n\n") |
1014 |
|
|
probs = probs + ("%-15s %s\n") % (_("Mount Point"), |
1015 |
|
|
_("Space Needed")) |
1016 |
|
|
|
1017 |
|
|
for (mount, need) in spaceneeded.items (): |
1018 |
|
|
log("(%s, %s)" %(mount, need)) |
1019 |
|
|
if need > (1024*1024): |
1020 |
|
|
need = (need + 1024 * 1024 - 1) / (1024 * 1024) |
1021 |
|
|
suffix = "M" |
1022 |
|
|
else: |
1023 |
|
|
need = (need + 1023) / 1024 |
1024 |
|
|
suffix = "k" |
1025 |
|
|
|
1026 |
|
|
prob = "%-15s %d %c\n" % (mount, need, suffix) |
1027 |
|
|
probs = probs + prob |
1028 |
|
|
if nodeneeded: |
1029 |
|
|
if probs: |
1030 |
|
|
probs = probs + '\n' |
1031 |
|
|
probs = probs + _("You don't appear to have enough file nodes " |
1032 |
|
|
"to install the packages you've selected. " |
1033 |
|
|
"You need more file nodes on the following " |
1034 |
|
|
"file systems:\n\n") |
1035 |
|
|
probs = probs + ("%-15s %s\n") % (_("Mount Point"), |
1036 |
|
|
_("Nodes Needed")) |
1037 |
|
|
|
1038 |
|
|
for (mount, need) in nodeneeded.items (): |
1039 |
|
|
prob = "%-15s %d\n" % (mount, need) |
1040 |
|
|
probs = probs + prob |
1041 |
|
|
|
1042 |
|
|
if len(probs) == 0: |
1043 |
|
|
probs = ("ERROR: NO! An unexpected problem has occurred with " |
1044 |
|
|
"your transaction set. Please see tty3 for more " |
1045 |
|
|
"information") |
1046 |
|
|
|
1047 |
|
|
intf.messageWindow (_("Disk Space"), probs) |
1048 |
|
|
|
1049 |
|
|
ts.closeDB() |
1050 |
|
|
del ts |
1051 |
|
|
instLog.close() |
1052 |
|
|
|
1053 |
|
|
if syslogname: |
1054 |
|
|
syslog.stop() |
1055 |
|
|
|
1056 |
|
|
method.systemUnmounted () |
1057 |
|
|
|
1058 |
|
|
return DISPATCH_BACK |
1059 |
|
|
|
1060 |
|
|
# This should close the RPM database so that you can |
1061 |
|
|
# do RPM ops in the chroot in a %post ks script |
1062 |
|
|
ts.closeDB() |
1063 |
|
|
del ts |
1064 |
|
|
|
1065 |
|
|
# make sure the window gets popped (#82862) |
1066 |
|
|
if not cb.beenCalled: |
1067 |
|
|
cb.initWindow.pop() |
1068 |
|
|
|
1069 |
|
|
method.filesDone () |
1070 |
|
|
|
1071 |
|
|
# rpm environment files go bye-bye |
1072 |
|
|
for file in ["__db.001", "__db.002", "__db.003"]: |
1073 |
|
|
try: |
1074 |
|
|
os.unlink("%s/var/lib/rpm/%s" %(instPath, file)) |
1075 |
|
|
except Exception, e: |
1076 |
|
|
log("failed to unlink /var/lib/rpm/%s: %s" %(file,e)) |
1077 |
|
|
# FIXME: remove the /var/lib/rpm symlink that keeps us from having |
1078 |
|
|
# db->close error messages shown. I don't really like this though :( |
1079 |
|
|
try: |
1080 |
|
|
os.unlink("/var/lib/rpm") |
1081 |
|
|
except Exception, e: |
1082 |
|
|
log("failed to unlink /var/lib/rpm: %s" %(e,)) |
1083 |
|
|
|
1084 |
|
|
instLog.close () |
1085 |
|
|
|
1086 |
|
|
id.instProgress = None |
1087 |
|
|
|
1088 |
|
|
def doPostInstall(method, id, intf, instPath): |
1089 |
|
|
if flags.test: |
1090 |
|
|
return |
1091 |
|
|
|
1092 |
|
|
upgrade = id.upgrade.get() |
1093 |
|
|
arch = iutil.getArch () |
1094 |
|
|
|
1095 |
|
|
if upgrade: |
1096 |
growell |
1.4 |
w = intf.progressWindow(_("Post Upgrade"), |
1097 |
|
|
_("Performing post upgrade configuration..."), 6) |
1098 |
|
|
else: |
1099 |
growell |
1.3 |
w = intf.progressWindow(_("Post Install"), |
1100 |
|
|
_("Performing post install configuration..."), 6) |
1101 |
|
|
|
1102 |
|
|
if upgrade: |
1103 |
slords |
1.1 |
logname = '/root/upgrade.log' |
1104 |
|
|
else: |
1105 |
|
|
logname = '/root/install.log' |
1106 |
|
|
|
1107 |
|
|
instLogName = instPath + logname |
1108 |
|
|
instLog = open(instLogName, "a") |
1109 |
|
|
|
1110 |
|
|
try: |
1111 |
|
|
if not upgrade: |
1112 |
|
|
w.set(1) |
1113 |
|
|
|
1114 |
|
|
copyExtraModules(instPath, id.grpset, id.extraModules) |
1115 |
|
|
|
1116 |
|
|
w.set(2) |
1117 |
|
|
|
1118 |
|
|
# pcmcia is supported only on i386 at the moment |
1119 |
|
|
if arch == "i386": |
1120 |
|
|
pcmcia.createPcmciaConfig( |
1121 |
|
|
instPath + "/etc/sysconfig/pcmcia") |
1122 |
|
|
|
1123 |
|
|
# we need to write out the network bits before kudzu runs |
1124 |
|
|
# to avoid getting devices in the wrong order (#102276) |
1125 |
|
|
id.network.write(instPath) |
1126 |
|
|
|
1127 |
|
|
w.set(3) |
1128 |
|
|
|
1129 |
|
|
# blah. If we're on a serial mouse, and we have X, we need to |
1130 |
|
|
# close the mouse device, then run kudzu, then open it again. |
1131 |
|
|
|
1132 |
|
|
# turn it off |
1133 |
|
|
mousedev = None |
1134 |
|
|
|
1135 |
|
|
# XXX currently Bad Things (X async reply) happen when doing |
1136 |
|
|
# Mouse Magic on Sparc (Mach64, specificly) |
1137 |
|
|
# The s390 doesn't even have a mouse! |
1138 |
|
|
if os.environ.get('DISPLAY') == ':1' and arch != 'sparc': |
1139 |
|
|
try: |
1140 |
|
|
import xmouse |
1141 |
|
|
mousedev = xmouse.get()[0] |
1142 |
|
|
except RuntimeError: |
1143 |
|
|
pass |
1144 |
|
|
|
1145 |
|
|
if mousedev: |
1146 |
|
|
try: |
1147 |
|
|
os.rename (mousedev, "/dev/disablemouse") |
1148 |
|
|
except OSError: |
1149 |
|
|
pass |
1150 |
|
|
try: |
1151 |
|
|
xmouse.reopen() |
1152 |
|
|
except RuntimeError: |
1153 |
|
|
pass |
1154 |
|
|
|
1155 |
|
|
if arch != "s390" and flags.setupFilesystems: |
1156 |
|
|
# we need to unmount usbdevfs before mounting it |
1157 |
|
|
usbWasMounted = iutil.isUSBDevFSMounted() |
1158 |
|
|
if usbWasMounted: |
1159 |
|
|
isys.umount('/proc/bus/usb', removeDir = 0) |
1160 |
|
|
|
1161 |
|
|
# see if unmount suceeded, if not pretent it isnt mounted |
1162 |
|
|
# because we're screwed anywyas if system is going to |
1163 |
|
|
# lock up |
1164 |
|
|
if iutil.isUSBDevFSMounted(): |
1165 |
|
|
usbWasMounted = 0 |
1166 |
|
|
|
1167 |
|
|
unmountUSB = 0 |
1168 |
|
|
try: |
1169 |
|
|
isys.mount('/usbfs', instPath+'/proc/bus/usb', 'usbfs') |
1170 |
|
|
unmountUSB = 1 |
1171 |
|
|
except: |
1172 |
|
|
log("Mount of /proc/bus/usb in chroot failed") |
1173 |
|
|
pass |
1174 |
|
|
|
1175 |
|
|
argv = [ "/usr/sbin/kudzu", "-q" ] |
1176 |
|
|
if id.grpset.hdrlist.has_key("kernel"): |
1177 |
|
|
ver = "%s-%s" %(id.grpset.hdrlist["kernel"][rpm.RPMTAG_VERSION], |
1178 |
|
|
id.grpset.hdrlist["kernel"][rpm.RPMTAG_RELEASE]) |
1179 |
|
|
argv.extend(["-k", ver]) |
1180 |
|
|
|
1181 |
|
|
devnull = os.open("/dev/null", os.O_RDWR) |
1182 |
|
|
iutil.execWithRedirect(argv[0], argv, root = instPath, |
1183 |
|
|
stdout = devnull) |
1184 |
|
|
# turn it back on |
1185 |
|
|
if mousedev: |
1186 |
|
|
try: |
1187 |
|
|
os.rename ("/dev/disablemouse", mousedev) |
1188 |
|
|
except OSError: |
1189 |
|
|
pass |
1190 |
|
|
try: |
1191 |
|
|
xmouse.reopen() |
1192 |
|
|
except RuntimeError: |
1193 |
|
|
pass |
1194 |
|
|
|
1195 |
|
|
if unmountUSB: |
1196 |
|
|
try: |
1197 |
|
|
isys.umount(instPath + '/proc/bus/usb', removeDir = 0) |
1198 |
|
|
except SystemError: |
1199 |
|
|
# if we fail to unmount, then we should just not |
1200 |
|
|
# try to remount it. this protects us from random |
1201 |
|
|
# suckage |
1202 |
|
|
usbWasMounted = 0 |
1203 |
|
|
|
1204 |
|
|
if usbWasMounted: |
1205 |
|
|
isys.mount('/usbfs', '/proc/bus/usb', 'usbfs') |
1206 |
|
|
|
1207 |
|
|
w.set(4) |
1208 |
|
|
|
1209 |
|
|
if upgrade and id.dbpath is not None: |
1210 |
|
|
# remove the old rpmdb |
1211 |
|
|
try: |
1212 |
|
|
iutil.rmrf (id.dbpath) |
1213 |
|
|
except OSError: |
1214 |
|
|
pass |
1215 |
|
|
|
1216 |
|
|
if upgrade: |
1217 |
|
|
# needed for prior systems which were not xinetd based |
1218 |
|
|
migrateXinetd(instPath, instLogName) |
1219 |
|
|
|
1220 |
|
|
# needed for prior to 2.6 so that mice have some chance |
1221 |
|
|
# of working afterwards. FIXME: this is a hack |
1222 |
|
|
migrateMouseConfig(instPath, instLogName) |
1223 |
|
|
|
1224 |
|
|
if id.grpset.hdrlist.has_key("rhgb") and id.grpset.hdrlist["rhgb"].isSelected(): |
1225 |
|
|
log("rhgb installed, adding to boot loader config") |
1226 |
|
|
id.bootloader.args.append("rhgb quiet") |
1227 |
|
|
|
1228 |
|
|
w.set(5) |
1229 |
|
|
|
1230 |
|
|
# FIXME: hack to install the comps package |
1231 |
|
|
if (id.compspkg is not None and |
1232 |
|
|
os.access(id.compspkg, os.R_OK)): |
1233 |
|
|
log("found the comps package") |
1234 |
|
|
try: |
1235 |
|
|
# ugly hack |
1236 |
|
|
path = id.compspkg.split("/mnt/sysimage")[1] |
1237 |
|
|
args = ["/bin/rpm", "-Uvh", path] |
1238 |
|
|
rc = iutil.execWithRedirect(args[0], args, |
1239 |
|
|
stdout = "/dev/tty5", |
1240 |
|
|
stderr = "/dev/tty5", |
1241 |
|
|
root = instPath) |
1242 |
|
|
ts = rpm.TransactionSet() |
1243 |
|
|
ts.setVSFlags(~(rpm.RPMVSF_NORSA|rpm.RPMVSF_NODSA)) |
1244 |
|
|
ts.closeDB() |
1245 |
|
|
fd = os.open(id.compspkg, os.O_RDONLY) |
1246 |
|
|
h = ts.hdrFromFdno(fd) |
1247 |
|
|
os.close(fd) |
1248 |
|
|
if upgrade: |
1249 |
|
|
text = _("Upgrading %s\n") |
1250 |
|
|
else: |
1251 |
|
|
text = _("Installing %s\n") |
1252 |
|
|
instLog.write (text % (hdrlist.nevra(h))) |
1253 |
|
|
os.unlink(id.compspkg) |
1254 |
|
|
del ts |
1255 |
|
|
|
1256 |
|
|
except Exception, e: |
1257 |
|
|
log("comps.rpm failed to install: %s" %(e,)) |
1258 |
|
|
try: |
1259 |
|
|
os.unlink(id.compspkg) |
1260 |
|
|
except: |
1261 |
|
|
pass |
1262 |
|
|
else: |
1263 |
|
|
log("no comps package found") |
1264 |
|
|
|
1265 |
|
|
w.set(6) |
1266 |
|
|
|
1267 |
|
|
|
1268 |
|
|
finally: |
1269 |
|
|
pass |
1270 |
|
|
|
1271 |
|
|
if upgrade: |
1272 |
|
|
instLog.write(_("\n\nThe following packages were available in " |
1273 |
|
|
"this version but NOT upgraded:\n")) |
1274 |
|
|
else: |
1275 |
|
|
instLog.write(_("\n\nThe following packages were available in " |
1276 |
|
|
"this version but NOT installed:\n")) |
1277 |
|
|
|
1278 |
|
|
ts = rpm.TransactionSet(instPath) |
1279 |
|
|
ts.setVSFlags(~(rpm.RPMVSF_NORSA|rpm.RPMVSF_NODSA)) |
1280 |
|
|
|
1281 |
|
|
lines = [] |
1282 |
|
|
for p in id.grpset.hdrlist.values(): |
1283 |
|
|
if not p.isSelected(): |
1284 |
slords |
1.2 |
text = "%s" % hdrlist.nevra(p) |
1285 |
|
|
for f in ts.dbMatch('name', p.hdr[rpm.RPMTAG_NAME]): |
1286 |
|
|
if hdrlist.nevra(p) == hdrlist.nevra(f): |
1287 |
|
|
text = "%s (already installed)" % text |
1288 |
|
|
else: |
1289 |
|
|
text = "%s (%s installed)" % (text, hdrlist.nevra(f)) |
1290 |
|
|
lines.append("%s\n" % text) |
1291 |
slords |
1.1 |
lines.sort() |
1292 |
|
|
for line in lines: |
1293 |
|
|
instLog.write(line) |
1294 |
|
|
|
1295 |
|
|
# XXX hack - we should really write a proper lvm "config". but for now |
1296 |
|
|
# just vgscan if they have /sbin/lvm and some appearance of volumes |
1297 |
|
|
if (os.access(instPath + "/sbin/lvm", os.X_OK) and |
1298 |
|
|
os.access(instPath + "/dev/mapper", os.X_OK) and |
1299 |
|
|
len(os.listdir("/dev/mapper")) > 1): |
1300 |
|
|
rc = iutil.execWithRedirect("/sbin/lvm", |
1301 |
|
|
["lvm", "vgscan", "-v"], |
1302 |
|
|
stdout = "/dev/tty5", |
1303 |
|
|
stderr = "/dev/tty5", |
1304 |
|
|
root = instPath, |
1305 |
|
|
searchPath = 1) |
1306 |
|
|
|
1307 |
|
|
# write out info on install method used |
1308 |
|
|
try: |
1309 |
|
|
if id.methodstr is not None: |
1310 |
|
|
if os.access (instPath + "/etc/sysconfig/installinfo", os.R_OK): |
1311 |
|
|
os.rename (instPath + "/etc/sysconfig/installinfo", |
1312 |
|
|
instPath + "/etc/sysconfig/installinfo.rpmsave") |
1313 |
|
|
|
1314 |
|
|
f = open(instPath + "/etc/sysconfig/installinfo", "w+") |
1315 |
|
|
f.write("INSTALLMETHOD=%s\n" % (string.split(id.methodstr, ':')[0],)) |
1316 |
|
|
|
1317 |
|
|
try: |
1318 |
|
|
ii = open("/tmp/isoinfo", "r") |
1319 |
|
|
il = ii.readlines() |
1320 |
|
|
ii.close() |
1321 |
|
|
for line in il: |
1322 |
|
|
f.write(line) |
1323 |
|
|
except: |
1324 |
|
|
pass |
1325 |
|
|
f.close() |
1326 |
|
|
else: |
1327 |
|
|
log("methodstr not set for some reason") |
1328 |
|
|
except: |
1329 |
|
|
log("Failed to write out installinfo") |
1330 |
|
|
|
1331 |
|
|
w.pop () |
1332 |
|
|
|
1333 |
|
|
sys.stdout.flush() |
1334 |
|
|
|
1335 |
|
|
if flags.setupFilesystems: |
1336 |
|
|
syslog.stop() |
1337 |
|
|
|
1338 |
|
|
# FIXME: this is a huge gross hack. hard coded list of files |
1339 |
|
|
# created by anaconda so that we can not be killed by selinux |
1340 |
|
|
def setFileCons(instPath, partitions): |
1341 |
|
|
import partRequests |
1342 |
|
|
|
1343 |
|
|
if flags.selinux: |
1344 |
|
|
log("setting SELinux contexts for anaconda created files") |
1345 |
|
|
|
1346 |
|
|
files = ["/etc/rpm/platform", "/etc/rpm/macros", |
1347 |
|
|
"/etc/lilo.conf", "/etc/lilo.conf.anaconda", |
1348 |
|
|
"/etc/mtab", "/etc/fstab", "/etc/resolv.conf", |
1349 |
|
|
"/etc/modprobe.conf", "/etc/modprobe.conf~", |
1350 |
|
|
"/var/log/wtmp", "/var/run/utmp", |
1351 |
|
|
"/dev/log", "/var/lib/rpm", "/", "/etc/raidtab", |
1352 |
|
|
"/etc/mdadm.conf"] |
1353 |
|
|
|
1354 |
|
|
vgs = [] |
1355 |
|
|
for entry in partitions.requests: |
1356 |
|
|
if isinstance(entry, partRequests.VolumeGroupRequestSpec): |
1357 |
|
|
vgs.append("/dev/%s" %(entry.volumeGroupName,)) |
1358 |
|
|
|
1359 |
|
|
# ugh, this is ugly |
1360 |
|
|
for dir in ["/var/lib/rpm", "/etc/lvm", "/dev/mapper"] + vgs: |
1361 |
|
|
def addpath(x): return dir + "/" + x |
1362 |
|
|
|
1363 |
|
|
if not os.path.isdir(instPath + dir): |
1364 |
|
|
continue |
1365 |
|
|
dirfiles = os.listdir(instPath + dir) |
1366 |
|
|
files.extend(map(addpath, dirfiles)) |
1367 |
|
|
files.append(dir) |
1368 |
|
|
|
1369 |
|
|
# blah, to work in a chroot, we need to actually be inside so the |
1370 |
|
|
# regexes will work |
1371 |
|
|
child = os.fork() |
1372 |
|
|
if (not child): |
1373 |
|
|
os.chroot(instPath) |
1374 |
|
|
for f in files: |
1375 |
|
|
if not os.access("%s" %(f,), os.R_OK): |
1376 |
|
|
log("%s doesn't exist" %(f,)) |
1377 |
|
|
continue |
1378 |
|
|
ret = isys.resetFileContext(f) |
1379 |
|
|
log("set fc of %s to %s" %(f, ret)) |
1380 |
|
|
os._exit(0) |
1381 |
|
|
|
1382 |
|
|
try: |
1383 |
|
|
os.waitpid(child, 0) |
1384 |
|
|
except OSError, (num, msg): |
1385 |
|
|
pass |
1386 |
|
|
|
1387 |
|
|
|
1388 |
|
|
return |
1389 |
|
|
|
1390 |
|
|
# XXX: large hack lies here |
1391 |
|
|
def migrateMouseConfig(instPath, instLog): |
1392 |
|
|
if not os.access (instPath + "/usr/sbin/fix-mouse-psaux", os.X_OK): |
1393 |
|
|
return |
1394 |
|
|
|
1395 |
|
|
argv = [ "/usr/sbin/fix-mouse-psaux" ] |
1396 |
|
|
|
1397 |
|
|
logfile = os.open (instLog, os.O_APPEND) |
1398 |
|
|
iutil.execWithRedirect(argv[0], argv, root = instPath, |
1399 |
|
|
stdout = logfile, stderr = logfile) |
1400 |
|
|
os.close(logfile) |
1401 |
|
|
|
1402 |
|
|
|
1403 |
|
|
def migrateXinetd(instPath, instLog): |
1404 |
|
|
if not os.access (instPath + "/usr/sbin/inetdconvert", os.X_OK): |
1405 |
|
|
return |
1406 |
|
|
|
1407 |
|
|
if not os.access (instPath + "/etc/inetd.conf.rpmsave", os.R_OK): |
1408 |
|
|
return |
1409 |
|
|
|
1410 |
|
|
argv = [ "/usr/sbin/inetdconvert", "--convertremaining", |
1411 |
|
|
"--inetdfile", "/etc/inetd.conf.rpmsave" ] |
1412 |
|
|
|
1413 |
|
|
logfile = os.open (instLog, os.O_APPEND) |
1414 |
|
|
iutil.execWithRedirect(argv[0], argv, root = instPath, |
1415 |
|
|
stdout = logfile, stderr = logfile) |
1416 |
|
|
os.close(logfile) |
1417 |
|
|
|
1418 |
|
|
def copyExtraModules(instPath, grpset, extraModules): |
1419 |
|
|
kernelVersions = grpset.kernelVersionList() |
1420 |
|
|
foundModule = 0 |
1421 |
|
|
|
1422 |
|
|
try: |
1423 |
|
|
f = open("/etc/arch") |
1424 |
|
|
arch = f.readline().strip() |
1425 |
|
|
del f |
1426 |
|
|
except IOError: |
1427 |
|
|
arch = os.uname()[2] |
1428 |
|
|
|
1429 |
|
|
for (path, name) in extraModules: |
1430 |
|
|
if not path: |
1431 |
|
|
path = "/modules.cgz" |
1432 |
|
|
pattern = "" |
1433 |
|
|
names = "" |
1434 |
|
|
for (n, tag) in kernelVersions: |
1435 |
|
|
if tag == "up": |
1436 |
|
|
pkg = "kernel" |
1437 |
|
|
else: |
1438 |
|
|
pkg = "kernel-%s" %(tag,) |
1439 |
|
|
arch = grpset.hdrlist[pkg][rpm.RPMTAG_ARCH] |
1440 |
|
|
# version 1 path |
1441 |
|
|
pattern = pattern + " %s/%s/%s.ko " % (n, arch, name) |
1442 |
|
|
# version 0 path |
1443 |
|
|
pattern = pattern + " %s/%s.ko " % (n, name) |
1444 |
|
|
names = names + " %s.ko" % (name,) |
1445 |
|
|
command = ("cd %s/lib/modules; gunzip < %s | " |
1446 |
|
|
"%s/bin/cpio --quiet -iumd %s" % |
1447 |
|
|
(instPath, path, instPath, pattern)) |
1448 |
|
|
log("running: '%s'" % (command, )) |
1449 |
|
|
os.system(command) |
1450 |
|
|
|
1451 |
|
|
for (n, tag) in kernelVersions: |
1452 |
|
|
if tag == "up": |
1453 |
|
|
pkg = "kernel" |
1454 |
|
|
else: |
1455 |
|
|
pkg = "kernel-%s" %(tag,) |
1456 |
|
|
|
1457 |
|
|
toDir = "%s/lib/modules/%s/updates" % \ |
1458 |
|
|
(instPath, n) |
1459 |
|
|
to = "%s/%s.ko" % (toDir, name) |
1460 |
|
|
|
1461 |
|
|
if (os.path.isdir("%s/lib/modules/%s" %(instPath, n)) and not |
1462 |
|
|
os.path.isdir("%s/lib/modules/%s/updates" %(instPath, n))): |
1463 |
|
|
os.mkdir("%s/lib/modules/%s/updates" %(instPath, n)) |
1464 |
|
|
if not os.path.isdir(toDir): |
1465 |
|
|
continue |
1466 |
|
|
|
1467 |
|
|
arch = grpset.hdrlist[pkg][rpm.RPMTAG_ARCH] |
1468 |
|
|
for p in ("%s/%s.ko" %(arch, name), "%s.ko" %(name,)): |
1469 |
|
|
fromFile = "%s/lib/modules/%s/%s" % (instPath, n, p) |
1470 |
|
|
|
1471 |
|
|
if (os.access(fromFile, os.R_OK)): |
1472 |
|
|
log("moving %s to %s" % (fromFile, to)) |
1473 |
|
|
os.rename(fromFile, to) |
1474 |
|
|
# the file might not have been owned by root in the cgz |
1475 |
|
|
os.chown(to, 0, 0) |
1476 |
|
|
foundModule = 1 |
1477 |
|
|
else: |
1478 |
|
|
log("missing DD module %s (this may be okay)" % |
1479 |
|
|
fromFile) |
1480 |
|
|
|
1481 |
|
|
if foundModule == 1: |
1482 |
|
|
for (n, tag) in kernelVersions: |
1483 |
|
|
recreateInitrd(n, instPath) |
1484 |
|
|
|
1485 |
|
|
|
1486 |
|
|
#Recreate initrd for use when driver disks add modules |
1487 |
|
|
def recreateInitrd (kernelTag, instRoot): |
1488 |
|
|
log("recreating initrd for %s" % (kernelTag,)) |
1489 |
|
|
iutil.execWithRedirect("/sbin/new-kernel-pkg", |
1490 |
|
|
[ "/sbin/new-kernel-pkg", "--mkinitrd", |
1491 |
|
|
"--depmod", "--install", kernelTag ], |
1492 |
|
|
stdout = None, stderr = None, |
1493 |
|
|
searchPath = 1, root = instRoot) |
1494 |
|
|
|
1495 |
|
|
# XXX Deprecated. Is this ever called anymore? |
1496 |
|
|
def depmodModules(comps, instPath): |
1497 |
|
|
kernelVersions = comps.kernelVersionList() |
1498 |
|
|
|
1499 |
|
|
for (version, tag) in kernelVersions: |
1500 |
|
|
iutil.execWithRedirect ("/sbin/depmod", |
1501 |
|
|
[ "/sbin/depmod", "-a", version, |
1502 |
|
|
"-F", "/boot/System.map-" + version ], |
1503 |
|
|
root = instPath, stderr = '/dev/null') |
1504 |
|
|
|
1505 |
|
|
|
1506 |
|
|
def betaNagScreen(intf, dir): |
1507 |
|
|
publicBetas = { "Red Hat Linux": "Red Hat Linux Public Beta", |
1508 |
|
|
"Red Hat Enterprise Linux": "Red Hat Enterprise Linux Public Beta", |
1509 |
|
|
"Fedora Core": "Fedora Core" } |
1510 |
|
|
|
1511 |
|
|
|
1512 |
|
|
if dir == DISPATCH_BACK: |
1513 |
|
|
return DISPATCH_NOOP |
1514 |
|
|
|
1515 |
|
|
fileagainst = None |
1516 |
|
|
for (key, val) in publicBetas.items(): |
1517 |
|
|
if productName.startswith(key): |
1518 |
|
|
fileagainst = val |
1519 |
|
|
if fileagainst is None: |
1520 |
|
|
fileagainst = "%s Beta" %(productName,) |
1521 |
|
|
|
1522 |
|
|
while 1: |
1523 |
|
|
rc = intf.messageWindow( _("Warning! This is pre-release software!"), |
1524 |
|
|
_("Thank you for downloading this " |
1525 |
|
|
"pre-release of %s.\n\n" |
1526 |
|
|
"This is not a final " |
1527 |
|
|
"release and is not intended for use " |
1528 |
|
|
"on production systems. The purpose of " |
1529 |
|
|
"this release is to collect feedback " |
1530 |
|
|
"from testers, and it is not suitable " |
1531 |
|
|
"for day to day usage.\n\n" |
1532 |
|
|
"To report feedback, please visit:\n\n" |
1533 |
|
|
" http://www.centos.orrg/bugs\n\n" |
1534 |
|
|
"and file a report against '%s'.\n" |
1535 |
|
|
%(productName, fileagainst)), |
1536 |
|
|
type="custom", custom_icon="warning", |
1537 |
|
|
custom_buttons=[_("_Exit"), _("_Install anyway")]) |
1538 |
|
|
|
1539 |
|
|
if not rc: |
1540 |
|
|
if flags.rootpath: |
1541 |
|
|
msg = _("The installer will now exit...") |
1542 |
|
|
buttons = [_("_Back"), _("_Exit")] |
1543 |
|
|
else: |
1544 |
|
|
msg = _("Your system will now be rebooted...") |
1545 |
|
|
buttons = [_("_Back"), _("_Reboot")] |
1546 |
|
|
rc = intf.messageWindow( _("Rebooting System"), |
1547 |
|
|
msg, |
1548 |
|
|
type="custom", custom_icon="warning", |
1549 |
|
|
custom_buttons=buttons) |
1550 |
|
|
if rc: |
1551 |
|
|
sys.exit(0) |
1552 |
|
|
else: |
1553 |
|
|
break |
1554 |
|
|
|
1555 |
|
|
# FIXME: this is a kind of poor way to do this, but it will work for now |
1556 |
|
|
def selectLanguageSupportGroups(grpset, langSupport): |
1557 |
|
|
sup = langSupport.supported |
1558 |
|
|
if len(sup) == 0: |
1559 |
|
|
sup = langSupport.getAllSupported() |
1560 |
|
|
|
1561 |
|
|
for group in grpset.groups.values(): |
1562 |
|
|
xmlgrp = grpset.compsxml.groups[group.basename] |
1563 |
|
|
langs = [] |
1564 |
|
|
for name in sup: |
1565 |
|
|
try: |
1566 |
|
|
lang = langSupport.langInfoByName[name][0] |
1567 |
|
|
langs.extend(language.expandLangs(lang)) |
1568 |
|
|
except: |
1569 |
|
|
continue |
1570 |
|
|
|
1571 |
|
|
if group.langonly is not None and group.langonly in langs: |
1572 |
|
|
group.select() |
1573 |
|
|
for package in xmlgrp.pkgConditionals.keys(): |
1574 |
|
|
req = xmlgrp.pkgConditionals[package] |
1575 |
|
|
if not grpset.hdrlist.has_key(package): |
1576 |
|
|
log("Missing %s which is in a langsupport conditional" %(package,)) |
1577 |
|
|
continue |
1578 |
|
|
# add to the deps in the dependencies structure for the |
1579 |
|
|
# package. this should take care of whenever we're |
1580 |
|
|
# selected |
1581 |
|
|
grpset.hdrlist[req].addDeps([package], main = 0) |
1582 |
|
|
if grpset.hdrlist[req].isSelected(): |
1583 |
|
|
grpset.hdrlist[package].select() |
1584 |
|
|
sys.stdout.flush() |
1585 |
|
|
grpset.hdrlist[package].usecount += grpset.hdrlist[req].usecount - 1 |
1586 |
|
|
group.selectDeps([package], uses = grpset.hdrlist[req].usecount) |
1587 |
|
|
|