コード例 #1
0
    def run(self):
        global name_to_status

        if '/dev/sda' in self.mountpoint:
            name_to_status[self.namedport] = self.mountpoint + ": Refusing to operate on /dev/sda. Burner script error"
            return  # refuse to run a burn thread on the root partition

        if not self.mountpoint.startswith('/dev/sd'):
            name_to_status[self.namedport] = self.mountpoint + ": Invalid mountpoint. Burning script error"

        sd = parted.getDevice(self.mountpoint)
        name_to_status[self.namedport] = self.mountpoint + ": Partitioning " + sd.model
        sd.clobber()
        sd_disk = parted.freshDisk(sd, 'msdos')

        geometry1 = parted.Geometry(start=disk.part1.start, end=disk.part1.end, device=sd)
        filesystem1 = parted.FileSystem(type=disk.part1.id, geometry=geometry1)
        partition1 = parted.Partition(disk=sd_disk, type=parted.PARTITION_NORMAL, fs=filesystem1, geometry=geometry1)
        sd_disk.addPartition(partition1, constraint=sd.optimalAlignedConstraint)
        sd_disk.commit()

        geometry2 = parted.Geometry(start=disk.part2.start, end=sd.length, device=sd)
        filesystem2 = parted.FileSystem(type=disk.part2.id, geometry=geometry2)
        partition2 = parted.Partition(disk=sd_disk, type=parted.PARTITION_NORMAL, fs=filesystem2, geometry=geometry2)
        sd_disk.addPartition(partition2, constraint=sd.optimalAlignedConstraint)
        sd_disk.commit()

        # set the disk identifier by blasting in the four bytes manually...
        with open(self.mountpoint, 'wb') as p:
            p.seek(0x1b8)
            p.write(struct.pack("<I", disk.partid))

        #### PARTITION 1 COPY
        name_to_status[self.namedport] = self.mountpoint + ": Copying partition 1..."
        p = subprocess.Popen(["dd", "if=" + image_dir + "/part1.img", "of=" + self.mountpoint + "1", "bs=1M"], stderr=subprocess.PIPE)
        for lines in p.stderr:
            if 'copied' in lines.decode("utf-8"):
                name_to_status[self.namedport] = self.mountpoint + ": " + lines.decode("utf-8")

        p.wait()
        if p.returncode != 0:
            name_to_status[self.namedport] = self.mountpoint + " ERROR: " + lines.decode("utf-8")
            return

        time.sleep(3)
        ##### PARTITION 2 COPY
        name_to_status[self.namedport] = self.mountpoint + ": Copying partition 2..."
        p = subprocess.Popen(["dd", "if=" + image_dir + "/part2.ext4", "of=" + self.mountpoint + "2", "bs=1M"], stderr=subprocess.PIPE)
        for lines in p.stderr:
            if 'copied' in lines.decode("utf-8"):
                name_to_status[self.namedport] = self.mountpoint + ": " + lines.decode("utf-8")

        p.wait()
        if p.returncode != 0:
            name_to_status[self.namedport] = self.mountpoint + " ERROR: " + lines.decode("utf-8")
            return

        time.sleep(3)
        ##### FSCK PARTITION 2 -- allow a couple iterations to get a "clean" fsck
        returncode = 1
        iters = 0
        while returncode != 0 and iters < 4:
            name_to_status[self.namedport] = self.mountpoint + ": fsck partition 2..."
            p = subprocess.Popen(["e2fsck", "-y", "-f", self.mountpoint + "2"], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
            for lines in p.stderr:
                name_to_status[self.namedport] = self.mountpoint + ": " + lines.decode("utf-8")

            p.wait()
            returncode = p.returncode
            iters = iters + 1

        if iters >= 3:
            name_to_status[self.namedport] = self.mountpoint + " ERROR: " + lines.decode("utf-8")
            return

        ##### RESIZE PARTITION 2
        name_to_status[self.namedport] = self.mountpoint + ": resize partition 2..."
        p = subprocess.Popen(["resize2fs", self.mountpoint + "2"], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
        for lines in p.stderr:
            name_to_status[self.namedport] = self.mountpoint + ": " + lines.decode("utf-8")

        p.wait()
        if p.returncode != 0:
            name_to_status[self.namedport] = self.mountpoint + " ERROR: " + lines.decode("utf-8")
            return

        ##### SET BLKID PARTITION 2 -- actually, this can be done in the source image!
        #name_to_status[self.namedport] = self.mountpoint + ": set blkid partition 2..."
        #p = subprocess.Popen(["tune2fs", self.mountpoint + "2", "-U", disk.uuid], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
        #for lines in p.stderr:
        #    name_to_status[self.namedport] = self.mountpoint + ": " + lines.decode("utf-8")

        #p.wait()
        #if p.returncode != 0:
        #    name_to_status[self.namedport] = self.mountpoint + " ERROR: " + lines.decode("utf-8")
        #    return

        ##### SET PASS STATE
        name_to_status[self.namedport] = self.mountpoint + " FINISHED"
        return
コード例 #2
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('name', help='name of the disk image to create')
    parser.add_argument(
        '--path',
        help='path to folder containing rootfs to be copied into disk image',
        type=str,
        default='/tmp/multistrap')
    args = parser.parse_args()

    # determine size of rootfs folder
    result = subprocess.run('du --null -sm {}'.format(args.path).split(),
                            check=True,
                            stdout=subprocess.PIPE,
                            encoding='UTF-8')
    rootsize = int(result.stdout.split()
                   [0])  # numeric size is at the beginning of the output line
    print('Found rootfs folder at {} with size {} MB'.format(
        args.path, rootsize))

    # create disk image file
    print('Creating empty disk image file...')
    imgpath = '/tmp/' + args.name
    image = open(imgpath, 'w')
    size = rootsize + bootsize + extraspace
    image.seek((size * 10**6) - 1)  # subtract one to align to 512-byte sector
    image.write('a')
    image.close()

    # setup loop device
    print('Setting up loopback device...')
    result = subprocess.run('losetup -f --show {}'.format(imgpath).split(),
                            check=True,
                            stdout=subprocess.PIPE,
                            encoding='UTF-8')
    devpath = result.stdout.strip(
    )  # output from losetup gives path to loopback device
    print("loopback device created at {}".format(devpath))

    # partition disk image
    print('Partitioning disk image...')
    # create boot partition
    print('Creating boot partition...')
    device = parted.getDevice(devpath)
    disk = parted.freshDisk(device, 'gpt')
    bootPartSize = bootsize * 10**6  # boot partiton is 128MB
    # convert from bytes to sectors
    bootlen = int(bootPartSize / device.sectorSize)
    bootgeom = parted.Geometry(device=device, start=1, length=bootlen)
    bootfs = parted.FileSystem(type='fat32', geometry=bootgeom)
    bootpart = parted.Partition(disk=disk,
                                type=parted.PARTITION_NORMAL,
                                fs=bootfs,
                                geometry=bootgeom)
    bootpart.name = 'boot'
    disk.addPartition(partition=bootpart,
                      constraint=device.optimalAlignedConstraint)
    disk.commit()

    # create root partition
    print('Creating root partition')
    rootgeom = disk.getFreeSpaceRegions()[-1]
    rootfs = parted.FileSystem(type='ext4', geometry=rootgeom)
    rootpart = parted.Partition(disk=disk,
                                type=parted.PARTITION_NORMAL,
                                fs=rootfs,
                                geometry=rootgeom)
    rootpart.name = 'Debian'
    disk.addPartition(partition=rootpart,
                      constraint=device.optimalAlignedConstraint)
    disk.commit()

    # delete loop device and recreate with partitions
    print('Removing loopback device and recreating with partition support...')
    result = subprocess.run('losetup -d {}'.format(devpath).split())
    result = subprocess.run('losetup -f --show -P {}'.format(imgpath).split(),
                            check=True,
                            stdout=subprocess.PIPE,
                            encoding='UTF-8')
    devpath = result.stdout.strip(
    )  # output from losetup gives path to loopback device
    print("loopback device created at {}".format(devpath))

    # format partitions
    print('Formatting partitions...')
    subprocess.run('mkfs.fat -F 32 {}p1'.format(devpath).split(),
                   check=True)  # format first partition to FAT32
    subprocess.run('mkfs.ext4 {}p2'.format(devpath).split(),
                   check=True)  # format second parition to ext4

    # mount filesystems and copy files

    # delete loop device
    print('Cleaning up loopback device...')
    result = subprocess.run('losetup -d {}'.format(devpath).split())
コード例 #3
0
import parted

target = "/dev/mmcblk0"

device = parted.getDevice(target)
disk = parted.Disk(device)

if len(disk.partitions) == 2:
        print "disk has 2 partitions - leaving it alone"
        print "storage partition ready at {}".format(disk.partitions[1].path)

elif len(disk.partitions) == 1:
        print "disk has 1 partition - creating storage partition"
        basePart = disk.partitions[0]
        storageStart = basePart.geometry.end + 1
        storageLength = device.getLength() - storageStart
        print "current partition runs from {} to {}, new one will be {} to {}".format(basePart.geometry.start, basePart.geometry.end, storageStart, storageStart + storageLength)

        storageGeometry = parted.Geometry(device=device, start=storageStart, length=device.getLength() - storageStart)
        storageFS = parted.FileSystem(type="ext4", geometry=storageGeometry)
        storagePartition = parted.Partition(disk=disk, type=parted.PARTITION_NORMAL, fs=storageFS, geometry=storageGeometry)

        disk.addPartition(partition=storagePartition, constraint=device.optimalAlignedConstraint)

        print "storage partition ready at {}".format(storagePartition.path)

else:
        print "unrecognized disk configuration"

disk.commit()
コード例 #4
0
def mkfakediskimg(disk_img):
    """Create a fake partitioned disk image

    :param disk_img: Full path to a partitioned disk image
    :type disk_img: str
    :returns: True if it was successful, False if something went wrong

    Include /boot, swap, and / partitions with fake kernel and /etc/passwd
    """
    try:
        mksparse(disk_img, 42 * 1024**2)
        # Make a /boot, / and swap partitions on it
        dev = parted.getDevice(disk_img)
        disk = parted.freshDisk(dev, "gpt")

        # (start, length, flags, name)
        for start, length, flags, name in [
            (1024**2, 1024**2, None, "boot"),
            (2 * 1024**2, 2 * 1024**2, parted.PARTITION_SWAP, "swap"),
            (4 * 1024**2, 38 * 1024**2, None, "root")
        ]:
            geo = parted.Geometry(device=dev,
                                  start=start // dev.sectorSize,
                                  length=length // dev.sectorSize)
            part = parted.Partition(disk=disk,
                                    type=parted.PARTITION_NORMAL,
                                    geometry=geo)
            part.getPedPartition().set_name(name)
            disk.addPartition(partition=part)
            if flags:
                part.setFlag(flags)
        disk.commit()
        os.sync()
    except parted.PartedException:
        return False

    # Mount the disk's partitions
    loop_devs = kpartx_disk_img(disk_img)

    try:
        # Format the partitions
        runcmd(["mkfs.ext4", "/dev/mapper/" + loop_devs[0][0]])
        runcmd(["mkswap", "/dev/mapper/" + loop_devs[1][0]])
        runcmd(["mkfs.ext4", "/dev/mapper/" + loop_devs[2][0]])

        # Mount the boot partition and make a fake kernel and initrd
        boot_mnt = mount("/dev/mapper/" + loop_devs[0][0])
        try:
            mkfakebootdir(boot_mnt)
        finally:
            umount(boot_mnt)

        # Mount the / partition and make a fake / filesystem with /etc/passwd
        root_mnt = mount("/dev/mapper/" + loop_devs[2][0])
        try:
            mkfakerootdir(root_mnt)
        finally:
            umount(root_mnt)
    except Exception:
        return False
    finally:
        # Remove the disk's mounted partitions
        runcmd(["kpartx", "-d", "-s", disk_img])

    return True
コード例 #5
0
 def setUp(self):
     RequiresDevice.setUp(self)
     self.g = parted.Geometry(device=self.device, start=0, length=100)
     self.a = parted.Alignment(offset=10, grainSize=0)
コード例 #6
0
    def runTest(self):
        length = 137
        geom = parted.Geometry(self.device, start=100, length=length)

        self.assertEqual(geom.getLength(), geom.length)
        self.assertEqual(geom.getLength(), length)
コード例 #7
0
    def partitionParted(self):
        """Build partitions according to the partition spec.

        XXX roth -- hopefully the GPT labels specified here
        work correctly (that is, are ignored) on an msdos label
        """

        constraint = self.partedDevice.optimalAlignedConstraint
        # default partition layout constraint

        devices = {}

        def _u2s(sz, u):
            """Convert to units of logical sectors."""
            bsz = sz * u
            bsz = bsz + self.partedDevice.sectorSize - 1
            return bsz / self.partedDevice.sectorSize

        def _align(spos):
            """Align this sector number."""
            sz = self.partedDevice.sectorSize
            psz = self.partedDevice.physicalSectorSize

            if type(psz) != int: return spos
            if psz <= sz: return spos
            if (psz % sz) != 0: return spos
            if psz > 1048576: return spos

            stride = psz / sz
            off = spos % stride
            off = stride - off
            off = off % stride

            spos += off
            return spos

        UNITS = {
            'GiB': 1024 * 1024 * 1024,
            'G': 1000 * 1000 * 1000,
            'MiB': 1024 * 1024,
            'M': 1000 * 1000,
            'KiB': 1024,
            'K': 1000,
        }

        for part in self.im.platformConf['installer']:

            label, partData = list(part.items())[0]
            if type(partData) == dict:
                sz, fmt = partData['='], partData.get('format', 'ext4')
            else:
                sz, fmt = partData, 'ext4'

            cnt = None
            nextBlock = self.nextBlock or 1
            minpart = self.minpart or 1
            for ul, ub in UNITS.items():
                if sz.endswith(ul):
                    cnt = _u2s(int(sz[:-len(ul)], 10), ub)
                    break
            if sz == '100%':
                cnt = self.partedDevice.getLength() - nextBlock
            if cnt is None:
                self.log.error("invalid size (no units) for %s: %s", part, sz)
                return 1

            start = _align(nextBlock)
            end = start + cnt - 1
            if end <= self.partedDevice.getLength():
                self.log.info("Allocating %d sectors for %s", cnt, label)
            else:
                self.log.warn("%s: start sector %d, end sector %d, max %d",
                              label, start, end, self.partedDevice.getLength())
                self.log.error("invalid partition %s [%s] (too big)", label,
                               sz)
                return 1

            geom = parted.Geometry(device=self.partedDevice,
                                   start=start,
                                   length=end - start + 1)
            fs = parted.FileSystem(type=fmt, geometry=geom)
            part = parted.Partition(disk=self.partedDisk,
                                    type=parted.PARTITION_NORMAL,
                                    fs=fs,
                                    geometry=geom)
            if self.partedDisk.type == 'gpt':
                part.getPedPartition().set_name(label)
            self.partedDisk.addPartition(part, constraint=constraint)
            self.partedDisk.commit()
            self.check_call((
                'partprobe',
                self.device,
            ))

            if fmt == 'raw':
                self.log.info("Leaving %s (%s) unformatted (raw)", part.path,
                              label)
            else:
                self.log.info("Formatting %s (%s) as %s", part.path, label,
                              fmt)
                if fmt == 'msdos':
                    self.mkdosfs(part.path, label=label)
                elif fmt == 'ext4':
                    self.mke4fs(part.path, label=label, huge_file=False)
                elif fmt == 'ext2':
                    self.mke2fs(part.path, label=label)
                else:
                    self.mkfs(part.path, fstype=fmt)

            self.nextBlock, self.minpart = end + 1, minpart + 1

            devices[label] = part.path

            if label == 'ONL-CONFIG' and self.configArchive is not None:
                self.restoreConfig(part.path)

        self.blkidParts = BlkidParser(log=self.log.getChild("blkid"))
        # re-read the partitions

        return 0
コード例 #8
0
 def map(self, src, sector):
     """Given a Geometry src that overlaps with self and a sector inside src,
        this method translates the address of the sector into an address
        inside self.  If self does not contain sector, ArithmeticError will
        be raised."""
     return parted.Geometry(PedGeometry=self.__geometry.map(src.getPedGeometry(), sector))
コード例 #9
0
def do_image_hd( outf, hd, fslabel, opt ):

        # Init to 0 because we increment before using it
        partition_number = 0

        sector_size = 512
	s=size_to_int(hd.text("size"))
	size_in_sectors = s / sector_size

        outf.do_command( 'rm "%s"' % hd.text("name"), allow_fail=True )
        f = open( hd.text("name"), "wb" )
        f.truncate( size_in_sectors * sector_size )
        f.close()

	imag = parted.Device( hd.text("name") )
        if hd.tag == "gpthd":
            disk = parted.freshDisk(imag, "gpt" )
        else:
            disk = parted.freshDisk(imag, "msdos" )

        outf.do_command( 'echo /opt/elbe/' + hd.text("name") + ' >> /opt/elbe/files-to-extract' )

        grub = grubinstaller( outf )

	current_sector = 2048
	for part in hd:

            if part.tag != "partition":
                continue

	    if part.text("size") == "remain" and hd.tag == "gpthd":
		sz = size_in_sectors - 35 - current_sector;
	    elif part.text("size") == "remain":
		sz = size_in_sectors - current_sector;
	    else:
		sz = size_to_int(part.text("size"))/sector_size

            g = parted.Geometry (device=imag,start=current_sector,length=sz)
            if fslabel.has_key(part.text("label")) and fslabel[part.text("label")].fstype == "vfat": 
                fs = simple_fstype("fat32")
                ppart = parted.Partition(disk, parted.PARTITION_NORMAL, fs, geometry=g)
		ppart.setFlag(_ped.PARTITION_LBA)
            else:
                ppart = parted.Partition(disk, parted.PARTITION_NORMAL, geometry=g)

	    cons = parted.Constraint(exactGeom=g)
	    disk.addPartition(ppart, cons)

	    if part.has("bootable"):
		ppart.setFlag(_ped.PARTITION_BOOT)

	    if part.has("biosgrub"):
		ppart.setFlag(_ped.PARTITION_BIOS_GRUB)

            partition_number += 1

            if not fslabel.has_key(part.text("label")):
                current_sector += sz
                continue

	    entry = fslabel[part.text("label")]
	    entry.offset = current_sector*sector_size
	    entry.size   = sz * sector_size
	    entry.filename = hd.text("name")
            if hd.tag == "gpthd":
                entry.number = "gpt%d" % partition_number
            else:
                entry.number = "msdos%d" % partition_number


            if entry.mountpoint == "/":
                grub.set_root_entry( entry )
            elif entry.mountpoint == "/boot":
                grub.set_boot_entry( entry )

            entry.losetup( outf, "loop0" )
	    outf.do_command( 'mkfs.%s %s %s /dev/loop0' % ( entry.fstype, entry.mkfsopt, entry.get_label_opt() ) )

            outf.do_command( 'mount /dev/loop0 %s' % opt.dir )
            outf.do_command( 'cp -a "%s"/* "%s"' % ( os.path.join( '/opt/elbe/filesystems', entry.label ), opt.dir ), allow_fail=True )
            outf.do_command( 'umount /dev/loop0' )
	    outf.do_command( 'losetup -d /dev/loop0' )

	    current_sector += sz

	disk.commit()

        if hd.has( "grub-install" ):
            grub.install( opt )
コード例 #10
0
    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)
コード例 #11
0
class Constraint(object):
    """Constraint()

       A Constraint object describes a set of restrictions on other pyparted
       operations.  Constraints can restrict the location and alignment of the
       start and end of a partition, and its minimum and maximum size.  Most
       constraint operations can raise CreateException if creating temporary
       objects fails, or ArithmeticError if an error occurs during
       calculations."""
    @localeC
    def __init__(self, *args, **kwargs):
        """Create a new Constraint object.  There are many different ways to
           create a Constraint, all depending on the parameters passed to
           __init__.  If minGeom and maxGeom are supplied, the constraint will
           be created to satisfy both.  If only one of minGeom or maxGeom are
           supplied, the constraint is only guaranteed to solve the given
           paramter.  If exactGeom is given, the constraint will only be
           satisfied by the given geometry.  If device is given, any region
           on that device will satisfy the constraint.

           If none of the previously mentioned parameters are supplied, all of
           startAlign, EndAlign, startRange, endRange, minSize, and maxSize
           must be given."""
        if "PedConstraint" in kwargs:
            self.__constraint = kwargs.get("PedConstraint")
        elif "minGeom" in kwargs and "maxGeom" in kwargs:
            ming = kwargs.get("minGeom").getPedGeometry()
            maxg = kwargs.get("maxGeom").getPedGeometry()
            self.__constraint = _ped.constraint_new_from_min_max(ming, maxg)
        elif "minGeom" in kwargs:
            ming = kwargs.get("minGeom").getPedGeometry()
            self.__constraint = _ped.constraint_new_from_min(ming)
        elif "maxGeom" in kwargs:
            maxg = kwargs.get("maxGeom").getPedGeometry()
            self.__constraint = _ped.constraint_new_from_max(maxg)
        elif "exactGeom" in kwargs:
            exact = kwargs.get("exactGeom").getPedGeometry()
            self.__constraint = _ped.constraint_exact(exact)
        elif "device" in kwargs:
            dev = kwargs.get("device").getPedDevice()
            self.__constraint = _ped.constraint_any(dev)
        elif "startAlign" in kwargs and "endAlign" in kwargs and \
             "startRange" in kwargs and "endRange" in kwargs and \
             "minSize" in kwargs and "maxSize" in kwargs:
            starta = kwargs.get("startAlign").getPedAlignment()
            enda = kwargs.get("endAlign").getPedAlignment()
            startr = kwargs.get("startRange").getPedGeometry()
            endr = kwargs.get("endRange").getPedGeometry()
            mins = kwargs.get("minSize")
            maxs = kwargs.get("maxSize")
            self.__constraint = _ped.Constraint(starta, enda, startr, endr,
                                                mins, maxs)
        else:
            raise parted.ConstraintException("missing initialization parameters")

    def __eq__(self, other):
        return not self.__ne__(other)

    def __ne__(self, other):
        if hash(self) == hash(other):
            return False

        if type(self) != type(other):
            return True

        c1 = self.getPedConstraint()
        c2 = other.getPedConstraint()

        return self.minSize != other.minSize \
                or self.maxSize != other.maxSize \
                or c1.start_align != c2.start_align \
                or c1.end_align != c2.end_align \
                or c1.start_range != c2.start_range \
                or c1.end_range != c2.end_range

    startAlign = property(
            lambda s: parted.Alignment(PedAlignment=s.__constraint.start_align),
            lambda s, v: setattr(s.__constraint, "start_align", v.getPedAlignment()))

    endAlign = property(
            lambda s: parted.Alignment(PedAlignment=s.__constraint.end_align),
            lambda s, v: setattr(s.__constraint, "end_align", v.getPedAlignment()))

    startRange = property(
            lambda s: parted.Geometry(PedGeometry=s.__constraint.start_range),
            lambda s, v: setattr(s.__constraint, "start_range", v.getPedGeometry()))

    endRange = property(
            lambda s: parted.Geometry(PedGeometry=s.__constraint.end_range),
            lambda s, v: setattr(s.__constraint, "end_range", v.getPedGeometry()))

    minSize = property(
            lambda s: s.__constraint.min_size,
            lambda s, v: setattr(s.__constraint, "min_size", v))

    maxSize = property(
            lambda s: s.__constraint.max_size,
            lambda s, v: setattr(s.__constraint, "max_size", v))

    def __str__(self):
        s = ("parted.Constraint instance --\n"
             "  startAlign: %(startAlign)r  endAlign: %(endAlign)r\n"
             "  startRange: %(startRange)r  endRange: %(endRange)r\n"
             "  minSize: %(minSize)s  maxSize: %(maxSize)s\n"
             "  PedConstraint: %(ped)r" %
             {"startAlign": self.startAlign, "endAlign": self.endAlign,
              "startRange": self.startRange, "endRange": self.endRange,
              "minSize": self.minSize, "maxSize": self.maxSize,
              "ped": self.__constraint})
        return s

    @localeC
    def intersect(self, b):
        """Return a new constraint that is the intersection of self and the
           provided constraint b.  The returned constraint will therefore be
           more restrictive than either input as it will have to satisfy
           both."""
        return parted.Constraint(PedConstraint=self.__constraint.intersect(b.getPedConstraint()))

    @localeC
    def solveMax(self):
        """Return a new geometry that is the largest region satisfying self.
           There may be more than one solution, and there are no guarantees as
           to which solution will be returned."""
        return parted.Geometry(PedGeometry=self.__constraint.solve_max())

    @localeC
    def solveNearest(self, geom):
        """Return a new geometry that is the nearest region to geom that
           satisfies self.  This function does not guarantee any specific
           meaning of 'nearest'."""
        return parted.Geometry(PedGeometry=self.__constraint.solve_nearest(geom.getPedGeometry()))

    @localeC
    def isSolution(self, geom):
        """Does geom satisfy this constraint?"""
        return self.__constraint.is_solution(geom.getPedGeometry())

    def getPedConstraint(self):
        """Return the _ped.Constraint object contained in this Constraint.
           For internal module use only."""
        return self.__constraint
コード例 #12
0
 def solveNearest(self, geom):
     """Return a new geometry that is the nearest region to geom that
        satisfies self.  This function does not guarantee any specific
        meaning of 'nearest'."""
     return parted.Geometry(PedGeometry=self.__constraint.solve_nearest(geom.getPedGeometry()))
コード例 #13
0
 def solveMax(self):
     """Return a new geometry that is the largest region satisfying self.
        There may be more than one solution, and there are no guarantees as
        to which solution will be returned."""
     return parted.Geometry(PedGeometry=self.__constraint.solve_max())
コード例 #14
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 /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)
コード例 #15
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)
コード例 #16
0
 while next_vol in volumes:
   v+=1
   next_vol=options.volume.format(v)
 drvs=drv_by_size[s]
 if options.action=='advise':
   drvnames=sorted([d.path for d in drvs])
   print "  sudo {0} -a create -v '{1}' {2} # size: {3} MiB".format(__file__, next_vol, " ".join(drvnames),s*len(drvnames))
 else:
   try:
     drvnames=[]
     for dev in drvs:
       if options.reboot:
         disk.maximizePartition(disk.partitions[-1],dev.optimalAlignedConstraint)
         disk.commitToDevice()
       else:
         geometry = parted.Geometry(device=dev, start=1, length=1)
         for p in disk.getFreeSpacePartitions():
           if p.geometry.length > geometry.length:
             geometry = p.geometry
         filesystem = parted.FileSystem(type='ext3', geometry=geometry)
         partition = parted.Partition(disk=disk, type=parted.PARTITION_NORMAL, fs=filesystem, geometry=geometry)
         disk.addPartition(partition=partition, constraint=dev.optimalAlignedConstraint)
         partition.setFlag(parted.PARTITION_LVM)
         disk.commit()
         subprocess.check_call(['pvcreate',partition.path],stdout=stdout, stderr=stderr)
         subprocess.check_call(['vgextend',options.VG,partition.path],stdout=stdout, stderr=stderr)
         #drvnames.append(partition.path)
         subprocess.check_call(['lvresize','-i',str(len(drvnames)),'-I','1M','-l', '+100%FREE','/dev/{$0}/$1'.format(options.VG,options.LV)],stdout=stdout, stderr=stderr)
   except Exception, e:
     print 'Error occurred during creation of {0}:\n{1}'.format(next_vol,e)
     errs+=1
