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
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)
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)]
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')]