def _build_mpath_topology(self):
        with open("/etc/multipath.conf") as conf:
            log.debug("/etc/multipath.conf contents:")
            map(lambda line: log.debug(line.rstrip()), conf)
            log.debug("(end of /etc/multipath.conf)")
        self._mpath_topology = parseMultipathOutput(
            iutil.execWithCapture("multipath", ["-d",]))
        self._mpath_topology.update(parseMultipathOutput(
                iutil.execWithCapture("multipath", ["-ll",])))

        delete_keys = []
        for (mp, disks) in self._mpath_topology.items():
            # single device mpath is not really an mpath, eliminate them:
            if len(disks) < 2:
                log.info("MultipathTopology: not a multipath: %s" % disks)
                delete_keys.append(mp)
                continue
            # some usb cardreaders use multiple lun's (for different slots) and
            # report a fake disk serial which is the same for all the lun's
            # (#517603). find those mpaths and eliminate them:
            only_non_usbs = [d for d in disks if
                             self._devmap[d].get("ID_USB_DRIVER") != "usb-storage"]
            if len(only_non_usbs) == 0:
                log.info("DeviceToppology: found multi lun usb "
                         "mass storage device: %s" % disks)
                delete_keys.append(mp)
        map(lambda key: self._mpath_topology.pop(key), delete_keys)
Пример #2
0
 def testExecCaptureNonZeroFatal(self):
     import iutil
     try:
         argv = ["-c", "import sys; sys.exit(3);"]
         iutil.execWithCapture(sys.executable, argv, root=None, fatal=True)
     except RuntimeError, ex:
         self.assertIn("return code: 3", str(ex))
Пример #3
0
    def exec_with_capture_test(self):
        """Test execWithCapture."""

        # check some output is returned
        self.assertGreater(len(iutil.execWithCapture("ls", ["--help"])), 0)

        # check no output is returned
        self.assertEqual(len(iutil.execWithCapture("true", [])), 0)
Пример #4
0
    def exec_with_capture_test(self):
        """Test execWithCapture."""

        # check some output is returned
        self.assertGreater(len(iutil.execWithCapture('ls', ['--help'])), 0)

        # check no output is returned
        self.assertEqual(len(iutil.execWithCapture('true', [])), 0)
Пример #5
0
    def testExecCaptureNonZeroFatal(self):
        import iutil

        try:
            argv = ["-c", "import sys; sys.exit(3);"]
            iutil.execWithCapture(sys.executable, argv, root=None, fatal=True)
        except RuntimeError, ex:
            self.assertIn("return code: 3", str(ex))
Пример #6
0
    def exec_with_capture_test(self):
        """Test execWithCapture."""

        # check some output is returned
        self.assertGreater(len(iutil.execWithCapture('ls', ['--help'])), 0)

        # check no output is returned
        self.assertEqual(len(iutil.execWithCapture('true', [])), 0)
Пример #7
0
def shutdownServer():
    """Try to shutdown any running XVNC server

    Why is this function on the module level and not in the VncServer class ?

    As the server needs to be killed from the exit handler, it would have
    to somehow get to the VncServer instance. Like this, it can just kill
    it by calling a function of the vnc module.
    """
    try:
        iutil.execWithCapture("killall", [XVNC_BINARY_NAME])
        log.info("The XVNC server has been shut down.")
    except OSError as e:
        log.error("Shutdown of the XVNC server failed with exception:\n%s", e)
Пример #8
0
def shutdownServer():
    """Try to shutdown any running XVNC server

    Why is this function on the module level and not in the VncServer class ?

    As the server needs to be killed from the exit handler, it would have
    to somehow get to the VncServer instance. Like this, it can just kill
    it by calling a function of the vnc module.
    """
    try:
        iutil.execWithCapture("killall", [XVNC_BINARY_NAME])
        log.info("The XVNC server has been shut down.")
    except OSError as e:
        log.error("Shutdown of the XVNC server failed with exception:\n%s", e)
Пример #9
0
    def exec_with_capture_empty_test(self):
        """Test execWithCapture with no output"""

        # check that the output is an empty string
        self.assertEqual(
                iutil.execWithCapture("/bin/sh", ["-c", "exit 0"]),
                "")
Пример #10
0
def lvs(vg_name):
    args = ["lvs", "--noheadings", "--nosuffix"] + \
            ["--units", "m"] + \
            ["-o", "lv_name,lv_uuid,lv_size,lv_attr"] + \
            config_args + \
            [vg_name]

    buf = iutil.execWithCapture("lvm",
                                args,
                                stderr="/dev/tty5")

    lvs = {}
    for line in buf.splitlines():
        line = line.strip()
        if not line:
            continue
        (name, uuid, size, attr) = line.split()
        lvs[name] = {"size": size,
                     "uuid": uuid,
                     "attr": attr}

    if not lvs:
        raise LVMError(_("lvs failed for %s" % vg_name))

    return lvs
Пример #11
0
    def minSize(self):
        """ The minimum filesystem size in megabytes. """
        if self._minInstanceSize is None:
            # we try one time to determine the minimum size.
            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
                        log.warning("Unable to parse output for minimum size on %s: %s" %(self.device, e))

                if minSize is None:
                    log.warning("Unable to discover minimum size of filesystem "
                                "on %s" %(self.device,))
                else:
                    size = minSize

            self._minInstanceSize = size
