summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Wilson <msw@redhat.com>2001-06-20 04:39:53 +0000
committerMatt Wilson <msw@redhat.com>2001-06-20 04:39:53 +0000
commitc4249bbe06e028e95f6514adb7f90ae11ab3b43b (patch)
tree408350beb14885893b86938d27a46688c4986003
parent8a566ec58b79dc8c583a4610a27a5182b31bacb8 (diff)
downloadanaconda-c4249bbe06e028e95f6514adb7f90ae11ab3b43b.tar.gz
anaconda-c4249bbe06e028e95f6514adb7f90ae11ab3b43b.tar.xz
anaconda-c4249bbe06e028e95f6514adb7f90ae11ab3b43b.zip
merge dispatch to HEAD
-rw-r--r--autopart.py357
-rw-r--r--bootloader.py407
-rw-r--r--desktop.py51
-rw-r--r--firewall.py89
-rw-r--r--flags.py25
-rw-r--r--instdata.py143
-rw-r--r--network.py256
-rw-r--r--packages.py797
-rw-r--r--timezone.py44
-rw-r--r--users.py220
-rw-r--r--videocard.py369
-rw-r--r--xf86config.py485
12 files changed, 2980 insertions, 263 deletions
diff --git a/autopart.py b/autopart.py
new file mode 100644
index 000000000..471801556
--- /dev/null
+++ b/autopart.py
@@ -0,0 +1,357 @@
+#
+# autopart.py - auto partitioning logic
+#
+# Jeremy Katz <katzj@redhat.com>
+#
+# Copyright 2001 Red Hat, Inc.
+#
+# This software may be freely redistributed under the terms of the GNU
+# library public license.
+#
+# You should have received a copy of the GNU Library Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+import parted
+import math
+from fsset import *
+from partitioning import *
+
+PARTITION_FAIL = -1
+PARTITION_SUCCESS = 0
+
+def findFreespace(diskset):
+ free = {}
+ for drive in diskset.disks.keys():
+ disk = diskset.disks[drive]
+ free[drive] = []
+ part = disk.next_partition()
+ while part:
+ if part.type & parted.PARTITION_FREESPACE:
+ free[drive].append(part)
+ part = disk.next_partition(part)
+ return free
+
+
+def bestPartType(disk):
+ numPrimary = len(get_primary_partitions(disk))
+ if numPrimary == 4:
+ # raise an error?
+ return PARTITION_FAIL
+ if numPrimary == 3 and not disk.extended_partition:
+ return parted.PARTITION_EXTENDED
+ return parted.PARTITION_PRIMARY
+
+
+# first step of partitioning voodoo
+# partitions with a specific start and end cylinder requested are
+# placed where they were asked to go
+def fitConstrained(diskset, requests):
+ for request in requests.requests:
+ if request.type != REQUEST_NEW:
+ continue
+ if request.drive and (request.start != None) and request.end:
+ fsType = request.fstype.getPartedFileSystemType()
+ disk = diskset.disks[request.drive]
+ if not disk: # this shouldn't happen
+ raise PartitioningError, "Selected to put partition on non-existent disk!"
+
+ startSec = start_cyl_to_sector(disk.dev, request.start)
+ endSec = end_cyl_to_sector(disk.dev, request.end)
+
+ # XXX need to check overlaps properly here
+ if startSec < 0:
+ startSec = 0L
+
+ if disk.type.check_feature(parted.DISK_TYPE_EXTENDED) and disk.extended_partition:
+
+ if (disk.extended_part.geom.start < startSec) and (disk.extended_part.geom.end > endSec):
+ partType = parted.PARTITION_LOGICAL
+ else:
+ # XXX need a better way to do primary vs logical stuff
+ ret = bestPartType(disk)
+ if ret == PARTITION_FAIL:
+ return ret
+ if ret == parted.PARTITION_PRIMARY:
+ partType = parted.PARTITION_PRIMARY
+ elif ret == parted.PARTITION_EXTENDED:
+ newp = disk.partition_new(parted.PARTITION_EXTENDED, None, startSec, endSec)
+ constraint = disk.constraint_any()
+ disk.maximize_partition (newp, constraint)
+ partType = parted.PARTITION_LOGICAL
+ else: # shouldn't get here
+ raise PartitioningError, "Impossible partition type to create"
+ newp = disk.partition_new (partType, fsType, startSec, endSec)
+ constraint = disk.constraint_any ()
+ try:
+ disk.add_partition (newp, constraint)
+ status = 1
+ except parted.error, msg:
+ return PARTITION_FAIL
+# raise PartitioningError, msg
+ for flag in request.fstype.getPartedPartitionFlags():
+ if not newp.is_flag_available(flag):
+ raise PartitioningError, ("requested FileSystemType needs "
+ "a flag that is not available.")
+ newp.set_flag(flag, 1)
+ request.device = PartedPartitionDevice(newp).getDevice()
+ request.realDevice = request.device
+ request.currentDrive = drive
+
+ return PARTITION_SUCCESS
+
+
+# fit partitions of a specific size with or without a specific disk
+# into the freespace
+def fitSized(diskset, requests):
+ todo = {}
+
+ for request in requests.requests:
+ if request.type != REQUEST_NEW:
+ continue
+ if request.realDevice:
+ continue
+ if not request.drive:
+ request.drive = diskset.disks.keys()
+ if type(request.drive) != type([]):
+ request.drive = [ request.drive ]
+ if not todo.has_key(len(request.drive)):
+ todo[len(request.drive)] = [ request ]
+ else:
+ todo[len(request.drive)].append(request)
+
+
+ number = todo.keys()
+ number.sort()
+ free = findFreespace(diskset)
+
+ for num in number:
+ for request in todo[num]:
+ largestPart = (0, None)
+ request.drive.sort()
+ for drive in request.drive:
+ disk = diskset.disks[drive]
+
+ for part in free[drive]:
+ partSize = getPartSize(part)
+ if partSize >= request.requestSize and partSize > largestPart[0]:
+ largestPart = (partSize, part)
+
+ if not largestPart[1]:
+ return PARTITION_FAIL
+# raise PartitioningError, "Can't fulfill request for partition: \n%s" %(request)
+
+ freespace = largestPart[1]
+ disk = freespace.geom.disk
+ startSec = freespace.geom.start + 1
+ endSec = startSec + ((request.requestSize * 1024L * 1024L) / disk.dev.sector_size) - 1
+
+ if endSec > freespace.geom.end:
+ endSec = freespace.geom.end
+ if startSec < freespace.geom.start:
+ startSec = freespace.geom.start
+
+ if freespace.type & parted.PARTITION_LOGICAL:
+ partType = parted.PARTITION_LOGICAL
+ else:
+ # XXX need a better way to do primary vs logical stuff
+ ret = bestPartType(disk)
+ if ret == PARTITION_FAIL:
+ return ret
+ print ret
+ if ret == parted.PARTITION_PRIMARY:
+ partType = parted.PARTITION_PRIMARY
+ elif ret == parted.PARTITION_EXTENDED:
+ newp = disk.partition_new(parted.PARTITION_EXTENDED, None, startSec, endSec)
+ constraint = disk.constraint_any()
+ disk.add_partition(newp, constraint)
+ disk.maximize_partition (newp, constraint)
+ partType = parted.PARTITION_LOGICAL
+ else: # shouldn't get here
+ raise PartitioningError, "Impossible partition to create"
+
+ fsType = request.fstype.getPartedFileSystemType()
+
+ newp = disk.partition_new (partType, fsType, startSec, endSec)
+ constraint = disk.constraint_any ()
+ try:
+ disk.add_partition (newp, constraint)
+ except parted.error, msg:
+ raise PartitioningError, msg
+ for flag in request.fstype.getPartedPartitionFlags():
+ if not newp.is_flag_available(flag):
+ raise PartitioningError, ("requested FileSystemType needs "
+ "a flag that is not available.")
+ newp.set_flag(flag, 1)
+ request.device = PartedPartitionDevice(newp).getDevice()
+ drive = newp.geom.disk.dev.path[5:]
+ request.currentDrive = drive
+ free[drive].remove(freespace)
+ part = disk.next_partition(newp)
+ if part and part.type & parted.PARTITION_FREESPACE:
+ free[drive].append(part)
+ return PARTITION_SUCCESS
+
+
+# grow partitions
+def growParts(diskset, requests):
+# print "growing"
+ newRequest = requests.copy()
+
+ free = findFreespace(diskset)
+ freeSize = {}
+
+ # find out the amount of free space on each drive
+ for key in free.keys():
+ if len(free[key]) == 0:
+ del free[key]
+ continue
+ freeSize[key] = 0
+ for part in free[key]:
+ freeSize[key] = freeSize[key] + getPartSize(part)
+
+ # find growable partitions and find out the size of the growable parts
+ growable = {}
+ growSize = {}
+ for request in newRequest.requests:
+ if request.grow:
+ if not growable.has_key(request.currentDrive):
+ growable[request.currentDrive] = [ request ]
+ growSize[request.currentDrive] = request.size
+ else:
+ growable[request.currentDrive].append(request)
+ growSize[request.currentDrive] = growSize[request.currentDrive] + request.requestSize
+
+ # there aren't any drives with growable partitions, this is easy!
+ if not growable.keys():
+ return PARTITION_SUCCESS
+
+ for drive in growable.keys():
+ # no free space on this drive, so can't grow any of its parts
+ if not free.has_key(drive):
+ continue
+
+ # process each request
+ for request in growable[drive]:
+ percent = request.size / (growSize[drive] * 1.0)
+
+ request.drive = request.currentDrive
+
+ max = int(percent * freeSize[drive]) + request.size
+ if max > request.maxSize:
+ max = request.maxSize
+
+ min = request.requestSize
+ diff = max - min
+ cur = max - (diff / 2)
+ lastDiff = 0
+
+ # binary search
+ while (max != min) and (lastDiff != diff):
+ request.requestSize = cur
+
+ # try adding
+ ret = processPartitioning(diskset, newRequest)
+# print diskset.diskState()
+
+ if ret == PARTITION_SUCCESS:
+ min = cur
+ else:
+ max = cur
+
+ lastDiff = diff
+ diff = max - min
+ cur = max - (diff / 2)
+
+
+ # we could have failed on the last try, in which case we
+ # should go back to the smaller size
+ if ret == PARTITION_FAIL:
+ request.requestSize = min
+ # XXX this can't fail (?)
+ processPartitioning(diskset, newRequest)
+
+ return PARTITION_SUCCESS
+
+
+def deletePart(diskset, delete):
+ disk = diskset.disks[delete.drive]
+ part = disk.next_partition()
+ while part:
+ if part.geom.start == delete.start and part.geom.end == delete.end:
+ disk.delete_partition(part)
+ return
+ part = disk.next_partition(part)
+
+
+def processPartitioning(diskset, requests):
+ # reset disk to original state
+ diskset.refreshDevices()
+ for request in requests.requests:
+ if request.type == REQUEST_NEW:
+ request.device = None
+# request.requestSize = request.size
+
+ # XXX - handle delete requests
+ for delete in requests.deletes:
+ deletePart(diskset, delete)
+# diskset.deleteAllPartitions()
+
+ # sort requests by size
+ requests.sortRequests()
+
+ # partitioning algorithm in simplistic terms
+ #
+ # we want to allocate partitions such that the most specifically
+ # spelled out partitions get what they want first in order to ensure
+ # they don't get preempted. first conflict found returns an error
+ # which must be handled by the caller by saying that the partition
+ # add is impossible (XXX can we get an impossible situation after delete?)
+ #
+ # potentially confusing terms
+ # type == primary vs logical
+ #
+ # order to allocate:
+ # start and end cylinders given (note that start + size & !grow is equivalent)
+ # drive, partnum
+ # drive, type
+ # drive
+ # priority partition (/boot or /)
+ # size
+
+ ret = fitConstrained(diskset, requests)
+ if ret == PARTITION_FAIL:
+ return ret
+
+ ret = fitSized(diskset, requests)
+ if ret == PARTITION_FAIL:
+ return ret
+
+ for request in requests.requests:
+ if request.type != REQUEST_RAID and not request.device:
+# return PARTITION_FAIL
+ raise PartitioningError, "Unsatisfied partition request\n%s" %(request)
+
+ return PARTITION_SUCCESS
+
+## print "disk layout after everything is done"
+## print diskset.diskState()
+
+
+def doPartitioning(diskset, requests):
+ for request in requests.requests:
+ request.requestSize = request.size
+
+ ret = processPartitioning(diskset, requests)
+
+ if ret == PARTITION_FAIL:
+ raise PartitioningError, "Partitioning failed"
+
+ ret = growParts(diskset, requests)
+
+ if ret == PARTITION_SUCCESS:
+ return
+
+ raise PartitioningError, "Growing partitions failed"
+
diff --git a/bootloader.py b/bootloader.py
new file mode 100644
index 000000000..8576ff370
--- /dev/null
+++ b/bootloader.py
@@ -0,0 +1,407 @@
+import isys
+import partitioning
+from translate import _
+from lilo import LiloConfigFile
+import os
+import language
+from flags import flags
+import iutil
+import string
+from log import log
+
+initrdsMade = {}
+
+class KernelArguments:
+
+ def get(self):
+ return self.args
+
+ def set(self, args):
+ self.args = args
+
+ def __init__(self):
+ cdrw = isys.ideCdRwList()
+ str = ""
+ for device in cdrw:
+ if str: str = str + " "
+ str = str + ("%s=ide-scsi" % device)
+
+ self.args = str
+
+class BootImages:
+
+ # returns dictionary of (label, devtype) pairs indexed by device
+ def getImages(self):
+ # return a copy so users can modify it w/o affecting us
+
+ dict = {}
+ for key in self.images.keys():
+ dict[key] = self.images[key]
+
+ return dict
+
+ def setImageLabel(self, dev, label):
+ self.images[dev] = (label, self.images[dev][1])
+
+ # default is a device
+ def setDefault(self, default):
+ self.default = default
+
+ def getDefault(self):
+ return self.default
+
+ def setup(self, diskSet, fsset):
+ devices = {}
+ devs = availableBootDevices(diskSet, fsset)
+ for (dev, type) in devs:
+ devices[dev] = 1
+
+ # These partitions have disappeared
+ for dev in self.images.keys():
+ if devices.has_key(dev): del self.images[dev]
+
+ # These have appeared
+ for (dev, type) in devs:
+ if not self.images.has_key(dev):
+ self.images[dev] = (None, type)
+
+ if not self.images.has_key(self.default):
+ entry = fsset.getEntryByMountPoint('/')
+ self.default = entry.device.getDevice()
+ (label, type) = self.images[self.default]
+ if not label:
+ self.images[self.default] = ("Red Hat Linux 7.2", type)
+
+ def __init__(self):
+ self.default = None
+ self.images = {}
+
+class x86BootloaderInfo:
+
+ def getDevice(self):
+ return self.device
+
+ def setDevice(self, device):
+ self.device = device
+
+ def setUseGrub(self, val):
+ self.useGrubVal = val
+
+ def useGrub(self):
+ return self.useGrubVal
+
+ def writeGrub(self, instRoot, fsset, bl, langs, kernelList, chainList,
+ defaultDev, justConfigFile):
+ images = bl.images.getImages()
+ rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
+ grubRootDev = grubbyPartitionName(rootDev)
+
+ cf = '/boot/grub/grub.conf'
+ perms = 0644
+ if os.access (instRoot + cf, os.R_OK):
+ perms = os.stat(instRoot + cf)[0] & 0777
+ os.rename(instRoot + cf,
+ instRoot + cf + '.rpmsave')
+
+ f = open(instRoot + cf, "w+")
+
+
+ bootDev = fsset.getEntryByMountPoint("/boot")
+ grubPath = "/grub"
+ cfPath = ""
+ if not bootDev:
+ bootDev = fsset.getEntryByMountPoint("/")
+ grubPath = "/boot/grub"
+ cfPath = "/boot"
+ else:
+ f.write ("# NOTICE: You have a /boot partition. This means that\n")
+ f.write ("# all kernel paths are relative to /boot/\n")
+
+ bootDev = bootDev.device.getDevice()
+
+ f.write('default=0\n')
+ f.write('timeout=30\n')
+
+ for (label, version) in kernelList:
+ kernelTag = "-" + version
+ kernelFile = cfPath + "/vmlinuz" + kernelTag
+
+ initrd = makeInitrd (kernelTag, instRoot)
+
+ f.write('title Red Hat Linux 7.2 (%s)\n' % version)
+ f.write('\troot %s\n' % grubRootDev)
+ f.write('\tkernel %s ro root=/dev/%s' % (kernelFile, rootDev))
+ if self.args.get():
+ f.write(' %s' % self.args.get())
+ f.write('\n')
+
+ if os.access (instRoot + initrd, os.R_OK):
+ f.write('\tinitrd %s\n' % (initrd[len(cfPath):], ))
+
+ f.close()
+
+ part = grubbyPartitionName(bootDev)
+ prefix = grubbyPartitionName(bootDev) + "/" + grubPath
+ cmd = "root %s\ninstall %s/i386-pc/stage1 d (%s) %s/i386-pc/stage2 p %s%s/grub.conf" % \
+ (part, grubPath, grubbyDiskName(bl.getDevice()), grubPath,
+ part, grubPath)
+
+ log("GRUB command %s", cmd)
+
+ if not justConfigFile:
+ p = os.pipe()
+ os.write(p[1], cmd + '\n')
+ os.close(p[1])
+
+ iutil.execWithRedirect('/sbin/grub' ,
+ [ "grub", "--batch" ], stdin = p[0],
+ stdout = "/dev/tty5", stderr = "/dev/tty5",
+ root = instRoot)
+ os.close(p[0])
+
+ return None
+
+ def writeLilo(self, instRoot, fsset, bl, langs, kernelList, chainList,
+ defaultDev, justConfigFile):
+ images = bl.images.getImages()
+
+ # on upgrade read in the lilo config file
+ lilo = LiloConfigFile ()
+ perms = 0644
+ if os.access (instRoot + '/etc/lilo.conf', os.R_OK):
+ perms = os.stat(instRoot + '/etc/lilo.conf')[0] & 0777
+ lilo.read (instRoot + '/etc/lilo.conf')
+ os.rename(instRoot + '/etc/lilo.conf',
+ instRoot + '/etc/lilo.conf.rpmsave')
+
+ # Remove any invalid entries that are in the file; we probably
+ # just removed those kernels.
+ for label in lilo.listImages():
+ (fsType, sl) = lilo.getImage(label)
+ if fsType == "other": continue
+
+ if not os.access(instRoot + sl.getPath(), os.R_OK):
+ lilo.delImage(label)
+
+ liloTarget = bl.getDevice()
+
+ lilo.addEntry("boot", '/dev/' + liloTarget, replace = 0)
+ lilo.addEntry("map", "/boot/map", replace = 0)
+ lilo.addEntry("install", "/boot/boot.b", replace = 0)
+ lilo.addEntry("prompt", replace = 0)
+ lilo.addEntry("timeout", "50", replace = 0)
+ message = "/boot/message"
+ for lang in language.expandLangs(langs.getDefault()):
+ fn = "/boot/message." + lang
+ if os.access(instRoot + fn, os.R_OK):
+ message = fn
+ break
+
+ lilo.addEntry("message", message, replace = 0)
+
+ if not lilo.testEntry('lba32') and not lilo.testEntry('linear'):
+ lilo.addEntry("linear", replace = 0)
+
+ rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
+ if not rootDev:
+ raise RuntimeError, "Installing lilo, but there is no root device"
+
+ if rootDev == defaultDev:
+ lilo.addEntry("default", kernelList[0][0])
+ else:
+ lilo.addEntry("default", otherList[0][0])
+
+ for (label, version) in kernelList:
+ kernelTag = "-" + version
+ kernelFile = "/boot/vmlinuz" + kernelTag
+
+ try:
+ lilo.delImage(label)
+ except IndexError, msg:
+ pass
+
+ sl = LiloConfigFile(imageType = "image", path = kernelFile)
+
+ initrd = makeInitrd (kernelTag, instRoot)
+
+ sl.addEntry("label", label)
+ if os.access (instRoot + initrd, os.R_OK):
+ sl.addEntry("initrd", initrd)
+
+ sl.addEntry("read-only")
+ sl.addEntry("root", '/dev/' + rootDev)
+
+ if self.args.get():
+ sl.addEntry('append', '"%s"' % self.args.get())
+
+ lilo.addImage (sl)
+
+ for (label, device) in chainList:
+ try:
+ (fsType, sl) = lilo.getImage(label)
+ lilo.delImage(label)
+ except IndexError:
+ sl = LiloConfigFile(imageType = "other", path = device)
+ sl.addEntry("optional")
+
+ sl.addEntry("label", label)
+ lilo.addImage (sl)
+
+ # Sanity check #1. There could be aliases in sections which conflict
+ # with the new images we just created. If so, erase those aliases
+ imageNames = {}
+ for label in lilo.listImages():
+ imageNames[label] = 1
+
+ for label in lilo.listImages():
+ (fsType, sl) = lilo.getImage(label)
+ if sl.testEntry('alias'):
+ alias = sl.getEntry('alias')
+ if imageNames.has_key(alias):
+ sl.delEntry('alias')
+ imageNames[alias] = 1
+
+ # Sanity check #2. If single-key is turned on, go through all of
+ # the image names (including aliases) (we just built the list) and
+ # see if single-key will still work.
+ if lilo.testEntry('single-key'):
+ singleKeys = {}
+ turnOff = 0
+ for label in imageNames.keys():
+ l = label[0]
+ if singleKeys.has_key(l):
+ turnOff = 1
+ singleKeys[l] = 1
+ if turnOff:
+ lilo.delEntry('single-key')
+
+ lilo.write(instRoot + "/etc/lilo.conf", perms = perms)
+
+ if not justConfigFile:
+ # throw away stdout, catch stderr
+ str = iutil.execWithCapture(instRoot + '/sbin/lilo' ,
+ [ "lilo", "-r", instRoot ],
+ catchfd = 2, closefd = 1)
+ else:
+ str = ""
+
+ return str
+
+ def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
+ defaultDev, justConfig):
+ if self.useGrubVal:
+ str = self.writeGrub(instRoot, fsset, bl, langs, kernelList,
+ chainList, defaultDev, justConfig)
+ else:
+ str = self.writeLilo(instRoot, fsset, bl, langs, kernelList,
+ chainList, defaultDev, justConfig)
+
+
+ def __init__(self):
+ self.args = KernelArguments()
+ self.images = BootImages()
+ self.useGrubVal = 1 # use lilo otherwise
+ self.device = None
+
+def availableBootDevices(diskSet, fsset):
+ devs = []
+ foundDos = 0
+ for (dev, type) in diskSet.partitionTypes():
+ if type == 'FAT' and not foundDos:
+ foundDos = 1
+ isys.makeDevInode(dev, '/tmp/' + dev)
+
+ try:
+ bootable = isys.checkBoot('/tmp/' + dev)
+ devs.append((dev, type))
+ except:
+ pass
+ elif type == 'ntfs' or type =='hpfs':
+ devs.append((dev, type))
+
+ devs.append((fsset.getEntryByMountPoint('/').device.getDevice(), 'ext2'))
+
+ devs.sort()
+
+ return devs
+
+def partitioningComplete(dispatch, bl, fsset, diskSet):
+ choices = fsset.bootloaderChoices(diskSet)
+ if not choices:
+ dispatch.skipStep("instbootloader")
+ else:
+ dispatch.skipStep("instbootloader", skip = 0)
+
+ bl.images.setup(diskSet, fsset)
+
+def writeBootloader(intf, instRoot, fsset, bl, langs, comps):
+ justConfigFile = not flags.setupFilesystems
+
+ w = intf.waitWindow(_("Bootloader"), _("Installing bootloader..."))
+
+ kernelList = []
+ otherList = []
+ rootDev = fsset.getEntryByMountPoint('/').device.getDevice()
+ defaultDev = bl.images.getDefault()
+
+ for (dev, (label, type)) in bl.images.getImages().items():
+ if dev == rootDev:
+ kernelLabel = label
+ elif dev == defaultDev:
+ otherList = [(label, dev)] + otherList
+ else:
+ otherList.append(label, dev)
+
+ plainLabelUsed = 0
+ for (version, nick) in comps.kernelVersionList():
+ if plainLabelUsed:
+ kernelList.append(kernelLabel + "-" + nick, version)
+ else:
+ kernelList.append(kernelLabel, version)
+ plainLabelUsed = 1
+
+ bl.write(instRoot, fsset, bl, langs, kernelList, otherList, defaultDev,
+ justConfigFile)
+
+ w.pop()
+
+def makeInitrd (kernelTag, instRoot):
+ global initrdsMade
+
+ initrd = "/boot/initrd%s.img" % (kernelTag, )
+
+ if not initrdsMade.has_key(initrd) and flags.setupFilesystems:
+ iutil.execWithRedirect("/sbin/mkinitrd",
+ [ "/sbin/mkinitrd",
+ "--ifneeded",
+ "-f",
+ initrd,
+ kernelTag[1:] ],
+ stdout = None, stderr = None, searchPath = 1,
+ root = instRoot)
+ initrdsMade[kernelTag] = 1
+
+ return initrd
+
+def grubbyDiskName(name):
+ drives = isys.hardDriveDict().keys()
+ drives.sort (isys.compareDrives)
+
+ return "hd%d" % drives.index(name)
+
+def grubbyPartitionName(dev):
+ cut = -1
+ if dev[-2] in string.digits:
+ cut = -2
+
+ partNum = int(dev[cut:]) - 1
+ name = dev[:cut]
+
+ # hack off the trailing 'p' from /dev/cciss/*, for example
+ if name[-1] == 'p':
+ for letter in name:
+ if letter not in string.letters and letter != "/":
+ name = name[:-1]
+ break
+
+ return "(%s,%d)" % (grubbyDiskName(name), partNum)
diff --git a/desktop.py b/desktop.py
new file mode 100644
index 000000000..4ab0caa92
--- /dev/null
+++ b/desktop.py
@@ -0,0 +1,51 @@
+import string
+import kudzu
+import iutil
+import isys
+from log import log
+
+class Desktop:
+#
+# This class represents the default desktop to run and the default runlevel
+# to start in
+#
+
+ def setDefaultDesktop(self, desktop):
+ self.desktop = desktop
+
+ def setDefaultRunLevel(self, runlevel):
+ if str(runlevel) != "3" and str(runlevel) != "5":
+ raise RuntimeError, "Desktop::setDefaultRunLevel() - Must specify runlevel as 3 or 5!"
+ self.runlevel = runlevel
+
+ def getDefaultDesktop(self):
+ return self.desktop
+
+ def getDefaultRunLevel(self):
+ return self.runlevel
+
+ def __init__ (self):
+ self.desktop = None
+ self.runlevel = 3
+
+ def write (self, instPath):
+ #
+ # XXX
+ #
+ return
+
+ try:
+ inittab = open (instPath + '/etc/inittab', 'r')
+ except IOError:
+ log ("WARNING, there is no inittab, bad things will happen!")
+ return
+ lines = inittab.readlines ()
+ inittab.close ()
+ inittab = open (instPath + '/etc/inittab', 'w')
+ for line in lines:
+ if len (line) > 3 and line[:3] == "id:":
+ fields = string.split (line, ':')
+ fields[1] = str (self.runlevel)
+ line = string.join (fields, ':')
+ inittab.write (line)
+ inittab.close ()
diff --git a/firewall.py b/firewall.py
new file mode 100644
index 000000000..00f3c819c
--- /dev/null
+++ b/firewall.py
@@ -0,0 +1,89 @@
+import os
+import iutil
+import string
+from log import log
+from flags import flags
+
+class Firewall:
+ def __init__ (self):
+ self.enabled = -1
+ self.ssh = 0
+ self.telnet = 0
+ self.smtp = 0
+ self.http = 0
+ self.ftp = 0
+ self.portlist = ""
+ self.ports = []
+ self.policy = 0
+ self.dhcp = 0
+ self.trustdevs = []
+
+ def writeKS(self, f):
+ f.write("firewall")
+
+ if self.enabled > 0:
+ for arg in self.getArgList():
+ f.write(" " + arg)
+ else:
+ f.write(" --disabled")
+
+ f.write("\n")
+
+ def getArgList(self):
+ args = []
+
+ if self.policy:
+ args.append ("--medium")
+ else:
+ args.append ("--high")
+ if self.dhcp:
+ args.append ("--dhcp")
+ if self.portlist:
+ ports = string.split(self.portlist,',')
+ for port in ports:
+ port = string.strip(port)
+ try:
+ if not string.index(port,':'):
+ port = '%s:tcp' % port
+ except:
+ pass
+ self.ports.append(port)
+ for port in self.ports:
+ args = args + [ "--port", port ]
+ if self.smtp:
+ args = args + [ "--port","smtp:tcp" ]
+ if self.http:
+ args = args + [ "--port","http:tcp" ]
+ if self.ftp:
+ args = args + [ "--port","ftp:tcp" ]
+ if self.ssh:
+ args = args + [ "--port","ssh:tcp" ]
+ if self.telnet:
+ args = args + [ "--port","telnet:tcp" ]
+ for dev in self.trustdevs:
+ args = args + [ "--trust", dev ]
+
+ return args
+
+ def write (self, instPath):
+ args = [ "/usr/sbin/lokkit", "--quiet", "--nostart" ]
+
+ if self.enabled > 0:
+ args = args + self.getArgList()
+
+ try:
+ if flags.setupFilesystems:
+ iutil.execWithRedirect(args[0], args, root = instPath,
+ stdout = None, stderr = None)
+ else:
+ log("would have run %s", args)
+ except RuntimeError, msg:
+ log ("lokkit run failed: %s", msg)
+ except OSError, (errno, msg):
+ log ("lokkit run failed: %s", msg)
+ else:
+ # remove /etc/sysconfig/ipchains
+ file = instPath + "/etc/sysconfig/ipchains"
+ if os.access(file, os.O_RDONLY):
+ os.remove(file)
+
diff --git a/flags.py b/flags.py
new file mode 100644
index 000000000..b2ef58f70
--- /dev/null
+++ b/flags.py
@@ -0,0 +1,25 @@
+# A lot of effort, but it only allows a limited set of flags to be referenced
+class Flags:
+
+ def __getattr__(self, attr):
+ if self.__dict__['flags'].has_key(attr):
+ return self.__dict__['flags'][attr]
+
+ raise AttributeError, attr
+
+ def __setattr__(self, attr, val):
+ if self.__dict__['flags'].has_key(attr):
+ self.__dict__['flags'][attr] = val
+ else:
+ raise AttributeError, attr
+
+ def __init__(self):
+ self.__dict__['flags'] = {}
+ self.__dict__['flags']['test'] = 0
+ self.__dict__['flags']['expert'] = 0
+ self.__dict__['flags']['serial'] = 0
+ self.__dict__['flags']['setupFilesystems'] = 1
+
+
+global flags
+flags = Flags()
diff --git a/instdata.py b/instdata.py
new file mode 100644
index 000000000..fa19390c0
--- /dev/null
+++ b/instdata.py
@@ -0,0 +1,143 @@
+import language
+import kbd
+import network
+import firewall
+import timezone
+import desktop
+import users
+import fsset
+import partitioning
+import bootloader
+from simpleconfig import SimpleConfigFile
+from translate import _
+
+class Boolean:
+ def set(self, val):
+ self.val = val
+
+ def get(self):
+ return self.val
+
+ def __init__(self, val = 0):
+ self.val = val
+
+# Collector class for all data related to an install/upgrade.
+
+class InstallData:
+
+ def reset(self):
+ # Reset everything except:
+ #
+ # - The mouse
+ # - The install language
+ # - The keyboard
+
+ self.langSupport = language.Language(0)
+ self.instClass = None
+ self.network = network.Network()
+ self.firewall = firewall.Firewall()
+ self.timezone = timezone.Timezone()
+ self.accounts = users.Accounts()
+ self.rootPassword = users.RootPassword ()
+ self.auth = users.Authentication()
+ self.desktop = desktop.Desktop()
+ self.hdList = None
+ self.comps = None
+ self.upgrade = Boolean()
+ self.fsset.reset()
+ self.diskset = partitioning.DiskSet()
+ self.partrequests = partitioning.PartitionRequests(self.diskset)
+ self.bootloader = bootloader.x86BootloaderInfo()
+
+ def setInstallProgressClass(self, c):
+ self.instProgress = c
+
+ # expects a Mouse object
+ def setMouse(self, mouse):
+ self.mouse = mouse
+
+ # expects a VideoCardInfo object
+ def setVideoCard(self, video):
+ self.videocard = video
+
+ # expects a Monitor object
+ def setMonitor(self, monitor):
+ self.monitor = monitor
+
+ # expects a XF86Config object
+ def setXconfig(self, xconfig):
+ self.xconfig = xconfig
+
+ def write(self, instPath):
+ self.langSupport.write (instPath)
+ self.mouse.write(instPath)
+ self.keyboard.write (instPath)
+ self.network.write (instPath)
+ self.auth.write (instPath)
+ self.firewall.write (instPath)
+ self.rootPassword.write (instPath, self.auth)
+ self.accounts.write (instPath, self.auth)
+ self.desktop.write (instPath)
+ self.fsset.write (instPath)
+
+ def writeKS(self, filename):
+ # make it so only root can read, could have password
+ f = open(filename, "w", 0600)
+
+ f.write("# Kickstart file automatically generated by anaconda.\n\n")
+ if self.upgrade.get():
+ f.write("upgrade\n");
+ else:
+ f.write("install\n");
+
+ self.instLanguage.writeKS(f)
+ self.langSupport.writeKS(f)
+ self.keyboard.writeKS(f)
+ self.mouse.writeKS(f)
+ self.xconfig.writeKS(f)
+ self.network.writeKS(f)
+ self.rootPassword.writeKS(f)
+ self.firewall.writeKS(f)
+ self.auth.writeKS(f)
+ self.timezone.writeKS(f)
+
+ f.write("\n%packages\n")
+ packages = {}
+ for comp in self.comps:
+ if comp.isSelected():
+ if comp.isSelected(justManual = 1) and comp.name != "Base":
+ f.write("@ %s\n" % comp.name)
+
+ for pkg in comp.packages():
+ packages[pkg] = 1
+
+ for pkg in self.hdList.values():
+ if not packages.has_key(pkg) and pkg.isSelected():
+ f.write("%s\n" % pkg.name)
+ if pkg.wasForcedOff():
+ f.write("-%s\n" %(pkg.name))
+
+ f.write("\n%post\n")
+ self.accounts.writeKScommands(f, self.auth)
+
+ # XXX
+ #self.monitor
+ #self.mouse
+ #self.videoCard
+ #self.fstab
+ #self.desktop
+ #
+
+
+ def __init__(self, extraModules):
+ self.instLanguage = language.InstallTimeLanguage()
+ self.keyboard = kbd.Keyboard()
+
+ self.mouse = None
+ self.monitor = None
+ self.videocard = None
+ self.xconfig = None
+ self.extraModules = extraModules
+ self.fsset = fsset.FileSystemSet()
+
+ self.reset()
diff --git a/network.py b/network.py
new file mode 100644
index 000000000..93caa608b
--- /dev/null
+++ b/network.py
@@ -0,0 +1,256 @@
+from simpleconfig import SimpleConfigFile
+import string
+import isys
+import socket
+import os
+from log import log
+
+class NetworkDevice (SimpleConfigFile):
+ def __str__ (self):
+ s = ""
+ s = s + "DEVICE=" + self.info["DEVICE"] + "\n"
+ keys = self.info.keys ()
+ keys.sort ()
+ keys.remove ("DEVICE")
+
+ # Don't let onboot be turned on unless we have config information
+ # to go along with it
+ if self.get('bootproto') != 'dhcp' and not self.get('ipaddr'):
+ forceOffOnBoot = 1
+ else:
+ forceOffOnBoot = 0
+
+ onBootWritten = 0
+ for key in keys:
+ if key == 'ONBOOT' and forceOffOnBoot:
+ s = s + key + "=" + 'no' + "\n"
+ else:
+ s = s + key + "=" + self.info[key] + "\n"
+
+ if key == 'ONBOOT':
+ onBootWritten = 1
+
+ if not onBootWritten:
+ s = s + 'ONBOOT=no\n'
+
+ return s
+
+ def __init__ (self, dev):
+ self.info = { "DEVICE" : dev }
+
+class Network:
+ def __init__ (self):
+ self.netdevices = {}
+ self.gateway = ""
+ self.primaryNS = ""
+ self.secondaryNS = ""
+ self.ternaryNS = ""
+ self.domains = []
+ self.readData = 0
+ self.isConfigured = 0
+ self.hostname = "localhost.localdomain"
+
+ try:
+ f = open ("/tmp/netinfo", "r")
+ except:
+ pass
+ else:
+ lines = f.readlines ()
+ f.close ()
+ info = {}
+ self.isConfigured = 1
+ for line in lines:
+ netinf = string.splitfields (line, '=')
+ info [netinf[0]] = string.strip (netinf[1])
+ self.netdevices [info["DEVICE"]] = NetworkDevice (info["DEVICE"])
+ if info.has_key ("IPADDR"):
+ self.netdevices [info["DEVICE"]].set (("IPADDR", info["IPADDR"]))
+ if info.has_key ("NETMASK"):
+ self.netdevices [info["DEVICE"]].set (("NETMASK", info["NETMASK"]))
+ if info.has_key ("BOOTPROTO"):
+ self.netdevices [info["DEVICE"]].set (("BOOTPROTO", info["BOOTPROTO"]))
+ if info.has_key ("ONBOOT"):
+ self.netdevices [info["DEVICE"]].set (("ONBOOT", info["ONBOOT"]))
+ if info.has_key ("GATEWAY"):
+ self.gateway = info["GATEWAY"]
+ if info.has_key ("DOMAIN"):
+ self.domains.append(info["DOMAIN"])
+ if info.has_key ("HOSTNAME"):
+ self.hostname = info["HOSTNAME"]
+
+ self.readData = 1
+ try:
+ f = open ("/etc/resolv.conf", "r")
+ except:
+ pass
+ else:
+ lines = f.readlines ()
+ f.close ()
+ for line in lines:
+ resolv = string.split (line)
+ if resolv and resolv[0] == 'nameserver':
+ if self.primaryNS == "":
+ self.primaryNS = resolv[1]
+ elif self.secondaryNS == "":
+ self.secondaryNS = resolv[1]
+ elif self.ternaryNS == "":
+ self.ternaryNS = resolv[1]
+
+ def getDevice(self, device):
+ return self.netdevices[device]
+
+ def available (self):
+ f = open ("/proc/net/dev")
+ lines = f.readlines()
+ f.close ()
+ # skip first two lines, they are header
+ lines = lines[2:]
+ for line in lines:
+ dev = string.strip (line[0:6])
+ if dev != "lo" and not self.netdevices.has_key (dev):
+ self.netdevices[dev] = NetworkDevice (dev)
+ return self.netdevices
+
+ def setHostname(self, hn):
+ self.hostname = hn
+
+ def lookupHostname (self):
+ # can't look things up if they don't exist!
+ if not self.hostname or self.hostname == "localhost.localdomain": return None
+ if not self.primaryNS: return
+ if not self.isConfigured:
+ for dev in self.netdevices.values():
+ if dev.get('bootproto') == "dhcp":
+ self.primaryNS = isys.pumpNetDevice(dev.get('device'))
+ self.isConfigured = 1
+ break
+ elif dev.get('ipaddr') and dev.get('netmask'):
+ try:
+ isys.configNetDevice(dev.get('device'),
+ dev.get('ipaddr'),
+ dev.get('netmask'),
+ self.gateway)
+ self.isConfigured = 1
+ break
+ except SystemError:
+ log ("failed to configure network device %s when "
+ "looking up host name", dev.get('device'))
+
+ if not self.isConfigured:
+ log ("no network devices were availabe to look up host name")
+ return None
+
+ f = open("/etc/resolv.conf", "w")
+ f.write("nameserver %s\n" % self.primaryNS)
+ f.close()
+ isys.resetResolv()
+ isys.setResolvRetry(2)
+
+ try:
+ ip = socket.gethostbyname(self.hostname)
+ except:
+ return None
+
+ return ip
+
+ def nameservers (self):
+ return [ self.primaryNS, self.secondaryNS, self.ternaryNS ]
+
+ def writeKS(self, f):
+ # XXX
+ #
+ # Hopefully the first one is the right one to use. We ought to support
+ # multiple "network" lines
+ #
+ # This doesn't write out nodns, ever.
+ #
+ devNames = self.netdevices.keys()
+ devNames.sort()
+ dev = self.netdevices[devNames[0]]
+
+ if dev.get('bootproto') == 'dhcp' or dev.get('ipaddr'):
+ f.write("network --device %s" % dev.get('device'))
+ if dev.get('bootproto') == 'dhcp':
+ f.write(" --bootproto dhcp")
+ else:
+ f.write(" --ip %s --network %s --netmask %s" %
+ (dev.get('ipaddr'), dev.get('netmask'), dev.get('gateway')))
+
+ if dev.get('nameserver'):
+ f.write(" --nameserver %s" % dev.get('nameserver'))
+
+ if self.hostname and self.hostname != "localhost.localdomain":
+ f.write(" --hostname %s" % dev.get('hostname'))
+
+ f.write("\n");
+
+ def write (self, instPath):
+ # /etc/sysconfig/network-scripts/ifcfg-*
+ for dev in self.netdevices.values ():
+ device = dev.get ("device")
+ fn = instPath + "/etc/sysconfig/network-scripts/ifcfg-" + device
+ f = open (fn, "w")
+ os.chmod(fn, 0600)
+ f.write (str (dev))
+ f.close ()
+
+ # /etc/sysconfig/network
+
+ f = open (instPath + "/etc/sysconfig/network", "w")
+ f.write ("NETWORKING=yes\n"
+ "HOSTNAME=")
+
+
+ # use instclass hostname if set (kickstart) to override
+ if self.hostname:
+ f.write(self.hostname + "\n")
+ else:
+ f.write("localhost.localdomain" + "\n")
+ if self.gateway:
+ f.write("GATEWAY=" + self.gateway + "\n")
+ f.close ()
+
+ # /etc/hosts
+ f = open (instPath + "/etc/hosts", "w")
+ localline = "127.0.0.1\t\t"
+
+ log ("self.hostname = %s", self.hostname)
+
+ ip = self.lookupHostname()
+
+ # If the hostname is not resolvable, tie it to 127.0.0.1
+ if not ip and self.hostname != "localhost.localdomain":
+ localline = localline + self.hostname + " "
+ l = string.split(self.hostname, ".")
+ if len(l) > 1:
+ localline = localline + l[0] + " "
+
+ localline = localline + "localhost.localdomain localhost\n"
+ f.write("# Do not remove the following line, or various programs\n")
+ f.write("# that require network functionality will fail.\n")
+ f.write (localline)
+
+ if ip:
+ f.write ("%s\t\t%s\n" % (ip, self.hostname))
+
+ # If the hostname was not looked up, but typed in by the user,
+ # domain might not be computed, so do it now.
+ if self.domains == [ "localdomain" ] or not self.domains:
+ if '.' in self.hostname:
+ # chop off everything before the leading '.'
+ domain = self.hostname[(string.find(self.hostname, '.') + 1):]
+ self.domains = [ domain ]
+
+ # /etc/resolv.conf
+ f = open (instPath + "/etc/resolv.conf", "w")
+
+ if self.domains != [ 'localdomain' ] and self.domains:
+ f.write ("search " + string.joinfields (self.domains, ' ')
+ + "\n")
+
+ for ns in self.nameservers ():
+ if ns:
+ f.write ("nameserver " + ns + "\n")
+
+ f.close ()
+
diff --git a/packages.py b/packages.py
new file mode 100644
index 000000000..b9da7961e
--- /dev/null
+++ b/packages.py
@@ -0,0 +1,797 @@
+#
+# packages.py: package management - mainly package installation
+#
+# Erik Troan <ewt@redhat.com>
+#
+# Copyright 2001 Red Hat, Inc.
+#
+# This software may be freely redistributed under the terms of the GNU
+# library public license.
+#
+# You should have received a copy of the GNU Library Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+from translate import _
+import iutil
+import isys
+import rpm
+import os
+import timer
+import sys
+import string
+import pcmcia
+import dispatch
+from log import log
+from flags import flags
+
+def queryUpgradeContinue(intf, dir, dispatch):
+ if dir == dispatch.DISPATCH_BACK:
+ return
+
+ rc = intf.messageWindow(_("Proceed with upgrade?"),
+ _("The filesystems of the Linux installation "
+ "you have chosen to upgrade have already been "
+ "mounted. You cannot go back past this point. "
+ "\n\n") +
+ _( "Would you like to continue with the upgrade?"),
+ type = "yesno").getrc()
+ if rc == 1:
+ sys.exit(0)
+ dispatch.gotoNext()
+
+def writeConfiguration(id, instPath):
+ log("Writing main configuration")
+ if not flags.test:
+ id.write(instPath)
+
+def writeKSConfiguration(id, instPath):
+ log("Writing autokickstart file")
+ if not flags.test:
+ fn = instPath + "/root/anaconda-ks.cfg"
+ else:
+ fn = "/tmp/anaconda-ks.cfg"
+
+ id.writeKS(fn)
+
+def writeXConfiguration(id, instPath):
+ xserver = id.videocard.primaryCard().getXServer()
+ if not xserver:
+ return
+
+ log("Writing X configuration")
+ if not flags.test:
+ fn = instPath
+
+ if os.access (instPath + "/etc/X11/X", os.R_OK):
+ os.rename (instPath + "/etc/X11/X",
+ instPath + "/etc/X11/X.rpmsave")
+
+ try:
+ os.unlink (instPath + "/etc/X11/X")
+ except OSError:
+ pass
+
+ os.symlink ("../../usr/X11R6/bin/" + xserver,
+ instPath + "/etc/X11/X")
+ print "linked ../../usr/X11R6/bin/",xserver," to ",instPath,"/etc/X11/X"
+ else:
+ fn = "/tmp/"
+
+ id.xconfig.write(fn+"/etc/X11")
+
+def readPackages(intf, method, id):
+ if (not id.hdList):
+ w = intf.waitWindow(_("Reading"), _("Reading package information..."))
+ id.hdList = method.readHeaders()
+ id.instClass.setPackageSelection(id.hdList)
+ w.pop()
+
+ if not id.comps:
+ id.comps = method.readComps(id.hdList)
+ id.instClass.setGroupSelection(id.comps)
+
+ # XXX
+ #updateInstClassComps ()
+ else:
+ # re-evaluate all the expressions for packages with qualifiers.
+
+ id.comps.updateSelections()
+
+def handleX11Packages(dir, intf, disp, id, instPath):
+
+ if dir == dispatch.DISPATCH_BACK:
+ return
+
+ # skip X setup if it is not being installed
+ if (not id.comps.packages.has_key('XFree86') or
+ not id.comps.packages['XFree86'].selected):
+ disp.skipStep("videocard")
+ disp.skipStep("monitor")
+ disp.skipStep("xcustom")
+ disp.skipStep("writexconfig")
+ elif disp.stepInSkipList("videocard"):
+ # if X is being installed, but videocard step skipped
+ # need to turn it back on
+ disp.skipStep("videocard", skip=0)
+ disp.skipStep("monitor", skip=0)
+ disp.skipStep("xcustom", skip=0)
+ disp.skipStep("writexconfig", skip=0)
+
+ # set default runlevel based on packages
+ gnomeSelected = (id.comps.packages.has_key('gnome-core')
+ and id.comps.packages['gnome-core'].selected)
+ kdeSelected = (id.comps.packages.has_key('kdebase')
+ and id.comps.packages['kdebase'].selected)
+
+ if gnomeSelected:
+ id.desktop.setDefaultDesktop("GNOME")
+ elif kdeSelected:
+ id.desktop.setDefaultDesktop("KDE")
+
+ if gnomeSelected or kdeSelected:
+ id.desktop.setDefaultRunLevel(5)
+
+
+def checkDependencies(dir, intf, disp, id, instPath):
+ if dir == dispatch.DISPATCH_BACK:
+ return
+
+ win = intf.waitWindow(_("Dependency Check"),
+ _("Checking dependencies in packages selected for installation..."))
+
+ id.dependencies = id.comps.verifyDeps(instPath, id.upgrade.get())
+
+ win.pop()
+
+ if id.dependencies:
+ disp.skipStep("dependencies", skip = 0)
+ else:
+ disp.skipStep("dependencies")
+
+#XXX
+#try:
+ #self.todo.getHeaderList ()
+ #self.todo.getCompsList()
+ #self.files_found = "TRUE"
+#except ValueError, msg:
+ #extra = msg
+#except RuntimeError, msg:
+ #extra = msg
+#except TypeError, msg:
+ #extra = msg
+#except KeyError, key:
+ #extra = ("The comps file references a package called \"%s\" which "
+ #"could not be found." % (key,))
+#except:
+ #extra = ""
+#
+#if self.files_found == "FALSE":
+ #if extra:
+ #text = (_("The following error occurred while "
+ #"retreiving hdlist file:\n\n"
+ #"%s\n\n"
+ #"Installer will exit now.") % extra)
+ #else:
+ #text = (_("An error has occurred while retreiving the hdlist "
+ #"file. The installation media or image is "
+ #"probably corrupt. Installer will exit now."))
+ #win = ErrorWindow (text)
+#else:
+
+class InstallCallback:
+
+ def cb(self, what, amount, total, h, (param)):
+ if (what == rpm.RPMCALLBACK_TRANS_START):
+ # step 6 is the bulk of the transaction set
+ # processing time
+ if amount == 6:
+ self.progressWindow = \
+ self.progressWindowClass (_("Processing"),
+ _("Preparing to install..."),
+ total)
+ if (what == rpm.RPMCALLBACK_TRANS_PROGRESS):
+ if self.progressWindow:
+ self.progressWindow.set (amount)
+
+ if (what == rpm.RPMCALLBACK_TRANS_STOP and self.progressWindow):
+ self.progressWindow.pop ()
+
+ if (what == rpm.RPMCALLBACK_INST_OPEN_FILE):
+ # We don't want to start the timer until we get to the first
+ # file.
+ self.pkgTimer.start()
+
+ self.progress.setPackage(h)
+ self.progress.setPackageScale(0, 1)
+ self.instLog.write (self.modeText % (h[rpm.RPMTAG_NAME],))
+ self.instLog.flush ()
+ fn = self.method.getFilename(h, self.pkgTimer)
+
+ self.rpmFD = -1
+ while self.rpmFD < 0:
+ try:
+ self.rpmFD = os.open(fn, os.O_RDONLY)
+ # Make sure this package seems valid
+ try:
+ (h, isSource) = rpm.headerFromPackage(self.rpmFD)
+ os.lseek(self.rpmFD, 0, 0)
+ except:
+ self.rpmFD = -1
+ os.close(self.rpmFD)
+ raise SystemError
+ except:
+ self.messageWindow(_("Error"),
+ _("The file %s cannot be opened. This is due to "
+ "a missing file, a bad package, or bad media. "
+ "Press <return> to try again.") % fn)
+
+ fn = self.method.unlinkFilename(fn)
+ return self.rpmFD
+ elif (what == rpm.RPMCALLBACK_INST_PROGRESS):
+ if total:
+ self.progress.setPackageScale(amount, total)
+ pass
+ elif (what == rpm.RPMCALLBACK_INST_CLOSE_FILE):
+ os.close (self.rpmFD)
+ self.progress.completePackage(h, self.pkgTimer)
+ else:
+ pass
+
+ self.progress.processEvents()
+
+ def __init__(self, messageWindow, progress, pkgTimer, method,
+ progressWindowClass, instLog, modeText):
+ self.messageWindow = messageWindow
+ self.progress = progress
+ self.pkgTimer = pkgTimer
+ self.method = method
+ self.progressWindowClass = progressWindowClass
+ self.progressWindow = None
+ self.instLog = instLog
+ self.modeText = modeText
+
+def sortPackages(first, second):
+ # install packages in cd order (cd tag is 1000002)
+ one = None
+ two = None
+
+ if first[1000003] != None:
+ one = first[1000003]
+
+ if second[1000003] != None:
+ two = second[1000003]
+
+ if one == None or two == None:
+ one = 0
+ two = 0
+ if first[1000002] != None:
+ one = first[1000002]
+
+ if second[1000002] != None:
+ two = second[1000002]
+
+ if one < two:
+ return -1
+ elif one > two:
+ return 1
+ elif string.lower(first[rpm.RPMTAG_NAME]) < string.lower(second[rpm.RPMTAG_NAME]):
+ return -1
+ elif string.lower(first[rpm.RPMTAG_NAME]) > string.lower(second[rpm.RPMTAG_NAME]):
+ return 1
+
+ return 0
+
+class rpmErrorClass:
+
+ def cb(self):
+ self.f.write (rpm.errorString () + "\n")
+
+ def __init__(self, f):
+ self.f = f
+
+def turnOnFilesystems(dir, fsset, diskset, upgrade, instPath):
+ if dir == dispatch.DISPATCH_BACK:
+ fsset.umountFilesystems(instPath)
+ return
+
+ if flags.setupFilesystems:
+ if not upgrade.get():
+ diskset.savePartitions ()
+ fsset.formatSwap(instPath)
+ fsset.turnOnSwap(instPath)
+ fsset.makeFilesystems (instPath)
+ fsset.mountFilesystems (instPath)
+
+def doInstall(method, id, intf, instPath):
+ if flags.test:
+ return
+
+ arch = iutil.getArch ()
+
+ if arch == "alpha":
+ # if were're on alpha with ARC console, set the clock
+ # so that our installed files won't be in the future
+ from milo import MiloInstall, onMILO
+ if onMILO ():
+ args = ("clock", "-A", "-s")
+ try:
+ iutil.execWithRedirect('/usr/sbin/clock', args)
+ except:
+ pass
+
+ # shorthand
+ upgrade = id.upgrade.get()
+
+ if not upgrade:
+ # this is NICE and LATE. It lets kickstart/server/workstation
+ # installs detect this properly
+ if (id.hdList.has_key('kernel-smp') and isys.smpAvailable()):
+ id.hdList['kernel-smp'].selected = 1
+
+ if (id.hdList.has_key('kernel-enterprise')):
+ import lilo
+
+ if lilo.needsEnterpriseKernel():
+ id.hdList['kernel-enterprise'].selected = 1
+
+ # we *always* need a kernel installed
+ if (id.hdList.has_key('kernel')):
+ id.hdList['kernel'].selected = 1
+
+ # if NIS is configured, install ypbind and dependencies:
+ if id.auth.useNIS:
+ id.hdList['ypbind'].selected = 1
+ id.hdList['yp-tools'].selected = 1
+ id.hdList['portmap'].selected = 1
+
+ if id.auth.useLdap:
+ id.hdList['nss_ldap'].selected = 1
+ id.hdList['openldap'].selected = 1
+ id.hdList['perl'].selected = 1
+
+ if id.auth.useKrb5:
+ id.hdList['pam_krb5'].selected = 1
+ id.hdList['krb5-workstation'].selected = 1
+ id.hdList['krbafs'].selected = 1
+ id.hdList['krb5-libs'].selected = 1
+
+ xserver = id.videocard.primaryCard().getXServer()
+ if xserver and id.comps.packages.has_key('XFree86') and id.comps.packages['XFree86'].selected and xserver != "XFree86":
+ try:
+ id.hdList['XFree86-' + xserver[5:]].selected = 1
+ except ValueError, message:
+ log ("Error selecting XFree86 server package: %s", message)
+
+ # make sure that all comps that include other comps are
+ # selected (i.e. - recurse down the selected comps and turn
+ # on the children
+
+ method.mergeFullHeaders(id.hdList)
+
+ if upgrade:
+ # An old mtab can cause confusion (esp if loop devices are
+ # in it)
+ f = open(instPath + "/etc/mtab", "w+")
+ f.close()
+
+ # XXX
+ #if method.systemMounted (fstab, instPath, id.hdList.selected()):
+ #fstab.umountFilesystems(instPath)
+ #return 1
+
+ for i in ( '/var', '/var/lib', '/var/lib/rpm', '/tmp', '/dev', '/etc',
+ '/etc/sysconfig', '/etc/sysconfig/network-scripts',
+ '/etc/X11' ):
+ try:
+ os.mkdir(instPath + i)
+ except os.error, (errno, msg):
+ # self.intf.messageWindow("Error", "Error making directory %s: %s" % (i, msg))
+ pass
+
+ db = rpm.opendb(1, instPath)
+ ts = rpm.TransactionSet(instPath, db)
+
+ total = 0
+ totalSize = 0
+
+ if upgrade:
+ how = "u"
+ else:
+ how = "i"
+
+ l = []
+
+ for p in id.hdList.selected():
+ l.append(p)
+ l.sort(sortPackages)
+
+ for p in l:
+ ts.add(p.h, p.h, how)
+ total = total + 1
+ totalSize = totalSize + (p[rpm.RPMTAG_SIZE] / 1024 )
+
+ if not id.hdList.preordered():
+ log ("WARNING: not all packages in hdlist had order tag")
+ ts.order()
+
+ if upgrade:
+ logname = '/tmp/upgrade.log'
+ else:
+ logname = '/tmp/install.log'
+
+ instLogName = instPath + logname
+ try:
+ os.unlink (instLogName)
+ except OSError:
+ pass
+
+ instLog = open(instLogName, "w+")
+ syslog = iutil.InstSyslog (instPath, instPath + logname)
+
+ ts.scriptFd = instLog.fileno ()
+ # the transaction set dup()s the file descriptor and will close the
+ # dup'd when we go out of scope
+
+ if upgrade:
+ modeText = _("Upgrading %s.\n")
+ else:
+ modeText = _("Installing %s.\n")
+
+ errors = rpmErrorClass(instLog)
+ oldError = rpm.errorSetCallback (errors.cb)
+ pkgTimer = timer.Timer(start = 0)
+
+ id.instProgress.setSizes(total, totalSize)
+ id.instProgress.processEvents()
+
+ cb = InstallCallback(intf.messageWindow, id.instProgress, pkgTimer,
+ method, intf.progressWindow, instLog, modeText)
+
+ problems = ts.run(0, ~rpm.RPMPROB_FILTER_DISKSPACE, cb.cb, 0)
+
+# problems = ts.run(rpm.RPMTRANS_FLAG_TEST, ~0, self.instCallback, 0)
+
+ if problems:
+ spaceneeded = {}
+ nodeneeded = {}
+ size = 12
+
+ # XXX
+ nodeprob = -1
+ if rpm.__dict__.has_key ("RPMPROB_DISKNODES"):
+ nodeprob = rpm.RPMPROB_DISKNODES
+
+ for (descr, (type, mount, need)) in problems:
+ idx = string.find (mount, "/mnt/sysimage")
+ if mount[0:13] == "/mnt/sysimage":
+ mount = mount[13:]
+ if not mount:
+ mount = '/'
+
+ if type == rpm.RPMPROB_DISKSPACE:
+ if spaceneeded.has_key (mount) and spaceneeded[mount] < need:
+ spaceneeded[mount] = need
+ else:
+ spaceneeded[mount] = need
+ elif type == nodeprob:
+ if nodeneeded.has_key (mount) and nodeneeded[mount] < need:
+ nodeneeded[mount] = need
+ else:
+ nodeneeded[mount] = need
+ else:
+ log ("WARNING: unhandled problem returned from transaction set type %d",
+ type)
+
+ probs = ""
+ if spaceneeded:
+ probs = probs + _("You don't appear to have enough disk space to install "
+ "the packages you've selected. You need more space on the "
+ "following filesystems:\n\n")
+ probs = probs + ("%-15s %s\n") % (_("Mount Point"), _("Space Needed"))
+
+ for (mount, need) in spaceneeded.items ():
+ if need > (1024*1024):
+ need = (need + 1024 * 1024 - 1) / (1024 * 1024)
+ suffix = "M"
+ else:
+ need = (need + 1023) / 1024
+ suffix = "k"
+
+ prob = "%-15s %d %c\n" % (mount, need, suffix)
+ probs = probs + prob
+ if nodeneeded:
+ if probs:
+ probs = probs + '\n'
+ probs = probs + _("You don't appear to have enough file nodes to install "
+ "the packages you've selected. You need more file nodes on the "
+ "following filesystems:\n\n")
+ probs = probs + ("%-15s %s\n") % (_("Mount Point"), _("Nodes Needed"))
+
+ for (mount, need) in nodeneeded.items ():
+ prob = "%-15s %d\n" % (mount, need)
+ probs = probs + prob
+
+ intf.messageWindow (_("Disk Space"), probs)
+
+ del ts
+ del db
+ instLog.close()
+ del syslog
+
+ method.systemUnmounted ()
+
+ rpm.errorSetCallback (oldError)
+ return dispatch.DISPATCH_BACK
+
+ # This should close the RPM database so that you can
+ # do RPM ops in the chroot in a %post ks script
+ del ts
+ del db
+ rpm.errorSetCallback (oldError)
+
+ method.filesDone ()
+
+ del p
+
+ if upgrade:
+ instLog.write ("\n\nThe following packages were available on the CD but NOT upgraded:\n")
+ for p in id.hdList.packages.values ():
+ if not p.selected:
+ instLog.write("%s-%s-%s.%s.rpm\n" %
+ (p.h[rpm.RPMTAG_NAME],
+ p.h[rpm.RPMTAG_VERSION],
+ p.h[rpm.RPMTAG_RELEASE],
+ p.h[rpm.RPMTAG_ARCH]))
+ instLog.close ()
+
+ id.instProgress = None
+
+ createWindow = (intf.progressWindow,
+ (_("Post Install"),
+ _("Performing post install configuration..."), 8))
+ w = apply(apply, createWindow)
+
+ try:
+ if not upgrade:
+ # XXX
+ #if self.fdDevice[0:2] == "fd":
+ #self.fstab.addMount(self.fdDevice, "/mnt/floppy", "auto")
+ #self.fstab.write (instPath)
+
+ w.set(1)
+
+ copyExtraModules(instPath, id.comps, id.extraModules)
+
+ w.set(2)
+
+ # pcmcia is supported only on i386 at the moment
+ if arch == "i386":
+ pcmcia.createPcmciaConfig(
+ instPath + "/etc/sysconfig/pcmcia")
+
+ # rootpath mode doesn't have this file around
+ if os.access("/tmp/modules.conf", os.R_OK):
+ iutil.copyFile("/tmp/modules.conf",
+ instPath + "/etc/modules.conf")
+
+ # XXX
+ #if not self.x.skip and self.x.server:
+ #if os.access (instPath + "/etc/X11/X", os.R_OK):
+ #os.rename (instPath + "/etc/X11/X",
+ #instPath + "/etc/X11/X.rpmsave")
+ #try:
+ #os.unlink (instPath + "/etc/X11/X")
+ #except OSError:
+ #pass
+ #os.symlink ("../../usr/X11R6/bin/" + self.x.server,
+ #instPath + "/etc/X11/X")
+
+ #self.x.write (instPath + "/etc/X11")
+
+ w.set(3)
+
+ # blah. If we're on a serial mouse, and we have X, we need to
+ # close the mouse device, then run kudzu, then open it again.
+
+ # turn it off
+ mousedev = None
+
+ # XXX currently Bad Things (X async reply) happen when doing
+ # Mouse Magic on Sparc (Mach64, specificly)
+ if os.environ.has_key ("DISPLAY") and not arch == "sparc":
+ import xmouse
+ try:
+ mousedev = xmouse.get()[0]
+ except RuntimeError:
+ pass
+
+ if mousedev:
+ try:
+ os.rename (mousedev, "/dev/disablemouse")
+ except OSError:
+ pass
+ try:
+ xmouse.reopen()
+ except RuntimeError:
+ pass
+
+ unmountUSB = 0
+ try:
+ isys.mount('/usbdevfs', instPath+'/proc/bus/usb', 'usbdevfs')
+ unmountUSB = 1
+ except:
+ log("Mount of /proc/bus/usb failed")
+ pass
+
+
+ argv = [ "/usr/sbin/kudzu", "-q" ]
+ devnull = os.open("/dev/null", os.O_RDWR)
+ iutil.execWithRedirect(argv[0], argv, root = instPath,
+ stdout = devnull)
+ # turn it back on
+ if mousedev:
+ try:
+ os.rename ("/dev/disablemouse", mousedev)
+ except OSError:
+ pass
+ try:
+ xmouse.reopen()
+ except RuntimeError:
+ pass
+
+ if unmountUSB:
+ isys.umount(instPath + '/proc/bus/usb', removeDir = 0)
+
+ w.set(4)
+
+ if upgrade:
+ # move the rebuilt db into place.
+ try:
+ iutil.rmrf (instPath + "/var/lib/rpm.rpmsave")
+ except OSError:
+ pass
+ os.rename (instPath + "/var/lib/rpm",
+ instPath + "/var/lib/rpm.rpmsave")
+ os.rename (instPath + self.dbpath,
+ instPath + "/var/lib/rpm")
+
+ # XXX - rpm 4.0.2 %post braindeadness support
+ try:
+ os.unlink (instPath + "/etc/rpm/macros.db1")
+ except OSError:
+ pass
+
+ # needed for prior systems which were not xinetd based
+ migrateXinetd(instPath, instLogName)
+
+ # XXX
+ if flags.setupFilesystems:
+ errors = None
+
+ if 0:
+ if arch == "sparc":
+ errors = self.silo.install (self.fstab, instPath,
+ id.hdList, upgrade)
+ elif arch == "i386":
+ defaultlang = self.language.getLangNickByName(self.language.getDefault())
+ langlist = expandLangs(defaultlang)
+ errors = self.lilo.install (self.fstab, instPath,
+ id.hdList, upgrade, langlist)
+ elif arch == "ia64":
+ errors = self.eli.install (self.fstab, instPath,
+ id.hdList, upgrade)
+ elif arch == "alpha":
+ errors = self.milo.write ()
+ else:
+ raise RuntimeError, "What kind of machine is this, anyway?!"
+
+ if errors:
+ w.pop()
+ mess = _("An error occured while installing "
+ "the bootloader.\n\n"
+ "We HIGHLY recommend you make a recovery "
+ "boot floppy when prompted, otherwise you "
+ "may not be able to reboot into Red Hat Linux."
+ "\n\nThe error reported was:\n\n") + errors
+ self.intf.messageWindow(_("Bootloader Errors"), mess)
+
+ # make sure bootdisk window appears
+ if iutil.getArch () == "i386":
+ self.instClass.removeFromSkipList('bootdisk')
+ self.bootdisk = 1
+
+ w = apply(apply, createWindow)
+
+
+ w.set(5)
+
+ # go ahead and depmod modules as modprobe in rc.sysinit
+ # will complain loaduly if we don't do it now.
+ depmodModules(id.comps, instPath)
+
+ w.set(6)
+
+ # XXX
+ #self.instClass.postAction(instPath, self.serial)
+
+ w.set(7)
+
+ if flags.setupFilesystems:
+ f = open("/tmp/cleanup", "w")
+ method.writeCleanupPath(f)
+ # XXX
+ #self.fstab.writeCleanupPath(f)
+ f.close()
+
+ w.set(8)
+
+ del syslog
+
+ finally:
+ pass
+
+ w.pop ()
+
+ sys.stdout.flush()
+
+def migrateXinetd(self, instPath, instLog):
+ if not os.access (instPath + "/usr/sbin/inetdconvert", os.X_OK):
+ log("did not find %s" % instPath + "/usr/sbin/inetdconvert")
+ return
+
+ if not os.access (instPath + "/etc/inetd.conf.rpmsave", os.R_OK):
+ log("did not run inetdconvert because no inetd.conf.rpmsave found")
+ return
+
+ argv = [ "/usr/sbin/inetdconvert", "--convertremaining",
+ "--inetdfile", "/etc/inetd.conf.rpmsave" ]
+
+ log("found inetdconvert, executing %s" % argv)
+
+ logfile = os.open (instLog, os.O_APPEND)
+ iutil.execWithRedirect(argv[0], argv, root = instPath,
+ stdout = logfile, stderr = logfile)
+ os.close(logfile)
+
+def copyExtraModules(instPath, comps, extraModules):
+ kernelVersions = comps.kernelVersionList()
+
+ for (path, subdir, name, pkg) in extraModules:
+ pattern = ""
+ names = ""
+ for (n, tag) in kernelVersions:
+ pattern = pattern + " " + n + "/" + name + ".o"
+ names = names + " " + name + ".o"
+ command = ("cd %s/lib/modules; gunzip < %s/modules.cgz | " +
+ "%s/bin/cpio --quiet -iumd %s") % \
+ (instPath, path, instPath, pattern)
+ log("running: '%s'" % (command, ))
+ os.system(command)
+
+ for (n, tag) in kernelVersions:
+ fromFile = "%s/lib/modules/%s/%s.o" % (instPath, n, name)
+ toDir = "%s/lib/modules/%s/kernel/drivers/%s" % \
+ (instPath, n, subdir)
+ to = "%s/%s.o" % (toDir, name)
+
+ if (os.access(fromFile, os.R_OK) and
+ os.access(toDir, os.X_OK)):
+ log("moving %s to %s" % (fromFile, to))
+ os.rename(fromFile, to)
+
+ # the file might not have been owned by root in the cgz
+ os.chown(to, 0, 0)
+ else:
+ log("missing DD module %s (this may be okay)" %
+ fromFile)
+
+def depmodModules(comps, instPath):
+ kernelVersions = comps.kernelVersionList()
+
+ for (version, tag) in kernelVersions:
+ iutil.execWithRedirect ("/sbin/depmod",
+ [ "/sbin/depmod", "-a", version ],
+ root = instPath, stderr = '/dev/null')
+
diff --git a/timezone.py b/timezone.py
new file mode 100644
index 000000000..a0d1e2918
--- /dev/null
+++ b/timezone.py
@@ -0,0 +1,44 @@
+import iutil
+from log import log
+
+def bool(val):
+ if val: return "true"
+ return "false"
+
+class Timezone:
+
+ def writeKS(self, f):
+ f.write("timezone")
+ if self.utc:
+ f.write(" --utc")
+ f.write(" %s\n" % self.tz)
+
+ def write(self, instPath):
+ fromFile = instPath + "/usr/share/zoneinfo/" + self.tz
+
+ try:
+ iutil.copyFile(fromFile, instPath + "/etc/localtime")
+ except OSError, (errno, msg):
+ log ("Error copying timezone (from %s): %s" % (fromFile, msg))
+
+ f = open(instPath + "/etc/sysconfig/clock", "w")
+
+ f.write('ZONE="%s"\n' % self.tz)
+ f.write("UTC=%s\n" % bool(self.utc))
+ f.write("ARC=%s\n" % bool(self.arc))
+
+ f.close()
+
+ def getTimezoneInfo(self):
+ return (self.tz, self.utc, self.arc)
+
+ def setTimezoneInfo(self, timezone, asUtc = 0, asArc = 0):
+ self.tz = timezone
+ self.utc = asUtc
+ self.arc = asArc
+
+ def __init__(self):
+ self.tz = "America/New_York"
+ self.utc = 0
+ self.arc = 0
+
diff --git a/users.py b/users.py
new file mode 100644
index 000000000..e6f1e55ec
--- /dev/null
+++ b/users.py
@@ -0,0 +1,220 @@
+import iutil
+import whrandom
+import crypt
+import os
+import string
+from flags import flags
+from log import log
+
+class Accounts:
+
+ # List of (accountName, fullName, password) tupes
+
+ def setUserList(self, users):
+ self.users = users
+
+ def getUserList(self):
+ return self.users
+
+ def writeKScommands(self, f, auth):
+ for (account, name, password) in self.users:
+ crypted = cryptPassword(password, auth.useMD5)
+
+ f.write("/usr/sbin/useradd %s\n" % (account));
+ f.write("chfn -f '%s' %s\n" % (name, account))
+ f.write("/usr/sbin/usermod -p '%s' %s\n" % (crypted, account))
+ f.write("\n")
+
+ def write(self, instPath, auth):
+ if not self.users: return
+
+ if not flags.setupFilesystems:
+ return
+
+ for (account, name, password) in self.users:
+ argv = [ "/usr/sbin/useradd", account ]
+ iutil.execWithRedirect(argv[0], argv, root = instPath,
+ stdout = None)
+
+ argv = [ "/usr/bin/chfn", "-f", name, account]
+ iutil.execWithRedirect(argv[0], argv, root = instPath,
+ stdout = None)
+
+ setPassword(instPath, account, password, auth.useMD5)
+
+ def __init__(self):
+ self.users = []
+
+class Password:
+ def __init__ (self):
+ self.crypt = None
+ self.pure = None
+
+ def getPure(self):
+ return self.pure
+
+ def set (self, password, isCrypted = 0):
+ if isCrypted:
+ self.crypt = password
+ self.pure = None
+ else:
+ salt = (whrandom.choice (string.letters +
+ string.digits + './') +
+ whrandom.choice (string.letters +
+ string.digits + './'))
+ self.crypt = crypt.crypt (password, salt)
+ self.pure = password
+
+ def getCrypted(self):
+ return self.crypt
+
+class RootPassword(Password):
+
+ def write(self, instPath, auth):
+ pure = self.getPure()
+ if pure:
+ setPassword(instPath, "root", pure, auth.useMD5)
+ else:
+ setPassword(instPath, "root", self.getCrypted (),
+ auth.useMD5, alreadyCrypted = 1)
+
+ def writeKS(self, f):
+ f.write("rootpw --iscrypted %s\n" % self.getCrypted())
+
+def cryptPassword(password, useMD5):
+ if useMD5:
+ salt = "$1$"
+ saltLen = 8
+ else:
+ salt = ""
+ saltLen = 2
+
+ for i in range(saltLen):
+ salt = salt + whrandom.choice (string.letters +
+ string.digits + './')
+
+ return crypt.crypt (password, salt)
+
+def setPassword(instPath, account, password, useMD5, alreadyCrypted = 0):
+ if not alreadyCrypted:
+ password = cryptPassword(password, useMD5)
+
+ devnull = os.open("/dev/null", os.O_RDWR)
+
+ argv = [ "/usr/sbin/usermod", "-p", password, account ]
+ iutil.execWithRedirect(argv[0], argv, root = instPath,
+ stdout = '/dev/null', stderr = None)
+ os.close(devnull)
+
+class Authentication:
+ def __init__ (self):
+ self.useShadow = 1
+ self.useMD5 = 1
+
+ self.useNIS = 0
+ self.nisDomain = ""
+ self.nisuseBroadcast = 1
+ self.nisServer = ""
+
+ self.useLdap = 0
+ self.useLdapauth = 0
+ self.ldapServer = ""
+ self.ldapBasedn = ""
+ self.ldapTLS = ""
+
+ self.useKrb5 = 0
+ self.krb5Realm = ""
+ self.krb5Kdc = ""
+ self.krb5Admin = ""
+
+ self.useHesiod = 0
+ self.hesiodLhs = ""
+ self.hesiodRhs = ""
+
+ def writeKS(self, f):
+ f.write("authconfig")
+ for arg in self.getArgList():
+ if arg[0:9] != "--disable":
+ f.write(" " + arg)
+ f.write("\n")
+
+ def getArgList(self):
+ args = []
+
+ if self.useShadow:
+ args.append ("--enableshadow")
+ else:
+ args.append ("--disableshadow")
+
+ if self.useMD5:
+ args.append ("--enablemd5")
+ else:
+ args.append ("--disablemd5")
+
+
+ if self.useNIS:
+ args.append ("--enablenis")
+ args.append ("--nisdomain")
+ args.append (self.nisDomain)
+ if not self.nisuseBroadcast:
+ args.append ("--nisserver")
+ args.append (self.nisServer)
+ else:
+ args.append ("--disablenis")
+
+ if self.useLdap:
+ args.append ("--enableldap")
+ else:
+ args.append ("--disableldap")
+ if self.useLdapauth:
+ args.append ("--enableldapauth")
+ else:
+ args.append ("--disableldapauth")
+ if self.useLdap or self.useLdapauth:
+ args.append ("--ldapserver")
+ args.append (self.ldapServer)
+ args.append ("--ldapbasedn")
+ args.append (self.ldapBasedn)
+ if self.ldapTLS:
+ args.append ("--enableldaptls")
+ else:
+ args.append ("--disableldaptls")
+
+ if self.useKrb5:
+ args.append ("--enablekrb5")
+ args.append ("--krb5realm")
+ args.append (self.krb5Realm)
+ args.append ("--krb5kdc")
+ args.append (self.krb5Kdc)
+ args.append ("--krb5adminserver")
+ args.append (self.krb5Admin)
+ else:
+ args.append ("--disablekrb5")
+
+ if self.useHesiod:
+ args.append ("--enablehesiod")
+ args.append ("--hesiodlhs")
+ args.append (self.hesiodLhs)
+ args.append ("--hesiodrhs")
+ args.append (self.hesiodRhs)
+ else:
+ args.append ("--disablehesiod")
+
+ return args
+
+
+ def write (self, instPath):
+ args = [ "/usr/sbin/authconfig", "--kickstart", "--nostart" ]
+ args = args + self.getArgList()
+
+ try:
+ if flags.setupFilesystems:
+ iutil.execWithRedirect(args[0], args,
+ stdout = None, stderr = None,
+ searchPath = 1,
+ root = instPath)
+ else:
+ log("Would have run %s", args)
+ except RuntimeError, msg:
+ log ("Error running %s: %s", args, msg)
+
diff --git a/videocard.py b/videocard.py
new file mode 100644
index 000000000..583752156
--- /dev/null
+++ b/videocard.py
@@ -0,0 +1,369 @@
+import copy
+import string
+import kudzu
+import iutil
+import isys
+
+from log import log
+
+Video_cardslist = {}
+
+def Video_cardsDBLookup(thecard):
+ card = Video_cardslist[thecard]
+ origcard = copy.copy(card)
+
+ count = 0
+ while count < 16 and card.has_key ("SEE"):
+ card = Video_cardslist[card["SEE"]]
+ count = count + 1
+
+ if count >= 16:
+ raise RunTimeError, "Could not find card ",origcard
+
+ return card
+
+
+class VideoCard:
+#
+# This class represents the base data about a videocard. These are
+# the internal members - PLEASE use methods to access values!
+#
+# device - if framebuffer running on card this is entry in /dev (string)
+# descr - human readable description (string)
+# server - X server to use (string)
+# probedcard - value returned for kudzu containing 'Card:........'
+# cardManf - name of manufacturer (string)
+# vidRam - amount of video ram (in kB) (string)
+# cardData - record from X card database, contains a dictionary of
+# key/values.
+# devID - ID from ddcprobe (string)
+# fbmodes - if framebuffer running, video mode in use (string)
+# fbbpp - if framebuffer running, pixel depth in use (string)
+#
+# These values will be None if undefined or not applicable.
+#
+
+ def __str__ (self):
+ return "device: %s\ndescr : %s\nserver: %s\ncardManf: %s\nvidRam: %s\ncarddata: %s\ndevID: %s\nfbmodes: %s\nfbbpp: %s\n" % (self.device, self.descr, self.server, self.cardManf, self.vidRam, self.cardData, self.devID, self.fbmodes, self.fbbpp)
+
+
+ def __init__ (self):
+ self.device = None
+ self.probedcard = None
+ self.descr = None
+ self.server = None
+ self.cardManf = None
+ self.vidRam = None
+ self.cardData = None
+ self.devID = None
+ self.fbmodes = None
+ self.fbbpp = None
+
+ def setDevice(self, device):
+ self.device = device
+
+ def setDescription(self, descr):
+ self.descr = descr
+
+ def setProbedCard(self, card):
+ self.probedcard = card
+
+ def setXServer(self, server):
+ self.server = server
+
+ def setVideoRam(self, vidRam):
+ self.vidRam = vidRam
+
+ def setCardData(self, card):
+ self.cardData = card
+
+ def setDevID(self, devid):
+ self.devID = devid
+
+ def setCardManf(self, manf):
+ self.cardManf = manf
+
+ def setFBModes(self, fbmodes):
+ self.fbmodes = fbmodes
+
+ def setFBBpp(self, bpp):
+ self.fbbpp = bpp
+
+ def getProbedCard(self):
+ return self.probedcard
+
+ def getVideoRam(self):
+ return self.vidRam
+
+ def getDescription(self):
+ return self.descr
+
+ def getDevice(self):
+ return self.device
+
+ def getDevID(self):
+ return self.devID
+
+ def getXServer(self):
+ return self.server
+
+ def getFBBpp(self):
+ return self.fbbpp
+
+ def shortDescription(self):
+ if self.devID and self.devID != "":
+ return self.devID
+ else:
+ return _("Unable to probe")
+
+ # dontResolve = 1 tells us to not follow 'SEE' records to find
+ # true card definition
+ def getCardData(self, dontResolve = 0):
+ if dontResolve:
+ return self.cardData
+ else:
+ return Video_cardsDBLookup(self.cardData["NAME"])
+
+ def canTestSafely(self):
+ cardData = self.getCardData()
+ if cardData.has_key("DRIVER"):
+ curdriver = cardData["DRIVER"]
+ noprobedriverList = ("i810", "tdfx")
+ for adriver in noprobedriverList:
+ if curdriver == adriver:
+ return 0
+
+ return 1
+
+
+class VideoCardInfo:
+
+#
+# This class represents the video cards on the system.
+#
+# Currently we only care about the primary card on the system.
+# This can be found by using the VideoCardInfo::primaryCard() function.
+#
+# NOTE - X configuration is not represented here. This class is
+# intended only to reprsent the available hardware on the system
+#
+
+
+ def primaryCard(self, useProbed = 0):
+ if useProbed:
+ if self.orig_videocards and self.orig_primary < len(self.orig_videocards):
+ return self.orig_videocards[self.orig_primary]
+ else:
+ return None
+ else:
+ if self.videocards and self.primary < len(self.videocards):
+ return self.videocards[self.primary]
+ else:
+ return None
+
+
+ def possible_ram_sizes(self):
+ #--Valid video ram sizes--
+ return [256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536]
+
+ def possible_depths(self):
+ #--Valid bit depths--
+ return ["8", "16", "24", "32"]
+
+ def manufacturerDB(self):
+ return ["3DLabs",
+ "ABit", "AOpen", "ASUS", "ATI", "Actix", "Ark Logic", "Avance Logic",
+ "Compaq", "Canopus", "Cardex", "Chaintech",
+ "Chips & Technologies", "Cirrus", "Creative Labs",
+ "DFI", "DSV", "DataExpert", "Dell", "Diamond", "Digital",
+ "ELSA", "EONtronics", "Epson", "ExpertColor",
+ "Gainward", "Genoa", "Guillemot",
+ "Hercules",
+ "Intel",
+ "Jaton",
+ "LeadTek",
+ "MELCO", "MachSpeed", "Matrox", "Miro",
+ "NVIDIA", "NeoMagic", "Number Nine",
+ "Oak", "Octek", "Orchid",
+ "Paradise", "PixelView",
+ "Quantum",
+ "RIVA", "Real3D", "Rendition",
+ "S3", "Sharp", "SNI", "SPEA", "STB", "SiS",
+ "Sierra", "Sigma", "Silicon Motion", "Soyo", "Spider", "Sun",
+ "TechWorks", "Toshiba", "Trident",
+ "VideoLogic", "ViewTop", "Voodoo",
+ "WD", "Weitek", "WinFast"]
+
+ def readCardsDB (self):
+ # all the straight servers
+ for server in [ "3DLabs", "8514", "FBDev", "I128",
+ "Mach8", "Mach32", "Mach64", "Mono",
+ "P9000", "S3", "S3V", "SVGA", "W32", "VGA16" ]:
+ Video_cardslist["Generic " + server] = { "SERVER" : server,
+ "NAME" : "Generic " + server }
+
+ db = open ('/usr/X11R6/lib/X11/Cards')
+ lines = db.readlines ()
+ db.close ()
+ card = {}
+ name = None
+ for line in lines:
+ line = string.strip (line)
+ if not line and name:
+ Video_cardslist[name] = card
+ card = {}
+ name = None
+ continue
+
+ if line and line[0] == '#':
+ continue
+
+ if len (line) > 4 and line[0:4] == 'NAME':
+ name = line[5:]
+
+ info = string.splitfields (line, ' ')
+ if card.has_key (info[0]):
+ card[info[0]] = card[info[0]] + '\n' + (string.joinfields (info[1:], ' '))
+ else:
+ card[info[0]] = string.joinfields (info[1:], ' ')
+
+ return
+
+ def cardsDB(self):
+ return Video_cardslist
+
+ def __str__(self):
+ retstr = "primary: %s\nvidCards: %s\n" % (self.primary, self.videocards)
+ if self.primaryCard():
+ retstr = retstr + ("Primary Video Card Info:\n%s" % (str(self.primaryCard())))
+ return retstr
+
+ def reset(self):
+ self.videocards = copy.deepcopy(self.orig_videocards)
+ self.primary = self.orig_primary
+
+ def __init__ (self, skipDDCProbe = 0):
+
+ cards = kudzu.probe (kudzu.CLASS_VIDEO,
+ kudzu.BUS_UNSPEC,
+ kudzu.PROBE_ALL);
+
+ # just use first video card we recognize
+ # store as a list of class VideoCard
+ self.videocards = []
+ self.primary = None
+
+ self.readCardsDB()
+
+ for card in cards:
+ (device, server, descr) = card
+
+ if len (server) > 9 and server[0:10] == "Server:Sun" and descr[0:4] == "Sun|":
+ server = "Card:Sun " + descr[4:]
+ if len (server) > 5 and server[0:5] == "Card:":
+# info = self.cardsDBLookup (server[5:])
+ info = Video_cardslist [server[5:]]
+ if len (server) > 7 and server[0:7] == "Server:":
+ info = { "NAME" : "Generic " + server[7:],
+ "SERVER" : server[7:] }
+
+ if info:
+ vc = VideoCard()
+ vc.setProbedCard(server)
+ vc.setDevice(device)
+ vc.setDescription(descr)
+ vc.setCardData (info)
+ vc.setDevID (info["NAME"])
+
+ if (vc.getCardData().has_key("DRIVER") and
+ not vc.getCardData().has_key("UNSUPPORTED")):
+ server = "XFree86"
+ else:
+ server = "XF86_" + vc.getCardData()["SERVER"]
+
+ vc.setXServer(server)
+ self.videocards.append(vc)
+
+
+ if len(self.videocards) == 0:
+ return
+
+ # default primary card to be the first card found
+ self.primary = 0
+
+ # VESA probe for videoram, etc.
+ # for now assume fb corresponds to primary video card
+ if not skipDDCProbe:
+ try:
+ probe = string.split (iutil.execWithCapture ("/usr/sbin/ddcprobe", ['ddcprobe']), '\n')
+ for line in probe:
+ if line and line[:9] == "OEM Name:":
+ cardManf = string.strip (line[10:])
+ self.primaryCard().setCardManf(cardManf)
+ self.primaryCard().getCardData()["VENDOR"] = cardManf
+ if line and line[:16] == "Memory installed":
+ memory = string.split (line, '=')
+ self.primaryCard().setVideoRam(string.strip (memory[2][:-2]))
+ except:
+ log("ddcprobe failed")
+ pass
+
+ # try to get frame buffer information if we don't know video ram
+ if not self.primaryCard().getVideoRam() and self.primaryCard().getDevice():
+ try:
+ (vidram, depth, mode, monitor) = isys.fbconProbe("/dev/" + self.primaryCard().getDevice())
+ if vidram:
+ self.primaryCard().setVideoRam("%d" % vidram)
+
+ if depth:
+ self.primaryCard().setFBModes({ "%d" % depth : [ mode ] })
+ self.primaryCard().setFBBpp( "%d" % depth )
+ except:
+ pass
+
+ try:
+ if isys.fbinfo() != None:
+ x, y, depth = isys.fbinfo()
+ self.primaryCard().setFBBpp(depth)
+ except:
+ pass
+
+ # kludge to handle i810 displays which require at least 16 Meg
+ if (self.primaryCard().getCardData()).has_key("DRIVER"):
+ cardData = self.primaryCard().getCardData()
+ if cardData["DRIVER"] == "i810":
+ self.primaryCard().setVideoRam("16384")
+
+
+ # save so we can reset
+ self.orig_videocards = copy.deepcopy(self.videocards)
+ self.orig_primary = self.primary
+
+
+#
+# XXX needed for kickstart only (via installclass.py::configureX())
+# some useful routines for setting videocard in various ways
+# needs to be ported to new VideoCard object
+
+ # pass videocard object for desired card; this sets card to be
+ # primary card
+ def setVidcard (self, videocard):
+ self.primary = self.videocards.index(videocard)
+
+
+ # find the appropriate videocard object for the requested card name
+ # this will only find the first instance of any card
+ def locateVidcardByName (self, card):
+ for vc in self.videocards:
+ print vc.getDescription()
+ if (vc.getDescription() == card):
+ return vc
+ raise RuntimeError, "Could not find valid video card driver"
+
+ # find the appropriate videocard object for the requested server name
+ # this will only find the first instance of any card
+ def locateVidcardByServer (self, server):
+ for vc in self.videocards:
+ if (vc.getXServer() == server):
+ return vc
+ raise RuntimeError, "Could not find valid video card driver."
diff --git a/xf86config.py b/xf86config.py
index e274f8f22..07545d638 100644
--- a/xf86config.py
+++ b/xf86config.py
@@ -573,38 +573,42 @@ EndSection
"""
class XF86Config:
- def __init__ (self, mouse = None, resolution = None):
+ def __init__ (self, video, monitor, mouse, resolution = None):
+
+ if video:
+ self.setVideo(video)
+ else:
+ raise RuntimeError, "no videocard specified in XF86Config __init__"
+
+ if monitor:
+ self.setMonitor(monitor)
+ else:
+ raise RuntimeError, "no monitor specified in XF86Config __init__"
if mouse:
self.setMouse(mouse)
else:
- self.mouse = Mouse (skipProbe = 1)
- self.server = None
- self.vidCards = []
- self.cardMan = None
- self.vidRam = None
- self.monEisa = None
- self.monName = None
- self.res = resolution
+ raise RuntimeError, "no mouse specified in XF86Config __init__"
- self.monSect = ""
- self.monID = "Unprobed Monitor"
- self.state = ""
- self.devID = None
- self.probed = 0
self.skip = 0
- self.primary = 0
+ self.res = resolution
self.manualModes = {}
+ self.fallbackModes = {}
+
+
+ monsyncknown = (self.monitor.getMonitorHorizSync() != None) and (self.monitor.getMonitorVertSync() != None)
if self.res == "640x480":
self.modes = { "8" : ["640x480"] }
- self.monHoriz = "31.5-35.5"
- self.monVert = "50-61"
+ if not monsyncknown:
+ self.monitor.setSpecs("31.5-35.5", "50-61")
else:
self.modes = { "16" : ["800x600"] }
- self.monHoriz = "31.5-48.5"
- self.monVert = "50-70"
+ if not monsyncknown:
+ self.monitor.setSpecs("31.5-48.5", "50-70")
+ self.fallbackModes = self.modes
+
self.device = None
self.keyRules = "xfree86"
self.keyModel = "pc101"
@@ -620,7 +624,7 @@ class XF86Config:
self.monids = {}
if isys.fbinfo() != None:
- x, y, depth = isys.fbinfo()
+ (x, y, depth) = isys.fbinfo()
self.fbDepth = depth
else:
self.fbDepth = 16
@@ -650,6 +654,12 @@ class XF86Config:
def setMouse(self, mouse):
self.mouse = mouse
+ def setVideo(self, video):
+ self.video = video
+
+ def setMonitor(self, monitor):
+ self.monitor = monitor
+
def areaCompare (self, first, second):
(sx1, sy1) = string.split (first, 'x')
(sx2, sy2) = string.split (second, 'x')
@@ -668,42 +678,47 @@ class XF86Config:
def availableModes (self):
modes = { "8" : [ "640x480" ] }
- if not self.vidRam:
+ if not self.video:
+ return modes
+
+ vidRam = self.video.primaryCard().getVideoRam()
+
+ if not vidRam:
return modes
laptop = self.laptop()
if laptop:
return laptop
- if string.atoi(self.vidRam) >= 8192:
+ if string.atoi(vidRam) >= 8192:
modes["8"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024", "1400x1050", "1600x1200"]
modes["16"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024", "1400x1050", "1600x1200"]
modes["32"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024", "1400x1050", "1600x1200"]
return modes
- elif string.atoi(self.vidRam) >= 6144:
+ elif string.atoi(vidRam) >= 6144:
modes["8"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024", "1400x1050", "1600x1200"]
modes["16"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024", "1400x1050", "1600x1200"]
modes["32"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024"]
return modes
- elif string.atoi(self.vidRam) >= 4096:
+ elif string.atoi(vidRam) >= 4096:
modes["8"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024"]
modes["16"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024"]
modes["32"] = ["640x480", "800x600", "1024x768", "1152x864"]
return modes
- elif string.atoi(self.vidRam) >= 2048:
+ elif string.atoi(vidRam) >= 2048:
modes["8"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024"]
modes["16"] = ["640x480", "800x600", "1024x768", "1152x864"]
modes["32"] = ["640x480", "800x600"]
return modes
- elif string.atoi(self.vidRam) >= 1024:
+ elif string.atoi(vidRam) >= 1024:
modes["8"] = ["640x480", "800x600", "1024x768", "1152x864"]
modes["16"] = ["640x480", "800x600"]
modes["32"] = []
return modes
- elif string.atoi(self.vidRam) >= 512:
+ elif string.atoi(vidRam) >= 512:
modes["8"] = ["640x480", "800x600"]
modes["16"] = ["640x480"]
modes["32"] = []
return modes
- elif string.atoi(self.vidRam) >= 256:
+ elif string.atoi(vidRam) >= 256:
modes["8"] = ["640x480"]
return modes
@@ -713,6 +728,21 @@ class XF86Config:
def setModes(self, modes):
self.modes = modes
+ def getModes(self):
+ return self.modes
+
+ def setManualModes(self, modes):
+ self.manualModes = modes
+
+ def getManualModes(self):
+ return self.manualModes
+
+ def setFallBackModes(self, modes):
+ self.fallbackModes = modes
+
+ def getFallBackModes(self):
+ return self.fallbackModes
+
def cards (self, thecard = None):
cards = {}
# all the straight servers
@@ -762,7 +792,7 @@ class XF86Config:
db = open ('/usr/X11R6/share/Xconfigurator/MonitorsDB')
lines = db.readlines ()
db.close ()
- found = 0
+
for line in lines:
line = string.strip (line)
if not line:
@@ -782,179 +812,38 @@ class XF86Config:
self.monids[eisa] = (man, model, eisa, vert, horiz)
return self.monlist
- def setMonitor (self, (monitor, (hrange, vrange))):
- self.monName = monitor
- self.monID = monitor
- self.monHoriz = hrange
- self.monVert = vrange
-
- # must pass card as a dictionary entry for desired card
- def setVidcard (self, card):
- self.vidCards = [card]
- self.primary = 0
-
- if self.vidCards:
- self.devID = self.vidCards[self.primary]["NAME"]
- if (self.vidCards[self.primary].has_key("DRIVER") and
- not self.vidCards[self.primary].has_key("UNSUPPORTED")):
- self.server = "XFree86"
- else:
- self.server = "XF86_" + self.vidCards[self.primary]["SERVER"]
-
- # locate dictionary entry for requested card name
- # case matters
- def locateVidcard (self, card):
- cards = self.cards()
- if cards.has_key(card):
- return cards[card]
- else:
- return None
-
- # server is string name of X server (eg. "SVGA")
- # case matters
- def setVidcardByServer (self, server):
- tmpcard = "Generic " + server
-
- entry = self.locateVidcard (tmpcard)
-
- if entry != None:
- self.setVidcard (entry)
- else:
- raise RuntimeError, "Could not find valid video card driver."
-
- # card is string name of video card (eg. "Generic SVGA")
- def setVidcardByName (self, card):
- entry = self.locateVidcard (card)
-
- if entry != None:
- self.setVidcard (entry)
- else:
- raise RuntimeError, "Could not find valid video card driver."
-
- def probe (self, probeMonitor = 1):
-# XXX defer monitor probe, then re-enable this check
-# if self.probed:
-# return
- self.probed = 1
- self.device = None
- self.descr = None
- self.primary = 0
- # PCI probe for video cards
- sections = {}
-
- cards = []
- cards = kudzu.probe (kudzu.CLASS_VIDEO,
- kudzu.BUS_UNSPEC,
- kudzu.PROBE_ALL);
-
- for card in cards:
- section = ""
- (device, server, descr) = card
- if device and not self.device:
- self.device = device
- self.primary = len(self.vidCards)
- self.descr = descr
- if len (server) > 9 and server[0:10] == "Server:Sun" and descr[0:4] == "Sun|":
- server = "Card:Sun " + descr[4:]
- if len (server) > 5 and server[0:5] == "Card:":
- self.vidCards.append (self.cards (server[5:]))
- if len (server) > 7 and server[0:7] == "Server:":
- info = { "NAME" : "Generic " + server[7:],
- "SERVER" : server[7:] }
- self.vidCards.append (info)
-
- if self.vidCards:
- self.devID = self.vidCards[self.primary]["NAME"]
- if (self.vidCards[self.primary].has_key("DRIVER") and
- not self.vidCards[self.primary].has_key("UNSUPPORTED")):
- self.server = "XFree86"
- else:
- self.server = "XF86_" + self.vidCards[self.primary]["SERVER"]
-
- # VESA probe for monitor/videoram, etc.
- if probeMonitor:
- try:
- probe = string.split (iutil.execWithCapture ("/usr/sbin/ddcprobe", ['ddcprobe']), '\n')
- for line in probe:
- if line and line[:9] == "OEM Name:":
- self.cardMan = string.strip (line[10:])
-
- if line and line[:16] == "Memory installed":
- memory = string.split (line, '=')
- self.vidRam = string.strip (memory[2][:-2])
-
- if line and line[:8] == "EISA ID:":
- self.monEisa = string.lower(line[9:])
- self.monID = line[9:]
-
- if line and line[:6] == "\tName:":
- if not self.monName or len (self.monName) < len (line[7:]):
- self.monName = line[7:]
-
- if line and line[:15] == "\tTiming ranges:":
- ranges = string.split (line, ',')
- self.monHoriz = string.strip (string.split (ranges[0], '=')[1])
- self.monVert = string.strip (string.split (ranges[1], '=')[1])
-
- if self.vidCards and self.cardMan:
- self.vidCards[self.primary]["VENDOR"] = self.cardMan
- if self.monEisa:
- # read the monitor DB
- self.monitors()
- if self.monids.has_key (self.monEisa):
- (man, model, eisa, vert, horiz) = self.monids[self.monEisa]
- self.monName = model
- self.monID = model
- self.monHoriz = horiz
- self.monVert = vert
- except:
- pass
- if not self.vidRam and self.device:
- try:
- (vidram, depth, mode, monitor) = isys.fbconProbe("/dev/" + self.device)
- if vidram:
- self.vidRam = "%d" % vidram
- if depth:
- self.modes = { "%d" % depth : [ mode ] }
- self.monSect = monitor
- self.bpp = "%d" % depth
- except:
- pass
-
- # kludge to handle i810 displays which require at least 16 Meg
- if (self.vidCards
- and self.vidCards[self.primary].has_key("DRIVER")
- and (self.vidCards[self.primary]["DRIVER"] == "i810")):
- self.vidRam = "16384"
-
def probeReport (self):
probe = ""
- if self.vidCards:
- probe = probe + _("Video Card") + ": " + self.vidCards[self.primary]["NAME"] + "\n"
- if self.vidRam:
- probe = probe + "\t" + _("Video Ram") + ": " + self.vidRam + " kb\n"
- if self.server:
+ if self.video:
+ primary = self.video.primaryCard()
+ vidCards = primary.getCardData()
+
+ if vidCards:
+ probe = probe + _("Video Card") + ": " + vidCards["NAME"] + "\n"
+ if primary.getVideoRam():
+ probe = probe + "\t" + _("Video Ram") + ": " + primary.getVideoRam() + " kb\n"
+ if primary.getXServer():
time.sleep(5)
- probe = probe + "\t" + _("X server") + ": " + self.server + "\n"
- if not self.server:
+ probe = probe + "\t" + _("X server") + ": " + primary.getXServer() + "\n"
+ else:
time.sleep(5)
probe = probe + "\t" + _("Unable to detect video card")
return probe
# disable monitor report
- probe = probe + "\n"
+# probe = probe + "\n"
- if self.monName:
- probe = probe + _("Monitor") + ": " + self.monName + "\n"
- elif self.monEisa:
- probe = probe + _("Monitor") + ": " + _("Plug and Play Monitor") + "\n"
- if self.monHoriz:
- probe = probe + "\t" + _("Horizontal frequency range") + ": " + self.monHoriz + " kHz\n"
- if self.monHoriz:
- probe = probe + "\t" + _("Vertical frequency range") + ": " + self.monVert + " Hz\n"
+# if self.monName:
+# probe = probe + _("Monitor") + ": " + self.monName + "\n"
+# elif self.monEisa:
+# probe = probe + _("Monitor") + ": " + _("Plug and Play Monitor") + "\n"
+# if self.monHoriz:
+# probe = probe + "\t" + _("Horizontal frequency range") + ": " + self.monHoriz + " kHz\n"
+# if self.monHoriz:
+# probe = probe + "\t" + _("Vertical frequency range") + ": " + self.monVert + " Hz\n"
- return probe
+# return probe
def write (self, path):
config = open (path + "/XF86Config", 'w')
@@ -966,34 +855,78 @@ class XF86Config:
return
config = open (path + "/XF86Config-4", 'w')
config.write (config4)
- config.close ()
+ config.close ()
+
+ def writeKS (self, f):
+ xmodes = self.getManualModes()
+
+ if len(xmodes) == 0:
+ f.write("skipx\n")
+ return
+
+ f.write("xconfig")
+
+ for arg in self.getArgList(xmodes):
+ f.write(" " + arg)
+ f.write("\n")
+
+ def getArgList(self, xmodes):
+ args = []
+ vc = self.video.primaryCard()
+
+ args = args + [ "--card", '"' + vc.shortDescription() + '"' ]
+ args = args + [ "--videoram", vc.getVideoRam() ]
+ args = args + [ "--hsync", self.monitor.getMonitorHorizSync() ]
+ args = args + [ "--vsync", self.monitor.getMonitorVertSync() ]
+
+ # XXX this isn't really quite right, but it works for the way
+ # things are now
+ depths = xmodes.keys()
+ args = args + [ "--resolution", xmodes[depths[0]][0] ]
+ args = args + [ "--depth", depths[0] ]
+
+ return args
+
def laptop (self):
- if not self.descr:
+
+ descr = self.video.primaryCard().getDescription()
+ if not descr:
return None
+
# PCI descr, (horiz, vert), modes
laptops = (("ATI|Rage Mobility",
("30-110", "60-110"),
- { "8" : ["800x600", "1024x768", "1280x1024", "1400x1050"],
- "16" : ["800x600", "1024x768", "1280x1024", "1400x1050"],
- "32" : ["800x600", "1024x768", "1280x1024", "1400x1050"]}),
+ { "8" : ["800x600", "1024x768", "1400x1050"],
+ "16" : ["800x600", "1024x768", "1400x1050"],
+ "32" : ["800x600", "1024x768", "1400x1050"]}),
)
for (card, (horiz, vert), modes) in laptops:
- if (len(self.descr) >= len (card)
- and self.descr[:len(card)] == card):
- self.monHoriz = horiz
- self.monVert = vert
- self.monID = "Laptop Screen"
+ if (len(descr) >= len (card)
+ and descr[:len(card)] == card):
+ self.monitor.setSpecs(horiz, vert, id="Laptop Screen")
return modes
return None
def test (self, serverflags=None, spawn=0):
- if not self.server:
-# print "self.server was None, doing nothing in test"
+ servername = self.video.primaryCard().getXServer()
+ if not servername:
return
files = self.files
- modes = self.modes
+ laptop = self.laptop()
+
+ # override modes if on a laptop
+ if laptop:
+ self.manualModes = laptop
+
+ # save current manually selected mode, override if non-existant
+ manmodes = self.manualModes
+ if not manmodes:
+ if self.fallbackModes:
+ self.manualModes = self.fallbackModes
+ else:
+ self.manualModes = self.modes
self.files = """
RgbPath "/usr/X11R6/lib/X11/rgb"
@@ -1014,7 +947,7 @@ class XF86Config:
"""
f = open ('/tmp/XF86Config.test', 'w')
- if self.server == "XFree86":
+ if servername == "XFree86":
config = self.Version4Config
else:
config = self.Version3Config
@@ -1022,16 +955,19 @@ class XF86Config:
f.close ()
self.files = files
- self.modes = modes
- serverPath = "/usr/X11R6/bin/" + self.server
+ # restore manualmodes
+ self.manualModes = manmodes
+
+ serverPath = "/usr/X11R6/bin/" + servername
- server = os.fork()
+ print "forking"
+ serverpid = os.fork()
- if (not server):
+ if (not serverpid):
args = [serverPath, '-xf86config', '/tmp/XF86Config.test' ]
logFile = "/tmp/X.log"
- if self.server == "XFree86":
+ if servername == "XFree86":
args = args + [ "-logfile", "/dev/null" ]
if serverflags:
args = args + serverflags
@@ -1055,7 +991,7 @@ class XF86Config:
if spawn:
- return server
+ return serverpid
child = os.fork()
if (not child):
@@ -1066,8 +1002,8 @@ class XF86Config:
status = -1
try:
pid, status = os.waitpid(child, 0)
- os.kill (server, 15)
- os.waitpid(server, 0)
+ os.kill (serverpid, 15)
+ os.waitpid(serverpid, 0)
if not os.WIFEXITED (status) or os.WEXITSTATUS (status):
if os.WEXITSTATUS (status) not in [ 0, 1, 2 ]:
failed = 1
@@ -1081,43 +1017,46 @@ class XF86Config:
info = {}
devices = ""
screens = ""
-
- for card in self.vidCards:
- devices = devices + """
+
+ monitor = self.monitor
+ card = self.video.primaryCard()
+ carddata = card.getCardData()
+ devices = devices + """
Section "Device"
Identifier "%(NAME)s"
-""" % card
- if card.has_key ("VENDOR"):
- devices = devices + ' VendorName "%(VENDOR)s"\n' % card
- if card.has_key ("BOARDNAME"):
- devices = devices + ' BoardName "%(BOARD)s"\n' % card
- if card.has_key ("RAMDAC"):
- devices = devices + ' Ramdac "%(RAMDAC)s"\n' % card
- if card.has_key ("LINE"):
- devices = devices + card["LINE"] + "\n"
- if self.vidRam:
- devices = devices + ' VideoRam %s\n' % (self.vidRam,)
- devices = devices + "EndSection\n"
-
- if self.devID:
+""" % carddata
+ if carddata.has_key ("VENDOR"):
+ devices = devices + ' VendorName "%(VENDOR)s"\n' % carddata
+ if carddata.has_key ("BOARDNAME"):
+ devices = devices + ' BoardName "%(BOARD)s"\n' % carddata
+ if carddata.has_key ("RAMDAC"):
+ devices = devices + ' Ramdac "%(RAMDAC)s"\n' % carddata
+ if carddata.has_key ("LINE"):
+ devices = devices + carddata["LINE"] + "\n"
+ if card.getVideoRam():
+ devices = devices + ' VideoRam %s\n' % (card.getVideoRam(),)
+ devices = devices + "EndSection\n"
+
+ if card.getDevID():
screens = ""
tmp = {}
maxdepth = -1
- for (depth, modes) in self.modes.items ():
+ xmodes = self.manualModes
+
+ for (depth, modes) in xmodes.items ():
modes.sort (self.areaCompare)
if len(modes) > 0 and string.atoi(depth) > maxdepth:
maxdepth = string.atoi(depth)
- if self.monSect:
- monitor = "Probed Monitor"
+ if monitor.getFBMonitorSection():
+ monitorname = "Probed Monitor"
else:
- monitor = self.monID
-
+ monitorname = monitor.getMonitorID()
for driver in [ "svga", "accel" ]:
tmp["driver"] = driver
- tmp["devID"] = self.devID
- tmp["monitorID"] = monitor
+ tmp["devID"] = card.getDevID()
+ tmp["monitorID"] = monitorname
screens = screens + """
# The %(driver)s server
Section "Screen"
@@ -1131,18 +1070,18 @@ Section "Screen"
if self.res == "640x480":
screens = screens + " DefaultColorDepth 8\n"
elif maxdepth > 0:
- if maxdepth > 16 and '16' in self.modes.keys() and self.modes['16']:
+ if maxdepth > 16 and '16' in xmodes.keys() and xmodes['16']:
screens = screens + " DefaultColorDepth 16\n"
else:
screens = screens + " DefaultColorDepth %d\n" % maxdepth
- for depth in self.modes.keys ():
- if not self.modes[depth]: continue
+ for depth in xmodes.keys ():
+ if not xmodes[depth]: continue
screens = screens + """
Subsection "Display"
Depth %s
Modes """ % depth
- for res in self.modes[depth]:
+ for res in xmodes[depth]:
screens = screens + '"' + res + '" '
screens = screens + """
ViewPort 0 0
@@ -1161,7 +1100,7 @@ Section "Screen"
mouseProto = self.mouse.info['XMOUSETYPE']
info = { "acceleratedDevices" : devices,
"acceleratedScreens" : screens,
- "devID" : self.devID,
+ "devID" : card.getDevID(),
"mouseProto" : mouseProto,
"mouseDevice" : self.mouse.device,
"XkbRules" : self.keyRules,
@@ -1171,13 +1110,19 @@ Section "Screen"
"enableVariant" : "#",
"XkbOptions" : self.keyOptions,
"enableOptions" : "#",
- "monitorID" : self.monID,
- "monitorHoriz" : self.monHoriz,
- "monitorVert" : self.monVert,
- "fbProbedMonitor" : self.monSect,
+ "monitorID" : monitor.getMonitorID(),
+ "monitorHoriz" : monitor.getMonitorHorizSync(),
+ "monitorVert" : monitor.getMonitorVertSync(),
+ "fbProbedMonitor" : monitor.getFBMonitorSection(),
"files" : self.files,
- "fbDepth" : self.fbDepth,
}
+
+ # HACK if no frame buffer running just wing it
+ if card.getFBBpp():
+ info["fbDepth"] = card.getFBBpp()
+ else:
+ info["fbDepth"] = 8
+
if self.keyVariant:
info["enableVariant"] = ""
if self.keyOptions:
@@ -1194,15 +1139,16 @@ Section "Screen"
return XF86Config_template % info
def Version4Config(self, test=0):
- if not self.vidCards:
+ if not self.video:
raise RuntimeError, "No known video cards"
screens = ""
maxdepth = -1
- for depth in self.modes.keys ():
- if not self.modes[depth]: continue
+ xmodes = self.manualModes
+ for depth in xmodes.keys ():
+ if not xmodes[depth]: continue
if depth == "32":
depth = "24"
- self.modes["24"] = self.modes["32"]
+ xmodes["24"] = xmodes["32"]
if maxdepth < string.atoi(depth):
maxdepth = string.atoi(depth)
screens = screens + """
@@ -1210,7 +1156,7 @@ Section "Screen"
Depth %s
Modes """ % depth
- modes = self.modes[depth]
+ modes = xmodes[depth]
modes.sort (self.areaCompare)
for res in modes:
screens = screens + '"' + res + '" '
@@ -1218,7 +1164,8 @@ Section "Screen"
EndSubsection
"""
if depth == "24":
- del self.modes["24"]
+ del xmodes["24"]
+
# XXX if we're going to be using IMPS/2 on
# reboot, but we're using PS/2 now, we'll need
# to temporarily use PS/2 so we don't frob the
@@ -1234,14 +1181,26 @@ Section "Screen"
emulate3 = "yes"
else:
emulate3 = "no"
+
+ card = self.video.primaryCard()
+ carddata = card.getCardData()
+ monitor = self.monitor
+
+ # set cardsoptions if unambiguous what version of XFree86 they
+ # apply to
+ cardoptions = " # no known options"
+ if carddata.has_key("DRIVER") and not carddata.has_key("SERVER"):
+ if carddata.has_key("LINE"):
+ cardoptions = carddata["LINE"]
+
data = { "mouseProto" : mouseProto,
"mouseDevice" : self.mouse.device,
- "cardsOptions" : " # no known options",
- "cardID" : self.vidCards[self.primary]["NAME"],
- "cardVendor" : self.vidCards[self.primary]["NAME"],
- "cardBoardName": self.vidCards[self.primary]["NAME"],
- "monitorHoriz" : self.monHoriz,
- "monitorVert" : self.monVert,
+ "cardsOptions" : cardoptions,
+ "cardID" : carddata["NAME"],
+ "cardVendor" : carddata["NAME"],
+ "cardBoardName": carddata["NAME"],
+ "monitorHoriz" : monitor.getMonitorHorizSync(),
+ "monitorVert" : monitor.getMonitorVertSync(),
"files" : self.files,
"screenModes" : screens,
"nonSparcMods" : '\n\tLoad "fbdevhw"',
@@ -1267,7 +1226,7 @@ Section "Screen"
data["enableOptions"] = ""
if maxdepth > 0:
- if maxdepth > 16 and '16' in self.modes.keys() and self.modes['16']:
+ if maxdepth > 16 and '16' in xmodes.keys() and xmodes['16']:
data["defaultDepth"] = "\n\tDefaultDepth\t16"
else:
data["defaultDepth"] = "\n\tDefaultDepth\t%d" % maxdepth
@@ -1278,10 +1237,10 @@ Section "Screen"
data["autorepeat"] = '# Option "AutoRepeat" "200 20"'
else:
data["autorepeat"] = '# Option "AutoRepeat" "500 5"'
- if self.vidCards[self.primary].has_key ("DRIVER"):
- data["cardDriver"] = self.vidCards[self.primary]["DRIVER"]
+ if carddata.has_key ("DRIVER"):
+ data["cardDriver"] = carddata["DRIVER"]
if data["cardDriver"] == "i810":
- data["videoRam"] = "\tVideoRam %s\n" % self.vidRam
+ data["videoRam"] = "\tVideoRam %s\n" % card.getVideoRam()
# DRI HACK!
#if data["cardDriver"] == "r128" or data["cardDriver"] == "mga":
# data["driMod"] = '\n\t#Load "dri"'