示例#1
0
def add_sqlite_file(ctx: BackupContext,
                    tar: TarFile,
                    src: t.Union[os.PathLike, str],
                    arcname: str) -> None:
    if not path.isfile(src):
        return

    with NamedTemporaryFile(mode='rb', suffix='.db') as db_backup_file:
        ctx.logger.debug('Dumping database from %s to %s',
                         src, db_backup_file.name)
        subprocess.run(
            ['sqlite3', str(src), f".backup '{db_backup_file.name}'"],
            check=True)

        # 元ファイルのメタデータを使用する
        src_stat = os.stat(src)
        ti = tar.gettarinfo(db_backup_file.name, arcname)
        ti.mtime = src_stat.st_mtime
        ti.mode = src_stat.st_mode
        ti.uid = src_stat.st_uid
        ti.gid = src_stat.st_gid
        ti.uname = ''
        ti.gname = ''

        with open(src, 'rb') as f:
            tar.addfile(ti, f)
示例#2
0
文件: population.py 项目: grcff/pyAGE
    def save_to_file(self, f):
        tar = TarFile(f, "w")

        # save info file
        f = StringIO(repr((self.agedesc, self.generation)))
        info = tar.gettarinfo(None, "info.py", f)
        tar.addfile(info, f)
        f.close()

        # save agents
        for i in range(len(self.agents)):
            f = StringIO()
            self.agents[i].save_to_file(f)
            info = tar.gettarinfo(None, str(i)+".agt", f)
            tar.addfile(info, f)
            f.close()

        tar.close()                
示例#3
0
文件: population.py 项目: grcff/pyAGE
    def save_to_file(self, f):
        tar = TarFile(f, "w")

        # save info file
        f = StringIO(repr((self.agedesc, self.generation)))
        info = tar.gettarinfo(None, "info.py", f)
        tar.addfile(info, f)
        f.close()

        # save agents
        for i in range(len(self.agents)):
            f = StringIO()
            self.agents[i].save_to_file(f)
            info = tar.gettarinfo(None, str(i) + ".agt", f)
            tar.addfile(info, f)
            f.close()

        tar.close()
示例#4
0
 def _add_pyproject(self, tar: tarfile.TarFile, tar_dir: str) -> None:
     """Rewrites the pyproject.toml before adding to tarball.
     This is mainly aiming at fixing the version number in pyproject.toml
     """
     pyproject = toml.loads(self.meta.filepath.read_text("utf-8"))
     if not isinstance(self.meta._metadata.get("version", ""), str):
         self.meta._metadata["version"] = self.meta.version
     pyproject["project"] = self.meta._metadata
     name = self.meta.filepath.name
     tarinfo = tar.gettarinfo(name, os.path.join(tar_dir, name))
     bio = io.BytesIO(toml.dumps(pyproject).encode("utf-8"))
     tarinfo.size = len(bio.getvalue())
     tar.addfile(tarinfo, bio)
