def _createBootAndInstallGrub(self, destination): with self._mountOp.mountBoot() as bootDestination: sh.run("rsync -rlpgDS --delete-before %s/boot/ %s/" % (destination, bootDestination)) with self._mountOp.mountBootInsideRoot(): serialDevices = self._getSerialDevices() if serialDevices: logging.info( "Overriding GRUB2 user settings to set serial devices to '%(devices)s'...", dict(devices=serialDevices)) grub.setSerialDevices(serialDevices, destination) else: logging.warn( "a 'console' argument was not given. Cannot tell which serial device to " "redirect the console output to (default values in the label will be used)." ) logging.info("Installing GRUB2...") grub.install(self._targetDevice, destination) logging.info( "Reading newly generated GRUB2 configuration file for later use..." ) grubConfigFilename = os.path.join(destination, "boot", "grub2", "grub.cfg") with open(grubConfigFilename, "r") as grubConfigFile: self._grubConfig = grubConfigFile.read()
def _createBootAndInstallGrub(self, destination): with self._mountOp.mountBoot() as bootDestination: sh.run("rsync -rlpgDS --delete-before %s/boot/ %s/" % (destination, bootDestination)) with self._mountOp.mountBootInsideRoot(): logging.info("Installing grub") grub.install(self._targetDevice, destination)
def _correctEXT4Errors(self, device): try: sh.run("/usr/sbin/fsck.ext4 -y -f %s" % device) except: logging.exception( "fsck returned with errors, this most likely means it has corrected issues on disk." " attepting to continue")
def setRootPassword(rootPath, password): if sh.has_tool(rootPath, 'chpasswd'): sh.run("echo 'root:%(password)s' | chroot %(rootPath)s chpasswd" % dict( password=password, rootPath=rootPath)) else: sh.run("echo '%(password)s' | chroot %(rootPath)s passwd --stdin root" % dict( password=password, rootPath=rootPath))
def _correctEXT4Errors(self, device): try: sh.run("/usr/sbin/fsck.ext4 -y %s" % device) except: logging.exception( "fsck returned with errors, this most likely means it has corrected issues on disk." " attepting to continue")
def fromBootPartitionGrubConfig(self, grubConfig, bootPath, rootPartition): parser = grubconfparser.GrubConfParser(grubConfig) sh.run("kexec --load %s --initrd=%s --append='root=%s %s'" % ( os.path.join(bootPath, parser.defaultKernelImage()), os.path.join(bootPath, parser.defaultInitrd()), rootPartition, self._filterOutRootArgument(parser.defaultKernelCommandLine())))
def _loadDriver(driver): "This is for upwards dependency, not modprobe like dependency" print "Driver: %s, modprobing" % driver sh.run("busybox modprobe %s" % driver) if driver in _ALSO: print "Additional drivers must be loaded for '%s': %s" % (driver, _ALSO[driver]) for also in _ALSO[driver]: _loadDriver(also)
def mountBootInsideRoot(self): sh.run("/usr/sbin/busybox mount -t ext4 %s %s/boot" % ( self._bootPartition, self._ROOT_MOUNT_POINT)) sh.run("/usr/sbin/busybox cp -a /dev/* %s/dev/" % self._ROOT_MOUNT_POINT) sh.run("/usr/sbin/busybox mount -t proc none %s/proc" % self._ROOT_MOUNT_POINT) yield self._ROOT_MOUNT_POINT sh.run("/usr/sbin/busybox umount %s/proc" % self._ROOT_MOUNT_POINT) sh.run("/usr/sbin/busybox umount %s/boot" % self._ROOT_MOUNT_POINT)
def __init__(self, macAddress, ipAddress, netmask, gateway): self._gateway = gateway interfacesTable = self._interfacesTable() assert macAddress.lower() in interfacesTable interfaceName = interfacesTable[macAddress.lower()] sh.run("/usr/sbin/ifconfig %s %s netmask %s" % (interfaceName, ipAddress, netmask)) sh.run("busybox route add default gw %s" % self._gateway) self._validateLinkIsUp()
def fromBootPartitionGrubConfig(self, bootPath, rootPartition, append): parser = grubconfparser.GrubConfParser.fromFile( os.path.join(bootPath, "grub2", "grub.cfg")) sh.run("kexec --load %s --initrd=%s --append='root=%s %s %s'" % (os.path.join(bootPath, parser.defaultKernelImage()), os.path.join(bootPath, parser.defaultInitrd()), rootPartition, self._filterOutRootArgument( parser.defaultKernelCommandLine()), append))
def _setFlags(self): for partitionIdx, partition in enumerate( self._physicalPartitionsOrder): partitionNr = partitionIdx + 1 flag = self._physicalPartitions[partition]["flags"] print "Setting flag '%s' for partition #%d..." % (flag, partitionNr) sh.run("parted -s %s set %d %s on" % (self._device, partitionNr, flag))
def parseLVMPhysicalVolume(cls, partition): sh.run("lvm pvscan --cache %s" % partition) fields = cls._fieldsOfLastTableRow( sh.run("lvm pvdisplay --units m --columns %s" % partition)) assert fields[ 0] == partition, "Invalid columns output from pvdisplay: %s" % fields assert fields[4].endswith("m") return dict(name=fields[1], sizeMB=int(re.match(r"\d+", fields[4]).group(0)))
def _findDevice(self): sh.run("busybox modprobe usb_storage") for i in xrange(10): try: return self._findDeviceOnce() except: time.sleep(1) sh.run("/usr/sbin/busybox mdev -s") return self._findDeviceOnce()
def _loadDriver(driver): "This is for upwards dependency, not modprobe like dependency" logging.info("Driver: %s, modprobing" % driver) sh.run("busybox modprobe %s" % driver) if driver in _ALSO: logging.info("Additional drivers must be loaded for '%s': %s" % (driver, _ALSO[driver])) for also in _ALSO[driver]: _loadDriver(also)
def install(targetDevice, destination): prefix = grub_prefix(destination) if prefix is None: raise Exception("Failed to install grub boot menu grub tools not found") chrootScript = '%(prefix)s-install %(targetDevice)s && %(prefix)s-mkconfig > /boot/%(prefix)s/grub.cfg' % dict( prefix=prefix, targetDevice=targetDevice) sh.run("/usr/sbin/busybox chroot %s sh -c '%s'" % (destination, chrootScript))
def mountBootInsideRoot(self): sh.run("/usr/sbin/busybox mount -t ext4 %s %s/boot" % (self._bootPartition, self._ROOT_MOUNT_POINT)) sh.run("/usr/sbin/busybox cp -a /dev/* %s/dev/" % self._ROOT_MOUNT_POINT) sh.run("/usr/sbin/busybox mount -t proc none %s/proc" % self._ROOT_MOUNT_POINT) yield self._ROOT_MOUNT_POINT sh.run("/usr/sbin/busybox umount %s/proc" % self._ROOT_MOUNT_POINT) sh.run("/usr/sbin/busybox umount %s/boot" % self._ROOT_MOUNT_POINT)
def _doOsmosisFromSource(self, destination): cleanup = osmosiscleanup.OsmosisCleanup(destination, objectStorePath=self._localObjectStore) try: self._doOsmosisFromSourceUnsafe(destination) except Exception as e: logging.exception("Failed to osmosis from source") cleanup.eraseEverything() sh.run("busybox rm -fr %s/*" % destination) if self._talkToServer: self._talkToServer.progress(dict(state='warning', message=str(e))) self._doOsmosisFromSourceUnsafe(destination)
def install(targetDevice, destination): try: chrootScript = 'grub2-install %s && grub2-mkconfig > /boot/grub2/grub.cfg' % targetDevice sh.run("/usr/sbin/busybox chroot %s sh -c '%s'" % (destination, chrootScript)) return '/boot/grub2/grub.cfg' except: logging.exception("Failed to run grub2-install or grub2-mkconfig. Is the dest rootfs a debian-like?") logging.warning("Trying to run grub-install and grub-mkconfig instead") chrootScript = 'grub-install %s && grub-mkconfig > /boot/grub/grub.cfg' % targetDevice sh.run("/usr/sbin/busybox chroot %s sh -c '%s'" % (destination, chrootScript)) return '/boot/grub/grub.cfg'
def verify(self): if not self._findMismatch(): print "Partition table already set up" sh.run("lvm pvscan --cache %s2" % self._device) sh.run("lvm vgchange --activate y %s" % self.VOLUME_GROUP) sh.run("lvm vgscan --mknodes") print "/dev/inaugurator:" try: print sh.run("busybox find /dev/inaugurator") except Exception as e: print "Unable: %s" % e return self._create() for retry in xrange(5): mismatch = self._findMismatch() if mismatch is None: return else: print "Partition table not correct even after %d retries: '%s'" % ( retry, mismatch) time.sleep(0.2) print "Found Partition Table:", self.parsePartitionTable() try: print "Found LVM physical:", self.parseLVMPhysicalVolume() except: print "Can't get physical LVM" try: print "Found LVM logical:", self.parseLVMLogicalVolume() except: print "Can't get logical LVM" print "Mismatch:", self._findMismatch() raise Exception("Created partition table isn't as expected")
def disableNCQ(cls): devices = cls._getSSDDeviceNames() if not devices: logging.info('Did not find any non-rotational storage devices on which to disable NCQ.') return logging.info('Disabling NCQ for the following SSD devices: {}...'.format(devices)) for device in devices: try: queueDepthPath = '/sys/block/{}/device/queue_depth'.format(device) logging.info(sh.run('busybox echo 1 > {}'.format(queueDepthPath))) logging.info(sh.run('busybox echo "{} is now:" '.format(queueDepthPath))) logging.info(sh.run('busybox cat {}'.format(queueDepthPath))) except: logging.info(traceback.format_exc())
def eraseEverything(self): try: sh.run("busybox rm -fr %s/*" % self._objectStore.root()) except Exception as e: try: ''' running this command again some times helps to clean the disk. for some reason busybox prompt of failure to remove some files, its unclear why, seems like a bug in busybox: http://lists.busybox.net/pipermail/busybox/2015-August/083233.html ''' sh.run("busybox rm -fr %s/*" % self._objectStore.root()) except: pass raise e
def install(targetDevice, destination): try: chrootScript = 'grub2-install %s && grub2-mkconfig > /boot/grub2/grub.cfg' % targetDevice sh.run("/usr/sbin/busybox chroot %s sh -c '%s'" % (destination, chrootScript)) return '/boot/grub2/grub.cfg' except: logging.exception( "Failed to run grub2-install or grub2-mkconfig. Is the dest rootfs a debian-like?" ) logging.warning("Trying to run grub-install and grub-mkconfig instead") chrootScript = 'grub-install %s && grub-mkconfig > /boot/grub/grub.cfg' % targetDevice sh.run("/usr/sbin/busybox chroot %s sh -c '%s'" % (destination, chrootScript)) return '/boot/grub/grub.cfg'
def get_network(): try: r = sh.run('lshw -c network -json') return _lshw_json_fix(r) except Exception as e: return {'error': e.message}
def _interfacesTable(self): REGEX = re.compile( r'\d+:\s+([^:]+):\s+.*\s+link/ether\s+((?:[a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2})' ) ipOutput = sh.run("/usr/sbin/ip -o link") return { mac.lower(): interface for interface, mac in REGEX.findall(ipOutput) }
def get_nvme_list(): def load_nvme_devices(): sh.run("mdev -s") try: load_nvme_devices() r = sh.run("nvme list -o json") return json.loads(r) except Exception as e: return {'error': e.message}
def _createBootAndInstallGrub(self, destination): with self._mountOp.mountBoot() as bootDestination: sh.run("rsync -rlpgDS --delete-before %s/boot/ %s/" % (destination, bootDestination)) with self._mountOp.mountBootInsideRoot(): serialDevices = self._getSerialDevices() if serialDevices: logging.info("Overriding GRUB2 user settings to set serial devices to '%(devices)s'...", dict(devices=serialDevices)) grub.setSerialDevices(serialDevices, destination) else: logging.warn("a 'console' argument was not given. Cannot tell which serial device to " "redirect the console output to (default values in the label will be used).") logging.info("Installing GRUB2...") grub.install(self._targetDevice, destination) logging.info("Reading newly generated GRUB2 configuration file for later use...") grubConfigFilename = os.path.join(destination, "boot", "grub2", "grub.cfg") with open(grubConfigFilename, "r") as grubConfigFile: self._grubConfig = grubConfigFile.read()
def parsePartitionTable(self): LINE = re.compile( r"(/\S+) : start=\s*\d+, size=\s*(\d+), Id=\s*([0-9a-fA-F]+)") lines = LINE.findall(sh.run("sfdisk --dump %s" % self._device)) return [ dict(device=device, sizeMB=int(size) * 512 / 1024 / 1024, id=int(id, 16)) for device, size, id in lines if int(size) > 0 ]
def parseLVMLogicalVolume(cls, label): fields = cls._fieldsOfLastTableRow( sh.run("lvm lvdisplay --units m --columns /dev/%s/%s" % (cls.VOLUME_GROUP, label))) assert fields[ 0] == label, "Invalid columns output from lvdisplay: %s" % fields assert fields[3].endswith("m") return dict(volumeGroup=fields[1], sizeMB=int(re.match(r"\d+", fields[3]).group(0)))
def _findDeviceUsingExpectedLabel(self): cmd = "/usr/sbin/busybox findfs LABEL=%s" % (self._expectedLabel,) try: content = sh.run(cmd) except: raise Exception("Couldn't find device with '%s' label" % (self._expectedLabel,)) device = [line for line in content.split('\n') if line.startswith('/dev/')] if len(device) != 1: raise Exception("Error parsing findfs output: %s" % content) return device[0]
def _findDevice(self): sh.run("busybox modprobe sr_mod") sh.run("busybox modprobe isofs") # The following is needed for virtual CDROMs sh.run("busybox modprobe usb_storage") for i in xrange(10): try: return self._findDeviceOnce() except: time.sleep(1) sh.run("/usr/sbin/busybox mdev -s") return self._findDeviceOnce()
def get_cpus(): try: r = sh.run("lscpu --json") d = json.loads(r) ret = dict() for prop in d.get('lscpu'): ret.update({prop['field'].strip(':').strip('(s)'): prop['data']}) return ret except Exception as e: return {'error': e.message}
def mountBoot(self): self._correctEXT4Errors(self._bootPartition) sh.run("/usr/sbin/busybox mkdir -p %s" % self._BOOT_MOUNT_POINT) sh.run("/usr/sbin/busybox mount -t ext4 %s %s" % (self._bootPartition, self._BOOT_MOUNT_POINT)) yield self._BOOT_MOUNT_POINT sh.run("/usr/sbin/busybox umount %s" % self._BOOT_MOUNT_POINT)
def mountRoot(self): self._correctEXT4Errors(self._rootPartition) sh.run("/usr/sbin/busybox mkdir -p %s" % self._ROOT_MOUNT_POINT) sh.run("/usr/sbin/busybox mount -t ext4 -o noatime,data=writeback %s %s" % ( self._rootPartition, self._ROOT_MOUNT_POINT)) yield self._ROOT_MOUNT_POINT sh.run("/usr/sbin/busybox umount %s" % self._ROOT_MOUNT_POINT)
def mount(self): os.makedirs(self._MOUNT_POINT) sh.run("busybox modprobe vfat") sh.run("/usr/sbin/busybox mount -t vfat -o ro %s %s" % ( self._partiton, self._MOUNT_POINT)) yield self._MOUNT_POINT sh.run("/usr/sbin/busybox umount %s" % self._MOUNT_POINT)
def mount(self): os.makedirs(self._MOUNT_POINT) sh.run("busybox modprobe vfat") sh.run("/usr/sbin/busybox mount -t vfat -o ro %s %s" % (self._partiton, self._MOUNT_POINT)) yield self._MOUNT_POINT sh.run("/usr/sbin/busybox umount %s" % self._MOUNT_POINT)
def _getDevicesLabeledAsBoot(self): output = sh.run("blkid") print "blkid output:\n" print output for line in output.splitlines(): line = line.strip() parts = line.split(":", 1) if len(parts) != 2: continue device, data = parts if " LABEL=\"BOOT\"" in data: device = device.strip() yield device
def installInaugurator(device, mountPoint): INAUGURATOR_KERNEL = "/usr/share/inaugurator/inaugurator.vmlinuz" INAUGURATOR_INITRD = "/usr/share/inaugurator/inaugurator.fat.initrd.img" shutil.copy(INAUGURATOR_KERNEL, mountPoint) shutil.copy(INAUGURATOR_INITRD, mountPoint) installerExecutable = "grub2-install" try: sh.run("which %s" % installerExecutable) except: installerExecutable = "grub-install" sh.run("%s --target=i386-pc --boot-directory=%s/boot %s" % (installerExecutable, mountPoint, device)) inauguratorArguments = '--inauguratorSource=DOK --inauguratorChangeRootPassword=strato' grubCfg = "%s/boot/grub2/grub.cfg" % mountPoint if not os.path.isdir(os.path.dirname(grubCfg)): grubCfg = "%s/boot/grub/grub.cfg" % mountPoint with open(grubCfg, "w") as f: f.write('set timeout=1\n' 'set default=0\n' 'menuentry "Installer" {\n' ' linux /inaugurator.vmlinuz %s\n' ' initrd /inaugurator.fat.initrd.img\n' '}\n' % inauguratorArguments)
def disableNCQ(cls): devices = cls._getSSDDeviceNames() if not devices: logging.info( 'Did not find any non-rotational storage devices on which to disable NCQ.' ) return logging.info( 'Disabling NCQ for the following SSD devices: {}...'.format( devices)) for device in devices: try: queueDepthPath = '/sys/block/{}/device/queue_depth'.format( device) logging.info( sh.run('busybox echo 1 > {}'.format(queueDepthPath))) logging.info( sh.run( 'busybox echo "{} is now:" '.format(queueDepthPath))) logging.info(sh.run('busybox cat {}'.format(queueDepthPath))) except: logging.info(traceback.format_exc())
def _findDeviceUsingExpectedLabel(self): cmd = "/usr/sbin/busybox findfs LABEL=%s" % (self._expectedLabel, ) try: content = sh.run(cmd) except: raise Exception("Couldn't find device with '%s' label" % (self._expectedLabel, )) device = [ line for line in content.split('\n') if line.startswith('/dev/') ] if len(device) != 1: raise Exception("Error parsing findfs output: %s" % content) return device[0]
def _mount(self, device): if not os.path.isdir(self._MOUNT_POINT): os.makedirs(self._MOUNT_POINT) sh.run("busybox modprobe isofs") sh.run("/usr/sbin/busybox mount -t iso9660 -o ro %s %s" % ( device, self._MOUNT_POINT)) yield sh.run("/usr/sbin/busybox umount %s" % self._MOUNT_POINT)
def mountRoot(self): self._correctEXT4Errors(self._rootPartition) sh.run("/usr/sbin/busybox mkdir -p %s" % self._ROOT_MOUNT_POINT) sh.run( "/usr/sbin/busybox mount -t ext4 -o noatime,data=writeback %s %s" % (self._rootPartition, self._ROOT_MOUNT_POINT)) yield self._ROOT_MOUNT_POINT sh.run("/usr/sbin/busybox umount %s" % self._ROOT_MOUNT_POINT)
def _createBootAndInstallGrub(self, destination): with self._mountOp.mountBoot() as bootDestination: sh.run("rsync -rlpgDS --delete-before %s/boot/ %s/" % (destination, bootDestination)) with self._mountOp.mountBootInsideRoot(): if self._args.inauguratorExtraDataToGrubCmdLine != "": grub.changeGrubConfiguration( destination, data=self._args.inauguratorExtraDataToGrubCmdLine) if "rhgb silent" not in self._args.inauguratorExtraDataToGrubCmdLine: serialDevices = self._getSerialDevices() if serialDevices: logging.info( "Overriding GRUB2 user settings to set serial devices to '%(devices)s'...", dict(devices=serialDevices)) serialDevicesStr = " ".join([dev for dev in serialDevices]) grub.changeGrubConfiguration(destination, data=serialDevicesStr, parameter="console") else: logging.warn( "a 'console' argument was not given. Cannot tell which serial device to " "redirect the console output to (default values in the label will be used)" ) else: logging.info( "Removing all console parameters from command line") grub.changeGrubConfiguration(destination, data=None, parameter="console") logging.info("Installing GRUB2...") grubConfigPath = grub.install(self._targetDevice, destination) logging.info( "Reading newly generated GRUB2 configuration file for later use..." ) grubConfigPathInDest = destination + grubConfigPath with open(grubConfigPathInDest, "r") as grubConfigFile: self._grubConfig = grubConfigFile.read()
def parsePartitionTable(self): cmd = "parted -s -m %(device)s unit MB print" % dict(device=self._device) output = sh.run(cmd) logging.info("Output of parted: %(output)s" % dict(output=output)) lines = [line.strip() for line in output.split(";")] lines = [line for line in lines if line] partitionsLines = lines[2:] partitions = [dict(zip(("nr", "start", "end", "size", "fs", "name", "flags"), partitionLine.split(":"))) for partitionLine in partitionsLines] return [dict(device="%(device)s%(nr)s" % dict(device=self._device, nr=partition["nr"]), sizeMB=float(partition["size"].rstrip("MB")), fs=partition["fs"], flags=partition["flags"]) for partition in partitions]
def _validateLinkIsUp(self): logging.info("Waiting for the connection to actually be up by pinging %s..." % (self._gateway,)) linkIsUp = False for attemptIdx in xrange(self._NR_PING_ATTEMPTS): attemptNr = attemptIdx + 1 try: result = sh.run("busybox ping -w 1 -c 1 %s" % (self._gateway,)) linkIsUp = True logging.info("Ping attempt #%d succeeded." % (attemptNr,)) break except: logging.info("Ping attempt #%d failed." % (attemptNr,)) if not linkIsUp: raise Exception("No response from %s when trying to test if link was up" % (self._gateway,))
def getDevicesWithLabel(self, label): os.system("/usr/sbin/busybox mdev -s") time.sleep(1) output = sh.run("blkid") logging.info("blkid output:\n") logging.info(output) for line in output.splitlines(): line = line.strip() parts = line.split(":", 1) if len(parts) != 2: continue device, data = parts if " LABEL=\"%s\"" % label in data: device = device.strip() yield device
def _mountPartition(self, partitionPath, mountPoint, optimizePerformance=False): self._correctEXT4Errors(partitionPath) sh.run("/usr/sbin/busybox mkdir -p %s" % mountPoint) if optimizePerformance: options = "-o noatime,data=writeback" else: options = "" sh.run("/usr/sbin/busybox mount -t ext4 %s %s %s" % (options, partitionPath, mountPoint)) yield mountPoint sh.run("/usr/sbin/busybox umount %s" % mountPoint)
def get_lspci_lf(): ''' lspci indicate if exist and if lightfield is overpassed ''' try: r = sh.run('lspci|grep -iE "8764|1d9a"') lines = r.strip().split('\n') lf_pci_lst = {} for line in lines: port, val = line.split(".", 1) lf_pci_lst[str(port).strip()] = val[2:] return lf_pci_lst except CalledProcessError as e: return {'errcode': e.returncode, 'error': e.output} except Exception as e: return {'error': e.message}
def _findDeviceUsingExpectedLabel(self): for device in self._getAllDevices(): devicePartition = device + "1" if not os.path.exists(devicePartition): logging.info("Will not check device %s for installation since it does not" "contain any partitions." % (device,)) continue try: content = sh.run("dosfslabel %s" % (devicePartition,)) except Exception as ex: logging.warning("Failed running dosfslabel on device '%s': '%s'" % (devicePartition, str(ex))) continue if self._expectedLabel in content: return device raise Exception("Couldn't find device with '%s' label" % (self._expectedLabel,))
def mount(self): if os.path.exists(self._MOUNT_POINT): assert os.path.isdir(self._MOUNT_POINT) else: os.makedirs(self._MOUNT_POINT) sh.run("busybox modprobe vfat") sh.run("/usr/sbin/busybox mount -t vfat -o ro %s %s" % ( self._partiton, self._MOUNT_POINT)) try: yield self._MOUNT_POINT finally: sh.run("/usr/sbin/busybox umount %s" % self._MOUNT_POINT)
def verify(self): mismatch = self._findMismatch() if not mismatch: logging.info("Partition table already set up") lvmPartitionPath = self._getPartitionPath("lvm") sh.run("lvm pvscan --cache %s" % lvmPartitionPath) for lv in ["root", "swap"]: lv = "%s/%s" % (self.VOLUME_GROUP, lv) logging.info("Activating %s" % (lv, )) sh.run("lvm lvchange --activate y %s" % lv) sh.run("lvm vgscan --mknodes") logging.info("/dev/inaugurator:") try: logging.info(sh.run("busybox find /dev/inaugurator")) except Exception as e: logging.info("Unable: %s" % e) self._wipeOldInstallationsIfAllowed() return logging.warning("Found mismatch in partition layout - %s", mismatch) if not self._wipeOldInstallations: raise Exception( "Found mismatch in partition layout. we cannot continue without wiping data" ) self._create() for retry in xrange(5): mismatch = self._findMismatch() if mismatch is None: self._wipeOldInstallationsIfAllowed() return else: logging.info( "Partition table not correct even after %d retries: '%s'" % (retry, mismatch)) time.sleep(0.2) logging.info("Found Partition Table: %s", self.parsePartitionTable()) try: logging.info("Found LVM physical: %s", self.parseLVMPhysicalVolume()) except: logging.info("Can't get physical LVM") try: logging.info("Found LVM logical: %s", self.parseLVMLogicalVolume()) except: logging.info("Can't get logical LVM") logging.info("Mismatch: %s", self._findMismatch()) raise Exception("Created partition table isn't as expected")