Ejemplo n.º 1
0
    def ovirt_boot_setup(self, reboot="N"):
        self.generate_paths()
        logger.info("Installing the image.")
        # copy grub.efi to safe location
        if _functions.is_efi_boot():
            if "OVIRT_ISCSI_INSTALL" in OVIRT_VARS:
                _functions.system("umount /boot")
            if os.path.isfile("/boot/efi/%s/grubx64.efi" % self.efi_path):
                shutil.copy("/boot/efi/%s/grubx64.efi" % self.efi_path, "/tmp")
            else:
                shutil.copy("/boot/efi/%s/grub.efi" % self.efi_path, "/tmp")
            _functions.mount_boot()
        if "OVIRT_ROOT_INSTALL" in OVIRT_VARS:
            if OVIRT_VARS["OVIRT_ROOT_INSTALL"] == "n":
                logger.info("Root Installation Not Required, Finished.")
                return True
        self.oldtitle = None
        grub_config_file = None
        if _functions.findfs("Boot") and _functions.is_upgrade():
            grub_config_file = "/boot/grub/grub.conf"
            if not _functions.connect_iscsi_root():
                return False
        _functions.mount_liveos()
        if os.path.ismount("/liveos"):
            if os.path.exists("/liveos/vmlinuz0") \
                              and os.path.exists("/liveos/initrd0.img"):
                grub_config_file = self.grub_config_file
        elif not _functions.is_firstboot():
            # find existing iscsi install
            if _functions.findfs("Boot"):
                grub_config_file = "/boot/grub/grub.conf"
            elif os.path.ismount("/dev/.initramfs/live"):
                if not _functions.grub2_available():
                    grub_config_file = "/dev/.initramfs/live/grub/grub.conf"
                else:
                    grub_config_file = "/dev/.initramfs/live/grub2/grub.cfg"
            elif os.path.ismount("/run/initramfs/live"):
                grub_config_file = "/run/initramfs/live/grub/grub.conf"
            if _functions.is_upgrade() and not _functions.is_iscsi_install():
                _functions.mount_liveos()
                grub_config_file = "/liveos/grub/grub.conf"
        if _functions.is_iscsi_install() or _functions.findfs("Boot") \
            and not _functions.is_efi_boot():
            grub_config_file = "/boot/grub/grub.conf"
        if _functions.is_efi_boot():
            logger.debug(str(os.listdir("/liveos")))
            _functions.system("umount /liveos")
            _functions.mount_efi(target="/liveos")
            if self.efi_name == "fedora":
                grub_config_file = "/liveos/EFI/fedora/grub.cfg"
            else:
                grub_config_file = "/liveos/%s/grub.conf" % self.efi_path
        grub_config_file_exists = grub_config_file is not None \
            and os.path.exists(grub_config_file)
        logger.debug("Grub config file is: %s" % grub_config_file)
        logger.debug("Grub config file exists: %s" % grub_config_file_exists)
        if not grub_config_file is None and os.path.exists(grub_config_file):
            f = open(grub_config_file)
            oldgrub = f.read()
            f.close()
            if _functions.grub2_available():
                m = re.search("^menuentry (.*)$", oldgrub, re.MULTILINE)
            else:
                m = re.search("^title (.*)$", oldgrub, re.MULTILINE)
            if m is not None:
                self.oldtitle = m.group(1)
                # strip off extra title characters
                if _functions.grub2_available():
                    self.oldtitle = self.oldtitle.replace('"', '').strip(" {")
        _functions.system("umount /liveos/efi")
        _functions.system("umount /liveos")
        if _functions.is_iscsi_install() or _functions.findfs("Boot"):
            self.boot_candidate = None
            boot_candidate_names = ["BootBackup", "BootUpdate", "BootNew"]
            for trial in range(1, 3):
                time.sleep(1)
                for candidate_name in boot_candidate_names:
                    logger.debug(os.listdir("/dev/disk/by-label"))
                    if _functions.findfs(candidate_name):
                        self.boot_candidate = candidate_name
                        break
                logger.debug("Trial %s to find candidate (%s)" % \
                             (trial, candidate_name))
                if self.boot_candidate:
                    logger.debug("Found candidate: %s" % self.boot_candidate)
                    break

            if not self.boot_candidate:
                logger.error("Unable to find boot partition")
                label_debug = ''
                for label in os.listdir("/dev/disk/by-label"):
                    label_debug += "%s\n" % label
                label_debug += _functions.subprocess_closefds("blkid", \
                                          shell=True, stdout=subprocess.PIPE,
                                          stderr=subprocess.STDOUT).stdout.read()
                logger.debug(label_debug)
                return False
            else:
                boot_candidate_dev = _functions.findfs(self.boot_candidate)
            # prepare Root partition update
            if self.boot_candidate != "BootNew":
                e2label_cmd = "e2label \"%s\" BootNew" % boot_candidate_dev
                logger.debug(e2label_cmd)
                if not _functions.system(e2label_cmd):
                    logger.error("Failed to label new Boot partition")
                    return False
            _functions.system("umount /boot")
            _functions.system("mount %s /boot &>/dev/null" \
                              % boot_candidate_dev)

        candidate = None
        candidate_dev = None
        candidate_names = ["RootBackup", "RootUpdate", "RootNew"]
        for trial in range(1, 3):
            time.sleep(1)
            for candidate_name in candidate_names:
                candidate_dev = _functions.findfs(candidate_name)
                logger.debug("Finding %s: '%s'" %
                             (candidate_name, candidate_dev))
                if candidate_dev:
                    candidate = candidate_name
                    logger.debug("Found: %s" % candidate)
                    break
            logger.debug("Trial %s to find candidate (%s)" %
                         (trial, candidate_name))
            if candidate:
                logger.debug("Found candidate: '%s'" % candidate)
                break

        if not candidate:
            logger.error("Unable to find root partition")
            label_debug = ''
            for label in os.listdir("/dev/disk/by-label"):
                label_debug += "%s\n" % label
            label_debug += _functions.subprocess_closefds(
                "blkid",
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT).stdout.read()
            logger.debug(label_debug)
            return False

        try:
            self.disk = candidate_dev
            logger.info("Candidate device: %s" % candidate_dev)
            logger.info("Candidate disk: %s" % self.disk)
            # grub2 starts at part 1
            self.partN = int(self.disk[-1:])
            if not _functions.grub2_available():
                self.partN = self.partN - 1
        except:
            logger.debug("Failed to get partition", exc_info=True)
            return False

        if self.disk is None or self.partN < 0:
            logger.error("Failed to determine Root partition number")
            return False
        # prepare Root partition update
        if candidate != "RootNew":
            e2label_cmd = "e2label \"%s\" RootNew" % candidate_dev
            logger.debug(e2label_cmd)
            if not _functions.system(e2label_cmd):
                logger.error("Failed to label new Root partition")
                return False
        mount_cmd = "mount \"%s\" /liveos" % candidate_dev
        if not _functions.system(mount_cmd):
            logger.error("Failed to mount %s on /liveos" % candidate_dev)
            _functions.system("lsof")
            _functions.system("dmsetup info -c")
            _functions.system("cat /proc/mounts")
            _functions.system("multipath -ll")
            _functions.system("lsblk")
            _functions.system("ls -l /dev/mapper")
        _functions.system("rm -rf /liveos/LiveOS")
        _functions.system("mkdir -p /liveos/LiveOS")
        _functions.mount_live()

        if os.path.isdir(self.grub_dir):
            shutil.rmtree(self.grub_dir)
        if not os.path.exists(self.grub_dir):
            os.makedirs(self.grub_dir)
            if _functions.is_efi_boot():
                logger.info("efi detected, installing efi configuration")
                _functions.system("mkdir /liveos/efi")
                _functions.mount_efi()
                _functions.system("mkdir -p /liveos/efi/%s" % self.efi_path)
                if _functions.is_iscsi_install() or _functions.is_efi_boot():
                    if os.path.isfile("/tmp/grubx64.efi"):
                        shutil.copy(
                            "/tmp/grubx64.efi",
                            "/liveos/efi/%s/grubx64.efi" % self.efi_path)
                    else:
                        shutil.copy("/tmp/grub.efi",
                                    "/liveos/efi/%s/grub.efi" % self.efi_path)
                elif os.path.isfile("/boot/efi/%s/grubx64.efi" %
                                    self.efi_path):
                    shutil.copy("/boot/efi/%s/grubx64.efi" % self.efi_path,
                                "/liveos/efi/%s/grubx64.efi" % self.efi_path)
                else:
                    shutil.copy("/boot/efi/%s/grub.efi" % self.efi_path,
                                "/liveos/efi/%s/grub.efi" % self.efi_path)
                if _functions.is_iscsi_install() or _functions.findfs(
                        "BootNew"):
                    self.disk = _functions.findfs("BootNew")
                if not "/dev/mapper/" in self.disk:
                    efi_disk = self.disk[:-1]
                else:
                    efi_disk = re.sub(r'p?[1,2,3]$', "", self.disk)
                # generate grub legacy config for efi partition
                #remove existing efi entries
                _functions.remove_efi_entry(_functions.PRODUCT_SHORT)
                if self.efi_name == "fedora":
                    _functions.add_efi_entry(
                        _functions.PRODUCT_SHORT,
                        ("\\EFI\\%s\\grubx64.efi" % self.efi_name), efi_disk)
                else:
                    if os.path.isfile("/liveos/efi/%s/grubx64.efi" %
                                      self.efi_path):
                        _functions.add_efi_entry(
                            _functions.PRODUCT_SHORT,
                            ("\\EFI\\%s\\grubx64.efi" % self.efi_name),
                            efi_disk)
                    else:
                        _functions.add_efi_entry(
                            _functions.PRODUCT_SHORT,
                            ("\\EFI\\%s\\grub.efi" % self.efi_name), efi_disk)
        self.kernel_image_copy()

        # reorder tty0 to allow both serial and phys console after installation
        if _functions.is_iscsi_install() or _functions.findfs("BootNew"):
            self.root_param = "root=live:LABEL=Root"
            if "OVIRT_NETWORK_LAYOUT" in OVIRT_VARS and \
                OVIRT_VARS["OVIRT_NETWORK_LAYOUT"] == "bridged":
                network_conf = "ip=br%s:dhcp bridge=br%s:%s" % \
                                (OVIRT_VARS["OVIRT_BOOTIF"],
                                 OVIRT_VARS["OVIRT_BOOTIF"],
                                 OVIRT_VARS["OVIRT_BOOTIF"])
            else:
                network_conf = "ip=%s:dhcp" % OVIRT_VARS["OVIRT_BOOTIF"]
            self.bootparams = "netroot=iscsi:%s::%s::%s %s " % (
                OVIRT_VARS["OVIRT_ISCSI_TARGET_HOST"],
                OVIRT_VARS["OVIRT_ISCSI_TARGET_PORT"],
                OVIRT_VARS["OVIRT_ISCSI_TARGET_NAME"], network_conf)
            if "OVIRT_ISCSI_NAME" in OVIRT_VARS:
                self.bootparams+= "iscsi_initiator=%s " % \
                    OVIRT_VARS["OVIRT_ISCSI_NAME"]
        else:
            self.root_param = "root=live:LABEL=Root"
            self.bootparams = "ro rootfstype=auto rootflags=ro "
        self.bootparams += OVIRT_VARS["OVIRT_BOOTPARAMS"].replace(
            "console=tty0", "").replace("rd_NO_MULTIPATH", "")

        if " " in self.disk:
            # workaround for grub setup failing with spaces in dev.name:
            # use first active sd* device
            self.disk = re.sub("p[1,2,3]$", "", self.disk)
            grub_disk_cmd = ("multipath -l " + "\"" + self.disk + "\" " +
                             "| egrep -o '[0-9]+:.*' " +
                             "| awk '/ active / {print $2}' " + "| head -n1")
            logger.debug(grub_disk_cmd)
            grub_disk = _functions.subprocess_closefds(
                grub_disk_cmd,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT)
            grub_disk_output, grub_disk_err = grub_disk.communicate()
            self.disk = grub_disk_output.strip()
            if "cciss" in self.disk:
                self.disk = self.disk.replace("!", "/")
            # flush to sync DM and blockdev, workaround from rhbz#623846#c14
            sysfs = open("/proc/sys/vm/drop_caches", "w")
            sysfs.write("3")
            sysfs.close()
        if not self.disk.startswith("/dev/"):
            self.disk = "/dev/" + self.disk
        try:
            if stat.S_ISBLK(os.stat(self.disk).st_mode):
                try:
                    if stat.S_ISBLK(os.stat(self.disk[:-1]).st_mode):
                        # e.g. /dev/sda2
                        self.disk = self.disk[:-1]
                except OSError:
                    pass
                try:
                    if stat.S_ISBLK(os.stat(self.disk[:-2]).st_mode):
                        # e.g. /dev/mapper/WWIDp2
                        self.disk = self.disk[:-2]
                except OSError:
                    pass
        except OSError:
            logger.error("Unable to determine disk for grub installation " +
                         traceback.format_exc())
            return False

        self.grub_dict = {
            "product": _functions.PRODUCT_SHORT,
            "version": _functions.PRODUCT_VERSION,
            "release": _functions.PRODUCT_RELEASE,
            "partN": self.partN,
            "root_param": self.root_param,
            "bootparams": self.bootparams,
            "disk": self.disk,
            "grub_dir": self.grub_dir,
            "grub_prefix": self.grub_prefix,
            "efi_hd": self.efi_hd,
            "linux": "linux",
            "initrd": "initrd",
        }
        if not _functions.is_firstboot():
            if os.path.ismount("/live"):
                with open("%s/version" % self.live_path) as version:
                    for line in version.readlines():
                        if "VERSION" in line:
                            key, value = line.split("=")
                            self.grub_dict["version"] = value.strip()
                        if "RELEASE" in line:
                            key, value = line.split("=")
                            self.grub_dict["release"] = value.strip()

        if _functions.grub2_available():
            if not self.grub2_install():
                logger.error("Grub2 Installation Failed ")
                return False
            else:
                logger.info("Grub2 EFI Installation Completed ")
        else:
            if not self.grub_install():
                logger.error("Grub Installation Failed ")
                return False
            else:
                logger.info("Grub Installation Completed")

        if _functions.is_iscsi_install() or _functions.findfs("BootNew"):
            # copy default for when Root/HostVG is inaccessible(iscsi upgrade)
            shutil.copy(_functions.OVIRT_DEFAULTS, "/boot")
            # mark new Boot ready to go, reboot() in ovirt-function switches it
            # to active
            e2label_cmd = "e2label \"%s\" BootUpdate" % boot_candidate_dev

            if not _functions.system(e2label_cmd):
                logger.error("Unable to relabel " + boot_candidate_dev +
                             " to RootUpdate ")
                return False
        else:
            _functions.system("umount /liveos/efi")
        _functions.system("umount /liveos")
        # mark new Root ready to go, reboot() in ovirt-function switches it
        # to active
        e2label_cmd = "e2label \"%s\" RootUpdate" % candidate_dev
        if not _functions.system(e2label_cmd):
            logger.error("Unable to relabel " + candidate_dev +
                         " to RootUpdate ")
            return False
        _functions.system("udevadm settle --timeout=10")

        #
        # Rebuild the initramfs
        # A few hacks are needed to prep the chroot
        # The general issue is that we need to run dracut in the context fo the new iso
        # and that we need to put the initrd in the right place of the new iso.
        # These two things make the logic a bit more complicated.
        #
        mnts = []
        try:
            if not _functions.system("blkid -L RootUpdate"):
                raise RuntimeError("RootUpdate not found")

            # Let's mount the update fs, and use that kernel version and modules
            # We need this work to help dracut
            isomnt = tempfile.mkdtemp("RootUpdate")
            squashmnt = tempfile.mkdtemp("RootUpdate-LiveOS")
            updfs = tempfile.mkdtemp("RootUpdate-LiveOS-Img")
            mnts += [isomnt, squashmnt, updfs]

            # Unpack the iso
            def _call(args):
                logger.debug("Calling: %s" % args)
                try:
                    out = subprocess.check_output(args)
                    logger.debug("Out: %s" % out)
                except Exception as e:
                    logger.debug("Failed with: %s %s" % (e, e.output))
                    raise

            _call(["mount", "LABEL=RootUpdate", isomnt])
            _call(["mount", "%s/LiveOS/squashfs.img" % isomnt, squashmnt])
            _call(["mount", "%s/LiveOS/ext3fs.img" % squashmnt, updfs])

            # Now mount the update modules into place, and find the
            # correct kver
            def rbind(path, updfs=updfs):
                dst = updfs + "/" + path
                logger.debug("Binding %r to %r" % (path, dst))
                _call(["mount", "--make-rshared", "--rbind", "/" + path, dst])
                return dst

            for path in ["etc", "dev", "proc", "sys", "tmp", "run", "var/tmp"]:
                mnts += [rbind(path)]

            upd_kver = str(
                _functions.passthrough("ls -1 %s/lib/modules" %
                                       updfs)).strip()

            if len(upd_kver.splitlines()) != 1:
                # It would be very unusual to see more than one kver directory
                # in /lib/modules but might happen when using edit-node.
                # Check via check_higher_kernel() the higher version available
                upd_kver = self.check_higher_kernel(updfs)
                if upd_kver is None:
                    raise RuntimeError("Unable to find the kernel version")

            # Update initramfs to pickup multipath wwids
            # Let /boot point to the filesystem on the update candidate partition
            builder = _system.Initramfs(dracut_chroot=updfs,
                                        boot_source=isomnt)
            builder.rebuild(kver=upd_kver)

        except Exception as e:
            logger.debug("Failed to build initramfs: %s" % e, exc_info=True)
            output = getattr(e, "output", "")
            if output:
                logger.debug("Output: %s" % output)
            raise

        finally:
            # Clean up all eventual mounts
            pass
            # Disabled for now because akward things happen, we leave it to
            # systemd to unnmount on reboot
            # for mnt in reversed(mnts):
            #     d = _functions.passthrough("umount -fl %s" % mnt, logger.debug)
            #     logger.debug("Returned: %s" % d)

        _functions.disable_firstboot()
        if _functions.finish_install():
            if _functions.is_firstboot():
                _iscsi.iscsi_auto()
            logger.info("Installation of %s Completed" % \
                                                      _functions.PRODUCT_SHORT)
            if reboot is not None and reboot == "Y":
                _system.async_reboot()
            return True
        else:
            return False
