def go(ui, args, answerfile_address, answerfile_script): extra_repo_defs = [] results = { 'keymap': None, 'serial-console': None, 'operation': init_constants.OPERATION_INSTALL, 'boot-serial': False, 'extra-repos': [], 'network-backend': constants.NETWORK_BACKEND_DEFAULT, 'root-password': ('pwdhash', '!!'), 'create-new-partitions': True, # FALSE = DOS | TRUE = GPT set via command line only with --disable-gpt 'new-partition-layout': False, # TRUE = GPT with LOG,BACKUP,ROOT,BOOT,SWAP,SR automatically set during install/upgrade 'services': {s: None for s in constants.SERVICES }, # default state for services, example {'sshd': None} } suppress_extra_cd_dialog = False serial_console = None boot_console = None boot_serial = False if not xen_control_domain() or '--virtual' in args: hardware.useVMHardwareFunctions() for (opt, val) in args.items(): if opt == "--boot-console": # takes precedence over --console if hardware.is_serialConsole(val): boot_console = hardware.getSerialConfig() elif opt == "--console": for console in val: if hardware.is_serialConsole(console): serial_console = hardware.getSerialConfig() if hardware.is_serialConsole(val[-1]): boot_serial = True elif opt == "--keymap": results["keymap"] = val logger.log("Keymap specified on command-line: %s" % val) elif opt == "--extrarepo": extra_repo_defs += val elif opt == "--onecd": suppress_extra_cd_dialog = True elif opt == "--disable-gpt": constants.GPT_SUPPORT = False results["create-new-partitions"] = False logger.log( "Forcing DOS partition table and old partition layout via command-line" ) elif opt == "--legacy-partitions": results["create-new-partitions"] = False logger.log("Forcing old partition layout via command-line") elif opt == "--cc-preparations": constants.CC_PREPARATIONS = True results['network-backend'] = constants.NETWORK_BACKEND_BRIDGE if boot_console and not serial_console: serial_console = boot_console boot_serial = True if serial_console: try: results['serial-console'] = hardware.SerialPort.from_string( serial_console) results['boot-serial'] = boot_serial logger.log( "Serial console specified on command-line: %s, default boot: %s" % (serial_console, boot_serial)) except: pass interactive = True try: if os.path.isfile(constants.defaults_data_file): data_file = open(constants.defaults_data_file) try: defaults = json.load(data_file) finally: data_file.close() results.update(defaults) # loading an answerfile? assert ui is not None or answerfile_address is not None or answerfile_script is not None if answerfile_address and answerfile_script: raise RuntimeError( "Both answerfile and answerfile generator passed on command line." ) a = None parsing_except = None if answerfile_address: a = answerfile.Answerfile.fetch(answerfile_address) elif answerfile_script: a = answerfile.Answerfile.generate(answerfile_script) if a: interactive = False results['network-hardware'] = netutil.scanConfiguration() try: results.update(a.parseScripts()) results.update(a.processAnswerfileSetup()) if ui and results.get('ui-confirmation-prompt', False): if not ui.init.confirm_proceed(): logger.log("User did not confirm installation. Reboot") return constants.EXIT_USER_CANCEL if 'extra-repos' in results: # load drivers now for media, address in results['extra-repos']: for r in repository.repositoriesFromDefinition( media, address, drivers=True): r.installPackages(lambda x: (), {'root': '/'}) if 'fcoe-interfaces' in results: fcoeutil.start_fcoe(results['fcoe-interfaces']) util.runCmd2(util.udevsettleCmd()) time.sleep(1) diskutil.mpath_part_scan() # ensure partitions/disks are not locked by LVM lvm = disktools.LVMTool() lvm.deactivateAll() del lvm diskutil.log_available_disks() results.update(a.processAnswerfile()) results = fixMpathResults(results) except Exception as e: logger.logException(e) parsing_except = e results['extra-repos'] += extra_repo_defs logger.log("Driver repos: %s" % str(results['extra-repos'])) scripts.run_scripts('installation-start') if parsing_except: raise parsing_except # log the modules that we loaded: logger.log("All needed modules should now be loaded. We have loaded:") util.runCmd2(["lsmod"]) status = constants.EXIT_OK # how much RAM do we have? ram_found_mb = hardware.getHostTotalMemoryKB() / 1024 ram_warning = ram_found_mb < constants.MIN_SYSTEM_RAM_MB vt_warning = not hardware.VTSupportEnabled() # Generate the UI sequence and populate some default # values in backend input. Note that not all these screens # will be displayed as they have conditional to skip them at # the start of each function. In future these conditionals will # be moved into the sequence definition and evaluated by the # UI dispatcher. aborted = False if ui and interactive: uiexit = ui.installer.runMainSequence(results, ram_warning, vt_warning, suppress_extra_cd_dialog) if uiexit == uicontroller.EXIT: aborted = True if not aborted: if results['install-type'] == constants.INSTALL_TYPE_RESTORE: logger.log('INPUT ANSWER DICTIONARY') backend.prettyLogAnswers(results) logger.log("SCRIPTS DICTIONARY:") backend.prettyLogAnswers(scripts.script_dict) logger.log("Starting actual restore") backup = results['backup-to-restore'] if ui: pd = tui.progress.initProgressDialog( "Restoring %s" % backup, "Restoring data - this may take a while...", 100) def progress(x): if ui and pd: tui.progress.displayProgressDialog(x, pd) restore.restoreFromBackup(backup, progress) if ui: tui.progress.clearModelessDialog() tui.progress.OKDialog( "Restore", "The restore operation completed successfully.") else: logger.log("Starting actual installation") backend.performInstallation(results, ui, interactive) if ui and interactive: ui.installer.screens.installation_complete() logger.log("The installation completed successfully.") else: logger.log( "The user aborted the installation from within the user interface." ) status = constants.EXIT_USER_CANCEL except Exception as e: try: # first thing to do is to get the traceback and log it: ex = sys.exc_info() err = str.join("", traceback.format_exception(*ex)) logger.log("INSTALL FAILED.") logger.log("A fatal exception occurred:") logger.log(err) # run the user's scripts - an arg of "1" indicates failure scripts.run_scripts('installation-complete', '1') # collect logs where possible xelogging.collectLogs("/tmp") # now display a friendly error dialog: if ui: ui.exn_error_dialog("install-log", True, interactive) else: txt = constants.error_string(str(e), 'install-log', True) logger.log(txt) # and now on the disk if possible: if 'primary-disk' in results and 'primary-partnum' in results and 'logs-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum'], results['logs-partnum']) elif 'primary-disk' in results and 'primary-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum'], None) logger.log(results) except Exception as e: # Don't let logging exceptions prevent subsequent actions print 'Logging failed: ' + str(e) # exit with failure status: status = constants.EXIT_ERROR else: # run the user's scripts - an arg of "0" indicates success try: scripts.run_scripts('installation-complete', '0') except: pass # put the log in /tmp: xelogging.collectLogs('/tmp') # and now on the disk if possible: if 'primary-disk' in results and 'primary-partnum' in results and 'logs-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum'], results['logs-partnum']) elif 'primary-disk' in results and 'primary-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum'], None) assert (status == constants.EXIT_OK or status == constants.EXIT_USER_CANCEL) return status
scripts.run_scripts('installation-complete', '1') # collect logs where possible xelogging.collectLogs("/tmp") # now display a friendly error dialog: if ui: ui.exn_error_dialog("install-log", True, interactive) else: txt = constants.error_string(str(e), 'install-log', True) xelogging.log(txt) # and now on the disk if possible: if 'primary-disk' in results and 'primary-partnum' in results and 'logs-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum'], results['logs-partnum']) elif 'primary-disk' in results and 'primary-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum'], None) xelogging.log(results) except Exception, e: # Don't let logging exceptions prevent subsequent actions print 'Logging failed: ' + str(e) # exit with failure status: status = constants.EXIT_ERROR else: # run the user's scripts - an arg of "0" indicates success
def go(ui, args, answerfile_address, answerfile_script): extra_repo_defs = [] results = { 'keymap': None, 'serial-console': None, 'operation': init_constants.OPERATION_INSTALL, 'boot-serial': False, 'extra-repos': [], 'network-backend': constants.NETWORK_BACKEND_DEFAULT, } suppress_extra_cd_dialog = False serial_console = None boot_console = None boot_serial = False if not xen_control_domain() or args.has_key('--virtual'): hardware.useVMHardwareFunctions() for (opt, val) in args.items(): if opt == "--boot-console": # takes precedence over --console if hardware.is_serialConsole(val): boot_console = hardware.getSerialConfig() elif opt == "--console": for console in val: if hardware.is_serialConsole(console): serial_console = hardware.getSerialConfig() if hardware.is_serialConsole(val[-1]): boot_serial = True elif opt == "--keymap": results["keymap"] = val xelogging.log("Keymap specified on command-line: %s" % val) elif opt == "--extrarepo": extra_repo_defs += val elif opt == "--onecd": suppress_extra_cd_dialog = True elif opt == "--disable-gpt": constants.GPT_SUPPORT = False if boot_console and not serial_console: serial_console = boot_console boot_serial = True if serial_console: try: results['serial-console'] = hardware.SerialPort.from_string(serial_console) results['boot-serial'] = boot_serial xelogging.log("Serial console specified on command-line: %s, default boot: %s" % (serial_console, boot_serial)) except: pass interactive = True try: # loading an answerfile? assert ui != None or answerfile_address != None or answerfile_script != None if answerfile_address and answerfile_script: raise RuntimeError, "Both answerfile and answerfile generator passed on command line." a = None if answerfile_address: a = answerfile.Answerfile(answerfile_address) elif answerfile_script: a = answerfile.Answerfile.generate(answerfile_script) if a: interactive = False results['network-hardware'] = netutil.scanConfiguration() results.update(a.parseScripts()) results.update(a.processAnswerfile()) if results.has_key('extra-repos'): # load drivers now for d in results['extra-repos']: media, address, _ = d for r in repository.repositoriesFromDefinition(media, address): for p in r: if p.type.startswith('driver'): if p.load() != 0: raise RuntimeError, "Failed to load driver %s." % p.name results['extra-repos'] += extra_repo_defs xelogging.log("Driver repos: %s" % str(results['extra-repos'])) scripts.run_scripts('installation-start') # log the modules that we loaded: xelogging.log("All needed modules should now be loaded. We have loaded:") util.runCmd2(["/bin/lsmod"]) status = constants.EXIT_OK # debug: print out what disks have been discovered diskutil.log_available_disks() # how much RAM do we have? ram_found_mb = hardware.getHostTotalMemoryKB() / 1024 ram_warning = ram_found_mb < constants.MIN_SYSTEM_RAM_MB vt_warning = not hardware.VTSupportEnabled() # Generate the UI sequence and populate some default # values in backend input. Note that not all these screens # will be displayed as they have conditional to skip them at # the start of each function. In future these conditionals will # be moved into the sequence definition and evaluated by the # UI dispatcher. aborted = False if ui and interactive: uiexit = ui.installer.runMainSequence( results, ram_warning, vt_warning, suppress_extra_cd_dialog ) if uiexit == uicontroller.EXIT: aborted = True if not aborted: if results['install-type'] == constants.INSTALL_TYPE_RESTORE: xelogging.log("Starting actual restore") backup = results['backup-to-restore'] if ui: pd = tui.progress.initProgressDialog("Restoring", "Restoring data - this may take a while...", 100) def progress(x): if ui and pd: tui.progress.displayProgressDialog(x, pd) restore.restoreFromBackup(backup.partition, backup.root_disk, progress) if pd: tui.progress.clearModelessDialog() tui.progress.OKDialog("Restore", "The restore operation completed successfully.") else: xelogging.log("Starting actual installation") results = backend.performInstallation(results, ui, interactive) if ui and interactive: ui.installer.screens.installation_complete() xelogging.log("The installation completed successfully.") else: xelogging.log("The user aborted the installation from within the user interface.") status = constants.EXIT_USER_CANCEL except Exception, e: try: # first thing to do is to get the traceback and log it: ex = sys.exc_info() err = str.join("", traceback.format_exception(*ex)) xelogging.log("INSTALL FAILED.") xelogging.log("A fatal exception occurred:") xelogging.log(err) # run the user's scripts - an arg of "1" indicates failure scripts.run_scripts('installation-complete', '1') # collect logs where possible xelogging.collectLogs("/tmp") # now display a friendly error dialog: if ui: ui.exn_error_dialog("install-log", True, interactive) else: txt = constants.error_string(str(e), 'install-log', True) xelogging.log(txt) # and now on the disk if possible: if 'primary-disk' in results and 'primary-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum']) xelogging.log(results) except Exception, e: # Don't let logging exceptions prevent subsequent actions print 'Logging failed: '+str(e)
backend.writeLog(results['primary-disk'], results['primary-partnum']) xelogging.log(results) except Exception, e: # Don't let logging exceptions prevent subsequent actions print 'Logging failed: '+str(e) # exit with failure status: status = constants.EXIT_ERROR else: # run the user's scripts - an arg of "0" indicates success try: scripts.run_scripts('installation-complete', '0') except: pass # put the log in /tmp: xelogging.collectLogs('/tmp') # and now on the disk if possible: if 'primary-disk' in results and 'primary-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum']) assert (status == constants.EXIT_OK or status == constants.EXIT_USER_CANCEL) return status if __name__ == "__main__": sys.exit(main(util.splitArgs(sys.argv[1:], array_args = ('--extrarepo'))))
def doRestore(backup, progress, backup_partition_layout, has_logs_partition): backup_partition = backup.partition backup_version = backup.version disk = backup.root_disk tool = PartitionTool(disk) _, boot_partnum, primary_partnum, backup_partnum, logs_partnum, swap_partnum, _ = backend.inspectTargetDisk( disk, None, [], constants.PRESERVE_IF_UTILITY, True, True) limit_version = product.THIS_PLATFORM_VERSION logs_partition = tool.getPartition(logs_partnum) boot_partition = tool.getPartition(boot_partnum) assert backup_partition.startswith('/dev/') assert disk.startswith('/dev/') label = None bootlabel = None if has_logs_partition and not backup_partition_layout: # From 7.x (new layout) to 6.x restore_partition = partitionDevice(disk, logs_partnum) else: restore_partition = partitionDevice(disk, primary_partnum) xelogging.log("Restoring to partition %s." % restore_partition) tool = PartitionTool(disk) boot_part = tool.getPartition(boot_partnum) boot_device = partitionDevice(disk, boot_partnum) if boot_part else None efi_boot = boot_part and boot_part['id'] == GPTPartitionTool.ID_EFI_BOOT # determine current location of bootloader current_location = 'unknown' try: root_fs = util.TempMount(restore_partition, 'root-', options=['ro'], boot_device=boot_device) try: boot_config = bootloader.Bootloader.loadExisting( root_fs.mount_point) current_location = boot_config.location xelogging.log("Bootloader currently in %s" % current_location) finally: root_fs.unmount() except: pass # mount the backup fs backup_fs = util.TempMount(backup_partition, 'restore-backup-', options=['ro']) try: # extract the bootloader config boot_config = bootloader.Bootloader.loadExisting(backup_fs.mount_point) if boot_config.src_fmt == 'grub': raise RuntimeError, "Backup uses grub bootloader which is no longer supported - " + \ "to restore please use a version of the installer that matches the backup partition" # format the restore partition(s): if util.runCmd2(['mkfs.%s' % constants.rootfs_type, restore_partition ]) != 0: raise RuntimeError, "Failed to create root filesystem" if efi_boot: if util.runCmd2(['mkfs.vfat', boot_device]) != 0: raise RuntimeError, "Failed to create boot filesystem" # mount restore partition: dest_fs = util.TempMount(restore_partition, 'restore-dest-') try: # copy files from the backup partition to the restore partition: objs = filter( lambda x: x not in ['lost+found', '.xen-backup-partition', '.xen-gpt.bin'], os.listdir(backup_fs.mount_point)) for i in range(len(objs)): obj = objs[i] xelogging.log("Restoring subtree %s..." % obj) progress((i * 100) / len(objs)) # Use 'cp' here because Python's copying tools are useless and # get stuck in an infinite loop when copying e.g. /dev/null. if util.runCmd2([ 'cp', '-a', os.path.join(backup_fs.mount_point, obj), dest_fs.mount_point ]) != 0: raise RuntimeError, "Failed to restore %s directory" % obj xelogging.log( "Data restoration complete. About to re-install bootloader.") location = boot_config.location m = re.search(r'root=LABEL=(\S+)', boot_config.menu[boot_config.default].kernel_args) if m: label = m.group(1) if location == constants.BOOT_LOCATION_PARTITION and current_location == constants.BOOT_LOCATION_MBR: # if bootloader in the MBR it's probably not safe to restore with it # on the partition xelogging.log( "Bootloader is currently installed to MBR, restoring to MBR instead of partition" ) location = constants.BOOT_LOCATION_MBR with open(os.path.join(backup_fs.mount_point, 'etc', 'fstab'), 'r') as fstab: for line in fstab: m = re.match(r'LABEL=(\S+)\s+/boot/efi\s', line) if m: bootlabel = m.group(1) mounts = { 'root': dest_fs.mount_point, 'boot': os.path.join(dest_fs.mount_point, 'boot') } # prepare extra mounts for installing bootloader: util.bindMount("/dev", "%s/dev" % dest_fs.mount_point) util.bindMount("/sys", "%s/sys" % dest_fs.mount_point) util.bindMount("/proc", "%s/proc" % dest_fs.mount_point) if boot_config.src_fmt == 'grub2': if efi_boot: branding = util.readKeyValueFile( os.path.join(backup_fs.mount_point, constants.INVENTORY_FILE)) branding['product-brand'] = branding['PRODUCT_BRAND'] backend.setEfiBootEntry(mounts, disk, boot_partnum, branding) else: if location == constants.BOOT_LOCATION_MBR: backend.installGrub2(mounts, disk, False) else: backend.installGrub2(mounts, restore_partition, True) else: backend.installExtLinux(mounts, disk, probePartitioningScheme(disk), location) # restore bootloader configuration dst_file = boot_config.src_file.replace(backup_fs.mount_point, dest_fs.mount_point, 1) util.assertDir(os.path.dirname(dst_file)) boot_config.commit(dst_file) finally: util.umount("%s/proc" % dest_fs.mount_point) util.umount("%s/sys" % dest_fs.mount_point) util.umount("%s/dev" % dest_fs.mount_point) dest_fs.unmount() finally: backup_fs.unmount() if not label: raise RuntimeError, "Failed to find label required for root filesystem." if efi_boot and not bootlabel: raise RuntimeError( "Failed to find label required for boot filesystem.") if util.runCmd2(['e2label', restore_partition, label]) != 0: raise RuntimeError, "Failed to label root partition" if bootlabel: if util.runCmd2(['fatlabel', boot_device, bootlabel]) != 0: raise RuntimeError, "Failed to label boot partition" if has_logs_partition: if not backup_partition_layout: # From 7.x (new layout) to 6.x # Delete backup, dom0, Boot and swap partitions tool.deletePartition(backup_partnum) tool.deletePartition(primary_partnum) tool.deletePartition(boot_partnum) tool.deletePartition(swap_partnum) # Rename logs partition to be n.1 tool.renamePartition(srcNumber=logs_partnum, destNumber=primary_partnum, overwrite=False) # Create 4GB backup partition tool.createPartition( tool.ID_LINUX, sizeBytes=constants.backup_size_old * 2**20, startBytes=tool.partitionEnd(primary_partnum) + tool.sectorSize, number=backup_partnum) # Commit partition table and mark dom0 disk as bootable tool.commit(log=True) tool.commitActivePartitiontoDisk(primary_partnum) xelogging.log("Bootloader restoration complete.") xelogging.log("Restore successful.") backend.writeLog(disk, primary_partnum, logs_partnum) elif 'LOG' in backup_partition_layout: # From 7.x (new layout) to 7.x (new layout) tool.commitActivePartitiontoDisk(boot_partnum) rdm_label = label.split("-")[1] logs_part = partitionDevice(disk, logs_partnum) swap_part = partitionDevice(disk, swap_partnum) if util.runCmd2([ 'e2label', logs_part, constants.logsfs_label % rdm_label ]) != 0: raise RuntimeError, "Failed to label logs partition" if util.runCmd2([ 'swaplabel', '-L', constants.swap_label % rdm_label, swap_part ]) != 0: raise RuntimeError, "Failed to label swap partition"
def restoreWithoutRepartButUEFI(backup, progress): backup_partition = backup.partition disk = backup.root_disk assert backup_partition.startswith('/dev/') assert disk.startswith('/dev/') # Restore the partition layout backup_fs = util.TempMount(backup_partition, 'restore-backup-', options=['ro']) gpt_bin = None try: src_bin = os.path.join(backup_fs.mount_point, '.xen-gpt.bin') if os.path.exists(src_bin): gpt_bin = tempfile.mktemp() shutil.copyfile(src_bin, gpt_bin) finally: backup_fs.unmount() if gpt_bin: xelogging.log("Restoring partition layout") rc, err = util.runCmd2(["sgdisk", "-l", gpt_bin, disk], with_stderr=True) if rc != 0: raise RuntimeError, "Failed to restore partition layout: %s" % err label = None bootlabel = None _, boot_partnum, primary_partnum, backup_partnum, logs_partnum, swap_partnum, _ = backend.inspectTargetDisk( disk, None, [], constants.PRESERVE_IF_UTILITY, True, True) restore_partition = partitionDevice(disk, primary_partnum) xelogging.log("Restoring to partition %s." % restore_partition) tool = PartitionTool(disk) boot_part = tool.getPartition(boot_partnum) boot_device = partitionDevice(disk, boot_partnum) if boot_part else None efi_boot = boot_part and boot_part['id'] == GPTPartitionTool.ID_EFI_BOOT # determine current location of bootloader current_location = 'unknown' try: root_fs = util.TempMount(restore_partition, 'root-', options=['ro'], boot_device=boot_device) try: boot_config = bootloader.Bootloader.loadExisting( root_fs.mount_point) current_location = boot_config.location xelogging.log("Bootloader currently in %s" % current_location) finally: root_fs.unmount() except: pass # mount the backup fs backup_fs = util.TempMount(backup_partition, 'restore-backup-', options=['ro']) try: # extract the bootloader config boot_config = bootloader.Bootloader.loadExisting(backup_fs.mount_point) if boot_config.src_fmt == 'grub': raise RuntimeError, "Backup uses grub bootloader which is no longer supported - " + \ "to restore please use a version of the installer that matches the backup partition" # format the restore partition(s): if util.runCmd2(['mkfs.%s' % constants.rootfs_type, restore_partition ]) != 0: raise RuntimeError, "Failed to create root filesystem" if efi_boot: if util.runCmd2(['mkfs.vfat', boot_device]) != 0: raise RuntimeError, "Failed to create boot filesystem" # mount restore partition: dest_fs = util.TempMount(restore_partition, 'restore-dest-', boot_device=boot_device, boot_mount_point='/boot/efi') try: # copy files from the backup partition to the restore partition: objs = filter( lambda x: x not in ['lost+found', '.xen-backup-partition', '.xen-gpt.bin'], os.listdir(backup_fs.mount_point)) for i in range(len(objs)): obj = objs[i] xelogging.log("Restoring subtree %s..." % obj) progress((i * 100) / len(objs)) # Use 'cp' here because Python's copying tools are useless and # get stuck in an infinite loop when copying e.g. /dev/null. if util.runCmd2([ 'cp', '-a', os.path.join(backup_fs.mount_point, obj), dest_fs.mount_point ]) != 0: raise RuntimeError, "Failed to restore %s directory" % obj xelogging.log( "Data restoration complete. About to re-install bootloader.") location = boot_config.location m = re.search(r'root=LABEL=(\S+)', boot_config.menu[boot_config.default].kernel_args) if m: label = m.group(1) if location == constants.BOOT_LOCATION_PARTITION and current_location == constants.BOOT_LOCATION_MBR: # if bootloader in the MBR it's probably not safe to restore with it # on the partition xelogging.log( "Bootloader is currently installed to MBR, restoring to MBR instead of partition" ) location = constants.BOOT_LOCATION_MBR with open(os.path.join(backup_fs.mount_point, 'etc', 'fstab'), 'r') as fstab: for line in fstab: m = re.match(r'LABEL=(\S+)\s+/boot/efi\s', line) if m: bootlabel = m.group(1) mounts = { 'root': dest_fs.mount_point, 'boot': os.path.join(dest_fs.mount_point, 'boot') } # prepare extra mounts for installing bootloader: util.bindMount("/dev", "%s/dev" % dest_fs.mount_point) util.bindMount("/sys", "%s/sys" % dest_fs.mount_point) util.bindMount("/proc", "%s/proc" % dest_fs.mount_point) if boot_config.src_fmt == 'grub2': if efi_boot: branding = util.readKeyValueFile( os.path.join(backup_fs.mount_point, constants.INVENTORY_FILE)) branding['product-brand'] = branding['PRODUCT_BRAND'] backend.setEfiBootEntry(mounts, disk, boot_partnum, branding) else: if location == constants.BOOT_LOCATION_MBR: backend.installGrub2(mounts, disk, False) else: backend.installGrub2(mounts, restore_partition, True) else: backend.installExtLinux(mounts, disk, probePartitioningScheme(disk), location) # restore bootloader configuration dst_file = boot_config.src_file.replace(backup_fs.mount_point, dest_fs.mount_point, 1) util.assertDir(os.path.dirname(dst_file)) boot_config.commit(dst_file) finally: util.umount("%s/proc" % dest_fs.mount_point) util.umount("%s/sys" % dest_fs.mount_point) util.umount("%s/dev" % dest_fs.mount_point) dest_fs.unmount() finally: backup_fs.unmount() if not label: raise RuntimeError, "Failed to find label required for root filesystem." if efi_boot and not bootlabel: raise RuntimeError( "Failed to find label required for boot filesystem.") if util.runCmd2(['e2label', restore_partition, label]) != 0: raise RuntimeError, "Failed to label root partition" if bootlabel: if util.runCmd2(['fatlabel', boot_device, bootlabel]) != 0: raise RuntimeError, "Failed to label boot partition" xelogging.log("Bootloader restoration complete.") xelogging.log("Restore successful.") backend.writeLog(disk, primary_partnum, logs_partnum)