Ejemplo n.º 1
0
    def addPartition(self,
                     size,
                     partitionlabel,
                     keep=False,
                     fslabel=None,
                     fstype='',
                     partitionflag=[]):
        """Add a partition of given size in MiB to partition table
        
        Where a partition for the given label exists, and is the same size, its uuid
        will be returned when its filesystem is the same as fstype or if fstype is blank.
        Where the partition size differs, the partition with the given partition label
        will be deleted and recreated at the appropriate size.

        :param: keep - when True, if the partition with given label exists keep it
        :return: uuid of existing or created partition
        """
        if not self.disk.confirmedAsExpectedDisk:
            self.disk.confirmExpectedDisk()

        existingPartition = self.getPartitionBy(partitionlabel, 'partlabel')
        if not existingPartition is None:
            if existingPartition.mibsize == size and keep:
                if fstype == '' or fstype == existingPartition.fstype:
                    return (existingPartition.partuuid)
            # Replacing
            self.rmPartition(existingPartition)
            existingPartition = None

        currentDevices = set(self._listDevices())
        startsector, endsector = self._findSpace(size)
        bash(
            f'sudo parted {self.disk.device} mkpart {partitionlabel} {fstype} {startsector}s {endsector}s'
        )

        self._updatePartitionTableData()
        newDevice = set(self._listDevices()) - currentDevices
        print(f'Making partition {partitionlabel} on {self.disk.device}')
        if (len(newDevice)) == 0:
            raise OSError(
                f'Partition {partitionlabel} could not be created on {self.disk.device}'
            )

        newDevice = Path(newDevice.pop())

        newPartition = self.getPartitionBy(newDevice, 'device')

        for flag in partitionflag:
            bash(
                f'sudo parted {self.disk.device} set {newPartition.partnbr} {flag} on'
            )

        print('Partition table written. Checking alignment')
        print(
            bash(
                f'sudo parted {self.disk.device} align-check optimal {newPartition.partnbr}'
            ).stdout)

        newPartition.mkfs(fstype, fslabel)
        return (newPartition.partuuid)
Ejemplo n.º 2
0
    def _updatePartitionTableData(self):
        """Use sfdisk, parted and blkid to read partition table information from disk"""
        if self.disk is None:
            raise ValueError("Disk must be set to read partition table")

        self._data['sfdisk']=\
            ast.literal_eval(bash(f'sudo sfdisk -l -J {self.disk.device}').stdout)
        self._data['parted']=\
            list(map(
                lambda x:x.rstrip(';').split(':'),
                    filter(
                        lambda x:re.match('[0-9]',x) is not None,
                        bash(f'sudo parted -m {self.disk.device} unit s print')
                            .stdout
                            .splitlines()
                        )
                    ))
        self._data['blkid']=getDictionaryFromKeyValueString(\
            bash(f'sudo blkid -o export {self.disk.device}').stdout)

        self.firstlba = self._data['sfdisk']['partitiontable']['firstlba']
        self.lastlba = self._data['sfdisk']['partitiontable']['lastlba']
        self.bytessector = self._data['sfdisk']['partitiontable']['sectorsize']

        def _collatePartitionData(sfdiskData):

            device = Path(sfdiskData['node'])
            blkidData=getDictionaryFromKeyValueString(\
                bash(f'sudo blkid -o export {device}').stdout)

            start = int(sfdiskData['start'])

            partedData = list(
                filter(lambda x: int(x[1].rstrip('s')) == start,
                       self._data['parted'])).pop()
            data = {
                'device': device,
                'startsector': start,
                'endsector': int(partedData[2].rstrip('s')),
                'sectorcount': int(sfdiskData['size']),
                'fstype': partedData[4],
                'fslabel': blkidData['LABEL'],
                'fsuuid': blkidData['UUID'],
                'partlabel': sfdiskData['name'],
                'partuuid': sfdiskData['uuid'],
                'partflag': partedData[6],
                'partnbr': int(partedData[0])
            }
            self.partitiondata[device] = data  #By device
            self.partitiondata[sfdiskData['name']] = data
            self.partitiondata[sfdiskData['uuid']] = data  #By uuid
            self.partitiondata[blkidData['UUID']] = data  #By fsuuid

        if 'partitions' in self._data['sfdisk']['partitiontable']:
            [
                _collatePartitionData(d)
                for d in self._data['sfdisk']['partitiontable']['partitions']
            ]

        self._updatePartitions()
