Beispiel #1
0
    def get_all_remaining_geom(self, disk, device, start):
        # See if there is a part after this
        for part in disk.partitions:
            geom = part.geometry
            if self.part_offset < geom.start:
                length = geom.end - self.part_offset
                length -= parted.sizeToSectors(1, 'MB', device.sectorSize)
                return parted.Geometry(
                    device=device, start=start, length=length)

        length = device.getLength() - start
        length -= parted.sizeToSectors(1, 'MB', device.sectorSize)
        return parted.Geometry(device=device, start=start, length=length)
Beispiel #2
0
    def get_all_remaining_geom(self, disk, device, start):
        # See if there is a part after this
        for part in disk.partitions:
            geom = part.geometry
            if self.part_offset < geom.start:
                length = geom.end - self.part_offset
                length -= parted.sizeToSectors(1, 'MB', device.sectorSize)
                return parted.Geometry(
                    device=device, start=start, length=length)

        length = device.getLength() - start
        length -= parted.sizeToSectors(1, 'MB', device.sectorSize)
        return parted.Geometry(device=device, start=start, length=length)
Beispiel #3
0
def revertRepartition(device, partition, deltastart, deltaend, unit='MiB'):
    dev = parted.getDevice(device)
    disk = parted.newDisk(dev)
    targetPartition = disk.getPartitionByPath(device + partition)
    geometry = targetPartition.geometry
    geometry.start += parted.sizeToSectors(deltastart, unit, dev.sectorSize)
    geometry.end += parted.sizeToSectors(deltaend, unit, dev.sectorSize)
    disk.deletePartition(targetPartition)
    partition = parted.Partition(disk=disk,
                                 type=parted.PARTITION_NORMAL,
                                 geometry=geometry)
    disk.addPartition(partition=partition,
                      constraint=dev.optimalAlignedConstraint)
    disk.commit()
Beispiel #4
0
    def _parse_last_sector_expr(self, start, value, sector_size):
        """Parses fdisk(1)-style partition end exception"""
        import re

        # map fdisk units to PyParted ones
        known_units = {'K': 'KiB', 'M': 'MiB', 'G': 'GiB',
                       'KB': 'kB', 'MB': 'MB', 'GB': 'GB'}

        match = re.search('^\+(?P<num>\d+)(?P<unit>[KMG]?)$', value)
        if match:
            # num must be an integer; if not, raise ValueError
            num = int(match.group('num'))
            unit = match.group('unit')
            if not unit:
                # +sectors
                sector = start + num
                return sector
            elif unit in known_units.keys():
                # +size{K,M,G}
                sector = start + \
                    parted.sizeToSectors(num, known_units[unit], sector_size)
                return sector
        else:
            # must be an integer (sector); if not, raise ValueError
            sector = int(value)
            return sector
Beispiel #5
0
    def apply(self, disk, simulate):
        """ Create a partition with the given type... """
        try:
            if not disk:
                raise RuntimeError("Cannot create partition on empty disk!")
            length = parted.sizeToSectors(self.size, 'B',
                                          disk.device.sectorSize)
            geom = parted.Geometry(device=self.device,
                                   start=self.part_offset,
                                   length=length)

            # Don't run off the end of the disk ...
            geom_cmp = self.get_all_remaining_geom(disk, disk.device,
                                                   self.part_offset)

            if geom_cmp.length < geom.length or geom.length < 0:
                geom = geom_cmp

            if "LVM" in self.fstype:
                fs = None
            else:
                fs = parted.FileSystem(type=self.fstype, geometry=geom)
            p = parted.Partition(disk=disk,
                                 type=self.ptype,
                                 fs=fs,
                                 geometry=geom)

            disk.addPartition(p, parted.Constraint(device=self.device))
            self.part = p
            self.part_end = self.part_offset + length
        except Exception as e:
            self.set_errors(e)
            return False
        return True
Beispiel #6
0
def shrinkpart(part, size):
    dsk = part.disk
    dev = dsk.device
    print('Resizing partition...')
    # Create a new geometry
    newgeo = parted.Geometry(start=part.geometry.start,
                             length=parted.sizeToSectors(
                                 shrink_to, 'B', dev.sectorSize),
                             device=dev)
    logging.DEBUG(newgeo.__str__())
    # Create a new partition with our new geometry
    newpart = parted.Partition(disk=dsk,
                               type=parted.PARTITION_NORMAL,
                               geometry=newgeo)
    # Create a constraint that aligns our new geometry with the optimal alignment of the disk
    constraint = parted.Constraint(maxGeom=newgeo).intersect(
        dev.optimalAlignedConstraint)
    dsk.deletePartition(part)
    dsk.addPartition(partition=newpart, constraint=constraint)
    try:
        dsk.commit()
    except:
        pass

    return (newgeo.end + 1) * dev.sectorSize
Beispiel #7
0
    def apply(self, disk, simulate):
        """ Create a partition with the given type... """
        try:
            if not disk:
                raise RuntimeError("Cannot create partition on empty disk!")
            length = parted.sizeToSectors(
                self.size, 'B', disk.device.sectorSize)
            geom = parted.Geometry(
                device=self.device, start=self.part_offset, length=length)

            # Don't run off the end of the disk ...
            geom_cmp = self.get_all_remaining_geom(
                disk, disk.device, self.part_offset)

            if geom_cmp.length < geom.length or geom.length < 0:
                geom = geom_cmp

            fs = parted.FileSystem(type=self.fstype, geometry=geom)
            p = parted.Partition(
                disk=disk, type=self.ptype, fs=fs, geometry=geom)

            disk.addPartition(
                p,  parted.Constraint(device=self.device))
            self.part = p
            self.part_end = self.part_offset + length
        except Exception as e:
            self.set_errors(e)
            return False
        return True
def gpt_easyhandler(dev, disk, start, end, number):
    fs = "ext4"
    bios_grub = False
    for p in disk.partitions:
        if p.number != number and p.getFlag(parted.PARTITION_BIOS_GRUB):
            bios_grub = True
            break
    if bios_grub and number > 0:
        return [disk, number]

    if bios_grub == False:
        if number > 0:
            disk = rfparted.rmpart(disk, number)
        size = parted.sizeToSectors(1, "MB", 512)
        disk = rfparted.mkpart(dev, disk, "primary", start, size, end, "bios_grub")
        start = start + size + 1

    partnumber = [part.number for part in disk.partitions]
    disk = rfparted.mkpart(dev, disk, "primary", start, 0, end, fs)
    number = 0
    for p in disk.partitions:
        if p.number in partnumber:
            continue
        number = p.number
        break

    return [disk, number]
Beispiel #9
0
def shrinkpart(part, size):
    dsk = part.disk
    dev = dsk.device
    print('Resizing partition...')
    # Create a new geometry
    newgeo = parted.Geometry(start=part.geometry.start,
                             length=parted.sizeToSectors(
                                 size, 'B', dev.sectorSize),
                             device=dev)
    #    logging.DEBUG(newgeo.__str__())
    # Create a new partition with our new geometry
    newpart = parted.Partition(disk=dsk,
                               type=parted.PARTITION_NORMAL,
                               geometry=newgeo)
    # Create a constraint that aligns our new geometry with the optimal alignment of the disk
    constraint = parted.Constraint(maxGeom=newgeo).intersect(
        dev.optimalAlignedConstraint)
    dsk.deletePartition(part)
    dsk.addPartition(partition=newpart, constraint=constraint)
    # This exception gets raised even though dsk.commit() seems to do its job just fine.
    # I am definitely not a fan of doing this, but so be it.
    try:
        dsk.commit()
    except parted._ped.IOException:
        pass

    return (newgeo.end + 1) * dev.sectorSize
Beispiel #10
0
    def _parse_last_sector_expr(self, start, value, sector_size):
        """Parses fdisk(1)-style partition end exception"""
        import re

        # map fdisk units to PyParted ones
        known_units = {'K': 'KiB', 'M': 'MiB', 'G': 'GiB',
                       'KB': 'kB', 'MB': 'MB', 'GB': 'GB'}

        match = re.search('^\+(?P<num>\d+)(?P<unit>[KMG]?)$', value)
        if match:
            # num must be an integer; if not, raise ValueError
            num = int(match.group('num'))
            unit = match.group('unit')
            if not unit:
                # +sectors
                sector = start + num
                return sector
            elif unit in known_units.keys():
                # +size{K,M,G}
                sector = start + parted.sizeToSectors(num, known_units[unit], sector_size)
                return sector
        else:
            # must be an integer (sector); if not, raise ValueError
            sector = int(value)
            return sector
def partition(diskname, specs, force=False, check_mode=False):
    """
    Create requested partitions.
    Returns nr. of created partitions or 0 when the disk was already partitioned.
    """
    count = 0

    dev = parted.getDevice(diskname)
    try:
        disk = parted.newDisk(dev)
    except parted.DiskException:
        # unrecognizable format, treat as empty disk
        disk = None

    if disk and len(disk.partitions) > 0 and not force:
        print "skipping", diskname
        return 0

    # create new partition table, wiping all existing data
    disk = parted.freshDisk(dev, 'gpt')
    # calculate nr. of partitions of each size
    assign_space(dev.getSize(), specs)
    last_megabyte = 1
    for spec in specs:
        for _ in range(spec.count):
            # create the partition
            start = parted.sizeToSectors(last_megabyte, "MiB", dev.sectorSize)
            length = parted.sizeToSectors(spec.size, "MiB", dev.sectorSize)
            geo = parted.Geometry(device=dev, start=start, length=length)
            filesystem = parted.FileSystem(type='ext4', geometry=geo)
            part = parted.Partition(disk=disk,
                                    type=parted.PARTITION_NORMAL,
                                    fs=filesystem,
                                    geometry=geo)
            disk.addPartition(partition=part,
                              constraint=dev.optimalAlignedConstraint)
            last_megabyte += spec.size
            count += 1
    try:
        if not check_mode:
            disk.commit()
    except parted.IOException:
        # partitions have been written, but we have been unable to inform the
        # kernel of the change, probably because they are in use.
        # Ignore it and hope for the best...
        pass
    return count
def partition(diskname, specs, force=False, check_mode=False):
    """
    Create requested partitions.
    Returns nr. of created partitions or 0 when the disk was already partitioned.
    """
    count = 0

    dev = parted.getDevice(diskname)
    try:
        disk = parted.newDisk(dev)
    except parted.DiskException:
        # unrecognizable format, treat as empty disk
        disk = None

    if disk and len(disk.partitions) > 0 and not force:
        print "skipping", diskname
        return 0

    # create new partition table, wiping all existing data
    disk = parted.freshDisk(dev, 'gpt')
    # calculate nr. of partitions of each size
    assign_space(dev.getSize(), specs)
    last_megabyte = 1
    for spec in specs:
        for _ in range(spec.count):
            # create the partition
            start = parted.sizeToSectors(last_megabyte, "MiB", dev.sectorSize)
            length = parted.sizeToSectors(spec.size, "MiB", dev.sectorSize)
            geo = parted.Geometry(device=dev, start=start, length=length)
            filesystem = parted.FileSystem(type='ext4', geometry=geo)
            part = parted.Partition(
                disk=disk,
                type=parted.PARTITION_NORMAL,
                fs=filesystem,
                geometry=geo)
            disk.addPartition(partition=part, constraint=dev.optimalAlignedConstraint)
            last_megabyte += spec.size
            count += 1
    try:
        if not check_mode:
            disk.commit()
    except parted.IOException:
        # partitions have been written, but we have been unable to inform the
        # kernel of the change, probably because they are in use.
        # Ignore it and hope for the best...
        pass
    return count
Beispiel #13
0
def _compute_geometries(device):
    sectorSize = device.sectorSize
    esp = parted.Geometry(device=device,
                          start=parted.sizeToSectors(8, "MB", sectorSize),
                          length=parted.sizeToSectors(550, "MB", sectorSize))
    data = parted.Geometry(device=device,
                           start=esp.end + 1,
                           length=parted.sizeToSectors(PARTITION_SIZE_GB_DATA,
                                                       "GB", sectorSize))
    systemA = parted.Geometry(device=device,
                              start=data.end + 1,
                              length=parted.sizeToSectors(
                                  PARTITION_SIZE_GB_SYSTEM, "GB", sectorSize))
    systemB = parted.Geometry(device=device,
                              start=systemA.end + 1,
                              length=parted.sizeToSectors(
                                  PARTITION_SIZE_GB_SYSTEM, "GB", sectorSize))
    return {'esp': esp, 'data': data, 'systemA': systemA, 'systemB': systemB}
Beispiel #14
0
def raw_format(device_path, fstype, volume_label):

    do_umount(device_path)

    # First erase MBR and partition table , if any
    os.system("dd if=/dev/zero of=%s bs=512 count=1 >/dev/null 2>&1" %
              device_path)

    device = parted.getDevice(device_path)

    # Create a default partition set up
    disk = parted.freshDisk(device, 'msdos')
    disk.commit()
    regions = disk.getFreeSpaceRegions()

    if len(regions) > 0:
        #print "Build partition"
        # Define size
        region = regions[-1]
        start = parted.sizeToSectors(1, "MiB", device.sectorSize)
        #print "start %s" % start
        end = device.getLength() - start - 1024
        #print end

        # Alignment
        #cylinder = device.endSectorToCylinder(end)
        #end = device.endCylinderToSector(cylinder)
        #print end
        try:
            geometry = parted.Geometry(device=device, start=start, end=end)
        except:
            print "Geometry error - Can't create partition"
            sys.exit(5)

        # fstype
        fs = parted.FileSystem(type=fstype, geometry=geometry)

        # Create partition
        partition = parted.Partition(disk=disk,
                                     type=parted.PARTITION_NORMAL,
                                     geometry=geometry,
                                     fs=fs)
        constraint = parted.Constraint(exactGeom=geometry)
        disk.addPartition(partition=partition, constraint=constraint)
        disk.commit()

        # Format partition according to the fstype specified
        if fstype == "fat32":
            os.system("mkdosfs -F 32 -n \"%s\" %s >/dev/null 2>&1" %
                      (volume_label, partition.path))
        if fstype == "ntfs":
            os.system("mkntfs -f -L \"%s\" %s >/dev/null 2>&1" %
                      (volume_label, partition.path))
        elif fstype == "ext4":
            os.system("mkfs.ext4 -L \"%s\" %s >/dev/null 2>&1" %
                      (volume_label, partition.path))
    sys.exit(0)
