diff options
-rw-r--r-- | ChangeLog | 29 | ||||
-rw-r--r-- | fsset.py | 103 | ||||
-rw-r--r-- | iscsi.py | 23 | ||||
-rw-r--r-- | isys/isys.py | 33 | ||||
-rw-r--r-- | iw/iscsi_gui.py | 6 | ||||
-rw-r--r-- | kickstart.py | 8 | ||||
-rw-r--r-- | partitioning.py | 10 | ||||
-rw-r--r-- | yuminstall.py | 4 | ||||
-rw-r--r-- | zfcp.py | 5 |
9 files changed, 163 insertions, 58 deletions
@@ -1,5 +1,34 @@ 2006-06-21 Jeremy Katz <katzj@redhat.com> + * iw/iscsi_gui.py (iscsiWindow.getNext): Don't need to do the + startup here now. + + * isys/isys.py (compareDrives): Sort xvd devices first since + they're the "bootable" ones for Xen + (driveIsIscsi): Determine if a drive is iscsi or not. Kind of ugly. + + * zfcp.py (ZFCP.write): Copy zfcp.conf here. + + * yuminstall.py (YumBackend.doPreInstall): Write out network, zfcp + and iscsi info prior to the install starting. + + * partitioning.py (partitionObjectsInitialize): Flush drive dict + on initialization, set up iscsi devices here, make device nodes + for drives + + * kickstart.py (AnacondaKSHandlers.doIscsi): Initial iscsi + kickstart support. This syntax *will* change + + * iscsi.py (iscsi.action): Set nodes to start up automatically on + boot in the db + (iscsi.startup): Give a popup while we're waiting on iscsi devs + to initialize + (iscsi.write): Write out iscsi config + + * fsset.py: Add various bits so that we can set that a device + should be marked as _netdev in the fstab and use it appropriately + for iscsi. + * autopart.py (getDriveList): Sort drive list "correctly" 2006-06-20 Jeremy Katz <katzj@redhat.com> @@ -929,38 +929,6 @@ class prepbootFileSystem(FileSystemType): self.formattable = 0 def formatDevice(self, entry, progress, chroot='/'): - # copy and paste job from booty/bootloaderInfo.py... - def getDiskPart(dev): - cut = len(dev) - if (dev.startswith('rd/') or dev.startswith('ida/') or - dev.startswith('cciss/') or dev.startswith('i2o/') - or dev.startswith("sx8/")): - if dev[-2] == 'p': - cut = -1 - elif dev[-3] == 'p': - cut = -2 - else: - if dev[-2] in string.digits: - cut = -2 - elif dev[-1] in string.digits: - 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 - - if cut < 0: - partNum = int(dev[cut:]) - else: - partNum = None - - return (name, partNum) - # FIXME: oh dear is this a hack beyond my wildest imagination. # parted doesn't really know how to do these, so we're going to # exec sfdisk and make it set the partition type. this is bloody @@ -1613,15 +1581,20 @@ MAILADDR root sys.exit(0) def createLogicalVolumes (self, chroot='/'): + vgs = {} # first set up the volume groups for entry in self.entries: if entry.fsystem.name == "volume group (LVM)": entry.device.setupDevice(chroot) + vgs[entry.device.name] = entry.device # then set up the logical volumes for entry in self.entries: if isinstance(entry.device, LogicalVolumeDevice): - entry.device.setupDevice(chroot) + vg = None + if vgs.has_key(entry.device.vgname): + vg = vgs[entry.device.vgname] + entry.device.setupDevice(chroot, vgdevice = vg) self.volumesCreated = 1 @@ -1893,6 +1866,7 @@ class FileSystemSetEntry: self.options = options else: self.options = fsystem.getDefaultOptions(mountpoint) + self.options += device.getDeviceOptions() self.mountcount = 0 self.label = None if fsck == -1: @@ -2001,10 +1975,10 @@ class FileSystemSetEntry: class Device: def __init__(self, device = "none"): self.device = device - self.fsoptions = {} self.label = None self.isSetup = 0 self.doLabel = 1 + self.deviceOptions = "" def getComment (self): return "" @@ -2030,6 +2004,20 @@ class Device: except: return "" + def setAsNetdev(self): + """Ensure we're set up so that _netdev is in our device options.""" + if "_netdev" not in self.deviceOptions: + self.deviceOptions += ",_netdev" + + def isNetdev(self): + """Check to see if we're set as a netdev""" + if "_netdev" in self.deviceOptions: + return True + return False + + def getDeviceOptions(self): + return self.deviceOptions + class DevDevice(Device): """Device with a device node rooted in /dev that we just always use the pre-created device node for.""" @@ -2159,8 +2147,9 @@ class RAIDDevice(Device): if not self.isSetup: for device in self.members: - PartitionDevice(device).setupDevice(chroot, - devPrefix=devPrefix) + pd = PartitionDevice(device) + pd.setupDevice(chroot, devPrefix=devPrefix) + if pd.isNetdev(): self.setAsNetdev() args = ["/usr/sbin/mdadm", "--create", "/dev/%s" %(self.device,), "--run", "--chunk=%s" %(self.chunksize,), @@ -2217,6 +2206,7 @@ class VolumeGroupDevice(Device): for volume in self.physicalVolumes: # XXX the lvm tools are broken and will only work for /dev node = volume.setupDevice(chroot, devPrefix="/dev") + if volume.isNetdev(): self.setAsNetdev() # XXX I should check if the pv is set up somehow so that we # can have preexisting vgs and add new pvs to them. @@ -2286,7 +2276,7 @@ class LogicalVolumeDevice(Device): # self.extents # self.readaheadsectors - def setupDevice(self, chroot="/", devPrefix='/tmp'): + def setupDevice(self, chroot="/", devPrefix='/tmp', vgdevice = None): if not self.isSetup: lvm.writeForceConf() rc = iutil.execWithRedirect("lvm", @@ -2302,6 +2292,8 @@ class LogicalVolumeDevice(Device): lvm.unlinkConf() self.isSetup = 1 + if vgdevice and vgdevice.isNetdev(): self.setAsNetdev() + return "/dev/%s" % (self.getDevice(),) def getDevice(self, asBoot = 0): @@ -2318,6 +2310,10 @@ class PartitionDevice(Device): raise ValueError, "partition must be a string" self.device = partition + (disk, pnum) = getDiskPart(partition) + if isys.driveIsIscsi(disk): + self.setAsNetdev() + def setupDevice(self, chroot="/", devPrefix='/tmp'): path = '%s/%s' % (devPrefix, self.getDevice(),) isys.makeDevInode(self.getDevice(), path) @@ -2778,6 +2774,39 @@ def ext2FormatFilesystem(argList, messageFile, windowCreator, mntpoint): return 1 +# copy and paste job from booty/bootloaderInfo.py... +def getDiskPart(dev): + cut = len(dev) + if (dev.startswith('rd/') or dev.startswith('ida/') or + dev.startswith('cciss/') or dev.startswith('sx8/') or + dev.startswith('mapper/')): + if dev[-2] == 'p': + cut = -1 + elif dev[-3] == 'p': + cut = -2 + else: + if dev[-2] in string.digits: + cut = -2 + elif dev[-1] in string.digits: + 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 + + if cut < 0: + partNum = int(dev[cut:]) - 1 + else: + partNum = None + + return (name, partNum) + + if __name__ == "__main__": fsset = readFstab("fstab") @@ -17,8 +17,11 @@ import signal import iutil from flags import flags import logging +import shutil log = logging.getLogger("anaconda") +from rhpl.translate import _, N_ + # Note that stage2 copies all files under /sbin to /usr/sbin ISCSID="iscsid" @@ -59,6 +62,13 @@ class iscsi: stdout = "/dev/tty5", stderr = "/dev/tty5") + # ... and now we have to make it start automatically + argv = [ ISCSIADM, "-m", "node", "-r", "%s" %(recnum,), + "-o", "update", "-n", "node.startup", + "-v", "automatic" ] + iutil.execWithRedirect(argv[0], argv, searchPath = 1, + stdout = "/dev/tty5", + stderr = "/dev/tty5") def shutdown(self): if not self.iscsidStarted: @@ -78,7 +88,7 @@ class iscsi: self.iscsidStarted = False; - def startup(self): + def startup(self, intf = None): log.info("iSCSI IP address %s, port %s" % (self.ipaddr, self.port)) log.info("iSCSI initiator name %s", self.initiator) @@ -91,6 +101,10 @@ class iscsi: log.info("iSCSI: Not starting, no iscsi IP address specified") return + if intf: + w = intf.waitWindow(_("Initializing iSCSI initiator"), + _("Initializing iSCSI initiator")) + log.debug("Setting up %s" % (INITIATOR_FILE, )) if os.path.exists(INITIATOR_FILE): os.unlink(INITIATOR_FILE) @@ -112,6 +126,9 @@ class iscsi: self.action("--login") self.iscsidStarted = True + if intf: + w.pop() + def writeKS(self): # XXX Useful if we have auto-generated kickstart files. return @@ -121,8 +138,8 @@ class iscsi: os.write(fd, "InitiatorName=%s\n" %(self.initiator)) os.close(fd) - if not os.path.isdir(instPath + "/var/db/iscsi"): - iutil.mkdirChain(instPath + "/var/db/iscsi") + if not os.path.isdir(instPath + "/var/db"): + iutil.mkdirChain(instPath + "/var/db") shutil.copytree("/var/db/iscsi", instPath + "/var/db/iscsi") # vim:tw=78:ts=4:et:sw=4 diff --git a/isys/isys.py b/isys/isys.py index 166f3fd27..9ec1cba04 100644 --- a/isys/isys.py +++ b/isys/isys.py @@ -26,6 +26,7 @@ import kudzu import iutil import warnings import resource +import re import rhpl import struct @@ -465,9 +466,6 @@ for d in range(80, 80 + 15): biosdisks[disk] = d def compareDrives(first, second): - type1 = first[0:2] - type2 = second[0:2] - if biosdisks.has_key(first) and biosdisks.has_key(second): one = biosdisks[first] two = biosdisks[second] @@ -476,17 +474,21 @@ def compareDrives(first, second): elif (one > two): return 1 - if type1 == "hd": - type1 = 0 - elif type1 == "sd": - type1 = 1 + if first.startswith("hd"): + type1 = 0 + elif first.startswith("sd"): + type1 = 1 + elif first.startswith("xvd"): + type1 = -1 else: - type1 = 2 + type1 = 2 - if type2 == "hd": - type2 = 0 - elif type2 == "sd": + if second.startswith("hd"): + type2 = 0 + elif second.startswith("sd"): type2 = 1 + elif second.startswith("xvd"): + type2 = -1 else: type2 = 2 @@ -789,6 +791,15 @@ def driveIsRemovable(device): return False +def driveIsIscsi(device): + # ewww. just ewww. + if not os.path.islink("/sys/block/%s/device" %(device,)): + return False + target = os.readlink("/sys/block/%s/device" %(device,)) + if re.search("/platform/host[0-9]*/session[0-9]*/target[0-9]*:[0-9]*:[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*", target) is not None: + return True + return False + def vtActivate (num): _isys.vtActivate (num) diff --git a/iw/iscsi_gui.py b/iw/iscsi_gui.py index efeefc3ff..e147c234c 100644 --- a/iw/iscsi_gui.py +++ b/iw/iscsi_gui.py @@ -39,12 +39,6 @@ class iscsiWindow(InstallWindow): self.iscsi.port = self.port.get_text() self.iscsi.initiator = self.initiator.get_text() - w = self.intf.waitWindow(_("Initializing iSCSI initiator"), "") - self.iscsi.startup() - import time # XXX mmmm. hacktastic. - time.sleep(5) - w.pop() - return None def getScreen(self, anaconda): diff --git a/kickstart.py b/kickstart.py index 63ed1e540..1e5c913df 100644 --- a/kickstart.py +++ b/kickstart.py @@ -184,6 +184,14 @@ class AnacondaKSHandlers(KickstartHandlers): def doInteractive(self, id, args): KickstartHandlers.doInteractive(self, args) + def doIscsi(self, id, args): + KickstartHandlers.doIscsi(self, args) + self.skipSteps.append("iscsi") + + id.iscsi.ipaddr = self.ksdata.iscsi["target"] + id.iscsi.port = self.ksdata.iscsi["port"] + id.iscsi.initiator = self.ksdata.iscsi["initiator"] + def doKeyboard(self, id, args): KickstartHandlers.doKeyboard(self, args) id.instClass.setKeyboard(id, self.ksdata.keyboard) diff --git a/partitioning.py b/partitioning.py index 02351ff3a..0a6d5e28e 100644 --- a/partitioning.py +++ b/partitioning.py @@ -40,9 +40,16 @@ from rhpl.translate import _ def partitionObjectsInitialize(anaconda): if anaconda.dir == DISPATCH_BACK: anaconda.id.diskset.closeDevices() + anaconda.id.iscsi.shutdown() isys.flushDriveDict() return + # clean slate about drives + isys.flushDriveDict() + + # ensure iscsi devs are up + anaconda.id.iscsi.startup(anaconda.intf) + # read in drive info anaconda.id.diskset.refreshDevices(anaconda.intf, anaconda.id.partitions.reinitializeDisks, anaconda.id.partitions.zeroMbr, anaconda.id.partitions.autoClearPartDrives) @@ -52,6 +59,9 @@ def partitionObjectsInitialize(anaconda): anaconda.id.partitions.setFromDisk(anaconda.id.diskset) anaconda.id.partitions.setProtected(anaconda.dispatch) + # make sure we have all the device nodes we'll want + iutil.makeDriveDeviceNodes() + def partitioningComplete(anaconda): if anaconda.dir == DISPATCH_BACK and anaconda.id.fsset.isActive(): rc = anaconda.intf.messageWindow(_("Installation cannot continue."), diff --git a/yuminstall.py b/yuminstall.py index cb43d11dd..0efc9c8ee 100644 --- a/yuminstall.py +++ b/yuminstall.py @@ -1000,6 +1000,9 @@ class YumBackend(AnacondaBackend): if os.access("/tmp/zfcp.conf", os.R_OK): shutil.copyfile("/tmp/zfcp.conf", anaconda.rootPath + "/etc/zfcp.conf") + anaconda.id.network.write(anaconda.rootPath) + anaconda.id.iscsi.write(anaconda.rootPath) + anaconda.id.zfcp.write(anaconda.rootPath) # make a /etc/mtab so mkinitrd can handle certain hw (usb) correctly f = open(anaconda.rootPath + "/etc/mtab", "w+") @@ -1080,7 +1083,6 @@ class YumBackend(AnacondaBackend): else: w = anaconda.intf.waitWindow(_("Post Install"), _("Performing post install configuration...")) - anaconda.id.network.write(anaconda.rootPath) self.copyExtraModules(anaconda) @@ -17,6 +17,7 @@ import string import os import iutil import isys +import shutil from rhpl.translate import _, N_ @@ -234,6 +235,10 @@ class ZFCP: # FIXME KH not implemented yet return + def write(self, instPath): + if os.path.exists("/tmp/zfcp.conf"): + shutil.copyfile("/tmp/zfcp.conf", instPath + "/etc/zfcp.conf") + def readConfig(self): self.fcpdevices = [] try: |