Add repository "summary" file and metalink support

For Fedora and potentially other distributions which use globally
distributed mirrors, metalink is a popular solution to redirect
clients to a dynamic set of mirrors.

In order to make metalink work though, it needs *one* file which can
be checksummed.  (Well, potentially we could explode all refs into the
metalink.xml, but that would be a lot more invasive, and a bit weird
as we'd end up checksumming the checksum file).

This commit adds a new command:

$ ostree summary -u

To regenerate the summary file.  Can only be run by one process at a
time.

After that's done, the metalink can be generated based on it, and the
client fetch code will parse and load it.

https://bugzilla.gnome.org/show_bug.cgi?id=729585
This commit is contained in:
Colin Walters committed 2014-09-03 13:21:52 -04:00
1 parent 3571418557
commit f8f5da219e
17 files changed
+1352 -27

No files matched your search

+26
View File
@@ -139,6 +139,32 @@ ot_gio_checksum_stream (GInputStream *in,
return ot_gio_splice_get_checksum (NULL, in, out_csum, cancellable, error);
}
char *
ot_checksum_file (GFile *file,
GChecksumType checksum_type,
GCancellable *cancellable,
GError **error)
{
GChecksum *checksum = NULL;
char *ret = NULL;
gs_unref_object GInputStream *in = NULL;
in = (GInputStream*)g_file_read (file, cancellable, error);
if (!in)
goto out;
checksum = g_checksum_new (checksum_type);
if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error))
goto out;
ret = g_strdup (g_checksum_get_string (checksum));
out:
g_clear_pointer (&checksum, (GDestroyNotify) g_checksum_free);
return ret;
}
static void
checksum_stream_thread (GSimpleAsyncResult *result,
GObject *object,
+5
View File
@@ -53,6 +53,11 @@ gboolean ot_gio_checksum_stream (GInputStream *in,
GCancellable *cancellable,
GError **error);
char * ot_checksum_file (GFile *file,
GChecksumType checksum_type,
GCancellable *cancellable,
GError **error);
void ot_gio_checksum_stream_async (GInputStream *in,
int io_priority,
GCancellable *cancellable,
+64
View File
@@ -30,6 +30,12 @@
#include "otutil.h"
GVariant *
ot_gvariant_new_empty_string_dict (void)
{
return g_variant_builder_end (g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")));
}
GVariant *
ot_gvariant_new_bytearray (const guchar *data,
gsize len)
@@ -282,3 +288,61 @@ ot_variant_new_from_bytes (const GVariantType *type,
(GDestroyNotify)g_bytes_unref, bytes);
#endif
}
/**
* ot_variant_bsearch_str:
* @array: A GVariant array whose first element must be a string
* @str: Search for this string
* @out_pos: Output position
*
*
* Binary search in a GVariant array, which must be of the form 'a(s...)',
* where '...' may be anything. The array elements must be sorted.
*
* Returns: %TRUE if found, %FALSE otherwise
*/
gboolean
ot_variant_bsearch_str (GVariant *array,
const char *str,
int *out_pos)
{
gsize imax, imin;
gsize imid;
gsize n;
n = g_variant_n_children (array);
if (n == 0)
return FALSE;
imax = n - 1;
imin = 0;
while (imax >= imin)
{
gs_unref_variant GVariant *child = NULL;
const char *cur;
int cmp;
imid = (imin + imax) / 2;
child = g_variant_get_child_value (array, imid);
g_variant_get_child (child, 0, "&s", &cur, NULL);
cmp = strcmp (cur, str);
if (cmp < 0)
imin = imid + 1;
else if (cmp > 0)
{
if (imid == 0)
break;
imax = imid - 1;
}
else
{
*out_pos = imid;
return TRUE;
}
}
*out_pos = imid;
return FALSE;
}
+7
View File
@@ -31,6 +31,8 @@ GVariant *ot_gvariant_new_bytearray (const guchar *data,
GVariant *ot_gvariant_new_ay_bytes (GBytes *bytes);
GVariant *ot_gvariant_new_empty_string_dict (void);
GHashTable *ot_util_variant_asv_to_hash_table (GVariant *variant);
GVariant * ot_util_variant_take_ref (GVariant *variant);
@@ -70,5 +72,10 @@ ot_variant_new_from_bytes (const GVariantType *type,
GBytes *bytes,
gboolean trusted);
gboolean
ot_variant_bsearch_str (GVariant *array,
const char *str,
int *out_pos);
G_END_DECLS