diff --git a/app/flatpak-builtins-create-usb.c b/app/flatpak-builtins-create-usb.c index 1e8e0294..7d814ca6 100644 --- a/app/flatpak-builtins-create-usb.c +++ b/app/flatpak-builtins-create-usb.c @@ -664,7 +664,7 @@ flatpak_builtin_create_usb (int argc, char **argv, GCancellable *cancellable, GE /* Try to update the repo metadata by creating a FlatpakRemoteState object, * but don't fail on error because we want this to work offline. */ - state = flatpak_dir_get_remote_state_optional (dir, remote_name, cancellable, &local_error); + state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, &local_error); if (state == NULL) { g_printerr (_("Warning: Couldn't update repo metadata for remote ā€˜%s’: %s\n"), diff --git a/common/flatpak-dir-private.h b/common/flatpak-dir-private.h index f98da5b4..9b146404 100644 --- a/common/flatpak-dir-private.h +++ b/common/flatpak-dir-private.h @@ -882,6 +882,7 @@ gboolean flatpak_dir_remote_make_oci_summary (FlatpakDir *self, GError **error); FlatpakRemoteState * flatpak_dir_get_remote_state_optional (FlatpakDir *self, const char *remote, + gboolean only_cached, GCancellable *cancellable, GError **error); FlatpakRemoteState * flatpak_dir_get_remote_state_local_only (FlatpakDir *self, diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index ea807c0a..f25784e1 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -4153,7 +4153,7 @@ flatpak_dir_update_appstream (FlatpakDir *self, is_oci = flatpak_dir_get_remote_oci (self, remote); - state = flatpak_dir_get_remote_state_optional (self, remote, cancellable, error); + state = flatpak_dir_get_remote_state_optional (self, remote, FALSE, cancellable, error); if (state == NULL) return FALSE; @@ -10876,10 +10876,11 @@ flatpak_dir_get_remote_state_for_summary (FlatpakDir *self, FlatpakRemoteState * flatpak_dir_get_remote_state_optional (FlatpakDir *self, const char *remote, + gboolean only_cached, GCancellable *cancellable, GError **error) { - return _flatpak_dir_get_remote_state (self, remote, TRUE, FALSE, FALSE, NULL, NULL, cancellable, error); + return _flatpak_dir_get_remote_state (self, remote, TRUE, FALSE, only_cached, NULL, NULL, cancellable, error); } @@ -10902,7 +10903,7 @@ flatpak_dir_remote_has_ref (FlatpakDir *self, g_autoptr(GError) local_error = NULL; g_autoptr(FlatpakRemoteState) state = NULL; - state = flatpak_dir_get_remote_state_optional (self, remote, NULL, &local_error); + state = flatpak_dir_get_remote_state_optional (self, remote, FALSE, NULL, &local_error); if (state == NULL) { g_debug ("Can't get state for remote %s: %s", remote, local_error->message); @@ -11275,7 +11276,7 @@ flatpak_dir_find_remote_refs (FlatpakDir *self, g_autoptr(FlatpakRemoteState) state = NULL; GPtrArray *matched_refs; - state = flatpak_dir_get_remote_state_optional (self, remote, cancellable, error); + state = flatpak_dir_get_remote_state_optional (self, remote, FALSE, cancellable, error); if (state == NULL) return NULL; @@ -11372,7 +11373,7 @@ flatpak_dir_find_remote_ref (FlatpakDir *self, g_autoptr(FlatpakRemoteState) state = NULL; g_autoptr(GError) my_error = NULL; - state = flatpak_dir_get_remote_state_optional (self, remote, cancellable, error); + state = flatpak_dir_get_remote_state_optional (self, remote, FALSE, cancellable, error); if (state == NULL) return NULL; diff --git a/common/flatpak-installation.c b/common/flatpak-installation.c index 3cb300b2..0d9ac5fb 100644 --- a/common/flatpak-installation.c +++ b/common/flatpak-installation.c @@ -1995,7 +1995,7 @@ flatpak_installation_install_full (FlatpakInstallation *self, return NULL; } - state = flatpak_dir_get_remote_state_optional (dir, remote_name, cancellable, error); + state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error); if (state == NULL) return NULL; @@ -2158,7 +2158,7 @@ flatpak_installation_update_full (FlatpakInstallation *self, if (remote_name == NULL) return NULL; - state = flatpak_dir_get_remote_state_optional (dir, remote_name, cancellable, error); + state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error); if (state == NULL) return NULL; @@ -2392,7 +2392,7 @@ flatpak_installation_fetch_remote_size_sync (FlatpakInstallation *self, if (dir == NULL) return FALSE; - state = flatpak_dir_get_remote_state_optional (dir, remote_name, cancellable, error); + state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error); if (state == NULL) return FALSE; @@ -2433,7 +2433,7 @@ flatpak_installation_fetch_remote_metadata_sync (FlatpakInstallation *self, if (dir == NULL) return NULL; - state = flatpak_dir_get_remote_state_optional (dir, remote_name, cancellable, error); + state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error); if (state == NULL) return FALSE; @@ -2598,7 +2598,7 @@ flatpak_installation_fetch_remote_ref_sync_full (FlatpakInstallation *self, if (dir == NULL) return NULL; - state = flatpak_dir_get_remote_state (dir, remote_name, (flags & FLATPAK_QUERY_FLAGS_ONLY_CACHED) != 0, cancellable, error); + state = flatpak_dir_get_remote_state_optional (dir, remote_name, (flags & FLATPAK_QUERY_FLAGS_ONLY_CACHED) != 0, cancellable, error); if (state == NULL) return NULL; @@ -2624,6 +2624,77 @@ flatpak_installation_fetch_remote_ref_sync_full (FlatpakInstallation *self, coll_ref = flatpak_collection_ref_new (collection_id, ref); checksum = g_hash_table_lookup (ht, coll_ref); + /* Check LAN/USB sources too in case we're offline */ + if (checksum == NULL && collection_id != NULL && *collection_id != '\0') + { + OstreeRepo *repo; + const char * const *default_repo_finders; + g_autoptr(GAsyncResult) result = NULL; + OstreeCollectionRef ostree_coll_ref; + const OstreeCollectionRef *refs[2] = { NULL, }; + OstreeRepoFinder *finders[3] = { NULL, }; + guint finder_index = 0; + gsize i; + g_autoptr(GMainContextPopDefault) context = NULL; + g_autoptr(OstreeRepoFinder) finder_mount = NULL, finder_avahi = NULL; + + context = flatpak_main_context_new_default (); + + ostree_coll_ref.collection_id = collection_id; + ostree_coll_ref.ref_name = ref; + refs[0] = &ostree_coll_ref; + + if (!flatpak_dir_ensure_repo (dir, cancellable, error)) + return NULL; + repo = flatpak_dir_get_repo (dir); + default_repo_finders = ostree_repo_get_default_repo_finders (repo); + if (default_repo_finders == NULL || g_strv_contains (default_repo_finders, "mount")) + { + finder_mount = OSTREE_REPO_FINDER (ostree_repo_finder_mount_new (NULL)); + finders[finder_index++] = finder_mount; + } + + if (default_repo_finders == NULL || g_strv_contains (default_repo_finders, "lan")) + { + g_autoptr(GError) local_error = NULL; + finder_avahi = OSTREE_REPO_FINDER (ostree_repo_finder_avahi_new (context)); + finders[finder_index++] = finder_avahi; + + /* The Avahi finder may fail to start on, for example, a CI server. */ + ostree_repo_finder_avahi_start (OSTREE_REPO_FINDER_AVAHI (finder_avahi), &local_error); + if (local_error != NULL) + { + finders[--finder_index] = NULL; + g_clear_object (&finder_avahi); + } + } + + if (finders[0] != NULL) + { + g_auto(OstreeRepoFinderResultv) results = NULL; + + ostree_repo_find_remotes_async (repo, (const OstreeCollectionRef * const *)refs, + NULL, finders, NULL, cancellable, async_result_cb, &result); + while (result == NULL) + g_main_context_iteration (context, TRUE); + + results = ostree_repo_find_remotes_finish (repo, result, error); + + if (finder_avahi != NULL) + ostree_repo_finder_avahi_stop (OSTREE_REPO_FINDER_AVAHI (finder_avahi)); + + if (results == NULL) + return NULL; + + for (i = 0; results[i] != NULL; i++) + { + checksum = g_hash_table_lookup (results[i]->ref_to_checksum, &ostree_coll_ref); + if (checksum != NULL) + break; + } + } + } + /* If there was not a match, it may be because the collection ID is * not set in the local configuration, or it is wrong, so we resort to * trying to match just the ref name */ @@ -2814,7 +2885,7 @@ flatpak_installation_list_remote_related_refs_sync (FlatpakInstallation *self, if (dir == NULL) return NULL; - state = flatpak_dir_get_remote_state_optional (dir, remote_name, cancellable, error); + state = flatpak_dir_get_remote_state_optional (dir, remote_name, FALSE, cancellable, error); if (state == NULL) return NULL; diff --git a/common/flatpak-transaction.c b/common/flatpak-transaction.c index 402b4d00..9dfbe99a 100644 --- a/common/flatpak-transaction.c +++ b/common/flatpak-transaction.c @@ -1412,7 +1412,7 @@ flatpak_transaction_ensure_remote_state (FlatpakTransaction *self, if (state) return flatpak_remote_state_ref (state); - state = flatpak_dir_get_remote_state_optional (priv->dir, remote, NULL, error); + state = flatpak_dir_get_remote_state_optional (priv->dir, remote, FALSE, NULL, error); if (state) g_hash_table_insert (priv->remote_states, state->remote_name, flatpak_remote_state_ref (state)); diff --git a/system-helper/flatpak-system-helper.c b/system-helper/flatpak-system-helper.c index 4f90c866..7d97c027 100644 --- a/system-helper/flatpak-system-helper.c +++ b/system-helper/flatpak-system-helper.c @@ -645,7 +645,7 @@ handle_deploy (FlatpakSystemHelper *object, return TRUE; } - state = flatpak_dir_get_remote_state_optional (system, arg_origin, NULL, &error); + state = flatpak_dir_get_remote_state_optional (system, arg_origin, FALSE, NULL, &error); if (state == NULL) { flatpak_invocation_return_error (invocation, error, "Error getting remote state"); @@ -885,7 +885,7 @@ handle_deploy_appstream (FlatpakSystemHelper *object, return TRUE; } - state = flatpak_dir_get_remote_state_optional (system, arg_origin, NULL, &error); + state = flatpak_dir_get_remote_state_optional (system, arg_origin, FALSE, NULL, &error); if (state == NULL) { flatpak_invocation_return_error (invocation, error, "Error getting remote state");