示例#5
0
def add_file(tar: tarfile.TarFile,
             file_name: str) -> Tuple[int, int, datetime, Optional[str]]:

    # FIXME: error: "TarFile" has no attribute "offset"
    offset: int = tar.offset  # type: ignore
    tarinfo: tarfile.TarInfo = tar.gettarinfo(file_name)
    # Change the size of any hardlinks from 0 to the size of the actual file
    if tarinfo.islnk():
        tarinfo.size = os.path.getsize(file_name)
    # Add the file to the tar
    tar.addfile(tarinfo)

    md5: Optional[str] = None
    # Only add files or hardlinks.
    # (So don't add directories or softlinks.)
    if tarinfo.isfile() or tarinfo.islnk():
        f: _io.TextIOWrapper = open(file_name, "rb")
        hash_md5: _hashlib.HASH = hashlib.md5()
        if tar.fileobj is not None:
            fileobj: _io.BufferedWriter = tar.fileobj
        else:
            raise TypeError("Invalid tar.fileobj={}".format(tar.fileobj))
        while True:
            s: str = f.read(BLOCK_SIZE)
            if len(s) > 0:
                # If the block read in is non-empty, write it to fileobj and update the hash
                fileobj.write(s)
                hash_md5.update(s)
            if len(s) < BLOCK_SIZE:
                # If the block read in is smaller than BLOCK_SIZE,
                # then we have reached the end of the file.
                # blocks = how many blocks of tarfile.BLOCKSIZE fit in tarinfo.size
                # remainder = how much more content is required to reach tarinfo.size
                blocks: int
                remainder: int
                blocks, remainder = divmod(tarinfo.size, tarfile.BLOCKSIZE)
                if remainder > 0:
                    null_bytes: bytes = tarfile.NUL
                    # Write null_bytes to get the last block to tarfile.BLOCKSIZE
                    fileobj.write(null_bytes * (tarfile.BLOCKSIZE - remainder))
                    blocks += 1
                # Increase the offset by the amount already saved to the tar
                # FIXME: error: "TarFile" has no attribute "offset"
                tar.offset += blocks * tarfile.BLOCKSIZE  # type: ignore
                break
        f.close()
        md5 = hash_md5.hexdigest()
    size: int = tarinfo.size
    mtime: datetime = datetime.utcfromtimestamp(tarinfo.mtime)
    return offset, size, mtime, md5
示例#6
0
 def _add_pyproject(self, tar: tarfile.TarFile, tar_dir: str) -> None:
     """Rewrites the pyproject.toml before adding to tarball.
     This is mainly aiming at fixing the version number in pyproject.toml
     """
     with self.meta.filepath.open("rb") as f:
         pyproject = tomli.load(f)
     if self.meta.dynamic and "version" in self.meta.dynamic:
         self.meta._metadata["version"] = self.meta.version
         self.meta._metadata["dynamic"].remove("version")
     pyproject["project"] = self.meta._metadata
     name = self.meta.filepath.name
     tarinfo = tar.gettarinfo(name, os.path.join(tar_dir, name))
     bio = io.BytesIO()
     tomli_w.dump(pyproject, bio)
     tarinfo.size = len(bio.getvalue())
     bio.seek(0)
     tar.addfile(tarinfo, bio)
示例#7
0
 def _add_pyproject(self, tar: tarfile.TarFile, tar_dir: str) -> None:
     """Rewrites the pyproject.toml before adding to tarball.
     This is mainly aiming at fixing the version number in pyproject.toml
     """
     pyproject_content = self._meta.filepath.read_text()
     if not isinstance(self._meta._metadata.get("version", ""), str):
         pyproject_content = re.sub(
             r"^version *= *.+?$",
             f'version = "{self._meta.version}"',
             pyproject_content,
             flags=re.M,
         )
     name = "pyproject.toml"
     tarinfo = tar.gettarinfo(name, os.path.join(tar_dir, name))
     bio = io.BytesIO(pyproject_content.encode("utf-8"))
     tarinfo.size = len(bio.getvalue())
     tar.addfile(tarinfo, bio)
    def export_to_tar(self, tarfile: TarFile, destination_dir: str, mtime: int = BST_ARBITRARY_TIMESTAMP) -> None:
        # We need directories here, including non-empty ones,
        # so list_relative_paths is not used.
        for filename in sorted(os.listdir(self.__external_directory)):
            source_name = os.path.join(self.__external_directory, filename)
            arcname = os.path.join(destination_dir, filename)
            tarinfo = tarfile.gettarinfo(source_name, arcname)
            tarinfo.mtime = mtime
            tarinfo.uid = 0
            tarinfo.gid = 0
            tarinfo.uname = ""
            tarinfo.gname = ""

            if tarinfo.isreg():
                with open(source_name, "rb") as f:
                    tarfile.addfile(tarinfo, f)
            elif tarinfo.isdir():
                tarfile.addfile(tarinfo)
                self.open_directory(filename).export_to_tar(tarfile, arcname, mtime)
            else:
                tarfile.addfile(tarinfo)