Ejemplo n.º 2
0
    def ovirt_boot_setup(self, reboot="N"):
        self.generate_paths()
        logger.info("Installing the image.")
        # copy grub.efi to safe location
        if _functions.is_efi_boot():
            shutil.copy("/boot/efi/EFI/%s/grub.efi" % self.efi_dir_name,
                        "/tmp")
        if "OVIRT_ROOT_INSTALL" in OVIRT_VARS:
            if OVIRT_VARS["OVIRT_ROOT_INSTALL"] == "n":
                logger.info("Root Installation Not Required, Finished.")
                return True
        self.oldtitle = None
        grub_config_file = None
        if _functions.findfs("Boot") and _functions.is_upgrade():
            grub_config_file = "/boot/grub/grub.conf"
            if not _functions.connect_iscsi_root():
                return False
        _functions.mount_liveos()
        if os.path.ismount("/liveos"):
            if os.path.exists("/liveos/vmlinuz0") \
                              and os.path.exists("/liveos/initrd0.img"):
                grub_config_file = self.grub_config_file
        elif not _functions.is_firstboot():
            # find existing iscsi install
            if _functions.findfs("Boot"):
                grub_config_file = "/boot/grub/grub.conf"
            elif os.path.ismount("/dev/.initramfs/live"):
                if not _functions.grub2_available():
                    grub_config_file = "/dev/.initramfs/live/grub/grub.conf"
                else:
                    grub_config_file = "/dev/.initramfs/live/grub2/grub.cfg"
            elif os.path.ismount("/run/initramfs/live"):
                grub_config_file = "/run/initramfs/live/grub/grub.conf"
            if _functions.is_upgrade() and not _functions.is_iscsi_install():
                _functions.mount_liveos()
                grub_config_file = "/liveos/grub/grub.conf"
        if _functions.is_efi_boot():
            logger.debug(str(os.listdir("/liveos")))
            _functions.system("umount /liveos")
            _functions.mount_efi(target="/liveos")
            if self.efi_dir_name == "fedora":
                grub_config_file = "/liveos/EFI/fedora/grub.cfg"
            else:
                grub_config_file = "/liveos/EFI/redhat/grub.conf"
        if _functions.is_iscsi_install() or _functions.findfs("Boot"):
            grub_config_file = "/boot/grub/grub.conf"
        grub_config_file_exists = grub_config_file is not None \
            and os.path.exists(grub_config_file)
        logger.debug("Grub config file is: %s" % grub_config_file)
        logger.debug("Grub config file exists: %s" % grub_config_file_exists)
        if not grub_config_file is None and os.path.exists(grub_config_file):
            f = open(grub_config_file)
            oldgrub = f.read()
            f.close()
            if _functions.grub2_available():
                m = re.search("^menuentry (.*)$", oldgrub, re.MULTILINE)
            else:
                m = re.search("^title (.*)$", oldgrub, re.MULTILINE)
            if m is not None:
                self.oldtitle = m.group(1)
                # strip off extra title characters
                if _functions.grub2_available():
                    self.oldtitle = self.oldtitle.replace('"', '').strip(" {")
        _functions.system("umount /liveos/efi")
        _functions.system("umount /liveos")
        if _functions.is_iscsi_install() or _functions.findfs("Boot"):
            self.boot_candidate = None
            boot_candidate_names = ["BootBackup", "BootUpdate", "BootNew"]
            for trial in range(1, 3):
                time.sleep(1)
                _functions.system("partprobe")
                for candidate_name in boot_candidate_names:
                    logger.debug(os.listdir("/dev/disk/by-label"))
                    if _functions.findfs(candidate_name):
                        self.boot_candidate = candidate_name
                        break
                logger.debug("Trial %s to find candidate (%s)" % \
                             (trial, candidate_name))
                if self.boot_candidate:
                    logger.debug("Found candidate: %s" % self.boot_candidate)
                    break

            if not self.boot_candidate:
                logger.error("Unable to find boot partition")
                label_debug = ''
                for label in os.listdir("/dev/disk/by-label"):
                    label_debug += "%s\n" % label
                label_debug += _functions.subprocess_closefds("blkid", \
                                          shell=True, stdout=subprocess.PIPE,
                                          stderr=subprocess.STDOUT).stdout.read()
                logger.debug(label_debug)
                return False
            else:
                boot_candidate_dev = _functions.findfs(self.boot_candidate)
            # prepare Root partition update
            if self.boot_candidate != "BootNew":
                e2label_cmd = "e2label \"%s\" BootNew" % boot_candidate_dev
                logger.debug(e2label_cmd)
                if not _functions.system(e2label_cmd):
                    logger.error("Failed to label new Boot partition")
                    return False
            _functions.system("umount /boot")
            _functions.system("mount %s /boot &>/dev/null" \
                              % boot_candidate_dev)

        candidate = None
        candidate_names = ["RootBackup", "RootUpdate", "RootNew"]
        for trial in range(1, 3):
            time.sleep(1)
            _functions.system("partprobe")
            for candidate_name in candidate_names:
                if _functions.findfs(candidate_name):
                    candidate = candidate_name
                    break
            logger.debug("Trial %s to find candidate (%s)" %
                         (trial, candidate_name))
            if candidate:
                logger.debug("Found candidate: %s" % candidate)
                break

        if not candidate:
            logger.error("Unable to find root partition")
            label_debug = ''
            for label in os.listdir("/dev/disk/by-label"):
                label_debug += "%s\n" % label
            label_debug += _functions.subprocess_closefds(
                "blkid",
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT).stdout.read()
            logger.debug(label_debug)
            return False

        try:
            candidate_dev = self.disk = _functions.findfs(candidate)
            logger.info(candidate_dev)
            logger.info(self.disk)
            # grub2 starts at part 1
            self.partN = int(self.disk[-1:])
            if not _functions.grub2_available():
                self.partN = self.partN - 1
        except:
            logger.debug(traceback.format_exc())
            return False

        if self.disk is None or self.partN < 0:
            logger.error("Failed to determine Root partition number")
            return False
        # prepare Root partition update
        if candidate != "RootNew":
            e2label_cmd = "e2label \"%s\" RootNew" % candidate_dev
            logger.debug(e2label_cmd)
            if not _functions.system(e2label_cmd):
                logger.error("Failed to label new Root partition")
                return False
        mount_cmd = "mount \"%s\" /liveos" % candidate_dev
        _functions.system(mount_cmd)
        _functions.system("rm -rf /liveos/LiveOS")
        _functions.system("mkdir -p /liveos/LiveOS")
        _functions.mount_live()

        if os.path.isdir(self.grub_dir):
            shutil.rmtree(self.grub_dir)
        if not os.path.exists(self.grub_dir):
            os.makedirs(self.grub_dir)
            if _functions.is_efi_boot():
                logger.info("efi detected, installing efi configuration")
                _functions.system("mkdir /liveos/efi")
                _functions.mount_efi()
                _functions.system("mkdir -p /liveos/efi/EFI/redhat")
                if _functions.is_iscsi_install() or _functions.is_efi_boot():
                    shutil.copy("/tmp/grub.efi",
                                "/liveos/efi/EFI/redhat/grub.efi")
                else:
                    shutil.copy("/boot/efi/EFI/redhat/grub.efi",
                                "/liveos/efi/EFI/redhat/grub.efi")
                if _functions.is_iscsi_install() or _functions.findfs(
                        "BootNew"):
                    self.disk = _functions.findfs("BootNew")
                if not "/dev/mapper/" in self.disk:
                    efi_disk = self.disk[:-1]
                else:
                    efi_disk = re.sub("p[1,2,3]$", "", self.disk)
                # generate grub legacy config for efi partition
                #remove existing efi entries
                _functions.remove_efi_entry(_functions.PRODUCT_SHORT)
                if self.efi_dir_name == "fedora":
                    _functions.add_efi_entry(
                        _functions.PRODUCT_SHORT,
                        ("\\EFI\\%s\\grubx64.efi" % self.efi_dir_name),
                        efi_disk)
                else:
                    _functions.add_efi_entry(
                        _functions.PRODUCT_SHORT,
                        ("\\EFI\\%s\\grub.efi" % self.efi_dir_name), efi_disk)
        self.kernel_image_copy()

        # reorder tty0 to allow both serial and phys console after installation
        if _functions.is_iscsi_install() or _functions.findfs("BootNew"):
            self.root_param = "root=live:LABEL=Root"
            if "OVIRT_NETWORK_LAYOUT" in OVIRT_VARS and \
                OVIRT_VARS["OVIRT_NETWORK_LAYOUT"] == "bridged":
                network_conf = "ip=br%s:dhcp bridge=br%s:%s" % \
                                (OVIRT_VARS["OVIRT_BOOTIF"],
                                 OVIRT_VARS["OVIRT_BOOTIF"],
                                 OVIRT_VARS["OVIRT_BOOTIF"])
            else:
                network_conf = "ip=%s:dhcp" % OVIRT_VARS["OVIRT_BOOTIF"]
            self.bootparams = "netroot=iscsi:%s::%s::%s %s " % (
                OVIRT_VARS["OVIRT_ISCSI_TARGET_HOST"],
                OVIRT_VARS["OVIRT_ISCSI_TARGET_PORT"],
                OVIRT_VARS["OVIRT_ISCSI_TARGET_NAME"], network_conf)
            if "OVIRT_ISCSI_NAME" in OVIRT_VARS:
                self.bootparams+= "iscsi_initiator=%s " % \
                    OVIRT_VARS["OVIRT_ISCSI_NAME"]
        else:
            self.root_param = "root=live:LABEL=Root"
            self.bootparams = "ro rootfstype=auto rootflags=ro "
        self.bootparams += OVIRT_VARS["OVIRT_BOOTPARAMS"].replace(
            "console=tty0", "").replace("rd_NO_MULTIPATH", "")
        if " " in self.disk or os.path.exists("/dev/cciss"):
            # workaround for grub setup failing with spaces in dev.name:
            # use first active sd* device
            self.disk = re.sub("p[1,2,3]$", "", self.disk)
            grub_disk_cmd = ("multipath -l " + "\"" + self.disk + "\" " +
                             "| egrep -o '[0-9]+:.*' " +
                             "| awk '/ active / {print $2}' " + "| head -n1")
            logger.debug(grub_disk_cmd)
            grub_disk = _functions.subprocess_closefds(
                grub_disk_cmd,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT)
            grub_disk_output, grub_disk_err = grub_disk.communicate()
            self.disk = grub_disk_output.strip()
            if "cciss" in self.disk:
                self.disk = self.disk.replace("!", "/")
            # flush to sync DM and blockdev, workaround from rhbz#623846#c14
            sysfs = open("/proc/sys/vm/drop_caches", "w")
            sysfs.write("3")
            sysfs.close()
            partprobe_cmd = "partprobe \"/dev/%s\"" % self.disk
            logger.debug(partprobe_cmd)
            _functions.system(partprobe_cmd)

        if not self.disk.startswith("/dev/"):
            self.disk = "/dev/" + self.disk
        try:
            if stat.S_ISBLK(os.stat(self.disk).st_mode):
                try:
                    if stat.S_ISBLK(os.stat(self.disk[:-1]).st_mode):
                        # e.g. /dev/sda2
                        self.disk = self.disk[:-1]
                except OSError:
                    pass
                try:
                    if stat.S_ISBLK(os.stat(self.disk[:-2]).st_mode):
                        # e.g. /dev/mapper/WWIDp2
                        self.disk = self.disk[:-2]
                except OSError:
                    pass
        except OSError:
            logger.error("Unable to determine disk for grub installation " +
                         traceback.format_exc())
            return False

        self.grub_dict = {
            "product": _functions.PRODUCT_SHORT,
            "version": _functions.PRODUCT_VERSION,
            "release": _functions.PRODUCT_RELEASE,
            "partN": self.partN,
            "root_param": self.root_param,
            "bootparams": self.bootparams,
            "disk": self.disk,
            "grub_dir": self.grub_dir,
            "grub_prefix": self.grub_prefix,
            "efi_hd": self.efi_hd
        }
        if not _functions.is_firstboot():
            if os.path.ismount("/live"):
                with open("%s/version" % self.live_path) as version:
                    for line in version.readlines():
                        if "VERSION" in line:
                            key, value = line.split("=")
                            self.grub_dict["version"] = value.strip()
                        if "RELEASE" in line:
                            key, value = line.split("=")
                            self.grub_dict["release"] = value.strip()

        if _functions.grub2_available():
            if not self.grub2_install():
                logger.error("Grub2 Installation Failed ")
                return False
            else:
                logger.info("Grub2 EFI Installation Completed ")
        else:
            if not self.grub_install():
                logger.error("Grub Installation Failed ")
                return False
            else:
                logger.info("Grub Installation Completed")

        if _functions.is_iscsi_install() or _functions.findfs("BootNew"):
            # copy default for when Root/HostVG is inaccessible(iscsi upgrade)
            shutil.copy(_functions.OVIRT_DEFAULTS, "/boot")
            # mark new Boot ready to go, reboot() in ovirt-function switches it
            # to active
            e2label_cmd = "e2label \"%s\" BootUpdate" % boot_candidate_dev

            if not _functions.system(e2label_cmd):
                logger.error("Unable to relabel " + boot_candidate_dev +
                             " to RootUpdate ")
                return False
        else:
            _functions.system("umount /liveos/efi")
        _functions.system("umount /liveos")
        # mark new Root ready to go, reboot() in ovirt-function switches it
        # to active
        e2label_cmd = "e2label \"%s\" RootUpdate" % candidate_dev
        if not _functions.system(e2label_cmd):
            logger.error("Unable to relabel " + candidate_dev +
                         " to RootUpdate ")
            return False
        _functions.disable_firstboot()
        if _functions.finish_install():
            if _functions.is_firstboot():
                _iscsi.iscsi_auto()
            logger.info("Installation of %s Completed" % \
                                                      _functions.PRODUCT_SHORT)
            if reboot is not None and reboot == "Y":
                _system.async_reboot()
            return True
        else:
            return False