Ejemplo n.º 3
0
def lvm_backup(vg: str, lv: str, out_p: Path, verbose: bool = True) -> Path:
    """Creates a snapshot of a logical volume, mounts it in temporary directory
    creates an tar gzip archive in out_path and cleans up the snapshot afterwards.
    Returns a path to final archive containing backed up files."""
    opts = ExecOpts(quit=True, collect=False)
    system.install_pkg_if_bin_not_exists("tar")
    system.install_pkg_if_bin_not_exists("pigz")
    try:
        snapshot = lvm_snapshot(vg, lv, opts=opts)
        out_p = out_p / (snapshot + ".tgz")

        with TemporaryDirectory() as tempdir:
            inp_p = Path(tempdir) / snapshot
            inp_p.mkdir(parents=True)
            try:
                Command("mount", [f"/dev/{vg}/{snapshot}",
                                  str(inp_p)],
                        opts=opts).safe_run()
                flags = "-cvf" if verbose else "-cf"
                bash(
                    f"cd {str(inp_p)} && tar -I pigz {flags} {str(out_p)} ./*",
                    quit=True,
                )
            finally:
                Command("umount", [f"/dev/{vg}/{snapshot}"],
                        opts=opts).safe_run()
    finally:
        if "snapshot" in locals():
            lvm_remove(vg, snapshot)

    return out_p
Ejemplo n.º 4
0
    def confirmExpectedDisk(self):
        print('Is this disk the right disk?')
        print(bash(f'sudo sfdisk -l {self.device}').stdout)
        userConfirm('Is this the right disk? Y|N')

        print('Disk has the following partitions, confirm each one')
        print(bash(f'sudo parted -l {self.device}').stdout)
        #userConfirm('Are these the right partitions? Y|N')
        print('Disk now cleared to be have its partition table modified.')
        self.confirmedAsExpectedDisk = True
Ejemplo n.º 5
0
 def mkfs(self, typevalue, label):
     """Format partition filesystem and run pending callbacks
     :note: Only fs types in Disk.Partition.MKFS_FSTYPE will be
         prepared
     """
     if typevalue in Partition.MKFS_FSTYPE:
         self.fslabel = label
         print(f'Building {typevalue} filesystem on {self.device}')
         bash(f'sudo mkfs -t {typevalue} -L {self.fslabel} {self.device}')
         for f in self.doonmkfs:
             f()
Ejemplo n.º 6
0
    def __init__(self, devicepath):

        self.device = devicepath
        self.partitiontable = PartitionTable(self)
        self.alignmentoffset = Disk.ALIGNMENT_OFFSET
        self.confirmedAsExpectedDisk = False
        self.bytecount = int(
            bash(f'sudo blockdev --getsize64 {self.device}').stdout)
        self.GiBcount = int(self.bytecount / (pow(2, 30)))
        self.bytessector = int(
            bash(f'sudo blockdev --getpbsz {self.device}').stdout)
        self.sectorcount = self.bytecount / self.bytessector
Ejemplo n.º 7
0
def build_paru():
    install_sudo()

    bld_pkgs = ["base-devel"]
    if not bins_exist(bld_pkgs):
        install_pkgs(bld_pkgs)

    with TemporaryDirectory() as tmpdir:
        gitclone(PARU_REPO, Path(f"{tmpdir}/paru"))
        chown(tmpdir, "nobody", "nobody")
        bash(f"usermod -d {tmpdir} nobody")

        sudo_nopasswd("nobody")
        bash(f"cd {tmpdir}/paru && sudo -u nobody makepkg -srci --noconfirm")
        rm_sudo_nopasswd("nobody")