Beispiel #15
0
def __make_root__(device, start=config["ROOT"]["START"],
                  end=config["ROOT"]["END"], fs=config["ROOT"]["fs"]):
    """Make root partition"""
    # __parted__(device, ["mkpart", name, fs, str(start), str(end)])
    size = sectors_to_size(device.length, device.sectorSize)
    try:
        if start[-1] == "%":
            start = int(start[:-1]) / 100
            start = int(size * start)
    except TypeError:
        pass
    try:
        if end[-1] == "%":
            end = int(end[:-1]) / 100
            end = int(size * end)
    except TypeError:
        pass
    disk = parted.Disk(device)
    start_geo = parted.geometry.Geometry(device=device,
                                         start=parted.sizeToSectors(common.real_number(start - 20),
                                                                    "MB",
                                                                    device.sectorSize),
                                         end=parted.sizeToSectors(start + 20,
                                                                  "MB",
                                                                  device.sectorSize))
    end_geo = parted.geometry.Geometry(device=device,
                                       start=parted.sizeToSectors(common.real_number(end - 40),
                                                                  "MB",
                                                                  device.sectorSize),
                                       end=parted.sizeToSectors(end, "MB",
                                                                device.sectorSize))
    min_size = parted.sizeToSectors(common.real_number((end - start) - 150), "MB",
                                    device.sectorSize)
    max_size = parted.sizeToSectors(common.real_number((end - start) + 150), "MB",
                                    device.sectorSize)
    const = parted.Constraint(startAlign=device.optimumAlignment,
                              endAlign=device.optimumAlignment,
                              startRange=start_geo, endRange=end_geo,
                              minSize=min_size,
                              maxSize=max_size)
    geometry = parted.geometry.Geometry(start=parted.sizeToSectors(start, "MB",
                                                                   device.sectorSize),
                                        length=parted.sizeToSectors((end - start),
                                                                    "MB",
                                                                    device.sectorSize),
                                        device=device)
    new_part = parted.Partition(disk=disk,
                                type=parted.PARTITION_NORMAL,
                                geometry=geometry)
    disk.addPartition(partition=new_part, constraint=const)
    disk.commit()
    time.sleep(0.1)
    __mkfs__(new_part.path, fs)
    return new_part.path
def premkpart(args, dev, disk):
    """Given args, device and disk needed to make parted. The format 
    of args: args = [part.type, start, end, filesystem.type]. Raise
    Exception given wrong args."""

    parttype = primary
    fstype = None
    if disk.type == 'msdos':
        parttype = args[0]
        del args[0]

    start = parted.sizeToSectors(int(args[0]), "MiB", 512)
    end = parted.sizeToSectors(int(args[1]), "MiB", 512)

    if not (parttype == "extended"):
        fstype = args[2]

    disk = rfparted.mkpart(dev, disk, parttype, start, end, fstype)
    return disk
Beispiel #17
0
def raw_format(device_path, fstype, volume_label, uid, gid):

    do_umount(device_path)

    # First erase MBR and partition table , if any
    os.system ("dd if=/dev/zero of=%s bs=512 count=1 >/dev/null 2>&1" % device_path)

    device = parted.getDevice(device_path)

    # Create a default partition set up
    disk = parted.freshDisk(device, 'msdos')
    try:
        disk.commit()
    except:
        # Unable to write the new partition
        print "Can't create partition. The device could be read-only."
        sys.exit(5)
    regions = disk.getFreeSpaceRegions()

    if len(regions) > 0:
        #print "Build partition"
        # Define size
        start = parted.sizeToSectors(1, "MiB", device.sectorSize)
        #print "start %s" % start
        end = device.getLength() - start - 1024
        #print end

        # Alignment
        #cylinder = device.endSectorToCylinder(end)
        #end = device.endCylinderToSector(cylinder)
        #print end
        try:
            geometry = parted.Geometry(device=device, start=start, end=end)
        except:
            print "Geometry error - Can't create partition"
            sys.exit(5)

        # fstype
        fs = parted.FileSystem(type=fstype, geometry=geometry)

        # Create partition
        partition = parted.Partition(disk=disk, type=parted.PARTITION_NORMAL, geometry=geometry, fs=fs)
        constraint = parted.Constraint(exactGeom=geometry)
        disk.addPartition(partition=partition, constraint=constraint)
        disk.commit()

        # Format partition according to the fstype specified
        if fstype == "fat32":
            os.system("mkdosfs -F 32 -n \"%s\" %s >/dev/null 2>&1" % (volume_label, partition.path))
        if fstype == "ntfs":
            os.system("mkntfs -f -L \"%s\" %s >/dev/null 2>&1" % (volume_label, partition.path))
        elif fstype == "ext4":
            os.system("mkfs.ext4 -E root_owner=%s:%s -L \"%s\" %s >/dev/null 2>&1" % (uid, gid, volume_label, partition.path))
    sys.exit(0)
Beispiel #18
0
def particion_pri(sdb, disk, size, tipo, fin):
    geometry1 = parted.Geometry(start=fin,
                                length=parted.sizeToSectors(
                                    size, 'MiB', sdb.sectorSize),
                                device=sdb)
    filesystem1 = parted.FileSystem(type=tipo, geometry=geometry1)
    partition1 = parted.Partition(disk=disk,
                                  type=parted.PARTITION_NORMAL,
                                  fs=filesystem1,
                                  geometry=geometry1)
    disk.addPartition(partition1, constraint=sdb.optimalAlignedConstraint)
    disk.commit()
    return partition1.geometry.end
Beispiel #19
0
    def bolumOlustur(self, alan, bolumTur):

        if bolumTur == parted.PARTITION_NORMAL or bolumTur == parted.PARTITION_EXTENDED:
            for bosBolum in self.disk.getFreeSpacePartitions():
                _bolum = self.bolumBilgi(bosBolum, "GB")
                if _bolum["tur"] == parted.PARTITION_FREESPACE:
                    maksBoyut = float(_bolum["boyut"])
        elif bolumTur == bolumTur == parted.PARTITION_LOGICAL:
            for bosBolum in self.disk.getFreeSpacePartitions():
                _bolum = self.bolumBilgi(bosBolum, "GB")
                if _bolum["tur"] == 5:
                    maksBoyut = float(_bolum["boyut"])

        alignment = self.aygit.optimalAlignedConstraint
        constraint = self.aygit.getConstraint()
        data = {
            'start': constraint.startAlign.alignUp(alan, alan.start),
            'end': constraint.endAlign.alignDown(alan, alan.end),
        }

        boyut, ok = QInputDialog().getDouble(self,
                                             'Bölüm oluştur',
                                             'GB cinsinden boyut:',
                                             min=0.001,
                                             value=1,
                                             max=maksBoyut,
                                             decimals=3)

        if ok:
            data["end"] = int(data["start"]) + int(
                parted.sizeToSectors(float(boyut), "GiB",
                                     self.aygit.sectorSize))
            try:
                geometry = parted.Geometry(device=self.aygit,
                                           start=int(data["start"]),
                                           end=int(data["end"]))
                partition = parted.Partition(
                    disk=self.disk,
                    type=bolumTur,
                    geometry=geometry,
                )

                self.disk.addPartition(partition=partition,
                                       constraint=constraint)
            except (parted.PartitionException, parted.GeometryException,
                    parted.CreateException) as e:
                # GeometryException accounts for incorrect start/end values (e.g. start < end),
                # CreateException is raised e.g. when the partition doesn't fit on the disk.
                # PartedException is a generic error (e.g. start/end values out of range)
                raise RuntimeError(e.message)
    def _get_root_fs_size_in(self, sector_size):
        proc_comm = ProcessCommunicator()
        self.command_executor.Execute(command_to_execute="dumpe2fs -h /dev/sda1",
                                      raise_exception_on_failure=True,
                                      communicator=proc_comm)

        root_fs_block_count = re.findall(r'Block count:\s*(\d+)', proc_comm.stdout)
        root_fs_block_size = re.findall(r'Block size:\s*(\d+)', proc_comm.stdout)

        if not root_fs_block_count or not root_fs_block_size:
            raise Exception("Error parsing dumpe2fs output, count={0}, size={1}".format(root_fs_block_count,
                                                                                        root_fs_block_size))

        root_fs_block_count = int(root_fs_block_count[0])
        root_fs_block_size = int(root_fs_block_size[0])
        root_fs_size = parted.sizeToSectors(root_fs_block_count * root_fs_block_size, 'B', sector_size)

        return root_fs_size
    def on_mkpart(self, devpath, parttype, start, size, end, fs):
        data = {}
        if self.has_disk(devpath):
            disk = self.disks[devpath]
            dev = parted.getDevice(devpath)
            partnumber = [ part.number for part in disk.partitions ]
            size = parted.sizeToSectors(size, "GB", 512)
            try:
                self.disks[devpath] = lib.rfparted.mkpart(dev, disk, parttype, start,size, end, fs)
                self.disks_tag[devpath] = True
            except Exception, e:
                data = self.error_handle(e,None)

            for p in disk.partitions:
                if p.number in partnumber:
                    continue
                data = self.error_handle(None,"add"+devpath+ str(p.number))
                break;
Beispiel #22
0
    def _get_root_fs_size_in(self, sector_size):
        proc_comm = ProcessCommunicator()
        self.command_executor.Execute(command_to_execute="dumpe2fs -h /dev/sda1",
                                      raise_exception_on_failure=True,
                                      communicator=proc_comm)

        root_fs_block_count = re.findall(r'Block count:\s*(\d+)', proc_comm.stdout)
        root_fs_block_size = re.findall(r'Block size:\s*(\d+)', proc_comm.stdout)

        if not root_fs_block_count or not root_fs_block_size:
            raise Exception("Error parsing dumpe2fs output, count={0}, size={1}".format(root_fs_block_count,
                                                                                        root_fs_block_size))

        root_fs_block_count = int(root_fs_block_count[0])
        root_fs_block_size = int(root_fs_block_size[0])
        root_fs_size = parted.sizeToSectors(root_fs_block_count * root_fs_block_size, 'B', sector_size)

        return root_fs_size
Beispiel #23
0
    def _get_root_fs_size_in(self, sector_size):
        proc_comm = ProcessCommunicator()

        attempt = 1
        while attempt < 10:
            dump_result = self.command_executor.Execute(
                command_to_execute="dumpe2fs -h {0}".format(
                    self.rootfs_block_device),
                raise_exception_on_failure=False,
                communicator=proc_comm)

            if dump_result == 0:
                break

            self.command_executor.Execute('systemctl restart systemd-udevd')
            self.command_executor.Execute(
                'systemctl restart systemd-timesyncd')
            self.command_executor.Execute('udevadm trigger')

            sleep(10)

            attempt += 1

        if not attempt < 10:
            return Exception("Could not dumpe2fs, stderr: \n{0}".format(
                proc_comm.stderr))

        root_fs_block_count = re.findall(r'Block count:\s*(\d+)',
                                         proc_comm.stdout)
        root_fs_block_size = re.findall(r'Block size:\s*(\d+)',
                                        proc_comm.stdout)

        if not root_fs_block_count or not root_fs_block_size:
            raise Exception(
                "Error parsing dumpe2fs output, count={0}, size={1}".format(
                    root_fs_block_count, root_fs_block_size))

        root_fs_block_count = int(root_fs_block_count[0])
        root_fs_block_size = int(root_fs_block_size[0])
        root_fs_size = parted.sizeToSectors(
            root_fs_block_count * root_fs_block_size, 'B', sector_size)

        return root_fs_size