Ejemplo n.º 3
0
    def ovirt_boot_setup(self, reboot="N"):
        self.generate_paths()
        logger.info("Installing the image.")
        # copy grub.efi to safe location
        if _functions.is_efi_boot():
            shutil.copy("/boot/efi/EFI/%s/grub.efi" % self.efi_dir_name,
                        "/tmp")
        if "OVIRT_ROOT_INSTALL" in OVIRT_VARS:
            if OVIRT_VARS["OVIRT_ROOT_INSTALL"] == "n":
                logger.info("Root Installation Not Required, Finished.")
                return True
        self.oldtitle=None
        grub_config_file = None
        if _functions.findfs("Boot") and _functions.is_upgrade():
            grub_config_file = "/boot/grub/grub.conf"
            if not _functions.connect_iscsi_root():
                return False
        _functions.mount_liveos()
        if os.path.ismount("/liveos"):
            if os.path.exists("/liveos/vmlinuz0") \
                              and os.path.exists("/liveos/initrd0.img"):
                grub_config_file = self.grub_config_file
        elif not _functions.is_firstboot():
            # find existing iscsi install
            if _functions.findfs("Boot"):
                grub_config_file = "/boot/grub/grub.conf"
            elif os.path.ismount("/dev/.initramfs/live"):
                if not _functions.grub2_available():
                    grub_config_file = "/dev/.initramfs/live/grub/grub.conf"
                else:
                    grub_config_file = "/dev/.initramfs/live/grub2/grub.cfg"
            elif os.path.ismount("/run/initramfs/live"):
                grub_config_file = "/run/initramfs/live/grub/grub.conf"
            if _functions.is_upgrade() and not _functions.is_iscsi_install():
                _functions.mount_liveos()
                grub_config_file = "/liveos/grub/grub.conf"
        if _functions.is_efi_boot():
            logger.debug(str(os.listdir("/liveos")))
            _functions.system("umount /liveos")
            _functions.mount_efi(target="/liveos")
            if self.efi_dir_name == "fedora":
                grub_config_file = "/liveos/EFI/fedora/grub.cfg"
            else:
                grub_config_file = "/liveos/EFI/redhat/grub.conf"
        if _functions.is_iscsi_install() or _functions.findfs("Boot"):
            grub_config_file = "/boot/grub/grub.conf"
        grub_config_file_exists = grub_config_file is not None \
            and os.path.exists(grub_config_file)
        logger.debug("Grub config file is: %s" % grub_config_file)
        logger.debug("Grub config file exists: %s" % grub_config_file_exists)
        if not grub_config_file is None and os.path.exists(grub_config_file):
            f=open(grub_config_file)
            oldgrub=f.read()
            f.close()
            if _functions.grub2_available():
                m=re.search("^menuentry (.*)$", oldgrub, re.MULTILINE)
            else:
                m=re.search("^title (.*)$", oldgrub, re.MULTILINE)
            if m is not None:
                self.oldtitle=m.group(1)
                # strip off extra title characters
                if _functions.grub2_available():
                    self.oldtitle = self.oldtitle.replace('"','').strip(" {")
        _functions.system("umount /liveos/efi")
        _functions.system("umount /liveos")
        if _functions.is_iscsi_install() or _functions.findfs("Boot"):
            self.boot_candidate = None
            boot_candidate_names = ["BootBackup", "BootUpdate", "BootNew"]
            for trial in range(1, 3):
                time.sleep(1)
                _functions.system("partprobe")
                for candidate_name in boot_candidate_names:
                    logger.debug(os.listdir("/dev/disk/by-label"))
                    if _functions.findfs(candidate_name):
                        self.boot_candidate = candidate_name
                        break
                logger.debug("Trial %s to find candidate (%s)" % \
                             (trial, candidate_name))
                if self.boot_candidate:
                    logger.debug("Found candidate: %s" % self.boot_candidate)
                    break

            if not self.boot_candidate:
                logger.error("Unable to find boot partition")
                label_debug = ''
                for label in os.listdir("/dev/disk/by-label"):
                    label_debug += "%s\n" % label
                label_debug += _functions.subprocess_closefds("blkid", \
                                          shell=True, stdout=subprocess.PIPE,
                                          stderr=subprocess.STDOUT).stdout.read()
                logger.debug(label_debug)
                return False
            else:
                boot_candidate_dev = _functions.findfs(self.boot_candidate)
            # prepare Root partition update
            if self.boot_candidate != "BootNew":
                e2label_cmd = "e2label \"%s\" BootNew" % boot_candidate_dev
                logger.debug(e2label_cmd)
                if not _functions.system(e2label_cmd):
                    logger.error("Failed to label new Boot partition")
                    return False
            _functions.system("umount /boot")
            _functions.system("mount %s /boot &>/dev/null" \
                              % boot_candidate_dev)

        candidate = None
        candidate_names = ["RootBackup", "RootUpdate", "RootNew"]
        for trial in range(1, 3):
            time.sleep(1)
            _functions.system("partprobe")
            for candidate_name in candidate_names:
                if _functions.findfs(candidate_name):
                    candidate = candidate_name
                    break
            logger.debug("Trial %s to find candidate (%s)" % (trial,
                                                              candidate_name))
            if candidate:
                logger.debug("Found candidate: %s" % candidate)
                break

        if not candidate:
            logger.error("Unable to find root partition")
            label_debug = ''
            for label in os.listdir("/dev/disk/by-label"):
                label_debug += "%s\n" % label
            label_debug += _functions.subprocess_closefds("blkid", shell=True,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.STDOUT).stdout.read()
            logger.debug(label_debug)
            return False

        try:
            candidate_dev = self.disk = _functions.findfs(candidate)
            logger.info(candidate_dev)
            logger.info(self.disk)
            # grub2 starts at part 1
            self.partN = int(self.disk[-1:])
            if not _functions.grub2_available():
                self.partN = self.partN - 1
        except:
            logger.debug(traceback.format_exc())
            return False

        if self.disk is None or self.partN < 0:
            logger.error("Failed to determine Root partition number")
            return False
        # prepare Root partition update
        if candidate != "RootNew":
            e2label_cmd = "e2label \"%s\" RootNew" % candidate_dev
            logger.debug(e2label_cmd)
            if not _functions.system(e2label_cmd):
                logger.error("Failed to label new Root partition")
                return False
        mount_cmd = "mount \"%s\" /liveos" % candidate_dev
        _functions.system(mount_cmd)
        _functions.system("rm -rf /liveos/LiveOS")
        _functions.system("mkdir -p /liveos/LiveOS")
        _functions.mount_live()

        if os.path.isdir(self.grub_dir):
            shutil.rmtree(self.grub_dir)
        if not os.path.exists(self.grub_dir):
            os.makedirs(self.grub_dir)
            if _functions.is_efi_boot():
                logger.info("efi detected, installing efi configuration")
                _functions.system("mkdir /liveos/efi")
                _functions.mount_efi()
                _functions.system("mkdir -p /liveos/efi/EFI/redhat")
                if _functions.is_iscsi_install() or _functions.is_efi_boot():
                    shutil.copy("/tmp/grub.efi",
                                "/liveos/efi/EFI/redhat/grub.efi")
                else:
                    shutil.copy("/boot/efi/EFI/redhat/grub.efi",
                          "/liveos/efi/EFI/redhat/grub.efi")
                if _functions.is_iscsi_install() or _functions.findfs("BootNew"):
                    self.disk = _functions.findfs("BootNew")
                if not "/dev/mapper/" in self.disk:
                    efi_disk = self.disk[:-1]
                else:
                    efi_disk = re.sub("p[1,2,3]$", "", self.disk)
                # generate grub legacy config for efi partition
                #remove existing efi entries
                _functions.remove_efi_entry(_functions.PRODUCT_SHORT)
                if self.efi_dir_name == "fedora":
                    _functions.add_efi_entry(_functions.PRODUCT_SHORT,
                                             ("\\EFI\\%s\\grubx64.efi" %
                                              self.efi_dir_name),
                                             efi_disk)
                else:
                    _functions.add_efi_entry(_functions.PRODUCT_SHORT,
                                             ("\\EFI\\%s\\grub.efi" %
                                              self.efi_dir_name),
                                             efi_disk)
        self.kernel_image_copy()

        # reorder tty0 to allow both serial and phys console after installation
        if _functions.is_iscsi_install() or _functions.findfs("BootNew"):
            self.root_param = "root=live:LABEL=Root"
            if "OVIRT_NETWORK_LAYOUT" in OVIRT_VARS and \
                OVIRT_VARS["OVIRT_NETWORK_LAYOUT"] == "bridged":
                network_conf = "ip=br%s:dhcp bridge=br%s:%s" % \
                                (OVIRT_VARS["OVIRT_BOOTIF"],
                                 OVIRT_VARS["OVIRT_BOOTIF"],
                                 OVIRT_VARS["OVIRT_BOOTIF"])
            else:
                network_conf = "ip=%s:dhcp" % OVIRT_VARS["OVIRT_BOOTIF"]
            self.bootparams = "netroot=iscsi:%s::%s::%s %s " % (
                OVIRT_VARS["OVIRT_ISCSI_TARGET_HOST"],
                OVIRT_VARS["OVIRT_ISCSI_TARGET_PORT"],
                OVIRT_VARS["OVIRT_ISCSI_TARGET_NAME"],
                network_conf)
            if "OVIRT_ISCSI_NAME" in OVIRT_VARS:
                self.bootparams+= "iscsi_initiator=%s " % \
                    OVIRT_VARS["OVIRT_ISCSI_NAME"]
        else:
            self.root_param = "root=live:LABEL=Root"
            self.bootparams = "ro rootfstype=auto rootflags=ro "
        self.bootparams += OVIRT_VARS["OVIRT_BOOTPARAMS"].replace(
                                                            "console=tty0", ""
                                                            ).replace(
                                                            "rd_NO_MULTIPATH",
                                                            "")
        if " " in self.disk or os.path.exists("/dev/cciss"):
            # workaround for grub setup failing with spaces in dev.name:
            # use first active sd* device
            self.disk = re.sub("p[1,2,3]$", "", self.disk)
            grub_disk_cmd = ("multipath -l " +
                             "\"" + self.disk + "\" " +
                             "| egrep -o '[0-9]+:.*' " +
                             "| awk '/ active / {print $2}' " +
                             "| head -n1")
            logger.debug(grub_disk_cmd)
            grub_disk = _functions.subprocess_closefds(grub_disk_cmd,
                                            shell=True,
                                            stdout=subprocess.PIPE,
                                            stderr=subprocess.STDOUT)
            grub_disk_output, grub_disk_err = grub_disk.communicate()
            self.disk = grub_disk_output.strip()
            if "cciss" in self.disk:
                self.disk = self.disk.replace("!", "/")
            # flush to sync DM and blockdev, workaround from rhbz#623846#c14
            sysfs = open("/proc/sys/vm/drop_caches", "w")
            sysfs.write("3")
            sysfs.close()
            partprobe_cmd = "partprobe \"/dev/%s\"" % self.disk
            logger.debug(partprobe_cmd)
            _functions.system(partprobe_cmd)

        if not self.disk.startswith("/dev/"):
            self.disk = "/dev/" + self.disk
        try:
            if stat.S_ISBLK(os.stat(self.disk).st_mode):
                try:
                    if stat.S_ISBLK(os.stat(self.disk[:-1]).st_mode):
                        # e.g. /dev/sda2
                        self.disk = self.disk[:-1]
                except OSError:
                    pass
                try:
                    if stat.S_ISBLK(os.stat(self.disk[:-2]).st_mode):
                        # e.g. /dev/mapper/WWIDp2
                        self.disk = self.disk[:-2]
                except OSError:
                    pass
        except OSError:
            logger.error("Unable to determine disk for grub installation " +
                         traceback.format_exc())
            return False

        self.grub_dict = {
        "product": _functions.PRODUCT_SHORT,
        "version": _functions.PRODUCT_VERSION,
        "release": _functions.PRODUCT_RELEASE,
        "partN": self.partN,
        "root_param": self.root_param,
        "bootparams": self.bootparams,
        "disk": self.disk,
        "grub_dir": self.grub_dir,
        "grub_prefix": self.grub_prefix,
        "efi_hd": self.efi_hd
    }
        if not _functions.is_firstboot():
            if os.path.ismount("/live"):
                with open("%s/version" % self.live_path) as version:
                    for line in version.readlines():
                        if "VERSION" in line:
                            key, value = line.split("=")
                            self.grub_dict["version"] = value.strip()
                        if "RELEASE" in line:
                            key, value = line.split("=")
                            self.grub_dict["release"] = value.strip()

        if _functions.grub2_available():
            if not self.grub2_install():
                logger.error("Grub2 Installation Failed ")
                return False
            else:
                 logger.info("Grub2 EFI Installation Completed ")
        else:
            if not self.grub_install():
                logger.error("Grub Installation Failed ")
                return False
            else:
                logger.info("Grub Installation Completed")

        if _functions.is_iscsi_install() or _functions.findfs("BootNew"):
            # copy default for when Root/HostVG is inaccessible(iscsi upgrade)
            shutil.copy(_functions.OVIRT_DEFAULTS, "/boot")
            # mark new Boot ready to go, reboot() in ovirt-function switches it
            # to active
            e2label_cmd = "e2label \"%s\" BootUpdate" % boot_candidate_dev

            if not _functions.system(e2label_cmd):
                logger.error("Unable to relabel " + boot_candidate_dev +
                             " to RootUpdate ")
                return False
        else:
            _functions.system("umount /liveos/efi")
        _functions.system("umount /liveos")
        # mark new Root ready to go, reboot() in ovirt-function switches it
        # to active
        e2label_cmd = "e2label \"%s\" RootUpdate" % candidate_dev
        if not _functions.system(e2label_cmd):
            logger.error("Unable to relabel " + candidate_dev +
                         " to RootUpdate ")
            return False
        _functions.disable_firstboot()
        if _functions.finish_install():
            if _functions.is_firstboot():
                _iscsi.iscsi_auto()
            logger.info("Installation of %s Completed" % \
                                                      _functions.PRODUCT_SHORT)
            if reboot is not None and reboot == "Y":
                _system.async_reboot()
            return True
        else:
            return False
