Beispiel #1
0
    def add_stream(self, stream, path, compress, flags):
        """Add the contents of an iterable to the MAR file.

        Args:
            stream (iterable): yields blocks of data
            path (str): name of this file in the MAR file
            compress (str): One of 'xz', 'bz2', or None. Defaults to None.
            flags (int): permission of this file in the MAR file
        """
        self.data_fileobj.seek(self.last_offset)

        if compress == 'bz2':
            stream = bz2_compress_stream(stream)
        elif compress == 'xz':
            stream = xz_compress_stream(stream)
        elif compress is None:
            pass
        else:
            raise ValueError('Unsupported compression type: {}'.format(compress))

        size = write_to_file(stream, self.data_fileobj)

        # On Windows, convert \ to /
        # very difficult to mock this out for coverage on linux
        if os.sep == '\\':  # pragma: no cover
            path = path.replace('\\', '/')

        e = dict(
            name=six.u(path),
            offset=self.last_offset,
            size=size,
            flags=flags,
        )
        self.entries.append(e)
        self.last_offset += e['size']
Beispiel #2
0
    def add_stream(self, stream, path, compress, flags):
        """Add the contents of an iterable to the MAR file.

        Args:
            stream (iterable): yields blocks of data
            path (str): name of this file in the MAR file
            compress (str): One of 'xz', 'bz2', or None. Defaults to None.
            flags (int): permission of this file in the MAR file
        """
        self.data_fileobj.seek(self.last_offset)

        if compress == 'bz2':
            stream = bz2_compress_stream(stream)
        elif compress == 'xz':
            stream = xz_compress_stream(stream)
        elif compress is None:
            pass
        else:
            raise ValueError('Unsupported compression type: {}'.format(compress))

        size = write_to_file(stream, self.data_fileobj)

        # On Windows, convert \ to /
        # very difficult to mock this out for coverage on linux
        if os.sep == '\\':  # pragma: no cover
            path = path.replace('\\', '/')

        e = dict(
            name=six.u(path),
            offset=self.last_offset,
            size=size,
            flags=flags,
        )
        self.entries.append(e)
        self.last_offset += e['size']
Beispiel #3
0
    def extract(self, destdir, decompress='auto'):
        """Extract the entire MAR file into a directory.

        Args:
            destdir (str): A local directory on disk into which the contents of
                this MAR file will be extracted. Required parent directories
                will be created as necessary.
            decompress (obj, optional): Controls whether files are decompressed
                when extracted. Must be one of 'auto' or None. Defaults to
                'auto'.
        """
        for e in self.mardata.index.entries:
            name = e.name
            entry_path = safejoin(destdir, name)
            entry_dir = os.path.dirname(entry_path)
            mkdir(entry_dir)
            with open(entry_path, 'wb') as f:
                write_to_file(self.extract_entry(e, decompress), f)
Beispiel #4
0
    def extract(self, destdir, decompress='auto'):
        """Extract the entire MAR file into a directory.

        Args:
            destdir (str): A local directory on disk into which the contents of
                this MAR file will be extracted. Required parent directories
                will be created as necessary.
            decompress (obj, optional): Controls whether files are decompressed
                when extracted. Must be one of 'auto' or None. Defaults to
                'auto'.
        """
        for e in self.mardata.index.entries:
            name = e.name
            entry_path = safejoin(destdir, name)
            entry_dir = os.path.dirname(entry_path)
            mkdir(entry_dir)
            with open(entry_path, 'wb') as f:
                write_to_file(self.extract_entry(e, decompress), f)
                os.chmod(entry_path, e.flags)
