summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Lehman <dlehman@redhat.com>2009-02-23 12:21:24 -0600
committerDavid Lehman <dlehman@redhat.com>2009-02-23 12:21:24 -0600
commite1a7fe9887886044b07587b3ec2caa2ff53ebfb2 (patch)
tree447c0c31e503a74f9247d36c2947d8a483f68836
parent715e529c7ae2742ff57f7b9eba055e92e8077d82 (diff)
downloadanaconda-e1a7fe9887886044b07587b3ec2caa2ff53ebfb2.tar.gz
anaconda-e1a7fe9887886044b07587b3ec2caa2ff53ebfb2.tar.xz
anaconda-e1a7fe9887886044b07587b3ec2caa2ff53ebfb2.zip
Updates to make existing code use the new storage module.
-rwxr-xr-xanaconda3
-rw-r--r--backend.py7
-rw-r--r--bootloader.py51
-rw-r--r--dispatch.py10
-rw-r--r--exception.py2
-rw-r--r--installclass.py17
-rw-r--r--installmethod.py6
-rw-r--r--instdata.py36
-rwxr-xr-xisys/isys.py358
-rw-r--r--kickstart.py56
-rw-r--r--livecd.py39
-rw-r--r--network.py4
-rw-r--r--packages.py137
-rw-r--r--rescue.py46
-rw-r--r--upgrade.py207
-rw-r--r--yuminstall.py26
16 files changed, 236 insertions, 769 deletions
diff --git a/anaconda b/anaconda
index f669ee0e8..199168b05 100755
--- a/anaconda
+++ b/anaconda
@@ -983,11 +983,10 @@ if __name__ == "__main__":
# Skip the disk options in rootpath mode
if flags.rootpath:
- anaconda.dispatch.skipStep("partitionobjinit", permanent = 1)
anaconda.dispatch.skipStep("parttype", permanent = 1)
anaconda.dispatch.skipStep("autopartitionexecute", permanent = 1)
anaconda.dispatch.skipStep("partition", permanent = 1)
- anaconda.dispatch.skipStep("partitiondone", permanent = 1)
+ anaconda.dispatch.skipStep("storagedone", permanent = 1)
anaconda.dispatch.skipStep("bootloader", permanent = 1)
anaconda.dispatch.skipStep("bootloaderadvanced", permanent = 1)
anaconda.dispatch.skipStep("upgbootloader", permanent = 1)
diff --git a/backend.py b/backend.py
index e8bcf4f5c..475785b12 100644
--- a/backend.py
+++ b/backend.py
@@ -85,8 +85,8 @@ class AnacondaBackend:
# the initrd might need iscsi-initiator-utils, and chances are
# it was not installed yet the first time mkinitrd was run, as
# mkinitrd does not require it.
- for disk in anaconda.id.diskset.disks.keys():
- if isys.driveIsIscsi(disk):
+ for disk in anaconda.id.storage.disks:
+ if isys.driveIsIscsi(disk.path):
has_iscsi_disk = True
break
@@ -156,8 +156,9 @@ class AnacondaBackend:
if not anaconda.mediaDevice or not os.path.exists(installimg):
return
+ free = anaconda.id.storage.fsset.fsFreeSpace(anaconda.rootPath)
self._loopbackFile = "%s%s/rhinstall-install.img" % (anaconda.rootPath,
- anaconda.id.fsset.filesystemSpace(anaconda.rootPath)[0][0])
+ free[0][0])
try:
win = anaconda.intf.waitWindow(_("Copying File"),
diff --git a/bootloader.py b/bootloader.py
index b78cfd701..7ad11b4d5 100644
--- a/bootloader.py
+++ b/bootloader.py
@@ -60,49 +60,36 @@ def bootloaderSetupChoices(anaconda):
anaconda.id.bootloader.updateDriveList(pref)
if iutil.isEfi() and not anaconda.id.bootloader.device:
- drives = anaconda.id.diskset.disks.keys()
- drives.sort()
bootPart = None
- for drive in drives:
- disk = anaconda.id.diskset.disks[drive]
- for part in disk.partitions:
- if part.active and partedUtils.isEfiSystemPartition(part):
- bootPart = part.getDeviceNodeName()
+ partitions = anaconda.id.storage.partitions
+ for part in partitions:
+ if part.partedPartition.active and \
+ partedUtils.isEfiSystemPartition(part.partedPartition):
+ bootPart = part.name
break
- if bootPart:
- break
if bootPart:
anaconda.id.bootloader.setDevice(bootPart)
- dev = Device()
- dev.device = bootPart
- anaconda.id.fsset.add(FileSystemSetEntry(dev, None, fileSystemTypeGet("efi")))
# iSeries bootloader on upgrades
if iutil.getPPCMachine() == "iSeries" and not anaconda.id.bootloader.device:
- drives = anaconda.id.diskset.disks.keys()
- drives.sort()
bootPart = None
- for drive in drives:
- disk = anaconda.id.diskset.disks[drive]
- for part in disk.partitions:
- if part.active and part.getFlag(parted.PARTITION_PREP):
- bootPart = part.getDeviceNodeName()
- break
- if bootPart:
+ partitions = anaconda.id.storage.partitions
+ for part in partitions:
+ if part.partedPartition.active and \
+ part.partedPartition.getFlag(parted.PARTITION_PREP):
+ bootPart = part.name
break
if bootPart:
anaconda.id.bootloader.setDevice(bootPart)
- dev = Device()
- dev.device = bootPart
- anaconda.id.fsset.add(FileSystemSetEntry(dev, None, fileSystemTypeGet("PPC PReP Boot")))
- choices = anaconda.id.fsset.bootloaderChoices(anaconda.id.diskset, anaconda.id.bootloader)
+ choices = anaconda.id.storage.fsset.bootloaderChoices(anaconda.id.bootloader)
if not choices and iutil.getPPCMachine() != "iSeries":
anaconda.dispatch.skipStep("instbootloader")
else:
anaconda.dispatch.skipStep("instbootloader", skip = 0)
- anaconda.id.bootloader.images.setup(anaconda.id.diskset, anaconda.id.fsset)
+ # FIXME: ...
+ anaconda.id.bootloader.images.setup(anaconda.id.storage)
if anaconda.id.bootloader.defaultDevice != None and choices:
keys = choices.keys()
@@ -150,11 +137,7 @@ def writeBootloader(anaconda):
kernelList = []
otherList = []
- root = anaconda.id.fsset.getEntryByMountPoint('/')
- if root:
- rootDev = root.device.getDevice()
- else:
- rootDev = None
+ rootDev = getattr(anaconda.id.rootDevice, "path", None)
defaultDev = anaconda.id.bootloader.images.getDefault()
kernelLabel = None
@@ -204,8 +187,10 @@ def writeBootloader(anaconda):
dosync()
try:
- anaconda.id.bootloader.write(anaconda.rootPath, anaconda.id.fsset, anaconda.id.bootloader,
- anaconda.id.instLanguage, kernelList, otherList, defaultDev,
+ anaconda.id.bootloader.write(anaconda.rootPath, anaconda.id.storage,
+ anaconda.id.bootloader,
+ anaconda.id.instLanguage,
+ kernelList, otherList, defaultDev,
justConfigFile, anaconda.intf)
if not justConfigFile:
w.pop()
diff --git a/dispatch.py b/dispatch.py
index b773404dd..a09a86183 100644
--- a/dispatch.py
+++ b/dispatch.py
@@ -34,8 +34,9 @@ from packages import setupTimezone
from packages import setFileCons
from packages import regKeyScreen
from packages import writeRegKey
-from partitions import partitionObjectsInitialize
-from partitions import partitioningComplete
+from storage import storageInitialize
+from storage import storageComplete
+from storage.partitioning import doAutoPartition
from bootloader import writeBootloader, bootloaderSetupChoices
from flags import flags
from upgrade import upgradeMountFilesystems, queryUpgradeArch
@@ -71,13 +72,13 @@ installSteps = [
("keyboard", ),
("betanag", betaNagScreen, ),
("regkey", regKeyScreen, ),
+ ("storageinit", storageInitialize, ),
("findrootparts", findRootParts, ),
("findinstall", ),
("network", ),
("timezone", ),
("accounts", ),
("setuptime", setupTimezone, ),
- ("partitionobjinit", partitionObjectsInitialize, ),
("parttype", ),
("autopartitionexecute", doAutoPartition, ),
("partition", ),
@@ -88,8 +89,7 @@ installSteps = [
("addswap", ),
("upgrademigfind", upgradeMigrateFind, ),
("upgrademigratefs", ),
- ("partitiondone", partitioningComplete, ),
- ("migratefilesystems", doMigrateFilesystems, ),
+ ("storagedone", storageComplete, ),
("enablefilesystems", turnOnFilesystems, ),
("upgbootloader", ),
("bootloadersetup", bootloaderSetupChoices, ),
diff --git a/exception.py b/exception.py
index 7b6fdea9d..681b3ec5d 100644
--- a/exception.py
+++ b/exception.py
@@ -223,7 +223,7 @@ class AnacondaExceptionDump:
for file in ("/tmp/syslog", "/tmp/anaconda.log",
"/tmp/lvmout", "/tmp/resize.out",
- "/tmp/program.log",
+ "/tmp/program.log", "/tmp/storage.log",
anaconda.rootPath + "/root/install.log",
anaconda.rootPath + "/root/upgrade.log"):
try:
diff --git a/installclass.py b/installclass.py
index a3a97aed5..4a1e95269 100644
--- a/installclass.py
+++ b/installclass.py
@@ -96,14 +96,14 @@ class BaseInstallClass(object):
"language",
"keyboard",
"welcome",
+ "storageinit",
"findrootparts",
"betanag",
"installtype",
- "partitionobjinit",
"parttype",
"autopartitionexecute",
"partition",
- "partitiondone",
+ "storagedone",
"bootloadersetup",
"bootloader",
"network",
@@ -116,7 +116,6 @@ class BaseInstallClass(object):
"confirminstall",
"install",
"enablefilesystems",
- "migratefilesystems",
"setuptime",
"preinstallconfig",
"installpackages",
@@ -188,11 +187,11 @@ class BaseInstallClass(object):
from backend import AnacondaBackend
return AnacondaBackend
- def setDefaultPartitioning(self, partitions, clear = CLEARPART_TYPE_LINUX,
+ def setDefaultPartitioning(self, storage, clear = CLEARPART_TYPE_LINUX,
doClear = 1, useLVM = True):
autorequests = [ ("/", None, 1024, None, 1, 1, 1) ]
- bootreq = getAutopartitionBoot(partitions)
+ bootreq = getAutopartitionBoot(storage)
if bootreq:
autorequests.extend(bootreq)
@@ -200,13 +199,13 @@ class BaseInstallClass(object):
autorequests.append((None, "swap", minswap, maxswap, 1, 1, 1))
if doClear:
- partitions.autoClearPartType = clear
- partitions.autoClearPartDrives = []
+ storage.autoClearPartType = clear
+ storage.autoClearPartDrives = []
if useLVM:
- partitions.autoPartitionRequests = autoCreateLVMPartitionRequests(autorequests)
+ storage.autoPartitionRequests = autoCreateLVMPartitionRequests(autorequests)
else:
- partitions.autoPartitionRequests = autoCreatePartitionRequests(autorequests)
+ storage.autoPartitionRequests = autoCreatePartitionRequests(autorequests)
def setInstallData(self, anaconda):
diff --git a/installmethod.py b/installmethod.py
index ce1dd7f99..d62201583 100644
--- a/installmethod.py
+++ b/installmethod.py
@@ -47,9 +47,9 @@ def doMethodComplete(anaconda):
isys.ejectCdrom(dev)
mtab = "/dev/root / ext3 ro 0 0\n"
- for ent in anaconda.id.fsset.entries:
- if ent.mountpoint == "/":
- mtab = "/dev/root / %s ro 0 0\n" %(ent.fsystem.name,)
+ rootDevice = anaconda.id.storage.rootDevice
+ if rootDevice:
+ mtab = "/dev/root / %s ro 0 0\n" % rootDevice.format.type
f = open(anaconda.rootPath + "/etc/mtab", "w+")
f.write(mtab)
diff --git a/instdata.py b/instdata.py
index 25aee6157..86f389363 100644
--- a/instdata.py
+++ b/instdata.py
@@ -30,12 +30,8 @@ import firewall
import security
import timezone
import desktop
-import fsset
import bootloader
-import partitions
-import partedUtils
-import iscsi
-import zfcp
+import storage
import urllib
import iutil
import isys
@@ -67,8 +63,6 @@ class InstallData:
self.instClass = None
self.network = network.Network()
- self.iscsi = iscsi.iscsi()
- self.zfcp = zfcp.ZFCP()
self.firewall = firewall.Firewall()
self.security = security.Security()
self.timezone = timezone.Timezone()
@@ -80,10 +74,7 @@ class InstallData:
self.upgrade = None
if flags.cmdline.has_key("preupgrade"):
self.upgrade = True
- # XXX move fsset and/or diskset into Partitions object?
- self.fsset.reset()
- self.diskset = partedUtils.DiskSet(self.anaconda)
- self.partitions = partitions.Partitions(self.anaconda)
+ self.storage = storage.Storage(self.anaconda)
self.bootloader = bootloader.getBootloader()
self.upgradeRoot = None
self.rootParts = None
@@ -102,19 +93,13 @@ class InstallData:
if os.path.exists("/dev/live") and \
stat.S_ISBLK(os.stat("/dev/live")[stat.ST_MODE]):
target = os.readlink("/dev/live")
- self.partitions.protected = [target]
+ self.storage.protectedPartitions = [target]
elif self.anaconda.methodstr and self.anaconda.methodstr.startswith("hd:"):
method = self.anaconda.methodstr[3:]
- device = method.split(":", 3)[0]
+ devspec = method.split(":", 3)[0]
- if device.startswith("LABEL="):
- dev = isys.getDeviceByToken("LABEL", device[6:])
- elif device.startswith("UUID="):
- dev = isys.getDeviceByToken("UUID", device[5:])
- else:
- dev = device
-
- if dev is None:
+ device = storage.resolveDevice(devspec)
+ if device is None:
if self.getUpgrade():
return
else:
@@ -125,10 +110,7 @@ class InstallData:
type="custom", custom_buttons = [_("_Exit installer")])
sys.exit(1)
- if dev.startswith("/dev/"):
- dev = dev[5:]
-
- self.partitions.protected = [dev]
+ self.storage.protectedPartitions = [device.name]
def setInstallProgressClass(self, c):
self.instProgress = c
@@ -286,7 +268,6 @@ class InstallData:
if not self.isHeadless:
self.keyboard.writeKS(f)
self.network.writeKS(f)
- self.zfcp.writeKS(f)
if self.rootPassword["isCrypted"]:
args = " --iscrypted %s" % self.rootPassword["password"]
@@ -312,7 +293,7 @@ class InstallData:
self.security.writeKS(f)
self.timezone.writeKS(f)
self.bootloader.writeKS(f)
- self.partitions.writeKS(f)
+ self.storage.writeKS(f) # FIXME: unimplemented
if self.backend is not None:
self.backend.writeKS(f)
@@ -339,6 +320,5 @@ class InstallData:
self.videocard = None
self.isHeadless = 0
self.extraModules = extraModules
- self.fsset = fsset.FileSystemSet()
self.reset()
diff --git a/isys/isys.py b/isys/isys.py
index e6c4b3476..fb2fa5d57 100755
--- a/isys/isys.py
+++ b/isys/isys.py
@@ -59,7 +59,6 @@ NM_STATE_CONNECTED = 3
NM_STATE_DISCONNECTED = 4
mountCount = {}
-raidCount = {}
MIN_RAM = _isys.MIN_RAM
MIN_GUI_RAM = _isys.MIN_GUI_RAM
@@ -71,194 +70,12 @@ EARLY_SWAP_RAM = _isys.EARLY_SWAP_RAM
def pathSpaceAvailable(path):
return _isys.devSpaceFree(path)
-mdadmOutput = "/tmp/mdadmout"
-
-## An error occured when running mdadm.
-class MdadmError(Exception):
- ## The constructor.
- # @param args The arguments passed to the mdadm command.
- # @param name The the name of the RAID device used in the mdadm command.
- def __init__(self, args, name=None):
- self.args = args
- self.name = name
- self.log = self.getCmdOutput()
-
- ## Get the output of the last mdadm command run.
- # @return The formatted output of the mdadm command which caused an error.
- def getCmdOutput(self):
- f = open(mdadmOutput, "r")
- lines = reduce(lambda x,y: x + [string.strip(y),], f.readlines(), [])
- lines = string.join(reduce(lambda x,y: x + [" %s" % (y,)], \
- lines, []), "\n")
- return lines
-
- def __str__(self):
- s = ""
- if not self.name is None:
- s = " for device %s" % (self.name,)
- command = "mdadm " + string.join(self.args, " ")
- return "'%s' failed%s\nLog:\n%s" % (command, s, self.log)
-
-def _mdadm(*args):
- try:
- lines = iutil.execWithCapture("mdadm", args, stderr = mdadmOutput)
- lines = string.split(lines, '\n')
- lines = reduce(lambda x,y: x + [y.strip(),], lines, [])
- return lines
- except:
- raise MdadmError, args
-
-def _getRaidInfo(drive):
- log.info("mdadm -E %s" % (drive,))
- try:
- lines = _mdadm("-E", drive)
- except MdadmError:
- ei = sys.exc_info()
- ei[1].name = drive
- raise ei[0], ei[1], ei[2]
-
- info = {
- 'major': "-1",
- 'minor': "-1",
- 'uuid' : "",
- 'level': -1,
- 'nrDisks': -1,
- 'totalDisks': -1,
- 'mdMinor': -1,
- }
-
- for line in lines:
- vals = string.split(string.strip(line), ' : ')
- if len(vals) != 2:
- continue
- if vals[0] == "Version":
- vals = string.split(vals[1], ".")
- info['major'] = vals[0]
- info['minor'] = vals[1]
- elif vals[0] == "UUID":
- info['uuid'] = vals[1]
- elif vals[0] == "Raid Level":
- info['level'] = int(vals[1][4:])
- elif vals[0] == "Raid Devices":
- info['nrDisks'] = int(vals[1])
- elif vals[0] == "Total Devices":
- info['totalDisks'] = int(vals[1])
- elif vals[0] == "Preferred Minor":
- info['mdMinor'] = int(vals[1])
- else:
- continue
-
- if info['uuid'] == "":
- raise ValueError, info
-
- return info
-
-def _stopRaid(mdDevice):
- log.info("mdadm --stop %s" % (mdDevice,))
- try:
- _mdadm("--stop", mdDevice)
- except MdadmError:
- ei = sys.exc_info()
- ei[1].name = mdDevice
- raise ei[0], ei[1], ei[2]
-
-def raidstop(mdDevice):
- log.info("stopping raid device %s" %(mdDevice,))
- if raidCount.has_key (mdDevice):
- if raidCount[mdDevice] > 1:
- raidCount[mdDevice] = raidCount[mdDevice] - 1
- return
- del raidCount[mdDevice]
-
- devInode = "/dev/%s" % mdDevice
-
- try:
- _stopRaid(devInode)
- except:
- pass
-
-def _startRaid(mdDevice, mdMinor, uuid):
- log.info("mdadm -A --uuid=%s --super-minor=%s %s" % (uuid, mdMinor, mdDevice))
- try:
- _mdadm("-A", "--uuid=%s" % (uuid,), "--super-minor=%s" % (mdMinor,), \
- mdDevice)
- except MdadmError:
- ei = sys.exc_info()
- ei[1].name = mdDevice
- raise ei[0], ei[1], ei[2]
-
-def raidstart(mdDevice, aMember):
- log.info("starting raid device %s" %(mdDevice,))
- if raidCount.has_key(mdDevice) and raidCount[mdDevice]:
- raidCount[mdDevice] = raidCount[mdDevice] + 1
- return
-
- raidCount[mdDevice] = 1
-
- mdInode = "/dev/%s" % mdDevice
- mbrInode = "/dev/%s" % aMember
-
- if os.path.exists(mdInode):
- minor = os.minor(os.stat(mdInode).st_rdev)
- else:
- minor = int(mdDevice[2:])
- try:
- info = _getRaidInfo(mbrInode)
- if info.has_key('mdMinor'):
- minor = info['mdMinor']
- _startRaid(mdInode, minor, info['uuid'])
- except:
- pass
-
-## Remove the superblock from a RAID device.
-# @param device The complete path to the RAID device name to wipe.
-def wipeRaidSB(device):
- try:
- fd = os.open(device, os.O_WRONLY)
- except OSError, e:
- log.warning("error wiping raid device superblock for %s: %s", device, e)
- return
-
- try:
- _isys.wiperaidsb(fd)
- finally:
- os.close(fd)
- return
-
-## Get the raw superblock from a RAID device.
-# @param The basename of a RAID device to check. This device node does not
-# need to exist to begin with.
-# @return A RAID superblock in its raw on-disk format.
-def raidsb(mdDevice):
- return raidsbFromDevice("/dev/%s" % mdDevice)
-
-## Get the superblock from a RAID device.
-# @param The full path to a RAID device name to check. This device node must
-# already exist.
-# @return A tuple of the contents of the RAID superblock, or ValueError on
-# error.
-def raidsbFromDevice(device):
- try:
- info = _getRaidInfo(device)
- return (info['major'], info['minor'], info['uuid'], info['level'],
- info['nrDisks'], info['totalDisks'], info['mdMinor'])
- except:
- raise ValueError
-
-def getRaidChunkFromDevice(device):
- fd = os.open(device, os.O_RDONLY)
- rc = 64
- try:
- rc = _isys.getraidchunk(fd)
- finally:
- os.close(fd)
- return rc
-
## Set up an already existing device node to be used as a loopback device.
# @param device The full path to a device node to set up as a loopback device.
# @param file The file to mount as loopback on device.
# @param readOnly Should this loopback device be used read-only?
def losetup(device, file, readOnly = 0):
+ # FIXME: implement this as a storage.devices.Device subclass
if readOnly:
mode = os.O_RDONLY
else:
@@ -272,6 +89,7 @@ def losetup(device, file, readOnly = 0):
os.close(targ)
def lochangefd(device, file):
+ # FIXME: implement this as a storage.devices.Device subclass
loop = os.open(device, os.O_RDONLY)
targ = os.open(file, os.O_RDONLY)
try:
@@ -283,6 +101,7 @@ def lochangefd(device, file):
## Disable a previously setup loopback device.
# @param device The full path to an existing loopback device node.
def unlosetup(device):
+ # FIXME: implement this as a storage.devices.Device subclass
loop = os.open(device, os.O_RDONLY)
try:
_isys.unlosetup(loop)
@@ -407,175 +226,6 @@ def swapon (path):
def loadKeymap(keymap):
return _isys.loadKeymap (keymap)
-cachedDrives = None
-
-## Clear the drive dict cache.
-# This method clears the drive dict cache. If the drive state changes (by
-# loading and unloading modules, attaching removable devices, etc.) then this
-# function must be called before any of the *DriveDict or *DriveList functions.
-# If not, those functions will return information that does not reflect the
-# current machine state.
-def flushDriveDict():
- global cachedDrives
- cachedDrives = None
-
-def driveDict(klassArg):
- import parted
- global cachedDrives
- if cachedDrives is None:
- new = {}
- for dev in minihal.get_devices_by_type("storage"):
- if dev['device'] is None: # none devices make no sense
- continue
-
- device = dev['device'].replace('/dev/','')
- # we can't actually use the sg devices, so ignore them
- if device.startswith("sg"):
- log.info("ignoring sg device %s" %(device,))
- continue
-
- # we can't actually use the st devices, so ignore them
- if device.startswith("st"):
- log.info("ignoring st device %s" %(device,))
- continue
-
- # we want to ignore md devices as they're not hard disks in our pov
- if device.startswith("md"):
- continue
-
- if dev['storage.drive_type'] != 'disk':
- new[device] = dev
- continue
- try:
- if not mediaPresent (device):
- new[device] = dev
- continue
-
- # blacklist the device which the live image is running from
- # installing over that is almost certainly the wrong
- # thing to do.
- if os.path.exists("/dev/live") and \
- stat.S_ISBLK(os.stat("/dev/live")[stat.ST_MODE]):
- livetarget = os.path.realpath("/dev/live")
- if livetarget.startswith(dev['device']):
- log.info("%s looks to be the live device; ignoring" % (device,))
- continue
-
- if device.startswith("sd"):
- peddev = parted.getDevice(dev['device'])
- model = peddev.model
-
- # blacklist *STMF on power5 iSeries boxes
- if iutil.isPPC() and \
- model.find("IBM *STMF KERNEL") != -1:
- log.info("%s looks like STMF, ignoring" % (device,))
- del peddev
- continue
-
- # blacklist PS3 flash
- if iutil.isPPC() and \
- model.find("SCEI Flash-5") != -1:
- log.info("%s looks like PS3 flash, ignoring" % \
- (device,))
- del peddev
- continue
-
- # blacklist DGC/EMC LUNs for which we have no ACL.
- # We should be ignoring LUN_Z for all vendors, but I
- # don't know how (if) other vendors encode this into
- # the model info.
- #
- # XXX I need to work some SCC2 LUN mode page detection
- # into libbdevid, and then this should use that instead.
- # -- pjones
- if str(peddev.model) == "DGC LUNZ":
- log.info("%s looks like a LUN_Z device, ignoring" % \
- (device,))
- del peddev
- continue
-
- del peddev
- new[device] = dev
- except Exception, e:
- log.debug("exception checking disk blacklist on %s: %s" % \
- (device, e))
- cachedDrives = new
-
- ret = {}
- for key,dev in cachedDrives.items():
- # XXX these devices should have deviceclass attributes. Or they
- # should all be subclasses in a device tree and we should be able
- # to use isinstance on all of them. Not both.
- if isinstance(dev, block.MultiPath) or isinstance(dev, block.RaidSet):
- if klassArg == "disk":
- ret[key] = dev
- elif dev['storage.drive_type'] == klassArg:
- ret[key] = dev
- return ret
-
-## Get all the hard drives attached to the system.
-# This method queries the drive dict cache for all hard drives. If the cache
-# is empty, this will cause all disk devices to be probed. If the status of
-# the devices has changed, flushDriveDict must be called first.
-#
-# @see flushDriveDict
-# @see driveDict
-# @return A dict of all the hard drive descriptions, keyed on device name.
-def hardDriveDict():
- ret = {}
- dict = driveDict("disk")
- for item in dict.keys():
- try:
- ret[item] = dict[item]['description']
- except AttributeError:
- ret[item] = ""
- return ret
-
-## Get all the removable drives attached to the system.
-# This method queries the drive dict cache for all removable drives. If the cache
-# is empty, this will cause all disk devices to be probed. If the status of
-# the devices has changed, flushDriveDict must be run called first.
-#
-# @see flushDriveDict
-# @see driveDict
-# @return A dict of all the removable drive descriptions, keyed on device name.
-def removableDriveDict():
- ret = {}
- dict = driveDict("disk")
- for item in dict.keys():
- if dict[item]['storage.removable'] != 0:
- try:
- ret[item] = dict[item]['description']
- except AttributeError:
- ret[item] = ""
- return ret
-
-## Get all CD/DVD drives attached to the system.
-# This method queries the drive dict cache for all hard drives. If the cache
-# is empty, this will cause all disk devices to be probed. If the status of
-# the devices has changed, flushDriveDict must be called first.
-#
-# @see flushDriveDict
-# @see driveDict
-# @return A sorted list of all the CD/DVD drives, without any leading /dev/.
-def cdromList():
- list = driveDict("cdrom").keys()
- list.sort()
- return list
-
-## Get all tape drives attached to the system.
-# This method queries the drive dict cache for all hard drives. If the cache
-# is empty, this will cause all disk devices to be probed. If the status of
-# the devices has changed, flushDriveDict must be called first.
-#
-# @see flushDriveDict
-# @see driveDict
-# @return A sorted list of all the tape drives, without any leading /dev/.
-def tapeDriveList():
- list = driveDict("tape").keys()
- list.sort()
- return list
-
def getDasdPorts():
return _isys.getDasdPorts()
@@ -788,6 +438,7 @@ def ext2HasJournal(device):
return hasjournal
def ejectCdrom(device):
+ # XXX this should go into storage.devices.OpticalDevice
if not os.path.exists(device):
device = "/dev/%s" % device
@@ -834,6 +485,7 @@ def driveUsesModule(device, modules):
# @param device The basename of the device node.
# @return True if media is present in device, False otherwise.
def mediaPresent(device):
+ # XXX this should go into storage.devices.RemovableDevice or similar
try:
fd = os.open("/dev/%s" % device, os.O_RDONLY)
except OSError, (errno, strerror):
diff --git a/kickstart.py b/kickstart.py
index 9a7099f25..0fee19e07 100644
--- a/kickstart.py
+++ b/kickstart.py
@@ -24,13 +24,11 @@ import isys
import os
import tempfile
from autopart import *
-from fsset import *
from flags import flags
from constants import *
import sys
import raid
import string
-import partRequests
import urlgrabber.grabber as grabber
import lvm
import warnings
@@ -149,8 +147,8 @@ class AutoPart(commands.autopart.F9_AutoPart):
self.handler.id.instClass.setDefaultPartitioning(self.handler.id, doClear = 0)
if self.encrypted:
- self.handler.id.partitions.autoEncrypt = True
- self.handler.id.partitions.encryptionPassphrase = self.passphrase
+ self.handler.id.storage.autoEncrypt = True
+ self.handler.id.storage.encryptionPassphrase = self.passphrase
self.handler.skipSteps.extend(["partition", "zfcpconfig", "parttype"])
return retval
@@ -181,7 +179,11 @@ class Bootloader(commands.bootloader.F8_Bootloader):
self.handler.id.bootloader.doUpgradeOnly = 1
if self.driveorder:
- hds = isys.hardDriveDict().keys()
+ # XXX I don't like that we are supposed to have scanned the
+ # storage devices already and yet we cannot know about
+ # ignoredDisks, exclusiveDisks, or iscsi disks before we
+ # have processed the kickstart config file.
+ hds = [d.name for d in self.handler.id.storage.disks]
for disk in self.driveorder:
if disk not in hds:
raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in driveorder command" % disk)
@@ -238,10 +240,10 @@ class ClearPart(commands.clearpart.FC3_ClearPart):
if disk not in hds:
raise KickstartValueError, formatErrorMsg(self.lineno, msg="Specified nonexistent disk %s in clearpart command" % disk)
- self.handler.id.partitions.autoClearPartType = self.type
- self.handler.id.partitions.autoClearPartDrives = self.drives
+ self.handler.id.storage.autoClearPartType = self.type
+ self.handler.id.storage.autoClearPartDrives = self.drives
if self.initAll:
- self.handler.id.partitions.reinitializeDisks = self.initAll
+ self.handler.id.storage.reinitializeDisks = self.initAll
return retval
@@ -269,15 +271,13 @@ class IgnoreDisk(commands.ignoredisk.F8_IgnoreDisk):
def parse(self, args):
retval = commands.ignoredisk.F8_IgnoreDisk.parse(self, args)
- diskset = self.handler.id.diskset
for drive in self.ignoredisk:
- if not drive in diskset.skippedDisks:
- diskset.skippedDisks.append(drive)
+ if not drive in self.handler.id.storage.ignoredDisks:
+ self.handler.id.storage.ignoredDisks.append(drive)
- diskset = self.handler.id.diskset
for drive in self.onlyuse:
- if not drive in diskset.exclusiveDisks:
- diskset.exclusiveDisks.append(drive)
+ if not drive in self.handler.id.storage.exclusiveDisks:
+ self.handler.id.storage.exclusiveDisks.append(drive)
return retval
@@ -304,8 +304,6 @@ class Iscsi(commands.iscsi.F10_Iscsi):
if self.handler.id.iscsi.addTarget(**kwargs):
log.info("added iscsi target: %s" %(target.ipaddr,))
- # FIXME: flush the drive dict so we figure drives out again
- isys.flushDriveDict()
return retval
class IscsiName(commands.iscsiname.FC6_IscsiName):
@@ -359,7 +357,7 @@ class LogVol(commands.logvol.F9_LogVol):
except KeyError:
raise KickstartValueError, formatErrorMsg(self.lineno, msg="No volume group exists with the name '%s'. Specify volume groups before logical volumes." % lvd.vgname)
- for areq in self.handler.id.partitions.autoPartitionRequests:
+ for areq in self.handler.id.storage.autoPartitionRequests:
if areq.type == REQUEST_LV:
if areq.volumeGroup == vgid and areq.logicalVolumeName == lvd.name:
raise KickstartValueError, formatErrorMsg(self.lineno, msg="Logical volume name already used in volume group %s" % lvd.vgname)
@@ -395,8 +393,8 @@ class LogVol(commands.logvol.F9_LogVol):
if lvd.encrypted:
if lvd.passphrase and \
- not self.handler.anaconda.id.partitions.encryptionPassphrase:
- self.handler.anaconda.id.partitions.encryptionPassphrase = lvd.passphrase
+ not self.handler.anaconda.id.storage.encryptionPassphrase:
+ self.handler.anaconda.id.storage.encryptionPassphrase = lvd.passphrase
request.encryption = cryptodev.LUKSDevice(passphrase=lvd.passphrase, format=lvd.format)
addPartRequest(self.handler.anaconda, request)
@@ -635,7 +633,7 @@ class Partition(commands.partition.F9_Partition):
request.uniqueID = uniqueID
if pd.onPart != "":
request.device = pd.onPart
- for areq in self.handler.id.partitions.autoPartitionRequests:
+ for areq in self.handler.id.storage.autoPartitionRequests:
if areq.device is not None and areq.device == pd.onPart:
raise KickstartValueError, formatErrorMsg(self.lineno, "Partition already used")
@@ -644,8 +642,8 @@ class Partition(commands.partition.F9_Partition):
if pd.encrypted:
if pd.passphrase and \
- not self.handler.anaconda.id.partitions.encryptionPassphrase:
- self.handler.anaconda.id.partitions.encryptionPassphrase = pd.passphrase
+ not self.handler.anaconda.id.storage.encryptionPassphrase:
+ self.handler.anaconda.id.storage.encryptionPassphrase = pd.passphrase
request.encryption = cryptodev.LUKSDevice(passphrase=pd.passphrase, format=pd.format)
addPartRequest(self.handler.anaconda, request)
@@ -728,8 +726,8 @@ class Raid(commands.raid.F9_Raid):
if rd.encrypted:
if rd.passphrase and \
- not self.handler.anaconda.id.partitions.encryptionPassphrase:
- self.handler.anaconda.id.partitions.encryptionPassphrase = rd.passphrase
+ not self.handler.anaconda.id.storage.encryptionPassphrase:
+ self.handler.anaconda.id.storage.encryptionPassphrase = rd.passphrase
request.encryption = cryptodev.LUKSDevice(passphrase=rd.passphrase, format=rd.format)
addPartRequest(self.handler.anaconda, request)
@@ -830,7 +828,7 @@ class XConfig(commands.xconfig.F10_XConfig):
class ZeroMbr(commands.zerombr.FC3_ZeroMbr):
def parse(self, args):
retval = commands.zerombr.FC3_ZeroMbr.parse(self, args)
- self.handler.id.partitions.zeroMbr = 1
+ self.handler.id.storage.zeroMbr = 1
return retval
class ZFCP(commands.zfcp.FC3_ZFCP):
@@ -1002,14 +1000,14 @@ class AnacondaKSParser(KickstartParser):
# else with this mountpoint so that you can use autopart and override /
def addPartRequest(anaconda, request):
if not request.mountpoint:
- anaconda.id.partitions.autoPartitionRequests.append(request)
+ anaconda.id.storage.autoPartitionRequests.append(request)
return
- for req in anaconda.id.partitions.autoPartitionRequests:
+ for req in anaconda.id.storage.autoPartitionRequests:
if req.mountpoint and req.mountpoint == request.mountpoint:
- anaconda.id.partitions.autoPartitionRequests.remove(req)
+ anaconda.id.storage.autoPartitionRequests.remove(req)
break
- anaconda.id.partitions.autoPartitionRequests.append(request)
+ anaconda.id.storage.autoPartitionRequests.append(request)
def processKickstartFile(anaconda, file):
# make sure our disks are alive
diff --git a/livecd.py b/livecd.py
index 5d7d3f7b7..695f241d6 100644
--- a/livecd.py
+++ b/livecd.py
@@ -41,7 +41,6 @@ _ = lambda x: gettext.ldgettext("anaconda", x)
import backend
import isys
import iutil
-import fsset
import packages
@@ -174,16 +173,9 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
osimg = self._getLiveBlockDevice() # the real image
osfd = os.open(osimg, os.O_RDONLY)
- r = anaconda.id.fsset.getEntryByMountPoint("/")
- rootfs = r.device.setupDevice()
- rootfd = os.open(rootfs, os.O_WRONLY)
-
- # set the rootfs to have the right type. this lets things work
- # given ext2 or ext3 (and in the future, ext4)
- # FIXME: should we try to migrate if there isn't a match?
- roottype = isys.readFSType(osimg)
- if roottype is not None:
- r.fsystem = fsset.fileSystemTypeGet(roottype)
+ rootDevice = anaconda.id.fsset.rootDevice
+ rootDevice.setup()
+ rootfd = os.open(rootDevice.path, os.O_WRONLY)
readamt = 1024 * 1024 * 8 # 8 megs at a time
size = self._getLiveSize()
@@ -222,6 +214,7 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
anaconda.id.instProgress = None
def _doFilesystemMangling(self, anaconda):
+ # FIXME: this whole method is a big fucking mess
log.info("doing post-install fs mangling")
wait = anaconda.intf.waitWindow(_("Doing post-installation"),
_("Performing post-installation filesystem changes. This may take several minutes..."))
@@ -233,12 +226,16 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
anaconda.id.fsset.mountFilesystems(anaconda)
# restore the label of / to what we think it is
- r = anaconda.id.fsset.getEntryByMountPoint("/")
- anaconda.id.fsset.labelEntry(r, anaconda.rootPath, True)
+ rootDevice = anaconda.id.fsset.rootDevice
+ rootDevice.setup()
# ensure we have a random UUID on the rootfs
# FIXME: this should be abstracted per filesystem type
- iutil.execWithRedirect("tune2fs", ["-U", "random", "/dev/%s" % (r.device.getDevice())],
- stdout="/dev/tty5", stderr="/dev/tty5",
+ iutil.execWithRedirect("tune2fs",
+ ["-U",
+ "random",
+ rootDevice.path],
+ stdout="/dev/tty5",
+ stderr="/dev/tty5",
searchPath = 1)
# for any filesystem that's _not_ on the root, we need to handle
@@ -246,6 +243,7 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
# this is pretty distasteful, but should work with things like
# having a separate /usr/local
+ # XXX wow, what in the hell is going on here?
# get a list of fsset entries that are relevant
entries = sorted(filter(lambda e: not e.fsystem.isKernelFS() and \
e.getMountPoint(), anaconda.id.fsset.entries))
@@ -314,13 +312,12 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
def _resizeRootfs(self, anaconda, win = None):
log.info("going to do resize")
- r = anaconda.id.fsset.getEntryByMountPoint("/")
- rootdev = r.device.getDevice()
+ rootDevice = anaconda.id.fsset.rootDevice
# FIXME: we'd like to have progress here to give an idea of
# how long it will take. or at least, to give an indefinite
# progress window. but, not for this time
- cmd = ["resize2fs", "/dev/%s" %(rootdev,), "-p"]
+ cmd = ["resize2fs", rootDevice.path, "-p"]
out = open("/dev/tty5", "w")
proc = subprocess.Popen(cmd, stdout=out, stderr=out)
rc = proc.poll()
@@ -376,9 +373,8 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
# FIXME: really, this should be in the general sanity checking, but
# trying to weave that in is a little tricky at present.
ossize = self._getLiveSizeMB()
- slash = anaconda.id.partitions.getRequestByMountPoint("/")
- if slash and \
- slash.getActualSize(anaconda.id.partitions, anaconda.id.diskset) < ossize:
+ slash = anaconda.id.fsset.rootDevice
+ if slash.size < ossize:
rc = anaconda.intf.messageWindow(_("Error"),
_("The root filesystem you created is "
"not large enough for this live "
@@ -391,7 +387,6 @@ class LiveCDCopyBackend(backend.AnacondaBackend):
return DISPATCH_BACK
else:
sys.exit(1)
-
# package/group selection doesn't apply for this backend
def groupExists(self, group):
diff --git a/network.py b/network.py
index af6d858f7..3531de999 100644
--- a/network.py
+++ b/network.py
@@ -585,8 +585,8 @@ class Network:
# tell NM not to touch the interface(s) actually used for /, but we
# have no logic to determine that
if anaconda is not None:
- rootdev = anaconda.id.fsset.getEntryByMountPoint("/").device
- if rootdev.isNetdev():
+ rootdev = anaconda.id.storage.fsset.rootDevice
+ if rootdev.isNetdev:
f.write("NM_CONTROLLED=no\n")
f.close()
diff --git a/packages.py b/packages.py
index f871c49f8..b34725a73 100644
--- a/packages.py
+++ b/packages.py
@@ -107,19 +107,6 @@ def doMigrateFilesystems(anaconda):
bindMountDevDirectory(anaconda.rootPath)
def turnOnFilesystems(anaconda):
- def handleResizeError(e, dev):
- if os.path.exists("/tmp/resize.out"):
- details = open("/tmp/resize.out", "r").read()
- else:
- details = "%s" %(e,)
- anaconda.intf.detailedMessageWindow(_("Resizing Failed"),
- _("There was an error encountered "
- "resizing the device %s.") %(dev,),
- details,
- type = "custom",
- custom_buttons = [_("_Exit installer")])
- sys.exit(1)
-
if anaconda.dir == DISPATCH_BACK:
log.info("unmounting filesystems")
anaconda.id.fsset.umountFilesystems(anaconda.rootPath)
@@ -133,53 +120,87 @@ def turnOnFilesystems(anaconda):
iutil.execWithRedirect("swapoff", ["-a"],
stdout = "/dev/tty5", stderr="/dev/tty5",
searchPath = 1)
- anaconda.id.partitions.doMetaDeletes(anaconda.id.diskset)
- anaconda.id.fsset.setActive(anaconda.id.diskset, anaconda.id.partitions.requests)
- try:
- anaconda.id.fsset.shrinkFilesystems(anaconda.id.diskset, anaconda.rootPath)
- except fsset.ResizeError, (e, dev):
- handleResizeError(e, dev)
- if not anaconda.id.fsset.isActive():
- anaconda.id.diskset.savePartitions ()
- # this is somewhat lame, but we seem to be racing with
- # device node creation sometimes. so wait for device nodes
- # to settle
- time.sleep(1)
- w = anaconda.intf.waitWindow(_("Activating"), _("Activating new partitions. Please wait..."))
- rc = iutil.execWithRedirect("/sbin/udevadm", [ "settle" ],
- stdout = "/dev/tty5",
- stderr = "/dev/tty5",
- searchPath = 1)
- w.pop()
-
- anaconda.id.partitions.doEncryptionRetrofits()
-
- try:
- anaconda.id.partitions.doMetaResizes(anaconda.id.diskset)
- except lvm.LVResizeError, e:
- handleResizeError("%s" %(e,), "%s/%s" %(e.vgname, e.lvname))
try:
- anaconda.id.fsset.growFilesystems(anaconda.id.diskset, anaconda.rootPath)
- except fsset.ResizeError, (e, dev):
- handleResizeError(e, dev)
-
- if not anaconda.id.fsset.volumesCreated:
- try:
- anaconda.id.fsset.createLogicalVolumes(anaconda.rootPath)
- except SystemError, e:
- log.error("createLogicalVolumes failed with %s", str(e))
- anaconda.intf.messageWindow(_("LVM operation failed"),
- str(e)+"\n\n"+_("The installer will now exit..."),
- type="custom", custom_icon="error", custom_buttons=[_("_Reboot")])
- sys.exit(0)
-
- anaconda.id.fsset.formatSwap(anaconda.rootPath)
- anaconda.id.fsset.turnOnSwap(anaconda.rootPath)
- anaconda.id.fsset.makeFilesystems(anaconda.rootPath,
- anaconda.backend.skipFormatRoot)
- anaconda.id.fsset.mountFilesystems(anaconda,0,0,
- anaconda.backend.skipFormatRoot)
+ anaconda.id.storage.processActions(anaconda.intf)
+ except DeviceResizeError as (msg, device):
+ # XXX does this make any sense? do we support resize of
+ # devices other than partitions?
+ anaconda.intf.detailedMessageWindow(_("Device Resize Failed"),
+ _("An error was encountered while "
+ "resizing device %s.") % (device,),
+ msg,
+ type = "custom",
+ custom_buttons = [_("_Exit installer")])
+ sys.exit(1)
+ except DeviceCreateError as (msg, device):
+ anaconda.intf.detailedMessageWindow(_("Device Creation Failed"),
+ _("An error was encountered while "
+ "creating device %s.") % (device,),
+ msg,
+ type = "custom",
+ custom_buttons = [_("_Exit installer")])
+ sys.exit(1)
+ except DeviceDestroyError as (msg, device):
+ anaconda.intf.detailedMessageWindow(_("Device Removal Failed"),
+ _("An error was encountered while "
+ "removing device %s.") % (device,),
+ msg,
+ type = "custom",
+ custom_buttons = [_("_Exit installer")])
+ sys.exit(1)
+ except DeviceError as (msg, device):
+ anaconda.intf.detailedMessageWindow(_("Device Setup Failed"),
+ _("An error was encountered while "
+ "setting up device %s.") % (device,),
+ msg,
+ type = "custom",
+ custom_buttons = [_("_Exit installer")])
+ sys.exit(1)
+ except FSResizeError as (msg, device):
+ if os.path.exists("/tmp/resize.out"):
+ details = open("/tmp/resize.out", "r").read()
+ else:
+ details = "%s" %(msg,)
+ anaconda.intf.detailedMessageWindow(_("Resizing Failed"),
+ _("There was an error encountered while "
+ "resizing the device %s.") %(device,),
+ details,
+ type = "custom",
+ custom_buttons = [_("_Exit installer")])
+ sys.exit(1)
+ except FSMigrateError as (msg, device):
+ anaconda.intf.detailedMessageWindow(_("Migration Failed"),
+ _("An error was encountered while "
+ "migrating filesystem on device %s.")
+ % (device,),
+ msg,
+ type = "custom",
+ custom_buttons = [_("_Exit installer")])
+ sys.exit(1)
+ except FormatCreateError as (msg, device):
+ anaconda.intf.detailedMessageWindow(_("Formatting Failed"),
+ _("An error was encountered while "
+ "formatting device %s.") % (device,),
+ msg,
+ type = "custom",
+ custom_buttons = [_("_Exit installer")])
+ sys.exit(1)
+ except Exception as msg:
+ # catch-all
+ anaconda.intf.detailedMessageWindow(_("Storage Activation Failed"),
+ _("An error was encountered while "
+ "activating your storage configuration.")
+ msg,
+ type = "custom",
+ custom_buttons = [_("_Exit installer")])
+ sys.exit(1)
+
+ anaconda.id.fsset.turnOnSwap(anaconda.intf)
+ anaconda.id.storage.fsset.mountFilesystems(anaconda,
+ raiseErrors=False,
+ readOnly=False,
+ skipRoot=anaconda.backend.skipFormatRoot)
def setupTimezone(anaconda):
# we don't need this on an upgrade or going backwards
diff --git a/rescue.py b/rescue.py
index 42e5b960c..3006971a8 100644
--- a/rescue.py
+++ b/rescue.py
@@ -29,8 +29,8 @@ from flags import flags
import sys
import os
import isys
+from storage import mountExistingSystem
import iutil
-import fsset
import shutil
import time
import network
@@ -101,14 +101,17 @@ class RescueInterface:
# XXX grub-install is stupid and uses df output to figure out
# things when installing grub. make /etc/mtab be at least
# moderately useful.
-def makeMtab(instPath, theFsset):
- child = os.fork()
- if (not child):
- os.chroot(instPath)
+def makeMtab(instPath, fsset):
+ try:
f = open("/etc/mtab", "w+")
- f.write(theFsset.mtab())
+ except IOError, e:
+ log.info("failed to open /etc/mtab for write: %s" % e)
+ return
+
+ try:
+ f.write(fsset.mtab())
+ finally:
f.close()
- os._exit(0)
# make sure they have a resolv.conf in the chroot
def makeResolvConf(instPath):
@@ -265,17 +268,14 @@ def runRescue(anaconda, instClass):
else:
scroll = 0
- partList = []
- for (drive, fs, relstr, label, uuid) in disks:
- if label:
- partList.append("%s (%s)" % (drive, label))
- else:
- partList.append(drive)
+ devList = []
+ for (device, relstr) in disks:
+ devList.append(device.path)
(button, choice) = \
ListboxChoiceWindow(screen, _("System to Rescue"),
- _("What partition holds the root partition "
- "of your installation?"), partList,
+ _("Which device holds the root partition "
+ "of your installation?"), devList,
[ _("OK"), _("Exit") ], width = 30,
scroll = scroll, height = height,
help = "multipleroot")
@@ -283,19 +283,15 @@ def runRescue(anaconda, instClass):
if button == string.lower (_("Exit")):
root = None
else:
- root = disks[choice]
+ root = disks[choice][0]
rootmounted = 0
if root:
try:
- fs = fsset.FileSystemSet()
-
- # only pass first two parts of tuple for root, since third
- # element is a comment we dont want
- rc = upgrade.mountRootPartition(anaconda, root[:2], fs,
- allowDirty = 1, warnDirty = 1,
- readOnly = readOnly)
+ rc = mountExistingSystem(anaconda, root,
+ allowDirty = 1, warnDirty = 1,
+ readOnly = readOnly)
if rc == -1:
if anaconda.isKickstart:
@@ -325,7 +321,7 @@ def runRescue(anaconda, instClass):
# now turn on swap
if not readOnly:
try:
- fs.turnOnSwap("/")
+ anaconda.id.storage.fsset.turnOnSwap(anaconda.intf)
except:
log.error("Error enabling swap")
@@ -412,7 +408,7 @@ def runRescue(anaconda, instClass):
msgStr = ""
if rootmounted and not readOnly:
- makeMtab(anaconda.rootPath, fs)
+ makeMtab(anaconda.rootPath, anaconda.id.storage.fsset)
try:
makeResolvConf(anaconda.rootPath)
except Exception, e:
diff --git a/upgrade.py b/upgrade.py
index a554d3bbe..98979b836 100644
--- a/upgrade.py
+++ b/upgrade.py
@@ -26,14 +26,13 @@ import iutil
import time
import sys
import os.path
-import partedUtils
import string
import selinux
-import lvm
from flags import flags
-from fsset import *
from constants import *
from product import productName
+from storage import findExistingRootDevices, FSSet
+from storage.formats import getFormat
import rhpl
import rhpl.arch
@@ -134,11 +133,8 @@ def findRootParts(anaconda):
root_device=anaconda.id.ksdata.upgrade.root_device
anaconda.id.upgradeRoot = []
- for (dev, fs, meta, label, uuid) in anaconda.id.rootParts:
- if (root_device is not None) and ((dev == root_device) or (("UUID=%s" % uuid) == root_device) or (("LABEL=%s" % label) == root_device)):
- anaconda.id.upgradeRoot.append( (dev, fs) )
- else:
- anaconda.id.upgradeRoot.append( (dev, fs) )
+ for (dev, label) in anaconda.id.rootParts:
+ anaconda.id.upgradeRoot.append( (dev, fs) )
if anaconda.id.rootParts is not None and len(anaconda.id.rootParts) > 0:
anaconda.dispatch.skipStep("findinstall", skip = 0)
@@ -149,111 +145,19 @@ def findRootParts(anaconda):
anaconda.dispatch.skipStep("installtype", skip = 0)
def findExistingRoots(anaconda, upgradeany = 0):
- # make ibft configured iscsi disks available
- anaconda.id.iscsi.startup(anaconda.intf)
-
if not flags.setupFilesystems:
(prod, ver) = partedUtils.getReleaseString (anaconda.rootPath)
if flags.cmdline.has_key("upgradeany") or upgradeany == 1 or anaconda.id.instClass.productUpgradable(prod, ver):
- return [(anaconda.rootPath, 'ext2', "")]
+ return [(anaconda.rootPath, "")]
return []
- anaconda.id.diskset.openDevices()
- anaconda.id.partitions.getEncryptedDevices(anaconda.id.diskset)
- rootparts = anaconda.id.diskset.findExistingRootPartitions(upgradeany = upgradeany)
-
- # close the devices to make sure we don't leave things sitting open
- anaconda.id.diskset.closeDevices()
-
- # this is a hack... need to clear the skipped disk list after this
- partedUtils.DiskSet.skippedDisks = []
- partedUtils.DiskSet.exclusiveDisks = []
-
return rootparts
-def getDirtyDevString(dirtyDevs):
- ret = ""
- for dev in dirtyDevs:
- if dev != "loop":
- ret = "/dev/%s\n" % (dev,)
- else:
- ret = "%s\n" % (dev,)
- return ret
-
-def mountRootPartition(anaconda, rootInfo, oldfsset, allowDirty = 0,
- warnDirty = 0, readOnly = 0):
- (root, rootFs) = rootInfo
- bindMount = 0
-
- encryptedDevices = anaconda.id.partitions.encryptedDevices
- diskset = partedUtils.DiskSet(anaconda)
- diskset.openDevices()
- for cryptoDev in encryptedDevices.values():
- cryptoDev.openDevice()
- diskset.startMPath()
- diskset.startDmRaid()
- diskset.startMdRaid()
- for cryptoDev in encryptedDevices.values():
- cryptoDev.openDevice()
- lvm.vgscan()
- lvm.vgactivate()
- for cryptoDev in encryptedDevices.values():
- cryptoDev.openDevice()
-
- if root in anaconda.id.partitions.protectedPartitions() and os.path.ismount("/mnt/isodir"):
- root = "/mnt/isodir"
- bindMount = 1
-
- log.info("going to mount %s on %s as %s" %(root, anaconda.rootPath, rootFs))
- isys.mount(root, anaconda.rootPath, rootFs, bindMount=bindMount)
-
- oldfsset.reset()
- newfsset = readFstab(anaconda)
-
- for entry in newfsset.entries:
- oldfsset.add(entry)
-
- if not bindMount:
- isys.umount(anaconda.rootPath)
-
- dirtyDevs = oldfsset.hasDirtyFilesystems(anaconda.rootPath)
- if not allowDirty and dirtyDevs != []:
- lvm.vgdeactivate()
- diskset.stopMdRaid()
- diskset.stopDmRaid()
- diskset.stopMPath()
- anaconda.intf.messageWindow(_("Dirty File Systems"),
- _("The following file systems for your Linux system "
- "were not unmounted cleanly. Please boot your "
- "Linux installation, let the file systems be "
- "checked and shut down cleanly to upgrade.\n"
- "%s" %(getDirtyDevString(dirtyDevs),)))
- sys.exit(0)
- elif warnDirty and dirtyDevs != []:
- rc = anaconda.intf.messageWindow(_("Dirty File Systems"),
- _("The following file systems for your Linux "
- "system were not unmounted cleanly. Would "
- "you like to mount them anyway?\n"
- "%s" % (getDirtyDevString(dirtyDevs,))),
- type = "yesno")
- if rc == 0:
- return -1
-
- if flags.setupFilesystems:
- for dev, crypto in encryptedDevices.items():
- if crypto.openDevice():
- log.error("failed to open encrypted device %s" % (dev,))
-
- oldfsset.mountFilesystems(anaconda, readOnly = readOnly,
- skiprootfs = bindMount)
-
- rootEntry = oldfsset.getEntryByMountPoint("/")
- if (not rootEntry or not rootEntry.fsystem or not rootEntry.fsystem.isMountable()):
- raise RuntimeError, "/etc/fstab did not list a fstype for the root partition which we support"
-
def bindMountDevDirectory(instPath):
- fs = fileSystemTypeGet("bind")
- fs.mount("/dev", "/dev", bindMount=1, instroot=instPath)
+ getFormat("bind",
+ device="/dev",
+ mountpoint="/dev",
+ exists=True).mount(chroot=instPath)
# returns None if no filesystem exist to migrate
def upgradeMigrateFind(anaconda):
@@ -295,13 +199,15 @@ def upgradeSwapSuggestion(anaconda):
fsList = []
- for entry in anaconda.id.fsset.entries:
- if entry.fsystem.getName() in getUsableLinuxFs():
- if flags.setupFilesystems and not entry.isMounted():
+ for device in anaconda.id.fsset.devices:
+ if not device.format:
+ continue
+ if device.format.mountable and device.format.linuxNative:
+ if flags.setupFilesystems and not device.format.status:
continue
- space = isys.pathSpaceAvailable(anaconda.rootPath + entry.mountpoint)
+ space = isys.pathSpaceAvailable(anaconda.rootPath + device.format.mountpoint)
if space > 16:
- info = (entry.mountpoint, entry.device.getDevice(), space)
+ info = (device, space)
fsList.append(info)
suggestion = mem * 2 - swap
@@ -311,57 +217,11 @@ def upgradeSwapSuggestion(anaconda):
suggestion = 32
suggSize = 0
suggMnt = None
- for (mnt, part, size) in fsList:
+ for (device, size) in fsList:
if (size > suggSize) and (size > (suggestion + 100)):
- suggMnt = mnt
-
- anaconda.id.upgradeSwapInfo = (fsList, suggestion, suggMnt)
-
-def swapfileExists(swapname):
- try:
- os.lstat(swapname)
- return 1
- except:
- return 0
+ suggDev = device
-def createSwapFile(instPath, theFsset, mntPoint, size):
- fstabPath = instPath + "/etc/fstab"
- prefix = ""
-
- if mntPoint != "/":
- file = mntPoint + "/SWAP"
- else:
- file = "/SWAP"
-
- swapFileDict = {}
- for entry in theFsset.entries:
- if entry.fsystem.getName() == "swap":
- swapFileDict[entry.device.getName()] = 1
-
- count = 0
- while (swapfileExists(instPath + file) or
- swapFileDict.has_key(file)):
- count = count + 1
- tmpFile = "/SWAP-%d" % (count)
- if mntPoint != "/":
- file = mntPoint + tmpFile
- else:
- file = tmpFile
-
- device = SwapFileDevice(file)
- device.setSize(size)
- fsystem = fileSystemTypeGet("swap")
- entry = FileSystemSetEntry(device, "swap", fsystem)
- entry.setFormat(1)
- theFsset.add(entry)
- theFsset.formatEntry(entry, instPath)
- theFsset.turnOnSwap(instPath, upgrading=True)
-
- # XXX generalize fstab modification
- f = open(fstabPath, "a")
- format = "%-23s %-23s %-7s %-15s %d %d\n";
- f.write(format % (prefix + file, "swap", "swap", "defaults", 0, 0))
- f.close()
+ anaconda.id.upgradeSwapInfo = (fsList, suggestion, suggDev)
# XXX handle going backwards
def upgradeMountFilesystems(anaconda):
@@ -369,21 +229,15 @@ def upgradeMountFilesystems(anaconda):
if flags.setupFilesystems:
try:
- mountRootPartition(anaconda, anaconda.id.upgradeRoot[0], anaconda.id.fsset,
- allowDirty = 0)
- except SystemError:
+ mountExistingSystem(anaconda,
+ anaconda.id.upgradeRoot[0],
+ allowDirty = 0)
+ except Exception:
anaconda.intf.messageWindow(_("Mount failed"),
_("One or more of the file systems listed in the "
"/etc/fstab on your Linux system cannot be mounted. "
"Please fix this problem and try to upgrade again."))
sys.exit(0)
- except RuntimeError:
- anaconda.intf.messageWindow(_("Mount failed"),
- _("One or more of the file systems listed in the "
- "/etc/fstab of your Linux system are inconsistent and "
- "cannot be mounted. Please fix this problem and try to "
- "upgrade again."))
- sys.exit(0)
checkLinks = ( '/etc', '/var', '/var/lib', '/var/lib/rpm',
'/boot', '/tmp', '/var/tmp', '/root',
@@ -430,15 +284,11 @@ def upgradeMountFilesystems(anaconda):
% (anaconda.rootPath + "/etc/fstab",),
type="ok")
return DISPATCH_BACK
-
- newfsset = readFstab(anaconda)
- for entry in newfsset.entries:
- anaconda.id.fsset.add(entry)
+
+ anaconda.id.storage.fsset.parseFSTab(chroot=anaconda.rootPath)
if flags.setupFilesystems:
- if iutil.isPPC():
- anaconda.id.fsset.formatSwap(anaconda.rootPath, forceFormat=True)
- anaconda.id.fsset.turnOnSwap(anaconda.rootPath, upgrading=True)
- anaconda.id.fsset.mkDevRoot(anaconda.rootPath)
+ anaconda.id.storage.fsset.turnOnSwap(upgrading=True)
+ anaconda.id.storage.fsset.mkDevRoot(anaconda.rootPath)
# if they've been booting with selinux disabled, then we should
# disable it during the install as well (#242510)
@@ -458,9 +308,9 @@ def setSteps(anaconda):
"keyboard",
"welcome",
"installtype",
+ "storageinit",
"findrootparts",
"findinstall",
- "partitionobjinit",
"upgrademount",
"upgrademigfind",
"upgrademigratefs",
@@ -473,7 +323,6 @@ def setSteps(anaconda):
"confirmupgrade",
"postselection",
"install",
- "migratefilesystems",
"preinstallconfig",
"installpackages",
"postinstallconfig",
diff --git a/yuminstall.py b/yuminstall.py
index 2d63dac5d..68fd5a191 100644
--- a/yuminstall.py
+++ b/yuminstall.py
@@ -1293,26 +1293,18 @@ reposdir=/etc/anaconda.repos.d,/tmp/updates/anaconda.repos.d,/tmp/product/anacon
elif iutil.isIA64():
self.selectPackage("elilo")
- def selectFSPackages(self, fsset, diskset):
- for entry in fsset.entries:
- map(self.selectPackage, entry.fsystem.getNeededPackages())
- if entry.device.crypto:
- self.selectPackage("cryptsetup-luks")
-
- for disk in diskset.disks.keys():
- if isys.driveIsIscsi(disk):
+ def selectFSPackages(self, storage):
+ for device in storage.fsset.devices:
+ # this takes care of device and filesystem packages
+ map(self.selectPackage, device.packages)
+
+ for disk in storage.disks:
+ # FIXME: this should get handled by the above
+ if isys.driveIsIscsi(disk.path):
log.info("ensuring iscsi is installed")
self.selectPackage("iscsi-initiator-utils")
break
- if diskset.__class__.mpList:
- log.info("ensuring device-mapper-multipath is installed")
- self.selectPackage("device-mapper-multipath")
- if diskset.__class__.dmList:
- log.info("ensuring dmraid is installed")
- self.selectPackage("dmraid")
-
-
# anaconda requires several programs on the installed system to complete
# installation, but we have no guarantees that some of these will be
# installed (they could have been removed in kickstart). So we'll force
@@ -1335,7 +1327,7 @@ reposdir=/etc/anaconda.repos.d,/tmp/updates/anaconda.repos.d,/tmp/product/anacon
# New installs only - upgrades will already have all this stuff.
self.selectBestKernel(anaconda)
self.selectBootloader()
- self.selectFSPackages(anaconda.id.fsset, anaconda.id.diskset)
+ self.selectFSPackages(anaconda.id.storage)
self.selectAnacondaNeeds()
if anaconda.id.getUpgrade():