Ejemplo n.º 8
0
        def _collatePartitionData(sfdiskData):

            device = Path(sfdiskData['node'])
            blkidData=getDictionaryFromKeyValueString(\
                bash(f'sudo blkid -o export {device}').stdout)

            start = int(sfdiskData['start'])

            partedData = list(
                filter(lambda x: int(x[1].rstrip('s')) == start,
                       self._data['parted'])).pop()
            data = {
                'device': device,
                'startsector': start,
                'endsector': int(partedData[2].rstrip('s')),
                'sectorcount': int(sfdiskData['size']),
                'fstype': partedData[4],
                'fslabel': blkidData['LABEL'],
                'fsuuid': blkidData['UUID'],
                'partlabel': sfdiskData['name'],
                'partuuid': sfdiskData['uuid'],
                'partflag': partedData[6],
                'partnbr': int(partedData[0])
            }
            self.partitiondata[device] = data  #By device
            self.partitiondata[sfdiskData['name']] = data
            self.partitiondata[sfdiskData['uuid']] = data  #By uuid
            self.partitiondata[blkidData['UUID']] = data  #By fsuuid
Ejemplo n.º 9
0
 def get_version(self):
     if self.is_available():
         version_str = bash(["clang-format", "--version"], log=False)
         m = re.search(
             r"version (?P<version>\d+\.\d+\.\d+) \([\w\/:.-]+ (?P<hash>[a-z0-9]+)\)$",
             version_str.strip())
         if m:
             version = (*(int(i) for i in m.group('version').split('.')),
                        m.group('hash'))
             return version
Ejemplo n.º 10
0
        def __init__(self, partition):
            """
            :sideeffect: Creates tempdir and mounts parititon there if not 
                already mounted. This will be cleaned up on object.__del__()
            """

            #Check false for if grep finds nothing
            mountsline = bash(
                f'cat {Partition.Mountpoint.SYSTEM_MOUNTS} | grep {partition.device}',
                check=False)

            if mountsline.returncode == 0:
                mountinfo = mountsline.stdout.split()
                self.mountpoint = Path(mountinfo[1])
                self.mountoptions = mountinfo[3]
            else:
                self.tempmount = Path(tempfile.mkdtemp())
                self.mountpoint = self.tempmount
                bash(f'sudo mount {partition.device} {self.mountpoint}')
Ejemplo n.º 11
0
    def _installGrub(self):
        '''Installs grub to the grub data partition once its fs has been intialized
        
        This is invoked once a filesystem for this partition exists.
        '''
                

        # Install grub, specifying path to grub data partition
        # NB: Grub will make this path relative to the filesystems root,
        # see function grub_make_system_path_relative_to_its_root_os of grub source 
        option=f'--boot-directory={self.grubpartition.getMountpoint()}'
        print(f"Installing grub to disk {self.device}'s mbr, boot partition {self.grubbootpartition} & grub data partition {self.grubpartition}")
        result = bash(f'sudo grub-install {option} {self.device}')
        print(result.stdout)
Ejemplo n.º 12
0
    def updateGrubMenu(self):
        '''Updates the grub menu in grub_data'''
        
        # Write menu file. Disable all others. 
        resetExecuteFile=[]
        for entry in os.scandir(Path(GRUB_SYSTEM_CONFIG_DIR)):
            if entry.is_file() and not entry.name in GRUB_MENU_WHITELIST:
                entryStat=entry.stat()
                if stat.filemode(entryStat.st_mode)[-1]=='x':
                    resetExecuteFile.append(entry.path)
                    bash(f'sudo chmod -x {entry.path}')

        menuFilePath=Path(ROOT,GRUB_MENU_FILE)
        menuFile=open(menuFilePath,'wt')
        menuFile.write(EMPTY_GRUB_CUSTOM_MENU)
        [menuFile.write(entry) for entry in self.grubmenu ]
        menuFile.close()
        bash(f'sudo chmod +x {menuFilePath}')
        bash(f'sudo cp {menuFilePath} {GRUB_SYSTEM_CONFIG_DIR}')
        bash(f'sudo grub-mkconfig -o {self.grubpartition.mountpoint}')
        os.unlink(menuFilePath)
        [bash(f'sudo chmod +x {p}') for p in resetExecuteFile]