Пример #12
0
def pvinfo(device):
    """
        If the PV was created with '--metadacopies 0', lvm will do some
        scanning of devices to determine from their metadata which VG
        this PV belongs to.

        pvs -o pv_name,pv_mda_count,vg_name,vg_uuid --config \
            'devices { scan = "/dev" filter = ["a/loop0/", "r/.*/"] }'
    """
    #cfg = "'devices { scan = \"/dev\" filter = [\"a/%s/\", \"r/.*/\"] }'" 
    args = ["pvs", "--noheadings"] + \
            ["--units", "m"] + \
            ["-o", "pv_name,pv_mda_count,vg_name,vg_uuid"] + \
            config_args + \
            [device]

    rc = iutil.execWithCapture("lvm", args,
                                stderr = "/dev/tty5")
    vals = rc.split()
    if not vals:
        raise LVMError("pvinfo failed for %s" % device)

    # don't raise an exception if pv is not a part of any vg
    pv_name = vals[0]
    try:
        vg_name, vg_uuid = vals[2], vals[3]
    except IndexError:
        vg_name, vg_uuid = "", ""
    
    info = {'pv_name': pv_name,
            'vg_name': vg_name,
            'vg_uuid': vg_uuid}

    return info
Пример #13
0
def pvinfo(device):
    """
        If the PV was created with '--metadacopies 0', lvm will do some
        scanning of devices to determine from their metadata which VG
        this PV belongs to.

        pvs -o pv_name,pv_mda_count,vg_name,vg_uuid --config \
            'devices { scan = "/dev" filter = ["a/loop0/", "r/.*/"] }'
    """
    #cfg = "'devices { scan = \"/dev\" filter = [\"a/%s/\", \"r/.*/\"] }'"
    args = ["pvs", "--noheadings"] + \
            ["--units", "m"] + \
            ["-o", "pv_name,pv_mda_count,vg_name,vg_uuid"] + \
            config_args + \
            [device]

    rc = iutil.execWithCapture("lvm", args, stderr="/dev/tty5")
    vals = rc.split()
    if not vals:
        raise LVMError("pvinfo failed for %s" % device)

    # don't raise an exception if pv is not a part of any vg
    pv_name = vals[0]
    try:
        vg_name, vg_uuid = vals[2], vals[3]
    except IndexError:
        vg_name, vg_uuid = "", ""

    info = {'pv_name': pv_name, 'vg_name': vg_name, 'vg_uuid': vg_uuid}

    return info
Пример #14
0
    def minSize(self):
        """ The minimum filesystem size in megabytes. """
        if self._minInstanceSize is None:
            # we try one time to determine the minimum size.
            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
                        log.warning(
                            "Unable to parse output for minimum size on %s: %s"
                            % (self.device, e))

                if minSize is None:
                    log.warning(
                        "Unable to discover minimum size of filesystem "
                        "on %s" % (self.device, ))
                else:
                    size = minSize

            self._minInstanceSize = size
Пример #15
0
    def exec_with_capture_empty_test(self):
        """Test execWithCapture with no output"""

        # check that the output is an empty string
        self.assertEqual(
                iutil.execWithCapture("/bin/sh", ["-c", "exit 0"]),
                "")
Пример #16
0
    def minSize(self):
        """ Minimum size for this filesystem in MB. """
        if self._minInstanceSize is None:
            # try once in the beginning to get the minimum size for an
            # existing filesystem.
            size = self._minSize
            blockSize = None

            if self.exists and os.path.exists(self.device):
                # get block size
                buf = iutil.execWithCapture(self.infofsProg,
                                            ["-h", self.device],
                                            stderr="/dev/tty5")
                for line in buf.splitlines():
                    if line.startswith("Block size:"):
                        blockSize = int(line.split(" ")[-1])
                        break

                if blockSize is None:
                    raise FSError("failed to get block size for %s filesystem "
                                  "on %s" % (self.mountType, self.device))

                # get minimum size according to resize2fs
                buf = iutil.execWithCapture(self.resizefsProg,
                                            ["-P", self.device],
                                            stderr="/dev/tty5")
                for line in buf.splitlines():
                    if "minimum size of the filesystem:" not in line:
                        continue

                    # line will look like:
                    # Estimated minimum size of the filesystem: 1148649
                    #
                    # NOTE: The minimum size reported is in blocks.  Convert
                    # to bytes, then megabytes, and finally round up.
                    (text, sep, minSize) = line.partition(": ")
                    size = long(minSize) * blockSize
                    size = math.ceil(size / 1024.0 / 1024.0)
                    break

                if size is None:
                    log.warning("failed to get minimum size for %s filesystem "
                                "on %s" % (self.mountType, self.device))

            self._minInstanceSize = size

        return self._minInstanceSize
Пример #17
0
    def minSize(self):
        """ Minimum size for this filesystem in MB. """
        if self._minInstanceSize is None:
            # try once in the beginning to get the minimum size for an
            # existing filesystem.
            size = self._minSize
            blockSize = None

            if self.exists and os.path.exists(self.device):
                # get block size
                buf = iutil.execWithCapture(self.infofsProg,
                                            ["-h", self.device],
                                            stderr="/dev/tty5")
                for line in buf.splitlines():
                    if line.startswith("Block size:"):
                        blockSize = int(line.split(" ")[-1])
                        break

                if blockSize is None:
                    raise FSError("failed to get block size for %s filesystem "
                                  "on %s" % (self.mountType, self.device))

                # get minimum size according to resize2fs
                buf = iutil.execWithCapture(self.resizefsProg,
                                            ["-P", self.device],
                                            stderr="/dev/tty5")
                for line in buf.splitlines():
                    if "minimum size of the filesystem:" not in line:
                        continue

                    # line will look like:
                    # Estimated minimum size of the filesystem: 1148649
                    #
                    # NOTE: The minimum size reported is in blocks.  Convert
                    # to bytes, then megabytes, and finally round up.
                    (text, sep, minSize) = line.partition(": ")
                    size = long(minSize) * blockSize
                    size = math.ceil(size / 1024.0 / 1024.0)
                    break

                if size is None:
                    log.warning("failed to get minimum size for %s filesystem "
                                "on %s" % (self.mountType, self.device))

            self._minInstanceSize = size

        return self._minInstanceSize