Beispiel #24
0
def __make_efi__(device, start=config["EFI"]["START"],
                 end=config["EFI"]["END"]):
    """Make EFI partition"""
    disk = parted.Disk(device)
    start_geo = parted.geometry.Geometry(device=device,
                                         start=parted.sizeToSectors(start,
                                                                    "MB",
                                                                    device.sectorSize),
                                         end=parted.sizeToSectors(start + 10,
                                                                  "MB",
                                                                  device.sectorSize))
    end_geo = parted.geometry.Geometry(device=device,
                                       start=parted.sizeToSectors(common.real_number(end - 20),
                                                                  "MB",
                                                                  device.sectorSize),
                                       end=parted.sizeToSectors(end + 10,
                                                                "MB",
                                                                device.sectorSize))
    min_size = parted.sizeToSectors(common.real_number((end - start) - 25), "MB",
                                    device.sectorSize)
    max_size = parted.sizeToSectors(common.real_number((end - start) + 20), "MB",
                                    device.sectorSize)
    const = parted.Constraint(startAlign=device.optimumAlignment,
                              endAlign=device.optimumAlignment,
                              startRange=start_geo, endRange=end_geo,
                              minSize=min_size, maxSize=max_size)
    geometry = parted.geometry.Geometry(start=start,
                                        length=parted.sizeToSectors(end - start,
                                                                    "MB",
                                                                    device.sectorSize),
                                        device=device)
    new_part = parted.Partition(disk=disk,
                                type=parted.PARTITION_NORMAL,
                                geometry=geometry)
    new_part.setFlag(parted.PARTITION_BOOT)
    disk.addPartition(partition=new_part, constraint=const)
    disk.commit()
    time.sleep(0.1)
    __mkfs_fat__(new_part.path)
    return new_part.path
    def _get_root_fs_size_in(self, sector_size):
        proc_comm = ProcessCommunicator()

        attempt = 1
        while attempt < 10:
            dump_result = self.command_executor.Execute(command_to_execute="dumpe2fs -h {0}".format(self.rootfs_block_device),
                                                        raise_exception_on_failure=False,
                                                        communicator=proc_comm)

            if dump_result == 0:
                break

            self.command_executor.Execute('systemctl restart systemd-udevd')
            self.command_executor.Execute('systemctl restart systemd-timesyncd')
            self.command_executor.Execute('udevadm trigger')

            sleep(10)

            attempt += 1

        if not attempt < 10:
            return Exception("Could not dumpe2fs, stderr: \n{0}".format(proc_comm.stderr))


        root_fs_block_count = re.findall(r'Block count:\s*(\d+)', proc_comm.stdout)
        root_fs_block_size = re.findall(r'Block size:\s*(\d+)', proc_comm.stdout)

        if not root_fs_block_count or not root_fs_block_size:
            raise Exception("Error parsing dumpe2fs output, count={0}, size={1}".format(root_fs_block_count,
                                                                                        root_fs_block_size))

        root_fs_block_count = int(root_fs_block_count[0])
        root_fs_block_size = int(root_fs_block_size[0])
        root_fs_size = parted.sizeToSectors(root_fs_block_count * root_fs_block_size, 'B', sector_size)

        return root_fs_size
    def enter(self):
        if not self.should_enter():
            return

        self.context.logger.log("Entering split_root_partition state")

        device = parted.getDevice('/dev/sda')
        disk = parted.newDisk(device)

        original_root_fs_size = self._get_root_fs_size_in(device.sectorSize)
        self.context.logger.log("Original root filesystem size (sectors): {0}".format(original_root_fs_size))

        desired_boot_partition_size = parted.sizeToSectors(256, 'MiB', device.sectorSize)
        self.context.logger.log("Desired boot partition size (sectors): {0}".format(desired_boot_partition_size))
      
        desired_root_fs_size = original_root_fs_size - desired_boot_partition_size
        self.context.logger.log("Desired root filesystem size (sectors): {0}".format(desired_root_fs_size))

        self.command_executor.Execute("resize2fs /dev/sda1 {0}s".format(desired_root_fs_size), True)

        resized_root_fs_size = self._get_root_fs_size_in(device.sectorSize)

        self.context.logger.log("Resized root filesystem size (sectors): {0}".format(resized_root_fs_size))

        if not desired_root_fs_size == resized_root_fs_size:
            raise Exception("resize2fs failed, desired: {0}, resized: {1}".format(desired_root_fs_size,
                                                                                  resized_root_fs_size))

        self.context.logger.log("Root filesystem resized successfully")

        root_partition = disk.partitions[0]

        original_root_partition_start = root_partition.geometry.start
        original_root_partition_end = root_partition.geometry.end

        self.context.logger.log("Original root partition start (sectors): {0}".format(original_root_partition_start))
        self.context.logger.log("Original root partition end (sectors): {0}".format(original_root_partition_end))

        desired_root_partition_start = original_root_partition_start
        desired_root_partition_end = original_root_partition_end - desired_boot_partition_size
        desired_root_partition_size = desired_root_partition_end - desired_root_partition_start

        self.context.logger.log("Desired root partition start (sectors): {0}".format(desired_root_partition_start))
        self.context.logger.log("Desired root partition end (sectors): {0}".format(desired_root_partition_end))
        self.context.logger.log("Desired root partition size (sectors): {0}".format(desired_root_partition_size))

        desired_root_partition_geometry = parted.Geometry(device=device,
                                                          start=desired_root_partition_start,
                                                          length=desired_root_partition_size)
        root_partition_constraint = parted.Constraint(exactGeom=desired_root_partition_geometry)
        disk.setPartitionGeometry(partition=root_partition,
                                  constraint=root_partition_constraint,
                                  start=desired_root_partition_start,
                                  end=desired_root_partition_end)

        desired_boot_partition_start = disk.getFreeSpaceRegions()[1].start
        desired_boot_partition_end = disk.getFreeSpaceRegions()[1].end
        desired_boot_partition_size = disk.getFreeSpaceRegions()[1].length

        self.context.logger.log("Desired boot partition start (sectors): {0}".format(desired_boot_partition_start))
        self.context.logger.log("Desired boot partition end (sectors): {0}".format(desired_boot_partition_end))

        desired_boot_partition_geometry = parted.Geometry(device=device,
                                                          start=desired_boot_partition_start,
                                                          length=desired_boot_partition_size)
        boot_partition_constraint = parted.Constraint(exactGeom=desired_boot_partition_geometry)
        desired_boot_partition = parted.Partition(disk=disk,
                                                  type=parted.PARTITION_NORMAL,
                                                  geometry=desired_boot_partition_geometry)

        disk.addPartition(partition=desired_boot_partition, constraint=boot_partition_constraint)

        disk.commit()

        probed_root_fs = parted.probeFileSystem(disk.partitions[0].geometry)
        if not probed_root_fs == 'ext4':
            raise Exception("Probed root fs is not ext4")

        disk.partitions[1].setFlag(parted.PARTITION_BOOT)

        disk.commit()
        
        self.command_executor.Execute("partprobe", True)
        self.command_executor.Execute("mkfs.ext2 /dev/sda2", True)
        
        boot_partition_uuid = self._get_uuid("/dev/sda2")

        # Move stuff from /oldroot/boot to new partition, make new partition mountable at the same spot
        self.command_executor.Execute("mount /dev/sda1 /oldroot", True)
        self.command_executor.Execute("mkdir /oldroot/memroot", True)
        self.command_executor.Execute("mount --make-rprivate /", True)
        self.command_executor.Execute("pivot_root /oldroot /oldroot/memroot", True)
        self.command_executor.ExecuteInBash("for i in dev proc sys; do mount --move /memroot/$i /$i; done", True)
        self.command_executor.Execute("mv /boot /boot.backup", True)
        self.command_executor.Execute("mkdir /boot", True)
        self._append_boot_partition_uuid_to_fstab(boot_partition_uuid)
        self.command_executor.Execute("cp /etc/fstab /memroot/etc/fstab", True)
        self.command_executor.Execute("mount /boot", True)
        self.command_executor.ExecuteInBash("mv /boot.backup/* /boot/", True)
        self.command_executor.Execute("rmdir /boot.backup", True)
        self.command_executor.Execute("mount --make-rprivate /", True)
        self.command_executor.Execute("pivot_root /memroot /memroot/oldroot", True)
        self.command_executor.Execute("rmdir /oldroot/memroot", True)
        self.command_executor.ExecuteInBash("for i in dev proc sys; do mount --move /oldroot/$i /$i; done", True)
        self.command_executor.Execute("systemctl restart rsyslog", True)
        self.command_executor.Execute("systemctl restart systemd-udevd", True)
        self.command_executor.Execute("systemctl restart walinuxagent", True)
        self.command_executor.Execute("umount /oldroot/boot", True)
        self.command_executor.Execute("umount /oldroot", True)
Beispiel #27
0
    def apply_disk_strategy(self, simulate):
        """ Attempt to apply the given disk strategy """
        strategy = self.info.strategy
        ops = strategy.get_operations()

        table_ops = [x for x in ops if isinstance(x, DiskOpCreateDisk)]
        resizes = [x for x in ops if isinstance(x, DiskOpResizeOS)]
        if len(table_ops) > 1:
            self.set_error_message("Wiping disk more than once, error")
            return False
        if len(resizes) > 1:
            self.set_error_message("Multiple resizes not supported")
            return False

        # Madman time: Go apply the operations. *Gulp*
        disk = strategy.disk
        if disk and simulate:
            disk = disk.duplicate()

        part_offset = 0
        part_step = parted.sizeToSectors(16, 'kB', strategy.device.sectorSize)
        if disk:
            # Start at the very beginning of the disk, we don't
            # support free-space installation
            part_offset = disk.getFirstPartition().geometry.end + part_step

        for op in ops:
            self.set_display_string(op.describe())
            op.set_part_offset(part_offset)
            if not op.apply(disk, simulate):
                er = op.get_errors()
                if not er:
                    er = "Failed to apply operation: {}".format(op.describe())
                self.set_error_message(er)
                return False
            # If it created a disk, go use it.
            if isinstance(op, DiskOpCreateDisk):
                disk = op.disk
                if not strategy.disk:
                    strategy.disk = disk
                # Now set the part offset
                part_offset = disk.getFirstPartition().geometry.end + part_step
            elif isinstance(op, DiskOpResizeOS):
                part_offset = op.new_part_off + part_step
            elif isinstance(op, DiskOpCreatePartition):
                # Push forward the offset
                part_offset = op.part_end + part_step

        if simulate:
            return True

        try:
            disk.commit()
        except Exception as e:
            self.set_error_message("Failed to update disk: {}".format(e))
            return False

        try:
            os.system("sync")
        except:
            pass

        # Post-process, format all the things
        for op in ops:
            if not isinstance(op, DiskOpCreatePartition):
                continue
            # Wait for device to show up!
            if not self.wait_disk(op):
                return False
            if not op.apply_format(disk):
                e = op.get_errors()
                self.set_error_message("Failed to apply format: {}".format(e))
                return False

        return True
Beispiel #28
0
    def create_partitions(self):
        """This method creates the partition table and the different partitions
    in the loopback device. It first read the device definition, then iterate
    the list of partitions.

    Device operation are done using the pyparted library.
    """
        #TODO cleanup method to remove loopback

        # Output current task to logs
        logging.info(
            "Creating the partitions in the image mounted in loopback")

        # Retrieve the partition type to create
        if Key.LABEL.value not in self.project.image[Key.DEVICES.value]:
            self.project.logging.warning(
                "Partition table label is not defined, defaulting to dos.")
            label = "msdos"
        else:
            label = self.project.image[Key.DEVICES.value][Key.LABEL.value]

        # Check that the value is in the list of valid values
        if label not in "aix" "amiga" "bsd" "dvh" "gpt" "loop" "mac" "msdos" "pc98" "sun":
            self.project.logging.critical("Unknown partition label '" + label +
                                          "' . Aborting")
            exit(1)
        else:
            self.project.logging.debug("Using partition label '" + label + "'")

        # Retrieve the partition alignment
        if Key.ALIGNMENT.value not in self.project.image[Key.DEVICES.value]:
            self.project.logging.warning(
                "Partition alignment is not defined, defaulting to none.")
            alignment = "none"
        else:
            alignment = self.project.image[Key.DEVICES.value][
                Key.ALIGNMENT.value]

        # TODO : handle partition alignment

        # Check that the value is in the list of valid values
        # if alignment == "none":
        #   parted_alignment = None
        # elif alignment == "optimal":
        #   parted_alignment = parted.OPTIMAL
        # elif alignment == "cylinder":
        #   parted_alignment = cylinder
        # elif alignment == "minimal":
        #   parted_alignment = minimal
        # else:
        #   self.project.logging.critical("Unknown partition alignment '" + alignment + "' . Aborting")
        #   exit(1)

        self.project.logging.debug("Using partition alignment '" + alignment +
                                   "'")

        # Create the partition tabl on the device
        device = parted.getDevice(self.loopback_device)

        # Create a new disk object
        disk = parted.freshDisk(device, label)

        # Check that there is a partition table inthe configuration file. If not it will fail later,
        # thus better fail now.
        if Key.PARTITIONS.value not in self.project.image[Key.DEVICES.value]:
            self.project.logging.error(
                "Partition table is not defined, nothing to do. Aborting")
            exit(1)

        # Nox iterate the partitiontables and create them
        for partition in self.project.image[Key.DEVICES.value][
                Key.PARTITIONS.value]:

            # Retrieve the partition name
            if Key.NAME.value in partition:
                part_name = partition[Key.NAME.value]
            else:
                part_name = ""

            self.project.logging.debug("Partition name =>  '" + part_name +
                                       "'")

            # Retrieve the partition type
            if Key.TYPE.value in partition:
                part_type = partition[Key.TYPE.value]
            else:
                part_type = "primary"

            # Check that the partition type is valid and convert in parted "define"
            if part_type == "primary":
                parted_type = parted.PARTITION_NORMAL
            elif part_type == "extended":
                parted_type = parted.PARTITION_EXTENDED
            elif part_type == "logical":
                parted_type = parted.PARTITION_LOGICAL
            else:
                self.project.logging.critical("Unknown partition type '" +
                                              part_type + "' . Aborting")
                exit(1)

            self.project.logging.debug("Partition type =>  '" + part_type +
                                       "'")

            # Retrieve the partition size
            if Key.SIZE.value not in partition:
                self.project.logging.critical(
                    "Partition size is not defined. Aborting")
                exit(1)
            else:
                # Retrieve the value and control it is an integer
                try:
                    part_size = int(partition[Key.SIZE.value])
                except ValueError:
                    self.project.logging.critical(
                        "Partition size is not a number : " +
                        partition[Key.SIZE.value])
                    exit(1)

            self.project.logging.debug("Partition size => '" + str(part_size) +
                                       "'")

            # Retrieve the partition unit
            if Key.UNIT.value not in partition:
                self.project.logging.warning(
                    "Partition size unit is not defined, defaultig to MB.")
                part_unit = "MB"
            else:
                part_unit = partition[Key.UNIT.value]

            # Compute the block size to use based on the unit
            if part_unit not in "s" "B" "KB" "KiB" "MB" "MiB" "GB" "GiB" "TB" "TiB":
                self.project.logging.critical("Unknwon unit '" + part_unit +
                                              "' . Aborting")
                exit(1)
            else:
                self.project.logging.debug("Partition unit => '" + part_unit +
                                           "'")

            # Retrieve the partition start sector
            if Key.START_SECTOR.value not in partition:
                self.project.logging.warning(
                    "Partition start_sector is not defined. " +
                    "Using next available in sequence")
                part_start_sector = -1
            else:
                # Retrieve the value and control it is an integer
                try:
                    part_start_sector = int(partition[Key.START_SECTOR.value])
                except ValueError:
                    self.project.logging.critical(
                        "Partition start_sector is not a number : " +
                        partition[Key.START_SECTOR.value])
                    exit(1)

            self.project.logging.debug("Partition start sector => '" +
                                       str(part_start_sector) + "'")

            # Retrieve the partition flags
            if Key.FLAGS.value not in partition:
                self.project.logging.debug(
                    "Partition flags are not defined. Skipping...")
                part_flags = None
            else:
                part_flags = partition[Key.FLAGS.value]
                self.project.logging.debug("Partition flags => '" +
                                           part_flags + "'")

            # Retrieve the partition file system type
            if Key.FILESYSTEM.value not in partition:
                self.project.logging.debug(
                    "File system to create on the partition is not defined.")
                part_filesystem = None
            else:
                part_filesystem = partition[Key.FILESYSTEM.value].lower()
                # Check that the value is in the list of valid values
                if part_filesystem not in parted.fileSystemType:
                    self.project.logging.critical("Unknown filesystem type '" +
                                                  part_filesystem +
                                                  "' . Aborting")
                    exit(1)
                else:
                    self.project.logging.debug("Filesystem type =>  '" +
                                               part_filesystem + "'")

            # Retrieve the partition format flag
            if Key.FORMAT.value not in partition:
                self.project.logging.debug(
                    "File system format flag is not defined. Defaulting to True"
                )
                part_format = True
            else:
                part_format = partition[Key.FORMAT.value]
                self.project.logging.debug("File system format flag => '" +
                                           str(part_format) + "'")

            #
            # All information have been parsed,now let's create the partition in the loopback device
            #

            # Compute the sector count based on size and unit. Need for parted
            sector_count = parted.sizeToSectors(part_size, part_unit,
                                                device.sectorSize)

            # Compute the geometry for this device
            geometry = parted.Geometry(start=part_start_sector,
                                       length=sector_count,
                                       device=device)

            # Create the arted filesystem object
            filesys = parted.FileSystem(type=part_filesystem,
                                        geometry=geometry)

            # Create the partition object in the loopback device
            new_partition = parted.Partition(disk=disk,
                                             type=parted_type,
                                             geometry=geometry,
                                             fs=filesys)

            # Create the constraint object for alignment, etc.
            # constraint = parted.Constraint(startAlign=parted_alignment, endAlign=parted_alignment, \
            #              startRange=start, endRange=end, minSize=min_size, maxSize=max_size)
            constraint = parted.Constraint(exactGeom=new_partition.geometry)

            # Add the partition to the disk
            disk.addPartition(partition=new_partition, constraint=constraint)

        # Make modification persistent to disk
        disk.commit()