Ejemplo n.º 4
0
    def ovirt_boot_setup(self, reboot="N"):
        self.generate_paths()
        logger.info("Installing the image.")
        # copy grub.efi to safe location
        if _functions.is_efi_boot():
            if "OVIRT_ISCSI_INSTALL" in OVIRT_VARS:
                _functions.system("umount /boot")
            if os.path.isfile("/boot/efi/%s/grubx64.efi" % self.efi_path):
                shutil.copy("/boot/efi/%s/grubx64.efi" % self.efi_path, "/tmp")
            else:
                shutil.copy("/boot/efi/%s/grub.efi" % self.efi_path, "/tmp")
            _functions.mount_boot()
        if "OVIRT_ROOT_INSTALL" in OVIRT_VARS:
            if OVIRT_VARS["OVIRT_ROOT_INSTALL"] == "n":
                logger.info("Root Installation Not Required, Finished.")
                return True
        self.oldtitle=None
        grub_config_file = None
        if _functions.findfs("Boot") and _functions.is_upgrade():
            grub_config_file = "/boot/grub/grub.conf"
            if not _functions.connect_iscsi_root():
                return False
        _functions.mount_liveos()
        if os.path.ismount("/liveos"):
            if os.path.exists("/liveos/vmlinuz0") \
                              and os.path.exists("/liveos/initrd0.img"):
                grub_config_file = self.grub_config_file
        elif not _functions.is_firstboot():
            # find existing iscsi install
            if _functions.findfs("Boot"):
                grub_config_file = "/boot/grub/grub.conf"
            elif os.path.ismount("/dev/.initramfs/live"):
                if not _functions.grub2_available():
                    grub_config_file = "/dev/.initramfs/live/grub/grub.conf"
                else:
                    grub_config_file = "/dev/.initramfs/live/grub2/grub.cfg"
            elif os.path.ismount("/run/initramfs/live"):
                grub_config_file = "/run/initramfs/live/grub/grub.conf"
            if _functions.is_upgrade() and not _functions.is_iscsi_install():
                _functions.mount_liveos()
                grub_config_file = "/liveos/grub/grub.conf"
        if _functions.is_iscsi_install() or _functions.findfs("Boot") \
            and not _functions.is_efi_boot():
            grub_config_file = "/boot/grub/grub.conf"
        if _functions.is_efi_boot():
            logger.debug(str(os.listdir("/liveos")))
            _functions.system("umount /liveos")
            _functions.mount_efi(target="/liveos")
            if self.efi_name == "fedora":
                grub_config_file = "/liveos/EFI/fedora/grub.cfg"
            else:
                grub_config_file = "/liveos/%s/grub.conf" % self.efi_path
        grub_config_file_exists = grub_config_file is not None \
            and os.path.exists(grub_config_file)
        logger.debug("Grub config file is: %s" % grub_config_file)
        logger.debug("Grub config file exists: %s" % grub_config_file_exists)
        if not grub_config_file is None and os.path.exists(grub_config_file):
            f=open(grub_config_file)
            oldgrub=f.read()
            f.close()
            if _functions.grub2_available():
                m=re.search("^menuentry (.*)$", oldgrub, re.MULTILINE)
            else:
                m=re.search("^title (.*)$", oldgrub, re.MULTILINE)
            if m is not None:
                self.oldtitle=m.group(1)
                # strip off extra title characters
                if _functions.grub2_available():
                    self.oldtitle = self.oldtitle.replace('"','').strip(" {")
        _functions.system("umount /liveos/efi")
        _functions.system("umount /liveos")
        if _functions.is_iscsi_install() or _functions.findfs("Boot"):
            self.boot_candidate = None
            boot_candidate_names = ["BootBackup", "BootUpdate", "BootNew"]
            for trial in range(1, 3):
                time.sleep(1)
                for candidate_name in boot_candidate_names:
                    logger.debug(os.listdir("/dev/disk/by-label"))
                    if _functions.findfs(candidate_name):
                        self.boot_candidate = candidate_name
                        break
                logger.debug("Trial %s to find candidate (%s)" % \
                             (trial, candidate_name))
                if self.boot_candidate:
                    logger.debug("Found candidate: %s" % self.boot_candidate)
                    break

            if not self.boot_candidate:
                logger.error("Unable to find boot partition")
                label_debug = ''
                for label in os.listdir("/dev/disk/by-label"):
                    label_debug += "%s\n" % label
                label_debug += _functions.subprocess_closefds("blkid", \
                                          shell=True, stdout=subprocess.PIPE,
                                          stderr=subprocess.STDOUT).stdout.read()
                logger.debug(label_debug)
                return False
            else:
                boot_candidate_dev = _functions.findfs(self.boot_candidate)
            # prepare Root partition update
            if self.boot_candidate != "BootNew":
                e2label_cmd = "e2label \"%s\" BootNew" % boot_candidate_dev
                logger.debug(e2label_cmd)
                if not _functions.system(e2label_cmd):
                    logger.error("Failed to label new Boot partition")
                    return False
            _functions.system("umount /boot")
            _functions.system("mount %s /boot &>/dev/null" \
                              % boot_candidate_dev)

        candidate = None
        candidate_dev = None
        candidate_names = ["RootBackup", "RootUpdate", "RootNew"]
        for trial in range(1, 3):
            time.sleep(1)
            for candidate_name in candidate_names:
                candidate_dev = _functions.findfs(candidate_name)
                logger.debug("Finding %s: '%s'" % (candidate_name, candidate_dev))
                if candidate_dev:
                    candidate = candidate_name
                    logger.debug("Found: %s" % candidate)
                    break
            logger.debug("Trial %s to find candidate (%s)" % (trial,
                                                              candidate_name))
            if candidate:
                logger.debug("Found candidate: '%s'" % candidate)
                break

        if not candidate:
            logger.error("Unable to find root partition")
            label_debug = ''
            for label in os.listdir("/dev/disk/by-label"):
                label_debug += "%s\n" % label
            label_debug += _functions.subprocess_closefds("blkid", shell=True,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.STDOUT).stdout.read()
            logger.debug(label_debug)
            return False

        try:
            self.disk = candidate_dev
            logger.info("Candidate device: %s" % candidate_dev)
            logger.info("Candidate disk: %s" % self.disk)
            # grub2 starts at part 1
            self.partN = int(self.disk[-1:])
            if not _functions.grub2_available():
                self.partN = self.partN - 1
        except:
            logger.debug("Failed to get partition", exc_info=True)
            return False

        if self.disk is None or self.partN < 0:
            logger.error("Failed to determine Root partition number")
            return False
        # prepare Root partition update
        if candidate != "RootNew":
            e2label_cmd = "e2label \"%s\" RootNew" % candidate_dev
            logger.debug(e2label_cmd)
            if not _functions.system(e2label_cmd):
                logger.error("Failed to label new Root partition")
                return False
        mount_cmd = "mount \"%s\" /liveos" % candidate_dev
        if not _functions.system(mount_cmd):
            logger.error("Failed to mount %s on /liveos" % candidate_dev)
            _functions.system("lsof")
            _functions.system("dmsetup info -c")
            _functions.system("cat /proc/mounts")
            _functions.system("multipath -ll")
            _functions.system("lsblk")
            _functions.system("ls -l /dev/mapper")
        _functions.system("rm -rf /liveos/LiveOS")
        _functions.system("mkdir -p /liveos/LiveOS")
        _functions.mount_live()

        if os.path.isdir(self.grub_dir):
            shutil.rmtree(self.grub_dir)
        if not os.path.exists(self.grub_dir):
            os.makedirs(self.grub_dir)
            if _functions.is_efi_boot():
                logger.info("efi detected, installing efi configuration")
                _functions.system("mkdir /liveos/efi")
                _functions.mount_efi()
                _functions.system("mkdir -p /liveos/efi/%s" % self.efi_path)
                if _functions.is_iscsi_install() or _functions.is_efi_boot():
                    if os.path.isfile("/tmp/grubx64.efi"):
                        shutil.copy("/tmp/grubx64.efi",
                                    "/liveos/efi/%s/grubx64.efi" %
                                    self.efi_path)
                    else:
                        shutil.copy("/tmp/grub.efi",
                                    "/liveos/efi/%s/grub.efi" % self.efi_path)
                elif os.path.isfile("/boot/efi/%s/grubx64.efi" %
                        self.efi_path):
                    shutil.copy("/boot/efi/%s/grubx64.efi" % self.efi_path,
                          "/liveos/efi/%s/grubx64.efi" % self.efi_path)
                else:
                    shutil.copy("/boot/efi/%s/grub.efi" % self.efi_path,
                          "/liveos/efi/%s/grub.efi" % self.efi_path)
                if _functions.is_iscsi_install() or _functions.findfs("BootNew"):
                    self.disk = _functions.findfs("BootNew")
                if not "/dev/mapper/" in self.disk:
                    efi_disk = self.disk[:-1]
                else:
                    efi_disk = re.sub(r'p?[1,2,3]$', "", self.disk)
                # generate grub legacy config for efi partition
                #remove existing efi entries
                _functions.remove_efi_entry(_functions.PRODUCT_SHORT)
                if self.efi_name == "fedora":
                    _functions.add_efi_entry(_functions.PRODUCT_SHORT,
                                             ("\\EFI\\%s\\grubx64.efi" %
                                              self.efi_name),
                                             efi_disk)
                else:
                    if os.path.isfile("/liveos/efi/%s/grubx64.efi" %
                            self.efi_path):
                        _functions.add_efi_entry(_functions.PRODUCT_SHORT,
                                                 ("\\EFI\\%s\\grubx64.efi" %
                                                  self.efi_name),
                                                 efi_disk)
                    else:
                        _functions.add_efi_entry(_functions.PRODUCT_SHORT,
                                                 ("\\EFI\\%s\\grub.efi" %
                                                  self.efi_name),
                                                 efi_disk)
        self.kernel_image_copy()

        # reorder tty0 to allow both serial and phys console after installation
        if _functions.is_iscsi_install() or _functions.findfs("BootNew"):
            self.root_param = "root=live:LABEL=Root"
            if "OVIRT_NETWORK_LAYOUT" in OVIRT_VARS and \
                OVIRT_VARS["OVIRT_NETWORK_LAYOUT"] == "bridged":
                network_conf = "ip=br%s:dhcp bridge=br%s:%s" % \
                                (OVIRT_VARS["OVIRT_BOOTIF"],
                                 OVIRT_VARS["OVIRT_BOOTIF"],
                                 OVIRT_VARS["OVIRT_BOOTIF"])
            else:
                network_conf = "ip=%s:dhcp" % OVIRT_VARS["OVIRT_BOOTIF"]
            self.bootparams = "netroot=iscsi:%s::%s::%s %s " % (
                OVIRT_VARS["OVIRT_ISCSI_TARGET_HOST"],
                OVIRT_VARS["OVIRT_ISCSI_TARGET_PORT"],
                OVIRT_VARS["OVIRT_ISCSI_TARGET_NAME"],
                network_conf)
            if "OVIRT_ISCSI_NAME" in OVIRT_VARS:
                self.bootparams+= "iscsi_initiator=%s " % \
                    OVIRT_VARS["OVIRT_ISCSI_NAME"]
        else:
            self.root_param = "root=live:LABEL=Root"
            self.bootparams = "ro rootfstype=auto rootflags=ro "
        self.bootparams += OVIRT_VARS["OVIRT_BOOTPARAMS"].replace(
                                                            "console=tty0", ""
                                                            ).replace(
                                                            "rd_NO_MULTIPATH",
                                                            "")

        if " " in self.disk:
            # workaround for grub setup failing with spaces in dev.name:
            # use first active sd* device
            self.disk = re.sub("p[1,2,3]$", "", self.disk)
            grub_disk_cmd = ("multipath -l " +
                             "\"" + self.disk + "\" " +
                             "| egrep -o '[0-9]+:.*' " +
                             "| awk '/ active / {print $2}' " +
                             "| head -n1")
            logger.debug(grub_disk_cmd)
            grub_disk = _functions.subprocess_closefds(grub_disk_cmd,
                                            shell=True,
                                            stdout=subprocess.PIPE,
                                            stderr=subprocess.STDOUT)
            grub_disk_output, grub_disk_err = grub_disk.communicate()
            self.disk = grub_disk_output.strip()
            if "cciss" in self.disk:
                self.disk = self.disk.replace("!", "/")
            # flush to sync DM and blockdev, workaround from rhbz#623846#c14
            sysfs = open("/proc/sys/vm/drop_caches", "w")
            sysfs.write("3")
            sysfs.close()
        if not self.disk.startswith("/dev/"):
            self.disk = "/dev/" + self.disk
        try:
            if stat.S_ISBLK(os.stat(self.disk).st_mode):
                try:
                    if stat.S_ISBLK(os.stat(self.disk[:-1]).st_mode):
                        # e.g. /dev/sda2
                        self.disk = self.disk[:-1]
                except OSError:
                    pass
                try:
                    if stat.S_ISBLK(os.stat(self.disk[:-2]).st_mode):
                        # e.g. /dev/mapper/WWIDp2
                        self.disk = self.disk[:-2]
                except OSError:
                    pass
        except OSError:
            logger.error("Unable to determine disk for grub installation " +
                         traceback.format_exc())
            return False

        self.grub_dict = {
        "product": _functions.PRODUCT_SHORT,
        "version": _functions.PRODUCT_VERSION,
        "release": _functions.PRODUCT_RELEASE,
        "partN": self.partN,
        "root_param": self.root_param,
        "bootparams": self.bootparams,
        "disk": self.disk,
        "grub_dir": self.grub_dir,
        "grub_prefix": self.grub_prefix,
        "efi_hd": self.efi_hd,
        "linux": "linux",
        "initrd": "initrd",
    }
        if not _functions.is_firstboot():
            if os.path.ismount("/live"):
                with open("%s/version" % self.live_path) as version:
                    for line in version.readlines():
                        if "VERSION" in line:
                            key, value = line.split("=")
                            self.grub_dict["version"] = value.strip()
                        if "RELEASE" in line:
                            key, value = line.split("=")
                            self.grub_dict["release"] = value.strip()

        if _functions.grub2_available():
            if not self.grub2_install():
                logger.error("Grub2 Installation Failed ")
                return False
            else:
                 logger.info("Grub2 EFI Installation Completed ")
        else:
            if not self.grub_install():
                logger.error("Grub Installation Failed ")
                return False
            else:
                logger.info("Grub Installation Completed")

        if _functions.is_iscsi_install() or _functions.findfs("BootNew"):
            # copy default for when Root/HostVG is inaccessible(iscsi upgrade)
            shutil.copy(_functions.OVIRT_DEFAULTS, "/boot")
            # mark new Boot ready to go, reboot() in ovirt-function switches it
            # to active
            e2label_cmd = "e2label \"%s\" BootUpdate" % boot_candidate_dev

            if not _functions.system(e2label_cmd):
                logger.error("Unable to relabel " + boot_candidate_dev +
                             " to RootUpdate ")
                return False
        else:
            _functions.system("umount /liveos/efi")
        _functions.system("umount /liveos")
        # mark new Root ready to go, reboot() in ovirt-function switches it
        # to active
        e2label_cmd = "e2label \"%s\" RootUpdate" % candidate_dev
        if not _functions.system(e2label_cmd):
            logger.error("Unable to relabel " + candidate_dev +
                         " to RootUpdate ")
            return False
        _functions.system("udevadm settle --timeout=10")

        #
        # Rebuild the initramfs
        # A few hacks are needed to prep the chroot
        # The general issue is that we need to run dracut in the context fo the new iso
        # and that we need to put the initrd in the right place of the new iso.
        # These two things make the logic a bit more complicated.
        #
        mnts = []
        try:
            if not _functions.system("blkid -L RootUpdate"):
                raise RuntimeError("RootUpdate not found")

            # Let's mount the update fs, and use that kernel version and modules
            # We need this work to help dracut
            isomnt = tempfile.mkdtemp("RootUpdate")
            squashmnt = tempfile.mkdtemp("RootUpdate-LiveOS")
            updfs = tempfile.mkdtemp("RootUpdate-LiveOS-Img")
            mnts += [isomnt, squashmnt, updfs]

            # Unpack the iso
            def _call(args):
                logger.debug("Calling: %s" % args)
                try:
                    out = subprocess.check_output(args)
                    logger.debug("Out: %s" % out)
                except Exception as e:
                    logger.debug("Failed with: %s %s" % (e, e.output))
                    raise

            _call(["mount", "LABEL=RootUpdate", isomnt])
            _call(["mount", "%s/LiveOS/squashfs.img" % isomnt, squashmnt])
            _call(["mount", "%s/LiveOS/ext3fs.img" % squashmnt, updfs])

            # Now mount the update modules into place, and find the
            # correct kver
            def rbind(path, updfs=updfs):
                dst = updfs + "/" + path
                logger.debug("Binding %r to %r" % (path, dst))
                _call(["mount", "--make-rshared", "--rbind", "/" + path, dst])
                return dst

            for path in ["etc", "dev", "proc", "sys", "tmp", "run", "var/tmp"]:
                mnts += [rbind(path)]

            upd_kver = str(_functions.passthrough("ls -1 %s/lib/modules" % updfs)).strip()

            if len(upd_kver.splitlines()) != 1:
                # It would be very unusual to see more than one kver directory
                # in /lib/modules, because our images just contain one kernel
                raise RuntimeError("Found more than one kernel version")

            # Update initramfs to pickup multipath wwids
            # Let /boot point to the filesystem on the update candidate partition
            builder = _system.Initramfs(dracut_chroot=updfs, boot_source=isomnt)
            builder.rebuild(kver=upd_kver)

        except Exception as e:
            logger.debug("Failed to build initramfs: %s" % e, exc_info=True)
            output = getattr(e, "output", "")
            if output:
                logger.debug("Output: %s" % output)
            raise


        finally:
            # Clean up all eventual mounts
            pass
            # Disabled for now because akward things happen, we leave it to
            # systemd to unnmount on reboot
            # for mnt in reversed(mnts):
            #     d = _functions.passthrough("umount -fl %s" % mnt, logger.debug)
            #     logger.debug("Returned: %s" % d)

        _functions.disable_firstboot()
        if _functions.finish_install():
            if _functions.is_firstboot():
                _iscsi.iscsi_auto()
            logger.info("Installation of %s Completed" % \
                                                      _functions.PRODUCT_SHORT)
            if reboot is not None and reboot == "Y":
                _system.async_reboot()
            return True
        else:
            return False