def modulesWithPaths():
    mods = []
    for modline in open("/proc/modules", "r"):
        modName = modline.split(" ", 1)[0]
        modInfo = iutil.execWithCapture("modinfo", ["-F", "filename", modName]).splitlines()
        modPaths = [line.strip() for line in modInfo if line != ""]
        mods.extend(modPaths)
    return mods
Пример #19
0
    def exec_with_capture_no_stderr_test(self):
        """Test execWithCapture with no stderr"""

        with tempfile.NamedTemporaryFile(mode="w+t") as testscript:
            testscript.write(
                """#!/bin/sh
echo "output"
echo "error" >&2
"""
            )
            testscript.flush()

            # check that only the output is captured
            self.assertEqual(iutil.execWithCapture("/bin/sh", [testscript.name], filter_stderr=True), "output\n")

            # check that both output and error are captured
            self.assertEqual(iutil.execWithCapture("/bin/sh", [testscript.name]), "output\nerror\n")
Пример #20
0
def modulesWithPaths():
    mods = []
    for modline in open("/proc/modules", "r"):
        modName = modline.split(" ", 1)[0]
        modInfo = iutil.execWithCapture(
            "modinfo", ["-F", "filename", modName]).splitlines()
        modPaths = [line.strip() for line in modInfo if line != ""]
        mods.extend(modPaths)
    return mods
Пример #21
0
    def exec_with_capture_no_stderr_test(self):
        """Test execWithCapture with no stderr"""

        with tempfile.NamedTemporaryFile(mode="w+t") as testscript:
            testscript.write("""#!/bin/sh
echo "output"
echo "error" >&2
""")
            testscript.flush()

            # check that only the output is captured
            self.assertEqual(
                    iutil.execWithCapture("/bin/sh", [testscript.name], filter_stderr=True),
                    "output\n")

            # check that both output and error are captured
            self.assertEqual(iutil.execWithCapture("/bin/sh", [testscript.name]),
                    "output\nerror\n")
Пример #22
0
def ifaceForHostIP(host):
    route = iutil.execWithCapture("ip", ["route", "get", "to", host])
    if not route:
        log.error("Could not get interface for route to %s", host)
        return ""

    routeInfo = route.split()
    if routeInfo[0] != host or len(routeInfo) < 5 or "dev" not in routeInfo or routeInfo.index("dev") > 3:
        log.error('Unexpected "ip route get to %s" reply: %s', host, routeInfo)
        return ""

    return routeInfo[routeInfo.index("dev") + 1]
Пример #23
0
def _get_backing_devnums_from_map(map_name):
    ret = []
    buf = iutil.execWithCapture(
        "dmsetup",
        ["info", "--columns", "--noheadings", "-o", "devnos_used", map_name],
        stderr="/dev/tty5")
    dev_nums = buf.split()
    for dev_num in dev_nums:
        (major, colon, minor) = dev_num.partition(":")
        ret.append((int(major), int(minor)))

    return ret
Пример #24
0
    def writeZipl(self, instRoot, bl, kernelList, chainList,
                  defaultDev, justConfigFile):
        rootDev = self.storage.rootDevice
        
        cf = '/etc/zipl.conf'
        self.perms = 0600
        if os.access (instRoot + cf, os.R_OK):
            self.perms = os.stat(instRoot + cf)[0] & 0777
            os.rename(instRoot + cf,
                      instRoot + cf + '.rpmsave')

        f = open(instRoot + cf, "w+")        

        f.write('[defaultboot]\n')
        if self.timeout:
            f.write('timeout=%d\n' % self.timeout)
        f.write('default=' + kernelList[0][0] + '\n')
        f.write('target=%s\n' % (self.kernelLocation))

        cfPath = "/boot/"
        for (label, longlabel, version) in kernelList:
            kernelTag = "-" + version
            kernelFile = "%svmlinuz%s" % (cfPath, kernelTag)

            initrd = self.makeInitrd(kernelTag, instRoot)
            f.write('[%s]\n' % (label))
            f.write('\timage=%s\n' % (kernelFile))
            if initrd:
                f.write('\tramdisk=%s%s\n' %(self.kernelLocation, initrd))

            realroot = rootDev.fstabSpec
            f.write('\tparameters="root=%s' %(realroot,))
            if bl.args.get():
                f.write(' %s' % (bl.args.get()))
            f.write('"\n')

        f.close()

        if not justConfigFile:
            rc = iutil.execWithCapture("zipl", [], root = instRoot,
                                       stderr = "/dev/stderr")
            for line in rc.splitlines():
                if line.startswith("Preparing boot device: "):
                    # Output here may look like:
                    #     Preparing boot device: dasdb (0200).
                    #     Preparing boot device: dasdl.
                    # We want to extract the device name and pass that.

                    fields = line[23:].split()
                    self.setDevice(fields[0].replace('.', ''))

        return 0
Пример #25
0
    def writeZipl(self, instRoot, bl, kernelList, chainList, defaultDev,
                  justConfigFile):
        rootDev = self.storage.rootDevice

        cf = '/etc/zipl.conf'
        self.perms = 0600
        if os.access(instRoot + cf, os.R_OK):
            self.perms = os.stat(instRoot + cf)[0] & 0777
            os.rename(instRoot + cf, instRoot + cf + '.rpmsave')

        f = open(instRoot + cf, "w+")

        f.write('[defaultboot]\n')
        if self.timeout:
            f.write('timeout=%d\n' % self.timeout)
        f.write('default=' + kernelList[0][0] + '\n')
        f.write('target=%s\n' % (self.kernelLocation))

        cfPath = "/boot/"
        for (label, longlabel, version) in kernelList:
            kernelTag = "-" + version
            kernelFile = "%svmlinuz%s" % (cfPath, kernelTag)

            initrd = self.makeInitrd(kernelTag, instRoot)
            f.write('[%s]\n' % (label))
            f.write('\timage=%s\n' % (kernelFile))
            if initrd:
                f.write('\tramdisk=%s%s\n' % (self.kernelLocation, initrd))

            realroot = rootDev.fstabSpec
            f.write('\tparameters="root=%s' % (realroot, ))
            if bl.args.get():
                f.write(' %s' % (bl.args.get()))
            f.write('"\n')

        f.close()

        if not justConfigFile:
            rc = iutil.execWithCapture("zipl", [],
                                       root=instRoot,
                                       stderr="/dev/stderr")
            for line in rc.splitlines():
                if line.startswith("Preparing boot device: "):
                    # Output here may look like:
                    #     Preparing boot device: dasdb (0200).
                    #     Preparing boot device: dasdl.
                    # We want to extract the device name and pass that.

                    fields = line[23:].split()
                    self.setDevice(fields[0].replace('.', ''))

        return 0
Пример #26
0
def ifaceForHostIP(host):
    route = iutil.execWithCapture("ip", ["route", "get", "to", host])
    if not route:
        log.error("Could not get interface for route to %s", host)
        return ""

    routeInfo = route.split()
    if routeInfo[0] != host or len(routeInfo) < 5 or \
       "dev" not in routeInfo or routeInfo.index("dev") > 3:
        log.error('Unexpected "ip route get to %s" reply: %s', host, routeInfo)
        return ""

    return routeInfo[routeInfo.index("dev") + 1]
Пример #27
0
def lvorigin(vg_name, lv_name):
    args = ["lvs", "--noheadings", "-o", "origin"] + \
            config_args + \
            ["%s/%s" % (vg_name, lv_name)]

    buf = iutil.execWithCapture("lvm", args, stderr="/dev/tty5")

    try:
        origin = buf.splitlines()[0].strip()
    except IndexError:
        origin = ''

    return origin
Пример #28
0
    def _startEDD(self, intf = None):
        rc = iutil.execWithCapture("/usr/libexec/fcoe/fcoe_edd.sh", [ "-i" ],
                                   stderr="/dev/tty5")
        if not rc.startswith("NIC="):
            log.info("No FCoE EDD info found: %s" % rc.rstrip())
            return

        (key, val) = rc.strip().split("=", 1)
        if val not in isys.getDeviceProperties():
            log.error("Unknown FCoE NIC found in EDD: %s, ignoring" % val)
            return

        log.info("FCoE NIC found in EDD: %s" % val)
        self.addSan(val, dcb=True, auto_vlan=True, intf=intf)
Пример #29
0
    def _startEDD(self, intf=None):
        rc = iutil.execWithCapture("/usr/libexec/fcoe/fcoe_edd.sh", ["-i"],
                                   stderr="/dev/tty5")
        if not rc.startswith("NIC="):
            log.info("No FCoE EDD info found: %s" % rc.rstrip())
            return

        (key, val) = rc.split("=", 1)
        if val not in isys.getDeviceProperties():
            log.error("Unknown FCoE NIC found in EDD: %s, ignoring" % val)
            return

        log.info("FCoE NIC found in EDD: %s" % val)
        self.addSan(val, dcb=True, intf=intf)
Пример #30
0
def lvorigin(vg_name, lv_name):
    args = ["lvs", "--noheadings", "-o", "origin"] + \
            config_args + \
            ["%s/%s" % (vg_name, lv_name)]

    buf = iutil.execWithCapture("lvm",
                                args,
                                stderr="/dev/tty5")

    try:
        origin = buf.splitlines()[0].strip()
    except IndexError:
        origin = ''

    return origin
Пример #31
0
def vginfo(vg_name):
    args = ["vgs", "--noheadings", "--nosuffix"] + \
            ["--units", "m"] + \
            ["-o", "uuid,size,free,extent_size,extent_count,free_count,pv_count"] + \
            config_args + \
            [vg_name]

    buf = iutil.execWithCapture("lvm", args, stderr="/dev/tty5")
    info = buf.split()
    if len(info) != 7:
        raise LVMError(_("vginfo failed for %s" % vg_name))

    d = {}
    (d['uuid'], d['size'], d['free'], d['pe_size'], d['pe_count'],
     d['pe_free'], d['pv_count']) = info
    return d
Пример #32
0
def dm_node_from_name(map_name):
    dm_node = block.getDmNodeFromName(map_name)
    if dm_node is not None:
        return dm_node

    devnum = iutil.execWithCapture(
        "dmsetup",
        ["info", "--columns", "--noheadings", "-o", "devno", map_name],
        stderr="/dev/tty5")
    (major, sep, minor) = devnum.strip().partition(":")
    if not sep:
        raise DMError("dm device does not exist")

    dm_node = "dm-%d" % int(minor)
    log.debug("dm_node_from_name(%s) returning '%s'" % (map_name, dm_node))
    return dm_node
Пример #33
0
def name_from_dm_node(dm_node):
    name = block.getNameFromDmNode(dm_node)
    if name is not None:
        return name

    st = os.stat("/dev/%s" % dm_node)
    major = os.major(st.st_rdev)
    minor = os.minor(st.st_rdev)
    name = iutil.execWithCapture("dmsetup", [
        "info", "--columns", "--noheadings", "-o", "name", "-j",
        str(major), "-m",
        str(minor)
    ],
                                 stderr="/dev/tty5")
    log.debug("name_from_dm(%s) returning '%s'" % (dm_node, name.strip()))
    return name.strip()
Пример #34
0
def vginfo(vg_name):
    args = ["vgs", "--noheadings", "--nosuffix"] + \
            ["--units", "m"] + \
            ["-o", "uuid,size,free,extent_size,extent_count,free_count,pv_count"] + \
            config_args + \
            [vg_name]

    buf = iutil.execWithCapture("lvm",
                                args,
                                stderr="/dev/tty5")
    info = buf.split()
    if len(info) != 7:
        raise LVMError(_("vginfo failed for %s" % vg_name))

    d = {}
    (d['uuid'],d['size'],d['free'],d['pe_size'],
     d['pe_count'],d['pe_free'],d['pv_count']) = info
    return d
Пример #35
0
def mdexamine(device):
    vars = iutil.execWithCapture("mdadm", ["--examine", "--brief", device],
                                 stderr="/dev/tty5").split()

    info = {}
    if vars:
        try:
            info["device"] = vars[1]
            vars = vars[2:]
        except IndexError:
            return {}

    for var in vars:
        (name, equals, value) = var.partition("=")
        if not equals:
            continue

        info[name.lower()] = value.strip()

    return info
def mdexamine(device):
    vars = iutil.execWithCapture("mdadm",
                                 ["--examine", "--brief", device],
                                 stderr="/dev/tty5").split()

    info = {}
    if vars:
        try:
            info["device"] = vars[1]
            vars = vars[2:]
        except IndexError:
            return {}

    for var in vars:
        (name, equals, value) = var.partition("=")
        if not equals:
            continue

        info[name.lower()] = value.strip()

    return info
Пример #37
0
def lvs(vg_name):
    args = ["lvs", "--noheadings", "--nosuffix"] + \
            ["--units", "m"] + \
            ["-o", "lv_name,lv_uuid,lv_size,lv_attr"] + \
            config_args + \
            [vg_name]

    buf = iutil.execWithCapture("lvm", args, stderr="/dev/tty5")

    lvs = {}
    for line in buf.splitlines():
        line = line.strip()
        if not line:
            continue
        (name, uuid, size, attr) = line.split()
        lvs[name] = {"size": size, "uuid": uuid, "attr": attr}

    if not lvs:
        raise LVMError(_("lvs failed for %s" % vg_name))

    return lvs
Пример #38
0
    def write(self):
        if self.desktop:
            with open(ROOT_PATH + "/etc/sysconfig/desktop", "w") as f:
                f.write("DESKTOP=%s\n" % self.desktop)

        if not os.path.isdir(ROOT_PATH + '/etc/systemd/system'):
            log.warning("there is no /etc/systemd/system directory, cannot update default.target!")
            return

        default_target = ROOT_PATH + '/etc/systemd/system/default.target'
        if os.path.islink(default_target):
            os.unlink(default_target)

        sd_prefix = iutil.execWithCapture(
            "pkg-config", ["--variable=prefix", "systemd"]).strip()
        if not sd_prefix:
            sd_prefix = "/usr"  # assume /usr in Gentoo/Sabayon

        os.symlink('%s/lib/systemd/system/%s' % (
                sd_prefix, RUNLEVELS[self.runlevel]),
                   default_target)
Пример #39
0
def nmcli_dev_list_callback():
    """Callback to get info about network devices."""

    return iutil.execWithCapture("nmcli", ["device", "show"])
Пример #40
0
def lsblk_callback():
    """Callback to get info about block devices."""

    return iutil.execWithCapture("lsblk", ["--perms", "--fs", "--bytes"])
Пример #41
0
    def _getExistingSize(self):
        """ Determine the size of this filesystem.  Filesystem must
            exist.  Each filesystem varies, but the general procedure
            is to run the filesystem dump or info utility and read
            the block size and number of blocks for the filesystem
            and compute megabytes from that.

            The loop that reads the output from the infofsProg is meant
            to be simple, but take in to account variations in output.
            The general procedure:
                1) Capture output from infofsProg.
                2) Iterate over each line of the output:
                       a) Trim leading and trailing whitespace.
                       b) Break line into fields split on ' '
                       c) If line begins with any of the strings in
                          _existingSizeFields, start at the end of
                          fields and take the first one that converts
                          to a long.  Store this in the values list.
                       d) Repeat until the values list length equals
                          the _existingSizeFields length.
                3) If the length of the values list equals the length
                   of _existingSizeFields, compute the size of this
                   filesystem by multiplying all of the values together
                   to get bytes, then convert to megabytes.  Return
                   this value.
                4) If we were unable to capture all fields, return 0.

            The caller should catch exceptions from this method.  Any
            exception raised indicates a need to change the fields we
            are looking for, the command to run and arguments, or
            something else.  If you catch an exception from this method,
            assume the filesystem cannot be resized.
        """
        size = self._size

        if self.infofsProg and self.mountable and self.exists and not size:
            try:
                values = []
                argv = self._defaultInfoOptions + [ self.device ]

                buf = iutil.execWithCapture(self.infofsProg, argv,
                                            stderr="/dev/tty5")

                for line in buf.splitlines():
                    found = False

                    line = line.strip()
                    tmp = line.split(' ')
                    tmp.reverse()

                    for field in self._existingSizeFields:
                        if line.startswith(field):
                            for subfield in tmp:
                                try:
                                    values.append(long(subfield))
                                    found = True
                                    break
                                except ValueError:
                                    continue

                        if found:
                            break

                    if len(values) == len(self._existingSizeFields):
                        break

                if len(values) != len(self._existingSizeFields):
                    return 0

                size = 1
                for value in values:
                    size *= value

                # report current size as megabytes
                size = math.floor(size / 1024.0 / 1024.0)
            except Exception as e:
                log.error("failed to obtain size of filesystem on %s: %s"
                          % (self.device, e))

        return size
Пример #42
0
 def _getRandomUUID(self):
     uuid = iutil.execWithCapture("uuidgen", []).strip()
     return uuid
Пример #43
0
def identifyMultipaths(devices):
    # this function does a couple of things
    # 1) identifies multipath disks
    # 2) sets their ID_FS_TYPE to multipath_member
    # 3) removes the individual members of an mpath's partitions
    # sample input with multipath pair [sdb,sdc]
    # [sr0, sda, sda1, sdb, sdb1, sdb2, sdc, sdc1, sdd, sdd1, sdd2]
    # sample output:
    # [sda, sdd], [[sdb, sdc]], [sr0, sda1, sdd1, sdd2]]
    log.info("devices to scan for multipath: %s" % [d['name'] for d in devices])

    topology = parseMultipathOutput(iutil.execWithCapture("multipath", ["-d",]))
    # find the devices that aren't in topology, and add them into it...
    topodevs = reduce(lambda x,y: x.union(y), topology.values(), set())
    for name in set([d['name'] for d in devices]).difference(topodevs):
        topology[name] = [name]
    
    devmap = {}
    non_disk_devices = {}
    for d in devices:
        if not udev_device_is_disk(d):
            non_disk_devices[d['name']] = d
            log.info("adding %s to non_disk_device list" % (d['name'],))
            continue
        devmap[d['name']] = d

    singlepath_disks = []
    multipaths = []

    for name, disks in topology.items():
        if len(disks) == 1:
            if not non_disk_devices.has_key(disks[0]):
                log.info("adding %s to singlepath_disks" % (disks[0],))
                singlepath_disks.append(devmap[disks[0]])
        else:
            # some usb cardreaders use multiple lun's (for different slots)
            # and report a fake disk serial which is the same for all the
            # lun's (#517603)
            all_usb = True
            # see if we've got any non-disk devices on our mpath list.
            # If so, they're probably false-positives.
            non_disks = False
            for disk in disks:
                d = devmap[disk]
                if d.get("ID_USB_DRIVER") != "usb-storage":
                    all_usb = False
                if (not devmap.has_key(disk)) and non_disk_devices.has_key(disk):
                    log.warning("non-disk device %s is part of an mpath" %
                                (disk,))
                    non_disks = True

            if all_usb:
                log.info("adding multi lun usb mass storage device to singlepath_disks: %s" %
                         (disks,))
                singlepath_disks.extend([devmap[d] for d in disks])
                continue

            if non_disks:
                for disk in disks:
                    if devmap.has_key(disk):
                        del devmap[disk]
                    if topology.has_key(disk):
                        del topology[disk]
                continue

            log.info("found multipath set: %s" % (disks,))
            for disk in disks:
                d = devmap[disk]
                log.info("adding %s to multipath_disks" % (disk,))
                d["ID_FS_TYPE"] = "multipath_member"
                d["ID_MPATH_NAME"] = name
            
            multipaths.append([devmap[d] for d in disks])

    non_disk_serials = {}
    for name,device in non_disk_devices.items():
        serial = udev_device_get_serial(device)
        non_disk_serials.setdefault(serial, [])
        non_disk_serials[serial].append(device)

    for mpath in multipaths:
        for serial in [d.get('ID_SERIAL_SHORT') for d in mpath]:
            if non_disk_serials.has_key(serial):
                log.info("filtering out non disk devices [%s]" % [d['name'] for d in non_disk_serials[serial]])
                for name in [d['name'] for d in non_disk_serials[serial]]:
                    if non_disk_devices.has_key(name):
                        del non_disk_devices[name]

    partition_devices = []
    for device in non_disk_devices.values():
        partition_devices.append(device)

    # this is the list of devices we want to keep from the original
    # device list, but we want to maintain its original order.
    singlepath_disks = filter(lambda d: d in devices, singlepath_disks)
    #multipaths = filter(lambda d: d in devices, multipaths)
    partition_devices = filter(lambda d: d in devices, partition_devices)

    mpathStr = "["
    for mpath in multipaths:
        mpathStr += str([d['name'] for d in mpath])
    mpathStr += "]"

    s = "(%s, %s, %s)" % ([d['name'] for d in singlepath_disks], \
                          mpathStr, \
                          [d['name'] for d in partition_devices])
    log.info("devices post multipath scan: %s" % s)
    return (singlepath_disks, multipaths, partition_devices)
