mirror of
https://github.com/ostreedev/ostree.git
synced 2024-12-22 17:35:55 +03:00
lib/repo-refs: Add ostree_repo_remote_list_collection_refs() API
This parallels ostree_repo_remote_list_refs(), but returns a map of OstreeCollectionRef → checksum, and includes refs from collection IDs other than the remote repository’s main collection ID. Use this in OstreeRepoFinderConfig to ensure that refs are matched against even if they’re stored in the repository summary file’s collection map, rather than its main ref map. This fixes false negatives when searching for refs in some situations. Signed-off-by: Philip Withnall <withnall@endlessm.com> Closes: #1058 Approved by: cgwalters
This commit is contained in:
parent
11e165b154
commit
f35b409077
@ -82,6 +82,7 @@ ostree_repo_get_collection_id
|
|||||||
ostree_repo_set_collection_id
|
ostree_repo_set_collection_id
|
||||||
ostree_validate_collection_id
|
ostree_validate_collection_id
|
||||||
ostree_repo_list_collection_refs
|
ostree_repo_list_collection_refs
|
||||||
|
ostree_repo_remote_list_collection_refs
|
||||||
ostree_repo_set_collection_ref_immediate
|
ostree_repo_set_collection_ref_immediate
|
||||||
ostree_repo_transaction_set_collection_ref
|
ostree_repo_transaction_set_collection_ref
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
@ -70,6 +70,7 @@ global:
|
|||||||
ostree_repo_list_collection_refs;
|
ostree_repo_list_collection_refs;
|
||||||
ostree_repo_pull_from_remotes_async;
|
ostree_repo_pull_from_remotes_async;
|
||||||
ostree_repo_pull_from_remotes_finish;
|
ostree_repo_pull_from_remotes_finish;
|
||||||
|
ostree_repo_remote_list_collection_refs;
|
||||||
ostree_repo_resolve_keyring_for_collection;
|
ostree_repo_resolve_keyring_for_collection;
|
||||||
ostree_repo_set_collection_id;
|
ostree_repo_set_collection_id;
|
||||||
ostree_repo_set_collection_ref_immediate;
|
ostree_repo_set_collection_ref_immediate;
|
||||||
|
@ -111,7 +111,7 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find
|
|||||||
for (i = 0; i < n_remotes; i++)
|
for (i = 0; i < n_remotes; i++)
|
||||||
{
|
{
|
||||||
g_autoptr(GError) local_error = NULL;
|
g_autoptr(GError) local_error = NULL;
|
||||||
g_autoptr(GHashTable) remote_refs = NULL; /* (element-type utf8 utf8) */
|
g_autoptr(GHashTable) remote_refs = NULL; /* (element-type OstreeCollectionRef utf8) */
|
||||||
const gchar *checksum;
|
const gchar *checksum;
|
||||||
g_autofree gchar *remote_collection_id = NULL;
|
g_autofree gchar *remote_collection_id = NULL;
|
||||||
|
|
||||||
@ -127,8 +127,9 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ostree_repo_remote_list_refs (parent_repo, remote_name, &remote_refs,
|
if (!ostree_repo_remote_list_collection_refs (parent_repo, remote_name,
|
||||||
cancellable, &local_error))
|
&remote_refs, cancellable,
|
||||||
|
&local_error))
|
||||||
{
|
{
|
||||||
g_debug ("Ignoring remote ‘%s’ due to error loading its refs: %s",
|
g_debug ("Ignoring remote ‘%s’ due to error loading its refs: %s",
|
||||||
remote_name, local_error->message);
|
remote_name, local_error->message);
|
||||||
@ -139,7 +140,7 @@ ostree_repo_finder_config_resolve_async (OstreeRepoFinder *find
|
|||||||
for (j = 0; refs[j] != NULL; j++)
|
for (j = 0; refs[j] != NULL; j++)
|
||||||
{
|
{
|
||||||
if (g_strcmp0 (refs[j]->collection_id, remote_collection_id) == 0 &&
|
if (g_strcmp0 (refs[j]->collection_id, remote_collection_id) == 0 &&
|
||||||
g_hash_table_lookup_extended (remote_refs, refs[j]->ref_name, NULL, (gpointer *) &checksum))
|
g_hash_table_lookup_extended (remote_refs, refs[j], NULL, (gpointer *) &checksum))
|
||||||
{
|
{
|
||||||
/* The requested ref is listed in the refs for this remote. Add
|
/* The requested ref is listed in the refs for this remote. Add
|
||||||
* the remote to the results, and the ref to its
|
* the remote to the results, and the ref to its
|
||||||
|
@ -779,6 +779,126 @@ ostree_repo_remote_list_refs (OstreeRepo *self,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
|
||||||
|
static gboolean
|
||||||
|
remote_list_collection_refs_process_refs (OstreeRepo *self,
|
||||||
|
const gchar *remote_name,
|
||||||
|
const gchar *summary_collection_id,
|
||||||
|
GVariant *summary_refs,
|
||||||
|
GHashTable *ret_all_refs,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
gsize j, n;
|
||||||
|
|
||||||
|
for (j = 0, n = g_variant_n_children (summary_refs); j < n; j++)
|
||||||
|
{
|
||||||
|
const guchar *csum_bytes;
|
||||||
|
g_autoptr(GVariant) ref_v = NULL, csum_v = NULL;
|
||||||
|
gchar tmp_checksum[OSTREE_SHA256_STRING_LEN + 1];
|
||||||
|
const gchar *ref_name;
|
||||||
|
|
||||||
|
/* Check the ref name. */
|
||||||
|
ref_v = g_variant_get_child_value (summary_refs, j);
|
||||||
|
g_variant_get_child (ref_v, 0, "&s", &ref_name);
|
||||||
|
|
||||||
|
if (!ostree_validate_rev (ref_name, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Check the commit checksum. */
|
||||||
|
g_variant_get_child (ref_v, 1, "(t@ay@a{sv})", NULL, &csum_v, NULL);
|
||||||
|
|
||||||
|
csum_bytes = ostree_checksum_bytes_peek_validate (csum_v, error);
|
||||||
|
if (csum_bytes == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ostree_checksum_inplace_from_bytes (csum_bytes, tmp_checksum);
|
||||||
|
|
||||||
|
g_hash_table_insert (ret_all_refs,
|
||||||
|
ostree_collection_ref_new (summary_collection_id, ref_name),
|
||||||
|
g_strdup (tmp_checksum));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_repo_remote_list_collection_refs:
|
||||||
|
* @self: Repo
|
||||||
|
* @remote_name: Name of the remote.
|
||||||
|
* @out_all_refs: (out) (element-type OstreeCollectionRef utf8): Mapping from collection–ref to checksum
|
||||||
|
* @cancellable: Cancellable
|
||||||
|
* @error: Error
|
||||||
|
*
|
||||||
|
* List refs advertised by @remote_name, including refs which are part of
|
||||||
|
* collections. If the repository at @remote_name has a collection ID set, its
|
||||||
|
* refs will be returned with that collection ID; otherwise, they will be returned
|
||||||
|
* with a %NULL collection ID in each #OstreeCollectionRef key in @out_all_refs.
|
||||||
|
* Any refs for other collections stored in the repository will also be returned.
|
||||||
|
* No filtering is performed.
|
||||||
|
*
|
||||||
|
* Since: 2017.10
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
ostree_repo_remote_list_collection_refs (OstreeRepo *self,
|
||||||
|
const char *remote_name,
|
||||||
|
GHashTable **out_all_refs,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
g_autoptr(GBytes) summary_bytes = NULL;
|
||||||
|
g_autoptr(GHashTable) ret_all_refs = NULL; /* (element-type OstreeCollectionRef utf8) */
|
||||||
|
g_autoptr(GVariant) summary_v = NULL;
|
||||||
|
g_autoptr(GVariant) additional_metadata_v = NULL;
|
||||||
|
g_autoptr(GVariant) summary_refs = NULL;
|
||||||
|
const char *summary_collection_id;
|
||||||
|
g_autoptr(GVariantIter) summary_collection_map = NULL;
|
||||||
|
|
||||||
|
if (!ostree_repo_remote_fetch_summary (self, remote_name,
|
||||||
|
&summary_bytes, NULL,
|
||||||
|
cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (summary_bytes == NULL)
|
||||||
|
return glnx_throw (error, "Remote refs not available; server has no summary file");
|
||||||
|
|
||||||
|
ret_all_refs = g_hash_table_new_full (ostree_collection_ref_hash,
|
||||||
|
ostree_collection_ref_equal,
|
||||||
|
(GDestroyNotify) ostree_collection_ref_free,
|
||||||
|
g_free);
|
||||||
|
|
||||||
|
summary_v = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
|
||||||
|
summary_bytes, FALSE);
|
||||||
|
additional_metadata_v = g_variant_get_child_value (summary_v, 1);
|
||||||
|
|
||||||
|
/* List the refs in the main map. */
|
||||||
|
if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_ID, "&s", &summary_collection_id))
|
||||||
|
summary_collection_id = NULL;
|
||||||
|
|
||||||
|
summary_refs = g_variant_get_child_value (summary_v, 0);
|
||||||
|
|
||||||
|
if (!remote_list_collection_refs_process_refs (self, remote_name,
|
||||||
|
summary_collection_id, summary_refs,
|
||||||
|
ret_all_refs, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* List the refs in the collection map. */
|
||||||
|
if (!g_variant_lookup (additional_metadata_v, OSTREE_SUMMARY_COLLECTION_MAP, "a{sa(s(taya{sv}))}", &summary_collection_map))
|
||||||
|
summary_collection_map = NULL;
|
||||||
|
|
||||||
|
while (summary_collection_map != NULL &&
|
||||||
|
g_variant_iter_loop (summary_collection_map, "{s@a(s(taya{sv}))}", &summary_collection_id, &summary_refs))
|
||||||
|
{
|
||||||
|
if (!remote_list_collection_refs_process_refs (self, remote_name,
|
||||||
|
summary_collection_id, summary_refs,
|
||||||
|
ret_all_refs, error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ot_transfer_out_value (out_all_refs, &ret_all_refs);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
relative_symlink_to (const char *relpath,
|
relative_symlink_to (const char *relpath,
|
||||||
const char *target)
|
const char *target)
|
||||||
|
@ -482,6 +482,15 @@ gboolean ostree_repo_remote_list_refs (OstreeRepo *self,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
|
||||||
|
_OSTREE_PUBLIC
|
||||||
|
gboolean ostree_repo_remote_list_collection_refs (OstreeRepo *self,
|
||||||
|
const char *remote_name,
|
||||||
|
GHashTable **out_all_refs,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error);
|
||||||
|
#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
|
||||||
|
|
||||||
_OSTREE_PUBLIC
|
_OSTREE_PUBLIC
|
||||||
gboolean ostree_repo_load_variant (OstreeRepo *self,
|
gboolean ostree_repo_load_variant (OstreeRepo *self,
|
||||||
OstreeObjectType objtype,
|
OstreeObjectType objtype,
|
||||||
|
Loading…
Reference in New Issue
Block a user