Ejemplo n.º 1
0
def extract_archive_tar(store, name, tag, checksums, size, content_source):
    """Extract an archive.tar.xz into `store`.

    :param store: A simplestreams `ObjectStore`.
    :param name: Logical name of the file being inserted.  Only needs to be
        unique within the scope of this boot image.
    :param tag: UUID, or "tag," for the file archive.tar.xz file. The
        archive.tar.xz file along with its contents will be stored in the
        cache directory under names derived from this tag.
    :param checksums: A Simplestreams checksums dict, mapping hash algorihm
        names (such as `sha256`) to the file's respective checksums as
        computed by those hash algorithms.
    :param size: Optional size for the file, so Simplestreams knows what size
        to expect.
    :param content_source: A Simplestreams `ContentSource` for reading the
        file.
    :return: A list of inserted files (file and archive.tar.xz) described
        as tuples of (path, logical name).  The path lies in the directory
        managed by `store` and has a filename based on `tag`, not logical name.
    """
    maaslog.debug("Inserting archive %s (tag=%s, size=%s).", name, tag, size)
    extracted_files = []
    cache_dir = store._fullpath('')
    # Check if the archive has already been extracted. This is done by scanning
    # the cache directory for files containing the given tag. Since the tag is
    # the SHA256 this will always be unique and if files are added/removed from
    # the archive we'll get a new tag.
    for root, dirs, files in os.walk(cache_dir):
        for f in files:
            if f.endswith(tag):
                # Strip out the tag
                filename = f[:-(len(tag) + 1)]
                if root != cache_dir:
                    filename = os.path.join(root[len(cache_dir):], filename)
                # Give full path to cached file
                filepath = os.path.join(root, f)
                extracted_files.append((filepath, filename))

    # If no files with the given tag were found we need to extract them.
    if extracted_files == []:
        maaslog.debug(
            "Extracting archive %s (tag=%s, size=%s).", name, tag, size)
        archive_path = store._fullpath(tag)
        store.insert(tag, content_source, checksums, mutable=False, size=size)
        with tarfile.open(archive_path, 'r|*') as tar:
            for member in tar:
                if member.isfile():
                    filename = member.name
                    filepath = store._fullpath('%s-%s' % (filename, tag))
                    fo = tar.extractfile(member)
                    store.insert(filepath, fo, mutable=False)
                    extracted_files.append((filepath, filename))
        store.remove(tag)

    # Return the list of sets containing the path to the cache file and the
    # real filename which should be used.
    return extracted_files
Ejemplo n.º 2
0
def write_keyring(keyring_path, keyring_data: bytes):
    """Write a keyring blob to a file.

    :param path: The path to the keyring file.
    :param keyring_data: The data to write to the keyring_file, as a
        base64-encoded string.
    """
    maaslog.debug("Writing keyring %s to disk.", keyring_path)
    with open(keyring_path, 'wb') as keyring_file:
        keyring_file.write(keyring_data)
Ejemplo n.º 3
0
def insert_file(store, name, tag, checksums, size, content_source):
    """Insert a file into `store`.

    :param store: A simplestreams `ObjectStore`.
    :param name: Logical name of the file being inserted.  Only needs to be
        unique within the scope of this boot image.
    :param tag: UUID, or "tag," for the file.  It will be inserted into
        `store` under this name, not its logical name.
    :param checksums: A Simplestreams checksums dict, mapping hash algorihm
        names (such as `sha256`) to the file's respective checksums as
        computed by those hash algorithms.
    :param size: Optional size for the file, so Simplestreams knows what size
        to expect.
    :param content_source: A Simplestreams `ContentSource` for reading the
        file.
    :return: A list of inserted files (actually, only the one file in this
        case) described as tuples of (path, logical name).  The path lies in
        the directory managed by `store` and has a filename based on `tag`,
        not logical name.
    """
    maaslog.debug("Inserting file %s (tag=%s, size=%s).", name, tag, size)
    store.insert(tag, content_source, checksums, mutable=False, size=size)
    # XXX jtv 2014-04-24 bug=1313580: Isn't _fullpath meant to be private?
    return [(store._fullpath(tag), name)]
Ejemplo n.º 4
0
def insert_root_image(store, tag, checksums, size, content_source):
    """Insert a root image into `store`.

    This may involve converting a UEC boot image into a root tarball.

    :param store: A simplestreams `ObjectStore`.
    :param tag: UUID, or "tag," for the file root image file.  The root image
        and root tarball will both be stored in the cache directory under
        names derived from this tag.
    :param checksums: A Simplestreams checksums dict, mapping hash algorihm
        names (such as `sha256`) to the file's respective checksums as
        computed by those hash algorithms.
    :param size: Optional size for the file, so Simplestreams knows what size
        to expect.
    :param content_source: A Simplestreams `ContentSource` for reading the
        file.
    :return: A list of inserted files (root image and root tarball) described
        as tuples of (path, logical name).  The path lies in the directory
        managed by `store` and has a filename based on `tag`, not logical name.
    """
    maaslog.debug("Inserting root image (tag=%s, size=%s).", tag, size)
    root_image_tag = 'root-image-%s' % tag
    # XXX jtv 2014-04-24 bug=1313580: Isn't _fullpath meant to be private?
    root_image_path = store._fullpath(root_image_tag)
    root_tgz_tag = 'root-tgz-%s' % tag
    root_tgz_path = store._fullpath(root_tgz_tag)
    if not os.path.isfile(root_image_path):
        maaslog.debug("New root image: %s.", root_image_path)
        store.insert(tag, content_source, checksums, mutable=False, size=size)
        uncompressed = FdContentSource(GzipFile(store._fullpath(tag)))
        store.insert(root_image_tag, uncompressed, mutable=False)
        store.remove(tag)
    if not os.path.isfile(root_tgz_path):
        maaslog.debug("Converting root tarball: %s.", root_tgz_path)
        call_uec2roottar(root_image_path, root_tgz_path)
    return [(root_image_path, 'root-image'), (root_tgz_path, 'root-tgz')]