Пример #44
0
    def _getExistingSize(self):
        """ Determine the size of this filesystem.  Filesystem must
            exist.  Each filesystem varies, but the general procedure
            is to run the filesystem dump or info utility and read
            the block size and number of blocks for the filesystem
            and compute megabytes from that.

            The loop that reads the output from the infofsProg is meant
            to be simple, but take in to account variations in output.
            The general procedure:
                1) Capture output from infofsProg.
                2) Iterate over each line of the output:
                       a) Trim leading and trailing whitespace.
                       b) Break line into fields split on ' '
                       c) If line begins with any of the strings in
                          _existingSizeFields, start at the end of
                          fields and take the first one that converts
                          to a long.  Store this in the values list.
                       d) Repeat until the values list length equals
                          the _existingSizeFields length.
                3) If the length of the values list equals the length
                   of _existingSizeFields, compute the size of this
                   filesystem by multiplying all of the values together
                   to get bytes, then convert to megabytes.  Return
                   this value.
                4) If we were unable to capture all fields, return 0.

            The caller should catch exceptions from this method.  Any
            exception raised indicates a need to change the fields we
            are looking for, the command to run and arguments, or
            something else.  If you catch an exception from this method,
            assume the filesystem cannot be resized.
        """
        size = self._size

        if self.infofsProg and self.mountable and self.exists and not size:
            try:
                values = []
                argv = self._defaultInfoOptions + [self.device]

                buf = iutil.execWithCapture(self.infofsProg,
                                            argv,
                                            stderr="/dev/tty5")

                for line in buf.splitlines():
                    found = False

                    line = line.strip()
                    tmp = line.split(' ')
                    tmp.reverse()

                    for field in self._existingSizeFields:
                        if line.startswith(field):
                            for subfield in tmp:
                                try:
                                    values.append(long(subfield))
                                    found = True
                                    break
                                except ValueError:
                                    continue

                        if found:
                            break

                    if len(values) == len(self._existingSizeFields):
                        break

                if len(values) != len(self._existingSizeFields):
                    return 0

                size = 1
                for value in values:
                    size *= value

                # report current size as megabytes
                size = math.floor(size / 1024.0 / 1024.0)
            except Exception as e:
                log.error("failed to obtain size of filesystem on %s: %s" %
                          (self.device, e))

        return size
Пример #45
0
    def startup(self, intf, exclusiveDisks, zeroMbr):
        """ Look for any unformatted DASDs in the system and offer the user
            the option for format them with dasdfmt or exit the installer.
        """
        if self.started:
            return

        self.started = True
        out = "/dev/tty5"
        err = "/dev/tty5"

        if not iutil.isS390():
            return

        log.info("Checking for unformatted DASD devices:")

        for device in os.listdir("/sys/block"):
            if not device.startswith("dasd"):
                continue

            statusfile = "/sys/block/%s/device/status" % (device, )
            if not os.path.isfile(statusfile):
                continue

            f = open(statusfile, "r")
            status = f.read().strip()
            f.close()

            if status in ["unformatted"] and device not in exclusiveDisks:
                bypath = deviceNameToDiskByPath(device)
                if not bypath:
                    bypath = "/dev/" + device

                log.info("    %s (%s) status is %s, needs dasdfmt" % (
                    device,
                    bypath,
                    status,
                ))
                self._dasdlist.append((device, bypath))

        if not len(self._dasdlist):
            log.info("    no unformatted DASD devices found")
            return

        askUser = True

        if zeroMbr:
            askUser = False
        elif not intf and not zeroMbr:
            log.info("    non-interactive kickstart install without zerombr "
                     "command, unable to run dasdfmt, exiting installer")
            sys.exit(0)

        c = len(self._dasdlist)

        if intf and askUser:
            devs = ''
            for dasd, bypath in self._dasdlist:
                devs += "%s\n" % (bypath, )

            rc = intf.questionInitializeDASD(c, devs)
            if rc == 1:
                log.info("    not running dasdfmt, continuing installation")
                return

        # gather total cylinder count
        argv = ["-t", "-v"] + self.commonArgv
        for dasd, bypath in self._dasdlist:
            buf = iutil.execWithCapture(self.dasdfmt,
                                        argv + ["/dev/" + dasd],
                                        stderr=err)
            for line in buf.splitlines():
                if line.startswith("Drive Geometry: "):
                    # line will look like this:
                    # Drive Geometry: 3339 Cylinders * 15 Heads =  50085 Tracks
                    cyls = long(filter(lambda s: s, line.split(' '))[2])
                    self.totalCylinders += cyls
                    break

        # format DASDs
        argv = ["-P"] + self.commonArgv
        update = self._updateProgressWindow

        title = P_("Formatting DASD Device", "Formatting DASD Devices", c)
        msg = P_("Preparing %d DASD device for use with Linux..." % c,
                 "Preparing %d DASD devices for use with Linux..." % c, c)

        if intf:
            if self.totalCylinders:
                pw = intf.progressWindow(title, msg, 1.0)
            else:
                pw = intf.progressWindow(title, msg, 100, pulse=True)

        for dasd, bypath in self._dasdlist:
            log.info("Running dasdfmt on %s" % (bypath, ))
            arglist = argv + ["/dev/" + dasd]

            try:
                if intf and self.totalCylinders:
                    ret = iutil.execWithCallback(self.dasdfmt,
                                                 arglist,
                                                 stdout=out,
                                                 stderr=err,
                                                 callback=update,
                                                 callback_data=pw,
                                                 echo=False)
                    rc = ret.rc
                elif intf:
                    ret = iutil.execWithPulseProgress(self.dasdfmt,
                                                      arglist,
                                                      stdout=out,
                                                      stderr=err,
                                                      progress=pw)
                    rc = ret.rc
                else:
                    rc = iutil.execWithRedirect(self.dasdfmt,
                                                arglist,
                                                stdout=out,
                                                stderr=err)
            except Exception as e:
                raise DasdFormatError(e, bypath)

            if rc:
                raise DasdFormatError("dasdfmt failed: %s" % rc, bypath)

        if intf:
            pw.pop()