Ejemplo n.º 13
0
def cleanup(workingDirectory, mounts):
    for m in mounts:
        bash(f'sudo umount {m}')
    shutil.rmtree(workingDirectory)
Ejemplo n.º 14
0
 def __del__(self):
     '''Unmounts and deletes any temporary mountpoint that exists for ptn'''
     if hasattr(self, 'mountpoint'):
         bash(f'sudo umount {self.mountpoint}')
         bash(f'rmdir {self.mountpoint}')
Ejemplo n.º 15
0
 def gen_fstab(self):
     bash(
         f"/usr/bin/genfstab -U {self.location} >> {self.location}/etc/fstab",
         quit=True,
     )
Ejemplo n.º 16
0
 def rmPartition(self, partition: 'Partition'):
     bash(f'sudo parted {self.disk.device} rm {partition.partnbr}')
     self._updatePartitionTableData()
Ejemplo n.º 17
0
def getFirstPartitionOffset(imageFile):
    data = json.loads(bash('sfdisk -l {} -J'.format(imageFile)).stdout)
    sectorsize = data['partitiontable']['sectorsize']
    firstsector = min(
        [n['start'] for n in data['partitiontable']['partitions']])
    return (sectorsize * firstsector)
Ejemplo n.º 18
0
 def archive_scripts(self):
     bash(
         f"cd {FULLPATH.parent} && cp ../*.py . && zip -r {self.location}/{FILENAME} ./*.py",
         quit=True,
     )
Ejemplo n.º 19
0
 def install_vim_plug(self):
     f = self.xdg_conf_dir().joinpath("nvim/autoload/plug.vim")
     url = "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"
     if not f.exists():
         bash(f"curl -fLo {f} --create-dirs {url}")
         system.chown(self.xdg_conf_dir(), self.username, self.username)
Ejemplo n.º 20
0
def run_tests(build_dir: PosixPath, test_filter_str=""):
    command = ["./test.sh", "popart", "-j16"]
    if test_filter_str:
        command += ["-R", test_filter_str]
    bash(command, build_dir, ignore_return_code=True)
Ejemplo n.º 21
0
        osdata = config['os'][osid]
        ostarball = Path(osdata['tarballpath'])

        zipImageFile = ostarball.parts[-1]
        imageFile = ostarball.stem

        # Install openelec, grub menu entry
        if not ostarball.exists():
            print(f'Retrieving {osid} image')
            dlFile(osdata['tarballurl'], ostarball)

        shutil.copy(ostarball, workingDirectory)

        print(f'Extracting {osid} image')
        bash(f'gunzip {zipImageFile}')

        print(f'Mounting {osid} image')
        offset = getFirstPartitionOffset(imageFile)
        mountpoint = Path(workingDirectory, imageFile + '.mnt')
        mounts.append(mountpoint)
        bash(f'mkdir {mountpoint}')
        bash(f'sudo mount -o loop,offset={offset} {imageFile} {mountpoint}')

        systemPartition = disk.partitiontable.getPartitionBy(
            osdata['partition']['system']['partitionlabel'], 'partlabel')
        print(
            f'Transferring files in mounted {osid} image to {systemPartition}')

        # Viashell for explansion of glob
        bash(f'sudo cp -r {mountpoint}/* {systemPartition.getMountpoint()}',