repo: Add API to load any object as a stream
We have APIs to load metadata as variants, and files as parsed content/info/xattrs, but for some cases such as static deltas, all we want is to operate on all objects in their canonical representation. https://bugzilla.gnome.org/show_bug.cgi?id=706031
This commit is contained in:
parent
c77908bf51
commit
11bdbe1fb8
|
|
@ -1 +1 @@
|
|||
Subproject commit 4150e6336881faec1a31f557567ca89c283b38c9
|
||||
Subproject commit 4501b425953c3849112206c4a3f6f27cd3264936
|
||||
|
|
@ -2041,6 +2041,73 @@ list_loose_objects (OstreeRepo *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_metadata_internal (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *sha256,
|
||||
gboolean error_if_not_found,
|
||||
GVariant **out_variant,
|
||||
GInputStream **out_stream,
|
||||
guint64 *out_size,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_unref_object GFile *object_path = NULL;
|
||||
gs_unref_object GInputStream *ret_stream = NULL;
|
||||
gs_unref_variant GVariant *ret_variant = NULL;
|
||||
|
||||
g_return_val_if_fail (OSTREE_OBJECT_TYPE_IS_META (objtype), FALSE);
|
||||
|
||||
if (!repo_find_object (self, objtype, sha256, &object_path,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (object_path != NULL)
|
||||
{
|
||||
if (out_variant)
|
||||
{
|
||||
if (!ot_util_variant_map (object_path, ostree_metadata_variant_type (objtype),
|
||||
TRUE, &ret_variant, error))
|
||||
goto out;
|
||||
if (out_size)
|
||||
*out_size = g_variant_get_size (ret_variant);
|
||||
}
|
||||
else if (out_stream)
|
||||
{
|
||||
ret_stream = gs_file_read_noatime (object_path, cancellable, error);
|
||||
if (!ret_stream)
|
||||
goto out;
|
||||
if (out_size)
|
||||
{
|
||||
struct stat stbuf;
|
||||
|
||||
if (!gs_stream_fstat ((GFileDescriptorBased*)ret_stream, &stbuf, cancellable, error))
|
||||
goto out;
|
||||
*out_size = stbuf.st_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (self->parent_repo)
|
||||
{
|
||||
if (!ostree_repo_load_variant (self->parent_repo, objtype, sha256, &ret_variant, error))
|
||||
goto out;
|
||||
}
|
||||
else if (error_if_not_found)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"No such metadata object %s.%s",
|
||||
sha256, ostree_object_type_to_string (objtype));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_variant, &ret_variant);
|
||||
ot_transfer_out_value (out_stream, &ret_stream);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_repo_load_file (OstreeRepo *self,
|
||||
const char *checksum,
|
||||
|
|
@ -2164,6 +2231,49 @@ ostree_repo_load_file (OstreeRepo *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_repo_load_object_stream (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *checksum,
|
||||
GInputStream **out_input,
|
||||
guint64 *out_size,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guint64 size;
|
||||
gs_unref_object GInputStream *ret_input = NULL;
|
||||
|
||||
if (OSTREE_OBJECT_TYPE_IS_META (objtype))
|
||||
{
|
||||
if (!load_metadata_internal (self, objtype, checksum, TRUE, NULL,
|
||||
&ret_input, &size,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
gs_unref_object GInputStream *input = NULL;
|
||||
gs_unref_object GFileInfo *finfo = NULL;
|
||||
gs_unref_variant GVariant *xattrs = NULL;
|
||||
|
||||
if (!ostree_repo_load_file (self, checksum, &input, &finfo, &xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_raw_file_to_content_stream (input, finfo, xattrs,
|
||||
&ret_input, &size,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_input, &ret_input);
|
||||
*out_size = size;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
repo_find_object (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
|
|
@ -2305,50 +2415,6 @@ ostree_repo_load_variant_c (OstreeRepo *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_variant_internal (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *sha256,
|
||||
gboolean error_if_not_found,
|
||||
GVariant **out_variant,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GCancellable *cancellable = NULL;
|
||||
gs_unref_object GFile *object_path = NULL;
|
||||
gs_unref_variant GVariant *ret_variant = NULL;
|
||||
|
||||
g_return_val_if_fail (OSTREE_OBJECT_TYPE_IS_META (objtype), FALSE);
|
||||
|
||||
if (!repo_find_object (self, objtype, sha256, &object_path,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (object_path != NULL)
|
||||
{
|
||||
if (!ot_util_variant_map (object_path, ostree_metadata_variant_type (objtype),
|
||||
TRUE, &ret_variant, error))
|
||||
goto out;
|
||||
}
|
||||
else if (self->parent_repo)
|
||||
{
|
||||
if (!ostree_repo_load_variant (self->parent_repo, objtype, sha256, &ret_variant, error))
|
||||
goto out;
|
||||
}
|
||||
else if (error_if_not_found)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"No such metadata object %s.%s",
|
||||
sha256, ostree_object_type_to_string (objtype));
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_variant, &ret_variant);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_repo_load_variant_if_exists:
|
||||
*
|
||||
|
|
@ -2363,8 +2429,8 @@ ostree_repo_load_variant_if_exists (OstreeRepo *self,
|
|||
GVariant **out_variant,
|
||||
GError **error)
|
||||
{
|
||||
return load_variant_internal (self, objtype, sha256, FALSE,
|
||||
out_variant, error);
|
||||
return load_metadata_internal (self, objtype, sha256, FALSE,
|
||||
out_variant, NULL, NULL, NULL, error);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2385,11 +2451,10 @@ ostree_repo_load_variant (OstreeRepo *self,
|
|||
GVariant **out_variant,
|
||||
GError **error)
|
||||
{
|
||||
return load_variant_internal (self, objtype, sha256, TRUE,
|
||||
out_variant, error);
|
||||
return load_metadata_internal (self, objtype, sha256, TRUE,
|
||||
out_variant, NULL, NULL, NULL, error);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ostree_repo_list_objects:
|
||||
* @self:
|
||||
|
|
|
|||
|
|
@ -198,6 +198,14 @@ gboolean ostree_repo_load_file (OstreeRepo *self,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_load_object_stream (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *checksum,
|
||||
GInputStream **out_input,
|
||||
guint64 *out_size,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_query_object_storage_size (OstreeRepo *self,
|
||||
OstreeObjectType objtype,
|
||||
const char *sha256,
|
||||
|
|
|
|||
|
|
@ -68,18 +68,10 @@ import_one_object (OtLocalCloneData *data,
|
|||
{
|
||||
guint64 length;
|
||||
gs_unref_object GInputStream *file_object = NULL;
|
||||
gs_unref_object GInputStream *input = NULL;
|
||||
gs_unref_object GFileInfo *file_info = NULL;
|
||||
gs_unref_variant GVariant *xattrs = NULL;
|
||||
|
||||
if (!ostree_repo_load_file (data->src_repo, checksum,
|
||||
&input, &file_info, &xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_raw_file_to_content_stream (input, file_info, xattrs,
|
||||
&file_object, &length,
|
||||
cancellable, error))
|
||||
if (!ostree_repo_load_object_stream (data->src_repo, objtype, checksum,
|
||||
&file_object, &length,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_stage_content_trusted (data->dest_repo, checksum,
|
||||
|
|
|
|||
Loading…
Reference in New Issue