Пример #46
0
def lsblk_callback():
    """Callback to get info about block devices."""

    return iutil.execWithCapture("lsblk", ["--perms", "--fs", "--bytes"])
Пример #47
0
    def startup(self, intf, exclusiveDisks, zeroMbr):
        """ Look for any unformatted DASDs in the system and offer the user
            the option for format them with dasdfmt or exit the installer.
        """
        if self.started:
            return

        self.started = True
        out = "/dev/tty5"
        err = "/dev/tty5"

        if not iutil.isS390():
            return

        log.info("Checking for unformatted DASD devices:")

        for device in os.listdir("/sys/block"):
            if not device.startswith("dasd"):
                continue

            statusfile = "/sys/block/%s/device/status" % (device,)
            if not os.path.isfile(statusfile):
                continue

            f = open(statusfile, "r")
            status = f.read().strip()
            f.close()

            if status in ["unformatted"] and device not in exclusiveDisks:
                bypath = deviceNameToDiskByPath(device)
                if not bypath:
                    bypath = "/dev/" + device

                log.info("    %s (%s) status is %s, needs dasdfmt" % (device,
                                                                      bypath,
                                                                      status,))
                self._dasdlist.append((device, bypath))

        if not len(self._dasdlist):
            log.info("    no unformatted DASD devices found")
            return

        askUser = True

        if zeroMbr:
            askUser = False
        elif not intf and not zeroMbr:
            log.info("    non-interactive kickstart install without zerombr "
                     "command, unable to run dasdfmt, exiting installer")
            sys.exit(0)

        c = len(self._dasdlist)

        if intf and askUser:
            devs = ''
            for dasd, bypath in self._dasdlist:
                devs += "%s\n" % (bypath,)

            rc = intf.questionInitializeDASD(c, devs)
            if rc == 1:
                log.info("    not running dasdfmt, continuing installation")
                return

        # gather total cylinder count
        argv = ["-t", "-v"] + self.commonArgv
        for dasd, bypath in self._dasdlist:
            buf = iutil.execWithCapture(self.dasdfmt, argv + ["/dev/" + dasd],
                                        stderr=err)
            for line in buf.splitlines():
                if line.startswith("Drive Geometry: "):
                    # line will look like this:
                    # Drive Geometry: 3339 Cylinders * 15 Heads =  50085 Tracks
                    cyls = long(filter(lambda s: s, line.split(' '))[2])
                    self.totalCylinders += cyls
                    break

        # format DASDs
        argv = ["-P"] + self.commonArgv
        update = self._updateProgressWindow

        title = P_("Formatting DASD Device", "Formatting DASD Devices", c)
        msg = P_("Preparing %d DASD device for use with Linux..." % c,
                 "Preparing %d DASD devices for use with Linux..." % c, c)

        if intf:
            if self.totalCylinders:
                pw = intf.progressWindow(title, msg, 1.0)
            else:
                pw = intf.progressWindow(title, msg, 100, pulse=True)

        for dasd, bypath in self._dasdlist:
            log.info("Running dasdfmt on %s" % (bypath,))
            arglist = argv + ["/dev/" + dasd]

            try:
                if intf and self.totalCylinders:
                    ret = iutil.execWithCallback(self.dasdfmt, arglist,
                                                 stdout=out, stderr=err,
                                                 callback=update,
                                                 callback_data=pw,
                                                 echo=False)
                    rc = ret.rc
                elif intf:
                    ret = iutil.execWithPulseProgress(self.dasdfmt, arglist,
                                                      stdout=out, stderr=err,
                                                      progress=pw)
                    rc = ret.rc
                else:
                    rc = iutil.execWithRedirect(self.dasdfmt, arglist,
                                                stdout=out, stderr=err)
            except Exception as e:
                raise DasdFormatError(e, bypath)

            if rc:
                raise DasdFormatError("dasdfmt failed: %s" % rc, bypath)

        if intf:
            pw.pop()
Пример #48
0
 def _getRandomUUID(self):
     uuid = iutil.execWithCapture("uuidgen", []).strip()
     return uuid
Пример #49
0
def nmcli_dev_list_callback():
    """Callback to get info about network devices."""

    return iutil.execWithCapture("nmcli", ["device", "show"])
Пример #50
0
def flush_mpaths():
    iutil.execWithRedirect("multipath", ["-F"])
    check_output = iutil.execWithCapture("multipath", ["-ll"]).strip()
    if check_output:
        log.error("multipath: some devices could not be flushed")