Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}