Beispiel #5
0
def add_signature_block(src_fileobj, dest_fileobj, signing_algorithm, signature=None):
    """Add a signature block to marfile, a MarReader object.

    Productversion and channel are preserved, but any existing signatures are overwritten.

    Args:
        src_fileobj (file object): The input MAR file to add a signature to
        dest_fileobj (file object): File object to write new MAR file to. Must be open in w+b mode.
        signing_algorithm (str): One of 'sha1', or 'sha384'
        signature (bytes): Signature to write, or None to use a dummy signature
    """
    algo_id = {'sha1': 1, 'sha384': 2}[signing_algorithm]
    if not signature:
        signature = make_dummy_signature(algo_id)

    src_fileobj.seek(0)
    mardata = mar.parse_stream(src_fileobj)

    # Header
    header = mardata.header
    dest_fileobj.write(mar_header.build(header))

    # Signature block
    sig = dict(algorithm_id=algo_id,
               size=len(signature),
               signature=signature,
               )

    # This will be fixed up later
    filesize = 0
    sigs_offset = dest_fileobj.tell()
    sigs = sigs_header.build(dict(
        filesize=filesize,
        count=1,
        sigs=[sig],
    ))
    dest_fileobj.write(sigs)

    # Write the additional section
    dest_fileobj.write(extras_header.build(mardata.additional))

    # Write the data
    data_offset = dest_fileobj.tell()
    src_fileobj.seek(mardata.data_offset)
    write_to_file(takeexactly(src_fileobj, mardata.data_length), dest_fileobj)

    # Write the index
    index_offset = dest_fileobj.tell()

    index = mardata.index

    # Adjust the offsets
    data_offset_delta = data_offset - mardata.data_offset

    for e in index.entries:
        e.offset += data_offset_delta

    dest_fileobj.write(index_header.build(index))
    filesize = dest_fileobj.tell()

    # Go back and update the index offset and filesize
    dest_fileobj.seek(0)
    header.index_offset = index_offset
    dest_fileobj.write(mar_header.build(header))

    dest_fileobj.seek(sigs_offset)
    sigs = sigs_header.build(dict(
        filesize=filesize,
        count=1,
        sigs=[sig],
    ))
    dest_fileobj.write(sigs)
Beispiel #6
0
def add_signature_block(src_fileobj,
                        dest_fileobj,
                        signing_algorithm,
                        signature=None):
    """Add a signature block to marfile, a MarReader object.

    Productversion and channel are preserved, but any existing signatures are overwritten.

    Args:
        src_fileobj (file object): The input MAR file to add a signature to
        dest_fileobj (file object): File object to write new MAR file to. Must be open in w+b mode.
        signing_algorithm (str): One of 'sha1', or 'sha384'
        signature (bytes): Signature to write, or None to use a dummy signature
    """
    algo_id = {'sha1': 1, 'sha384': 2}[signing_algorithm]
    if not signature:
        signature = make_dummy_signature(algo_id)

    src_fileobj.seek(0)
    mardata = mar.parse_stream(src_fileobj)

    # Header
    header = mardata.header
    dest_fileobj.write(mar_header.build(header))

    # Signature block
    sig = dict(
        algorithm_id=algo_id,
        size=len(signature),
        signature=signature,
    )

    # This will be fixed up later
    filesize = 0
    sigs_offset = dest_fileobj.tell()
    sigs = sigs_header.build(dict(
        filesize=filesize,
        count=1,
        sigs=[sig],
    ))
    dest_fileobj.write(sigs)

    # Write the additional section
    dest_fileobj.write(extras_header.build(mardata.additional))

    # Write the data
    data_offset = dest_fileobj.tell()
    src_fileobj.seek(mardata.data_offset)
    write_to_file(takeexactly(src_fileobj, mardata.data_length), dest_fileobj)

    # Write the index
    index_offset = dest_fileobj.tell()

    index = mardata.index

    # Adjust the offsets
    data_offset_delta = data_offset - mardata.data_offset

    for e in index.entries:
        e.offset += data_offset_delta

    dest_fileobj.write(index_header.build(index))
    filesize = dest_fileobj.tell()

    # Go back and update the index offset and filesize
    dest_fileobj.seek(0)
    header.index_offset = index_offset
    dest_fileobj.write(mar_header.build(header))

    dest_fileobj.seek(sigs_offset)
    sigs = sigs_header.build(dict(
        filesize=filesize,
        count=1,
        sigs=[sig],
    ))
    dest_fileobj.write(sigs)