summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/flatpak-dir.c110
-rw-r--r--data/flatpak-variants.gv5
2 files changed, 85 insertions, 30 deletions
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
index f8c126ea..2e2a710a 100644
--- a/common/flatpak-dir.c
+++ b/common/flatpak-dir.c
@@ -559,6 +559,21 @@ flatpak_remote_state_match_subrefs (FlatpakRemoteState *self,
return flatpak_summary_match_subrefs (self->summary, NULL, ref);
}
+/* 0 if not specified */
+static guint32
+flatpak_remote_state_get_cache_version (FlatpakRemoteState *self)
+{
+ VarMetadataRef meta;
+ VarSummaryRef summary;
+
+ if (!flatpak_remote_state_ensure_summary (self, NULL))
+ return 0;
+
+ summary = var_summary_from_gvariant (self->summary);
+ meta = var_summary_get_metadata (summary);
+
+ return GUINT32_FROM_LE (var_metadata_lookup_uint32 (meta, "xa.cache-version", 0));
+}
static gboolean
flatpak_remote_state_get_cache (FlatpakRemoteState *self,
@@ -4626,6 +4641,37 @@ extra_data_progress_report (guint64 downloaded_bytes,
flatpak_progress_update_extra_data (progress, downloaded_bytes);
}
+static void
+compute_extra_data_download_size (GVariant *commitv,
+ guint64 *out_n_extra_data,
+ guint64 *out_total_download_size)
+{
+ guint64 i;
+ guint64 n_extra_data = 0;
+ guint64 total_download_size = 0;
+ g_autoptr(GVariant) extra_data_sources = NULL;
+
+ extra_data_sources = flatpak_commit_get_extra_data_sources (commitv, NULL);
+ if (extra_data_sources != NULL)
+ {
+ n_extra_data = g_variant_n_children (extra_data_sources);
+ for (i = 0; i < n_extra_data; i++)
+ {
+ guint64 download_size;
+ flatpak_repo_parse_extra_data_sources (extra_data_sources, i,
+ NULL,
+ &download_size,
+ NULL,
+ NULL,
+ NULL);
+ total_download_size += download_size;
+ }
+ }
+
+ *out_n_extra_data = n_extra_data;
+ *out_total_download_size = total_download_size;
+}
+
static gboolean
flatpak_dir_setup_extra_data (FlatpakDir *self,
FlatpakRemoteState *state,
@@ -4639,47 +4685,51 @@ flatpak_dir_setup_extra_data (FlatpakDir *self,
GCancellable *cancellable,
GError **error)
{
- g_autoptr(GVariant) extra_data_sources = NULL;
- guint64 i;
- guint64 n_extra_data;
- guint64 total_download_size;
+ guint64 n_extra_data = 0;
+ guint64 total_download_size = 0;
/* ostree-metadata and appstreams never have extra data, so ignore those */
if (g_str_has_prefix (ref, "app/") || g_str_has_prefix (ref, "runtime/"))
{
- g_autoptr(GVariant) commitv = flatpak_remote_state_load_ref_commit (state, self, ref, rev, token, error);
- if (commitv == NULL)
- return FALSE;
+ g_autofree char *summary_checksum = NULL;
- extra_data_sources = flatpak_commit_get_extra_data_sources (commitv, NULL);
- }
-
- n_extra_data = 0;
- total_download_size = 0;
-
- if (extra_data_sources != NULL)
- n_extra_data = g_variant_n_children (extra_data_sources);
-
- if (n_extra_data > 0)
- {
- if ((flatpak_flags & FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA) == 0)
- return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED, _("Extra data not supported for non-gpg-verified local system installs"));
-
- for (i = 0; i < n_extra_data; i++)
+ /* Version 1 added extra data details, so we can rely on it
+ * either being in the sparse cache or no extra data. However,
+ * it only applies to the commit the summary contains, so verify
+ * that too.
+ */
+ if (state->summary &&
+ flatpak_summary_lookup_ref (state->summary, NULL, ref, &summary_checksum, NULL) &&
+ g_strcmp0 (rev, summary_checksum) == 0 &&
+ flatpak_remote_state_get_cache_version (state) >= 1)
{
- guint64 download_size;
+ VarMetadataRef metadata;
+ VarVariantRef res;
- flatpak_repo_parse_extra_data_sources (extra_data_sources, i,
- NULL,
- &download_size,
- NULL,
- NULL,
- NULL);
+ if (flatpak_remote_state_lookup_sparse_cache (state, ref, &metadata, NULL) &&
+ var_metadata_lookup (metadata, FLATPAK_SPARSE_CACHE_KEY_EXTRA_DATA_SIZE, NULL, &res) &&
+ var_variant_is_type (res, VAR_EXTRA_DATA_SIZE_TYPEFORMAT))
+ {
+ VarExtraDataSizeRef eds = var_extra_data_size_from_variant (res);
+ n_extra_data = var_extra_data_size_get_n_extra_data (eds);
+ total_download_size = var_extra_data_size_get_total_size (eds);
+ }
+ }
+ else
+ {
+ /* No summary/cache or old cache version, download commit and get size from there */
+ g_autoptr(GVariant) commitv = flatpak_remote_state_load_ref_commit (state, self, ref, rev, token, error);
+ if (commitv == NULL)
+ return FALSE;
- total_download_size += download_size;
+ compute_extra_data_download_size (commitv, &n_extra_data, &total_download_size);
}
}
+ if (n_extra_data > 0 &&
+ (flatpak_flags & FLATPAK_PULL_FLAGS_DOWNLOAD_EXTRA_DATA) == 0)
+ return flatpak_fail_error (error, FLATPAK_ERROR_UNTRUSTED, _("Extra data not supported for non-gpg-verified local system installs"));
+
flatpak_progress_init_extra_data (progress, n_extra_data, total_download_size);
return TRUE;
diff --git a/data/flatpak-variants.gv b/data/flatpak-variants.gv
index f3434d29..c2f6fd4f 100644
--- a/data/flatpak-variants.gv
+++ b/data/flatpak-variants.gv
@@ -57,3 +57,8 @@ type ContentRating {
rating_type: string;
ratings: 'Ratings [string] string;
};
+
+type ExtraDataSize {
+ n_extra_data: littleendian uint32;
+ total_size: littleendian uint64;
+};