static gboolean do_print_metadata_key (OstreeRepo *repo, const char *resolved_rev, gboolean detached, const char *key, GError **error) { gboolean ret = FALSE; gs_unref_variant GVariant *value = NULL; gs_unref_variant GVariant *commit = NULL; gs_unref_variant GVariant *metadata = NULL; if (!detached) { if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, resolved_rev, &commit, error)) goto out; /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */ metadata = g_variant_get_child_value (commit, 0); } else { if (!ostree_repo_read_commit_detached_metadata (repo, resolved_rev, &metadata, NULL, error)) goto out; if (metadata == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No detached metadata for commit %s", resolved_rev); goto out; } } value = g_variant_lookup_value (metadata, key, NULL); if (!value) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, "No such metadata key '%s'", key); goto out; } ot_dump_variant (value); ret = TRUE; out: return ret; }
static gboolean rewrite_delta (OstreeRepo *src_repo, const char *src_commit, OstreeRepo *dst_repo, const char *dst_commit, GVariant *dst_commitv, const char *from, GError **error) { g_autoptr(GFile) src_delta_file = NULL; g_autoptr(GFile) dst_delta_file = NULL; g_autofree char *src_detached_key = _ostree_get_relative_static_delta_path (from, src_commit, "commitmeta"); g_autofree char *dst_detached_key = _ostree_get_relative_static_delta_path (from, dst_commit, "commitmeta"); g_autofree char *src_delta_dir = _ostree_get_relative_static_delta_path (from, src_commit, NULL); g_autofree char *dst_delta_dir = _ostree_get_relative_static_delta_path (from, dst_commit, NULL); g_autofree char *src_superblock_path = _ostree_get_relative_static_delta_path (from, src_commit, "superblock"); g_autofree char *dst_superblock_path = _ostree_get_relative_static_delta_path (from, dst_commit, "superblock"); GMappedFile *mfile = NULL; g_auto(GVariantBuilder) superblock_builder = FLATPAK_VARIANT_BUILDER_INITIALIZER; g_autoptr(GVariant) src_superblock = NULL; g_autoptr(GVariant) dst_superblock = NULL; g_autoptr(GBytes) bytes = NULL; g_autoptr(GVariant) dst_detached = NULL; g_autoptr(GVariant) src_metadata = NULL; g_autoptr(GVariant) src_recurse = NULL; g_autoptr(GVariant) src_parts = NULL; g_auto(GVariantDict) dst_metadata_dict = FLATPAK_VARIANT_DICT_INITIALIZER; int i; src_delta_file = g_file_resolve_relative_path (ostree_repo_get_path (src_repo), src_superblock_path); mfile = g_mapped_file_new (flatpak_file_get_path_cached (src_delta_file), FALSE, NULL); if (mfile == NULL) return TRUE; /* No superblock, not an error */ bytes = g_mapped_file_get_bytes (mfile); g_mapped_file_unref (mfile); src_superblock = g_variant_ref_sink (g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), bytes, FALSE)); src_metadata = g_variant_get_child_value (src_superblock, 0); src_recurse = g_variant_get_child_value (src_superblock, 5); src_parts = g_variant_get_child_value (src_superblock, 6); if (g_variant_n_children (src_recurse) != 0) return flatpak_fail (error, "Recursive deltas not supported, ignoring"); g_variant_builder_init (&superblock_builder, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT)); g_variant_dict_init (&dst_metadata_dict, src_metadata); g_variant_dict_remove (&dst_metadata_dict, src_detached_key); if (ostree_repo_read_commit_detached_metadata (dst_repo, dst_commit, &dst_detached, NULL, NULL) && dst_detached != NULL) g_variant_dict_insert_value (&dst_metadata_dict, dst_detached_key, dst_detached); g_variant_builder_add_value (&superblock_builder, g_variant_dict_end (&dst_metadata_dict)); g_variant_builder_add_value (&superblock_builder, g_variant_get_child_value (src_superblock, 1)); /* timestamp */ g_variant_builder_add_value (&superblock_builder, from ? ostree_checksum_to_bytes_v (from) : new_bytearray ((guchar *) "", 0)); g_variant_builder_add_value (&superblock_builder, ostree_checksum_to_bytes_v (dst_commit)); g_variant_builder_add_value (&superblock_builder, dst_commitv); g_variant_builder_add_value (&superblock_builder, src_recurse); g_variant_builder_add_value (&superblock_builder, src_parts); g_variant_builder_add_value (&superblock_builder, g_variant_get_child_value (src_superblock, 7)); /* fallback */ dst_superblock = g_variant_ref_sink (g_variant_builder_end (&superblock_builder)); if (!glnx_shutil_mkdir_p_at (ostree_repo_get_dfd (dst_repo), dst_delta_dir, 0755, NULL, error)) return FALSE; for (i = 0; i < g_variant_n_children (src_parts); i++) { g_autofree char *src_part_path = g_strdup_printf ("%s/%d", src_delta_dir, i); g_autofree char *dst_part_path = g_strdup_printf ("%s/%d", dst_delta_dir, i); if (!glnx_file_copy_at (ostree_repo_get_dfd (src_repo), src_part_path, NULL, ostree_repo_get_dfd (dst_repo), dst_part_path, GLNX_FILE_COPY_OVERWRITE | GLNX_FILE_COPY_NOXATTRS, NULL, error)) return FALSE; } dst_delta_file = g_file_resolve_relative_path (ostree_repo_get_path (dst_repo), dst_superblock_path); if (!flatpak_variant_save (dst_delta_file, dst_superblock, NULL, error)) return FALSE; return TRUE; }