static gboolean do_print_variant_generic (const GVariantType *type, const char *filename, GError **error) { gboolean ret = FALSE; gs_unref_object GFile *f = NULL; gs_unref_variant GVariant *variant = NULL; f = g_file_new_for_path (filename); if (!ot_util_variant_map (f, type, TRUE, &variant, error)) goto out; ot_dump_variant (variant); ret = TRUE; out: return ret; }
static void meta_fetch_on_complete (GObject *object, GAsyncResult *result, gpointer user_data) { FetchObjectData *fetch_data = user_data; OtPullData *pull_data = fetch_data->pull_data; gs_unref_variant GVariant *metadata = NULL; const char *checksum; OstreeObjectType objtype; GError *local_error = NULL; GError **error = &local_error; ostree_object_name_deserialize (fetch_data->object, &checksum, &objtype); g_debug ("fetch of %s complete", ostree_object_to_string (checksum, objtype)); fetch_data->temp_path = ostree_fetcher_request_uri_with_partial_finish ((OstreeFetcher*)object, result, error); if (!fetch_data->temp_path) { if (!g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) goto out; else if (fetch_data->is_detached_meta) { /* There isn't any detached metadata, just fetch the commit */ g_clear_error (&local_error); enqueue_one_object_request (pull_data, fetch_data->object, FALSE); } goto out; } if (fetch_data->is_detached_meta) { if (!ot_util_variant_map (fetch_data->temp_path, G_VARIANT_TYPE ("a{sv}"), FALSE, &metadata, error)) goto out; if (!ostree_repo_write_commit_detached_metadata (pull_data->repo, checksum, metadata, pull_data->cancellable, error)) goto out; enqueue_one_object_request (pull_data, fetch_data->object, FALSE); } else { if (!ot_util_variant_map (fetch_data->temp_path, ostree_metadata_variant_type (objtype), FALSE, &metadata, error)) goto out; ostree_repo_write_metadata_async (pull_data->repo, objtype, checksum, metadata, pull_data->cancellable, on_metadata_writed, fetch_data); pull_data->n_outstanding_metadata_write_requests++; } out: pull_data->n_outstanding_metadata_fetches--; pull_data->n_fetched_metadata++; throw_async_error (pull_data, local_error); if (local_error) { g_variant_unref (fetch_data->object); g_free (fetch_data); } }
/** * ostree_repo_static_delta_execute_offline: * @self: Repo * @dir: Path to a directory containing static delta data * @skip_validation: If %TRUE, assume data integrity * @cancellable: Cancellable * @error: Error * * Given a directory representing an already-downloaded static delta * on disk, apply it, generating a new commit. The directory must be * named with the form "FROM-TO", where both are checksums, and it * must contain a file named "superblock", along with at least one part. */ gboolean ostree_repo_static_delta_execute_offline (OstreeRepo *self, GFile *dir, gboolean skip_validation, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; guint i, n; gs_unref_object GFile *meta_file = g_file_get_child (dir, "superblock"); gs_unref_variant GVariant *meta = NULL; gs_unref_variant GVariant *headers = NULL; gs_unref_variant GVariant *fallback = NULL; if (!ot_util_variant_map (meta_file, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT), FALSE, &meta, error)) goto out; /* Parsing OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT */ /* Write the to-commit object */ { gs_unref_variant GVariant *to_csum_v = NULL; gs_free char *to_checksum = NULL; gs_unref_variant GVariant *to_commit = NULL; gboolean have_to_commit; to_csum_v = g_variant_get_child_value (meta, 3); if (!ostree_validate_structureof_csum_v (to_csum_v, error)) goto out; to_checksum = ostree_checksum_from_bytes_v (to_csum_v); if (!ostree_repo_has_object (self, OSTREE_OBJECT_TYPE_COMMIT, to_checksum, &have_to_commit, cancellable, error)) goto out; if (!have_to_commit) { to_commit = g_variant_get_child_value (meta, 4); if (!ostree_repo_write_metadata (self, OSTREE_OBJECT_TYPE_COMMIT, to_checksum, to_commit, NULL, cancellable, error)) goto out; } } fallback = g_variant_get_child_value (meta, 7); if (g_variant_n_children (fallback) > 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Cannot execute delta offline: contains nonempty http fallback entries"); goto out; } headers = g_variant_get_child_value (meta, 6); n = g_variant_n_children (headers); for (i = 0; i < n; i++) { guint64 size; guint64 usize; const guchar *csum; gboolean have_all; gs_unref_variant GVariant *header = NULL; gs_unref_variant GVariant *csum_v = NULL; gs_unref_variant GVariant *objects = NULL; gs_unref_object GFile *part_path = NULL; gs_unref_object GInputStream *raw_in = NULL; gs_unref_object GInputStream *in = NULL; header = g_variant_get_child_value (headers, i); g_variant_get (header, "(@aytt@ay)", &csum_v, &size, &usize, &objects); if (!_ostree_repo_static_delta_part_have_all_objects (self, objects, &have_all, cancellable, error)) goto out; /* If we already have these objects, don't bother executing the * static delta. */ if (have_all) continue; csum = ostree_checksum_bytes_peek_validate (csum_v, error); if (!csum) goto out; part_path = ot_gfile_resolve_path_printf (dir, "%u", i); in = (GInputStream*)g_file_read (part_path, cancellable, error); if (!in) goto out; if (!skip_validation) { gs_free char *expected_checksum = ostree_checksum_from_bytes (csum); if (!_ostree_static_delta_part_validate (self, part_path, i, expected_checksum, cancellable, error)) goto out; } { GMappedFile *mfile = gs_file_map_noatime (part_path, cancellable, error); gs_unref_bytes GBytes *bytes = NULL; if (!mfile) goto out; bytes = g_mapped_file_get_bytes (mfile); g_mapped_file_unref (mfile); if (!_ostree_static_delta_part_execute (self, objects, bytes, cancellable, error)) { g_prefix_error (error, "executing delta part %i: ", i); goto out; } } } ret = TRUE; out: return ret; }