Beispiel #29
0
 def _kib_to_sectors(self, device, kib):
     return parted.sizeToSectors(kib, 'KiB', device.sectorSize)
Beispiel #30
0
    def apply_disk_strategy(self, simulate):
        """ Attempt to apply the given disk strategy """
        strategy = self.info.strategy
        ops = strategy.get_operations()

        table_ops = [x for x in ops if isinstance(x, DiskOpCreateDisk)]
        resizes = [x for x in ops if isinstance(x, DiskOpResizeOS)]
        if len(table_ops) > 1:
            self.set_error_message("Wiping disk more than once, error")
            return False
        if len(resizes) > 1:
            self.set_error_message("Multiple resizes not supported")
            return False

        # Madman time: Go apply the operations. *Gulp*
        disk = strategy.disk
        if disk and simulate:
            disk = disk.duplicate()

        part_offset = 0
        part_step = parted.sizeToSectors(1, 'MiB', strategy.device.sectorSize)
        if disk:
            # Start at the very beginning of the disk, we don't
            # support free-space installation
            part_offset = self.round_up_next_block(
                disk.getFirstPartition().geometry.end, part_step)
        for op in ops:
            self.set_display_string(op.describe())
            op.set_part_offset(part_offset)
            if not op.apply(disk, simulate):
                er = op.get_errors()
                if not er:
                    er = "Failed to apply operation: {}".format(op.describe())
                self.set_error_message(er)
                return False
            # If it created a disk, go use it.
            if isinstance(op, DiskOpCreateDisk):
                disk = op.disk
                if not strategy.disk:
                    strategy.disk = disk
                # Now set the part offset
                part_offset = self.round_up_next_block(
                    disk.getFirstPartition().geometry.end, part_step)
            elif isinstance(op, DiskOpResizeOS):
                part_offset = self.round_up_next_block(op.new_part_off,
                                                       part_step)
            elif isinstance(op, DiskOpCreatePartition):
                # Push forward the offset
                part_offset = self.round_up_next_block(op.part_end, part_step)

        if simulate:
            return True

        try:
            disk.commit()
        except Exception as e:
            self.set_error_message("Failed to update disk: {}".format(e))
            return False

        try:
            os.system("sync")
        except:
            pass

        # Post-process, format all the things
        post_types = [
            DiskOpCreatePartition,
            DiskOpCreateLogicalVolume,
            DiskOpCreateVolumeGroup,
            DiskOpFormatRootLate,
            DiskOpFormatSwapLate,
        ]

        for op in ops:
            is_type = False
            for t in post_types:
                if isinstance(op, t):
                    is_type = True
                    break
            if not is_type:
                continue
            # Wait for device to show up!
            if isinstance(op, DiskOpCreatePartition):
                if not self.wait_disk(op):
                    return False

            p = op.describe()
            self.set_display_string("Applying operation: {}".format(p))
            if not op.apply_format(disk):
                e = op.get_errors()
                self.set_error_message("Failed to apply format: {}".format(e))
                print(op.describe())
                return False

        return True
Beispiel #31
0
    def new(self):
        """Create a new partition from free space."""
        def create_primary():
            """Create a new primary partition."""
            return parted.PARTITION_NORMAL

        def create_logical():
            """Create a new logical partition."""
            return parted.PARTITION_LOGICAL

        def cancel():
            """Don't create a partition."""
            self.vis_opts = self.free_opts
            self.draw_options()
            return None

        def at_beginning():
            """Add partition at beginning of free space."""
            return "Beginning"

        def at_end():
            """Add partiton at end of free space."""
            return "End"

        opts1 = (("Primary", create_primary), ("Logical", create_logical),
                 ("Cancel", cancel))
        opts2 = (("Beginning", at_beginning), ("End", at_end),
                 ("Cancel", cancel))

        alignment = self.device.optimumAlignment
        sector_size = self.device.sectorSize
        free = self.__partition.geometry
        start = free.start
        end = free.end
        length = None

        # Determine what type of partition to create.
        part_type = check_free_space(self.__partition)
        if part_type == "Pri/Log":
            part_type = self.sub_menu(opts1)
            if part_type is None:
                return
        elif part_type == "Primary":
            part_type = parted.PARTITION_NORMAL
        else:
            part_type = parted.PARTITION_LOGICAL

        # Determine what length the new partition should be.
        text = "Size in {:}: ".format(self.unit)
        offset = self.center(text + str(free.getLength(self.unit)))
        self.window.hline(self.menu_line, 0, " ", self.window_width)
        self.window.addstr(self.menu_line, offset, text + str(free.getLength(self.unit)))
        self.window.move(self.menu_line, offset + len(text))
        key = self.window.getkey()
        if key != "\n":
            self.window.clrtoeol()
            editwin = curses.newwin(1, 20, self.menu_line, offset + len(text))
            editwin.addstr(key)
            textbox = curses.textpad.Textbox(editwin)
            accept_bs = lambda key: curses.KEY_BACKSPACE if key == 127 else key
            try:
                length = float(textbox.edit(accept_bs))
                if self.unit != "sectors":
                    length = parted.sizeToSectors(length, self.unit, sector_size)
                else:
                    length = int(length)
            except Exception as e:
                self.refresh_menu()
                self.draw_info("ERROR: {:}".format(e))
                return

        # Determine whether the partition should be placed at the beginning or end
        # of the free space, and adjust the start/end locations accordingly.
        if length and length < free.length:
            location = self.sub_menu(opts2)
            if location == "Beginning":
                end = start + length
            elif location == "End":
                start = end - length
            else:
                return

        try:
            # Create or extend an extended partition to hold the logical one.
            if part_type == parted.PARTITION_LOGICAL:
                grow_ext(self.__partition)

            if not alignment.isAligned(free, start):
                start = alignment.alignDown(free, start)
            if not alignment.isAligned(free, end):
                end = alignment.alignUp(free, end)

            free = parted.Geometry(self.device, start, end = end)
            max_length = self.disk.maxPartitionLength

            if max_length and max_length < free.length:
                self.draw_info("ERROR: partition size too large")
                return

            part = parted.Partition(self.disk, part_type, geometry = free)
            constraint = parted.Constraint(exactGeom = free)
            self.disk.addPartition(part, constraint)

        except Exception as e:
            if part_type == parted.PARTITION_LOGICAL:
                self.disk.minimizeExtendedPartition()
            self.refresh_menu()
            self.draw_info("ERROR: {:}".format(e))
            return

        if part_type == parted.PARTITION_LOGICAL:
            self.disk.minimizeExtendedPartition()
        self.refresh_menu()
def __make_root__(device,
                  start=config["ROOT"]["START"],
                  end=config["ROOT"]["END"],
                  fs=config["ROOT"]["fs"]):
    """Make root partition"""
    # __parted__(device, ["mkpart", name, fs, str(start), str(end)])
    size = sectors_to_size(device.length, device.sectorSize)
    try:
        if start[-1] == "%":
            start = int(start[:-1]) / 100
            start = int(size * start)
    except TypeError:
        pass
    try:
        if end[-1] == "%":
            end = int(end[:-1]) / 100
            end = int(size * end)
    except TypeError:
        pass
    disk = parted.Disk(device)
    s_geo = parted.geometry.Geometry(
        device=device,
        start=parted.sizeToSectors(common.real_number(start - 20), "MB",
                                   device.sectorSize),
        end=parted.sizeToSectors(start + 20, "MB", device.sectorSize))
    e_geo = parted.geometry.Geometry(
        device=device,
        start=parted.sizeToSectors(common.real_number(end - 100), "MB",
                                   device.sectorSize),
        end=parted.sizeToSectors(end, "MB", device.sectorSize))
    min_size = parted.sizeToSectors(common.real_number((end - start) - 250),
                                    "MB", device.sectorSize)
    max_size = parted.sizeToSectors(common.real_number((end - start) + 250),
                                    "MB", device.sectorSize)
    const = parted.Constraint(startAlign=device.optimumAlignment,
                              endAlign=device.optimumAlignment,
                              startRange=s_geo,
                              endRange=e_geo,
                              minSize=min_size,
                              maxSize=max_size)
    geo = parted.geometry.Geometry(start=parted.sizeToSectors(
        start, "MB", device.sectorSize),
                                   length=parted.sizeToSectors(
                                       (end - start), "MB", device.sectorSize),
                                   device=device)
    new_part = parted.Partition(disk=disk,
                                type=parted.PARTITION_NORMAL,
                                geometry=geo)
    try:
        disk.addPartition(partition=new_part, constraint=const)
    except parted._ped.PartitionException:
        # Simply use the geometry of the first free space region, if it is big enough
        data = disk.getFreeSpaceRegions()
        sizes = {}
        for each in data:
            sizes[each.getSize(unit="b")] = each
        sizes_sorted = sorted(sizes)
        made = False
        for each in range(len(sizes_sorted) - 1, -1, -1):
            if sizes[sizes_sorted[each]].getSize(
                    unit="b") >= get_min_root_size():
                s_geo = parted.geometry.Geometry(
                    device=device,
                    start=parted.sizeToSectors(
                        common.real_number(sizes[sizes_sorted[each]].start -
                                           2000), "MB", device.sectorSize),
                    end=parted.sizeToSectors(
                        sizes[sizes_sorted[each]].start + 2000, "MB",
                        device.sectorSize))
                e_geo = parted.geometry.Geometry(
                    device=device,
                    start=parted.sizeToSectors(
                        common.real_number(sizes[sizes_sorted[each]].end -
                                           2000), "MB", device.sectorSize),
                    end=parted.sizeToSectors(
                        sizes[sizes_sorted[each]].end + 2000, "MB",
                        device.sectorSize))
                min_size = parted.sizeToSectors(
                    common.real_number((sizes[sizes_sorted[each]].end -
                                        sizes[sizes_sorted[each]].start) -
                                       2000), "MB", device.sectorSize)
                max_size = parted.sizeToSectors(
                    common.real_number((sizes[sizes_sorted[each]].end -
                                        sizes[sizes_sorted[each]].start) +
                                       2000), "MB", device.sectorSize)
                const = parted.Constraint(startAlign=device.optimumAlignment,
                                          endAlign=device.optimumAlignment,
                                          startRange=s_geo,
                                          endRange=e_geo,
                                          minSize=min_size,
                                          maxSize=max_size)
                new_part = parted.Partition(disk=disk,
                                            type=parted.PARTITION_NORMAL,
                                            geometry=sizes[sizes_sorted[each]])
                try:
                    disk.addPartition(partition=new_part, constraint=const)
                except:
                    break
                made = True
                break
        if not made:
            common.eprint(
                "WAS NOT ABLE TO CREATE ROOT PARTITION. LIKELY NOT ENOUGH SPACE FOR ONE."
            )
            common.eprint("INSTALLATION WILL FAIL")

    disk.commit()
    time.sleep(0.1)
    __mkfs__(new_part.path, fs)
    return new_part.path
