]> git.ipfire.org Git - ipfire-3.x.git/commitdiff
Daily checkin.
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 24 May 2009 15:44:29 +0000 (17:44 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 30 Jul 2009 18:28:07 +0000 (20:28 +0200)
26 files changed:
src/pomona/Makefile
src/pomona/dispatch.py
src/pomona/isys/Makefile [new file with mode: 0644]
src/pomona/isys/isys.c [new file with mode: 0644]
src/pomona/isys/isys.h [new file with mode: 0644]
src/pomona/isys/isys.py [new file with mode: 0644]
src/pomona/isys/mount.c [new file with mode: 0644]
src/pomona/isys/mount.h [new file with mode: 0644]
src/pomona/partition.py
src/pomona/storage/devicelibs/swap.py [new file with mode: 0644]
src/pomona/storage/formats/__init__.py
src/pomona/storage/formats/fs.py
src/pomona/storage_old/__init__.py [deleted file]
src/pomona/storage_old/deviceaction.py [deleted file]
src/pomona/storage_old/devicelibs/__init__.py [deleted file]
src/pomona/storage_old/devicelibs/lvm.py [deleted file]
src/pomona/storage_old/devices.py [deleted file]
src/pomona/storage_old/devicetree.py [deleted file]
src/pomona/storage_old/devicetree.py_old [deleted file]
src/pomona/storage_old/errors.py [deleted file]
src/pomona/storage_old/formats/__init__.py [deleted file]
src/pomona/storage_old/formats/fs.py [deleted file]
src/pomona/storage_old/formats/lvmpv.py [deleted file]
src/pomona/storage_old/formats/swap.py [deleted file]
src/pomona/storage_old/partitioning.py [deleted file]
src/pomona/storage_old/udev.py [deleted file]

index 6c7bba017cc8adba8e48959970d8e89991f9dcba..41c9fc4f8d7c0cf810894f2e9b9dccc78af01dab 100644 (file)
@@ -20,7 +20,7 @@
 
 include Makefile.inc
 
-SUBDIRS = po
+SUBDIRS = isys po
 
 all: subdirs
 
index 9f10fc1c3eff72783feaa8e75ecd26407291d35f..4bf132601d806c1326a5899720591bf2793c3791 100644 (file)
@@ -7,16 +7,16 @@ from constants import *
 from windows import *
 
 installSteps = [
-                ("welcome",       welcomeWindow,),
-                ("experimental",  experimentalWindow,),
-                ("console",       [ "LanguageWindow", "KeyboardWindow",]),
+                #("welcome",       welcomeWindow,),
+                #("experimental",  experimentalWindow,),
+                #("console",       [ "LanguageWindow", "KeyboardWindow",]),
                 ("storage",       storageInitialize,),
                 ("partmethod",    partmethodWindow,),
-                ("autopartition", autopartitionWindow,),
-                ("autopartitionexecute", doAutoPartition,),
+                #("autopartition", autopartitionWindow,),
+                #("autopartitionexecute", doAutoPartition,),
                 ("partition",     [ "PartitionWindow",]),
-                ("bootloader",    bootloaderWindow,),
-                ("complete",      finishedWindow,),
+                #("bootloader",    bootloaderWindow,),
+                #("complete",      finishedWindow,),
                ]
 
 
diff --git a/src/pomona/isys/Makefile b/src/pomona/isys/Makefile
new file mode 100644 (file)
index 0000000..680ae05
--- /dev/null
@@ -0,0 +1,51 @@
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2008  Michael Tremer & Christian Schmidt                      #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+include ../Makefile.inc
+
+OBJECTS = isys.o mount.o
+
+CFLAGS += -I$(PYTHONINCLUDE)
+LDFLAGS =
+LIBS =
+
+all: depend _isys.so
+
+depend: $(patsubst %.o,%.c,$(OBJECTS))
+       $(CPP) -M $(CFLAGS) $(patsubst %.o,%.c,$(OBJECTS)) > depend
+
+%.o: %.c
+       $(CC) -c $(CFLAGS) -o $@ $<
+
+_isys.so: $(OBJECTS)
+       $(CC) -shared $(CFLAGS) $(LDFLAGS) $(LIBS) -o $@ $(OBJECTS)
+
+install: _isys.so isys.py
+       cp -vf _isys.so isys.py $(PYTHONLIBDIR)
+
+clean:
+       rm -vf $(OBJECTS) depend _isys.so *.py[co]
+
+test: _isys.so
+       python -c "import isys"
+
+ifeq (depend,$(wildcard depend))
+include depend
+endif
diff --git a/src/pomona/isys/isys.c b/src/pomona/isys/isys.c
new file mode 100644 (file)
index 0000000..08684fa
--- /dev/null
@@ -0,0 +1,62 @@
+
+
+#include <Python.h>
+
+#include "isys.h"
+#include "mount.h"
+
+
+static PyObject * doMount(PyObject * s, PyObject * args);
+static PyObject * doUMount(PyObject * s, PyObject * args);
+
+static PyMethodDef isysModuleMethods[] = {
+    { "mount", (PyCFunction) doMount, METH_VARARGS, NULL },
+    { "umount", (PyCFunction) doUMount, METH_VARARGS, NULL },
+};
+
+void init_isys(void) {
+    PyObject * m, * d;
+
+    m = Py_InitModule("_isys", isysModuleMethods);
+    d = PyModule_GetDict(m);
+}
+
+static PyObject * doMount(PyObject * s, PyObject * args) {
+    char *err = NULL, *fs, *device, *mntpoint, *flags = NULL;
+    int rc;
+
+    if (!PyArg_ParseTuple(args, "sss|z", &fs, &device, &mntpoint,
+                         &flags)) return NULL;
+
+    rc = doPwMount(device, mntpoint, fs, flags, &err);
+    if (rc == MOUNT_ERR_ERRNO)
+        PyErr_SetFromErrno(PyExc_SystemError);
+    else if (rc) {
+        PyObject *tuple = PyTuple_New(2);
+
+        PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc));
+        PyTuple_SetItem(tuple, 1, PyString_FromString(err));
+        PyErr_SetObject(PyExc_SystemError, tuple);
+    }
+
+    if (rc)
+        return NULL;
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject * doUMount(PyObject * s, PyObject * args) {
+    char * fs;
+
+    if (!PyArg_ParseTuple(args, "s", &fs))
+        return NULL;
+
+    if (umount(fs)) {
+          PyErr_SetFromErrno(PyExc_SystemError);
+          return NULL;
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
diff --git a/src/pomona/isys/isys.h b/src/pomona/isys/isys.h
new file mode 100644 (file)
index 0000000..4757e4c
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef H_ISYS
+#define H_ISYS
+
+
+#endif
diff --git a/src/pomona/isys/isys.py b/src/pomona/isys/isys.py
new file mode 100644 (file)
index 0000000..ffc2c97
--- /dev/null
@@ -0,0 +1,79 @@
+#!/usr/bin/python
+
+import _isys
+
+import os
+import string
+
+mountCount = {}
+
+## Mount a filesystem, similar to the mount system call.
+# @param device The device to mount.  If bindMount is 1, this should be an
+#               already mounted directory.  Otherwise, it should be a device
+#               name.
+# @param location The path to mount device on.
+# @param fstype The filesystem type on device.  This can be disk filesystems
+#               such as vfat or ext3, or pseudo filesystems such as proc or
+#               selinuxfs.
+# @param readOnly Should this filesystem be mounted readonly?
+# @param bindMount Is this a bind mount?  (see the mount(8) man page)
+# @param remount Are we mounting an already mounted filesystem?
+# @return The return value from the mount system call.
+def mount(device, location, fstype = "ext2", readOnly = 0, bindMount = 0, remount = 0, options = "defaults"):
+    flags = None
+    location = os.path.normpath(location)
+    opts = string.split(options)
+
+    # We don't need to create device nodes for devices that start with '/'
+    # (like '/usbdevfs') and also some special fake devices like 'proc'.
+    # First try to make a device node and if that fails, assume we can
+    # mount without making a device node.  If that still fails, the caller
+    # will have to deal with the exception.
+    # We note whether or not we created a node so we can clean up later.
+
+    if mountCount.has_key(location) and mountCount[location] > 0:
+        mountCount[location] = mountCount[location] + 1
+        return
+
+    if readOnly or bindMount or remount:
+        if readOnly:
+            opts.append("ro")
+        if bindMount:
+            opts.append("bind")
+        if remount:
+            opts.append("remount")
+
+    flags = ",".join(opts)
+
+    #log.debug("isys.py:mount()- going to mount %s on %s with options %s" %(device, location, flags))
+    rc = _isys.mount(fstype, device, location, flags)
+
+    if not rc:
+        mountCount[location] = 1
+
+    return rc
+
+## Unmount a filesystem, similar to the umount system call.
+# @param what The directory to be unmounted.  This does not need to be the
+#             absolute path.
+# @param removeDir Should the mount point be removed after being unmounted?
+# @return The return value from the umount system call.
+def umount(what, removeDir = 1):
+    what = os.path.normpath(what)
+
+    if not os.path.isdir(what):
+        raise ValueError, "isys.umount() can only umount by mount point"
+
+    if mountCount.has_key(what) and mountCount[what] > 1:
+        mountCount[what] = mountCount[what] - 1
+        return
+
+    rc = _isys.umount(what)
+
+    if removeDir and os.path.isdir(what):
+        os.rmdir(what)
+
+    if not rc and mountCount.has_key(what):
+        del mountCount[what]
+
+    return rc
diff --git a/src/pomona/isys/mount.c b/src/pomona/isys/mount.c
new file mode 100644 (file)
index 0000000..6b0f175
--- /dev/null
@@ -0,0 +1,186 @@
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "mount.h"
+
+static int mkdirIfNone(char * directory);
+
+static int readFD(int fd, char **buf) {
+    char *p;
+    size_t size = 4096;
+    int s, filesize = 0;
+
+    *buf = calloc(4096, sizeof (char));
+    if (*buf == NULL)
+        abort();
+
+    do {
+        p = &(*buf)[filesize];
+        s = read(fd, p, 4096);
+        if (s < 0)
+            break;
+
+        filesize += s;
+        if (s == 0)
+           break;
+
+        size += s;
+        *buf = realloc(*buf, size);
+        if (*buf == NULL)
+            abort();
+    } while (1);
+
+    if (filesize == 0 && s < 0) {
+        free(*buf);
+        *buf = NULL;
+        return -1;
+    }
+
+    return filesize;
+}
+
+int doPwMount(char *dev, char *where, char *fs, char *options, char **err) {
+    int rc, child, status, pipefd[2];
+    char *opts = NULL, *device;
+    
+    if (mkdirChain(where))
+        return MOUNT_ERR_ERRNO;
+
+    if (strstr(fs, "nfs")) {
+        if (options) {
+            if (asprintf(&opts, "%s,nolock", options) == -1) {
+                fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
+                        strerror(errno));
+                fflush(stderr);
+                abort();
+            }
+        } else {
+            opts = strdup("nolock");
+        }
+        device = strdup(dev);
+    } else {
+        if ((options && strstr(options, "bind") == NULL) &&
+            strncmp(dev, "LABEL=", 6) && strncmp(dev, "UUID=", 5) &&
+            *dev != '/') {
+           if (asprintf(&device, "/dev/%s", dev) == -1) {
+               fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__,
+                       strerror(errno));
+               fflush(stderr);
+               abort();
+           }
+        } else {
+           device = strdup(dev);
+        }
+        if (options)
+            opts = strdup(options);
+    }
+
+    if (pipe(pipefd))
+        return MOUNT_ERR_ERRNO;
+
+    if (!(child = fork())) {
+        int fd;
+
+        close(pipefd[0]);
+
+        /* Close stdin entirely, redirect stdout to tty5, and redirect stderr
+         * to a pipe so we can put error messages into exceptions.  We'll
+         * only use these messages should mount also return an error code.
+         */
+        fd = open("/dev/tty5", O_RDONLY);
+        close(STDIN_FILENO);
+        dup2(fd, STDIN_FILENO);
+        close(fd);
+
+        fd = open("/dev/tty5", O_WRONLY);
+        close(STDOUT_FILENO);
+        dup2(fd, STDOUT_FILENO);
+
+        dup2(pipefd[1], STDERR_FILENO);
+
+        if (opts) {
+            rc = execl("/bin/mount",
+                       "/bin/mount", "-n", "-t", fs, "-o", opts, device, where, NULL);
+            exit(1);
+        }
+        else {
+            rc = execl("/bin/mount", "/bin/mount", "-n", "-t", fs, device, where, NULL);
+            exit(1);
+        }
+    }
+
+    close(pipefd[1]);
+
+    if (err != NULL)
+        rc = readFD(pipefd[0], err);
+
+    close(pipefd[0]);
+    waitpid(child, &status, 0);
+
+    free(opts);
+    free(device);
+    if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status)))
+       return MOUNT_ERR_OTHER;
+
+    return 0;
+}
+
+int mkdirChain(char * origChain) {
+    char * chain;
+    char * chptr;
+
+    chain = alloca(strlen(origChain) + 1);
+    strcpy(chain, origChain);
+    chptr = chain;
+
+    while ((chptr = strchr(chptr, '/'))) {
+        *chptr = '\0';
+        if (mkdirIfNone(chain)) {
+            *chptr = '/';
+            return MOUNT_ERR_ERRNO;
+        }
+    
+        *chptr = '/';
+        chptr++;
+    }
+
+    if (mkdirIfNone(chain))
+        return MOUNT_ERR_ERRNO;
+
+    return 0;
+}
+
+static int mkdirIfNone(char * directory) {
+    int rc, mkerr;
+    char * chptr;
+
+    /* If the file exists it *better* be a directory -- I'm not going to
+       actually check or anything */
+    if (!access(directory, X_OK))
+        return 0;
+
+    /* if the path is '/' we get ENOFILE not found" from mkdir, rather
+       then EEXIST which is weird */
+    for (chptr = directory; *chptr; chptr++)
+        if (*chptr != '/')
+            break;
+    if (!*chptr)
+        return 0;
+
+    rc = mkdir(directory, 0755);
+    mkerr = errno;
+
+    if (!rc || mkerr == EEXIST)
+        return 0;
+
+    return MOUNT_ERR_ERRNO;
+}
diff --git a/src/pomona/isys/mount.h b/src/pomona/isys/mount.h
new file mode 100644 (file)
index 0000000..b505322
--- /dev/null
@@ -0,0 +1,13 @@
+
+#ifndef H_MOUNT
+#define H_MOUNT
+
+#define MOUNT_ERR_ERRNO        1
+#define MOUNT_ERR_OTHER        2
+
+#include <sys/mount.h>         /* for umount() */
+
+int doPwMount(char *dev, char *where, char *fs, char *options, char **err);
+int mkdirChain(char * origChain);
+
+#endif
index 843dba8945090d51a90f7b83e370d31612c62e0b..1eaa4be3f8e7c5b0a44f222fefc494a14dc1757b 100644 (file)
@@ -53,7 +53,8 @@ class PartitionWindow(object):
                     if part.format:
                         type = part.format.name
                         try:
-                            mountpoint = part.format.mountpoint
+                            if part.format.mountpoint:
+                                mountpoint = part.format.mountpoint
                         except AttributeError:
                             pass
                     self.lb.append(["  %s" % part.name,
diff --git a/src/pomona/storage/devicelibs/swap.py b/src/pomona/storage/devicelibs/swap.py
new file mode 100644 (file)
index 0000000..6c45d7d
--- /dev/null
@@ -0,0 +1,85 @@
+import resource
+
+import util
+import os
+
+from ..errors import *
+
+import gettext
+_ = lambda x: gettext.ldgettext("pomona", x)
+
+def mkswap(device, label=''):
+    argv = []
+    if label:
+        argv.extend(["-L", label])
+    argv.append(device)
+
+    rc = util.execWithRedirect("mkswap", argv,
+                                stderr = "/dev/tty5",
+                                stdout = "/dev/tty5",
+                                searchPath=1)
+
+    if rc:
+        raise SwapError("mkswap failed for '%s'" % device)
+
+def swapon(device, priority=None):
+    pagesize = resource.getpagesize()
+    buf = None
+    if pagesize > 2048:
+        num = pagesize
+    else:
+        num = 2048
+
+    try:
+        fd = os.open(device, os.O_RDONLY)
+        buf = os.read(fd, num)
+    except OSError:
+        pass
+    finally:
+        try:
+            os.close(fd)
+        except (OSError, UnboundLocalError):
+            pass
+
+    if buf is not None and len(buf) == pagesize:
+        sig = buf[pagesize - 10:]
+        if sig == 'SWAP-SPACE':
+            raise OldSwapError
+        if sig == 'S1SUSPEND\x00' or sig == 'S2SUSPEND\x00':
+            raise SuspendError
+
+    argv = []
+    if isinstance(priority, int) and 0 <= priority <= 32767:
+        argv.extend(["-p", "%d" % priority])
+    argv.append(device)
+        
+    rc = util.execWithRedirect("swapon",
+                                argv,
+                                stderr = "/dev/tty5",
+                                stdout = "/dev/tty5",
+                                searchPath=1)
+
+    if rc:
+        raise SwapError("swapon failed for '%s'" % device)
+
+def swapoff(device):
+    rc = util.execWithRedirect("swapoff", [device],
+                                stderr = "/dev/tty5",
+                                stdout = "/dev/tty5",
+                                searchPath=1)
+
+    if rc:
+        raise SwapError("swapoff failed for '%s'" % device)
+
+def swapstatus(device):
+    lines = open("/proc/swaps").readlines()
+    status = False
+    for line in lines:
+        if not line.strip():
+            continue
+            
+        if line.split()[0] == device:
+            status = True
+            break
+
+    return status
index b8fd9bc43af376682b67b0b12754aa9a3ba500dc..b271c00a2980ce366b0ae865ee675d9914d4a801 100644 (file)
@@ -156,7 +156,7 @@ class DeviceFormat(object):
 
     def _setDevice(self, devspec):
         if devspec and not devspec.startswith("/"):
-            raise ValueError("device must be a fully qualified path")
+            raise ValueError("device must be a fully qualified path: %s" % devspec)
         self._device = devspec
 
     def _getDevice(self):
index d2e4071dd59b424554d0d492a66480470853c559..2eace6153aa8cc127c4e3d8d507ccef5649f1a18 100644 (file)
@@ -3,6 +3,8 @@
 import os
 import tempfile
 
+import isys
+
 import util
 
 from ..errors import *
diff --git a/src/pomona/storage_old/__init__.py b/src/pomona/storage_old/__init__.py
deleted file mode 100644 (file)
index 702e3be..0000000
+++ /dev/null
@@ -1,1133 +0,0 @@
-#/usr/bin/python
-
-import os
-import sys
-import time
-
-sys.path.append("/usr/src/src/pomona") # XXX
-
-import gettext
-_ = lambda x: gettext.ldgettext("pomona", x)
-
-from constants import *
-
-from devicetree import DeviceTree
-from devices import *
-from deviceaction import *
-from devicelibs.lvm import safeLvmName
-from udev import *
-import formats
-
-def storageInitialize(installer):
-    storage = installer.ds.storage
-
-    storage.shutdown()
-
-    if installer.dispatch.dir == DISPATCH_BACK:
-        return
-
-    # XXX I don't understand why I have to do this
-    udev_trigger(subsystem="block")
-
-    #XXX Determine our cdrom drive/usb key here and add it to protectedPartiotions
-    storage.reset()
-
-class Storage(object):
-    def __init__(self, installer, ignored=[], clear=[]):
-        self.installer = installer
-
-        self.doAutoPart = False
-        self.clearDisks = clear
-        self.ignoredDisks = ignored
-
-        self.encryptedAutoPart = False
-        self.encryptionPassphrase = None
-
-        self.autoPartitionRequests = []
-
-        self.devicetree = DeviceTree(self)
-        
-        self._nextID = 0
-
-    def shutdown(self):
-        try:
-            self.devicetree.teardownAll()
-        except Exception as e:
-            self.installer.log.error("Failure tearing down device tree: %s" % e)
-
-    def reset(self):
-        """ Reset storage configuration to reflect actual system state.
-
-            This should rescan from scratch but not clobber user-obtained
-            information like passphrases, &c
-        """
-        # save passphrases for luks devices so we don't have to reprompt
-        self.encryptionPassphrase = None
-        #for device in self.devices:
-        #    if device.format.type == "luks" and device.format.exists:
-        #        self.__luksDevs[device.format.uuid] = device.format._LUKS__passphrase
-
-        self.installer.window = self.installer.intf.waitWindow(_("Finding Devices"),
-                                    _("Finding storage devices..."))
-        self.devicetree = DeviceTree(self)
-        self.devicetree.populate()
-        self.fsset = FSSet(self.installer)
-        self.installer.window.pop()
-
-    @property
-    def nextID(self):
-        id = self._nextID
-        self._nextID += 1
-        return id
-
-    @property
-    def devices(self):
-        """ A list of all the devices in the device tree. """
-        devices = self.devicetree.devices.values()
-        devices.sort(key=lambda d: d.path)
-        return devices
-
-    @property
-    def disks(self):
-        """ A list of the disks in the device tree.
-
-            Ignored disks are not included, as are disks with no media present.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        disks = []
-        devices = self.devicetree.devices
-        for d in devices:
-            if isinstance(devices[d], DiskDevice) and devices[d].mediaPresent:
-                disks.append(devices[d])
-        disks.sort(key=lambda d: d.name)
-        return disks
-
-    @property
-    def partitions(self):
-        """ A list of the partitions in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        partitions = self.devicetree.getDevicesByInstance(PartitionDevice)
-        partitions.sort(key=lambda d: d.name)
-        return partitions
-
-    @property
-    def vgs(self):
-        """ A list of the LVM Volume Groups in the device tree.
-
-            This is based on the current state of the device tree and
-            does not necessarily reflect the actual on-disk state of the
-            system's disks.
-        """
-        vgs = self.devicetree.getDevicesByType("lvmvg")
-        vgs.sort(key=lambda d: d.name)
-        return vgs
-
-    def sanityCheck(self):
-        """ Run a series of tests to verify the storage configuration.
-
-            This function is called at the end of partitioning so that
-            we can make sure you don't have anything silly (like no /,
-            a really small /, etc).  Returns (errors, warnings) where
-            each is a list of strings.
-        """
-        checkSizes = [('/usr', 250), ('/tmp', 50), ('/var', 384),
-                      ('/home', 100), ('/boot', 75)]
-        warnings = []
-        errors = []
-
-        filesystems = self.fsset.mountpoints
-        root = self.fsset.rootDevice
-        swaps = self.fsset.swapDevices
-        #try:
-        #    boot = self.anaconda.platform.bootDevice()
-        #except DeviceError:
-        #    boot = None
-        boot = None
-
-        if not root:
-            errors.append(_("You have not defined a root partition (/), "
-                            "which is required for installation of %s "
-                            "to continue.") % (PRODUCT_NAME,))
-
-        if root and root.size < 250:
-            warnings.append(_("Your root partition is less than 250 "
-                              "megabytes which is usually too small to "
-                              "install %s.") % (PRODUCT_NAME,))
-
-        if (root and root.size < self.installer.backend.getMinimumSizeMB("/")):
-            errors.append(_("Your / partition is less than %s "
-                            "megabytes which is lower than recommended "
-                            "for a normal %s install.")
-                          %(self.installer.backend.getMinimumSizeMB("/"),
-                            PRODUCT_NAME))
-
-        # livecds have to have the rootfs type match up
-        #if (root and
-        #    self.installer.backend.rootFsType and
-        #    root.format.type != self.installer.backend.rootFsType):
-        #    errors.append(_("Your / partition does not match the "
-        #                    "the live image you are installing from.  "
-        #                    "It must be formatted as %s.")
-        #                  % (self.anaconda.backend.rootFsType,))
-
-        for (mount, size) in checkSizes:
-            if mount in filesystems and filesystems[mount].size < size:
-                warnings.append(_("Your %s partition is less than %s "
-                                  "megabytes which is lower than recommended "
-                                  "for a normal %s install.")
-                                %(mount, size, PRODUCT_NAME))
-
-        usb_disks = []
-        firewire_disks = []
-        #for disk in self.disks:
-        #    if isys.driveUsesModule(disk.name, ["usb-storage", "ub"]):
-        #        usb_disks.append(disk)
-        #    elif isys.driveUsesModule(disk.name, ["sbp2", "firewire-sbp2"]):
-        #        firewire_disks.append(disk)   
-
-        uses_usb = False
-        uses_firewire = False
-        for device in filesystems.values():
-            for disk in usb_disks:
-                if device.dependsOn(disk):
-                    uses_usb = True
-                    break
-
-            for disk in firewire_disks:
-                if device.dependsOn(disk):
-                    uses_firewire = True
-                    break
-
-        if uses_usb:
-            warnings.append(_("Installing on a USB device.  This may "
-                              "or may not produce a working system."))
-        if uses_firewire:
-            warnings.append(_("Installing on a FireWire device.  This may "
-                              "or may not produce a working system."))
-
-        if not boot:
-            errors.append(_("You have not created a boot partition."))
-
-        if (boot and boot.type == "mdarray" and
-            boot.level != 1):
-            errors.append(_("Bootable partitions can only be on RAID1 "
-                            "devices."))
-
-        # can't have bootable partition on LV
-        if boot and boot.type == "lvmlv":
-            errors.append(_("Bootable partitions cannot be on a "
-                            "logical volume."))
-
-        # most arches can't have boot on RAID
-        if boot and boot.type == "mdarray" and not self.anaconda.platform.supportsMdRaidBoot:
-            errors.append(_("Bootable partitions cannot be on a RAID "
-                            "device."))
-
-        # Lots of filesystems types don't support /boot.
-        if boot and not boot.format.bootable:
-            errors.append(_("Bootable partitions cannot be on an %s "
-                            "filesystem.") % boot.format.name)
-
-        # vfat /boot is insane.
-        if (boot and boot == root and boot.format.type == "vfat"):
-            errors.append(_("Bootable partitions cannot be on an %s "
-                            "filesystem.") % boot.format.type)
-
-        if (boot and filter(lambda d: d.type == "luks/dm-crypt",
-                            self.deviceDeps(boot))):
-            errors.append(_("Bootable partitions cannot be on an "
-                            "encrypted block device"))
-
-        if not swaps:
-            warnings.append(_("You have not specified a swap partition.  "
-                              "Although not strictly required in all cases, "
-                              "it will significantly improve performance for "
-                              "most installations."))
-
-        return (errors, warnings)
-
-    def checkNoDisks(self):
-        """Check that there are valid disk devices."""
-        if not self.disks:
-            self.installer.intf.messageWindow(_("No Drives Found"),
-                               _("An error has occurred - no valid devices were "
-                                 "found on which to create new file systems. "
-                                 "Please check your hardware for the cause "
-                                 "of this problem."))
-            return True
-        return False
-
-    def newPartition(self, *args, **kwargs):
-        """ Return a new PartitionDevice instance for configuring. """
-        if kwargs.has_key("fmt_type"):
-            kwargs["format"] = getFormat(self.installer, kwargs.pop("fmt_type"),
-                                         mountpoint=kwargs.pop("mountpoint", None))
-
-        if kwargs.has_key("disks"):
-            parents = kwargs.pop("disks")
-            if isinstance(parents, Device):
-                kwargs["parents"] = [parents]
-            else:
-                kwargs["parents"] = parents
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-        else:
-            name = "req%d" % self.nextID
-
-        return PartitionDevice(self.installer, name, *args, **kwargs)
-
-    def newVG(self, *args, **kwargs):
-        """ Return a new LVMVolumeGroupDevice instance. """
-        pvs = kwargs.pop("pvs", [])
-        for pv in pvs:
-            if pv not in self.devices:
-                raise ValueError("pv is not in the device tree")
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-        else:
-            # XXX name = self.createSuggestedVGName(self.anaconda.id.network)
-            name = self.createSuggestedVGName(None)
-
-        if name in [d.name for d in self.devices]:
-            raise ValueError("name already in use")
-
-        return LVMVolumeGroupDevice(self.installer, name, pvs, *args, **kwargs)
-
-    def newLV(self, *args, **kwargs):
-        """ Return a new LVMLogicalVolumeDevice instance. """
-        if kwargs.has_key("vg"):
-            vg = kwargs.pop("vg")
-
-        mountpoint = kwargs.pop("mountpoint", None)
-        if kwargs.has_key("fmt_type"):
-            kwargs["format"] = getFormat(kwargs.pop("fmt_type"),
-                                         mountpoint=mountpoint)
-
-        if kwargs.has_key("name"):
-            name = kwargs.pop("name")
-        else:
-            if kwargs.get("format") and kwargs["format"].type == "swap":
-                swap = True
-            else:
-                swap = False
-            name = self.createSuggestedLVName(vg,
-                                              swap=swap,
-                                              mountpoint=mountpoint)
-
-        if name in [d.name for d in self.devices]:
-            raise ValueError("name already in use")
-
-        return LVMLogicalVolumeDevice(self.installer, name, vg, *args, **kwargs)
-
-    def createSuggestedVGName(self, network):
-        """ Return a reasonable, unused VG name. """
-        # try to create a volume group name incorporating the hostname
-        #hn = network.hostname # XXX
-        hn = "ipfire.localdomain"
-        vgnames = [vg.name for vg in self.vgs]
-        if hn is not None and hn != '':
-            if hn == 'localhost' or hn == 'localhost.localdomain':
-                vgtemplate = "VolGroup"
-            elif hn.find('.') != -1:
-                hn = safeLvmName(hn)
-                vgtemplate = "vg_%s" % (hn.split('.')[0].lower(),)
-            else:
-                hn = safeLvmName(hn)
-                vgtemplate = "vg_%s" % (hn.lower(),)
-        else:
-            vgtemplate = "VolGroup"
-
-        if vgtemplate not in vgnames and \
-                vgtemplate not in lvm.lvm_vg_blacklist:
-            return vgtemplate
-        else:
-            i = 0
-            while 1:
-                tmpname = "%s%02d" % (vgtemplate, i,)
-                if not tmpname in vgnames and \
-                        tmpname not in lvm.lvm_vg_blacklist:
-                    break
-
-                i += 1
-                if i > 99:
-                    tmpname = ""
-
-            return tmpname
-
-    def createSuggestedLVName(self, vg, swap=None, mountpoint=None):
-        """ Return a suitable, unused name for a new logical volume. """
-        # FIXME: this is not at all guaranteed to work
-        if mountpoint:
-            # try to incorporate the mountpoint into the name
-            if mountpoint == '/':
-                lvtemplate = 'lv_root'
-            else:
-                tmp = safeLvmName(mountpoint)
-                lvtemplate = "lv_%s" % (tmp,)
-        else:
-            if swap:
-                if len([s for s in self.swaps if s in vg.lvs]):
-                    idx = len([s for s in self.swaps if s in vg.lvs])
-                    while True:
-                        lvtemplate = "lv_swap%02d" % idx
-                        if lvtemplate in [lv.lvname for lv in vg.lvs]:
-                            idx += 1
-                        else:
-                            break
-                else:
-                    lvtemplate = "lv_swap"
-            else:
-                idx = len(vg.lvs)
-                while True:
-                    lvtemplate = "LogVol%02d" % idx
-                    if lvtemplate in [l.lvname for l in vg.lvs]:
-                        idx += 1
-                    else:
-                        break
-
-        return lvtemplate
-
-    def deviceDeps(self, device):
-        return self.devicetree.getDependentDevices(device)
-
-    def createDevice(self, device):
-        """ Schedule creation of a device.
-
-            TODO: We could do some things here like assign the next
-                  available raid minor if one isn't already set.
-        """
-        self.devicetree.registerAction(ActionCreateDevice(self.installer, device))
-        if device.format.type:
-            self.devicetree.registerAction(ActionCreateFormat(self.installer, device))
-
-    def destroyDevice(self, device):
-        """ Schedule destruction of a device. """
-        if device.format.exists and device.format.type:
-            # schedule destruction of any formatting while we're at it
-            self.devicetree.registerAction(ActionDestroyFormat(self.installer, device))
-
-        action = ActionDestroyDevice(self.installer, device)
-        self.devicetree.registerAction(action)
-
-    def formatDevice(self, device, format):
-        """ Schedule formatting of a device. """
-        self.devicetree.registerAction(ActionDestroyFormat(device))
-        self.devicetree.registerAction(ActionCreateFormat(device, format))
-
-    def formatByDefault(self, device):
-        """Return whether the device should be reformatted by default."""
-        formatlist = ['/boot', '/var', '/tmp', '/usr']
-        exceptlist = ['/home', '/usr/local', '/opt', '/var/www']
-
-        if not device.format.linuxNative:
-            return False
-
-        if device.format.mountable:
-            if device.format.mountpoint == "/" or \
-               device.format.mountpoint in formatlist:
-                return True
-
-            for p in formatlist:
-                if device.format.mountpoint.startswith(p):
-                    for q in exceptlist:
-                        if device.format.mountpoint.startswith(q):
-                            return False
-                    return True
-        elif device.format.type == "swap":
-            return True
-
-        # be safe for anything else and default to off
-        return False
-
-class FSSet(object):
-    """ A class to represent a set of filesystems. """
-    def __init__(self, installer):
-        self.installer = installer
-        self.devicetree = installer.ds.storage.devicetree
-        self.cryptTab = None
-        self.blkidTab = None
-        self.origFStab = None
-        self.active = False
-        self._dev = None
-        self._devpts = None
-        self._sysfs = None
-        self._proc = None
-        self._devshm = None
-
-    @property
-    def sysfs(self):
-        if not self._sysfs:
-            self._sysfs = NoDevice(format=getFormat("sysfs",
-                                                    device="sys",
-                                                    mountpoint="/sys"))
-        return self._sysfs
-
-    @property
-    def dev(self):
-        if not self._dev:
-            self._dev = DirectoryDevice("/dev", format=getFormat("bind",
-                                                                 device="/dev",
-                                                                 mountpoint="/dev",
-                                                                 exists=True),
-                                        exists=True)
-
-        return self._dev
-
-    @property
-    def devpts(self):
-        if not self._devpts:
-            self._devpts = NoDevice(format=getFormat("devpts",
-                                                     device="devpts",
-                                                     mountpoint="/dev/pts"))
-        return self._devpts
-
-    @property
-    def proc(self):
-        if not self._proc:
-            self._proc = NoDevice(format=getFormat("proc",
-                                                   device="proc",
-                                                   mountpoint="/proc"))
-        return self._proc
-
-    @property
-    def devshm(self):
-        if not self._devshm:
-            self._devshm = NoDevice(format=getFormat("tmpfs",
-                                                     device="tmpfs",
-                                                     mountpoint="/dev/shm"))
-        return self._devshm
-
-    @property
-    def devices(self):
-        devices = self.devicetree.devices.values()
-        devices.sort(key=lambda d: d.path)
-        return devices
-
-    @property
-    def mountpoints(self):
-        filesystems = {}
-        for device in self.devices:
-            if device.format.mountable and device.format.mountpoint:
-                filesystems[device.format.mountpoint] = device
-        return filesystems
-
-    def _parseOneLine(self, (devspec, mountpoint, fstype, options, dump, passno)):
-        # find device in the tree
-        device = self.devicetree.resolveDevice(devspec,
-                                               cryptTab=self.cryptTab,
-                                               blkidTab=self.blkidTab)
-        if device:
-            # fall through to the bottom of this block
-            pass
-        elif devspec.startswith("/dev/loop"):
-            # FIXME: create devices.LoopDevice
-            self.installer.log.warning("completely ignoring your loop mount")
-        elif ":" in devspec:
-            # NFS -- preserve but otherwise ignore
-            device = NFSDevice(devspec,
-                               format=getFormat(fstype,
-                                                device=devspec))
-        elif devspec.startswith("/") and fstype == "swap":
-            # swap file
-            device = FileDevice(devspec,
-                                parents=get_containing_device(devspec, self.devicetree),
-                                format=getFormat(fstype,
-                                                 device=devspec,
-                                                 exists=True),
-                                exists=True)
-        elif fstype == "bind" or "bind" in options:
-            # bind mount... set fstype so later comparison won't
-            # turn up false positives
-            fstype = "bind"
-            device = FileDevice(devspec,
-                                parents=get_containing_device(devspec, self.devicetree),
-                                exists=True)
-            device.format = getFormat("bind",
-                                      device=device.path,
-                                      exists=True)
-        elif mountpoint in ("/proc", "/sys", "/dev/shm", "/dev/pts"):
-            # drop these now -- we'll recreate later
-            return None
-        else:
-            # nodev filesystem -- preserve or drop completely?
-            format = getFormat(fstype)
-            if devspec == "none" or \
-               isinstance(format, get_device_format_class("nodev")):
-                device = NoDevice(format)
-            else:
-                device = StorageDevice(devspec)
-
-        if device is None:
-            self.installer.log.error("failed to resolve %s (%s) from fstab" % (devspec,
-                                                                               fstype))
-            return None
-
-        # make sure, if we're using a device from the tree, that
-        # the device's format we found matches what's in the fstab
-        fmt = getFormat(fstype, device=device.path)
-        if fmt.type != device.format.type:
-            self.installer.log.warning("scanned format (%s) differs from fstab "
-                                       "format (%s)" % (device.format.type, fstype))
-
-        if device.format.mountable:
-            device.format.mountpoint = mountpoint
-            device.format.mountopts = options
-
-        # is this useful?
-        try:
-            device.format.options = options
-        except AttributeError:
-            pass
-
-        return device
-
-    def parseFSTab(self, chroot=""):
-        """ parse /etc/fstab
-
-            preconditions:
-                all storage devices have been scanned, including filesystems
-            postconditions:
-
-            FIXME: control which exceptions we raise
-
-            XXX do we care about bind mounts?
-                how about nodev mounts?
-                loop mounts?
-        """
-        if not chroot or not os.path.isdir(chroot):
-            chroot = ""
-
-        path = "%s/etc/fstab" % chroot
-        if not os.access(path, os.R_OK):
-            # XXX should we raise an exception instead?
-            self.installer.log.info("cannot open %s for read" % path)
-            return
-
-        blkidTab = BlkidTab(self.installer, chroot=chroot)
-        try:
-            blkidTab.parse()
-            self.installer.log.debug("blkid.tab devs: %s" % blkidTab.devices.keys())
-        except Exception as e:
-            self.installer.log.info("error parsing blkid.tab: %s" % e)
-            blkidTab = None
-
-        cryptTab = CryptTab(self.devicetree, blkidTab=blkidTab, chroot=chroot)
-        try:
-            cryptTab.parse(chroot=chroot)
-            self.installer.log.debug("crypttab maps: %s" % cryptTab.mappings.keys())
-        except Exception as e:
-            self.installer.log.info("error parsing crypttab: %s" % e)
-            cryptTab = None
-
-        self.blkidTab = blkidTab
-        self.cryptTab = cryptTab
-
-        with open(path) as f:
-            self.installer.log.debug("parsing %s" % path)
-
-            lines = f.readlines()
-
-            # save the original file
-            self.origFStab = ''.join(lines)
-
-            for line in lines:
-                # strip off comments
-                (line, pound, comment) = line.partition("#")
-                fields = line.split()
-
-                if not 4 <= len(fields) <= 6:
-                    continue
-                elif len(fields) == 4:
-                    fields.extend([0, 0])
-                elif len(fields) == 5:
-                    fields.append(0)
-
-                (devspec, mountpoint, fstype, options, dump, passno) = fields
-
-                try:
-                    device = self._parseOneLine((devspec, mountpoint, fstype, options, dump, passno))
-                except Exception as e:
-                    raise Exception("fstab entry %s is malformed: %s" % (devspec, e))
-
-                if not device:
-                    continue
-
-                if device not in self.devicetree.devices.values():
-                    self.devicetree._addDevice(device)
-
-    def fsFreeSpace(self, chroot='/'):
-        space = []
-        for device in self.devices:
-            if not device.format.mountable or \
-               not device.format.status:
-                continue
-
-            path = "%s/%s" % (chroot, device.format.mountpoint)
-            try:
-                space.append((device.format.mountpoint,
-                              isys.pathSpaceAvailable(path)))
-            except SystemError:
-                self.installer.log.error("failed to calculate free space for %s" % (device.format.mountpoint,))
-
-        space.sort(key=lambda s: s[1])
-        return space
-
-    def mtab(self):
-        format = "%s %s %s %s 0 0\n"
-        mtab = ""
-        devices = self.mountpoints.values() + self.swapDevices
-        devices.extend([self.devshm, self.devpts, self.sysfs, self.proc])
-        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
-        for device in devices:
-            if not device.format.status:
-                continue
-            if not device.format.mountable:
-                continue
-            if device.format.mountpoint:
-                options = device.format.mountopts
-                if options:
-                    options = options.replace("defaults,", "")
-                    options = options.replace("defaults", "")
-
-                if options:
-                    options = "rw," + options
-                else:
-                    options = "rw"
-                mtab = mtab + format % (device.path,
-                                        device.format.mountpoint,
-                                        device.format.type,
-                                        options)
-        return mtab
-
-    def turnOnSwap(self):
-        intf = self.installer.intf
-        for device in self.swapDevices:
-            try:
-                device.setup()
-                device.format.setup()
-            except SuspendError:
-                if intf:
-                    msg = _("The swap device:\n\n     %s\n\n"
-                            "in your /etc/fstab file is currently in "
-                            "use as a software suspend device, "
-                            "which means your system is hibernating. "
-                            "If you are performing a new install, "
-                            "make sure the installer is set "
-                            "to format all swap devices.") \
-                            % device.path
-                    intf.messageWindow(_("Error"), msg)
-                sys.exit(0)
-            except DeviceError as msg:
-                if intf:
-                    err = _("Error enabling swap device %s: %s\n\n"
-                            "This most likely means this swap "
-                            "device has not been initialized.\n\n"
-                            "Press OK to exit the installer.") % \
-                            (device.path, msg)
-                    intf.messageWindow(_("Error"), err)
-                sys.exit(0)
-
-    def mountFilesystems(self, installer, raiseErrors=None, readOnly=None,
-                         skipRoot=False):
-        intf = installer.intf
-        devices = self.mountpoints.values() + self.swapDevices
-        devices.extend([self.dev, self.devshm, self.devpts, self.sysfs, self.proc])
-        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
-
-        for device in devices:
-            if not device.format.mountable or not device.format.mountpoint:
-                continue
-
-            if skipRoot and device.format.mountpoint == "/":
-                continue
-
-            options = device.format.options
-            if "noauto" in options.split(","):
-                continue
-
-            try:
-                device.setup()
-            except Exception as msg:
-                # FIXME: need an error popup
-                continue
-
-            if readOnly:
-                options = "%s,%s" % (options, readOnly)
-
-            try:
-                device.format.setup(options=options,
-                                    chroot=installer.rootPath)
-            except OSError as (num, msg):
-                if intf:
-                    if num == errno.EEXIST:
-                        intf.messageWindow(_("Invalid mount point"),
-                                           _("An error occurred when trying "
-                                             "to create %s.  Some element of "
-                                             "this path is not a directory. "
-                                             "This is a fatal error and the "
-                                             "install cannot continue.\n\n"
-                                             "Press <Enter> to exit the "
-                                             "installer.")
-                                           % (device.format.mountpoint,))
-                    else:
-                        intf.messageWindow(_("Invalid mount point"),
-                                           _("An error occurred when trying "
-                                             "to create %s: %s.  This is "
-                                             "a fatal error and the install "
-                                             "cannot continue.\n\n"
-                                             "Press <Enter> to exit the "
-                                             "installer.")
-                                            % (device.format.mountpoint, msg))
-                self.installer.log.error("OSError: (%d) %s" % (num, msg) )
-                sys.exit(0)
-            except SystemError as (num, msg):
-                if raiseErrors:
-                    raise
-                if intf and not device.format.linuxNative:
-                    ret = intf.messageWindow(_("Unable to mount filesystem"),
-                                             _("An error occurred mounting "
-                                             "device %s as %s.  You may "
-                                             "continue installation, but "
-                                             "there may be problems.") %
-                                             (device.path,
-                                              device.format.mountpoint),
-                                             type="custom",
-                                             custom_icon="warning",
-                                             custom_buttons=[_("_Exit installer"),
-                                                            _("_Continue")])
-
-                    if ret == 0:
-                        sys.exit(0)
-                    else:
-                        continue
-
-                self.installer.log.error("SystemError: (%d) %s" % (num, msg) )
-                sys.exit(0)
-            except FSError as msg:
-                if intf:
-                    intf.messageWindow(_("Unable to mount filesystem"),
-                                       _("An error occurred mounting "
-                                         "device %s as %s: %s. This is "
-                                         "a fatal error and the install "
-                                         "cannot continue.\n\n"
-                                         "Press <Enter> to exit the "
-                                         "installer.")
-                                        % (device.path,
-                                           device.format.mountpoint,
-                                           msg))
-                self.installer.log.error("FSError: %s" % msg)
-                sys.exit(0)
-
-        self.active = True
-
-    def umountFilesystems(self, instPath, ignoreErrors=True, swapoff=True):
-        devices = self.mountpoints.values() + self.swapDevices
-        devices.extend([self.dev, self.devshm, self.devpts, self.sysfs, self.proc])
-        devices.sort(key=lambda d: getattr(d.format, "mountpoint", None))
-        devices.reverse()
-        for device in devices:
-            if not device.format.mountable and \
-               (device.format.type != "swap" or swapoff):
-                continue
-
-            device.format.teardown()
-            device.teardown()
-
-        self.active = False
-
-    def createSwapFile(self, rootPath, device, size):
-        """ Create and activate a swap file under rootPath. """
-        filename = "/SWAP"
-        count = 0
-        basedir = os.path.normpath("%s/%s" % (rootPath,
-                                              device.format.mountpoint))
-        while os.path.exists("%s/%s" % (basedir, filename)) or \
-              self.devicetree.getDeviceByName(filename):
-            file = os.path.normpath("%s/%s" % (basedir, filename))
-            count += 1
-            filename = "/SWAP-%d" % count
-
-        dev = FileDevice(filename,
-                         size=size,
-                         parents=[device],
-                         format=getFormat("swap", device=filename))
-        dev.create()
-        dev.setup()
-        dev.format.create()
-        dev.format.setup()
-        # nasty, nasty
-        self.devicetree._addDevice(dev)
-
-    def mkDevRoot(self, instPath):
-        root = self.rootDevice
-        dev = "%s/%s" % (instPath, root.path)
-        if not os.path.exists("%s/dev/root" %(instPath,)) and os.path.exists(dev):
-            rdev = os.stat(dev).st_rdev
-            os.mknod("%s/dev/root" % (instPath,), stat.S_IFBLK | 0600, rdev)
-
-    @property
-    def swapDevices(self):
-        swaps = []
-        for device in self.devices:
-            if device.format.type == "swap":
-                swaps.append(device)
-        return swaps
-
-    @property
-    def rootDevice(self):
-        for device in self.devices:
-            try:
-                mountpoint = device.format.mountpoint
-            except AttributeError:
-                mountpoint = None
-
-            if mountpoint == "/":
-                return device
-
-    @property
-    def migratableDevices(self):
-        """ List of devices whose filesystems can be migrated. """
-        migratable = []
-        for device in self.devices:
-            if device.format.migratable and device.format.exists:
-                migratable.append(device)
-
-        return migratable
-
-    def write(self, instPath):
-        """ write out all config files based on the set of filesystems """
-        # /etc/fstab
-        fstab_path = os.path.normpath("%s/etc/fstab" % instPath)
-        fstab = self.fstab()
-        open(fstab_path, "w").write(fstab)
-
-        # /etc/crypttab
-        crypttab_path = os.path.normpath("%s/etc/crypttab" % instPath)
-        crypttab = self.crypttab()
-        open(crypttab_path, "w").write(crypttab)
-
-        # /etc/mdadm.conf
-        mdadm_path = os.path.normpath("%s/etc/mdadm.conf" % instPath)
-        mdadm_conf = self.mdadmConf()
-        open(mdadm_path, "w").write(mdadm_conf)
-
-    def crypttab(self):
-        # if we are upgrading, do we want to update crypttab?
-        # gut reaction says no, but plymouth needs the names to be very
-        # specific for passphrase prompting
-        if not self.cryptTab:
-            self.cryptTab = CryptTab(self.devicetree)
-            self.cryptTab.populate()
-
-        devices = self.mountpoints.values() + self.swapDevices
-
-        # prune crypttab -- only mappings required by one or more entries
-        for name in self.cryptTab.mappings.keys():
-            keep = False
-            mapInfo = self.cryptTab[name]
-            cryptoDev = mapInfo['device']
-            for device in devices:
-                if device == cryptoDev or device.dependsOn(cryptoDev):
-                    keep = True
-                    break
-
-            if not keep:
-                del self.cryptTab.mappings[name]
-
-        return self.cryptTab.crypttab()
-
-    def mdadmConf(self):
-        """ Return the contents of mdadm.conf. """
-        arrays = self.devicetree.getDevicesByType("mdarray")
-        conf = ""
-        devices = self.mountpoints.values() + self.swapDevices
-        for array in arrays:
-            writeConf = False
-            for device in devices:
-                if device == array or device.dependsOn(array):
-                    writeConf = True
-                    break
-
-            if writeConf:
-                conf += array.mdadmConfEntry
-
-        return conf
-
-    def fstab (self):
-        format = "%-23s %-23s %-7s %-15s %d %d\n"
-        fstab = """
-#
-# /etc/fstab
-# Created by pomona on %s
-#
-# Accessible filesystems, by reference, are maintained under '/dev/disk'
-# See man pages fstab(5), findfs(8), mount(8) and/or vol_id(8) for more info
-#
-""" % time.asctime()
-
-        devices = self.mountpoints.values() + self.swapDevices
-        devices.extend([self.devshm, self.devpts, self.sysfs, self.proc])
-        netdevs = self.devicetree.getDevicesByInstance(NetworkStorageDevice)
-        for device in devices:
-            # why the hell do we put swap in the fstab, anyway?
-            if not device.format.mountable and device.format.type != "swap":
-                continue
-
-            fstype = device.format.type
-            if fstype == "swap":
-                mountpoint = "swap"
-                options = device.format.options
-            else:
-                mountpoint = device.format.mountpoint
-                options = device.format.mountopts
-                if not mountpoint:
-                    self.installer.log.warning("%s filesystem on %s has no mountpoint" % \
-                                               (fstype, device.path))
-                    continue
-
-            options = options or "defaults"
-            for netdev in netdevs:
-                if device.dependsOn(netdev):
-                    options = options + ",_netdev"
-                    break
-            devspec = device.fstabSpec
-            dump = device.format.dump
-            if device.format.check and mountpoint == "/":
-                passno = 1
-            elif device.format.check:
-                passno = 2
-            else:
-                passno = 0
-            fstab = fstab + device.fstabComment
-            fstab = fstab + format % (devspec, mountpoint, fstype,
-                                      options, dump, passno)
-        return fstab
-
-class BlkidTab(object):
-    """ Dictionary-like interface to blkid.tab with device path keys """
-    def __init__(self, installer, chroot=""):
-        self.installer = installer
-        self.chroot = chroot
-        self.devices = {}
-
-    def parse(self):
-        path = "%s/etc/blkid/blkid.tab" % self.chroot
-        self.installer.log.debug("parsing %s" % path)
-        with open(path) as f:
-            for line in f.readlines():
-                # this is pretty ugly, but an XML parser is more work than
-                # is justifiable for this purpose
-                if not line.startswith("<device "):
-                    continue
-
-                line = line[len("<device "):-len("</device>\n")]
-                (data, sep, device) = line.partition(">")
-                if not device:
-                    continue
-
-                self.devices[device] = {}
-                for pair in data.split():
-                    try:
-                        (key, value) = pair.split("=")
-                    except ValueError:
-                        continue
-
-                    self.devices[device][key] = value[1:-1] # strip off quotes
-
-    def __getitem__(self, key):
-        return self.devices[key]
-
-    def get(self, key, default=None):
-        return self.devices.get(key, default)
-
-
-class CryptTab(object):
-    """ Dictionary-like interface to crypttab entries with map name keys """
-    def __init__(self, devicetree, blkidTab=None, chroot=""):
-        self.devicetree = devicetree
-        self.blkidTab = blkidTab
-        self.chroot = chroot
-        self.mappings = {}
-
-    def parse(self, chroot=""):
-        """ Parse /etc/crypttab from an existing installation. """
-        if not chroot or not os.path.isdir(chroot):
-            chroot = ""
-
-        path = "%s/etc/crypttab" % chroot
-        log.debug("parsing %s" % path)
-        with open(path) as f:
-            if not self.blkidTab:
-                try:
-                    self.blkidTab = BlkidTab(chroot=chroot)
-                    self.blkidTab.parse()
-                except Exception:
-                    self.blkidTab = None
-
-            for line in f.readlines():
-                (line, pound, comment) = line.partition("#")
-                fields = line.split()
-                if not 2 <= len(fields) <= 4:
-                    continue
-                elif len(fields) == 2:
-                    fields.extend(['none', ''])
-                elif len(fields) == 3:
-                    fields.append('')
-
-                (name, devspec, keyfile, options) = fields
-
-                # resolve devspec to a device in the tree
-                device = self.devicetree.resolveDevice(devspec,
-                                                       blkidTab=self.blkidTab)
-                if device:
-                    self.mappings[name] = {"device": device,
-                                           "keyfile": keyfile,
-                                           "options": options}
-
-    def populate(self):
-        """ Populate the instance based on the device tree's contents. """
-        for device in self.devicetree.devices.values():
-            # XXX should we put them all in there or just the ones that
-            #     are part of a device containing swap or a filesystem?
-            #
-            #       Put them all in here -- we can filter from FSSet
-            if device.format.type != "luks":
-                continue
-
-            key_file = device.format.keyFile
-            if not key_file:
-                key_file = "none"
-
-            options = device.format.options
-            if not options:
-                options = ""
-
-            self.mappings[device.format.mapName] = {"device": device,
-                                                    "keyfile": key_file,
-                                                    "options": options}
-
-    def crypttab(self):
-        """ Write out /etc/crypttab """
-        crypttab = ""
-        for name in self.mappings:
-            entry = self[name]
-            crypttab += "%s UUID=%s %s %s\n" % (name,
-                                                entry['device'].format.uuid,
-                                                entry['keyfile'],
-                                                entry['options'])
-        return crypttab                       
-
-    def __getitem__(self, key):
-        return self.mappings[key]
-
-    def get(self, key, default=None):
-        return self.mappings.get(key, default)
diff --git a/src/pomona/storage_old/deviceaction.py b/src/pomona/storage_old/deviceaction.py
deleted file mode 100644 (file)
index 9e7478d..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-#!/usr/bin/python
-
-import copy
-
-from devices import StorageDevice, PartitionDevice
-from formats import getFormat
-from errors import *
-from udev import *
-
-# The values are just hints as to the ordering.
-# Eg: fsmod and devmod ordering depends on the mod (shrink -v- grow)
-ACTION_TYPE_NONE = 0
-ACTION_TYPE_DESTROY = 1000
-ACTION_TYPE_RESIZE = 500
-ACTION_TYPE_MIGRATE = 250
-ACTION_TYPE_CREATE = 100
-
-action_strings = {ACTION_TYPE_NONE: "None",
-                  ACTION_TYPE_DESTROY: "Destroy",
-                  ACTION_TYPE_RESIZE: "Resize",
-                  ACTION_TYPE_MIGRATE: "Migrate",
-                  ACTION_TYPE_CREATE: "Create"}
-
-ACTION_OBJECT_NONE = 0
-ACTION_OBJECT_FORMAT = 1
-ACTION_OBJECT_DEVICE = 2
-
-object_strings = {ACTION_OBJECT_NONE: "None",
-                  ACTION_OBJECT_FORMAT: "Format",
-                  ACTION_OBJECT_DEVICE: "Device"}
-
-RESIZE_SHRINK = 88
-RESIZE_GROW = 89
-
-resize_strings = {RESIZE_SHRINK: "Shrink",
-                  RESIZE_GROW: "Grow"}
-
-def action_type_from_string(type_string):
-    if type_string is None:
-        return None
-
-    for (k,v) in action_strings.items():
-        if v.lower() == type_string.lower():
-            return k
-
-    return resize_type_from_string(type_string)
-
-def action_object_from_string(type_string):
-    if type_string is None:
-        return None
-
-    for (k,v) in object_strings.items():
-        if v.lower() == type_string.lower():
-            return k
-
-def resize_type_from_string(type_string):
-    if type_string is None:
-        return None
-
-    for (k,v) in resize_strings.items():
-        if v.lower() == type_string.lower():
-            return k
-
-class DeviceAction(object):
-    """ An action that will be carried out in the future on a Device.
-
-        These classes represent actions to be performed on devices or
-        filesystems.
-
-        The operand Device instance will be modified according to the
-        action, but no changes will be made to the underlying device or
-        filesystem until the DeviceAction instance's execute method is
-        called. The DeviceAction instance's cancel method should reverse
-        any modifications made to the Device instance's attributes.
-
-        If the Device instance represents a pre-existing device, the
-        constructor should call any methods or set any attributes that the
-        action will eventually change. Device/DeviceFormat classes should verify
-        that the requested modifications are reasonable and raise an
-        exception if not.
-
-        Only one action of any given type/object pair can exist for any
-        given device at any given time. This is enforced by the
-        DeviceTree.
-
-        Basic usage:
-
-            a = DeviceAction(dev)
-            a.execute()
-
-            OR
-
-            a = DeviceAction(dev)
-            a.cancel()
-
-
-        XXX should we back up the device with a deep copy for forcibly
-            cancelling actions?
-
-            The downside is that we lose any checking or verification that
-            would get done when resetting the Device instance's attributes to
-            their original values.
-
-            The upside is that we would be guaranteed to achieve a total
-            reversal. No chance of, eg: resizes ending up altering Device
-            size due to rounding or other miscalculation.
-"""
-    type = ACTION_TYPE_NONE
-    obj = ACTION_OBJECT_NONE
-
-    def __init__(self, installer, device):
-        self.installer = installer
-        if not isinstance(device, StorageDevice):
-            raise ValueError("arg 1 must be a StorageDevice instance")
-        self.device = device
-
-
-    def execute(self, intf=None):
-        """ perform the action """
-        pass
-
-    def cancel(self):
-        """ cancel the action """
-        pass
-
-    def isDestroy(self):
-        return self.type == ACTION_TYPE_DESTROY
-
-    def isCreate(self):
-        return self.type == ACTION_TYPE_CREATE
-
-    def isMigrate(self):
-        return self.type == ACTION_TYPE_MIGRATE
-
-    def isResize(self):
-        return self.type == ACTION_TYPE_RESIZE
-
-    def isShrink(self):
-        return (self.type == ACTION_TYPE_RESIZE and self.dir == RESIZE_SHRINK)
-
-    def isGrow(self):
-        return (self.type == ACTION_TYPE_RESIZE and self.dir == RESIZE_GROW)
-
-    def isDevice(self):
-        return self.obj == ACTION_OBJECT_DEVICE
-
-    def isFormat(self):
-        return self.obj == ACTION_OBJECT_FORMAT
-
-    def __str__(self):
-        s = "%s %s" % (action_strings[self.type], object_strings[self.obj])
-        if self.isResize():
-            s += " (%s)" % resize_strings[self.dir]
-        if self.isFormat():
-            if self.device.format:
-                fmt_type = self.device.format.type
-            else:
-                fmt_type = None
-            s += " %s on" % fmt_type
-        if self.isMigrate():
-            pass
-        s += " %s (%s)" % (self.device.name, self.device.type)
-        return s
-
-class ActionCreateDevice(DeviceAction):
-    """ Action representing the creation of a new device. """
-    type = ACTION_TYPE_CREATE
-    obj = ACTION_OBJECT_DEVICE
-
-    def __init__(self, installer, device):
-        # FIXME: assert device.fs is None
-        DeviceAction.__init__(self, installer, device)
-
-    def execute(self, intf=None):
-        self.device.create(intf=intf)
-
-
-class ActionDestroyDevice(DeviceAction):
-    """ An action representing the deletion of an existing device. """
-    type = ACTION_TYPE_DESTROY
-    obj = ACTION_OBJECT_DEVICE
-
-    def __init__(self, installer, device):
-        # XXX should we insist that device.fs be None?
-        DeviceAction.__init__(self, installer, device)
-        if device.exists:
-            device.teardown()
-
-    def execute(self, intf=None):
-        self.device.destroy()
-
-
-class ActionResizeDevice(DeviceAction):
-    """ An action representing the resizing of an existing device. """
-    type = ACTION_TYPE_RESIZE
-    obj = ACTION_OBJECT_DEVICE
-
-    def __init__(self, installer, device, newsize):
-        if device.currentSize == newsize:
-            raise ValueError("new size same as old size")
-
-        if not device.resizable:
-            raise ValueError("device is not resizable")
-
-        DeviceAction.__init__(self, installer, device)
-        if newsize > device.currentSize:
-            self.dir = RESIZE_GROW
-        else:
-            self.dir = RESIZE_SHRINK
-        self.origsize = device.targetSize
-        self.device.targetSize = newsize
-
-    def execute(self, intf=None):
-        self.device.resize(intf=intf)
-
-    def cancel(self):
-        self.device.targetSize = self.origsize
-
-
-class ActionCreateFormat(DeviceAction):
-    """ An action representing creation of a new filesystem. """
-    type = ACTION_TYPE_CREATE
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, installer, device, format=None):
-        DeviceAction.__init__(self, installer, device)
-        if format:
-            self.origFormat = device.format
-            if self.device.format.exists:
-                self.device.format.teardown()
-            self.device.format = format
-        else:
-            self.origFormat = getFormat(self.installer, None)
-
-    def execute(self, intf=None):
-        if isinstance(self.device, PartitionDevice):
-            if self.format.partedFlag is not None:
-                self.device.setFlag(self.format.partedFlag)
-                self.device.disk.commit()
-
-        udev_settle()
-        self.device.setup()
-        self.device.format.create(intf=intf,
-                                  device=self.device.path,
-                                  options=self.device.formatArgs)
-        # Get the UUID now that the format is created
-        udev_settle()
-        self.device.updateSysfsPath()
-        info = udev_get_block_device("/sys%s" % self.device.sysfsPath)
-        self.device.format.uuid = udev_device_get_uuid(info)
-
-    def cancel(self):
-        self.device.format = self.origFormat
-
-    @property
-    def format(self):
-        return self.device.format
-
-
-class ActionDestroyFormat(DeviceAction):
-    """ An action representing the removal of an existing filesystem.
-
-        XXX this seems unnecessary
-    """
-    type = ACTION_TYPE_DESTROY
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, installer, device):
-        DeviceAction.__init__(self, installer, device)
-        # Save a deep copy of the device stack this format occupies.
-        # This is necessary since the stack of devices and formats
-        # required to get to this format may get yanked out from under
-        # us between now and execute.
-        self._device = copy.deepcopy(device)
-        self.origFormat = self._device.format
-        if device.format.exists:
-            device.format.teardown()
-        self.device.format = None
-
-    def execute(self, intf=None):
-        """ wipe the filesystem signature from the device """
-        if self.origFormat:
-            if isinstance(self.device, PartitionDevice) and \
-               self.origFormat.partedFlag is not None:
-                # unset partition flags and commit
-                self.device.unsetFlag(self.origFormat.partedFlag)
-                self.device.disk.commit()
-                udev_settle()
-
-            # set up our copy of the original device stack since the
-            # reference we got may have had any number of things changed
-            # since then (most notably, formats removed by this very
-            # class' constructor)
-            self._device.setup()
-            self.origFormat.destroy()
-            udev_settle()
-            self._device.teardown()
-
-    def cancel(self):
-        self.device.format = self.origFormat
-
-    @property
-    def format(self):
-        return self.origFormat
-
-
-class ActionResizeFormat(DeviceAction):
-    """ An action representing the resizing of an existing filesystem.
-
-        XXX Do we even want to support resizing of a filesystem without
-            also resizing the device it resides on?
-    """
-    type = ACTION_TYPE_RESIZE
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, installer, device, newsize):
-        if device.targetSize == newsize:
-            raise ValueError("new size same as old size")
-
-        DeviceAction.__init__(self, installer, device)
-        if newsize > device.format.currentSize:
-            self.dir = RESIZE_GROW
-        else:
-            self.dir = RESIZE_SHRINK
-        self.origSize = self.device.format.targetSize
-        self.device.format.targetSize = newsize
-
-    def execute(self, intf=None):
-        self.device.setup()
-        self.device.format.doResize(intf=intf)
-
-    def cancel(self):
-        self.device.format.targetSize = self.origSize
-
-class ActionMigrateFormat(DeviceAction):
-    """ An action representing the migration of an existing filesystem. """
-    type = ACTION_TYPE_MIGRATE
-    obj = ACTION_OBJECT_FORMAT
-
-    def __init__(self, installer, device):
-        if not device.format.migratable or not device.format.exists:
-            raise ValueError("device format is not migratable")
-
-        DeviceAction.__init__(self, installer, device)
-        self.device.format.migrate = True
-
-    def execute(self, intf=None):
-        self.device.setup()
-        self.device.format.doMigrate(intf=intf)
-
-    def cancel(self):
-        self.device.format.migrate = False
diff --git a/src/pomona/storage_old/devicelibs/__init__.py b/src/pomona/storage_old/devicelibs/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/pomona/storage_old/devicelibs/lvm.py b/src/pomona/storage_old/devicelibs/lvm.py
deleted file mode 100644 (file)
index 20fa02a..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/python
-
-import os
-import re
-
-import util
-
-MAX_LV_SLOTS = 256
-
-def has_lvm():
-    has_lvm = False
-    for path in os.environ["PATH"].split(":"):
-        if os.access("%s/lvm" % path, os.X_OK):
-            has_lvm = True
-            break
-
-    if has_lvm:
-        has_lvm = False
-        for line in open("/proc/devices").readlines():
-            if "device-mapper" in line.split():
-                has_lvm = True
-                break
-
-    return has_lvm
-
-# Start config_args handling code
-#
-# Theoretically we can handle all that can be handled with the LVM --config
-# argument.  For every time we call an lvm_cc (lvm compose config) funciton
-# we regenerate the config_args with all global info.
-config_args = [] # Holds the final argument list
-config_args_data = { "filterRejects": [],    # regular expressions to reject.
-                            "filterAccepts": [] }   # regexp to accept
-
-def _composeConfig():
-    """lvm command accepts lvm.conf type arguments preceded by --config. """
-    global config_args, config_args_data
-    config_args = []
-
-    filter_string = ""
-    rejects = config_args_data["filterRejects"]
-    # we don't need the accept for now.
-    # accepts = config_args_data["filterAccepts"]
-    # if len(accepts) > 0:
-    #   for i in range(len(rejects)):
-    #       filter_string = filter_string + ("\"a|%s|\", " % accpets[i])
-
-    if len(rejects) > 0:
-        for i in range(len(rejects)):
-            filter_string = filter_string + ("\"r|%s|\"," % rejects[i])
-
-    filter_string = " filter=[%s] " % filter_string.strip(",")
-
-    # As we add config strings we should check them all.
-    if filter_string == "":
-        # Nothing was really done.
-        return
-
-    # devices_string can have (inside the brackets) "dir", "scan",
-    # "preferred_names", "filter", "cache_dir", "write_cache_state",
-    # "types", "sysfs_scan", "md_component_detection".  see man lvm.conf.
-    devices_string = " devices {%s} " % (filter_string) # strings can be added
-    config_string = devices_string # more strings can be added.
-    config_args = ["--config", config_string]
-
-def lvm_cc_addFilterRejectRegexp(regexp):
-    """ Add a regular expression to the --config string."""
-    global config_args_data
-    config_args_data["filterRejects"].append(regexp)
-
-    # compoes config once more.
-    _composeConfig()
-
-def lvm_cc_resetFilter():
-    global config_args_data
-    config_args_data["filterRejects"] = []
-    config_args_data["filterAccepts"] = []
-# End config_args handling code.
-
-# Names that should not be used int the creation of VGs
-lvm_vg_blacklist = []
-def blacklistVG(name):
-    global lvm_vg_blacklist
-    lvm_vg_blacklist.append(name)
-
-def getPossiblePhysicalExtents(floor=0):
-    """Returns a list of integers representing the possible values for
-       the physical extent of a volume group.  Value is in KB.
-
-       floor - size (in KB) of smallest PE we care about.
-    """
-
-    possiblePE = []
-    curpe = 8
-    while curpe <= 16384*1024:
-        if curpe >= floor:
-            possiblePE.append(curpe)
-        curpe = curpe * 2
-
-    return possiblePE
-
-def getMaxLVSize():
-    """ Return the maximum size (in MB) of a logical volume. """
-    if util.getArch() in ("x86_64",): #64bit architectures
-        return (8*1024*1024*1024*1024) #Max is 8EiB (very large number..)
-    else:
-        return (16*1024*1024) #Max is 16TiB
-
-def safeLvmName(name):
-    tmp = name.strip()
-    tmp = tmp.replace("/", "_")
-    tmp = re.sub("[^0-9a-zA-Z._]", "", tmp)
-    tmp = tmp.lstrip("_")
-
-    return tmp
diff --git a/src/pomona/storage_old/devices.py b/src/pomona/storage_old/devices.py
deleted file mode 100644 (file)
index ae9032d..0000000
+++ /dev/null
@@ -1,1602 +0,0 @@
-#!/usr/bin/python
-
-import os
-import math
-import parted
-import _ped
-
-from util import notify_kernel, numeric_type
-from formats import get_device_format_class, getFormat
-from devicelibs import lvm
-from udev import *
-
-def get_device_majors():
-    majors = {}
-    for line in open("/proc/devices").readlines():
-        try:
-            (major, device) = line.split()
-        except ValueError:
-            continue
-        try:
-            majors[int(major)] = device
-        except ValueError:
-            continue
-    return majors
-device_majors = get_device_majors()
-
-def devicePathToName(devicePath):
-    if devicePath.startswith("/dev/"):
-        name = devicePath[5:]
-    else:
-        name = devicePath
-
-    if name.startswith("mapper/"):
-        name = name[7:]
-
-    return name
-
-class Device(object):
-    """ A generic device.
-
-        Device instances know which devices they depend upon (parents
-        attribute). They do not know which devices depend upon them, but
-        they do know whether or not they have any dependent devices
-        (isleaf attribute).
-
-        A Device's setup method should set up all parent devices as well
-        as the device itself. It should not run the resident format's
-        setup method.
-
-            Which Device types rely on their parents' formats being active?
-                DMCryptDevice
-
-        A Device's teardown method should accept the keyword argument
-        recursive, which takes a boolean value and indicates whether or
-        not to recursively close parent devices.
-
-        A Device's create method should create all parent devices as well
-        as the device itself. It should also run the Device's setup method
-        after creating the device. The create method should not create a
-        device's resident format.
-
-            Which device type rely on their parents' formats to be created
-            before they can be created/assembled?
-                VolumeGroup
-                DMCryptDevice
-
-        A Device's destroy method should destroy any resident format
-        before destroying the device itself.
-
-    """
-    _type = "generic device"
-    _packages = []
-
-    def __init__(self, installer, name, parents=None, description=''):
-        """ Create a Device instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                parents -- a list of required Device instances
-                description -- a string describing the device
-
-        """
-        self.installer = installer
-        self._name = name
-        if parents is None:
-            parents = []
-        elif not isinstance(parents, list):
-            raise ValueError("parents must be a list of Device instances")
-        self.parents = parents
-        self.kids = 0
-        self.description = description
-
-        for parent in self.parents:
-            parent.addChild()
-
-    def __deepcopy__(self, memo):
-        """ Create a deep copy of a Device instance.
-
-            We can't do copy.deepcopy on parted objects, which is okay.
-            For these parted objects, we just do a shallow copy.
-        """
-        new = self.__class__.__new__(self.__class__)
-        memo[id(self)] = new
-        shallow_copy_attrs = ('partedDisk', '_partedDevice',
-                             '_partedPartition', '_origPartedDisk',
-                             '_raidSet')
-        for (attr, value) in self.__dict__.items():
-            if attr in shallow_copy_attrs:
-                setattr(new, attr, copy.copy(value))
-            else:
-                setattr(new, attr, copy.deepcopy(value, memo))
-
-        return new
-
-    def __str__(self):
-        s = ("%(type)s instance (%(id)s) --\n"
-             "  description = %(descr)s  name = %(name)s  status = %(status)s"
-             "  parents = %(parents)s\n"
-             "  kids = %(kids)s\n" %
-             {"type": self.__class__.__name__, "id": "%#x" % id(self),
-              "name": self.name, "parents": self.parents, "kids": self.kids,
-              "descr": self.description, "status": self.status})
-        return s
-
-    def removeChild(self):
-        self.kids -= 1
-
-    def addChild(self):
-        self.kids += 1
-
-    def setup(self, intf=None):
-        """ Open, or set up, a device. """
-        raise NotImplementedError("setup method not defined for Device")
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        raise NotImplementedError("teardown method not defined for Device")
-
-    def create(self, intf=None):
-        """ Create the device. """
-        raise NotImplementedError("create method not defined for Device")
-
-    def destroy(self):
-        """ Destroy the device. """
-        raise NotImplementedError("destroy method not defined for Device")
-
-    def setupParents(self):
-        """ Run setup method of all parent devices. """
-        for parent in self.parents:
-            parent.setup()
-
-    def teardownParents(self, recursive=None):
-        """ Run teardown method of all parent devices. """
-        for parent in self.parents:
-            parent.teardown(recursive=recursive)
-
-    def createParents(self):
-        """ Run create method of all parent devices. """
-        self.installer.log.info("NOTE: recursive device creation disabled")
-        for parent in self.parents:
-            if not parent.exists:
-                raise DeviceError("parent device does not exist")
-            #parent.create()
-
-    def dependsOn(self, dep):
-        """ Return True if this device depends on dep. """
-        # XXX does a device depend on itself?
-        if dep in self.parents:
-            return True
-
-        for parent in self.parents:
-            if parent.dependsOn(dep):
-                return True
-
-        return False
-
-    @property
-    def status(self):
-        """ This device's status.
-
-            For now, this should return a boolean:
-                True    the device is open and ready for use
-                False   the device is not open
-        """
-        return False
-
-    @property
-    def name(self):
-        """ This device's name. """
-        return self._name
-
-    @property
-    def isleaf(self):
-        """ True if this device has no children. """
-        return self.kids == 0
-
-    @property
-    def typeDescription(self):
-        """ String describing the device type. """
-        return self._type
-
-    @property
-    def type(self):
-        """ Device type. """
-        return self._type
-
-    @property
-    def mediaPresent(self):
-        return True
-
-
-class StorageDevice(Device):
-    """ A generic storage device.
-
-        A fully qualified path to the device node can be obtained via the
-        path attribute, although it is not guaranteed to be useful, or
-        even present, unless the StorageDevice's setup method has been
-        run.
-
-        StorageDevice instances can optionally contain a filesystem,
-        represented by an FS instance. A StorageDevice's create method
-        should create a filesystem if one has been specified.
-    """
-    _type = "storage device"
-    _devDir = "/dev"
-    sysfsBlockDir = "class/block"
-    _resizable = False
-
-    def __init__(self, installer, device, format=None,
-                 size=None, major=None, minor=None,
-                 sysfsPath='', parents=None, exists=None):
-        """ Create a StorageDevice instance.
-
-            Arguments:
-
-                device -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                size -- the device's size (units/format TBD)
-                major -- the device major
-                minor -- the device minor
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                description -- a string describing the device
-
-        """
-        self.installer = installer
-
-        # allow specification of individual parents
-        if isinstance(parents, Device):
-            parents = [parents]
-
-        Device.__init__(self, installer, device, parents=parents)
-
-        self.uuid = None
-        self._format = None
-        self._size = numeric_type(size)
-        self.major = numeric_type(major)
-        self.minor = numeric_type(minor)
-        self.sysfsPath = sysfsPath
-        self.exists = exists
-
-        # this may be handy for disk, dmraid, mpath, mdraid
-        self.diskLabel = None
-
-        self.format = format
-        self.fstabComment = ""
-        self._targetSize = self._size
-
-        self._partedDevice = None
-
-    @property
-    def partedDevice(self):
-        if self.exists and self.status and not self._partedDevice:
-            self.installer.log.debug("Looking up parted Device: %s" % self.path)
-
-            # We aren't guaranteed to be able to get a device.  In
-            # particular, built-in USB flash readers show up as devices but
-            # do not always have any media present, so parted won't be able
-            # to find a device.
-            try:
-                self._partedDevice = parted.Device(path=self.path)
-            except _ped.DeviceException:
-                pass
-
-        return self._partedDevice
-
-    def _getTargetSize(self):
-        return self._targetSize
-
-    def _setTargetSize(self, newsize):
-        self._targetSize = newsize
-
-    targetSize = property(lambda s: s._getTargetSize(),
-                          lambda s, v: s._setTargetSize(v),
-                          doc="Target size of this device")
-
-    def __str__(self):
-        s = Device.__str__(self)
-        s += ("  uuid = %(uuid)s  format = %(format)r  size = %(size)s\n"
-              "  major = %(major)s  minor = %(minor)r  exists = %(exists)s\n"
-              "  sysfs path = %(sysfs)s  label = %(diskLabel)s\n"
-              "  target size = %(targetSize)s  path = %(path)s\n"
-              "  format args = %(formatArgs)s" %
-              {"uuid": self.uuid, "format": self.format, "size": self.size,
-               "major": self.major, "minor": self.minor, "exists": self.exists,
-               "sysfs": self.sysfsPath, "diskLabel": self.diskLabel,
-               "targetSize": self.targetSize, "path": self.path,
-               "formatArgs": self.formatArgs})
-        return s
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        return "%s/%s" % (self._devDir, self.name)
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        sysfsName = self.name.replace("/", "!")
-        path = os.path.join("/sys", self.sysfsBlockDir, sysfsName)
-        self.sysfsPath = os.path.realpath(path)[4:]
-        self.installer.log.debug("%s sysfsPath set to %s" % (self.name, self.sysfsPath))
-
-    @property
-    def formatArgs(self):
-        """ Device-specific arguments to format creation program. """
-        return []
-
-    @property
-    def resizable(self):
-        """ Can this type of device be resized? """
-        return self._resizable and self.exists
-
-    def notifyKernel(self):
-        """ Send a 'change' uevent to the kernel for this device. """
-        if not self.exists:
-            self.installer.log.debug("Not sending change uevent for non-existent device")
-            return
-
-        if not self.status:
-            self.installer.log.debug("Not sending change uevent for inactive device")
-            return
-
-        path = os.path.normpath("/sys/%s" % self.sysfsPath)
-        try:
-            notify_kernel(path, action="change")
-        except Exception, e:
-            self.installer.log.warning("Failed to notify kernel of change: %s" % e)
-
-    @property
-    def fstabSpec(self):
-        spec = self.path
-        if self.format and self.format.uuid:
-            spec = "UUID=%s" % self.format.uuid
-        return spec
-
-    def resize(self, intf=None):
-        """ Resize the device.
-
-            New size should already be set.
-        """
-        raise NotImplementedError("resize method not defined for StorageDevice")
-
-    def setup(self, intf=None):
-        """ Open, or set up, a device. """
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-        self.setupParents()
-        for parent in self.parents:
-            parent.format.setup()
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created")
-
-        if self.status and self.format.exists:
-            self.format.teardown()
-            udev_settle(timeout=10)
-
-        if recursive:
-            self.teardownParents(recursive=recursive)
-
-    def _getSize(self):
-        """ Get the device's size in MB, accounting for pending changes. """
-        if self.exists and not self.mediaPresent:
-            return 0
-
-        if self.exists and self.partedDevice:
-            self._size = self.currentSize
-
-        size = self._size
-        if self.exists and self.resizable and self.targetSize != size:
-            size = self.targetSize
-
-        return size
-
-    def _setSize(self, newsize):
-        """ Set the device's size to a new value. """
-        if newsize > self.maxSize:
-            raise DeviceError("device cannot be larger than %s MB" %
-                              (self.maxSize(),))
-        self._size = newsize
-
-    size = property(lambda x: x._getSize(),
-                    lambda x, y: x._setSize(y),
-                    doc="The device's size in MB, accounting for pending changes")
-
-    @property
-    def currentSize(self):
-        """ The device's actual size. """
-        size = 0
-        if self.exists and self.partedDevice:
-            size = self.partedDevice.getSize()
-        elif self.exists:
-            size = self._size
-        return size
-
-    @property
-    def minSize(self):
-        """ The minimum size this device can be. """
-        if self.exists:
-            self.setup()
-
-        if self.format.minSize:
-            return self.format.minSize
-        else:
-            return self.size
-
-    @property
-    def maxSize(self):
-        """ The maximum size this device can be. """
-        if self.format.maxSize > self.currentSize:
-            return self.currentSize
-        else:
-            return self.format.maxSize
-
-    @property
-    def status(self):
-        """ This device's status.
-
-            For now, this should return a boolean:
-                True    the device is open and ready for use
-                False   the device is not open
-        """
-        if not self.exists:
-            return False
-        return os.access(self.path, os.W_OK)
-
-    def _setFormat(self, format):
-        """ Set the Device's format. """
-        if not format:
-            format = getFormat(None, self.installer, device=self.path, exists=self.exists)
-        if self._format and self._format.status:
-            # FIXME: self.format.status doesn't mean much
-            raise DeviceError("cannot replace active format")
-
-        self._format = format
-
-    def _getFormat(self):
-        return self._format
-
-    format = property(lambda d: d._getFormat(),
-                      lambda d,f: d._setFormat(f),
-                      doc="The device's formatting.")
-
-    def create(self, intf=None):
-        """ Create the device. """
-        if self.exists:
-            raise DeviceError("device has already been created")
-
-        self.createParents()
-        self.setupParents()
-        self.exists = True
-        self.setup()
-
-    def destroy(self):
-        """ Destroy the device. """
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-        if not self.isleaf:
-            raise DeviceError("Cannot destroy non-leaf device")
-
-        self.exists = False
-
-    @property
-    def removable(self):
-        devpath = os.path.normpath("/sys/%s" % self.sysfsPath)
-        remfile = os.path.normpath("%s/removable" % devpath)
-        return (self.sysfsPath and os.path.exists(devpath) and
-                os.access(remfile, os.R_OK) and
-                open(remfile).readline().strip() == "1")
-
-class NetworkStorageDevice(object):
-    """ Virtual base class for network backed storage devices """
-
-    def __init__(self, installer, host_address):
-        """ Create a NetworkStorage Device instance. Note this class is only
-            to be used as a baseclass and then only with multiple inheritance.
-            The only correct use is:
-            class MyStorageDevice(StorageDevice, NetworkStorageDevice):
-
-            The sole purpose of this class is to:
-            1) Be able to check if a StorageDevice is network backed
-               (using isinstance).
-            2) To be able to get the host address of the host (server) backing
-               the storage.
-
-            Arguments:
-
-                host_address -- host address of the backing server
-        """
-        self.installer = installer
-        self.host_address = host_address
-
-class DiskDevice(StorageDevice):
-    """ A disk """
-    _type = "disk"
-
-    def __init__(self, installer, device, format=None,
-                 size=None, major=None, minor=None, sysfsPath='', \
-                 parents=None, initcb=None, initlabel=None):
-        """ Create a DiskDevice instance.
-
-            Arguments:
-
-                device -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                size -- the device's size (units/format TBD)
-                major -- the device major
-                minor -- the device minor
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                removable -- whether or not this is a removable device
-
-                initcb -- the call back to be used when initiating disk.
-                initlabel -- whether to start with a fresh disklabel
-
-
-            DiskDevices always exist.
-        """
-        self.installer = installer
-        StorageDevice.__init__(self, self.installer, device, format=format,
-                                size=size, major=major, minor=minor, exists=True,
-                               sysfsPath=sysfsPath, parents=parents)
-
-        self.partedDisk = None
-
-        self.installer.log.debug("Looking up parted Device: %s" % self.path)
-
-        if self.partedDevice:
-            self.installer.log.debug("Creating parted Disk: %s" % self.path)
-            if initlabel:
-                self.partedDisk = self.freshPartedDisk()
-            else:
-                try:
-                    self.partedDisk = parted.Disk(device=self.partedDevice)
-                except _ped.DiskLabelException:
-                    # if we have a cb function use it. else an error.
-                    if initcb is not None and initcb():
-                        self.partedDisk = parted.freshDisk(device=self.partedDevice, \
-                                ty = platform.getPlatform(None).diskType)
-                    else:
-                        raise DeviceUserDeniedFormatError("User prefered to not format.")
-
-        # We save the actual state of the disk here. Before the first
-        # modification (addPartition or removePartition) to the partition
-        # table we reset self.partedPartition to this state so we can
-        # perform the modifications one at a time.
-        if self.partedDisk:
-            self._origPartedDisk = self.partedDisk.duplicate()
-        else:
-            self._origPartedDisk = None
-
-    def __str__(self):
-        s = StorageDevice.__str__(self)
-        s += ("  removable = %(removable)s  partedDevice = %(partedDevice)r\n"
-              "  partedDisk = %(partedDisk)r" %
-              {"removable": self.removable, "partedDisk": self.partedDisk,
-               "partedDevice": self.partedDevice})
-        return s
-
-    def freshPartedDisk(self):
-        labelType = platform.getPlatform(None).diskType
-        return parted.freshDisk(device=self.partedDevice, ty=labelType)
-
-    @property
-    def mediaPresent(self):
-        return self.partedDevice is not None
-
-    @property
-    def model(self):
-        return getattr(self.partedDevice, "model", None)
-
-    @property
-    def size(self):
-        """ The disk's size in MB """
-        return super(DiskDevice, self).size
-    #size = property(StorageDevice._getSize)
-
-    def resetPartedDisk(self):
-        """ Reset parted.Disk to reflect the actual layout of the disk. """
-        self.partedDisk = self._origPartedDisk
-
-    def removePartition(self, device):
-        if not self.mediaPresent:
-            raise DeviceError("cannot remove partition from disk %s which has no media" % self.name)
-
-        partition = self.partedDisk.getPartitionByPath(device.path)
-        if partition:
-            self.partedDisk.removePartition(partition)
-
-    def addPartition(self, device):
-        if not self.mediaPresent:
-            raise DeviceError("cannot add partition to disk %s which has no media" % self.name)
-
-        for part in self.partedDisk.partitions:
-            self.installer.log.debug("Disk %s: partition %s has geom %s" % (self.name,
-                                                             part.getDeviceNodeName(),
-                                                             part.geometry))
-
-        geometry = device.partedPartition.geometry
-        constraint = parted.Constraint(exactGeom=geometry)
-        partition = parted.Partition(disk=self.partedDisk,
-                                     type=device.partedPartition.type,
-                                     geometry=geometry)
-        self.partedDisk.addPartition(partition,
-                                     constraint=constraint)
-
-    def probe(self):
-        """ Probe for any missing information about this device.
-
-            pyparted should be able to tell us anything we want to know.
-            size, disklabel type, maybe even partition layout
-        """
-        if not self.diskLabel:
-            self.installer.log.debug("Setting %s diskLabel to %s" % (self.name,
-                                                      self.partedDisk.type))
-            self.diskLabel = self.partedDisk.type
-
-    def commit(self, intf=None):
-        """ Commit changes to the device. """
-        if not self.mediaPresent:
-            raise DeviceError("cannot commit to disk %s which has no media" % self.name)
-
-        self.setupParents()
-        self.setup()
-
-        # give committing 5 tries, failing that, raise an exception
-        attempt = 1
-        maxTries = 5
-        keepTrying = True
-
-        while keepTrying and (attempt <= maxTries):
-            try:
-                self.partedDisk.commit()
-                keepTrying = False
-            except parted.DiskException as msg:
-                self.installer.log.warning(msg)
-                attempt += 1
-
-        if keepTrying:
-            raise DeviceError("cannot commit to disk %s after %d attempts" % (self.name, maxTries,))
-
-        # commit makes the kernel re-scan the partition table
-        udev_settle()
-
-    def destroy(self):
-        """ Destroy the device. """
-        if not self.mediaPresent:
-            raise DeviceError("cannot destroy disk %s which has no media" % self.name)
-
-        self.partedDisk.deleteAllPartitions()
-        # this is perhaps a separate operation (wiping the disklabel)
-        self.partedDisk.clobber()
-        self.partedDisk.commit()
-        self.teardown()
-
-    def setup(self, intf=None):
-        """ Open, or set up, a device. """
-        if not os.path.exists(self.path):
-            raise DeviceError("device does not exist")
-
-class PartitionDevice(StorageDevice):
-    """ A disk partition.
-
-        On types and flags...
-
-        We don't need to deal with numerical partition types at all. The
-        only type we are concerned with is primary/logical/extended. Usage
-        specification is accomplished through the use of flags, which we
-        will set according to the partition's format.
-    """
-    _type = "partition"
-    _resizable = True
-
-    def __init__(self, installer, name, format=None,
-                 size=None, grow=False, maxsize=None,
-                 major=None, minor=None, bootable=None,
-                 sysfsPath='', parents=None, exists=None,
-                 partType=None, primary=False, weight=0):
-        """ Create a PartitionDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                exists -- indicates whether this is an existing device
-                format -- the device's format (DeviceFormat instance)
-
-                For existing partitions:
-
-                    parents -- the disk that contains this partition
-                    major -- the device major
-                    minor -- the device minor
-                    sysfsPath -- sysfs device path
-
-                For new partitions:
-
-                    partType -- primary,extended,&c (as parted constant)
-                    grow -- whether or not to grow the partition
-                    maxsize -- max size for growable partitions (in MB)
-                    size -- the device's size (in MB)
-                    bootable -- whether the partition is bootable
-                    parents -- a list of potential containing disks
-                    weight -- an initial sorting weight to assign
-        """
-        self.installer = installer
-        self.req_disks = []
-        self.req_partType = None
-        self.req_primary = None
-        self.req_grow = None
-        self.req_bootable = None
-        self.req_size = 0
-        self.req_base_size = 0
-        self.req_max_size = 0
-        self.req_base_weight = 0
-
-        self._bootable = False
-
-        StorageDevice.__init__(self, installer, name, format=format, size=size,
-                               major=major, minor=minor, exists=exists,
-                               sysfsPath=sysfsPath, parents=parents)
-
-        if not exists:
-            # this is a request, not a partition -- it has no parents
-            self.req_disks = self.parents[:]
-            for dev in self.parents:
-                dev.removeChild()
-            self.parents = []
-
-        # FIXME: Validate partType, but only if this is a new partition
-        #        Otherwise, overwrite it with the partition's type.
-        self._partType = None
-        self.partedFlags = {}
-        self._partedPartition = None
-
-        # FIXME: Validate size, but only if this is a new partition.
-        #        For existing partitions we will get the size from
-        #        parted.
-
-        if self.exists:
-            self.installer.log.debug("Looking up parted Partition: %s" % self.path)
-            #self.partedPartition = parted.getPartitionByName(self.path)
-            self._partedPartition = self.disk.partedDisk.getPartitionByPath(self.path)
-            if not self._partedPartition:
-                raise DeviceError("cannot find parted partition instance")
-
-            # collect information about the partition from parted
-            self.probe()
-        else:
-            # XXX It might be worthwhile to create a shit-simple
-            #     PartitionRequest class and pass one to this constructor
-            #     for new partitions.
-            self.req_name = name
-            self.req_partType = partType
-            self.req_primary = primary
-            self.req_max_size = numeric_type(maxsize)
-            self.req_grow = grow
-            self.req_bootable = bootable
-
-            # req_size may be manipulated in the course of partitioning
-            self.req_size = self._size
-
-            # req_base_size will always remain constant
-            self.req_base_size = self._size
-
-            self.req_base_weight = weight
-
-    def __str__(self):
-        s = StorageDevice.__str__(self)
-        s += ("  grow = %(grow)s  max size = %(maxsize)s  bootable = %(bootable)s\n"
-              "  part type = %(partType)s  primary = %(primary)s\n"
-              "  partedPartition = %(partedPart)r  disk = %(disk)r" %
-              {"grow": self.req_grow, "maxsize": self.req_max_size,
-               "bootable": self.bootable, "partType": self.partType,
-               "primary": self.req_primary,
-               "partedPart": self.partedPartition, "disk": self.disk})
-        return s
-
-    def _setTargetSize(self, newsize):
-        if newsize != self.currentSize:
-            # change this partition's geometry in-memory so that other
-            # partitioning operations can complete (e.g., autopart)
-            self._targetSize = newsize
-            disk = self.disk.partedDisk
-
-            # resize the partition's geometry in memory
-            (constraint, geometry) = self._computeResize(self.partedPartition)
-            disk.setPartitionGeometry(partition=self.partedPartition,
-                                      constraint=constraint,
-                                      start=geometry.start, end=geometry.end)
-
-    @property
-    def path(self):
-        """ Device node representing this device. """
-        if not self.parents:
-            # Bogus, but code in various places compares devices by path
-            # So we must return something unique
-            return self.name
-
-        return "%s/%s" % (self.parents[0]._devDir, self.name)
-
-    @property
-    def partType(self):
-        """ Get the partition's type (as parted constant). """
-        try:
-            ptype = self.partedPartition.type
-        except AttributeError:
-            ptype = self._partType
-
-        if not self.exists and ptype is None:
-            ptype = self.req_partType
-
-        return ptype
-
-    @property
-    def isExtended(self):
-        return self.partType & parted.PARTITION_EXTENDED
-
-    @property
-    def isLogical(self):
-        return self.partType & parted.PARTITION_LOGICAL
-
-    @property
-    def isPrimary(self):
-        return self.partType == parted.PARTITION_NORMAL
-
-    @property
-    def isProtected(self):
-        return self.partType & parted.PARTITION_PROTECTED
-
-    def _getPartedPartition(self):
-        return self._partedPartition
-
-    def _setPartedPartition(self, partition):
-        """ Set this PartitionDevice's parted Partition instance. """
-        if partition is None:
-            path = None
-        elif isinstance(partition, parted.Partition):
-            path = partition.path
-        else:
-            raise ValueError("partition must be a parted.Partition instance")
-
-        self.installer.log.debug("Device %s new partedPartition %s has path %s" % (self.name, partition, path))
-        self._partedPartition = partition
-        self.updateName()
-
-    partedPartition = property(lambda d: d._getPartedPartition(),
-                               lambda d,p: d._setPartedPartition(p))
-
-    def _getWeight(self):
-        return self.req_base_weight
-
-    def _setWeight(self, weight):
-        self.req_base_weight = weight
-
-    weight = property(lambda d: d._getWeight(),
-                      lambda d,w: d._setWeight(w))
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        if not self.parents:
-            self.sysfsPath = ''
-
-        elif self.parents[0]._devDir == "/dev/mapper":
-            dm_node = dm.dm_node_from_name(self.name)
-            path = os.path.join("/sys", self.sysfsBlockDir, dm_node)
-            self.sysfsPath = os.path.realpath(path)[4:]
-
-        else:
-            StorageDevice.updateSysfsPath(self)
-
-    def updateName(self):
-        if self.partedPartition is None:
-            self._name = self.req_name
-        else:
-            self._name = \
-                devicePathToName(self.partedPartition.getDeviceNodeName())
-
-    def dependsOn(self, dep):
-        """ Return True if this device depends on dep. """
-        if isinstance(dep, PartitionDevice) and dep.isExtended and self.isLogical:
-            return True
-
-        return Device.dependsOn(self, dep)
-
-    def _setFormat(self, format):
-        """ Set the Device's format. """
-        StorageDevice._setFormat(self, format)
-
-    def _setBootable(self, bootable):
-        """ Set the bootable flag for this partition. """
-        if self.partedPartition:
-            if self.flagAvailable(parted.PARTITION_BOOT):
-                if bootable:
-                    self.setFlag(parted.PARTITION_BOOT)
-                else:
-                    self.unsetFlag(parted.PARTITION_BOOT)
-            else:
-                raise DeviceError(_("boot flag not available for this "
-                                    "partition"))
-
-            self._bootable = bootable
-        else:
-            self.req_bootable = bootable
-
-    def _getBootable(self):
-        return self._bootable or self.req_bootable
-
-    bootable = property(_getBootable, _setBootable)
-
-    def flagAvailable(self, flag):
-        if not self.partedPartition:
-            return
-
-        return self.partedPartition.isFlagAvailable(flag)
-
-    def getFlag(self, flag):
-        if not self.partedPartition or not self.flagAvailable(flag):
-            return
-
-        return self.partedPartition.getFlag(flag)
-
-    def setFlag(self, flag):
-        if not self.partedPartition or not self.flagAvailable(flag):
-            return
-
-        self.partedPartition.setFlag(flag)
-
-    def unsetFlag(self, flag):
-        if not self.partedPartition or not self.flagAvailable(flag):
-            return
-
-        self.partedPartition.unsetFlag(flag)
-
-    def probe(self):
-        """ Probe for any missing information about this device.
-
-            size, partition type, flags
-        """
-        if not self.exists:
-            return
-
-        # this is in MB
-        self._size = self.partedPartition.getSize()
-        self.targetSize = self._size
-
-        self._partType = self.partedPartition.type
-
-        self._bootable = self.getFlag(parted.PARTITION_BOOT)
-
-    def create(self, intf=None):
-        """ Create the device. """
-        if self.exists:
-            raise DeviceError("device already exists")
-
-        self.createParents()
-        self.setupParents()
-
-        self.disk.addPartition(self)
-        self.disk.commit()
-
-        self.partedPartition = self.disk.partedDisk.getPartitionByPath(self.path)
-
-        self.exists = True
-        self.setup()
-
-    def _computeResize(self, partition):
-        # compute new size for partition
-        currentGeom = partition.geometry
-        currentDev = currentGeom.device
-        newLen = long(self.targetSize * 1024 * 1024) / currentDev.sectorSize
-        newGeometry = parted.Geometry(device=currentDev,
-                                      start=currentGeom.start,
-                                      length=newLen)
-        constraint = parted.Constraint(exactGeom=newGeometry)
-
-        return (constraint, newGeometry)
-
-    def resize(self, intf=None):
-        """ Resize the device.
-
-            self.targetSize must be set to the new size.
-        """
-        if self.targetSize != self.currentSize:
-            # partedDisk has been restored to _origPartedDisk, so
-            # recalculate resize geometry because we may have new
-            # partitions on the disk, which could change constraints
-            partition = self.disk.partedDisk.getPartitionByPath(self.path)
-            (constraint, geometry) = self._computeResize(partition)
-
-            self.disk.partedDisk.setPartitionGeometry(partition=partition,
-                                                      constraint=constraint,
-                                                      start=geometry.start,
-                                                      end=geometry.end)
-
-            self.disk.commit()
-            self.notifyKernel()
-
-    def destroy(self):
-        """ Destroy the device. """
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-        if not self.sysfsPath:
-            return
-
-        if not self.isleaf:
-            raise DeviceError("Cannot destroy non-leaf device")
-
-        self.setupParents()
-        self.disk.removePartition(self)
-        self.disk.commit()
-
-        self.exists = False
-
-    def _getSize(self):
-        """ Get the device's size. """
-        size = self._size
-        if self.partedPartition:
-            # this defaults to MB
-            size = self.partedPartition.getSize()
-        return size
-
-    def _setSize(self, newsize):
-        """ Set the device's size (for resize, not creation).
-
-            Arguments:
-
-                newsize -- the new size (in MB)
-
-        """
-        if not self.exists:
-            raise DeviceError("device does not exist")
-
-        if newsize > self.disk.size:
-            raise ValueError("partition size would exceed disk size")
-
-        # this defaults to MB
-        maxAvailableSize = self.partedPartition.getMaxAvailableSize()
-
-        if newsize > maxAvailableSize:
-            raise ValueError("new size is greater than available space")
-
-         # now convert the size to sectors and update the geometry
-        geometry = self.partedPartition.geometry
-        physicalSectorSize = geometry.device.physicalSectorSize
-
-        new_length = (newsize * (1024 * 1024)) / physicalSectorSize
-        geometry.length = new_length
-
-    def _getDisk(self):
-        """ The disk that contains this partition."""
-        try:
-            disk = self.parents[0]
-        except IndexError:
-            disk = None
-        return disk
-
-    def _setDisk(self, disk):
-        """Change the parent.
-
-        Setting up a disk is not trivial.  It has the potential to change
-        the underlying object.  If necessary we must also change this object.
-        """
-        if self.disk:
-            self.disk.removeChild()
-
-        if disk:
-            self.parents = [disk]
-            disk.addChild()
-        else:
-            self.parents = []
-
-    disk = property(lambda p: p._getDisk(), lambda p,d: p._setDisk(d))
-
-    @property
-    def maxSize(self):
-        """ The maximum size this partition can be. """
-        # XXX: this is MB by default
-        maxPartSize = self.partedPartition.getMaxAvailableSize()
-
-        if self.format.maxSize > maxPartSize:
-            return maxPartSize
-        else:
-            return self.format.maxSize
-
-
-class OpticalDevice(StorageDevice):
-    """ An optical drive, eg: cdrom, dvd+r, &c.
-
-        XXX Is this useful?
-    """
-    _type = "cdrom"
-
-    def __init__(self, installer, name, major=None, minor=None, exists=None,
-                 format=None, parents=None, sysfsPath=''):
-        self.installer = installer
-        StorageDevice.__init__(self, installer, name, format=format,
-                               major=major, minor=minor, exists=True,
-                               parents=parents, sysfsPath=sysfsPath)
-
-    @property
-    def mediaPresent(self):
-        """ Return a boolean indicating whether or not the device contains
-            media.
-        """
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-        try:
-            fd = os.open(self.path, os.O_RDONLY)
-        except OSError as e:
-            # errno 123 = No medium found
-            if e.errno == 123:
-                return False
-            else:
-                return True
-        else:
-            os.close(fd)
-            return True
-
-    def eject(self):
-        """ Eject the drawer. """
-        #import _isys
-
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-        # XXX TODO
-        # Make a best effort attempt to do the eject.  If it fails, it's not
-        # critical.
-        #fd = os.open(self.path, os.O_RDONLY | os.O_NONBLOCK)
-
-        #try:
-        #    _isys.ejectcdrom(fd)
-        #except SystemError as e:
-        #    self.installer.log.warning("error ejecting cdrom %s: %s" % (self.name, e))
-
-        #os.close(fd)
-
-class DMDevice(StorageDevice):
-    """ A device-mapper device """
-    _type = "dm"
-    _devDir = "/dev/mapper"
-
-    def __init__(self, installer, name, format=None, size=None, dmUuid=None,
-                 target=None, exists=None, parents=None, sysfsPath=''):
-        """ Create a DMDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-
-            Keyword Arguments:
-
-                target -- the device-mapper target type (string)
-                size -- the device's size (units/format TBD)
-                dmUuid -- the device's device-mapper UUID
-                sysfsPath -- sysfs device path
-                format -- a DeviceFormat instance
-                parents -- a list of required Device instances
-                exists -- indicates whether this is an existing device
-        """
-        StorageDevice.__init__(self, installer, name, format=format, size=size,
-                               exists=exists,
-                               parents=parents, sysfsPath=sysfsPath)
-        self.target = target
-        self.dmUuid = dmUuid
-
-    def __str__(self):
-        s = StorageDevice.__str__(self)
-        s += ("  target = %(target)s  dmUuid = %(dmUuid)s" %
-              {"target": self.target, "dmUuid": self.dmUuid})
-        return s
-
-    @property
-    def fstabSpec(self):
-        """ Return the device specifier for use in /etc/fstab. """
-        return self.path
-
-    def updateSysfsPath(self):
-        """ Update this device's sysfs path. """
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-        if self.status:
-            dm_node = self.getDMNode()
-            path = os.path.join("/sys", self.sysfsBlockDir, dm_node)
-            self.sysfsPath = os.path.realpath(path)[4:]
-        else:
-            self.sysfsPath = ''
-
-    #def getTargetType(self):
-    #    return dm.getDmTarget(name=self.name)
-
-    def getDMNode(self):
-        """ Return the dm-X (eg: dm-0) device node for this device. """
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-        return dm.dm_node_from_name(self.name)
-
-    def _setName(self, name):
-        """ Set the device's map name. """
-        if self.status:
-            raise DeviceError("device is active")
-
-        self._name = name
-        #self.sysfsPath = "/dev/disk/by-id/dm-name-%s" % self.name
-
-    name = property(lambda d: d._name,
-                    lambda d,n: d._setName(n))
-
-
-class LVMVolumeGroupDevice(DMDevice):
-    """ An LVM Volume Group
-
-        XXX Maybe this should inherit from StorageDevice instead of
-            DMDevice since there's no actual device.
-    """
-    _type = "lvmvg"
-
-    def __init__(self, installer, name, parents, size=None, free=None,
-                 peSize=None, peCount=None, peFree=None, pvCount=None,
-                 lvNames=[], uuid=None, exists=None, sysfsPath=''):
-        """ Create a LVMVolumeGroupDevice instance.
-
-            Arguments:
-
-                name -- the device name (generally a device node's basename)
-                parents -- a list of physical volumes (StorageDevice)
-
-            Keyword Arguments:
-
-                peSize -- physical extent size (in MB)
-                exists -- indicates whether this is an existing device
-                sysfsPath -- sysfs device path
-
-                For existing VG's only:
-
-                    size -- the VG's size (in MB)
-                    free -- amount of free space in the VG
-                    peFree -- number of free extents
-                    peCount -- total number of extents
-                    pvCount -- number of PVs in this VG
-                    lvNames -- the names of this VG's LVs
-                    uuid -- the VG's UUID
-
-        """
-        self.pvClass = get_device_format_class("lvmpv")
-        if not self.pvClass:
-            raise DeviceError("cannot find 'lvmpv' class")
-
-        if isinstance(parents, list):
-            for dev in parents:
-                if not isinstance(dev.format, self.pvClass):
-                    raise ValueError("constructor requires a list of PVs")
-        elif not isinstance(parents.format, self.pvClass):
-            raise ValueError("constructor requires a list of PVs")
-
-        DMDevice.__init__(self, installer, name, parents=parents,
-                          exists=exists, sysfsPath=sysfsPath)
-
-        self.uuid = uuid
-        self.free = numeric_type(free)
-        self.peSize = numeric_type(peSize)
-        self.peCount = numeric_type(peCount)
-        self.peFree = numeric_type(peFree)
-        self.pvCount = numeric_type(pvCount)
-        self.lvNames = lvNames
-
-        # circular references, here I come
-        self._lvs = []
-
-        # TODO: validate peSize if given
-        if not self.peSize:
-            self.peSize = 4.0   # MB
-
-        #self.probe()
-
-    def __str__(self):
-        s = DMDevice.__str__(self)
-        s += ("  free = %(free)s  PE Size = %(peSize)s  PE Count = %(peCount)s\n"
-              "  PE Free = %(peFree)s  PV Count = %(pvCount)s\n"
-              "  LV Names = %(lvNames)s  modified = %(modified)s\n"
-              "  extents = %(extents)s  free space = %(freeSpace)s\n"
-              "  free extents = %(freeExtents)s\n"
-              "  PVs = %(pvs)s\n"
-              "  LVs = %(lvs)s" %
-              {"free": self.free, "peSize": self.peSize, "peCount": self.peCount,
-               "peFree": self.peFree, "pvCount": self.pvCount,
-               "lvNames": self.lvNames, "modified": self.isModified,
-               "extents": self.extents, "freeSpace": self.freeSpace,
-               "freeExtents": self.freeExtents, "pvs": self.pvs, "lvs": self.lvs})
-        return s
-
-    def probe(self):
-        """ Probe for any information about this device. """
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-    @property
-    def status(self):
-        """ The device's status (True means active). """
-        if not self.exists:
-            return False
-
-        # certainly if any of this VG's LVs are active then so are we
-        for lv in self.lvs:
-            if lv.status:
-                return True
-
-        # if any of our PVs are not active then we cannot be
-        for pv in self.pvs:
-            if not pv.status:
-                return False
-
-        # if we are missing some of our PVs we cannot be active
-        if len(self.pvs) != self.pvCount:
-            return False
-
-        return True
-
-    def _addDevice(self, device):
-        """ Add a new physical volume device to the volume group.
-
-            XXX This is for use by device probing routines and is not
-                intended for modification of the VG.
-        """
-        if not self.exists:
-            raise DeviceError("device does not exist")
-
-        if not isinstance(device.format, self.pvClass):
-            raise ValueError("addDevice requires a PV arg")
-
-        if self.uuid and device.format.vgUuid != self.uuid:
-            raise ValueError("UUID mismatch")
-
-        if device in self.pvs:
-            raise ValueError("device is already a member of this VG")
-
-        self.parents.append(device)
-        device.addChild()
-
-        # now see if the VG can be activated
-        if len(self.parents) == self.pvCount:
-            self.setup()
-
-    def _removeDevice(self, device):
-        """ Remove a physical volume from the volume group.
-
-            This is for cases like clearing of preexisting partitions.
-        """
-        try:
-            self.parents.remove(device)
-        except ValueError, e:
-            raise ValueError("cannot remove non-member PV device from VG")
-
-        device.removeChild()
-
-    def setup(self, intf=None):
-        """ Open, or set up, a device.
-
-            XXX we don't do anything like "vgchange -ay" because we don't
-                want all of the LVs activated, just the VG itself.
-        """
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-        if self.status:
-            return
-
-        if len(self.parents) < self.pvCount:
-            raise DeviceError("cannot activate VG with missing PV(s)")
-
-        self.setupParents()
-
-    def teardown(self, recursive=None):
-        """ Close, or tear down, a device. """
-        if not self.exists and not recursive:
-            raise DeviceError("device has not been created")
-
-        if self.status:
-            lvm.vgdeactivate(self.name)
-
-        if recursive:
-            self.teardownParents(recursive=recursive)
-
-    def create(self, intf=None):
-        """ Create the device. """
-        if self.exists:
-            raise DeviceError("device already exists")
-
-        pv_list = []
-        #for pv in self.parents:
-            # This is a little bit different from other devices in that
-            # for VG we need the PVs to be formatted before we can create
-            # the VG.
-        #    pv.create()
-        #    pv.format.create()
-        #    pv_list.append(pv.path)
-        pv_list = [pv.path for pv in self.parents]
-        self.createParents()
-        self.setupParents()
-        lvm.vgcreate(self.name, pv_list, self.peSize)
-        # FIXME set / update self.uuid here
-        self.exists = True
-        self.setup()
-
-    def destroy(self):
-        """ Destroy the device. """
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-        # set up the pvs since lvm needs access to them to do the vgremove
-        self.setupParents()
-
-        # this sometimes fails for some reason.
-        try:
-            lvm.vgreduce(self.name, [], rm=True)
-            lvm.vgremove(self.name)
-        except lvm.LVMError:
-            raise DeviceError("Could not completely remove VG %s" % self.name)
-        finally:
-            self.notifyKernel()
-            self.exists = False
-
-    def reduce(self, pv_list):
-        """ Remove the listed PVs from the VG. """
-        if not self.exists:
-            raise DeviceError("device has not been created")
-
-        lvm.vgreduce(self.name, pv_list)
-        # XXX do we need to notify the kernel?
-
-    def _addLogVol(self, lv):
-        """ Add an LV to this VG. """
-        if lv in self._lvs:
-            raise ValueError("lv is already part of this vg")
-
-        # verify we have the space, then add it
-        # do not verify for growing vg (because of ks)
-        if not lv.exists and \
-           not [pv for pv in self.pvs if getattr(pv, "req_grow", None)] and \
-           lv.size > self.freeSpace:
-            raise DeviceError("new lv is too large to fit in free space")
-
-        self._lvs.append(lv)
-
-    def _removeLogVol(self, lv):
-        """ Remove an LV from this VG. """
-        if lv not in self.lvs:
-            raise ValueError("specified lv is not part of this vg")
-
-        self._lvs.remove(lv)
-
-    def _addPV(self, pv):
-        """ Add a PV to this VG. """
-        if pv in self.pvs:
-            raise ValueError("pv is already part of this vg")
-
-        # for the time being we will not allow vgextend
-        if self.exists:
-            raise DeviceError("cannot add pv to existing vg")
-
-        self.parents.append(pv)
-        pv.addChild()
-
-    def _removePV(self, pv):
-        """ Remove an PV from this VG. """
-        if not pv in self.pvs:
-            raise ValueError("specified pv is not part of this vg")
-
-        # for the time being we will not allow vgreduce
-        if self.exists:
-            raise DeviceError("cannot remove pv from existing vg")
-
-        self.parents.remove(pv)
-        pv.removeChild()
-
-    # We can't rely on lvm to tell us about our size, free space, &c
-    # since we could have modifications queued, unless the VG and all of
-    # its PVs already exist.
-    #
-    #        -- liblvm may contain support for in-memory devices
-
-    @property
-    def isModified(self):
-        """ Return True if the VG has changes queued that LVM is unaware of. """
-        modified = True
-        if self.exists and not filter(lambda d: not d.exists, self.pvs):
-            modified = False
-
-        return modified
-
-    @property
-    def size(self):
-        """ The size of this VG """
-        # TODO: just ask lvm if isModified returns False
-
-        # sum up the sizes of the PVs and align to pesize
-        size = 0
-        for pv in self.pvs:
-            size += max(0, self.align(pv.size - pv.format.peStart))
-
-        return size
-
-    @property
-    def extents(self):
-        """ Number of extents in this VG """
-        # TODO: just ask lvm if isModified returns False
-
-        return self.size / self.peSize
-
-    @property
-    def freeSpace(self):
-        """ The amount of free space in this VG (in MB). """
-        # TODO: just ask lvm if isModified returns False
-
-        # total the sizes of any LVs
-        used = 0
-        size = self.size
-        self.installer.log.debug("%s size is %dMB" % (self.name, size))
-        for lv in self.lvs:
-            self.installer.log.debug("lv %s (%s) uses %dMB" % (lv.name, lv, lv.size))
-            used += self.align(lv.size, roundup=True)
-
-        free = self.size - used
-        self.installer.log.debug("vg %s has %dMB free" % (self.name, free))
-        return free
-
-    @property
-    def freeExtents(self):
-        """ The number of free extents in this VG. """
-        # TODO: just ask lvm if isModified returns False
-        return self.freeSpace / self.peSize
-
-    def align(self, size, roundup=None):
-        """ Align a size to a multiple of physical extent size. """
-        size = numeric_type(size)
-
-        if roundup:
-            round = math.ceil
-        else:
-            round = math.floor
-
-        # we want Kbytes as a float for our math
-        size *= 1024.0
-        pesize = self.peSize * 1024.0
-        return long((round(size / pesize) * pesize) / 1024)
-
-    @property
-    def pvs(self):
-        """ A list of this VG's PVs """
-        return self.parents[:]  # we don't want folks changing our list
-
-    @property
-    def lvs(self):
-        """ A list of this VG's LVs """
-        return self._lvs[:]     # we don't want folks changing our list
-
-    @property
-    def complete(self):
-        """Check if the vg has all its pvs in the system
-        Return True if complete.
-        """
-        return len(self.pvs) == self.pvCount or not self.exists
diff --git a/src/pomona/storage_old/devicetree.py b/src/pomona/storage_old/devicetree.py
deleted file mode 100644 (file)
index 5e38588..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-
-import os
-
-import formats
-
-from devices import *
-from errors import *
-from udev import *
-
-class DeviceTree:
-    def __init__(self, storage):
-        self.installer = storage.installer
-        self.storage = storage
-
-        # internal data members
-        self._devices = []
-        self._actions = []
-
-        self._ignoredDisks = []
-        for disk in self.storage.ignoredDisks:
-            self.addIgnoredDisk(disk)
-
-    def addIgnoredDisk(self, disk):
-        self._ignoredDisks.append(disk)
-        lvm.lvm_cc_addFilterRejectRegexp(disk)
-
-    def populate(self):
-        """ Locate all storage devices. """
-        # each iteration scans any devices that have appeared since the
-        # previous iteration
-        old_devices = []
-        ignored_devices = []
-        while True:
-            devices = []
-            new_devices = udev_get_block_devices()
-
-            for new_device in new_devices:
-                found = False
-                for old_device in old_devices:
-                    if old_device['name'] == new_device['name']:
-                        found = True
-                        break
-
-                if not found:
-                    devices.append(new_device)
-
-            if len(devices) == 0:
-                # nothing is changing -- we are finished building devices
-                break
-
-            old_devices = new_devices
-            self.installer.log.info("devices to scan: %s" % [d['name'] for d in devices])
-            for dev in devices:
-                self.addUdevDevice(dev)
-
-        # After having the complete tree we make sure that the system
-        # inconsistencies are ignored or resolved.
-        #for leaf in self.leaves:
-        #    self._handleInconsistencies(leaf)
-
-        #self.teardownAll()
-        try:
-            os.unlink("/etc/mdadm.conf")
-        except OSError:
-            self.installer.log.info("failed to unlink /etc/mdadm.conf")
-
-    def isIgnored(self, info):
-        """ Return True if info is a device we should ignore.
-
-            Arguments:
-
-                info -- a dict representing a udev db entry
-
-            TODO:
-
-                - filtering of SAN/FC devices
-                - filtering by driver?
-
-        """
-        sysfs_path = udev_device_get_sysfs_path(info)
-        name = udev_device_get_name(info)
-        if not sysfs_path:
-            return None
-
-        if name in self._ignoredDisks:
-            return True
-
-        for ignored in self._ignoredDisks:
-            if ignored == os.path.basename(os.path.dirname(sysfs_path)):
-                # this is a partition on a disk in the ignore list
-                return True
-
-        # Ignore partitions found on the raw disks which are part of a
-        # dmraidset
-        for set in self.getDevicesByType("dm-raid array"):
-            for disk in set.parents:
-                if disk.name == os.path.basename(os.path.dirname(sysfs_path)):
-                    return True
-
-        # Ignore loop and ram devices, we normally already skip these in
-        # udev.py: enumerate_block_devices(), but we can still end up trying
-        # to add them to the tree when they are slaves of other devices, this
-        # happens for example with the livecd
-        if name.startswith("loop") or name.startswith("ram"):
-            return True
-
-        # FIXME: check for virtual devices whose slaves are on the ignore list
-
-    def _removeDevice(self, dev, force=None, moddisk=True):
-        """ Remove a device from the tree.
-
-            Only leaves may be removed.
-        """
-        if dev not in self._devices:
-            raise ValueError("Device '%s' not in tree" % dev.name)
-
-        if not dev.isleaf and not force:
-            self.installer.log.debug("%s has %d kids" % (dev.name, dev.kids))
-            raise ValueError("Cannot remove non-leaf device '%s'" % dev.name)
-
-        # if this is a partition we need to remove it from the parted.Disk
-        if moddisk and isinstance(dev, PartitionDevice) and \
-                dev.disk is not None:
-            # if this partition hasn't been allocated it could not have
-            # a disk attribute
-            if dev.partedPartition.type == parted.PARTITION_EXTENDED and \
-                    len(dev.disk.partedDisk.getLogicalPartitions()) > 0:
-                raise ValueError("Cannot remove extended partition %s.  "
-                        "Logical partitions present." % dev.name)
-
-            dev.disk.partedDisk.removePartition(dev.partedPartition)
-
-        self._devices.remove(dev)
-        self.installer.log.debug("removed %s (%s) from device tree" % (dev.name,
-                                                                       dev.type))
-
-        for parent in dev.parents:
-            # Will this cause issues with garbage collection?
-            #   Do we care about garbage collection? At all?
-            parent.removeChild()
-
-    def registerAction(self, action):
-        """ Register an action to be performed at a later time.
-
-            Modifications to the Device instance are handled before we
-            get here.
-        """
-        self.installer.log.debug("Trying to register action: %s" % action)
-        if (action.isDestroy() or action.isResize() or \
-            (action.isCreate() and action.isFormat())) and \
-           action.device not in self._devices:
-            raise DeviceTreeError("device is not in the tree")
-        elif (action.isCreate() and action.isDevice()):
-            # this allows multiple create actions w/o destroy in between;
-            # we will clean it up before processing actions
-            #raise DeviceTreeError("device is already in the tree")
-            if action.device in self._devices:
-                self._removeDevice(action.device)
-            for d in self._devices:
-                if d.path == action.device.path:
-                    self._removeDevice(d)
-
-        if action.isCreate() and action.isDevice():
-            self._addDevice(action.device)
-        elif action.isDestroy() and action.isDevice():
-            self._removeDevice(action.device)
-        elif action.isCreate() and action.isFormat():
-            if isinstance(action.device.format, formats.fs.FS) and \
-               action.device.format.mountpoint in self.filesystems:
-                raise DeviceTreeError("mountpoint already in use")
-
-        self.installer.log.debug("registered action: %s" % action)
-        self._actions.append(action)
-
-    def _addDevice(self, newdev):
-        """ Add a device to the tree.
-
-            Raise ValueError if the device's identifier is already
-            in the list.
-        """
-        if newdev.path in [d.path for d in self._devices]:
-            raise ValueError("device is already in tree")
-
-        # make sure this device's parent devices are in the tree already
-        for parent in newdev.parents:
-            if parent not in self._devices:
-                raise DeviceTreeError("parent device not in tree")
-
-        self._devices.append(newdev)
-        self.installer.log.debug("Added %s (%s) to device tree" % (newdev.name, newdev.type))
-
-    def addUdevPartitionDevice(self, info):
-        name = udev_device_get_name(info)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        disk_name = os.path.basename(os.path.dirname(sysfs_path))
-        disk = self.getDeviceByName(disk_name)
-
-        if disk is None:
-            # create a device instance for the disk
-            path = os.path.dirname(os.path.realpath(sysfs_path))
-            new_info = udev_get_block_device(path)
-            if new_info:
-                self.addUdevDevice(new_info)
-                disk = self.getDeviceByName(disk_name)
-
-            if disk is None:
-                # if the current device is still not in
-                # the tree, something has gone wrong
-                self.installer.log.error("Failure scanning device %s" % disk_name)
-                return
-
-        try:
-            device = PartitionDevice(self.installer, name, sysfsPath=sysfs_path,
-                                     major=udev_device_get_major(info),
-                                     minor=udev_device_get_minor(info),
-                                     exists=True, parents=[disk])
-        except DeviceError:
-            # corner case sometime the kernel accepts a partition table
-            # which gets rejected by parted, in this case we will
-            # prompt to re-initialize the disk, so simply skip the
-            # faulty partitions.
-            return
-
-        self._addDevice(device)
-        return device
-
-    def addUdevDiskDevice(self, info):
-        name = udev_device_get_name(info)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        self.installer.log.debug("%s is a disk" % name)
-
-        try:
-            device = DiskDevice(self.installer, name,
-                              major=udev_device_get_major(info),
-                              minor=udev_device_get_minor(info),
-                              sysfsPath=sysfs_path,
-                              initlabel=False)
-        except DeviceUserDeniedFormatError: #drive not initialized?
-            self.addIgnoredDisk(name)
-            return
-
-        self._addDevice(device)
-        return device
-
-    def addUdevOpticalDevice(self, info):
-        # XXX should this be RemovableDevice instead?
-        #
-        # Looks like if it has ID_INSTANCE=0:1 we can ignore it.
-        device = OpticalDevice(self.installer, udev_device_get_name(info),
-                               major=udev_device_get_major(info),
-                               minor=udev_device_get_minor(info),
-                               sysfsPath=udev_device_get_sysfs_path(info))
-        self._addDevice(device)
-        return device
-
-    def addUdevDevice(self, info):
-        # FIXME: this should be broken up into more discrete chunks
-        name = udev_device_get_name(info)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-
-        if self.isIgnored(info):
-            self.installer.log.debug("Ignoring %s (%s)" % (name, sysfs_path))
-            return
-
-        self.installer.log.debug("Scanning %s (%s)..." % (name, sysfs_path))
-        device = self.getDeviceByName(name)
-
-        #
-        # The first step is to either look up or create the device
-        #
-        if udev_device_is_dm(info):
-            self.installer.log.debug("%s is a device-mapper device" % name)
-            # try to look up the device
-            if device is None and uuid:
-                # try to find the device by uuid
-                device = self.getDeviceByUuid(uuid)
-
-            if device is None:
-                device = self.addUdevDMDevice(info)
-        elif udev_device_is_md(info):
-            self.installer.log.debug("%s is an md device" % name)
-            if device is None and uuid:
-                # try to find the device by uuid
-                device = self.getDeviceByUuid(uuid)
-
-            if device is None:
-                device = self.addUdevMDDevice(info)
-        elif udev_device_is_cdrom(info):
-            self.installer.log.debug("%s is a cdrom" % name)
-            if device is None:
-                device = self.addUdevOpticalDevice(info)
-        elif udev_device_is_dmraid(info):
-            # This is special handling to avoid the "unrecognized disklabel"
-            # code since dmraid member disks won't have a disklabel. We
-            # use a StorageDevice because DiskDevices need disklabels.
-            # Quite lame, but it doesn't matter much since we won't use
-            # the StorageDevice instances for anything.
-            self.installer.log.debug("%s is part of a dmraid" % name)
-            if device is None:
-                device = StorageDevice(name,
-                                major=udev_device_get_major(info),
-                                minor=udev_device_get_minor(info),
-                                sysfsPath=sysfs_path, exists=True)
-                self._addDevice(device)
-        elif udev_device_is_disk(info):
-            if device is None:
-                device = self.addUdevDiskDevice(info)
-        elif udev_device_is_partition(info):
-            self.installer.log.debug("%s is a partition" % name)
-            if device is None:
-                device = self.addUdevPartitionDevice(info)
-
-        # now handle the device's formatting
-        self.handleUdevDeviceFormat(info, device)
-
-    def handleUdevDeviceFormat(self, info, device):
-        #self.installer.log.debug("%s" % info)
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        uuid = udev_device_get_uuid(info)
-        label = udev_device_get_label(info)
-        format_type = udev_device_get_format(info)
-
-        #self.installer.log.debug("Type is '%s'" % format_type)
-
-        format = None
-        if (not device) or (not format_type) or device.format.type:
-            # this device has no formatting or it has already been set up
-            # FIXME: this probably needs something special for disklabels
-            #self.installer.log.debug("bailing")
-            return
-
-        # set up the common arguments for the format constructor
-        args = [format_type]
-        kwargs = {"uuid": uuid,
-                  "label": label,
-                  "device": device.path,
-                  "exists": True}
-
-        # set up type-specific arguments for the format constructor
-        if format_type == "crypto_LUKS":
-            # luks/dmcrypt
-            kwargs["name"] = "luks-%s" % uuid
-        elif format_type == "linux_raid_member":
-            # mdraid
-            try:
-                kwargs["mdUuid"] = udev_device_get_md_uuid(info)
-            except KeyError:
-                self.installer.log.debug("mdraid member %s has no md uuid" % name)
-        elif format_type == "LVM2_member":
-            # lvm
-            try:
-                kwargs["vgName"] = udev_device_get_vg_name(info)
-            except KeyError as e:
-                self.installer.log.debug("PV %s has no vg_name" % name)
-            try:
-                kwargs["vgUuid"] = udev_device_get_vg_uuid(info)
-            except KeyError:
-                self.installer.log.debug("PV %s has no vg_uuid" % name)
-            try:
-                kwargs["peStart"] = udev_device_get_pv_pe_start(info)
-            except KeyError:
-                self.installer.log.debug("PV %s has no pe_start" % name)
-        elif format_type == "vfat":
-            # efi magic
-            if isinstance(device, PartitionDevice) and device.bootable:
-                efi = formats.getFormat("efi")
-                if efi.minSize <= device.size <= efi.maxSize:
-                    args[0] = "efi"
-        elif format_type == "hfs":
-            # apple bootstrap magic
-            if isinstance(device, PartitionDevice) and device.bootable:
-                apple = formats.getFormat("appleboot")
-                if apple.minSize <= device.size <= apple.maxSize:
-                    args[0] = "appleboot"
-
-        device.format = formats.getFormat(self.installer, *args, **kwargs)
-
-        #
-        # now do any special handling required for the device's format
-        #
-        if device.format.type == "luks":
-            self.handleUdevLUKSFormat(info, device)
-        elif device.format.type == "mdmember":
-            self.handleUdevMDMemberFormat(info, device)
-        elif device.format.type == "dmraidmember":
-            self.handleUdevDMRaidMemberFormat(info, device)
-        elif device.format.type == "lvmpv":
-            self.handleUdevLVMPVFormat(info, device)
-
-    def getDeviceByName(self, name):
-        #self.installer.log.debug("Looking for device '%s'..." % name)
-        found = None
-        for device in self._devices:
-            if device.name == name:
-                found = device
-                break
-
-        #self.installer.log.debug("Found %s" % found)
-        return found
-
-    def getDevicesByType(self, device_type):
-        # TODO: expand this to catch device format types
-        return [d for d in self._devices if d.type == device_type]
-
-    def getDevicesByInstance(self, device_class):
-        return [d for d in self._devices if isinstance(d, device_class)]
-
-    @property
-    def devices(self):
-        """ Dict with device path keys and Device values. """
-        devices = {}
-
-        for device in self._devices:
-            if device.path in devices:
-                raise DeviceTreeError("duplicate paths in device tree")
-
-            devices[device.path] = device
-
-        return devices
-
-    def getDependentDevices(self, dep):
-        """ Return a list of devices that depend on dep.
-
-            The list includes both direct and indirect dependents.
-        """
-        dependents = []
-
-        # special handling for extended partitions since the logical
-        # partitions and their deps effectively depend on the extended
-        logicals = []
-        if isinstance(dep, PartitionDevice) and dep.partType and \
-           dep.isExtended:
-            # collect all of the logicals on the same disk
-            for part in self.getDevicesByInstance(PartitionDevice):
-                if part.partType and part.isLogical and part.disk == dep.disk:
-                    logicals.append(part)
diff --git a/src/pomona/storage_old/devicetree.py_old b/src/pomona/storage_old/devicetree.py_old
deleted file mode 100644 (file)
index dfa0d5f..0000000
+++ /dev/null
@@ -1,977 +0,0 @@
-
-import os
-
-from udev import *
-
-class DeviceTree:
-    def __init__(self, storage):
-        self.installer = storage.installer
-        self.storage = storage
-
-        # internal data members
-        self._devices = []
-        self._actions = []
-
-        self._ignoredDisks = []
-        for disk in self.storage.ignoredDisks:
-            self.addIgnoredDisk(disk)
-
-    def addIgnoredDisk(self, disk):
-        self._ignoredDisks.append(disk)
-        lvm.lvm_cc_addFilterRejectRegexp(disk)
-
-    def _handleInconsistencies(self, device):
-        def reinitializeVG(vg):
-            # First we remove VG data
-            try:
-                vg.destroy()
-            except DeviceError:
-                # the pvremoves will finish the job.
-                self.installer.log.debug("There was an error destroying the VG %s." % vg.name)
-
-            # remove VG device from list.
-            self._removeDevice(vg)
-
-            for parent in vg.parents:
-                parent.format.destroy()
-
-                # Give the vg the a default format
-                kwargs = {"uuid": parent.uuid,
-                          "label": parent.diskLabel,
-                          "device": parent.path,
-                          "exists": parent.exists}
-                parent.format = formats.getFormat(*[""], **kwargs)
-
-        if device.type == "lvmvg":
-            paths = []
-            for parent in device.parents:
-                paths.append(parent.path)
-
-            # when zeroMbr is true he wont ask.
-            if not device.complete and (self.zeroMbr or \
-                    questionReinitILVM(intf=self.intf, \
-                        vg_name=device.name, pv_names=paths)):
-                reinitializeVG(device)
-
-            elif not device.complete:
-                # The user chose not to reinitialize.
-                # hopefully this will ignore the vg components too.
-                self._removeDevice(device)
-                lvm.lvm_cc_addFilterRejectRegexp(device.name)
-                lvm.blacklistVG(device.name)
-                for parent in device.parents:
-                    self._removeDevice(parent, moddisk=False)
-                    lvm.lvm_cc_addFilterRejectRegexp(parent.name)
-
-            return
-
-        elif device.type == "lvmlv":
-            # we might have already fixed this.
-            if device not in self._devices or \
-                    device.name in self._ignoredDisks:
-                return
-
-            paths = []
-            for parent in device.vg.parents:
-                paths.append(parent.path)
-
-            if not device.complete and (self.zeroMbr or \
-                questionReinitILVM(intf=self.intf, \
-                    lv_name=device.name, pv_names=paths)):
-
-                # destroy all lvs.
-                for lv in device.vg.lvs:
-                    lv.destroy()
-                    device.vg._removeLogVol(lv)
-                    self._removeDevice(lv)
-
-                reinitializeVG(device.vg)
-
-            elif not device.complete:
-                # ignore all the lvs.
-                for lv in device.vg.lvs:
-                    self._removeDevice(lv)
-                    lvm.lvm_cc_addFilterRejectRegexp(lv.name)
-                # ignore the vg
-                self._removeDevice(device.vg)
-                lvm.lvm_cc_addFilterRejectRegexp(device.vg.name)
-                lvm.blacklistVG(device.vg.name)
-                # ignore all the pvs
-                for parent in device.vg.parents:
-                    self._removeDevice(parent, moddisk=False)
-                    lvm.lvm_cc_addFilterRejectRegexp(parent.name)
-            return
-
-    def populate(self):
-        """ Locate all storage devices. """
-        # each iteration scans any devices that have appeared since the
-        # previous iteration
-        old_devices = []
-        ignored_devices = []
-        while True:
-            devices = []
-            new_devices = udev_get_block_devices()
-
-            for new_device in new_devices:
-                found = False
-                for old_device in old_devices:
-                    if old_device['name'] == new_device['name']:
-                        found = True
-                        break
-
-                if not found:
-                    devices.append(new_device)
-
-            if len(devices) == 0:
-                # nothing is changing -- we are finished building devices
-                break
-
-            old_devices = new_devices
-            self.installer.log.info("Devices to scan: %s" % [d['name'] for d in devices])
-            for dev in devices:
-                self.addUdevDevice(dev)
-
-        # After having the complete tree we make sure that the system
-        # inconsistencies are ignored or resolved.
-        for leaf in self.leaves:
-            self._handleInconsistencies(leaf)
-
-        self.teardownAll()
-        try:
-            os.unlink("/etc/mdadm.conf")
-        except OSError:
-            self.installer.log.info("Failed to unlink /etc/mdadm.conf")
-
-    def teardownAll(self):
-        """ Run teardown methods on all devices. """
-        for device in self.leaves:
-            try:
-                device.teardown(recursive=True)
-            except (DeviceError, DeviceFormatError, LVMError) as e:
-                log.info("teardown of %s failed: %s" % (device.name, e))
-
-    def setupAll(self):
-        """ Run setup methods on all devices. """
-        for device in self.leaves:
-            try:
-                device.setup()
-            except DeviceError as e:
-                log.debug("setup of %s failed: %s" % (device.name, e))
-
-    def _addDevice(self, newdev):
-        """ Add a device to the tree.
-
-            Raise ValueError if the device's identifier is already
-            in the list.
-        """
-        if newdev.path in [d.path for d in self._devices]:
-            raise ValueError("device is already in tree")
-
-        # make sure this device's parent devices are in the tree already
-        for parent in newdev.parents:
-            if parent not in self._devices:
-                raise DeviceTreeError("parent device not in tree")
-
-        self._devices.append(newdev)
-        self.installer.log.debug("added %s (%s) to device tree" % (newdev.name, newdev.type))
-
-    def isIgnored(self, info):
-        """ Return True if info is a device we should ignore.
-
-            Arguments:
-
-                info -- a dict representing a udev db entry
-
-            TODO:
-
-                - filtering of SAN/FC devices
-                - filtering by driver?
-
-        """
-        sysfs_path = udev_device_get_sysfs_path(info)
-        name = udev_device_get_name(info)
-        if not sysfs_path:
-            return None
-
-        if name in self._ignoredDisks:
-            return True
-
-        for ignored in self._ignoredDisks:
-            if ignored == os.path.basename(os.path.dirname(sysfs_path)):
-                # this is a partition on a disk in the ignore list
-                return True
-
-        # Ignore partitions found on the raw disks which are part of a
-        # dmraidset
-        for set in self.getDevicesByType("dm-raid array"):
-            for disk in set.parents:
-                if disk.name == os.path.basename(os.path.dirname(sysfs_path)):
-                    return True
-
-        # Ignore loop and ram devices, we normally already skip these in
-        # udev.py: enumerate_block_devices(), but we can still end up trying
-        # to add them to the tree when they are slaves of other devices, this
-        # happens for example with the livecd
-        if name.startswith("loop") or name.startswith("ram"):
-            return True
-
-        # FIXME: check for virtual devices whose slaves are on the ignore list
-
-    def handleUdevLUKSFormat(self, info, device):
-        if not device.format.uuid:
-            log.info("luks device %s has no uuid" % device.path)
-            return
-
-        # look up or create the mapped device
-        if not self.getDeviceByName(device.format.mapName):
-            passphrase = self.__luksDevs.get(device.format.uuid)
-            if passphrase:
-                device.format.passphrase = passphrase
-            else:
-                (passphrase, isglobal) = getLUKSPassphrase(self.intf,
-                                                    device,
-                                                    self.__passphrase)
-                if isglobal and device.format.status:
-                    self.__passphrase = passphrase
-
-            luks_device = LUKSDevice(device.format.mapName,
-                                     parents=[device],
-                                     exists=True)
-            try:
-                luks_device.setup()
-            except (LUKSError, CryptoError, DeviceError) as e:
-                sefl.installer.log.info("setup of %s failed: %s" % (device.format.mapName, e))
-                device.removeChild()
-            else:
-                self._addDevice(luks_device)
-        else:
-            self.installer.log.warning("luks device %s already in the tree"
-                        % device.format.mapName)
-
-    def handleUdevLVMPVFormat(self, info, device):
-        # lookup/create the VG and LVs
-        try:
-            vg_name = udev_device_get_vg_name(info)
-        except KeyError:
-            # no vg name means no vg -- we're done with this pv
-            return
-
-        vg_device = self.getDeviceByName(vg_name)
-        if vg_device:
-            vg_device._addDevice(device)
-            for lv in vg_device.lvs:
-                try:
-                    lv.setup()
-                except DeviceError as e:
-                    self.installer.log.info("setup of %s failed: %s" % (lv.name, e))
-        else:
-            try:
-                vg_uuid = udev_device_get_vg_uuid(info)
-                vg_size = udev_device_get_vg_size(info)
-                vg_free = udev_device_get_vg_free(info)
-                pe_size = udev_device_get_vg_extent_size(info)
-                pe_count = udev_device_get_vg_extent_count(info)
-                pe_free = udev_device_get_vg_free_extents(info)
-                pv_count = udev_device_get_vg_pv_count(info)
-            except (KeyError, ValueError) as e:
-                self.installer.log.warning("invalid data for %s: %s" % (name, e))
-                return
-
-            vg_device = LVMVolumeGroupDevice(vg_name,
-                                             device,
-                                             uuid=vg_uuid,
-                                             size=vg_size,
-                                             free=vg_free,
-                                             peSize=pe_size,
-                                             peCount=pe_count,
-                                             peFree=pe_free,
-                                             pvCount=pv_count,
-                                             exists=True)
-            self._addDevice(vg_device)
-
-            try:
-                lv_names = udev_device_get_lv_names(info)
-                lv_uuids = udev_device_get_lv_uuids(info)
-                lv_sizes = udev_device_get_lv_sizes(info)
-            except KeyError as e:
-                self.installer.log.warning("invalid data for %s: %s" % (name, e))
-                return
-
-            if not lv_names:
-                self.installer.log.debug("no LVs listed for VG %s" % name)
-                return
-
-            lvs = []
-            for (index, lv_name) in enumerate(lv_names):
-                name = "%s-%s" % (vg_name, lv_name)
-                lv_dev = self.getDeviceByName(name)
-                if lv_dev is None:
-                    lv_uuid = lv_uuids[index]
-                    lv_size = lv_sizes[index]
-                    lv_device = LVMLogicalVolumeDevice(lv_name,
-                                                       vg_device,
-                                                       uuid=lv_uuid,
-                                                       size=lv_size,
-                                                       exists=True)
-                    self._addDevice(lv_device)
-
-                    try:
-                        lv_device.setup()
-                    except DeviceError as e:
-                        self.installer.log.info("setup of %s failed: %s"
-                                            % (lv_device.name, e))
-
-    def handleUdevMDMemberFormat(self, info, device):
-        # either look up or create the array device
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-
-        md_array = self.getDeviceByUuid(device.format.mdUuid)
-        if device.format.mdUuid and md_array:
-            md_array._addDevice(device)
-        else:
-            # create the array with just this one member
-            # FIXME: why does this exact block appear twice?
-            try:
-                # level is reported as, eg: "raid1"
-                md_level = udev_device_get_md_level(info)
-                md_devices = int(udev_device_get_md_devices(info))
-                md_uuid = udev_device_get_md_uuid(info)
-            except (KeyError, ValueError) as e:
-                self.installer.log.warning("invalid data for %s: %s" % (name, e))
-                return
-
-            # find the first unused minor
-            minor = 0
-            while True:
-                if self.getDeviceByName("md%d" % minor):
-                    minor += 1
-                else:
-                    break
-
-            md_name = "md%d" % minor
-            md_array = MDRaidArrayDevice(md_name,
-                                         level=md_level,
-                                         minor=minor,
-                                         memberDevices=md_devices,
-                                         uuid=md_uuid,
-                                         sysfsPath=sysfs_path,
-                                         exists=True,
-                                         parents=[device])
-            try:
-                md_array.setup()
-            except (DeviceError, MDRaidError) as e:
-                self.installer.log.info("setup of md array %s failed: %s"
-                            % (md_array.name, e))
-            self._addDevice(md_array)
-
-    def handleUdevDMRaidMemberFormat(self, info, device):
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        uuid = udev_device_get_uuid(info)
-        major = udev_device_get_major(info)
-        minor = udev_device_get_minor(info)
-
-        def _all_ignored(rss):
-            retval = True
-            for rs in rss:
-                if rs.name not in self._ignoredDisks:
-                    retval = False
-                    break
-            return retval
-
-        # Have we already created the DMRaidArrayDevice?
-        rss = block.getRaidSetFromRelatedMem(uuid=uuid, name=name,
-                                            major=major, minor=minor)
-        if len(rss) == 0:
-            # we ignore the device in the hope that all the devices
-            # from this set will be ignored.
-            # FIXME: Can we reformat a raid device?
-            self.addIgnoredDisk(device.name)
-            return
-
-        # We ignore the device if all the rss are in self._ignoredDisks
-        if _all_ignored(rss):
-            self.addIgnoredDisk(device.name)
-            return
-
-        for rs in rss:
-            dm_array = self.getDeviceByName(rs.name)
-            if dm_array is not None:
-                # We add the new device.
-                dm_array._addDevice(device)
-            else:
-                # Activate the Raid set.
-                rs.activate(mknod=True)
-
-                # Create the DMRaidArray
-                if self.zeroMbr:
-                    cb = lambda: True
-                else:
-                    cb = lambda: questionInitializeDisk(self.intf,
-                                                        rs.name)
-
-                # Create the DMRaidArray
-                if not self.clearPartDisks or \
-                   rs.name in self.clearPartDisks:
-                    # if the disk contains protected partitions
-                    # we will not wipe the disklabel even if
-                    # clearpart --initlabel was specified
-                    initlabel = self.reinitializeDisks
-                    for protected in self.protectedPartitions:
-                        disk_name = re.sub(r'p\d+$', '', protected)
-                        if disk_name != protected and \
-                           disk_name == rs.name:
-                            initlabel = False
-                            break
-
-                try:
-                    dm_array = DMRaidArrayDevice(rs.name,
-                                                 raidSet=rs,
-                                                 parents=[device],
-                                                 initcb=cb,
-                                                 initlabel=initlabel)
-
-                    self._addDevice(dm_array)
-                    # Use the rs's object on the device.
-                    # pyblock can return the memebers of a set and the
-                    # device has the attribute to hold it.  But ATM we
-                    # are not really using it. Commenting this out until
-                    # we really need it.
-                    #device.format.raidmem = block.getMemFromRaidSet(dm_array,
-                    #        major=major, minor=minor, uuid=uuid, name=name)
-                except DeviceUserDeniedFormatError:
-                    # We should ignore the dmraid and its components
-                    self.addIgnoredDisk(rs.name)
-                    if _all_ignored(rss):
-                        self.addIgnoredDisk(device.name)
-                    rs.deactivate()
-
-    def handleUdevDeviceFormat(self, info, device):
-        name = udev_device_get_name(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        uuid = udev_device_get_uuid(info)
-        label = udev_device_get_label(info)
-        format_type = udev_device_get_format(info)
-
-        self.installer.log.debug("Type is '%s'" % format_type)
-
-        format = None
-        if (not device) or (not format_type) or device.format.type:
-            # this device has no formatting or it has already been set up
-            # FIXME: this probably needs something special for disklabels
-            return
-
-        # set up the common arguments for the format constructor
-        args = [format_type]
-        kwargs = {"uuid": uuid,
-                  "label": label,
-                  "device": device.path,
-                  "exists": True}
-
-        # set up type-specific arguments for the format constructor
-        if format_type == "crypto_LUKS":
-            # luks/dmcrypt
-            kwargs["name"] = "luks-%s" % uuid
-        elif format_type == "linux_raid_member":
-            # mdraid
-            try:
-                kwargs["mdUuid"] = udev_device_get_md_uuid(info)
-            except KeyError:
-                log.debug("mdraid member %s has no md uuid" % name)
-        elif format_type == "LVM2_member":
-            # lvm
-            try:
-                kwargs["vgName"] = udev_device_get_vg_name(info)
-            except KeyError as e:
-                log.debug("PV %s has no vg_name" % name)
-            try:
-                kwargs["vgUuid"] = udev_device_get_vg_uuid(info)
-            except KeyError:
-                log.debug("PV %s has no vg_uuid" % name)
-            try:
-                kwargs["peStart"] = udev_device_get_pv_pe_start(info)
-            except KeyError:
-                log.debug("PV %s has no pe_start" % name)
-        elif format_type == "vfat":
-            # efi magic
-            if isinstance(device, PartitionDevice) and device.bootable:
-                efi = formats.getFormat("efi")
-                if efi.minSize <= device.size <= efi.maxSize:
-                    args[0] = "efi"
-
-        device.format = formats.getFormat(*args, **kwargs)
-
-        #
-        # now do any special handling required for the device's format
-        #
-        if device.format.type == "luks":
-            self.handleUdevLUKSFormat(info, device)
-        elif device.format.type == "mdmember":
-            self.handleUdevMDMemberFormat(info, device)
-        elif device.format.type == "dmraidmember":
-            self.handleUdevDMRaidMemberFormat(info, device)
-        elif device.format.type == "lvmpv":
-            self.handleUdevLVMPVFormat(info, device)
-
-    def addUdevDMDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        for dmdev in self.devices.values():
-            if not isinstance(dmdev, DMDevice):
-                continue
-
-            try:
-                # there is a device in the tree already with the same
-                # major/minor as this one but with a different name
-                # XXX this is kind of racy
-                if dmdev.getDMNode() == os.path.basename(sysfs_path):
-                    # XXX should we take the name already in use?
-                    device = dmdev
-                    break
-            except DMError:
-                # This is a little lame, but the VG device is a DMDevice
-                # and it won't have a dm node. At any rate, this is not
-                # important enough to crash the install.
-                self.installer.log.debug("Failed to find dm node for %s" % dmdev.name)
-                continue
-
-        if device is None:
-            # we couldn't find it, so create it
-            # first, get a list of the slave devs and look them up
-            slaves = []
-            dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
-            slave_names = os.listdir(dir)
-            for slave_name in slave_names:
-                # if it's a dm-X name, resolve it to a map name first
-                if slave_name.startswith("dm-"):
-                    dev_name = dm.name_from_dm_node(slave_name)
-                else:
-                    dev_name = slave_name
-                slave_dev = self.getDeviceByName(dev_name)
-                if slave_dev:
-                    slaves.append(slave_dev)
-                else:
-                    # we haven't scanned the slave yet, so do it now
-                    path = os.path.normpath("%s/%s" % (dir, slave_name))
-                    new_info = udev_get_block_device(os.path.realpath(path))
-                    if new_info:
-                        self.addUdevDevice(new_info)
-                        if self.getDeviceByName(dev_name) is None:
-                            # if the current slave is still not in
-                            # the tree, something has gone wrong
-                            self.installer.log.error("Failure scanning device %s: could not add slave %s" % (name, dev_name))
-                            return
-
-            # try to get the device again now that we've got all the slaves
-            device = self.getDeviceByName(name)
-
-            if device is None and \
-                    udev_device_is_dmraid_partition(info, self):
-                diskname = udev_device_get_dmraid_partition_disk(info)
-                disk = self.getDeviceByName(diskname)
-                device = PartitionDevice(name, sysfsPath=sysfs_path,
-                                         major=udev_device_get_major(info),
-                                         minor=udev_device_get_minor(info),
-                                         exists=True, parents=[disk])
-                # DWL FIXME: call self.addUdevPartitionDevice here instead
-                self._addDevice(device)
-
-            # if we get here, we found all of the slave devices and
-            # something must be wrong -- if all of the slaves are in
-            # the tree, this device should be as well
-            if device is None:
-                self.installer.log.warning("Using generic DM device for %s" % name)
-                device = DMDevice(name, exists=True, parents=slaves)
-                self._addDevice(device)
-
-        return device
-
-    def addUdevMDDevice(self, info):
-        name = udev_device_get_name(info)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        slaves = []
-        dir = os.path.normpath("/sys/%s/slaves" % sysfs_path)
-        slave_names = os.listdir(dir)
-        for slave_name in slave_names:
-            # if it's a dm-X name, resolve it to a map name
-            if slave_name.startswith("dm-"):
-                dev_name = dm.name_from_dm_node(slave_name)
-            else:
-                dev_name = slave_name
-            slave_dev = self.getDeviceByName(dev_name)
-            if slave_dev:
-                slaves.append(slave_dev)
-            else:
-                # we haven't scanned the slave yet, so do it now
-                path = os.path.normpath("%s/%s" % (dir, slave_name))
-                new_info = udev_get_block_device(os.path.realpath(path))
-                if new_info:
-                    self.addUdevDevice(new_info)
-                    if self.getDeviceByName(dev_name) is None:
-                        # if the current slave is still not in
-                        # the tree, something has gone wrong
-                        self.installer.log.error("Failure scanning device %s: could not add slave %s" % (name, dev_name))
-                        return
-
-        # try to get the device again now that we've got all the slaves
-        device = self.getDeviceByName(name)
-
-        # if we get here, we found all of the slave devices and
-        # something must be wrong -- if all of the slaves we in
-        # the tree, this device should be as well
-        if device is None:
-            self.installer.log.warning("Using MD RAID device for %s" % name)
-            try:
-                # level is reported as, eg: "raid1"
-                md_level = udev_device_get_md_level(info)
-                md_devices = int(udev_device_get_md_devices(info))
-                md_uuid = udev_device_get_md_uuid(info)
-            except (KeyError, IndexError, ValueError) as e:
-                self.installer.log.warning("Invalid data for %s: %s" % (name, e))
-                return
-
-            device = MDRaidArrayDevice(name,
-                                       level=md_level,
-                                       memberDevices=md_devices,
-                                       uuid=md_uuid,
-                                       exists=True,
-                                       parents=slaves)
-            self._addDevice(device)
-
-        return device
-
-    def addUdevPartitionDevice(self, info):
-        name = udev_device_get_name(info)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        disk_name = os.path.basename(os.path.dirname(sysfs_path))
-        disk = self.getDeviceByName(disk_name)
-
-        if disk is None:
-            # create a device instance for the disk
-            path = os.path.dirname(os.path.realpath(sysfs_path))
-            new_info = udev_get_block_device(path)
-            if new_info:
-                self.addUdevDevice(new_info)
-                disk = self.getDeviceByName(disk_name)
-
-            if disk is None:
-                # if the current device is still not in
-                # the tree, something has gone wrong
-                self.installer.log.error("Failure scanning device %s" % disk_name)
-                return
-
-        try:
-            device = PartitionDevice(name, sysfsPath=sysfs_path,
-                                     major=udev_device_get_major(info),
-                                     minor=udev_device_get_minor(info),
-                                     exists=True, parents=[disk])
-        except DeviceError:
-            # corner case sometime the kernel accepts a partition table
-            # which gets rejected by parted, in this case we will
-            # prompt to re-initialize the disk, so simply skip the
-            # faulty partitions.
-            return
-
-        self._addDevice(device)
-        return device
-
-    def addUdevDiskDevice(self, info):
-        name = udev_device_get_name(info)
-        log_method_call(self, name=name)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-        device = None
-
-        kwargs = {}
-        diskType = DiskDevice
-        self.installer.log.debug("%s is a disk" % name)
-        cb = lambda: questionInitializeDisk(self.intf, name)
-
-        # if the disk contains protected partitions we will
-        # not wipe the disklabel even if clearpart --initlabel
-        # was specified
-
-        initlabel = self.reinitializeDisks
-        for protected in self.protectedPartitions:
-            _p = "/sys/%s/%s" % (sysfs_path, protected)
-            if os.path.exists(os.path.normpath(_p)):
-                initlabel = False
-                break
-
-        try:
-            device = diskType(name,
-                              major=udev_device_get_major(info),
-                              minor=udev_device_get_minor(info),
-                              sysfsPath=sysfs_path,
-                              initcb=cb, initlabel=initlabel, **kwargs)
-        except DeviceUserDeniedFormatError: #drive not initialized?
-            self.addIgnoredDisk(name)
-            return
-
-        self._addDevice(device)
-        return device
-
-    def addUdevDevice(self, info):
-        # FIXME: this should be broken up into more discrete chunks
-        name = udev_device_get_name(info)
-        uuid = udev_device_get_uuid(info)
-        sysfs_path = udev_device_get_sysfs_path(info)
-
-        if self.isIgnored(info):
-            self.installer.log.debug("Ignoring %s (%s)" % (name, sysfs_path))
-            return
-
-        self.installer.log.debug("Scanning %s (%s)..." % (name, sysfs_path))
-        device = self.getDeviceByName(name)
-
-        #
-        # The first step is to either look up or create the device
-        #
-        if udev_device_is_dm(info):
-            self.installer.log.debug("%s is a device-mapper device" % name)
-            # try to look up the device
-            if device is None and uuid:
-                # try to find the device by uuid
-                device = self.getDeviceByUuid(uuid)
-
-            if device is None:
-                device = self.addUdevDMDevice(info)
-        elif udev_device_is_md(info):
-            self.installer.log.debug("%s is an md device" % name)
-            if device is None and uuid:
-                # try to find the device by uuid
-                device = self.getDeviceByUuid(uuid)
-
-            if device is None:
-                device = self.addUdevMDDevice(info)
-        elif udev_device_is_cdrom(info):
-            self.installer.log.debug("%s is a cdrom" % name)
-            if device is None:
-                device = self.addUdevOpticalDevice(info)
-        elif udev_device_is_dmraid(info):
-            # This is special handling to avoid the "unrecognized disklabel"
-            # code since dmraid member disks won't have a disklabel. We
-            # use a StorageDevice because DiskDevices need disklabels.
-            # Quite lame, but it doesn't matter much since we won't use
-            # the StorageDevice instances for anything.
-            self.installer.log.debug("%s is part of a dmraid" % name)
-            if device is None:
-                device = StorageDevice(name,
-                                major=udev_device_get_major(info),
-                                minor=udev_device_get_minor(info),
-                                sysfsPath=sysfs_path, exists=True)
-                self._addDevice(device)
-        elif udev_device_is_disk(info):
-            if device is None:
-                device = self.addUdevDiskDevice(info)
-        elif udev_device_is_partition(info):
-            self.installer.log.debug("%s is a partition" % name)
-            if device is None:
-                device = self.addUdevPartitionDevice(info)
-
-        # now handle the device's formatting
-        self.handleUdevDeviceFormat(info, device)
-
-    def getDeviceBySysfsPath(self, path):
-        found = None
-        for device in self._devices:
-            if device.sysfsPath == path:
-                found = device
-                break
-
-        return found
-
-    def getDeviceByUuid(self, uuid):
-        found = None
-        for device in self._devices:
-            if device.uuid == uuid:
-                found = device
-                break
-            elif device.format.uuid == uuid:
-                found = device
-                break
-
-        return found
-
-    def getDeviceByLabel(self, label):
-        found = None
-        for device in self._devices:
-            _label = getattr(device.format, "label", None)
-            if not _label:
-                continue
-
-            if _label == label:
-                found = device
-                break
-
-        return found
-
-    def getDeviceByName(self, name):
-        self.installer.log.debug("Looking for device '%s'..." % name)
-        self.installer.log.debug("All devices: %s" % self._devices)
-        found = None
-        for device in self._devices:
-            if device.name == name:
-                found = device
-                break
-
-        self.installer.log.debug("Found %s" % found)
-        return found
-
-    def getDevicesByType(self, device_type):
-        # TODO: expand this to catch device format types
-        return [d for d in self._devices if d.type == device_type]
-
-    def getDevicesByInstance(self, device_class):
-        return [d for d in self._devices if isinstance(d, device_class)]
-
-    @property
-    def devices(self):
-        """ Dict with device path keys and Device values. """
-        devices = {}
-
-        for device in self._devices:
-            if device.path in devices:
-                raise DeviceTreeError("duplicate paths in device tree")
-
-            devices[device.path] = device
-
-        return devices
-
-    @property
-    def filesystems(self):
-        """ List of filesystems. """
-        #""" Dict with mountpoint keys and filesystem values. """
-        filesystems = []
-        for dev in self.leaves:
-            if dev.format and getattr(dev.format, 'mountpoint', None):
-                filesystems.append(dev.format)
-
-        return filesystems
-
-    @property
-    def uuids(self):
-        """ Dict with uuid keys and Device values. """
-        uuids = {}
-        for dev in self._devices:
-            try:
-                uuid = dev.uuid
-            except AttributeError:
-                uuid = None
-
-            if uuid:
-                uuids[uuid] = dev
-
-            try:
-                uuid = dev.format.uuid
-            except AttributeError:
-                uuid = None
-
-            if uuid:
-                uuids[uuid] = dev
-
-        return uuids
-
-    @property
-    def labels(self):
-        """ Dict with label keys and Device values.
-
-            FIXME: duplicate labels are a possibility
-        """
-        labels = {}
-        for dev in self._devices:
-            if dev.format and getattr(dev.format, "label", None):
-                labels[dev.format.label] = dev
-
-        return labels
-
-    @property
-    def leaves(self):
-        """ List of all devices upon which no other devices exist. """
-        leaves = [d for d in self._devices if d.isleaf]
-        return leaves
-
-    def getChildren(self, device):
-        """ Return a list of a device's children. """
-        return [c for c in self._devices if device in c.parents]
-
-    def resolveDevice(self, devspec, blkidTab=None, cryptTab=None):
-        # find device in the tree
-        device = None
-        if devspec.startswith("UUID="):
-            # device-by-uuid
-            uuid = devspec.partition("=")[2]
-            device = self.uuids.get(uuid)
-            if device is None:
-                self.installer.log.error("Failed to resolve device %s" % devspec)
-        elif devspec.startswith("LABEL="):
-            # device-by-label
-            label = devspec.partition("=")[2]
-            device = self.labels.get(label)
-            if device is None:
-                self.installer.log.error("Failed to resolve device %s" % devspec)
-        elif devspec.startswith("/dev/"):
-            # device path
-            device = self.devices.get(devspec)
-            if device is None:
-                if blkidTab:
-                    # try to use the blkid.tab to correlate the device
-                    # path with a UUID
-                    blkidTabEnt = blkidTab.get(devspec)
-                    if blkidTabEnt:
-                        self.installer.log.debug("Found blkid.tab entry for '%s'" % devspec)
-                        uuid = blkidTabEnt.get("UUID")
-                        if uuid:
-                            device = self.getDeviceByUuid(uuid)
-                            if device:
-                                devstr = device.name
-                            else:
-                                devstr = "None"
-                            self.installer.log.debug("Found device '%s' in tree" % devstr)
-                        if device and device.format and \
-                           device.format.type == "luks":
-                            map_name = device.format.mapName
-                            self.installer.log.debug("Luks device; map name is '%s'" % map_name)
-                            mapped_dev = self.getDeviceByName(map_name)
-                            if mapped_dev:
-                                device = mapped_dev
-
-                if device is None and cryptTab and \
-                   devspec.startswith("/dev/mapper/"):
-                    # try to use a dm-crypt mapping name to 
-                    # obtain the underlying device, possibly
-                    # using blkid.tab
-                    cryptTabEnt = cryptTab.get(devspec.split("/")[-1])
-                    if cryptTabEnt:
-                        luks_dev = cryptTabEnt['device']
-                        try:
-                            device = self.getChildren(luks_dev)[0]
-                        except IndexError as e:
-                            pass
-                elif device is None:
-                    # dear lvm: can we please have a few more device nodes
-                    #           for each logical volume?
-                    #           three just doesn't seem like enough.
-                    name = devspec[5:]      # strip off leading "/dev/"
-                    (vg_name, slash, lv_name) = name.partition("/")
-                    if lv_name and not "/" in lv_name:
-                        # looks like we may have one
-                        lv = "%s-%s" % (vg_name, lv_name)
-                        device = self.getDeviceByName(lv)
-
-        if device:
-            self.installer.log.debug("Resolved '%s' to '%s' (%s)" % (devspec, device.name, device.type))
-        else:
-            self.installer.log.debug("Failed to resolve '%s'" % devspec)
-        return device
diff --git a/src/pomona/storage_old/errors.py b/src/pomona/storage_old/errors.py
deleted file mode 100644 (file)
index 7a02dc0..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/python
-
-class StorageError(Exception):
-    pass
-
-# Device
-class DeviceError(StorageError):
-    pass
-
-class DeviceCreateError(DeviceError):
-    pass
-
-class DeviceDestroyError(DeviceError):
-    pass
-
-class DeviceResizeError(DeviceError):
-    pass
-
-class DeviceSetupError(DeviceError):
-    pass
-
-class DeviceTeardownError(DeviceError):
-    pass
-
-class DeviceUserDeniedFormatError(DeviceError):
-    pass
-
-# DeviceFormat
-class DeviceFormatError(StorageError):
-    pass
-
-class FormatCreateError(DeviceFormatError):
-    pass
-
-class FormatDestroyError(DeviceFormatError):
-    pass
-
-class FormatSetupError(DeviceFormatError):
-    pass
-
-class FormatTeardownError(DeviceFormatError):
-    pass
-
-class DMRaidMemberError(DeviceFormatError):
-    pass
-
-class FSError(DeviceFormatError):
-    pass
-
-class FSResizeError(FSError):
-    pass
-
-class FSMigrateError(FSError):
-    pass
-
-class LUKSError(DeviceFormatError):
-    pass
-
-class MDMemberError(DeviceFormatError):
-    pass
-
-class PhysicalVolumeError(DeviceFormatError):
-    pass
-
-class SwapSpaceError(DeviceFormatError):
-    pass
-
-# devicelibs
-class SwapError(StorageError):
-    pass
-
-class SuspendError(SwapError):
-    pass
-
-class OldSwapError(SwapError):
-    pass
-
-class MDRaidError(StorageError):
-    pass
-
-class DMError(StorageError):
-    pass
-
-class LVMError(StorageError):
-    pass
-
-class CryptoError(StorageError):
-    pass
-
-# DeviceTree
-class DeviceTreeError(StorageError):
-    pass
-
-# DeviceAction
-class DeviceActionError(StorageError):
-    pass
-
-# partitioning
-class PartitioningError(StorageError):
-    pass
-
-class PartitioningWarning(StorageError):
-    pass
-
-# udev
-class UdevError(StorageError):
-    pass
diff --git a/src/pomona/storage_old/formats/__init__.py b/src/pomona/storage_old/formats/__init__.py
deleted file mode 100644 (file)
index bd5d414..0000000
+++ /dev/null
@@ -1,318 +0,0 @@
-#!/usr/bin/python
-
-import os
-
-from util import notify_kernel
-from constants import *
-
-device_formats = {}
-def register_device_format(fmt_class):
-    if not issubclass(fmt_class, DeviceFormat):
-        raise ValueError("arg1 must be a subclass of DeviceFormat")
-
-    device_formats[fmt_class._type] = fmt_class
-    #log.debug("registered device format class %s as %s" % (fmt_class.__name__,
-    #                                                       fmt_class._type))
-
-default_fstypes = ("ext4", "ext3", "ext2")
-default_boot_fstypes = ("ext3", "ext2")
-def get_default_filesystem_type(boot=None):
-    if boot:
-        fstypes = default_boot_fstypes
-    else:
-        fstypes = default_fstypes
-
-    for fstype in fstypes:
-        try:
-            supported = get_device_format_class(fstype).supported
-        except AttributeError:
-            supported = None
-
-        if supported:
-            return fstype
-
-    raise DeviceFormatError("None of %s is supported by your kernel" % ",".join(fstypes))
-
-def getFormat(installer, fmt_type, *args, **kwargs):
-    """ Return a DeviceFormat instance based on fmt_type and args.
-
-        Given a device format type and a set of constructor arguments,
-        return a DeviceFormat instance.
-
-        Return None if no suitable format class is found.
-
-        Arguments:
-
-            fmt_type -- the name of the format type (eg: 'ext3', 'swap')
-
-        Keyword Arguments:
-
-            The keyword arguments may vary according to the format type,
-            but here is the common set:
-
-            device -- path to the device on which the format resides
-            uuid -- the UUID of the (preexisting) formatted device
-            exists -- whether or not the format exists on the device
-
-    """
-    fmt_class = get_device_format_class(fmt_type)
-    fmt = None
-    if fmt_class:
-        fmt = fmt_class(installer, *args, **kwargs)
-    try:
-        className = fmt.__class__.__name__
-    except AttributeError:
-        className = None
-    #log.debug("getFormat('%s') returning %s instance" % (fmt_type, className))
-    return fmt
-
-def collect_device_format_classes():
-    """ Pick up all device format classes from this directory.
-
-        Note: Modules must call register_device_format(FormatClass) in
-              order for the format class to be picked up.
-    """
-    dir = os.path.dirname(__file__)
-    for module_file in os.listdir(dir):
-        # make sure we're not importing this module
-        if module_file.endswith(".py") and module_file != __file__:
-            mod_name = module_file[:-3]
-            # imputil is deprecated in python 2.6
-            try:
-                globals()[mod_name] = __import__(mod_name, globals(), locals(), [], -1)
-            except ImportError, e:
-                #log.debug("import of device format module '%s' failed" % mod_name)
-                pass
-
-def get_device_format_class(fmt_type):
-    """ Return an appropriate format class based on fmt_type. """
-    if not device_formats:
-        collect_device_format_classes()
-
-    fmt = device_formats.get(fmt_type)
-    if not fmt:
-        for fmt_class in device_formats.values():
-            if fmt_type and fmt_type == fmt_class._name:
-                fmt = fmt_class
-                break
-            elif fmt_type in fmt_class._udevTypes:
-                fmt = fmt_class
-                break
-
-    # default to no formatting, AKA "Unknown"
-    if not fmt:
-        fmt = DeviceFormat
-    return fmt
-
-class DeviceFormat:
-    """ Generic device format. """
-    _type = None
-    _name = "Unknown"
-    _udevTypes = []
-    partedFlag = None
-    _formattable = False                # can be formatted
-    _supported = False                  # is supported
-    _linuxNative = False                # for clearpart
-    _resizable = False                  # can be resized
-    _bootable = False                   # can be used as boot
-    _migratable = False                 # can be migrated
-    _maxSize = 0                        # maximum size in MB
-    _minSize = 0                        # minimum size in MB
-    _dump = False
-    _check = False
-
-    def __init__(self, installer, *args, **kwargs):
-        """ Create a DeviceFormat instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this format's UUID
-                exists -- indicates whether this is an existing format
-
-        """
-        self.installer = installer
-
-        self.device = kwargs.get("device")
-        self.uuid = kwargs.get("uuid")
-        self.exists = kwargs.get("exists")
-        self.options = kwargs.get("options")
-        self._migrate = False
-
-        # don't worry about existence if this is a DeviceFormat instance
-        #if self.__class__ is DeviceFormat:
-        #    self.exists = True
-
-    def _setOptions(self, options):
-        self._options = options
-
-    def _getOptions(self):
-        return self._options
-
-    options = property(_getOptions, _setOptions)
-
-    def _setDevice(self, devspec):
-        if devspec and not devspec.startswith("/"):
-            raise ValueError("device must be a fully qualified path")
-        self._device = devspec
-
-    def _getDevice(self):
-        return self._device
-
-    device = property(lambda f: f._getDevice(),
-                      lambda f,d: f._setDevice(d),
-                      doc="Full path the device this format occupies")
-
-    @property
-    def name(self):
-        if self._name:
-            name = self._name
-        else:
-            name = self.type
-        return name
-
-    @property
-    def type(self):
-        return self._type
-
-    def probe(self):
-        pass
-
-    def notifyKernel(self):
-        if not self.device:
-            return
-
-        if self.device.startswith("/dev/mapper/"):
-            try:
-                name = dm_node_from_name(os.path.basename(self.device))
-            except Exception, e:
-                self.installer.log.warning("Failed to get dm node for %s" % self.device)
-                return
-        elif self.device:
-            name = os.path.basename(self.device)
-
-        path = get_sysfs_path_by_name(name)
-        try:
-            notify_kernel(path, action="change")
-        except Exception, e:
-            self.installer.log.warning("Failed to notify kernel of change: %s" % e)
-
-    def create(self, *args, **kwargs):
-        # allow late specification of device path
-        device = kwargs.get("device")
-        if device:
-            self.device = device
-
-        if not os.path.exists(self.device):
-            raise FormatCreateError("invalid device specification")
-
-    def destroy(self, *args, **kwargs):
-        # zero out the 1MB at the beginning and end of the device in the
-        # hope that it will wipe any metadata from filesystems that
-        # previously occupied this device
-        self.installer.log.debug("Zeroing out beginning and end of %s..." % self.device)
-        try:
-            fd = os.open(self.device, os.O_RDWR)
-            buf = '\0' * 1024 * 1024
-            os.write(fd, buf)
-            os.lseek(fd, -1024 * 1024, 2)
-            os.write(fd, buf)
-            os.close(fd)
-        except OSError as e:
-            if getattr(e, "errno", None) == 28: # No space left in device
-                pass
-            else:
-                self.installer.log.error("Error zeroing out %s: %s" % (self.device, e))
-            os.close(fd)
-        except Exception as e:
-            self.installer.log.error("error zeroing out %s: %s" % (self.device, e))
-            os.close(fd)
-
-        self.exists = False
-
-    def setup(self, *args, **kwargs):
-        if not self.exists:
-            raise FormatSetupError("format has not been created")
-
-        if self.status:
-            return
-
-        # allow late specification of device path
-        device = kwargs.get("device")
-        if device:
-            self.device = device
-
-        if not self.device or not os.path.exists(self.device):
-            raise FormatSetupError("invalid device specification")
-
-    def teardown(self, *args, **kwargs):
-        pass
-
-    @property
-    def status(self):
-        return (self.exists and
-                self.__class__ is not DeviceFormat and
-                isinstance(self.device, str) and
-                self.device and
-                os.path.exists(self.device))
-
-    @property
-    def formattable(self):
-        """ Can we create formats of this type? """
-        return self._formattable
-
-    @property
-    def supported(self):
-        """ Is this format a supported type? """
-        return self._supported
-
-    @property
-    def resizable(self):
-        """ Can formats of this type be resized? """
-        return self._resizable
-
-    @property
-    def bootable(self):
-        """ Is this format type suitable for a boot partition? """
-        return self._bootable
-
-    @property
-    def migratable(self):
-        """ Can formats of this type be migrated? """
-        return self._migratable
-
-    @property
-    def migrate(self):
-        return self._migrate
-
-    @property
-    def linuxNative(self):
-        """ Is this format type native to linux? """
-        return self._linuxNative
-
-    @property
-    def mountable(self):
-        """ Is this something we can mount? """
-        return False
-
-    @property
-    def dump(self):
-        """ Whether or not this format will be dumped by dump(8). """
-        return self._dump
-
-    @property
-    def check(self):
-        """ Whether or not this format is checked on boot. """
-        return self._check
-
-    @property
-    def maxSize(self):
-        """ Maximum size (in MB) for this format type. """
-        return self._maxSize
-
-    @property
-    def minSize(self):
-        """ Minimum size (in MB) for this format type. """
-        return self._minSize
-
-collect_device_format_classes()
diff --git a/src/pomona/storage_old/formats/fs.py b/src/pomona/storage_old/formats/fs.py
deleted file mode 100644 (file)
index 2a18fe7..0000000
+++ /dev/null
@@ -1,948 +0,0 @@
-# filesystems.py
-
-import os
-import tempfile
-
-import util
-
-from ..errors import *
-from . import DeviceFormat, register_device_format
-
-import gettext
-_ = lambda x: gettext.ldgettext("pomona", x)
-
-fs_configs = {}
-
-def get_kernel_filesystems():
-    fs_list = []
-    for line in open("/proc/filesystems").readlines():
-        fs_list.append(line.split()[-1])
-    return fs_list
-
-global kernel_filesystems
-kernel_filesystems = get_kernel_filesystems()
-
-class FS(DeviceFormat):
-    """ Filesystem class. """
-    _type = "Abstract Filesystem Class"  # fs type name
-    _mountType = None                    # like _type but for passing to mount
-    _name = None
-    _mkfs = ""                           # mkfs utility
-    _modules = []                        # kernel modules required for support
-    _resizefs = ""                       # resize utility
-    _labelfs = ""                        # labeling utility
-    _fsck = ""                           # fs check utility
-    _migratefs = ""                      # fs migration utility
-    _defaultFormatOptions = []           # default options passed to mkfs
-    _defaultMountOptions = ["defaults"]  # default options passed to mount
-    _defaultLabelOptions = []
-    _defaultCheckOptions = []
-    _defaultMigrateOptions = []
-    _migrationTarget = None
-    lostAndFoundContext = None
-
-    def __init__(self, installer, *args, **kwargs):
-        """ Create a FS instance.
-
-            Keyword Args:
-
-                device -- path to the device containing the filesystem
-                mountpoint -- the filesystem's mountpoint
-                label -- the filesystem label
-                uuid -- the filesystem UUID
-                mountopts -- mount options for the filesystem
-                size -- the filesystem's size in MiB
-                exists -- indicates whether this is an existing filesystem
-
-        """
-        if self.__class__ is FS:
-            raise TypeError("FS is an abstract class.")
-
-        self.installer = installer
-
-        DeviceFormat.__init__(self, self.installer, *args, **kwargs)
-        # TODO: fsprofiles and other ways to add format args
-        self.mountpoint = kwargs.get("mountpoint")
-        self.mountopts = kwargs.get("mountopts")
-        self.label = kwargs.get("label")
-
-        # filesystem size does not necessarily equal device size
-        self._size = kwargs.get("size")
-        self._mountpoint = None     # the current mountpoint when mounted
-        if self.exists:
-            self._size = self._getExistingSize()
-
-        self._targetSize = self._size
-
-        if self.supported:
-            self.loadModule()
-
-    def _setTargetSize(self, newsize):
-        """ Set a target size for this filesystem. """
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if newsize is None:
-            # unset any outstanding resize request
-            self._targetSize = None
-            return
-
-        if not self.minSize < newsize < self.maxSize:
-            raise ValueError("invalid target size request")
-
-        self._targetSize = newsize
-
-    def _getTargetSize(self):
-        """ Get this filesystem's target size. """
-        return self._targetSize
-
-    targetSize = property(_getTargetSize, _setTargetSize,
-                          doc="Target size for this filesystem")
-
-    def _getSize(self):
-        """ Get this filesystem's size. """
-        size = self._size
-        if self.resizable and self.targetSize != size:
-            size = self.targetSize
-        return size
-
-    size = property(_getSize, doc="This filesystem's size, accounting "
-                                  "for pending changes")
-
-    def _getExistingSize(self):
-        """ Determine the size of this filesystem.  Filesystem must
-            exist.
-        """
-        size = 0
-
-        if self.mountable:
-            origMountPoint = self._mountpoint
-
-            tmppath = tempfile.mkdtemp(prefix='getsize-', dir='/tmp')
-            self.mount(mountpoint=tmppath, options="ro")
-            buf = os.statvfs(tmppath)
-            self.unmount()
-            os.rmdir(tmppath)
-
-            self._mountpoint = origMountPoint
-
-            size = (buf.f_frsize * buf.f_blocks) / 1024.0 / 1024.0
-
-        return size
-
-    @property
-    def currentSize(self):
-        """ The filesystem's current actual size. """
-        size = 0
-        if self.exists:
-            size = self._size
-        return float(size)
-
-    def _getFormatOptions(self, options=None):
-        argv = []
-        if options and isinstance(options, list):
-            argv.extend(options)
-        argv.extend(self.defaultFormatOptions)
-        argv.append(self.device)
-        return argv
-
-    def doFormat(self, *args, **kwargs):
-        """ Create the filesystem.
-
-            Arguments:
-
-                None
-
-            Keyword Arguments:
-
-                intf -- InstallInterface instance
-                options -- list of options to pass to mkfs
-
-        """
-        intf = kwargs.get("intf")
-        options = kwargs.get("options")
-
-        if self.exists:
-            raise FormatCreateError("filesystem already exists", self.device)
-
-        if not self.formattable:
-            return
-
-        if not self.mkfsProg:
-            return
-
-        if self.exists:
-            return
-
-        if not os.path.exists(self.device):
-            raise FormatCreateError("device does not exist", self.device)
-
-        argv = self._getFormatOptions(options=options)
-
-        self.installer.window = None
-        self.installer.window = self.installer.intf.progressWindow(_("Formatting"),
-                                                                   _("Creating filesystem on %s...") % (self.device,),
-                                                                   100, pulse = True)
-
-        try:
-            rc = util.execWithPulseProgress(self.mkfsProg,
-                                             argv,
-                                             stdout="/dev/tty5",
-                                             stderr="/dev/tty5",
-                                             progress=w)
-        except Exception as e:
-            raise FormatCreateError(e, self.device)
-        finally:
-            if self.installer.window:
-                self.installer.window.pop()
-
-        if rc:
-            raise FormatCreateError("format failed: %s" % rc, self.device)
-
-        self.exists = True
-        self.notifyKernel()
-
-    def doMigrate(self, intf=None):
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self.migratable or not self.migrate:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSError("device does not exist")
-
-        # if journal already exists skip
-        if isys.ext2HasJournal(self.device):
-            self.installer.log.info("Skipping migration of %s, has a journal already." % self.device)
-            return
-
-        argv = self._defaultMigrateOptions[:]
-        argv.append(self.device)
-        try:
-            rc = iutil.execWithRedirect(self.migratefsProg,
-                                        argv,
-                                        stdout = "/dev/tty5",
-                                        stderr = "/dev/tty5",
-                                        searchPath = 1)
-        except Exception as e:
-            raise FSMigrateError("filesystem migration failed: %s" % e, self.device)
-
-        if rc:
-            raise FSMigrateError("filesystem migration failed: %s" % rc, self.device)
-
-        # the other option is to actually replace this instance with an
-        # instance of the new filesystem type.
-        self._type = self.migrationTarget
-
-    @property
-    def resizeArgs(self):
-        argv = [self.device, "%d" % (self.targetSize,)]
-        return argv
-
-    def doResize(self, *args, **kwargs):
-        """ Resize this filesystem to new size @newsize.
-
-            Arguments:
-
-                None
-
-            Keyword Arguments:
-
-                intf -- InstallInterface instance
-
-        """
-        intf = kwargs.get("intf")
-
-        if not self.exists:
-            raise FSResizeError("filesystem does not exist", self.device)
-
-        if not self.resizable:
-            raise FSResizeError("filesystem not resizable", self.device)
-
-        if self.targetSize == self.currentSize:
-            return
-
-        if not self.resizefsProg:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSResizeError("device does not exist", self.device)
-
-        self.doCheck(intf=intf)
-
-        w = None
-        if intf:
-            w = intf.progressWindow(_("Resizing"),
-                                    _("Resizing filesystem on %s...")
-                                    % (self.device,),
-                                    100, pulse = True)
-
-        try:
-            rc = iutil.execWithPulseProgress(self.resizefsProg,
-                                             self.resizeArgs,
-                                             stdout="/dev/tty5",
-                                             stderr="/dev/tty5",
-                                             progress=w)
-        except Exception as e:
-            raise FSResizeError(e, self.device)
-        finally:
-            if w:
-                w.pop()
-
-        if rc:
-            raise FSResizeError("resize failed: %s" % rc, self.device)
-
-        # XXX must be a smarter way to do this
-        self._size = self.targetSize
-        self.notifyKernel()
-
-    def _getCheckArgs(self):
-        argv = []
-        argv.extend(self.defaultCheckOptions)
-        argv.append(self.device)
-        return argv
-
-    def doCheck(self, intf=None):
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self.fsckProg:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSError("device does not exist")
-
-        w = None
-        if intf:
-            w = intf.progressWindow(_("Checking"),
-                                    _("Checking filesystem on %s...")
-                                    % (self.device),
-                                    100, pulse = True)
-
-        try:
-            rc = iutil.execWithPulseProgress(self.fsckProg,
-                                             self._getCheckArgs(),
-                                             stdout="/dev/tty5",
-                                             stderr="/dev/tty5",
-                                             progress = w)
-        except Exception as e:
-            raise FSError("filesystem check failed: %s" % e)
-        finally:
-            if w:
-                w.pop()
-
-        if rc >= 4:
-            raise FSError("filesystem check failed: %s" % rc)
-
-    def loadModule(self):
-        """Load whatever kernel module is required to support this filesystem."""
-        global kernel_filesystems
-
-        if not self._modules or self.mountType in kernel_filesystems:
-            return
-
-        for module in self._modules:
-            try:
-                rc = iutil.execWithRedirect("modprobe", [module],
-                                            stdout="/dev/tty5", stderr="/dev/tty5",
-                                            searchPath=1)
-            except Exception as e:
-                self.installer.log.error("Could not load kernel module %s: %s" % (module, e))
-                self._supported = False
-                return
-
-            if rc:
-                self.installer.log.error("Could not load kernel module %s" % module)
-                self._supported = False
-                return
-
-        # If we successfully loaded a kernel module, for this filesystem, we
-        # also need to update the list of supported filesystems.
-        kernel_filesystems = get_kernel_filesystems()
-
-    def mount(self, *args, **kwargs):
-        """ Mount this filesystem.
-
-            Arguments:
-
-                None
-
-            Keyword Arguments:
-
-                options -- mount options (overrides all other option strings)
-                chroot -- prefix to apply to mountpoint
-                mountpoint -- mountpoint (overrides self.mountpoint)
-        """
-        options = kwargs.get("options", "")
-        chroot = kwargs.get("chroot", "/")
-        mountpoint = kwargs.get("mountpoint")
-
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not mountpoint:
-            mountpoint = self.mountpoint
-
-        if not mountpoint:
-            raise FSError("no mountpoint given")
-
-        if self.status:
-            return
-
-        if not isinstance(self, NoDevFS) and not os.path.exists(self.device):
-            raise FSError("device %s does not exist" % self.device)
-
-        # XXX os.path.join is FUBAR:
-        #
-        #         os.path.join("/mnt/foo", "/") -> "/"
-        #
-        #mountpoint = os.path.join(chroot, mountpoint)
-        mountpoint = os.path.normpath("%s/%s" % (chroot, mountpoint))
-        util.mkdirChain(mountpoint)
-
-        # passed in options override default options
-        if not options or not isinstance(options, str):
-            options = self.options
-
-        try:
-            rc = isys.mount(self.device, mountpoint,
-                            fstype=self.mountType,
-                            options=options,
-                            bindMount=isinstance(self, BindFS))
-        except Exception as e:
-            raise FSError("mount failed: %s" % e)
-
-        if rc:
-            raise FSError("mount failed: %s" % rc)
-
-        self._mountpoint = mountpoint
-
-    def unmount(self):
-        """ Unmount this filesystem. """
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self._mountpoint:
-            # not mounted
-            return
-
-        if not os.path.exists(self._mountpoint):
-            raise FSError("mountpoint does not exist")
-
-        rc = isys.umount(self._mountpoint, removeDir = False)
-        if rc:
-            raise FSError("umount failed")
-
-        self._mountpoint = None
-
-    def _getLabelArgs(self, label):
-        argv = []
-        argv.extend(self.defaultLabelOptions)
-        argv.extend([self.device, label])
-        return argv
-
-    def writeLabel(self, label):
-        """ Create a label for this filesystem. """
-        if not self.exists:
-            raise FSError("filesystem has not been created")
-
-        if not self.labelfsProg:
-            return
-
-        if not os.path.exists(self.device):
-            raise FSError("device does not exist")
-
-        argv = self._getLabelArgs(label)
-        rc = iutil.execWithRedirect(self.labelfsProg,
-                                    argv,
-                                    stderr="/dev/tty5",
-                                    searchPath=1)
-        if rc:
-            raise FSError("label failed")
-
-        self.label = label
-        self.notifyKernel()
-
-    @property
-    def isDirty(self):
-        return False
-
-    @property
-    def mkfsProg(self):
-        """ Program used to create filesystems of this type. """
-        return self._mkfs
-
-    @property
-    def fsckProg(self):
-        """ Program used to check filesystems of this type. """
-        return self._fsck
-
-    @property
-    def resizefsProg(self):
-        """ Program used to resize filesystems of this type. """
-        return self._resizefs
-
-    @property
-    def labelfsProg(self):
-        """ Program used to manage labels for this filesystem type. """
-        return self._labelfs
-
-    @property
-    def migratefsProg(self):
-        """ Program used to migrate filesystems of this type. """
-        return self._migratefs
-
-    @property
-    def migrationTarget(self):
-        return self._migrationTarget
-
-    @property
-    def utilsAvailable(self):
-        # we aren't checking for fsck because we shouldn't need it
-        for prog in [self.mkfsProg, self.resizefsProg, self.labelfsProg]:
-            if not prog:
-                continue
-
-            if not filter(lambda d: os.access("%s/%s" % (d, prog), os.X_OK),
-                          os.environ["PATH"].split(":")):
-                return False
-
-        return True
-
-    @property
-    def supported(self):
-        log_method_call(self, supported=self._supported)
-        return self._supported and self.utilsAvailable
-
-    @property
-    def mountable(self):
-        return (self.mountType in kernel_filesystems) or \
-               (os.access("/sbin/mount.%s" % (self.mountType,), os.X_OK))
-
-    @property
-    def defaultFormatOptions(self):
-        """ Default options passed to mkfs for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultFormatOptions[:]
-
-    @property
-    def defaultMountOptions(self):
-        """ Default options passed to mount for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultMountOptions[:]
-
-    @property
-    def defaultLabelOptions(self):
-        """ Default options passed to labeler for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultLabelOptions[:]
-
-    @property
-    def defaultCheckOptions(self):
-        """ Default options passed to checker for this filesystem type. """
-        # return a copy to prevent modification
-        return self._defaultCheckOptions[:]
-
-    def _getOptions(self):
-        options = ",".join(self.defaultMountOptions)
-        if self.mountopts:
-            # XXX should we clobber or append?
-            options = self.mountopts
-        return options
-
-    def _setOptions(self, options):
-        self.mountopts = options
-
-    options = property(_getOptions, _setOptions)
-
-    @property
-    def migratable(self):
-        """ Can filesystems of this type be migrated? """
-        return bool(self._migratable and self.migratefsProg and
-                    filter(lambda d: os.access("%s/%s"
-                                               % (d, self.migratefsProg,),
-                                               os.X_OK),
-                           os.environ["PATH"].split(":")) and
-                    self.migrationTarget)
-
-    def _setMigrate(self, migrate):
-        if not migrate:
-            self._migrate = migrate
-            return
-
-        if self.migratable and self.exists:
-            self._migrate = migrate
-        else:
-            raise ValueError("cannot set migrate on non-migratable filesystem")
-
-    migrate = property(lambda f: f._migrate, lambda f,m: f._setMigrate(m))
-
-    @property
-    def type(self):
-        _type = self._type
-        if self.migrate:
-            _type = self.migrationTarget
-
-        return _type
-
-    @property
-    def mountType(self):
-        if not self._mountType:
-            self._mountType = self._type
-
-        return self._mountType
-
-    # These methods just wrap filesystem-specific methods in more
-    # generically named methods so filesystems and formatted devices
-    # like swap and LVM physical volumes can have a common API.
-    def create(self, *args, **kwargs):
-        if self.exists:
-            raise FSError("filesystem already exists")
-
-        DeviceFormat.create(self, *args, **kwargs)
-
-        return self.doFormat(*args, **kwargs)
-
-    def setup(self, *args, **kwargs):
-        """ Mount the filesystem.
-
-            THe filesystem will be mounted at the directory indicated by
-            self.mountpoint.
-        """
-        return self.mount(**kwargs)
-
-    def teardown(self, *args, **kwargs):
-        return self.unmount(*args, **kwargs)
-
-    @property
-    def status(self):
-        # FIXME check /proc/mounts or similar
-        if not self.exists:
-            return False
-        return self._mountpoint is not None
-
-
-class Ext2FS(FS):
-    """ ext2 filesystem. """
-    _type = "ext2"
-    _mkfs = "mke2fs"
-    _modules = ["ext2"]
-    _resizefs = "resize2fs"
-    _labelfs = "e2label"
-    _fsck = "e2fsck"
-    _formattable = True
-    _supported = True
-    _resizable = True
-    _bootable = True
-    _linuxNative = True
-    _maxSize = 8 * 1024 * 1024
-    _minSize = 0
-    _defaultFormatOptions = []
-    _defaultMountOptions = ["defaults"]
-    _defaultCheckOptions = ["-f", "-p", "-C", "0"]
-    _dump = True
-    _check = True
-    _migratable = True
-    _migrationTarget = "ext3"
-    _migratefs = "tune2fs"
-    _defaultMigrateOptions = ["-j"]
-
-    @property
-    def minSize(self):
-        """ Minimum size for this filesystem in MB. """
-        size = self._minSize
-        if self.exists and os.path.exists(self.device):
-            buf = util.execWithCapture(self.resizefsProg,
-                                        ["-P", self.device],
-                                        stderr="/dev/tty5")
-            size = None
-            for line in buf.splitlines():
-                if "minimum size of the filesystem:" not in line:
-                    continue
-
-                (text, sep, minSize) = line.partition(": ")
-
-                size = int(minSize) / 1024.0
-
-            if size is None:
-                self.installer.log.warning("failed to get minimum size for %s filesystem "
-                            "on %s" % (self.mountType, self.device))
-                size = self._minSize
-
-        return size
-
-    @property
-    def isDirty(self):
-        return isys.ext2IsDirty(self.device)
-
-    @property
-    def resizeArgs(self):
-        argv = ["-p", self.device, "%dM" % (self.targetSize,)]
-        return argv
-
-register_device_format(Ext2FS)
-
-
-class Ext3FS(Ext2FS):
-    """ ext3 filesystem. """
-    _type = "ext3"
-    _defaultFormatOptions = ["-t", "ext3"]
-    _migrationTarget = "ext4"
-    _modules = ["ext3"]
-    _defaultMigrateOptions = ["-O", "extents"]
-
-    @property
-    def migratable(self):
-        """ Can filesystems of this type be migrated? """
-        return (flags.cmdline.has_key("ext4migrate") and
-                Ext2FS.migratable)
-
-register_device_format(Ext3FS)
-
-
-class Ext4FS(Ext3FS):
-    """ ext4 filesystem. """
-    _type = "ext4"
-    _bootable = False
-    _defaultFormatOptions = ["-t", "ext4"]
-    _migratable = False
-    _modules = ["ext4"]
-
-register_device_format(Ext4FS)
-
-
-class FATFS(FS):
-    """ FAT filesystem. """
-    _type = "vfat"
-    _mkfs = "mkdosfs"
-    _modules = ["vfat"]
-    _labelfs = "dosfslabel"
-    _fsck = "dosfsck"
-    _formattable = True
-    _maxSize = 1024 * 1024
-    _defaultMountOptions = ["umask=0077", "shortname=winnt"]
-
-register_device_format(FATFS)
-
-
-class EFIFS(FATFS):
-    _type = "efi"
-    _mountType = "vfat"
-    _modules = ["vfat"]
-    _name = "EFI System Partition"
-    _minSize = 50
-    _maxSize = 256
-    _bootable = True
-
-    @property
-    def supported(self):
-        import platform
-        p = platform.getPlatform(None)
-        return (isinstance(p, platform.EFI) and
-                p.isEfi and
-                self.utilsAvailable)
-
-register_device_format(EFIFS)
-
-
-class BTRFS(FS):
-    """ btrfs filesystem """
-    _type = "btrfs"
-    _mkfs = "mkfs.btrfs"
-    _modules = ["btrfs"]
-    _resizefs = "btrfsctl"
-    _formattable = True
-    _linuxNative = True
-    _bootable = False
-    _maxLabelChars = 256
-    _supported = True
-    _dump = True
-    _check = True
-    _maxSize = 16 * 1024 * 1024
-
-    def _getFormatOptions(self, options=None):
-        argv = []
-        if options and isinstance(options, list):
-            argv.extend(options)
-        argv.extend(self.defaultFormatOptions)
-        if self.label:
-            argv.extend(["-L", self.label])
-        argv.append(self.device)
-        return argv
-
-    @property
-    def resizeArgs(self):
-        argv = ["-r", "%dm" % (self.targetSize,), self.device]
-        return argv
-
-register_device_format(BTRFS)
-
-class XFS(FS):
-    """ XFS filesystem """
-    _type = "xfs"
-    _mkfs = "mkfs.xfs"
-    _modules = ["xfs"]
-    _labelfs = "xfs_admin"
-    _defaultFormatOptions = ["-f"]
-    _defaultLabelOptions = ["-L"]
-    _maxLabelChars = 16
-    _maxSize = 16 * 1024 * 1024
-    _formattable = True
-    _linuxNative = True
-    _supported = True
-    _dump = True
-    _check = True
-
-register_device_format(XFS)
-
-class NTFS(FS):
-    """ ntfs filesystem. """
-    _type = "ntfs"
-    _resizefs = "ntfsresize"
-    _fsck = "ntfsresize"
-    _resizable = True
-    _minSize = 1
-    _maxSize = 16 * 1024 * 1024
-    _defaultMountOptions = ["defaults"]
-    _defaultCheckOptions = ["-c"]
-
-    @property
-    def minSize(self):
-        """ The minimum filesystem size in megabytes. """
-        size = self._minSize
-        if self.exists and os.path.exists(self.device):
-            minSize = None
-            buf = iutil.execWithCapture(self.resizefsProg,
-                                        ["-m", self.device],
-                                        stderr = "/dev/tty5")
-            for l in buf.split("\n"):
-                if not l.startswith("Minsize"):
-                    continue
-                try:
-                    min = l.split(":")[1].strip()
-                    minSize = int(min) + 250
-                except Exception, e:
-                    minSize = None
-                    self.installer.log.warning("Unable to parse output for minimum size on %s: %s" %(self.device, e))
-
-            if minSize is None:
-                self.installer.log.warning("Unable to discover minimum size of filesystem "
-                            "on %s" %(self.device,))
-            else:
-                size = minSize
-
-        return size
-
-    @property
-    def resizeArgs(self):
-        # You must supply at least two '-f' options to ntfsresize or
-        # the proceed question will be presented to you.
-        argv = ["-ff", "-s", "%dM" % (self.targetSize,), self.device]
-        return argv
-
-register_device_format(NTFS)
-
-
-# if this isn't going to be mountable it might as well not be here
-class NFS(FS):
-    """ NFS filesystem. """
-    _type = "nfs"
-    _modules = ["nfs"]
-
-    def _deviceCheck(self, devspec):
-        if devspec is not None and ":" not in devspec:
-            raise ValueError("device must be of the form <host>:<path>")
-
-    @property
-    def mountable(self):
-        return False
-
-    def _setDevice(self, devspec):
-        self._deviceCheck(devspec)
-        self._device = devspec
-
-    def _getDevice(self):
-        return self._device
-
-    device = property(lambda f: f._getDevice(),
-                      lambda f,d: f._setDevice(d),
-                      doc="Full path the device this format occupies")
-
-register_device_format(NFS)
-
-
-class NFSv4(NFS):
-    """ NFSv4 filesystem. """
-    _type = "nfs4"
-    _modules = ["nfs4"]
-
-register_device_format(NFSv4)
-
-
-class Iso9660FS(FS):
-    """ ISO9660 filesystem. """
-    _type = "iso9660"
-    _formattable = False
-    _supported = True
-    _resizable = False
-    _bootable = False
-    _linuxNative = False
-    _dump = False
-    _check = False
-    _migratable = False
-    _defaultMountOptions = ["ro"]
-
-register_device_format(Iso9660FS)
-
-
-class NoDevFS(FS):
-    """ nodev filesystem base class """
-    _type = "nodev"
-
-    def __init__(self, *args, **kwargs):
-        FS.__init__(self, *args, **kwargs)
-        self.exists = True
-        self.device = self.type
-
-    def _setDevice(self, devspec):
-        self._device = devspec
-
-register_device_format(NoDevFS)
-
-
-class DevPtsFS(NoDevFS):
-    """ devpts filesystem. """
-    _type = "devpts"
-    _defaultMountOptions = ["gid=5", "mode=620"]
-
-register_device_format(DevPtsFS)
-
-
-# these don't really need to be here
-class ProcFS(NoDevFS):
-    _type = "proc"
-
-register_device_format(ProcFS)
-
-
-class SysFS(NoDevFS):
-    _type = "sysfs"
-
-register_device_format(SysFS)
-
-
-class TmpFS(NoDevFS):
-    _type = "tmpfs"
-
-register_device_format(TmpFS)
-
-
-class BindFS(FS):
-    _type = "bind"
-
-    @property
-    def mountable(self):
-        return True
-
-register_device_format(BindFS)
diff --git a/src/pomona/storage_old/formats/lvmpv.py b/src/pomona/storage_old/formats/lvmpv.py
deleted file mode 100644 (file)
index b1ef617..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/usr/bin/python
-
-from parted import PARTITION_LVM
-from . import DeviceFormat, register_device_format
-from ..errors import *
-from ..devicelibs import lvm
-
-class LVMPhysicalVolume(DeviceFormat):
-    """ An LVM physical volume. """
-    _type = "lvmpv"
-    _name = "physical volume (LVM)"
-    _udevTypes = ["LVM2_member"]
-    partedFlag = PARTITION_LVM
-    _formattable = True                 # can be formatted
-    _supported = True                   # is supported
-    _linuxNative = True                 # for clearpart
-
-    def __init__(self, *args, **kwargs):
-        """ Create an LVMPhysicalVolume instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this PV's uuid (not the VG uuid)
-                vgName -- the name of the VG this PV belongs to
-                vgUuid -- the UUID of the VG this PV belongs to
-                peStart -- offset of first physical extent
-                exists -- indicates whether this is an existing format
-
-        """
-        DeviceFormat.__init__(self, *args, **kwargs)
-        self.vgName = kwargs.get("vgName")
-        self.vgUuid = kwargs.get("vgUuid")
-        # liblvm may be able to tell us this at some point, even
-        # for not-yet-created devices
-        self.peStart = kwargs.get("peStart", 0.1875)    # in MB
-
-    def probe(self):
-        """ Probe for any missing information about this device. """
-        if not self.exists:
-            raise PhysicalVolumeError("format has not been created")
-
-        #info = lvm.pvinfo(self.device)
-        #self.vgName = info['vg_name']
-        #self.vgUuid = info['vg_uuid']
-
-    def create(self, *args, **kwargs):
-        """ Create the format. """
-        DeviceFormat.create(self, *args, **kwargs)
-        # Consider use of -Z|--zero
-        # -f|--force or -y|--yes may be required
-
-        # lvm has issues with persistence of metadata, so here comes the
-        # hammer...
-        DeviceFormat.destroy(self, *args, **kwargs)
-
-        lvm.pvcreate(self.device)
-        self.exists = True
-        self.notifyKernel()
-
-    def destroy(self, *args, **kwargs):
-        """ Destroy the format. """
-        if not self.exists:
-            raise PhysicalVolumeError("format has not been created")
-
-        if self.status:
-            raise PhysicalVolumeError("device is active")
-
-        # FIXME: verify path exists?
-        try:
-            lvm.pvremove(self.device)
-        except LVMError:
-            DeviceFormat.destroy(self, *args, **kwargs)
-
-        self.exists = False
-        self.notifyKernel()
-
-    @property
-    def status(self):
-        # XXX hack
-        return (self.exists and self.vgName and
-                os.path.isdir("/dev/mapper/%s" % self.vgName))
-
-register_device_format(LVMPhysicalVolume)
diff --git a/src/pomona/storage_old/formats/swap.py b/src/pomona/storage_old/formats/swap.py
deleted file mode 100644 (file)
index 289f985..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/python
-
-from parted import PARTITION_SWAP
-
-from . import DeviceFormat, register_device_format
-
-class SwapSpace(DeviceFormat):
-    """ Swap space """
-    _type = "swap"
-    _name = None
-    _udevTypes = ["swap"]
-    partedFlag = PARTITION_SWAP
-    _formattable = True                # can be formatted
-    _supported = True                  # is supported
-    _linuxNative = True                # for clearpart
-
-    def __init__(self, installer, *args, **kwargs):
-        """ Create a SwapSpace instance.
-
-            Keyword Arguments:
-
-                device -- path to the underlying device
-                uuid -- this swap space's uuid
-                label -- this swap space's label
-                priority -- this swap space's priority
-                exists -- indicates whether this is an existing format
-
-        """
-        self.installer = installer
-        DeviceFormat.__init__(self, self.installer, *args, **kwargs)
-
-        self.priority = kwargs.get("priority")
-        self.label = kwargs.get("label")
-
-    def _setPriority(self, priority):
-        if priority is None:
-            self._priority = None
-            return
-
-        if not isinstance(priority, int) or not 0 <= priority <= 32767:
-            raise ValueError("swap priority must be an integer between 0 and 32767")
-
-        self._priority = priority
-
-    def _getPriority(self):
-        return self._priority
-
-    priority = property(_getPriority, _setPriority,
-                        doc="The priority of the swap device")
-
-    def _getOptions(self):
-        opts = ""
-        if self.priority is not None:
-            opts += "pri=%d" % self.priority
-
-        return opts
-
-    def _setOptions(self, opts):
-        if not opts:
-            self.priority = None
-            return
-
-        for option in opts.split(","):
-            (opt, equals, arg) = option.partition("=")
-            if equals and opt == "pri":
-                try:
-                    self.priority = int(arg)
-                except ValueError:
-                    self.installer.log.info("invalid value for swap priority: %s" % arg)
-
-    options = property(_getOptions, _setOptions,
-                       doc="The swap device's fstab options string")
-
-    @property
-    def status(self):
-        """ Device status. """
-        return self.exists and swap.swapstatus(self.device)
-
-    def setup(self, *args, **kwargs):
-        """ Open, or set up, a device. """
-        if not self.exists:
-            raise SwapSpaceError("format has not been created")
-
-        if self.status:
-            return
-
-        DeviceFormat.setup(self, *args, **kwargs)
-        swap.swapon(self.device, priority=self.priority)
-
-    def teardown(self, *args, **kwargs):
-        """ Close, or tear down, a device. """
-        if not self.exists:
-            raise SwapSpaceError("format has not been created")
-
-        if self.status:
-            swap.swapoff(self.device)
-
-    def create(self, *args, **kwargs):
-        """ Create the device. """
-        if self.exists:
-            raise SwapSpaceError("format already exists")
-
-        if self.status:
-            raise SwapSpaceError("device exists and is active")
-
-        DeviceFormat.create(self, *args, **kwargs)
-        swap.mkswap(self.device, label=self.label)
-        self.exists = True
-
-
-register_device_format(SwapSpace)
diff --git a/src/pomona/storage_old/partitioning.py b/src/pomona/storage_old/partitioning.py
deleted file mode 100644 (file)
index 97fd49d..0000000
+++ /dev/null
@@ -1,1075 +0,0 @@
-#!/usr/bin/python
-
-import os
-import parted
-
-from errors import *
-from constants import *
-
-import gettext
-_ = lambda x: gettext.ldgettext("pomona", x)
-
-def _createFreeSpacePartitions(installer):
-    # get a list of disks that have at least one free space region of at
-    # least 100MB
-    disks = []
-    for disk in installer.ds.storage.disks:
-        if disk.name not in installer.ds.storage.clearDisks:
-            continue
-
-        partedDisk = disk.partedDisk
-        part = disk.partedDisk.getFirstPartition()
-        while part:
-            if not part.type & parted.PARTITION_FREESPACE:
-                part = part.nextPartition()
-                continue
-
-            if part.getSize(unit="MB") > 100:
-                disks.append(disk)
-                break
-
-            part = part.nextPartition()
-
-    # create a separate pv partition for each disk with free space
-    devs = []
-    for disk in disks:
-        if installer.ds.storage.encryptedAutoPart:
-            fmt_type = "luks"
-        else:
-            fmt_type = "lvmpv"
-        part = installer.ds.storage.newPartition(fmt_type=fmt_type,
-                                                 size=1,
-                                                 grow=True,
-                                                 disks=[disk])
-        installer.ds.storage.createDevice(part)
-        devs.append(part)
-
-    return (disks, devs)
-
-def _schedulePartitions(installer, disks):
-    #
-    # Convert storage.autoPartitionRequests into Device instances and
-    # schedule them for creation
-    #
-    # First pass is for partitions only. We'll do LVs later.
-    #
-    installer.log.debug("REQUESTS: %s" % installer.ds.storage.autoPartitionRequests)
-    for request in installer.ds.storage.autoPartitionRequests:
-        installer.log.debug("_schedulePartitions: Request: %s" % request)
-        if request.asVol:
-            continue
-
-        if request.fstype is None:
-            request.fstype = installer.ds.storage.defaultFSType
-
-        dev = installer.ds.storage.newPartition(fmt_type=request.fstype,
-                                                size=request.size,
-                                                grow=request.grow,
-                                                maxsize=request.maxSize,
-                                                mountpoint=request.mountpoint,
-                                                disks=disks,
-                                                weight=request.weight)
-
-        # schedule the device for creation
-        installer.ds.storage.createDevice(dev)
-
-    # make sure preexisting broken lvm/raid configs get out of the way
-    return
-
-def _scheduleLVs(installer, devs):
-    if installer.ds.storage.encryptedAutoPart:
-        pvs = []
-        for dev in devs:
-            pv = LUKSDevice("luks-%s" % dev.name,
-                            format=getFormat("lvmpv", device=dev.path),
-                            size=dev.size,
-                            parents=dev)
-            pvs.append(pv)
-            installer.ds.storage.createDevice(pv)
-    else:
-        pvs = devs
-
-    # create a vg containing all of the autopart pvs
-    vg = installer.ds.storage.newVG(pvs=pvs)
-    installer.ds.storage.createDevice(vg)
-
-    #
-    # Convert storage.autoPartitionRequests into Device instances and
-    # schedule them for creation.
-    #
-    # Second pass, for LVs only.
-    for request in installer.ds.storage.autoPartitionRequests:
-        if not request.asVol:
-            continue
-
-        if request.fstype is None:
-            request.fstype = installer.ds.storage.defaultFSType
-
-        # FIXME: move this to a function and handle exceptions
-        dev = installer.ds.storage.newLV(vg=vg,
-                                         fmt_type=request.fstype,
-                                         mountpoint=request.mountpoint,
-                                         grow=request.grow,
-                                         maxsize=request.maxSize,
-                                         size=request.size)
-
-        # schedule the device for creation
-        installer.ds.storage.createDevice(dev)
-
-def clearPartitions(installer):
-    """ Clear partitions and dependent devices from disks.
-
-        Arguments:
-
-            storage -- a storage.Storage instance
-
-        Keyword arguments:
-
-            None
-
-        NOTES:
-
-            - Needs some error handling, especially for the parted bits.
-
-    """
-    storage = installer.ds.storage
-
-    # we are only interested in partitions that physically exist
-    partitions = [p for p in storage.partitions if p.exists]
-    disks = []  # a list of disks from which we've removed partitions
-    clearparts = [] # list of partitions we'll remove
-    for part in partitions:
-        # if we got a list of disks to clear, make sure this one's on it
-        if storage.clearDisks and part.disk.name not in storage.clearDisks:
-            continue
-
-        # don't clear partitions holding install media
-        #if part.name in storage.protectedPartitions:
-        #    continue
-
-        # we don't want to fool with extended partitions, freespace, &c
-        if part.partType not in (parted.PARTITION_NORMAL,
-                                 parted.PARTITION_LOGICAL):
-            continue
-
-        installer.log.debug("clearPartitions: Clearing %s" % part.name)
-
-        # XXX is there any argument for not removing incomplete devices?
-        #       -- maybe some RAID devices
-        devices = storage.deviceDeps(part)
-        while devices:
-            installer.log.debug("clearPartitions: Devices to remove: %s" % ([d.name for d in devices],))
-            leaves = [d for d in devices if d.isleaf]
-            installer.log.debug("clearPartitions: Leaves to remove: %s" % ([d.name for d in leaves],))
-            for leaf in leaves:
-                storage.destroyDevice(leaf)
-                devices.remove(leaf)
-
-        #installer.log.debug("clearPartitions: Partitions left: %s" % [p.getDeviceNodeName() for p in part.partedPartition.disk.partitions])
-        disk_name = os.path.basename(part.partedPartition.disk.device.path)
-        if disk_name not in disks:
-            disks.append(disk_name)
-
-        clearparts.append(part)
-
-    for part in clearparts:
-        storage.destroyDevice(part)
-
-    # now remove any empty extended partitions
-    removeEmptyExtendedPartitions(installer)
-
-def removeEmptyExtendedPartitions(installer):
-    storage = installer.ds.storage
-    for disk in storage.disks:
-        installer.log.debug("removeEmptyExtendedPartitions: Checking whether disk %s has an empty extended" % disk.name)
-        extended = disk.partedDisk.getExtendedPartition()
-        logical_parts = disk.partedDisk.getLogicalPartitions()
-        installer.log.debug("removeEmptyExtendedPartitions: Extended is %s ; logicals is %s" % (extended, [p.getDeviceNodeName() for p in logical_parts]))
-        if extended and not logical_parts:
-            installer.log.debug("removeEmptyExtendedPartitions: Removing empty extended partition from %s" % disk.name)
-            extended_name = devicePathToName(extended.getDeviceNodeName())
-            extended = storage.devicetree.getDeviceByName(extended_name)
-            storage.destroyDevice(extended)
-            #disk.partedDisk.removePartition(extended.partedPartition)
-
-def doAutoPartition(installer):
-    if installer.dispatch.dir == DISPATCH_BACK:
-        installer.ds.storage.reset()
-        return
-    
-    installer.log.debug("All names: %s" % [d.name for d in installer.ds.storage.devicetree.devices.values()])
-
-    disks = []
-    devs = []
-
-    if installer.ds.storage.doAutoPart:
-        clearPartitions(installer)
-
-    if installer.ds.storage.doAutoPart:
-        (disks, devs) = _createFreeSpacePartitions(installer)
-
-        if disks == []:
-            installer.intf.messageWindow(_("Error Partitioning"),
-                                        _("Could not find enough free space "
-                                          "for automatic partitioning, please "
-                                          "use another partitioning method."))
-            return DISPATCH_BACK
-
-        _schedulePartitions(installer, disks)
-
-    # sanity check the individual devices
-    installer.log.warning("doAutoPartition: not sanity checking devices because I don't know how yet")
-
-    # run the autopart function to allocate and grow partitions
-    try:
-        doPartitioning(installer)
-
-        if installer.ds.storage.doAutoPart:
-            _scheduleLVs(installer, devs)
-
-        # grow LVs
-        growLVM(installer)
-    except PartitioningWarning as msg:
-        installer.intf.messageWindow(_("Warnings During Automatic Partitioning"),
-                                               _("Following warnings occurred during automatic "
-                                               "partitioning:\n\n%s") % (msg,),)
-        log.warning(msg)
-    except PartitioningError as msg:
-        # restore drives to original state
-        installer.ds.storage.reset()
-        #installer.dispatch.skipStep("partition", skip = 0)
-        installer.intf.messageWindow(_("Error Partitioning"),
-               _("Could not allocate requested partitions: \n\n"
-                 "%s.%s") % (msg, extra))
-        return
-
-    # sanity check the collection of devices
-    installer.log.warning("not sanity checking storage config because I don't know how yet")
-    # now do a full check of the requests
-    (errors, warnings) = installer.ds.storage.sanityCheck()
-    if warnings:
-        for warning in warnings:
-            installer.log.warning(warning)
-    if errors:
-        errortxt = "\n".join(errors)
-        installer.intf.messageWindow(_("Automatic Partitioning Errors"),
-                           _("The following errors occurred with your "
-                             "partitioning:\n\n%s\n\n"
-                             "This can happen if there is not enough "
-                             "space on your hard drive(s) for the "
-                             "installation.\n\n"
-                                                        "Press 'OK' to choose a different partitioning option.")
-                           % (errortxt,),)
-
-        installer.ds.storage.reset()
-        #return DISPATCH_BACK
-        return INSTALL_OK
-
-def doPartitioning(installer):
-    """ Allocate and grow partitions.
-
-        When this function returns without error, all PartitionDevice
-        instances must have their parents set to the disk they are
-        allocated on, and their partedPartition attribute set to the
-        appropriate parted.Partition instance from their containing
-        disk. All req_xxxx attributes must be unchanged.
-
-        Arguments:
-
-            storage - Main anaconda Storage instance
-
-        Keyword arguments:
-
-            exclusiveDisks -- list of names of disks to use
-
-    """
-    storage = installer.ds.storage
-    disks = storage.disks
-
-    exclusiveDisks = storage.clearDisks
-    if exclusiveDisks:
-        disks = [d for d in disks if d.name in exclusiveDisks]
-
-    for disk in disks:
-        disk.setup()
-
-    partitions = storage.partitions
-    for part in partitions:
-        part.req_bootable = False
-        if not part.exists:
-            # start over with flexible-size requests
-            part.req_size = part.req_base_size
-
-    # FIXME: isn't there a better place for this to happen?
-    #try:
-    #    bootDev = anaconda.platform.bootDevice()
-    #except DeviceError:
-    #    bootDev = None
-
-    #if bootDev:
-    #    bootDev.req_bootable = True
-
-    # FIXME: make sure non-existent partitions have empty parents list
-    allocatePartitions(installer, disks, partitions)
-    growPartitions(installer, disks, partitions)
-    # The number and thus the name of partitions may have changed now,
-    # allocatePartitions() takes care of this for new partitions, but not
-    # for pre-existing ones, so we update the name of all partitions here
-    for part in partitions:
-        part.updateName()
-
-    # XXX hack -- if we created any extended partitions we need to add
-    #             them to the tree now
-    for disk in disks:
-        extended = disk.partedDisk.getExtendedPartition()
-        if not extended:
-            continue
-
-        extendedName = devicePathToName(extended.getDeviceNodeName())
-        device = storage.devicetree.getDeviceByName(extendedName)
-        if device:
-            if not device.exists:
-                # created by us, update partedPartition
-                device.partedPartition = extended
-            continue
-
-        # This is a little odd because normally instantiating a partition
-        # that does not exist means leaving self.parents empty and instead
-        # populating self.req_disks. In this case, we need to skip past
-        # that since this partition is already defined.
-        device = PartitionDevice(extendedName, parents=disk)
-        device.parents = [disk]
-        device.partedPartition = extended
-        storage.createDevice(device)
-
-def allocatePartitions(installer, disks, partitions):
-    """ Allocate partitions based on requested features.
-
-        Non-existing partitions are sorted according to their requested
-        attributes, and then allocated.
-
-        The basic approach to sorting is that the more specifically-
-        defined a request is, the earlier it will be allocated. See
-        the function partitionCompare for details on the sorting
-        criteria.
-
-        The PartitionDevice instances will have their name and parents
-        attributes set once they have been allocated.
-    """
-    installer.log.debug("allocatePartitions: disks=%s ; partitions=%s" % (disks,
-                                                                partitions))
-    new_partitions = [p for p in partitions if not p.exists]
-    new_partitions.sort(cmp=partitionCompare)
-
-    # XXX is this needed anymore?
-    partedDisks = {}
-    for disk in disks:
-        if disk.path not in partedDisks.keys():
-            partedDisks[disk.path] = disk.partedDisk #.duplicate()
-
-    # remove all newly added partitions from the disk
-    installer.log.debug("removing all non-preexisting from disk(s)")
-    for _part in new_partitions:
-        if _part.partedPartition:
-            if _part.isExtended:
-                # these get removed last
-                continue
-            #_part.disk.partedDisk.removePartition(_part.partedPartition)
-            partedDisk = partedDisks[_part.disk.partedDisk.device.path]
-            installer.log.debug("removing part %s (%s) from disk %s (%s)" %
-                      (_part.partedPartition.path,
-                       [p.path for p in _part.partedPartition.disk.partitions],
-                       partedDisk.device.path,
-                       [p.path for p in partedDisk.partitions]))
-
-            partedDisk.removePartition(_part.partedPartition)
-            _part.partedPartition = None
-            _part.disk = None
-
-            # remove empty extended so it doesn't interfere
-            extended = partedDisk.getExtendedPartition()
-            if extended and not partedDisk.getLogicalPartitions():
-                installer.log.debug("removing empty extended partition")
-                #partedDisk.minimizeExtendedPartition()
-                partedDisk.removePartition(extended)
-
-    for _part in new_partitions:
-        if _part.partedPartition and _part.isExtended:
-            # ignore new extendeds as they are implicit requests
-            continue
-
-        # obtain the set of candidate disks
-        req_disks = []
-        if _part.disk:
-            # we have a already selected a disk for this request
-            req_disks = [_part.disk]
-        elif _part.req_disks:
-            # use the requested disk set
-            req_disks = _part.req_disks
-        else:
-            # no disks specified means any disk will do
-            req_disks = disks
-
-        installer.log.debug("allocating partition: %s ; disks: %s ; boot: %s ; "
-                            "primary: %s ; size: %dMB ; grow: %s ; max_size: %s" %
-                            (_part.name, req_disks, _part.req_bootable, _part.req_primary,
-                            _part.req_size, _part.req_grow, _part.req_max_size))
-        free = None
-        use_disk = None
-        part_type = None
-        # loop through disks
-        for _disk in req_disks:
-            disk = partedDisks[_disk.path]
-            #for p in disk.partitions:
-            #    installer.log.debug("disk %s: part %s" % (disk.device.path, p.path))
-            sectorSize = disk.device.physicalSectorSize
-            best = None
-
-            installer.log.debug("checking freespace on %s" % _disk.name)
-
-            new_part_type = getNextPartitionType(disk)
-            if new_part_type is None:
-                # can't allocate any more partitions on this disk
-                installer.log.debug("no free partition slots on %s" % _disk.name)
-                continue
-
-            if _part.req_primary and new_part_type != parted.PARTITION_NORMAL:
-                # we need a primary slot and none are free on this disk
-                installer.log.debug("no primary slots available on %s" % _disk.name)
-                continue
-
-            best = getBestFreeSpaceRegion(installer, disk,
-                                          new_part_type,
-                                          _part.req_size,
-                                          best_free=free,
-                                          boot=_part.req_bootable)
-
-            if best == free and not _part.req_primary and \
-               new_part_type == parted.PARTITION_NORMAL:
-                # see if we can do better with a logical partition
-                installer.log.debug("not enough free space for primary -- trying logical")
-                new_part_type = getNextPartitionType(disk, no_primary=True)
-                if new_part_type:
-                    best = getBestFreeSpaceRegion(disk,
-                                                  new_part_type,
-                                                  _part.req_size,
-                                                  best_free=free,
-                                                  boot=_part.req_bootable)
-
-            if best and free != best:
-                # now we know we are choosing a new free space,
-                # so update the disk and part type
-                installer.log.debug("updating use_disk to %s (%s), type: %s"
-                                    % (_disk, _disk.name, new_part_type))
-                part_type = new_part_type
-                use_disk = _disk
-                installer.log.debug("new free: %s (%d-%d / %dMB)" % (best,
-                                                                     best.start,
-                                                                     best.end,
-                                                                     best.getSize()))
-                free = best
-
-            if free and _part.req_bootable:
-                # if this is a bootable partition we want to
-                # use the first freespace region large enough
-                # to satisfy the request
-                installer.log.debug("found free space for bootable request")
-                break
-
-        if free is None:
-            raise PartitioningError("not enough free space on disks")
-
-        _disk = use_disk
-        disk = _disk.partedDisk
-
-        # create the extended partition if needed
-        # TODO: move to a function (disk, free)
-        if part_type == parted.PARTITION_EXTENDED:
-            installer.log.debug("creating extended partition")
-            geometry = parted.Geometry(device=disk.device,
-                                       start=free.start,
-                                       length=free.length,
-                                       end=free.end)
-            extended = parted.Partition(disk=disk,
-                                        type=parted.PARTITION_EXTENDED,
-                                        geometry=geometry)
-            constraint = parted.Constraint(device=disk.device)
-            # FIXME: we should add this to the tree as well
-            disk.addPartition(extended, constraint)
-
-            # end proposed function
-
-            # now the extended partition exists, so set type to logical
-            part_type = parted.PARTITION_LOGICAL
-
-            # recalculate freespace
-            installer.log.debug("recalculating free space")
-            free = getBestFreeSpaceRegion(disk,
-                                          part_type,
-                                          _part.req_size,
-                                          boot=_part.req_bootable)
-            if not free:
-                raise PartitioningError("not enough free space after "
-                                        "creating extended partition")
-
-        # create minimum geometry for this request
-        # req_size is in MB
-        sectors_per_track = disk.device.biosGeometry[2]
-        length = (_part.req_size * (1024 * 1024)) / sectorSize
-        new_geom = parted.Geometry(device=disk.device,
-                                   start=max(sectors_per_track, free.start),
-                                   length=length)
-
-        # create maximum and minimum geometries for constraint
-        start = max(0 , free.start - 1)
-        max_geom = parted.Geometry(device=disk.device,
-                                   start=start,
-                                   length=min(length + 1, disk.device.length - start))
-        min_geom = parted.Geometry(device=disk.device,
-                                   start=free.start + 1,
-                                   length=length-1)
-
-
-        # create the partition and add it to the disk
-        partition = parted.Partition(disk=disk,
-                                     type=part_type,
-                                     geometry=new_geom)
-        constraint = parted.Constraint(maxGeom=max_geom, minGeom=min_geom)
-        disk.addPartition(partition=partition,
-                          constraint=constraint)
-        installer.log.debug("created partition %s of %dMB and added it to %s" %
-                (partition.getDeviceNodeName(), partition.getSize(), disk))
-
-        # this one sets the name
-        _part.partedPartition = partition
-        _part.disk = _disk
-
-        # parted modifies the partition in the process of adding it to
-        # the disk, so we need to grab the latest version...
-        _part.partedPartition = disk.getPartitionByPath(_part.path)
-
-def partitionCompare(part1, part2):
-    """ More specifically defined partitions come first.
-
-        < 1 => x < y
-          0 => x == y
-        > 1 => x > y
-    """
-    ret = 0
-
-    if part1.req_base_weight:
-        ret -= part1.req_base_weight
-
-    if part2.req_base_weight:
-        ret += part2.req_base_weight
-
-    # bootable partitions to the front
-    ret -= cmp(part1.req_bootable, part2.req_bootable) * 1000
-
-    # more specific disk specs to the front of the list
-    ret += cmp(len(part1.parents), len(part2.parents)) * 500
-
-    # primary-only to the front of the list
-    ret -= cmp(part1.req_primary, part2.req_primary) * 200
-
-    # larger requests go to the front of the list
-    ret -= cmp(part1.size, part2.size) * 100
-
-    # fixed size requests to the front
-    ret += cmp(part1.req_grow, part2.req_grow) * 50
-
-    # potentially larger growable requests go to the front
-    if part1.req_grow and part2.req_grow:
-        if not part1.req_max_size and part2.req_max_size:
-            ret -= 25
-        elif part1.req_max_size and not part2.req_max_size:
-            ret += 25
-        else:
-            ret -= cmp(part1.req_max_size, part2.req_max_size) * 25
-
-    if ret > 0:
-        ret = 1
-    elif ret < 0:
-        ret = -1
-
-    return ret
-
-def growPartitions(installer, disks, partitions):
-    """ Grow all growable partition requests.
-
-        All requests should know what disk they will be on by the time
-        this function is called. This is reflected in the
-        PartitionDevice's disk attribute. Note that the req_disks
-        attribute remains unchanged.
-
-        The total available free space is summed up for each disk and
-        partition requests are allocated a maximum percentage of the
-        available free space on their disk based on their own base size.
-
-        Each attempted size means calling allocatePartitions again with
-        one request's size having changed.
-
-        After taking into account several factors that may limit the
-        maximum size of a requested partition, we arrive at a firm
-        maximum number of sectors by which a request can potentially grow.
-
-        An initial attempt is made to allocate the full maximum size. If
-        this fails, we begin a rough binary search with a maximum of three
-        iterations to settle on a new size.
-
-        Arguments:
-
-            disks -- a list of all usable disks (DiskDevice instances)
-            partitions -- a list of all partitions (PartitionDevice
-                          instances)
-    """
-    installer.log.debug("growPartitions: disks=%s, partitions=%s" %
-                ([d.name for d in disks], [p.name for p in partitions]))
-    all_growable = [p for p in partitions if p.req_grow]
-    if not all_growable:
-        return
-
-    # sort requests by base size in decreasing order
-    all_growable.sort(key=lambda p: p.req_size, reverse=True)
-
-    installer.log.debug("growable requests are %s" % [p.name for p in all_growable])
-
-    for disk in disks:
-        installer.log.debug("growing requests on %s" % disk.name)
-        for p in disk.partedDisk.partitions:
-            installer.log.debug("  %s: %s (%dMB)" % (disk.name, p.getDeviceNodeName(),
-                                         p.getSize()))
-        sectorSize = disk.partedDisk.device.physicalSectorSize
-        # get a list of free space regions on the disk
-        free = disk.partedDisk.getFreeSpaceRegions()
-        if not free:
-            installer.log.debug("no free space on %s" % disk.name)
-            continue
-
-        # sort the free regions in decreasing order of size
-        free.sort(key=lambda r: r.length, reverse=True)
-        disk_free = reduce(lambda x,y: x + y, [f.length for f in free])
-        installer.log.debug("total free: %d sectors ; largest: %d sectors (%dMB)"
-                    % (disk_free, free[0].length, free[0].getSize()))
-
-        # make a list of partitions currently allocated on this disk
-        # -- they're already sorted
-        growable = []
-        disk_total = 0
-        for part in all_growable:
-            #log.debug("checking if part %s (%s) is on this disk" % (part.name,
-            #                                                        part.disk.name))
-            if part.disk == disk:
-                growable.append(part)
-                disk_total += part.partedPartition.geometry.length
-                installer.log.debug("add %s (%dMB/%d sectors) to growable total"
-                            % (part.name, part.partedPartition.getSize(),
-                                part.partedPartition.geometry.length))
-                installer.log.debug("growable total is now %d sectors" % disk_total)
-
-        # now we loop through the partitions...
-        # this first loop is to identify obvious chunks of free space that
-        # will be left over due to max size
-        leftover = 0
-        limited = {}
-        unlimited_total = 0
-        for part in growable:
-            # calculate max number of sectors this request can grow
-            req_sectors = part.partedPartition.geometry.length
-            share = float(req_sectors) / float(disk_total)
-            max_grow = (share * disk_free)
-            max_sectors = req_sectors + max_grow
-            limited[part.name] = False
-
-            if part.req_max_size:
-                req_max_sect = (part.req_max_size * (1024 * 1024)) / sectorSize
-                if req_max_sect < max_sectors:
-                    mb = ((max_sectors - req_max_sect) * sectorSize) / (1024*1024)
-
-                    installer.log.debug("adding %dMB to leftovers from %s"
-                                % (mb, part.name))
-                    leftover += (max_sectors - req_max_sect)
-                    limited[part.name] = True
-
-            if not limited[part.name]:
-                unlimited_total += req_sectors
-
-        # now we loop through the partitions...
-        for part in growable:
-            # calculate max number of sectors this request can grow
-            req_sectors = part.partedPartition.geometry.length
-            share = float(req_sectors) / float(disk_total)
-            max_grow = (share * disk_free)
-            if not limited[part.name]:
-                leftover_share = float(req_sectors) / float(unlimited_total)
-                max_grow += leftover_share * leftover
-            max_sectors = req_sectors + max_grow
-            max_mb = (max_sectors * sectorSize) / (1024 * 1024)
-
-            installer.log.debug("%s: base_size=%dMB, max_size=%sMB" %
-                    (part.name, part.req_base_size,  part.req_max_size))
-            installer.log.debug("%s: current_size=%dMB (%d sectors)" %
-                    (part.name, part.partedPartition.getSize(),
-                        part.partedPartition.geometry.length))
-            installer.log.debug("%s: %dMB (%d sectors, or %d%% of %d)" %
-                    (part.name, max_mb, max_sectors, share * 100, disk_free))
-
-            installer.log.debug("checking constraints on max size...")
-            # don't grow beyond the request's maximum size
-            if part.req_max_size:
-                installer.log.debug("max_size: %dMB" % part.req_max_size)
-                # FIXME: round down to nearest cylinder boundary
-                req_max_sect = (part.req_max_size * (1024 * 1024)) / sectorSize
-                if req_max_sect < max_sectors:
-                    max_grow -= (max_sectors - req_max_sect)
-                    max_sectors = req_sectors + max_grow
-
-            # don't grow beyond the resident filesystem's max size
-            if part.format.maxSize > 0:
-                installer.log.debug("format maxsize: %dMB" % part.format.maxSize)
-                # FIXME: round down to nearest cylinder boundary
-                fs_max_sect = (part.format.maxSize * (1024 * 1024)) / sectorSize
-                if fs_max_sect < max_sectors:
-                    max_grow -= (max_sectors - fs_max_sect)
-                    max_sectors = req_sectors + max_grow
-
-            # we can only grow as much as the largest free region on the disk
-            if free[0].length < max_grow:
-                installer.log.debug("largest free region: %d sectors (%dMB)" %
-                        (free[0].length, free[0].getSize()))
-                # FIXME: round down to nearest cylinder boundary
-                max_grow = free[0].length
-                max_sectors = req_sectors + max_grow
-
-            # Now, we try to grow this partition as close to max_grow
-            # sectors as we can.
-            #
-            # We could call allocatePartitions after modifying this
-            # request and saving the original value of part.req_size,
-            # or we could try to use disk.maximizePartition().
-            max_size = (max_sectors * sectorSize) / (1024 * 1024)
-            orig_size = part.req_size
-            # try the max size to begin with
-            installer.log.debug("attempting to allocate maximum size: %dMB" % max_size)
-            part.req_size = max_size
-            try:
-                allocatePartitions(installer, disks, partitions)
-            except PartitioningError, e:
-                installer.log.debug("max size attempt failed: %s (%dMB)" % (part.name,
-                                                                            max_size))
-                part.req_size = orig_size
-            else:
-                continue
-
-            installer.log.debug("starting binary search: size=%d max_size=%d" % (part.req_size, max_size))
-            count = 0
-            op_func = add
-            increment = max_grow
-            last_good_size = part.req_size
-            last_outcome = None
-            while count < 3:
-                last_size = part.req_size
-                increment /= 2
-                req_sectors = op_func(req_sectors, increment)
-                part.req_size = (req_sectors * sectorSize) / (1024 * 1024)
-                installer.log.debug("attempting size=%dMB" % part.req_size)
-                count += 1
-                try:
-                    allocatePartitions(disks, partitions)
-                except PartitioningError, e:
-                    installer.log.debug("attempt at %dMB failed" % part.req_size)
-                    op_func = sub
-                    last_outcome = False
-                else:
-                    op_func = add
-                    last_good_size = part.req_size
-                    last_outcome = True
-
-            if not last_outcome:
-                part.req_size = last_good_size
-                installer.log.debug("backing up to size=%dMB" % part.req_size)
-                try:
-                    allocatePartitions(disks, partitions)
-                except PartitioningError, e:
-                    raise PartitioningError("failed to grow partitions")
-
-    # reset all requests to their original requested size
-    for part in partitions:
-        if part.exists:
-            continue
-        part.req_size = part.req_base_size
-
-def lvCompare(lv1, lv2):
-    """ More specifically defined lvs come first.
-
-        < 1 => x < y
-          0 => x == y
-        > 1 => x > y
-    """
-    ret = 0
-
-    # larger requests go to the front of the list
-    ret -= cmp(lv1.size, lv2.size) * 100
-
-    # fixed size requests to the front
-    ret += cmp(lv1.req_grow, lv2.req_grow) * 50
-
-    # potentially larger growable requests go to the front
-    if lv1.req_grow and lv2.req_grow:
-        if not lv1.req_max_size and lv2.req_max_size:
-            ret -= 25
-        elif lv1.req_max_size and not lv2.req_max_size:
-            ret += 25
-        else:
-            ret -= cmp(lv1.req_max_size, lv2.req_max_size) * 25
-
-    if ret > 0:
-        ret = 1
-    elif ret < 0:
-        ret = -1
-
-    return ret
-
-def growLVM(installer):
-    """ Grow LVs according to the sizes of the PVs. """
-    storage = installer.ds.storage
-    for vg in storage.vgs:
-        total_free = vg.freeSpace
-        if not total_free:
-            installer.log.debug("vg %s has no free space" % vg.name)
-            continue
-
-        installer.log.debug("vg %s: %dMB free ; lvs: %s" % (vg.name, vg.freeSpace,
-                                                  [l.lvname for l in vg.lvs]))
-
-        # figure out how much to grow each LV
-        grow_amounts = {}
-        lv_total = vg.size - total_free
-        installer.log.debug("used: %dMB ; vg.size: %dMB" % (lv_total, vg.size))
-
-        # This first loop is to calculate percentage-based growth
-        # amounts. These are based on total free space.
-        lvs = vg.lvs
-        lvs.sort(cmp=lvCompare)
-        for lv in lvs:
-            if not lv.req_grow or not lv.req_percent:
-                continue
-
-            portion = (lv.req_percent * 0.01)
-            grow = portion * vg.vgFree
-            new_size = lv.req_size + grow
-            if lv.req_max_size and new_size > lv.req_max_size:
-                grow -= (new_size - lv.req_max_size)
-
-            if lv.format.maxSize and lv.format.maxSize < new_size:
-                grow -= (new_size - lv.format.maxSize)
-
-            # clamp growth amount to a multiple of vg extent size
-            grow_amounts[lv.name] = vg.align(grow)
-            total_free -= grow
-            lv_total += grow
-
-        # This second loop is to calculate non-percentage-based growth
-        # amounts. These are based on free space remaining after
-        # calculating percentage-based growth amounts.
-
-        # keep a tab on space not allocated due to format or requested
-        # maximums -- we'll dole it out to subsequent requests
-        leftover = 0
-        for lv in lvs:
-            installer.log.debug("checking lv %s: req_grow: %s ; req_percent: %s"
-                      % (lv.name, lv.req_grow, lv.req_percent))
-            if not lv.req_grow or lv.req_percent:
-                continue
-
-            portion = float(lv.req_size) / float(lv_total)
-            grow = portion * total_free
-            installer.log.debug("grow is %dMB" % grow)
-
-            todo = lvs[lvs.index(lv):]
-            unallocated = reduce(lambda x,y: x+y,
-                                 [l.req_size for l in todo
-                                  if l.req_grow and not l.req_percent])
-            extra_portion = float(lv.req_size) / float(unallocated)
-            extra = extra_portion * leftover
-            installer.log.debug("%s getting %dMB (%d%%) of %dMB leftover space"
-                      % (lv.name, extra, extra_portion * 100, leftover))
-            leftover -= extra
-            grow += extra
-            installer.log.debug("grow is now %dMB" % grow)
-            max_size = lv.req_size + grow
-            if lv.req_max_size and max_size > lv.req_max_size:
-                max_size = lv.req_max_size
-
-            if lv.format.maxSize and max_size > lv.format.maxSize:
-                max_size = lv.format.maxSize
-
-            installer.log.debug("max size is %dMB" % max_size)
-            max_size = max_size
-            leftover += (lv.req_size + grow) - max_size
-            grow = max_size - lv.req_size
-            installer.log.debug("lv %s gets %dMB" % (lv.name, vg.align(grow)))
-            grow_amounts[lv.name] = vg.align(grow)
-
-        if not grow_amounts:
-            installer.log.debug("no growable lvs in vg %s" % vg.name)
-            continue
-
-        # now grow the lvs by the amounts we've calculated above
-        for lv in lvs:
-            if lv.name not in grow_amounts.keys():
-                continue
-            lv.size += grow_amounts[lv.name]
-
-        # now there shouldn't be any free space left, but if there is we
-        # should allocate it to one of the LVs
-        vg_free = vg.freeSpace
-        installer.log.debug("vg %s has %dMB free" % (vg.name, vg_free))
-        if vg_free:
-            for lv in lvs:
-                if not lv.req_grow:
-                    continue
-
-                if lv.req_max_size and lv.size == lv.req_max_size:
-                    continue
-
-                if lv.format.maxSize and lv.size == lv.format.maxSize:
-                    continue
-
-                # first come, first served
-                projected = lv.size + vg.freeSpace
-                if lv.req_max_size and projected > lv.req_max_size:
-                    projected = lv.req_max_size
-
-                if lv.format.maxSize and projected > lv.format.maxSize:
-                    projected = lv.format.maxSize
-
-                installer.log.debug("giving leftover %dMB to %s" % (projected - lv.size,
-                                                                    lv.name))
-                lv.size = projected
-
-def getNextPartitionType(disk, no_primary=None):
-    """ Find the type of partition to create next on a disk.
-
-        Return a parted partition type value representing the type of the
-        next partition we will create on this disk.
-
-        If there is only one free primary partition and we can create an
-        extended partition, we do that.
-
-        If there are free primary slots and an extended partition we will
-        recommend creating a primary partition. This can be overridden
-        with the keyword argument no_primary.
-
-        Arguments:
-
-            disk -- a parted.Disk instance representing the disk
-
-        Keyword arguments:
-
-            no_primary -- given a choice between primary and logical
-                          partitions, prefer logical
-
-    """
-    part_type = None
-    extended = disk.getExtendedPartition()
-    supports_extended = disk.supportsFeature(parted.DISK_TYPE_EXTENDED)
-    logical_count = len(disk.getLogicalPartitions())
-    max_logicals = disk.getMaxLogicalPartitions()
-    primary_count = disk.primaryPartitionCount
-
-    if primary_count == disk.maxPrimaryPartitionCount and \
-       extended and logical_count < max_logicals:
-        part_type = parted.PARTITION_LOGICAL
-    elif primary_count == (disk.maxPrimaryPartitionCount - 1) and \
-         not extended and supports_extended:
-        # last chance to create an extended partition
-        part_type = parted.PARTITION_EXTENDED
-    elif no_primary and extended and logical_count < max_logicals:
-        # create a logical even though we could presumably create a
-        # primary instead
-        part_type = parted.PARTITION_LOGICAL
-    elif not no_primary:
-        # XXX there is a possiblity that the only remaining free space on
-        #     the disk lies within the extended partition, but we will
-        #     try to create a primary first
-        part_type = parted.PARTITION_NORMAL
-
-    return part_type
-
-def getBestFreeSpaceRegion(installer, disk, part_type, req_size,
-                           boot=None, best_free=None):
-    """ Return the "best" free region on the specified disk.
-
-        For non-boot partitions, we return the largest free region on the
-        disk. For boot partitions, we return the first region that is
-        large enough to hold the partition.
-
-        Partition type (parted's PARTITION_NORMAL, PARTITION_LOGICAL) is
-        taken into account when locating a suitable free region.
-
-        For locating the best region from among several disks, the keyword
-        argument best_free allows the specification of a current "best"
-        free region with which to compare the best from this disk. The
-        overall best region is returned.
-
-        Arguments:
-
-            disk -- the disk (a parted.Disk instance)
-            part_type -- the type of partition we want to allocate
-                         (one of parted's partition type constants)
-            req_size -- the requested size of the partition (in MB)
-
-        Keyword arguments:
-
-            boot -- indicates whether this will be a bootable partition
-                    (boolean)
-            best_free -- current best free region for this partition
-
-    """
-    installer.log.debug("getBestFreeSpaceRegion: disk=%s part_type=%d req_size=%dMB boot=%s best=%s" %
-                        (disk.device.path, part_type, req_size, boot, best_free))
-    extended = disk.getExtendedPartition()
-    for _range in disk.getFreeSpaceRegions():
-        if extended:
-            # find out if there is any overlap between this region and the
-            # extended partition
-            installer.log.debug("looking for intersection between extended (%d-%d) and free (%d-%d)" %
-                         (extended.geometry.start, extended.geometry.end, _range.start, _range.end))
-
-            # parted.Geometry.overlapsWith can handle this
-            try:
-                free_geom = extended.geometry.intersect(_range)
-            except ArithmeticError, e:
-                # this freespace region does not lie within the extended
-                # partition's geometry
-                free_geom = None
-
-            if (free_geom and part_type == parted.PARTITION_NORMAL) or \
-               (not free_geom and part_type == parted.PARTITION_LOGICAL):
-                installer.log.debug("free region not suitable for request")
-                continue
-
-            if part_type == parted.PARTITION_NORMAL:
-                # we're allocating a primary and the region is not within
-                # the extended, so we use the original region
-                free_geom = _range
-        else:
-            free_geom = _range
-
-        installer.log.debug("current free range is %d-%d (%dMB)" % (free_geom.start,
-                                                                    free_geom.end,
-                                                                    free_geom.getSize()))
-        free_size = free_geom.getSize()
-
-        if req_size <= free_size:
-            if not best_free or free_geom.length > best_free.length:
-                best_free = free_geom
-
-                if boot:
-                    # if this is a bootable partition we want to
-                    # use the first freespace region large enough
-                    # to satisfy the request
-                    break
-
-    return best_free
diff --git a/src/pomona/storage_old/udev.py b/src/pomona/storage_old/udev.py
deleted file mode 100644 (file)
index a9a7377..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-#!/usr/bin/python
-
-import os
-import sys
-
-import util
-
-def udev_settle(timeout=None):
-    argv = ["settle"]
-    if timeout:
-        argv.append("--timeout=%d" % int(timeout))
-
-    util.execWithRedirect("udevadm", argv, stderr="/dev/null", searchPath=1)
-
-def udev_trigger(subsystem=None):
-    argv = ["trigger"]
-    if subsystem:
-        argv.append("--subsystem-match=%s" % subsystem)
-
-    util.execWithRedirect("udevadm", argv, stderr="/dev/null", searchPath=1)
-
-def udev_get_block_devices():
-    #udev_settle(timeout=30)
-    entries = []
-    for path in enumerate_block_devices():
-        entry = udev_get_block_device(path)
-        if entry:
-            entries.append(entry)
-    return entries
-
-def __is_blacklisted_blockdev(dev_name):
-    """Is this a blockdev we never want for an install?"""
-    if dev_name.startswith("loop") or dev_name.startswith("ram") or dev_name.startswith("fd"):
-        return True
-
-    if os.path.exists("/sys/class/block/%s/device/model" %(dev_name,)):
-        model = open("/sys/class/block/%s/device/model" %(dev_name,)).read()
-        for bad in ("IBM *STMF KERNEL", "SCEI Flash-5", "DGC LUNZ"):
-            if model.find(bad) != -1:
-                return True
-
-    return False
-
-def enumerate_block_devices():
-    top_dir = "/sys/class/block"
-    devices = []
-    for dev_name in os.listdir(top_dir):
-        if __is_blacklisted_blockdev(dev_name):
-            continue
-        full_path = os.path.join(top_dir, dev_name)
-        link_ref = os.readlink(full_path)
-        real_path = os.path.join(top_dir, link_ref)
-        sysfs_path = os.path.normpath(real_path)
-        devices.append(sysfs_path)
-    return devices
-
-def udev_get_block_device(sysfs_path):
-    if not os.path.exists(sysfs_path):
-        return None
-
-    db_entry = sysfs_path[4:].replace("/", "\\x2f")
-    db_root = "/dev/.udev/db"
-    db_path = os.path.normpath("%s/%s" % (db_root, db_entry))
-    if not os.access(db_path, os.R_OK):
-        return None
-
-    entry = open(db_path).read()
-    dev = udev_parse_block_entry(entry)
-    if dev:
-        # XXX why do we do this? is /sys going to move during installation?
-        dev['sysfs_path'] = sysfs_path[4:]  # strip off the leading '/sys'
-        dev = udev_parse_uevent_file(dev)
-
-    # now add in the contents of the uevent file since they're handy
-    return dev
-
-def udev_parse_uevent_file(dev):
-    path = os.path.normpath("/sys/%s/uevent" % dev['sysfs_path'])
-    if not os.access(path, os.R_OK):
-        return dev
-
-    with open(path) as f:
-        for line in f.readlines():
-            (key, equals, value) = line.strip().partition("=")
-            if not equals:
-                continue
-            dev[key] = value
-
-    return dev
-
-def udev_parse_block_entry(buf):
-    dev = {'name': None,
-           'symlinks': []}
-
-    for line in buf.splitlines():
-        line.strip()
-        (tag, sep, val) = line.partition(":")
-        if not sep:
-            continue
-
-        if tag == "N":
-            dev['name'] = val
-        elif tag == "S":
-            dev['symlinks'].append(val)
-        elif tag == "E":
-            if val.count("=") > 1 and val.count(" ") > 0:
-                # eg: LVM2_LV_NAME when querying the VG for its LVs
-                vars = val.split()
-                vals = []
-                var_name = None
-                for (index, subval) in enumerate(vars):
-                    (var_name, sep, var_val) = subval.partition("=")
-                    if sep:
-                        vals.append(var_val)
-
-                dev[var_name] = vals
-            else:
-                (var_name, sep, var_val) = val.partition("=")
-                if not sep:
-                    continue
-
-                if var_val.count(" "):
-                    # eg: DEVLINKS
-                    var_val = var_val.split()
-
-                dev[var_name] = var_val
-
-    if dev.get("name"):
-        return dev
-
-# These are functions for retrieving specific pieces of information from
-# udev database entries.
-def udev_device_get_name(udev_info):
-    """ Return the best name for a device based on the udev db data. """
-    return udev_info.get("DM_NAME", udev_info["name"])
-
-def udev_device_get_format(udev_info):
-    """ Return a device's format type as reported by udev. """
-    return udev_info.get("ID_FS_TYPE")
-
-def udev_device_get_uuid(udev_info):
-    """ Get the UUID from the device's format as reported by udev. """
-    md_uuid = udev_info.get("MD_UUID")
-    uuid = udev_info.get("ID_FS_UUID")
-    # we don't want to return the array's uuid as a member's uuid
-    if uuid and not md_uuid == uuid:
-        return udev_info.get("ID_FS_UUID")
-
-def udev_device_get_label(udev_info):
-    """ Get the label from the device's format as reported by udev. """
-    return udev_info.get("ID_FS_LABEL")
-
-def udev_device_is_dm(info):
-    """ Return True if the device is a device-mapper device. """
-    return info.has_key("DM_NAME")
-
-def udev_device_is_md(info):
-    """ Return True is the device is an mdraid array device. """
-    return info.has_key("MD_METADATA")
-
-def udev_device_is_cdrom(info):
-    """ Return True if the device is an optical drive. """
-    # FIXME: how can we differentiate USB drives from CD-ROM drives?
-    #         -- USB drives also generate a sdX device.
-    return info.get("ID_CDROM") == "1"
-
-def udev_device_is_disk(info):
-    """ Return True is the device is a disk. """
-    has_range = os.path.exists("/sys/%s/range" % info['sysfs_path'])
-    return info.get("DEVTYPE") == "disk" or has_range
-
-def udev_device_is_partition(info):
-    has_start = os.path.exists("/sys/%s/start" % info['sysfs_path'])
-    return info.get("DEVTYPE") == "partition" or has_start
-
-def udev_device_get_sysfs_path(info):
-    return info['sysfs_path']
-
-def udev_device_get_major(info):
-    return int(info["MAJOR"])
-
-def udev_device_get_minor(info):
-    return int(info["MINOR"])
-
-def udev_device_get_md_level(info):
-    return info["MD_LEVEL"]
-
-def udev_device_get_md_devices(info):
-    return int(info["MD_DEVICES"])
-
-def udev_device_get_md_uuid(info):
-    return info["MD_UUID"]
-
-def udev_device_get_vg_name(info):
-    return info['LVM2_VG_NAME']
-
-def udev_device_get_vg_uuid(info):
-    return info['LVM2_VG_UUID']
-
-def udev_device_get_vg_size(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_VG_SIZE']) / 1024
-
-def udev_device_get_vg_free(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_VG_FREE']) / 1024
-
-def udev_device_get_vg_extent_size(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_VG_EXTENT_SIZE']) / 1024
-
-def udev_device_get_vg_extent_count(info):
-    return int(info['LVM2_VG_EXTENT_COUNT'])
-
-def udev_device_get_vg_free_extents(info):
-    return int(info['LVM2_VG_FREE_COUNT'])
-
-def udev_device_get_vg_pv_count(info):
-    return int(info['LVM2_PV_COUNT'])
-
-def udev_device_get_pv_pe_start(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    return float(info['LVM2_PE_START']) / 1024
-
-def udev_device_get_lv_names(info):
-    names = info['LVM2_LV_NAME']
-    if not names:
-        names = []
-    elif not isinstance(names, list):
-        names = [names]
-    return names
-
-def udev_device_get_lv_uuids(info):
-    uuids = info['LVM2_LV_UUID']
-    if not uuids:
-        uuids = []
-    elif not isinstance(uuids, list):
-        uuids = [uuids]
-    return uuids
-
-def udev_device_get_lv_sizes(info):
-    # lvm's decmial precision is not configurable, so we tell it to use
-    # KB and convert to MB here
-    sizes = info['LVM2_LV_SIZE']
-    if not sizes:
-        sizes = []
-    elif not isinstance(sizes, list):
-        sizes = [sizes]
-
-    return [float(s) / 1024 for s in sizes]
-
-def udev_device_is_dmraid(info):
-    # Note that this function does *not* identify raid sets.
-    # Tests to see if device is parto of a dmraid set.
-    # dmraid and mdriad have the same ID_FS_USAGE string,  ID_FS_TYPE has a
-    # string that describes the type of dmraid (isw_raid_member...),  I don't
-    # want to maintain a list and mdraid's ID_FS_TYPE='linux_raid_member', so
-    # dmraid will be everything that is raid and not linux_raid_member
-    #from formats.dmraid import DMRaidMember
-    #if info.has_key("ID_FS_TYPE") and \
-    #        info["ID_FS_TYPE"] in DMRaidMember._udevTypes:
-    #    return True
-    #
-    return False
-
-def udev_device_get_dmraid_partition_disk(info):
-    try:
-        p_index = info["DM_NAME"].rindex("p")
-    except (KeyError, AttributeError, ValueError):
-        return None
-
-    if not info["DM_NAME"][p_index+1:].isdigit():
-        return None
-
-    return info["DM_NAME"][:p_index]
-
-def udev_device_is_dmraid_partition(info, devicetree):
-    #diskname = udev_device_get_dmraid_partition_disk(info)
-    #dmraid_devices = devicetree.getDevicesByType("dm-raid array")
-    #
-    #for device in dmraid_devices:
-    #    if diskname == device.name:
-    #        return True
-    #
-    return False
-
-if __name__ == "__main__":
-    for device in udev_get_block_devices():
-        print udev_device_get_name(device)
-        print " Label   :", udev_device_get_label(device)
-        print " UUID    :", udev_device_get_uuid(device)
-        print " Format  :", udev_device_get_format(device)
-        print " Is disk :", udev_device_is_disk(device)
-        print " Is cdrom:", udev_device_is_cdrom(device)
-        print " Is part :", udev_device_is_partition(device)
-        print " Is dm   :", udev_device_is_dm(device)
-        print " Is md   :", udev_device_is_md(device)
-        #syspath = "/sys" + udev_device_get_sysfs_path(device)
-        #for (key, value) in udev_get_block_device(syspath).items():
-        #    print " (%s : %s)" % (key, value,)
-        print