コード例 #17
0
 def setUp(self):
     super(PartitionNewTestCase, self).setUp()
     self.geom = parted.Geometry(self.device, start=100, length=100)
     self.fs = parted.FileSystem(type='ext2', geometry=self.geom)
     self.part = parted.Partition(self.disk, parted.PARTITION_NORMAL,
                             geometry=self.geom, fs=self.fs)
コード例 #18
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)
コード例 #19
0
ファイル: build_image.py プロジェクト: jean-marc-LACROIX/dft
    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()
コード例 #20
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.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)
コード例 #21
0
ファイル: import_partition.py プロジェクト: pigger101/chrome
# Fix the backup GPT by "moving" it to end of disk (its already there but
# contains checksums that needs recomputing as well as pointers to its position
# on disk)
subprocess.run(f"sgdisk -e {sdcard}",
               shell=True,
               capture_output=True,
               check=True)

# Now the disk image contains the new partition and the GPT is adjusted for the
# new free space. We just have to add our new partition and its ready to use
device = parted.getDevice(sdcard)
disk = parted.newDisk(device)

geometry = parted.Geometry(device,
                           start=partition_insertion_point_sector,
                           length=new_partition_size_sectors)

print(f"New partition geometry:\n{geometry}")

filesystem = parted.FileSystem(type='ext2', geometry=geometry)
new_partition = parted.Partition(disk=disk,
                                 type=parted.PARTITION_NORMAL,
                                 fs=filesystem,
                                 geometry=geometry)
# name isn't in the constructor but we can set it separately
new_partition.name = "myimportedpartition"
disk.addPartition(partition=new_partition,
                  constraint=parted.Constraint(exactGeom=geometry))

disk.commit()
コード例 #22
0
ファイル: sd.py プロジェクト: himblick/himblick
    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])
コード例 #23
0
 def getMaxGeometry(self, constraint):
     """Given a constraint, return the maximum Geometry that self can be
        grown to.  Raises Partitionexception on error."""
     return parted.Geometry(PedGeometry=self.disk.getPedDisk().get_max_partition_geometry(self.__partition, constraint.getPedConstraint()))