Beispiel #33
0
def partition(root, efi, home):
    """Partition drive 'root' for Linux installation

root: needs to be path to installation drive (i.e.: /dev/sda, /dev/nvme0n1)
efi: booleen indicated whether system was booted with UEFI
home: whether to make a home partition, or if one already exists
    Possible values:
        None, 'NULL':            Do not make a home partition, and one does not already exist
        'MAKE':                  Make a home partition on the installation drive
        (some partition path):   path to a partition to be used as home directory
"""
    common.eprint("\t###\tauto_partioner.py STARTED\t###\t")
    part1 = None
    part2 = None
    part3 = None
    device = parted.getDevice(root)
    try:
        disk = parted.Disk(device)
    except parted._ped.DiskLabelException:
        common.eprint("NO PARTITION TABLE EXISTS. MAKING NEW ONE . . .")
        disk = parted.freshDisk(device, "gpt")
    size = sectors_to_size(device.length, device.sectorSize) * 1000
    if home in ("NULL", "null", None, "MAKE"):
        common.eprint("DELETING PARTITIONS.")
        device.clobber()
        disk = parted.freshDisk(device, "gpt")
        disk.commit()
    else:
        common.eprint("HOME PARTITION EXISTS. NOT DELETING PARTITIONS.")
    if size == LIMITER:
        if efi:
            part1 = __make_efi__(device)
            part2 = __make_root__(device, end="100%")
        else:
            part1 = __make_root__(device, start="0%", end="100%")
            __make_root_boot__(device)
        common.eprint("\t###\tauto_partioner.py CLOSED\t###\t")
        return __generate_return_data__(home, efi, part1, part2, part3)
    # Handled 16GB drives
    # From here until 64GB drives, we want our root partition to be AT LEAST
    # 16GB
    if home == "MAKE":
        # If home == "MAKE", we KNOW there are no partitons because we made a
        # new partition table
        if size >= gb_to_bytes(config["mdswh"]):
            root_end = int((size * 0.35) / (1000 ** 2))
        else:
            root_end = config["min root size"]
        if (efi and (part1 is None)):
            part1 = __make_efi__(device)
            part2 = __make_root__(device, end=root_end)
            part3 = __make_home__(device, new_start=root_end)
        elif part1 is None:
            part1 = __make_root__(device, start="0%", end=root_end)
            __make_root_boot__(device)
            part2 = __make_home__(device, new_start=root_end)
        common.eprint("\t###\tauto_partioner.py CLOSED\t###\t")
        return __generate_return_data__(home, efi, part1, part2, part3)
    if home in ("NULL", "null", None):
        # If home == any possible 'null' value,
        # we KNOW there are no partitons because we made a
        # new partition table
        if efi:
            part1 = __make_efi__(device)
            part2 = __make_root__(device, end="100%")
        else:
            part1 = __make_root__(device, start="0%", end="100%")
            __make_root_boot__(device)
        common.eprint("\t###\tauto_partioner.py CLOSED\t###\t")
        return __generate_return_data__(home, efi, part1, part2, part3)
    # This one we need to figure out if the home partiton is on the drive
    # we are working on or elsewhere
    if "nvme" in home:
        check = home[:-2]
    else:
        check = home[:-1]
    if root == check:
        # It IS on the same drive. We need to figure out where at and work
        # around it
        # NOTE: WE NEED TO WORK IN MB ONLY IN THIS SECTION
        disk = parted.Disk(device)
        data = disk.getFreeSpaceRegions()
        sizes = {}
        for each in data:
            sizes[each.length] = each
        sizes_sorted = sorted(sizes)
        # Lets make some partitons!
        if efi:
            for each in sizes_sorted:
                if sizes[each].getSize() >= 200:
                    end = sizes[each].start + parted.sizeToSectors(200, "MB",
                                                                   device.sectorSize)
                    end = sectors_to_size(end, device.sectorSize)
                    part1 = __make_efi__(device, start=sizes[each].start,
                                         end=end)
                    part2 = __make_root__(device, start=end,
                                          end=sizes[each].end)
                    break
        else:
            for each in sizes_sorted:
                if sizes[each].getSize() >= 200:
                    part1 = __make_root__(device, start=sizes[each].start,
                                          end=sizes[each].end)
                    __make_root_boot__(device)
                    break
        common.eprint("\t###\tauto_partioner.py CLOSED\t###\t")
        return __generate_return_data__(home, efi, part1, part2, part3)
    else:
        # it's elsewhere. We're good.
        if efi:
            part1 = __make_efi__(device)
            part2 = __make_root__(device)
        else:
            part1 = __make_root__(device, start="0%", end="100%")
            __make_root_boot__(device)
    part3 = home
    # Figure out what parts are for what
    # Return that data as a dictonary
    common.eprint("\t###\tauto_partioner.py CLOSED\t###\t")
    return __generate_return_data__(home, efi, part1, part2, part3)
    def enter(self):
        if not self.should_enter():
            return

        self.context.logger.log("Entering split_root_partition state")

        device = parted.getDevice(self.rootfs_disk)
        disk = parted.Disk(device)

        original_root_fs_size = self._get_root_fs_size_in(device.sectorSize)
        self.context.logger.log("Original root filesystem size (sectors): {0}".format(original_root_fs_size))

        desired_boot_partition_size = parted.sizeToSectors(256, 'MiB', device.sectorSize)
        self.context.logger.log("Desired boot partition size (sectors): {0}".format(desired_boot_partition_size))
        
        root_partition = disk.partitions[0]

        original_root_partition_start = root_partition.geometry.start
        original_root_partition_end = root_partition.geometry.end

        self.context.logger.log("Original root partition start (sectors): {0}".format(original_root_partition_start))
        self.context.logger.log("Original root partition end (sectors): {0}".format(original_root_partition_end))

        desired_root_partition_start = original_root_partition_start
        desired_root_partition_end = original_root_partition_end - desired_boot_partition_size
        desired_root_partition_size = desired_root_partition_end - desired_root_partition_start

        self.context.logger.log("Desired root partition start (sectors): {0}".format(desired_root_partition_start))
        self.context.logger.log("Desired root partition end (sectors): {0}".format(desired_root_partition_end))
        self.context.logger.log("Desired root partition size (sectors): {0}".format(desired_root_partition_size))
        
        self.context.logger.log("Resizing root filesystem")
        desired_root_fs_size = desired_root_partition_size
        self._resize_root_fs_to_sectors(desired_root_fs_size, device.sectorSize)

        desired_root_partition_geometry = parted.Geometry(device=device,
                                                          start=desired_root_partition_start,
                                                          length=desired_root_partition_size)
        root_partition_constraint = parted.Constraint(exactGeom=desired_root_partition_geometry)
        disk.setPartitionGeometry(partition=root_partition,
                                  constraint=root_partition_constraint,
                                  start=desired_root_partition_start,
                                  end=desired_root_partition_end)

        desired_boot_partition_start = disk.getFreeSpaceRegions()[1].start
        desired_boot_partition_end = disk.getFreeSpaceRegions()[1].end
        desired_boot_partition_size = disk.getFreeSpaceRegions()[1].length

        self.context.logger.log("Desired boot partition start (sectors): {0}".format(desired_boot_partition_start))
        self.context.logger.log("Desired boot partition end (sectors): {0}".format(desired_boot_partition_end))

        desired_boot_partition_geometry = parted.Geometry(device=device,
                                                          start=desired_boot_partition_start,
                                                          length=desired_boot_partition_size)
        boot_partition_constraint = parted.Constraint(exactGeom=desired_boot_partition_geometry)
        desired_boot_partition = parted.Partition(disk=disk,
                                                  type=parted.PARTITION_NORMAL,
                                                  geometry=desired_boot_partition_geometry)

        disk.addPartition(partition=desired_boot_partition, constraint=boot_partition_constraint)

        disk.commit()

        probed_root_fs = parted.probeFileSystem(disk.partitions[0].geometry)
        if not probed_root_fs == 'ext4':
            raise Exception("Probed root fs is not ext4")

        disk.partitions[1].setFlag(parted.PARTITION_BOOT)

        disk.commit()
        
        self.command_executor.Execute("partprobe", False)
        self.command_executor.Execute("mkfs.ext2 {0}".format(self.bootfs_block_device), True)
        
        boot_partition_uuid = self._get_uuid(self.bootfs_block_device)

        # Move stuff from /oldroot/boot to new partition, make new partition mountable at the same spot
        self.command_executor.Execute("mount {0} /oldroot".format(self.rootfs_block_device), True)
        self.command_executor.Execute("mkdir /oldroot/memroot", True)
        self.command_executor.Execute("mount --make-rprivate /", True)
        self.command_executor.Execute("pivot_root /oldroot /oldroot/memroot", True)
        self.command_executor.ExecuteInBash("for i in dev proc sys; do mount --move /memroot/$i /$i; done", True)
        self.command_executor.Execute("mv /boot /boot.backup", True)
        self.command_executor.Execute("mkdir /boot", True)
        self._append_boot_partition_uuid_to_fstab(boot_partition_uuid)
        self.command_executor.Execute("cp /etc/fstab /memroot/etc/fstab", True)
        self.command_executor.Execute("mount /boot", True)
        self.command_executor.ExecuteInBash("mv /boot.backup/* /boot/", True)
        self.command_executor.Execute("rmdir /boot.backup", True)
        self.command_executor.Execute("mount --make-rprivate /", True)
        self.command_executor.Execute("pivot_root /memroot /memroot/oldroot", True)
        self.command_executor.Execute("rmdir /oldroot/memroot", True)
        self.command_executor.ExecuteInBash("for i in dev proc sys; do mount --move /oldroot/$i /$i; done", True)
        self.command_executor.Execute("service rsyslog restart", True)
        self.command_executor.Execute("service udev restart", True)
        self.command_executor.Execute("umount /oldroot/boot", True)

        try:
            self.command_executor.Execute("umount /oldroot", True)
        except:
            self.context.logger.log("Could not unmount /oldroot, attempting to restart WALA and unmount again")

            self.should_exit()
            
            self.context.logger.log("Removing marker for UnmountOldrootState")
            os.unlink(os.path.join(self.context.encryption_environment.os_encryption_markers_path, 'UnmountOldrootState'))

            self.command_executor.Execute('at -f /restart-wala.sh now + 1 minutes', True)
            self.command_executor.Execute('service walinuxagent stop', True)
def fdhandler(dev, mem, disks, sysflag):
    DevEndSector = dev.getLength()  ##the last sector of the device
    Dsize = dev.getLength("GB")
    parttype = "primary"
    fs = "ext4"
    number = 0  ##record the number of the part created
    boot_number = 0  ##record the number of boot part

    disk = disks[dev.path]
    disk.deleteAllPartitions()
    disks[dev.path] = disk

    start = parted.sizeToSectors(0, "GB", 512)
    end = 0
    if disk.type == "gpt":
        number = number + 1
        size = parted.sizeToSectors(1, "MB", 512)
        disk = rfparted.mkpart(dev, disk, parttype, start, size, end, "bios_grub")
        start = start + size + 1

    if sysflag == "sony":
        number = number + 1
        fs = "ext3"
        size = parted.sizeToSectors(10, "GB", 512)
        disk = rfparted.mkpart(dev, disk, parttype, start, size, end, fs)
        start = start + size + 1

    if Dsize > 54:
        number = number + 1
        boot_number = number
        size = parted.sizeToSectors(50, "GB", 512)
        disk = rfparted.mkpart(dev, disk, parttype, start, size, end, fs)
        rfparted.setFlag(disk, number, "boot", True)
        start = start + size + 1
        number = number + 1
        size = parted.sizeToSectors(4, "GB", 512)
        disk = rfparted.mkpart(dev, disk, parttype, start, size, end, "linux-swap(v1)")
    elif Dsize > 10:
        if find_swap(disks) is False:
            number = number + 1
            size = parted.sizeToSectors(mem, "B", 512)
            disk = rfparted.mkpart(dev, disk, parttype, start, size, end, "linux-swap(v1)")
            start = start + size + 1
        if Dsize > 30:
            number = number + 1
            boot_number = number
            end = parted.sizeToSectors(30, "GB", 512)  ##rootsize = 30 - swap
            disk = rfparted.mkpart(dev, disk, parttype, start, 0, end, fs)
            start = end + 1
        number = number + 1
        if boot_number == 0:
            boot_number = number
        end = DevEndSector
        disk = rfparted.mkpart(dev, disk, parttype, start, 0, end, fs)
    elif Dsize >= 6:
        number = number + 1
        boot_number = number
        end = DevEndSector
        disk = rfparted.mkpart(dev, disk, parttype, start, 0, end, fs)
    else:
        raise Exception, "Error, select a disk of at least 6 GB ."
    return [disk, boot_number]
