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;
|
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
|
gboolean
|
||||||
ostree_repo_load_file (OstreeRepo *self,
|
ostree_repo_load_file (OstreeRepo *self,
|
||||||
const char *checksum,
|
const char *checksum,
|
||||||
|
|
@ -2164,6 +2231,49 @@ ostree_repo_load_file (OstreeRepo *self,
|
||||||
return ret;
|
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
|
static gboolean
|
||||||
repo_find_object (OstreeRepo *self,
|
repo_find_object (OstreeRepo *self,
|
||||||
OstreeObjectType objtype,
|
OstreeObjectType objtype,
|
||||||
|
|
@ -2305,50 +2415,6 @@ ostree_repo_load_variant_c (OstreeRepo *self,
|
||||||
return ret;
|
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:
|
* ostree_repo_load_variant_if_exists:
|
||||||
*
|
*
|
||||||
|
|
@ -2363,8 +2429,8 @@ ostree_repo_load_variant_if_exists (OstreeRepo *self,
|
||||||
GVariant **out_variant,
|
GVariant **out_variant,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
return load_variant_internal (self, objtype, sha256, FALSE,
|
return load_metadata_internal (self, objtype, sha256, FALSE,
|
||||||
out_variant, error);
|
out_variant, NULL, NULL, NULL, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2385,11 +2451,10 @@ ostree_repo_load_variant (OstreeRepo *self,
|
||||||
GVariant **out_variant,
|
GVariant **out_variant,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
return load_variant_internal (self, objtype, sha256, TRUE,
|
return load_metadata_internal (self, objtype, sha256, TRUE,
|
||||||
out_variant, error);
|
out_variant, NULL, NULL, NULL, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ostree_repo_list_objects:
|
* ostree_repo_list_objects:
|
||||||
* @self:
|
* @self:
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,14 @@ gboolean ostree_repo_load_file (OstreeRepo *self,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
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,
|
gboolean ostree_repo_query_object_storage_size (OstreeRepo *self,
|
||||||
OstreeObjectType objtype,
|
OstreeObjectType objtype,
|
||||||
const char *sha256,
|
const char *sha256,
|
||||||
|
|
|
||||||
|
|
@ -68,18 +68,10 @@ import_one_object (OtLocalCloneData *data,
|
||||||
{
|
{
|
||||||
guint64 length;
|
guint64 length;
|
||||||
gs_unref_object GInputStream *file_object = NULL;
|
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,
|
if (!ostree_repo_load_object_stream (data->src_repo, objtype, checksum,
|
||||||
&input, &file_info, &xattrs,
|
&file_object, &length,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!ostree_raw_file_to_content_stream (input, file_info, xattrs,
|
|
||||||
&file_object, &length,
|
|
||||||
cancellable, error))
|
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!ostree_repo_stage_content_trusted (data->dest_repo, checksum,
|
if (!ostree_repo_stage_content_trusted (data->dest_repo, checksum,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue