def ovirt_boot_setup(self, reboot="N"): self.generate_paths() logger.info("Installing the image.") 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 _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(): 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") grub_config_file = "/liveos/EFI/%s/grub.cfg" % self.efi_dir_name if _functions.is_iscsi_install(): 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(): 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: if _functions.findfs(candidate_name): self.boot_candidate = candidate_name break logger.debug("Trial %s to find candidate (%s)" % \ (trial, self.boot_candidate)) 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("mount LABEL=%s /boot &>/dev/null" % self.boot_candidate) if os.path.exists("/boot/ovirt"): try: f = open("/boot/ovirt", 'r') for line in f: try: line = line.strip() key, value = line.split("\"", 1) key = key.strip("=") key = key.strip() value = value.strip("\"") OVIRT_VARS[key] = value except: pass f.close() iscsiadm_cmd = (("iscsiadm -p %s:%s -m discovery -t " + "sendtargets") % ( OVIRT_VARS["OVIRT_ISCSI_TARGET_IP"], OVIRT_VARS["OVIRT_ISCSI_TARGET_PORT"])) _functions.system(iscsiadm_cmd) logger.info("Restarting iscsi service") _functions.system("service iscsi restart") except: pass 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)) 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") _functions.system("cp /boot/efi/EFI/redhat/grub.efi " + "/liveos/efi/EFI/redhat/grub.efi") 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(self.efi_dir_name) efi_mgr_cmd = ("efibootmgr -c -l '\\EFI\\%s\\grubx64.efi' " + "-L '%s' -d %s -v") % (self.efi_dir_name, \ _functions.PRODUCT_SHORT, \ efi_disk) logger.info(efi_mgr_cmd) _functions.system(efi_mgr_cmd) self.kernel_image_copy() # reorder tty0 to allow both serial and phys console after installation if _functions.is_iscsi_install(): self.root_param = "root=live:LABEL=Root" self.bootparams = "netroot=iscsi:%s::%s::%s ip=br%s:dhcp bridge=br%s:%s " % ( OVIRT_VARS["OVIRT_ISCSI_TARGET_HOST"], OVIRT_VARS["OVIRT_ISCSI_TARGET_PORT"], OVIRT_VARS["OVIRT_ISCSI_TARGET_NAME"], OVIRT_VARS["OVIRT_BOOTIF"], OVIRT_VARS["OVIRT_BOOTIF"], OVIRT_VARS["OVIRT_BOOTIF"]) else: self.root_param = "root=live:LABEL=Root" self.bootparams = "ro rootfstype=auto rootflags=ro " self.bootparams += OVIRT_VARS["OVIRT_BOOTPARAMS"].replace( "console=tty0", "") 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 + \ "\" | awk '/ active / {print $3}' | head -n1" logger.debug(grub_disk_cmd) grub_disk = _functions.subprocess_closefds(grub_disk_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) self.disk = grub_disk.stdout.read().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("/live/%s/version" % self.syslinux) 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(): # copy default for when Root/HostVG is inaccessible(iscsi upgrade) shutil.copy(_functions.OVIRT_DEFAULTS, "/boot") # mark new Root 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
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
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
def ovirt_boot_setup(self, reboot="N"): self.generate_paths() logger.info("Installing the image.") 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 if os.path.ismount("/liveos"): if (os.path.exists("/liveos/vmlinuz0") and os.path.exists("/liveos/initrd0.img")): f = open(self.grub_config_file) oldgrub = f.read() f.close() m = re.search("^title (.*)$", oldgrub, re.MULTILINE) if m is not None: self.oldtitle = m.group(1) _functions.system("umount /liveos") if _functions.findfs("BootBackup"): self.boot_candidate = "BootBackup" elif _functions.findfs("Boot"): self.boot_candidate = "Boot" if not os.path.ismount("/boot"): logger.error("Boot partition not available, Install Failed") return False # Grab OVIRT_ISCSI VARIABLES from boot partition for upgrading # file created only if OVIRT_ISCSI_ENABLED=y if os.path.exists("/boot/ovirt"): try: f = open("/boot/ovirt", 'r') for line in f: try: line = line.strip() key, value = line.split("\"", 1) key = key.strip("=") key = key.strip() value = value.strip("\"") OVIRT_VARS[key] = value except: pass f.close() iscsiadm_cmd = (("iscsiadm -p %s:%s -m discovery -t " + "sendtargets") % ( OVIRT_VARS["OVIRT_ISCSI_TARGET_IP"], OVIRT_VARS["OVIRT_ISCSI_TARGET_PORT"])) _functions.system(iscsiadm_cmd) logger.info("Restarting iscsi service") _functions.system("service iscsi restart") except: pass if _functions.findfs("RootBackup"): candidate = "RootBackup" elif _functions.findfs("RootUpdate"): candidate = "RootUpdate" elif _functions.findfs("RootNew"): candidate = "RootNew" else: logger.error("Unable to find %s partition" % candidate) 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 logger.debug("candidate: " + candidate) if _functions.is_iscsi_install(): _functions.system("mount LABEL=%s /boot" % self.boot_candidate) 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 os.path.exists("/sbin/grub2-install") \ or _functions.is_efi_boot()): 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") _functions.system("cp /boot/efi/EFI/redhat/grub.efi " + "/liveos/efi/EFI/redhat/grub.efi") efi_disk = re.sub("p[1,2,3]$", "", self.disk) # generate grub legacy config for efi partition #remove existing efi entries efi_mgr_cmd = "efibootmgr|grep '%s'" % _functions.PRODUCT_SHORT efi_mgr = _functions.subprocess_closefds(efi_mgr_cmd, \ shell=True, \ stdout=subprocess.PIPE, \ stderr=subprocess.STDOUT) efi_out = efi_mgr.stdout.read().strip() logger.debug(efi_mgr_cmd) logger.debug(efi_out) for line in efi_out.splitlines(): if not "Warning" in line: num = line[4:8] # grabs 4 digit hex id cmd = "efibootmgr -B -b %s" % num _functions.system(cmd) efi_mgr_cmd = ("efibootmgr -c -l '\\EFI\\redhat\\grub.efi' " + "-L '%s' -d %s -v") % (_functions.PRODUCT_SHORT, efi_disk) logger.info(efi_mgr_cmd) _functions.system(efi_mgr_cmd) self.kernel_image_copy() # reorder tty0 to allow both serial and phys console after installation if _functions.is_iscsi_install(): self.root_param = "root=LABEL=Root" self.bootparams = "root=iscsi:%s::%s::%s ip=%s:dhcp" % ( OVIRT_VARS["OVIRT_ISCSI_TARGET_HOST"], OVIRT_VARS["OVIRT_ISCSI_TARGET_PORT"], OVIRT_VARS["OVIRT_ISCSI_TARGET_NAME"], OVIRT_VARS["OVIRT_BOOTIF"]) else: self.root_param = "root=live:LABEL=Root" self.bootparams = "ro rootfstype=auto rootflags=ro " self.bootparams += OVIRT_VARS["OVIRT_BOOTPARAMS"].replace( "console=tty0", "") 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 \"" + os.path.basename(self.disk) + \ "\" | awk '/ active / {print $3}' | head -n1" logger.debug(grub_disk_cmd) grub_disk = _functions.subprocess_closefds(grub_disk_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) self.disk = grub_disk.stdout.read().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 os.path.exists("/sbin/grub2-install"): if not _functions.is_efi_boot(): if not self.grub2_install(): logger.error("Grub2 Installation Failed ") return False else: if not self.grub_install(): logger.error("Grub EFI Installation Failed ") return False else: logger.info("Grub 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(): # copy default for when Root/HostVG is inaccessible(iscsi upgrade) shutil.copy(_functions.OVIRT_DEFAULTS, "/boot") _functions.system("umount /boot") 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(): _iscsi.iscsi_auto() logger.info("Installation of %s Completed" % \ _functions.PRODUCT_SHORT) if reboot is not None and reboot == "Y": f = open('/var/spool/cron/root', 'w') f.write('* * * * * sleep 10 && /sbin/reboot') f.close() #ensure crond is started subprocess_closefds("crond", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) return True else: return False
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/EFI/%s/grubx64.efi" % self.efi_dir_name): shutil.copy("/boot/efi/EFI/%s/grubx64.efi" % self.efi_dir_name, "/tmp") else: shutil.copy("/boot/efi/EFI/%s/grub.efi" % self.efi_dir_name, "/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_dir_name == "fedora": grub_config_file = "/liveos/EFI/fedora/grub.cfg" else: grub_config_file = "/liveos/EFI/redhat/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) 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/EFI/redhat") if _functions.is_iscsi_install() or _functions.is_efi_boot(): if os.path.isfile("/tmp/grubx64.efi"): shutil.copy("/tmp/grubx64.efi", "/liveos/efi/EFI/redhat/grubx64.efi") else: shutil.copy("/tmp/grub.efi", "/liveos/efi/EFI/redhat/grub.efi") elif os.path.isfile("/boot/efi/EFI/redhat/grubx64.efi"): shutil.copy("/boot/efi/EFI/redhat/grubx64.efi", "/liveos/efi/EFI/redhat/grubx64.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(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_dir_name == "fedora": _functions.add_efi_entry(_functions.PRODUCT_SHORT, ("\\EFI\\%s\\grubx64.efi" % self.efi_dir_name), efi_disk) else: if os.path.isfile("/liveos/efi/EFI/redhat/grubx64.efi"): _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", "") is_mpath_root = self.disk and self.disk.startswith("/dev/mapper") has_mpath_wwid = "mpath.wwid=" in self.bootparams if is_mpath_root and not has_mpath_wwid: """We need to specify the wwid of the root device if it is using multiple paths to prevent races within dracut. Basically there are two options: 1. bake wwid of root device into initrd 2. pass wwid of root device on kernel cmdline I choose 2 because it seems to be less invasive. https://bugzilla.redhat.com/show_bug.cgi?id=1152948 """ lsblkcmd = "lsblk -inls %s | awk 'FNR==2 {print $1}'" % self.disk lsblkproc = _functions.subprocess_closefds(lsblkcmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) lsblkout, lsblkerr = lsblkproc.communicate() logger.debug("lsblk returned: %s -- %s" % (lsblkout, lsblkerr)) if not lsblkout.strip(): raise RuntimeError("Failed to determin parent of partition: %s" % self.disk) part_parent = "/dev/mapper/" + lsblkout.strip() logger.debug("lsblk found parent for partition %s: %s" % (self.disk, part_parent)) wwidcmd = "multipath -ll %s | egrep -o '^.*dm-[0-9]' | cut -d' ' -f1" % part_parent logger.debug("Checking device for multipath: %s" % wwidcmd) wwidproc = _functions.subprocess_closefds(wwidcmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) wwidout, wwiderr = wwidproc.communicate() logger.debug("multipath returned: %s -- %s" % (wwidout, wwiderr)) wwid = wwidout.strip() if wwid: logger.debug("Using multipath wwid: %s" % wwid) self.bootparams += " mpath.wwid=%s" % wwid logger.debug("Cmdline with mpath: %s" % self.bootparams) else: logger.debug("Got NO multipath wwid, not using any") 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.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
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