Beispiel #36
0
    def enter(self):
        if not self.should_enter():
            return

        self.context.logger.log("Entering split_root_partition state")

        device = parted.getDevice(self.rootfs_disk)
        disk = parted.Disk(device)

        original_root_fs_size = self._get_root_fs_size_in(device.sectorSize)
        self.context.logger.log(
            "Original root filesystem size (sectors): {0}".format(
                original_root_fs_size))

        desired_boot_partition_size = parted.sizeToSectors(
            256, 'MiB', device.sectorSize)
        self.context.logger.log(
            "Desired boot partition size (sectors): {0}".format(
                desired_boot_partition_size))

        root_partition = disk.partitions[0]

        original_root_partition_start = root_partition.geometry.start
        original_root_partition_end = root_partition.geometry.end

        self.context.logger.log(
            "Original root partition start (sectors): {0}".format(
                original_root_partition_start))
        self.context.logger.log(
            "Original root partition end (sectors): {0}".format(
                original_root_partition_end))

        desired_root_partition_start = original_root_partition_start
        desired_root_partition_end = original_root_partition_end - desired_boot_partition_size
        desired_root_partition_size = desired_root_partition_end - desired_root_partition_start

        self.context.logger.log(
            "Desired root partition start (sectors): {0}".format(
                desired_root_partition_start))
        self.context.logger.log(
            "Desired root partition end (sectors): {0}".format(
                desired_root_partition_end))
        self.context.logger.log(
            "Desired root partition size (sectors): {0}".format(
                desired_root_partition_size))

        self.context.logger.log("Resizing root filesystem")
        desired_root_fs_size = desired_root_partition_size
        self._resize_root_fs_to_sectors(desired_root_fs_size,
                                        device.sectorSize)

        desired_root_partition_geometry = parted.Geometry(
            device=device,
            start=desired_root_partition_start,
            length=desired_root_partition_size)
        root_partition_constraint = parted.Constraint(
            exactGeom=desired_root_partition_geometry)
        disk.setPartitionGeometry(partition=root_partition,
                                  constraint=root_partition_constraint,
                                  start=desired_root_partition_start,
                                  end=desired_root_partition_end)

        desired_boot_partition_start = disk.getFreeSpaceRegions()[1].start
        desired_boot_partition_end = disk.getFreeSpaceRegions()[1].end
        desired_boot_partition_size = disk.getFreeSpaceRegions()[1].length

        self.context.logger.log(
            "Desired boot partition start (sectors): {0}".format(
                desired_boot_partition_start))
        self.context.logger.log(
            "Desired boot partition end (sectors): {0}".format(
                desired_boot_partition_end))

        desired_boot_partition_geometry = parted.Geometry(
            device=device,
            start=desired_boot_partition_start,
            length=desired_boot_partition_size)
        boot_partition_constraint = parted.Constraint(
            exactGeom=desired_boot_partition_geometry)
        desired_boot_partition = parted.Partition(
            disk=disk,
            type=parted.PARTITION_NORMAL,
            geometry=desired_boot_partition_geometry)

        disk.addPartition(partition=desired_boot_partition,
                          constraint=boot_partition_constraint)

        disk.commit()

        probed_root_fs = parted.probeFileSystem(disk.partitions[0].geometry)
        if not probed_root_fs == 'ext4':
            raise Exception("Probed root fs is not ext4")

        disk.partitions[1].setFlag(parted.PARTITION_BOOT)

        disk.commit()

        self.command_executor.Execute("partprobe", False)
        self.command_executor.Execute(
            "mkfs.ext2 {0}".format(self.bootfs_block_device), True)

        boot_partition_uuid = self._get_uuid(self.bootfs_block_device)

        # Move stuff from /oldroot/boot to new partition, make new partition mountable at the same spot
        self.command_executor.Execute(
            "mount {0} /oldroot".format(self.rootfs_block_device), True)
        self.command_executor.Execute("mkdir -p /boot", True)
        self.command_executor.Execute("cp /oldroot/etc/fstab /etc/fstab", True)
        self._append_boot_partition_uuid_to_fstab(boot_partition_uuid)
        self.command_executor.Execute("cp /etc/fstab /oldroot/etc/fstab", True)
        self.command_executor.Execute("mount /boot", True)
        self.command_executor.ExecuteInBash("mv /oldroot/boot/* /boot/", True)
        self.command_executor.Execute("umount /boot", True)
        self.command_executor.Execute("umount /oldroot", True)
Beispiel #37
0
    def editPartition(self, targetPartition, deltaStart, deltaEnd, fstype, fslabel, unit='MiB', formatPartition=True, safeDataThroughTmp=False):
        log.info("editPartition: Editing partition " + targetPartition.path + ". Start = Start + (" + str(deltaStart) + "). End = End + (" + str(deltaEnd) + ").")

        # Backup data to a directory in tmp
        if safeDataThroughTmp:
            # Make sure targetPartition is mounted in mountpoint
            if isMounted(targetPartition.path):
                mountpoint = getMountpoint(targetPartition.path)
            else:
                try:
                    mountpoint = tempfile.mkdtemp(prefix='resinhup-', dir='/tmp')
                except:
                    log.error("editPartition: Failed to create temporary mountpoint.")
                    return False
                if not mount(targetPartition.path, mountpoint):
                    log.error("editPartition: Failed to mount %s in %s." %(targetPartition.path, mountpoint))
                    return False

            # Backup files to a directory in /tmp
            try:
                backupdir = tempfile.mkdtemp(prefix='resinhup-', dir='/tmp')
            except:
                log.error("editPartition: Failed to create temporary backup directory.")
                return False
            if not safeCopy(mountpoint, backupdir):
                log.error("editPartition: Could not backup files from %s to %s." %(mountpoint, backupdir))

        # Make sure that partition is not mounted
        if isMounted(targetPartition.path):
            if not umount(targetPartition.path):
                return False

        # Committing partition changes to OS needs udev running
        startUdevDaemon()

        # Calculate the new geometry
        geometry = targetPartition.geometry
        geometry.start += parted.sizeToSectors(deltaStart, unit, self.device.sectorSize)
        geometry.end += parted.sizeToSectors(deltaEnd, unit, self.device.sectorSize)

        # Destroy the partition and recreate it with the new geometry
        self.disk.deletePartition(targetPartition)
        filesystem = parted.FileSystem(type=fstype, geometry=geometry)
        partition = parted.Partition(disk=self.disk, type=parted.PARTITION_NORMAL, fs=filesystem, geometry=geometry)
        self.disk.addPartition(partition=partition, constraint=self.device.optimalAlignedConstraint)
        self.disk.commit()

        # Format filesystem
        if formatPartition:
            if (fstype == 'ext3') or (fstype == 'ext4'):
                if not formatEXT3(partition.path, fslabel):
                    log.error("movePartition: Could not format " + partition.path + " as ext3.")
                    return False
            elif fstype == 'fat32':
                if not formatVFAT(partition.path, fslabel):
                    log.error("movePartition: Could not format " + partition.path + " as vfat.")
                    return False
            else:
                log.error("movePartition: Format of " + fstype + " is not implemented.")
                return False

        # Restore data in targetPartition
        if safeDataThroughTmp:
            # Make sure targetPartition is mounted in mountpoint
            if isMounted(targetPartition.path):
                log.error("editPartition: Something is wrong. %s should not be mounted." % targetPartition.path)
                return False
            else:
                if not mount(targetPartition.path, mountpoint):
                    log.error("editPartition: Failed to mount %s in %s." %(targetPartition.path, mountpoint))
                    return False

            # Copy back the data
            if not safeCopy(backupdir, mountpoint, sync=True):
                log.error("editPartition: Could not restore files from %s to %s." %(backupdir, mountpoint))

            # Cleanup temporary backup files
            shutil.rmtree(backupdir)

        return True
Beispiel #38
0
 def runTest(self):
     self.assertRaises(SyntaxError, parted.sizeToSectors, 9, "yb", 1)
     self.assertEqual(int(parted.sizeToSectors(7777.0, "B", 512)),
                      parted.sizeToSectors(7777.0, "B", 512))
def partition(root, efi, home, raid_array):
    """Partition drive 'root' for Linux installation

root: needs to be path to installation drive (i.e.: /dev/sda, /dev/nvme0n1)
efi: booleen indicated whether system was booted with UEFI
home: whether to make a home partition, or if one already exists

Possible values:
  None, 'NULL':            Do not make a home partition, and one does not exist
  'MAKE':                  Make a home partition on the installation drive
  (some partition path):   path to a partition to be used as home directory
"""
    # Initial set up for partitioning
    common.eprint("\t###\tauto_partioner.py STARTED\t###\t")
    part1 = None
    part2 = None
    part3 = None
    if raid_array["raid_type"] not in (None, "OEM"):
        if raid_array["raid_type"].lower() == "raid0":
            raid_array["raid_type"] = 0
        elif raid_array["raid_type"].lower() == "raid1":
            raid_array["raid_type"] = 1
        elif raid_array["raid_type"].lower() == "raid10":
            raid_array["raid_type"] = 10
        for each in raid_array["disks"]:
            if each in ("1", "2"):
                if raid_array["disks"][each] is None:
                    # Invalid RAID array. Do not create.
                    raid_array["raid_type"] = None
    # We double check this to ensure we are working with valid RAID arrays
    if raid_array["raid_type"] is not None:
        disks = []
        for each in raid_array["disks"]:
            if raid_array["disks"][each] is not None:
                disks.append(raid_array["disks"][each])
        raid_array["disks"] = disks
    device = parted.getDevice(root)
    try:
        disk = parted.Disk(device)
    except parted._ped.DiskLabelException:
        common.eprint("NO PARTITION TABLE EXISTS. MAKING NEW ONE . . .")
        disk = parted.freshDisk(device, "gpt")
    # sectors_to_size() returns size in MBs, multiply by 1 million to convert to bytes
    size = sectors_to_size(device.length, device.sectorSize) * 1000000
    if ((home in ("NULL", "null", None, "MAKE"))
            and (raid_array["raid_type"] is None)):
        disk = clobber_disk(device)
    elif raid_array["raid_type"] is not None:
        disk = clobber_disk(device)
        common.eprint("CREATING RAID ARRAY")
        common.eprint(f"RAID TYPE: {raid_array['raid_type']}")
        if not make_raid_array(raid_array["disks"], raid_array["raid_type"]):
            common.eprint("INITIAL RAID ARRAY CREATION FAILED. FORCING . . .")
            if not make_raid_array(
                    raid_array["disks"], raid_array["raid_type"], force=True):
                common.eprint("FORCED RAID ARRAY CREATION FAILED. BAD DRIVE?")
                common.eprint("FALLING BACK TO NO HOME PARTITION.")
                home = None
    else:
        # we know there is a pre-existing home partition
        # determine if it is on the same drive and act accordingly
        home_drive = get_drive_path(home)
        if home_drive == root:
            common.eprint("HOME PARTITION EXISTS. NOT DELETING PARTITIONS.")
        else:
            disk = clobber_disk(device)
    if size <= LIMITER:
        if efi:
            part1 = __make_efi__(device)
            part2 = __make_root__(device, end="100%")
        else:
            part1 = __make_root__(device, start="0%", end="100%")
            __make_root_boot__(device)
        common.eprint("\t###\tauto_partioner.py CLOSED\t###\t")
        return __generate_return_data__(home, efi, part1, part2, part3)
    # Handled 16GB drives
    # From here until 64GB drives, we want our root partition to be AT LEAST
    # 16GB
    if home == "MAKE":
        # If home == "MAKE", we KNOW there are no partitons because we made a
        # new partition table
        if size >= gb_to_bytes(config["mdswh"]):
            root_end = int((size * 0.35) / (1000**2))
        else:
            root_end = get_min_root_size()
        if (efi and (part1 is None)):
            part1 = __make_efi__(device)
            part2 = __make_root__(device, end=root_end)
            part3 = __make_home__(device, new_start=root_end)
        elif part1 is None:
            part1 = __make_root__(device, start="0%", end=root_end)
            __make_root_boot__(device)
            part2 = __make_home__(device, new_start=root_end)
        common.eprint("\t###\tauto_partioner.py CLOSED\t###\t")
        return __generate_return_data__(home, efi, part1, part2, part3)
    if home in ("NULL", "null", None):
        # If home == any possible 'null' value,
        # we KNOW there are no partitons because we made a
        # new partition table
        if efi:
            part1 = __make_efi__(device)
            part2 = __make_root__(device, end="100%")
        else:
            part1 = __make_root__(device, start="0%", end="100%")
            __make_root_boot__(device)
        common.eprint("\t###\tauto_partioner.py CLOSED\t###\t")
        return __generate_return_data__(home, efi, part1, part2, part3)
    # This one we need to figure out if the home partiton is on the drive
    # we are working on or elsewhere
    if root == get_drive_path(home):
        # It IS on the same drive. We need to figure out where at and work
        # around it
        # NOTE: WE NEED TO WORK IN MB ONLY IN THIS SECTION
        disk = parted.Disk(device)
        data = disk.getFreeSpaceRegions()
        sizes = {}
        for each in data:
            sizes[each.length] = each
        sizes_sorted = sorted(sizes)
        # Lets make some partitons!
        if efi:
            for each in sizes_sorted:
                if sizes[each].getSize() >= 200:
                    end = sizes[each].start + parted.sizeToSectors(
                        200, "MB", device.sectorSize)
                    end = sectors_to_size(end, device.sectorSize)
                    part1 = __make_efi__(device,
                                         start=sizes[each].start,
                                         end=end)
                    part2 = __make_root__(device,
                                          start=end,
                                          end=sizes[each].end)
                    break
        else:
            for each in sizes_sorted:
                if sizes[each].getSize() >= 200:
                    part1 = __make_root__(device,
                                          start=sizes[each].start + 1,
                                          end=sizes[each].end - 1)
                    __make_root_boot__(device)
                    break
        common.eprint("\t###\tauto_partioner.py CLOSED\t###\t")
        return __generate_return_data__(home, efi, part1, part2, part3)
    # it's elsewhere. We're good.
    if efi:
        part1 = __make_efi__(device)
        part2 = __make_root__(device, end="100%")
    else:
        part1 = __make_root__(device, start="0%", end="100%")
        __make_root_boot__(device)
    part3 = home
    # Figure out what parts are for what
    # Return that data as a dictonary
    common.eprint("\t###\tauto_partioner.py CLOSED\t###\t")
    return __generate_return_data__(home, efi, part1, part2, part3)
