def _import_layers_into_ostree(repo, imagebranch, manifest, layers): repo.prepare_transaction() for layer, tar in layers.items(): mtree = OSTree.MutableTree() def filter_func(*args): info = args[2] if info.get_file_type() == Gio.FileType.DIRECTORY: info.set_attribute_uint32( "unix::mode", info.get_attribute_uint32("unix::mode") | stat.S_IWUSR) return OSTree.RepoCommitFilterResult.ALLOW modifier = OSTree.RepoCommitModifier.new(0, filter_func, None) repo.write_archive_to_mtree(Gio.File.new_for_path(tar), mtree, modifier, True) root = repo.write_mtree(mtree)[1] metav = GLib.Variant("a{sv}", {'docker.layer': GLib.Variant('s', layer)}) csum = repo.write_commit(None, "", None, metav, root)[1] repo.transaction_set_ref(None, "%s%s" % (OSTREE_OCIIMAGE_PREFIX, layer), csum) # create a $OSTREE_OCIIMAGE_PREFIX$image-$tag branch if not isinstance(manifest, str): manifest = json.dumps(manifest) metadata = GLib.Variant( "a{sv}", {'docker.manifest': GLib.Variant('s', manifest)}) mtree = OSTree.MutableTree() file_info = Gio.FileInfo() file_info.set_attribute_uint32("unix::uid", 0) file_info.set_attribute_uint32("unix::gid", 0) file_info.set_attribute_uint32("unix::mode", 0o755 | stat.S_IFDIR) dirmeta = OSTree.create_directory_metadata(file_info, None) csum_dirmeta = repo.write_metadata(OSTree.ObjectType.DIR_META, None, dirmeta)[1] mtree.set_metadata_checksum(OSTree.checksum_from_bytes(csum_dirmeta)) root = repo.write_mtree(mtree)[1] csum = repo.write_commit(None, "", None, metadata, root)[1] repo.transaction_set_ref(None, imagebranch, csum) repo.commit_transaction(None)
def setUp(self): self.tmp = tempfile.TemporaryDirectory() self.repo = OSTree.Repo.new(Gio.File.new_for_path(self.tmp.name)) self.repo.set_disable_fsync(True) self.repo.create(OSTree.RepoMode.BARE_USER_ONLY) self.mtree = OSTree.MutableTree()
def _import_layers_into_ostree(repo, imagebranch, manifest, layers): repo.prepare_transaction() for layer, tar in layers.items(): mtree = OSTree.MutableTree() def filter_func(*args): info = args[2] if info.get_file_type() == Gio.FileType.DIRECTORY: info.set_attribute_uint32("unix::mode", info.get_attribute_uint32("unix::mode") | stat.S_IWUSR) return OSTree.RepoCommitFilterResult.ALLOW modifier = OSTree.RepoCommitModifier.new(0, filter_func, None) metav = GLib.Variant("a{sv}", {'docker.layer': GLib.Variant('s', layer)}) imported = False try: repo.write_archive_to_mtree(Gio.File.new_for_path(tar), mtree, modifier, True) root = repo.write_mtree(mtree)[1] csum = repo.write_commit(None, "", None, metav, root)[1] imported = True except GLib.GError as e: #pylint: disable=catching-non-exception # libarchive which is used internally by OSTree to import a tarball doesn't support correctly # files with xattrs. If that happens, extract the tarball and import the directory. if e.domain != "g-io-error-quark": # pylint: disable=no-member raise e #pylint: disable=raising-non-exception if not imported: try: temp_dir = tempfile.mkdtemp() with tarfile.open(tar, 'r') as t: t.extractall(temp_dir) repo.write_directory_to_mtree(Gio.File.new_for_path(temp_dir), mtree, modifier) root = repo.write_mtree(mtree)[1] csum = repo.write_commit(None, "", None, metav, root)[1] finally: shutil.rmtree(temp_dir) root = repo.write_mtree(mtree)[1] csum = repo.write_commit(None, "", None, metav, root)[1] repo.transaction_set_ref(None, "%s%s" % (OSTREE_OCIIMAGE_PREFIX, layer), csum) # create a $OSTREE_OCIIMAGE_PREFIX$image-$tag branch if not isinstance(manifest, str): manifest = json.dumps(manifest) metadata = GLib.Variant("a{sv}", {'docker.manifest': GLib.Variant('s', manifest)}) mtree = OSTree.MutableTree() file_info = Gio.FileInfo() file_info.set_attribute_uint32("unix::uid", 0) file_info.set_attribute_uint32("unix::gid", 0) file_info.set_attribute_uint32("unix::mode", 0o755 | stat.S_IFDIR) dirmeta = OSTree.create_directory_metadata(file_info, None) csum_dirmeta = repo.write_metadata(OSTree.ObjectType.DIR_META, None, dirmeta)[1] mtree.set_metadata_checksum(OSTree.checksum_from_bytes(csum_dirmeta)) root = repo.write_mtree(mtree)[1] csum = repo.write_commit(None, "", None, metadata, root)[1] repo.transaction_set_ref(None, imagebranch, csum) repo.commit_transaction(None)