Beispiel #40
0
    def partition_reset(self, dev: Dict[str, Any]):
        """
        Repartition the SD card from scratch
        """
        try:
            import parted
        except ModuleNotFoundError:
            raise Fail("please install python3-parted")

        device = parted.getDevice(dev["path"])

        device.clobber()
        disk = parted.freshDisk(device, "msdos")

        # Add 256M fat boot
        optimal = device.optimumAlignment
        constraint = parted.Constraint(
            startAlign=optimal,
            endAlign=optimal,
            startRange=parted.Geometry(
                device=device,
                start=parted.sizeToSectors(4, "MiB", device.sectorSize),
                end=parted.sizeToSectors(16, "MiB", device.sectorSize)),
            endRange=parted.Geometry(
                device=device,
                start=parted.sizeToSectors(256, "MiB", device.sectorSize),
                end=parted.sizeToSectors(512, "MiB", device.sectorSize)),
            minSize=parted.sizeToSectors(256, "MiB", device.sectorSize),
            maxSize=parted.sizeToSectors(260, "MiB", device.sectorSize))
        geometry = parted.Geometry(
            device,
            start=0,
            length=parted.sizeToSectors(256, "MiB", device.sectorSize),
        )
        geometry = constraint.solveNearest(geometry)
        boot = parted.Partition(
                disk=disk, type=parted.PARTITION_NORMAL, fs=parted.FileSystem(type='fat32', geometry=geometry),
                geometry=geometry)
        boot.setFlag(parted.PARTITION_LBA)
        disk.addPartition(partition=boot, constraint=constraint)

        # Add 4G ext4 rootfs
        constraint = parted.Constraint(
            startAlign=optimal,
            endAlign=optimal,
            startRange=parted.Geometry(
                device=device,
                start=geometry.end,
                end=geometry.end + parted.sizeToSectors(16, "MiB", device.sectorSize)),
            endRange=parted.Geometry(
                device=device,
                start=geometry.end + parted.sizeToSectors(4, "GiB", device.sectorSize),
                end=geometry.end + parted.sizeToSectors(4.2, "GiB", device.sectorSize)),
            minSize=parted.sizeToSectors(4, "GiB", device.sectorSize),
            maxSize=parted.sizeToSectors(4.2, "GiB", device.sectorSize))
        geometry = parted.Geometry(
            device,
            start=geometry.start,
            length=parted.sizeToSectors(4, "GiB", device.sectorSize),
        )
        geometry = constraint.solveNearest(geometry)
        rootfs = parted.Partition(
                disk=disk, type=parted.PARTITION_NORMAL, fs=parted.FileSystem(type='ext4', geometry=geometry),
                geometry=geometry)
        disk.addPartition(partition=rootfs, constraint=constraint)

        # Add media partition on the rest of the disk
        constraint = parted.Constraint(
            startAlign=optimal,
            endAlign=optimal,
            startRange=parted.Geometry(
                device=device,
                start=geometry.end,
                end=geometry.end + parted.sizeToSectors(16, "MiB", device.sectorSize)),
            endRange=parted.Geometry(
                device=device,
                start=geometry.end + parted.sizeToSectors(16, "MiB", device.sectorSize),
                end=disk.maxPartitionLength),
            minSize=parted.sizeToSectors(4, "GiB", device.sectorSize),
            maxSize=disk.maxPartitionLength)
        geometry = constraint.solveMax()
        # Create media partition
        media = parted.Partition(
                disk=disk, type=parted.PARTITION_NORMAL,
                geometry=geometry)
        disk.addPartition(partition=media, constraint=constraint)

        disk.commit()
        time.sleep(0.5)

        # Fix disk identifier to match what is in cmdline.txt
        with open(dev["path"], "r+b") as fd:
            buf = bytearray(512)
            fd.readinto(buf)
            buf[0x1B8] = 0x13
            buf[0x1B9] = 0x6e
            buf[0x1BA] = 0x58
            buf[0x1BB] = 0x6c
            fd.seek(0)
            fd.write(buf)
        time.sleep(0.5)

        # Format boot partition with 'boot' label
        run(["mkfs.fat", "-F", "32", "-n", "boot", disk.partitions[0].path])

        # Format rootfs partition with 'rootfs' label
        run(["mkfs.ext4", "-F", "-L", "rootfs", "-O", "^64bit,^huge_file,^metadata_csum", disk.partitions[1].path])

        # Format exfatfs partition with 'media' label
        run(["mkexfatfs", "-n", "media", disk.partitions[2].path])
    def enter(self):
        if not self.should_enter():
            return

        self.context.logger.log("Entering split_root_partition state")

        device = parted.getDevice(self.rootfs_disk)
        disk = parted.newDisk(device)

        original_root_fs_size = self._get_root_fs_size_in(device.sectorSize)
        self.context.logger.log("Original root filesystem size (sectors): {0}".format(original_root_fs_size))

        desired_boot_partition_size = parted.sizeToSectors(256, 'MiB', device.sectorSize)
        self.context.logger.log("Desired boot partition size (sectors): {0}".format(desired_boot_partition_size))

        desired_root_fs_size = int(original_root_fs_size - desired_boot_partition_size)
        self.context.logger.log("Desired root filesystem size (sectors): {0}".format(desired_root_fs_size))

        attempt = 1
        while attempt < 10:
            resize_result = self.command_executor.Execute("resize2fs {0} {1}s".format(self.rootfs_block_device, desired_root_fs_size))

            if resize_result == 0:
                break
            else:
                self.command_executor.Execute('systemctl restart systemd-udevd')
                self.command_executor.Execute('systemctl restart systemd-timesyncd')
                self.command_executor.Execute('udevadm trigger')

                sleep(10)

                attempt += 1

        resized_root_fs_size = self._get_root_fs_size_in(device.sectorSize)

        self.context.logger.log("Resized root filesystem size (sectors): {0}".format(resized_root_fs_size))

        if not desired_root_fs_size == resized_root_fs_size:
            raise Exception("resize2fs failed, desired: {0}, resized: {1}".format(desired_root_fs_size,
                                                                                  resized_root_fs_size))

        self.context.logger.log("Root filesystem resized successfully")

        root_partition = disk.getPartitionByPath(os.path.realpath(self.rootfs_block_device))

        original_root_partition_start = root_partition.geometry.start
        original_root_partition_end = root_partition.geometry.end

        self.context.logger.log("Original root partition start (sectors): {0}".format(original_root_partition_start))
        self.context.logger.log("Original root partition end (sectors): {0}".format(original_root_partition_end))

        desired_root_partition_start = original_root_partition_start
        desired_root_partition_end = original_root_partition_end - desired_boot_partition_size
        desired_root_partition_size = desired_root_partition_end - desired_root_partition_start

        self.context.logger.log("Desired root partition start (sectors): {0}".format(desired_root_partition_start))
        self.context.logger.log("Desired root partition end (sectors): {0}".format(desired_root_partition_end))
        self.context.logger.log("Desired root partition size (sectors): {0}".format(desired_root_partition_size))

        desired_root_partition_geometry = parted.Geometry(device=device,
                                                          start=desired_root_partition_start,
                                                          length=desired_root_partition_size)
        root_partition_constraint = parted.Constraint(exactGeom=desired_root_partition_geometry)
        disk.setPartitionGeometry(partition=root_partition,
                                  constraint=root_partition_constraint,
                                  start=desired_root_partition_start,
                                  end=desired_root_partition_end)

        desired_boot_partition_start = disk.getFreeSpaceRegions()[1].start
        desired_boot_partition_end = disk.getFreeSpaceRegions()[1].end
        desired_boot_partition_size = disk.getFreeSpaceRegions()[1].length

        self.context.logger.log("Desired boot partition start (sectors): {0}".format(desired_boot_partition_start))
        self.context.logger.log("Desired boot partition end (sectors): {0}".format(desired_boot_partition_end))

        desired_boot_partition_geometry = parted.Geometry(device=device,
                                                          start=desired_boot_partition_start,
                                                          length=desired_boot_partition_size)
        boot_partition_constraint = parted.Constraint(exactGeom=desired_boot_partition_geometry)
        desired_boot_partition = parted.Partition(disk=disk,
                                                  type=parted.PARTITION_NORMAL,
                                                  geometry=desired_boot_partition_geometry)

        if (root_partition.getFlag(parted.PARTITION_BOOT)):
            desired_boot_partition.setFlag(parted.PARTITION_BOOT)

        disk.addPartition(partition=desired_boot_partition, constraint=boot_partition_constraint)

        disk.commit()

        probed_root_fs = parted.probeFileSystem(desired_root_partition_geometry)
        if not probed_root_fs == 'ext4':
            raise Exception("Probed root fs is not ext4")

        self.command_executor.Execute("partprobe", True)
        self.command_executor.Execute("mkfs.ext2 {0}".format(self.bootfs_block_device), True)

        boot_partition_uuid = self._get_uuid(self.bootfs_block_device)

        # Move stuff from /oldroot/boot to new partition, make new partition mountable at the same spot
        self.command_executor.Execute("mount {0} /oldroot".format(self.rootfs_block_device), True)
        self.command_executor.Execute("mkdir -p /boot", True)
        self.command_executor.Execute("cp /oldroot/etc/fstab /etc/fstab", True)
        self._append_boot_partition_uuid_to_fstab(boot_partition_uuid)
        self.command_executor.Execute("cp /etc/fstab /oldroot/etc/fstab", True)
        self.command_executor.Execute("mount /boot", True)
        self.command_executor.ExecuteInBash("mv /oldroot/boot/* /boot/", True)
        self.command_executor.Execute("umount /boot", True)
        self.command_executor.Execute("umount /oldroot", True)
Beispiel #42
0
    def apply(self, disk, simulate):
        try:
            nlen = parted.sizeToSectors(self.their_size, 'B',
                                        disk.device.sectorSize)
            cmd = None

            if self.part.fileSystem.type == "ntfs":
                newSz = str(int(self.their_size) / 1000)

                prefix = "/usr/sbin"
                check_cmd = "{}/ntfsresize -i -f --force -v {} {}".format(
                    prefix, "--no-action" if simulate else "", self.part.path)

                resize_cmd = "{}/ntfsresize {} -f -f -b --size {}k {}".format(
                    prefix, "--no-action" if simulate else "", newSz,
                    self.part.path)

                # Check first
                try:
                    subprocess.check_call(check_cmd, shell=True)
                except Exception as e:
                    self.set_errors(e)
                    return False

                # Now resize it
                try:
                    subprocess.check_call(resize_cmd, shell=True)
                except Exception as e:
                    self.set_errors(e)
                    return False

                (c, geom) = self.get_size_constraint(disk, nlen)
                self.part.disk.setPartitionGeometry(partition=self.part,
                                                    constraint=c,
                                                    start=geom.start,
                                                    end=geom.end)
                self.new_part_off = geom.end
                # All done
                return True
            elif self.part.fileSystem.type.startswith("ext"):
                if simulate:
                    (c, geom) = self.get_size_constraint(disk, nlen)
                    self.part.disk.setPartitionGeometry(partition=self.part,
                                                        constraint=c,
                                                        start=geom.start,
                                                        end=geom.end)
                    self.new_part_off = geom.end
                    return True
                # check it first
                cmd1 = "/sbin/e2fsck -f -p {}".format(self.part.path)
                try:
                    subprocess.check_call(cmd1, shell=True)
                except Exception as ex:
                    print(ex)
                    self.set_errors(ex)
                    return False

                new_size = str(int(self.their_size / 1024))
                cmd = "/sbin/resize2fs {} {}K".format(self.part.path, new_size)
                try:
                    subprocess.check_call(cmd, shell=True)
                except Exception as ex:
                    print(ex)
                    self.set_errors(ex)
                    return False

                (c, geom) = self.get_size_constraint(disk, nlen)
                self.part.disk.setPartitionGeometry(partition=self.part,
                                                    constraint=c,
                                                    start=geom.start,
                                                    end=geom.end)
                self.new_part_off = geom.end
            else:
                return False
        except Exception as e:
            self.set_errors(e)
            return False
        return True
Beispiel #43
0
 def _kib_to_sectors(self,device, kib):
     return parted.sizeToSectors(kib, 'KiB', device.sectorSize)
    def enter(self):
        if not self.should_enter():
            return

        self.context.logger.log("Entering split_root_partition state")

        device = parted.getDevice('/dev/sda')
        disk = parted.newDisk(device)

        original_root_fs_size = self._get_root_fs_size_in(device.sectorSize)
        self.context.logger.log(
            "Original root filesystem size (sectors): {0}".format(
                original_root_fs_size))

        desired_boot_partition_size = parted.sizeToSectors(
            256, 'MiB', device.sectorSize)
        self.context.logger.log(
            "Desired boot partition size (sectors): {0}".format(
                desired_boot_partition_size))

        desired_root_fs_size = original_root_fs_size - desired_boot_partition_size
        self.context.logger.log(
            "Desired root filesystem size (sectors): {0}".format(
                desired_root_fs_size))

        self.command_executor.Execute(
            "resize2fs /dev/sda1 {0}s".format(desired_root_fs_size), True)

        resized_root_fs_size = self._get_root_fs_size_in(device.sectorSize)

        self.context.logger.log(
            "Resized root filesystem size (sectors): {0}".format(
                resized_root_fs_size))

        if not desired_root_fs_size == resized_root_fs_size:
            raise Exception(
                "resize2fs failed, desired: {0}, resized: {1}".format(
                    desired_root_fs_size, resized_root_fs_size))

        self.context.logger.log("Root filesystem resized successfully")

        root_partition = disk.partitions[0]

        original_root_partition_start = root_partition.geometry.start
        original_root_partition_end = root_partition.geometry.end

        self.context.logger.log(
            "Original root partition start (sectors): {0}".format(
                original_root_partition_start))
        self.context.logger.log(
            "Original root partition end (sectors): {0}".format(
                original_root_partition_end))

        desired_root_partition_start = original_root_partition_start
        desired_root_partition_end = original_root_partition_end - desired_boot_partition_size
        desired_root_partition_size = desired_root_partition_end - desired_root_partition_start

        self.context.logger.log(
            "Desired root partition start (sectors): {0}".format(
                desired_root_partition_start))
        self.context.logger.log(
            "Desired root partition end (sectors): {0}".format(
                desired_root_partition_end))
        self.context.logger.log(
            "Desired root partition size (sectors): {0}".format(
                desired_root_partition_size))

        desired_root_partition_geometry = parted.Geometry(
            device=device,
            start=desired_root_partition_start,
            length=desired_root_partition_size)
        root_partition_constraint = parted.Constraint(
            exactGeom=desired_root_partition_geometry)
        disk.setPartitionGeometry(partition=root_partition,
                                  constraint=root_partition_constraint,
                                  start=desired_root_partition_start,
                                  end=desired_root_partition_end)

        desired_boot_partition_start = disk.getFreeSpaceRegions()[1].start
        desired_boot_partition_end = disk.getFreeSpaceRegions()[1].end
        desired_boot_partition_size = disk.getFreeSpaceRegions()[1].length

        self.context.logger.log(
            "Desired boot partition start (sectors): {0}".format(
                desired_boot_partition_start))
        self.context.logger.log(
            "Desired boot partition end (sectors): {0}".format(
                desired_boot_partition_end))

        desired_boot_partition_geometry = parted.Geometry(
            device=device,
            start=desired_boot_partition_start,
            length=desired_boot_partition_size)
        boot_partition_constraint = parted.Constraint(
            exactGeom=desired_boot_partition_geometry)
        desired_boot_partition = parted.Partition(
            disk=disk,
            type=parted.PARTITION_NORMAL,
            geometry=desired_boot_partition_geometry)

        disk.addPartition(partition=desired_boot_partition,
                          constraint=boot_partition_constraint)

        disk.commit()

        probed_root_fs = parted.probeFileSystem(disk.partitions[0].geometry)
        if not probed_root_fs == 'ext4':
            raise Exception("Probed root fs is not ext4")

        disk.partitions[1].setFlag(parted.PARTITION_BOOT)

        disk.commit()

        self.command_executor.Execute("partprobe", True)
        self.command_executor.Execute("mkfs.ext2 /dev/sda2", True)

        boot_partition_uuid = self._get_uuid("/dev/sda2")

        # Move stuff from /oldroot/boot to new partition, make new partition mountable at the same spot
        self.command_executor.Execute("mount /dev/sda1 /oldroot", True)
        self.command_executor.Execute("mkdir /oldroot/memroot", True)
        self.command_executor.Execute("mount --make-rprivate /", True)
        self.command_executor.Execute("pivot_root /oldroot /oldroot/memroot",
                                      True)
        self.command_executor.ExecuteInBash(
            "for i in dev proc sys; do mount --move /memroot/$i /$i; done",
            True)
        self.command_executor.Execute("mv /boot /boot.backup", True)
        self.command_executor.Execute("mkdir /boot", True)
        self._append_boot_partition_uuid_to_fstab(boot_partition_uuid)
        self.command_executor.Execute("cp /etc/fstab /memroot/etc/fstab", True)
        self.command_executor.Execute("mount /boot", True)
        self.command_executor.ExecuteInBash("mv /boot.backup/* /boot/", True)
        self.command_executor.Execute("rmdir /boot.backup", True)
        self.command_executor.Execute("mount --make-rprivate /", True)
        self.command_executor.Execute("pivot_root /memroot /memroot/oldroot",
                                      True)
        self.command_executor.Execute("rmdir /oldroot/memroot", True)
        self.command_executor.ExecuteInBash(
            "for i in dev proc sys; do mount --move /oldroot/$i /$i; done",
            True)
        self.command_executor.Execute("systemctl restart rsyslog", True)
        self.command_executor.Execute("systemctl restart systemd-udevd", True)
        self.command_executor.Execute("systemctl restart walinuxagent", True)
        self.command_executor.Execute("umount /oldroot/boot", True)
        self.command_executor.Execute("umount /oldroot", True)
Beispiel #45
0
    def apply(self, disk, simulate):
        try:
            nlen = parted.sizeToSectors(self.their_size,
                                        'B', disk.device.sectorSize)
            cmd = None

            if self.part.fileSystem.type == "ntfs":
                newSz = str(int(self.their_size) / 1000)

                prefix = "/usr/sbin"
                check_cmd = "{}/ntfsresize -i -f --force -v {} {}".format(
                    prefix,
                    "--no-action" if simulate else "", self.part.path)

                resize_cmd = "{}/ntfsresize {} -f -f -b --size {}k {}".format(
                    prefix,
                    "--no-action" if simulate else "", newSz, self.part.path)

                # Check first
                try:
                    subprocess.check_call(check_cmd, shell=True)
                except Exception as e:
                    self.set_errors(e)
                    return False

                # Now resize it
                try:
                    subprocess.check_call(resize_cmd, shell=True)
                except Exception as e:
                    self.set_errors(e)
                    return False

                (c, geom) = self.get_size_constraint(disk, nlen)
                self.part.disk.setPartitionGeometry(partition=self.part,
                                                    constraint=c,
                                                    start=geom.start,
                                                    end=geom.end)
                self.new_part_off = geom.end
                # All done
                return True
            elif self.part.fileSystem.type.startswith("ext"):
                if simulate:
                    (c, geom) = self.get_size_constraint(disk, nlen)
                    self.part.disk.setPartitionGeometry(partition=self.part,
                                                        constraint=c,
                                                        start=geom.start,
                                                        end=geom.end)
                    self.new_part_off = geom.end
                    return True
                # check it first
                cmd1 = "/sbin/e2fsck -f -p {}".format(self.part.path)
                try:
                    subprocess.check_call(cmd1, shell=True)
                except Exception as ex:
                    print(ex)
                    self.set_errors(ex)
                    return False

                new_size = str(int(self.their_size / 1024))
                cmd = "/sbin/resize2fs {} {}K".format(
                    self.part.path, new_size)
                try:
                    subprocess.check_call(cmd, shell=True)
                except Exception as ex:
                    print(ex)
                    self.set_errors(ex)
                    return False

                (c, geom) = self.get_size_constraint(disk, nlen)
                self.part.disk.setPartitionGeometry(partition=self.part,
                                                    constraint=c,
                                                    start=geom.start,
                                                    end=geom.end)
                self.new_part_off = geom.end
            else:
                return False
        except Exception as e:
            self.set_errors(e)
            return False
        return True
 def runTest(self):
     self.assertRaises(SyntaxError, parted.sizeToSectors, 9, "yb", 1)
     self.assertEqual(int(parted.sizeToSectors(7777.0, "B", 512)),
                          parted.sizeToSectors(7777.0, "B", 512))
    def enter(self):
        if not self.should_enter():
            return

        self.context.logger.log("Entering split_root_partition state")

        device = parted.getDevice(self.rootfs_disk)
        disk = parted.Disk(device)

        original_root_fs_size = self._get_root_fs_size_in(device.sectorSize)
        self.context.logger.log(
            "Original root filesystem size (sectors): {0}".format(
                original_root_fs_size))

        desired_boot_partition_size = parted.sizeToSectors(
            256, 'MiB', device.sectorSize)
        self.context.logger.log(
            "Desired boot partition size (sectors): {0}".format(
                desired_boot_partition_size))

        root_partition = disk.partitions[0]

        original_root_partition_start = root_partition.geometry.start
        original_root_partition_end = root_partition.geometry.end

        self.context.logger.log(
            "Original root partition start (sectors): {0}".format(
                original_root_partition_start))
        self.context.logger.log(
            "Original root partition end (sectors): {0}".format(
                original_root_partition_end))

        desired_root_partition_start = original_root_partition_start
        desired_root_partition_end = original_root_partition_end - desired_boot_partition_size
        desired_root_partition_size = desired_root_partition_end - desired_root_partition_start

        self.context.logger.log(
            "Desired root partition start (sectors): {0}".format(
                desired_root_partition_start))
        self.context.logger.log(
            "Desired root partition end (sectors): {0}".format(
                desired_root_partition_end))
        self.context.logger.log(
            "Desired root partition size (sectors): {0}".format(
                desired_root_partition_size))

        self.context.logger.log("Resizing root filesystem")
        desired_root_fs_size = desired_root_partition_size
        self._resize_root_fs_to_sectors(desired_root_fs_size,
                                        device.sectorSize)

        desired_root_partition_geometry = parted.Geometry(
            device=device,
            start=desired_root_partition_start,
            length=desired_root_partition_size)
        root_partition_constraint = parted.Constraint(
            exactGeom=desired_root_partition_geometry)
        disk.setPartitionGeometry(partition=root_partition,
                                  constraint=root_partition_constraint,
                                  start=desired_root_partition_start,
                                  end=desired_root_partition_end)

        desired_boot_partition_start = disk.getFreeSpaceRegions()[1].start
        desired_boot_partition_end = disk.getFreeSpaceRegions()[1].end
        desired_boot_partition_size = disk.getFreeSpaceRegions()[1].length

        self.context.logger.log(
            "Desired boot partition start (sectors): {0}".format(
                desired_boot_partition_start))
        self.context.logger.log(
            "Desired boot partition end (sectors): {0}".format(
                desired_boot_partition_end))

        desired_boot_partition_geometry = parted.Geometry(
            device=device,
            start=desired_boot_partition_start,
            length=desired_boot_partition_size)
        boot_partition_constraint = parted.Constraint(
            exactGeom=desired_boot_partition_geometry)
        desired_boot_partition = parted.Partition(
            disk=disk,
            type=parted.PARTITION_NORMAL,
            geometry=desired_boot_partition_geometry)

        disk.addPartition(partition=desired_boot_partition,
                          constraint=boot_partition_constraint)

        disk.commit()

        probed_root_fs = parted.probeFileSystem(disk.partitions[0].geometry)
        if not probed_root_fs == 'ext4':
            raise Exception("Probed root fs is not ext4")

        disk.partitions[1].setFlag(parted.PARTITION_BOOT)

        disk.commit()

        self.command_executor.Execute("partprobe", False)
        self.command_executor.Execute(
            "mkfs.ext2 {0}".format(self.bootfs_block_device), True)

        boot_partition_uuid = self._get_uuid(self.bootfs_block_device)

        # Move stuff from /oldroot/boot to new partition, make new partition mountable at the same spot
        self.command_executor.Execute(
            "mount {0} /oldroot".format(self.rootfs_block_device), True)
        self.command_executor.Execute("mkdir /oldroot/memroot", True)
        self.command_executor.Execute("mount --make-rprivate /", True)
        self.command_executor.Execute("pivot_root /oldroot /oldroot/memroot",
                                      True)
        self.command_executor.ExecuteInBash(
            "for i in dev proc sys; do mount --move /memroot/$i /$i; done",
            True)
        self.command_executor.Execute("mv /boot /boot.backup", True)
        self.command_executor.Execute("mkdir /boot", True)
        self._append_boot_partition_uuid_to_fstab(boot_partition_uuid)
        self.command_executor.Execute("cp /etc/fstab /memroot/etc/fstab", True)
        self.command_executor.Execute("mount /boot", True)
        self.command_executor.ExecuteInBash("mv /boot.backup/* /boot/", True)
        self.command_executor.Execute("rmdir /boot.backup", True)
        self.command_executor.Execute("mount --make-rprivate /", True)
        self.command_executor.Execute("pivot_root /memroot /memroot/oldroot",
                                      True)
        self.command_executor.Execute("rmdir /oldroot/memroot", True)
        self.command_executor.ExecuteInBash(
            "for i in dev proc sys; do mount --move /oldroot/$i /$i; done",
            True)
        self.command_executor.Execute("service rsyslog restart", True)
        self.command_executor.Execute("service udev restart", True)
        self.command_executor.Execute("umount /oldroot/boot", True)

        try:
            self.command_executor.Execute("umount /oldroot", True)
        except:
            self.context.logger.log(
                "Could not unmount /oldroot, attempting to restart WALA and unmount again"
            )

            self.should_exit()

            self.context.logger.log("Removing marker for UnmountOldrootState")
            os.unlink(
                os.path.join(
                    self.context.encryption_environment.
                    os_encryption_markers_path, 'UnmountOldrootState'))

            self.command_executor.Execute(
                'at -f /restart-wala.sh now + 1 minutes', True)
            self.command_executor.Execute('service walinuxagent stop', True)