From 62fcf143d16208822959ba887218d5a78949ecc3 Mon Sep 17 00:00:00 2001 From: Kalev Lember Date: Thu, 29 Mar 2018 21:29:41 +0200 Subject: [PATCH] Make rpm-ostree update triggering work --- gnome-software.spec | 2 + rpm-ostree-updates.patch | 803 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 805 insertions(+) create mode 100644 rpm-ostree-updates.patch diff --git a/gnome-software.spec b/gnome-software.spec index dd5938a..ef800aa 100644 --- a/gnome-software.spec +++ b/gnome-software.spec @@ -23,6 +23,7 @@ Patch0: 0001-Revert-Revert-trivial-Use-new-libappstream-glib-to-b.patch Patch1: 0001-plugin-loader-Don-t-abort-for-refine-errors.patch Patch2: 0001-appstream-Don-t-compare-appstream-origin-to-package-.patch Patch3: empty-os-updates.patch +Patch4: rpm-ostree-updates.patch BuildRequires: gettext BuildRequires: libxslt @@ -218,6 +219,7 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %changelog * Thu Mar 29 2018 Kalev Lember - 3.28.0-5 - Fix empty OS Updates showing up +- Make rpm-ostree update triggering work * Thu Mar 15 2018 Kalev Lember - 3.28.0-4 - Fix opening results from gnome-shell search provider diff --git a/rpm-ostree-updates.patch b/rpm-ostree-updates.patch new file mode 100644 index 0000000..f6e0d73 --- /dev/null +++ b/rpm-ostree-updates.patch @@ -0,0 +1,803 @@ +From 433feac892472ca2c6ab2cf074117100764a3f75 Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Thu, 22 Mar 2018 15:00:56 +0100 +Subject: [PATCH] trivial: rpm-ostree: Update rpmostree1 dbus interface + description + +--- + .../rpm-ostree/org.projectatomic.rpmostree1.xml | 81 ++++++++++++++++++++-- + 1 file changed, 76 insertions(+), 5 deletions(-) + +diff --git a/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml b/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml +index 0a4a915c6493..edfa28f319bd 100644 +--- a/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml ++++ b/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml +@@ -23,8 +23,10 @@ + + + +- ++ + ++ ++ + + ++ ++ + + + +@@ -74,12 +79,36 @@ + 'timestamp' (type 't') + 'origin' (type 's') + 'signatures' (type 'av') ++ 'gpg-enabled' (type 'b') ++ 'ref-has-new-commit' (type 'b') ++ TRUE if 'checksum' refers to a new base commit we're not booted in. ++ 'rpm-diff' (type 'a{sv}') ++ 'upgraded' (type 'a(us(ss)(ss))') ++ 'downgraded' (type 'a(us(ss)(ss))') ++ 'removed' (type 'a(usss)') ++ 'added' (type 'a(usss)') ++ 'advisories' (type 'a(suuasa{sv})') + --> + + + +- +- ++ ++ ++ ++ ++ ++ ++ + + + +@@ -218,17 +247,44 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + + ++ ++ ++ ++ ++ + + + +@@ -273,6 +341,9 @@ + + + ++ ++ ++ + + + +-- +2.16.2 + +From bea127b2be371c80ace8a0a49295c2046b58fbd8 Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Thu, 29 Mar 2018 15:31:27 +0200 +Subject: [PATCH 1/7] rpm-ostree: Use Upgrade instead of DownloadUpdateRpmDiff + +Upgrade is new do-it-all API that supersedes DownloadUpdateRpmDiff and +many other individual rpm-ostree dbus methods. +--- + plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 45 +++++++++++++++++++++++++++---- + 1 file changed, 40 insertions(+), 5 deletions(-) + +diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +index aae2e6dbd6dc..5b173dfdd509 100644 +--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c ++++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +@@ -364,6 +364,29 @@ make_app (GVariant *variant) + return g_steal_pointer (&app); + } + ++static GVariant * ++make_rpmostree_options_variant (gboolean reboot, ++ gboolean allow_downgrade, ++ gboolean cache_only, ++ gboolean download_only, ++ gboolean skip_purge, ++ gboolean no_pull_base, ++ gboolean dry_run, ++ gboolean no_overrides) ++{ ++ GVariantDict dict; ++ g_variant_dict_init (&dict, NULL); ++ g_variant_dict_insert (&dict, "reboot", "b", reboot); ++ g_variant_dict_insert (&dict, "allow-downgrade", "b", allow_downgrade); ++ g_variant_dict_insert (&dict, "cache-only", "b", cache_only); ++ g_variant_dict_insert (&dict, "download-only", "b", download_only); ++ g_variant_dict_insert (&dict, "skip-purge", "b", skip_purge); ++ g_variant_dict_insert (&dict, "no-pull-base", "b", no_pull_base); ++ g_variant_dict_insert (&dict, "dry-run", "b", dry_run); ++ g_variant_dict_insert (&dict, "no-overrides", "b", no_overrides); ++ return g_variant_ref_sink (g_variant_dict_end (&dict)); ++} ++ + gboolean + gs_plugin_refresh (GsPlugin *plugin, + guint cache_age, +@@ -375,11 +398,23 @@ gs_plugin_refresh (GsPlugin *plugin, + + if (flags & GS_PLUGIN_REFRESH_FLAGS_METADATA) { + g_autofree gchar *transaction_address = NULL; +- +- if (!gs_rpmostree_os_call_download_update_rpm_diff_sync (priv->os_proxy, +- &transaction_address, +- cancellable, +- error)) { ++ g_autoptr(GVariant) options = NULL; ++ ++ options = make_rpmostree_options_variant (FALSE, /* reboot */ ++ FALSE, /* allow-downgrade */ ++ FALSE, /* cache-only */ ++ TRUE, /* download-only */ ++ FALSE, /* skip-purge */ ++ FALSE, /* no-pull-base */ ++ FALSE, /* dry-run */ ++ FALSE); /* no-overrides */ ++ if (!gs_rpmostree_os_call_upgrade_sync (priv->os_proxy, ++ options, ++ NULL /* fd list */, ++ &transaction_address, ++ NULL /* fd list out */, ++ cancellable, ++ error)) { + gs_utils_error_convert_gio (error); + return FALSE; + } +-- +2.16.2 + + +From 533ab16b0a671bb8e39c6c0b6afa4c4438a5cb70 Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Thu, 29 Mar 2018 18:13:05 +0200 +Subject: [PATCH 2/7] rpm-ostree: Avoid using GetCachedUpdateRpmDiff dbus + method + +rpm-ostree GetCachedUpdateRpmDiff method doesn't handle layered packages +correctly. Instead, this commit switches to using the newer CachedUpdate +property instead which has all the info we need for add_updates(). +--- + plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 196 +++++++++++++++++++++--------- + 1 file changed, 140 insertions(+), 56 deletions(-) + +diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +index 5b173dfdd509..64a86bef9549 100644 +--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c ++++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +@@ -303,16 +303,14 @@ out: + } + + static GsApp * +-make_app (GVariant *variant) ++app_from_modified_pkg_variant (GVariant *variant) + { + g_autoptr(GsApp) app = NULL; +- g_autoptr(GVariant) details = NULL; +- const char *old_name, *old_evr, *old_arch; +- const char *new_name, *new_evr, *new_arch; +- gboolean have_old = FALSE; +- gboolean have_new = FALSE; ++ const char *name; ++ const char *old_evr, *old_arch; ++ const char *new_evr, *new_arch; + +- app = gs_app_new (NULL); ++ g_variant_get (variant, "(us(ss)(ss))", NULL /* type*/, &name, &old_evr, &old_arch, &new_evr, &new_arch); + + /* create new app */ + app = gs_app_new (NULL); +@@ -323,42 +321,51 @@ make_app (GVariant *variant) + gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); + gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM); + +- details = g_variant_get_child_value (variant, 2); +- g_return_val_if_fail (details != NULL, NULL); ++ /* update or downgrade */ ++ gs_app_add_source (app, name); ++ gs_app_set_version (app, old_evr); ++ gs_app_set_update_version (app, new_evr); ++ gs_app_set_state (app, AS_APP_STATE_UPDATABLE); + +- have_old = g_variant_lookup (details, +- "PreviousPackage", "(&s&s&s)", +- &old_name, &old_evr, &old_arch); ++ g_debug ("!%s-%s-%s\n", name, old_evr, old_arch); ++ g_debug ("=%s-%s-%s\n", name, new_evr, new_arch); + +- have_new = g_variant_lookup (details, +- "NewPackage", "(&s&s&s)", +- &new_name, &new_evr, &new_arch); ++ return g_steal_pointer (&app); ++} + +- if (have_old && have_new) { +- g_assert (g_strcmp0 (old_name, new_name) == 0); ++static GsApp * ++app_from_single_pkg_variant (GVariant *variant, gboolean addition) ++{ ++ g_autoptr(GsApp) app = NULL; ++ const char *name; ++ const char *evr; ++ const char *arch; + +- /* update */ +- gs_app_add_source (app, old_name); +- gs_app_set_version (app, old_evr); +- gs_app_set_update_version (app, new_evr); +- gs_app_set_state (app, AS_APP_STATE_UPDATABLE); ++ g_variant_get (variant, "(usss)", NULL /* type*/, &name, &evr, &arch); + +- g_print ("!%s-%s-%s\n", old_name, old_evr, old_arch); +- g_print ("=%s-%s-%s\n", new_name, new_evr, new_arch); +- } else if (have_old) { +- /* removal */ +- gs_app_add_source (app, old_name); +- gs_app_set_version (app, old_evr); +- gs_app_set_state (app, AS_APP_STATE_UNAVAILABLE); ++ /* create new app */ ++ app = gs_app_new (NULL); ++ gs_app_add_quirk (app, AS_APP_QUIRK_NEEDS_REBOOT); ++ gs_app_set_management_plugin (app, "rpm-ostree"); ++ gs_app_set_size_download (app, 0); ++ gs_app_set_kind (app, AS_APP_KIND_GENERIC); ++ gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_PACKAGE); ++ gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM); + +- g_print ("-%s-%s-%s\n", old_name, old_evr, old_arch); +- } else if (have_new) { +- /* install */ +- gs_app_add_source (app, new_name); +- gs_app_set_version (app, new_evr); ++ if (addition) { ++ /* addition */ ++ gs_app_add_source (app, name); ++ gs_app_set_version (app, evr); + gs_app_set_state (app, AS_APP_STATE_AVAILABLE); + +- g_print ("+%s-%s-%s\n", new_name, new_evr, new_arch); ++ g_debug ("+%s-%s-%s\n", name, evr, arch); ++ } else { ++ /* removal */ ++ gs_app_add_source (app, name); ++ gs_app_set_version (app, evr); ++ gs_app_set_state (app, AS_APP_STATE_UNAVAILABLE); ++ ++ g_debug ("-%s-%s-%s\n", name, evr, arch); + } + + return g_steal_pointer (&app); +@@ -438,33 +445,110 @@ gs_plugin_add_updates (GsPlugin *plugin, + GError **error) + { + GsPluginData *priv = gs_plugin_get_data (plugin); +- g_autoptr(GVariant) result = NULL; +- g_autoptr(GVariant) details = NULL; +- GVariantIter iter; +- GVariant *child; +- +- if (!gs_rpmostree_os_call_get_cached_update_rpm_diff_sync (priv->os_proxy, +- "", +- &result, +- &details, +- cancellable, +- error)) { +- gs_utils_error_convert_gio (error); ++ g_autoptr(GVariant) cached_update = NULL; ++ g_autoptr(GVariant) rpm_diff = NULL; ++ const gchar *checksum = NULL; ++ const gchar *version = NULL; ++ g_auto(GVariantDict) cached_update_dict; ++ ++ cached_update = gs_rpmostree_os_dup_cached_update (priv->os_proxy); ++ g_variant_dict_init (&cached_update_dict, cached_update); ++ ++ if (!g_variant_dict_lookup (&cached_update_dict, "checksum", "&s", &checksum)) { ++ g_set_error_literal (error, ++ GS_PLUGIN_ERROR, ++ GS_PLUGIN_ERROR_INVALID_FORMAT, ++ "no 'checksum' in CachedUpdate dict"); + return FALSE; + } ++ if (!g_variant_dict_lookup (&cached_update_dict, "version", "&s", &version)) { ++ g_set_error_literal (error, ++ GS_PLUGIN_ERROR, ++ GS_PLUGIN_ERROR_INVALID_FORMAT, ++ "no 'version' in CachedUpdate dict"); ++ return FALSE; ++ } ++ g_debug ("got CachedUpdate version '%s', checksum '%s'", version, checksum); ++ ++ rpm_diff = g_variant_dict_lookup_value (&cached_update_dict, "rpm-diff", G_VARIANT_TYPE ("a{sv}")); ++ if (rpm_diff != NULL) { ++ GVariantIter iter; ++ GVariant *child; ++ g_autoptr(GVariant) upgraded = NULL; ++ g_autoptr(GVariant) downgraded = NULL; ++ g_autoptr(GVariant) removed = NULL; ++ g_autoptr(GVariant) added = NULL; ++ g_auto(GVariantDict) rpm_diff_dict; ++ g_variant_dict_init (&rpm_diff_dict, rpm_diff); ++ ++ upgraded = g_variant_dict_lookup_value (&rpm_diff_dict, "upgraded", G_VARIANT_TYPE ("a(us(ss)(ss))")); ++ if (upgraded == NULL) { ++ g_set_error_literal (error, ++ GS_PLUGIN_ERROR, ++ GS_PLUGIN_ERROR_INVALID_FORMAT, ++ "no 'upgraded' in rpm-diff dict"); ++ return FALSE; ++ } ++ downgraded = g_variant_dict_lookup_value (&rpm_diff_dict, "downgraded", G_VARIANT_TYPE ("a(us(ss)(ss))")); ++ if (downgraded == NULL) { ++ g_set_error_literal (error, ++ GS_PLUGIN_ERROR, ++ GS_PLUGIN_ERROR_INVALID_FORMAT, ++ "no 'downgraded' in rpm-diff dict"); ++ return FALSE; ++ } ++ removed = g_variant_dict_lookup_value (&rpm_diff_dict, "removed", G_VARIANT_TYPE ("a(usss)")); ++ if (removed == NULL) { ++ g_set_error_literal (error, ++ GS_PLUGIN_ERROR, ++ GS_PLUGIN_ERROR_INVALID_FORMAT, ++ "no 'removed' in rpm-diff dict"); ++ return FALSE; ++ } ++ added = g_variant_dict_lookup_value (&rpm_diff_dict, "added", G_VARIANT_TYPE ("a(usss)")); ++ if (added == NULL) { ++ g_set_error_literal (error, ++ GS_PLUGIN_ERROR, ++ GS_PLUGIN_ERROR_INVALID_FORMAT, ++ "no 'added' in rpm-diff dict"); ++ return FALSE; ++ } + +- if (g_variant_n_children (result) == 0) +- return TRUE; ++ /* iterate over all upgraded packages and add them */ ++ g_variant_iter_init (&iter, upgraded); ++ while ((child = g_variant_iter_next_value (&iter)) != NULL) { ++ g_autoptr(GsApp) app = app_from_modified_pkg_variant (child); ++ if (app != NULL) ++ gs_app_list_add (list, app); ++ g_variant_unref (child); ++ } ++ ++ /* iterate over all downgraded packages and add them */ ++ g_variant_iter_init (&iter, downgraded); ++ while ((child = g_variant_iter_next_value (&iter)) != NULL) { ++ g_autoptr(GsApp) app = app_from_modified_pkg_variant (child); ++ if (app != NULL) ++ gs_app_list_add (list, app); ++ g_variant_unref (child); ++ } + +- /* GVariant format should be a(sua{sv}) */ +- g_variant_iter_init (&iter, result); ++ /* iterate over all removed packages and add them */ ++ g_variant_iter_init (&iter, removed); ++ while ((child = g_variant_iter_next_value (&iter)) != NULL) { ++ g_autoptr(GsApp) app = app_from_single_pkg_variant (child, FALSE); ++ if (app != NULL) ++ gs_app_list_add (list, app); ++ g_variant_unref (child); ++ } + +- while ((child = g_variant_iter_next_value (&iter)) != NULL) { +- g_autoptr(GsApp) app = make_app (child); +- if (app != NULL) { +- gs_app_list_add (list, app); ++ /* iterate over all added packages and add them */ ++ g_variant_iter_init (&iter, added); ++ while ((child = g_variant_iter_next_value (&iter)) != NULL) { ++ g_autoptr(GsApp) app = app_from_single_pkg_variant (child, TRUE); ++ if (app != NULL) ++ gs_app_list_add (list, app); ++ g_variant_unref (child); + } +- g_variant_unref (child); + } + + return TRUE; +-- +2.16.2 + + +From 5c2c66a4843a4d783796e50bb639edb1cf6a4831 Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Thu, 29 Mar 2018 20:31:23 +0200 +Subject: [PATCH 3/7] rpm-ostree: Implement triggering an update + +We only downloaded and showed updates so far, but didn't actually +implement triggering an update. This commit is the missing piece for +making rpm-ostree updates work. +--- + plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 80 +++++++++++++++++++++++++++++++ + 1 file changed, 80 insertions(+) + +diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +index 64a86bef9549..68de8943927a 100644 +--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c ++++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +@@ -35,6 +35,7 @@ struct GsPluginData { + GsRPMOSTreeSysroot *sysroot_proxy; + OstreeRepo *ot_repo; + OstreeSysroot *ot_sysroot; ++ gboolean update_triggered; + }; + + void +@@ -554,6 +555,85 @@ gs_plugin_add_updates (GsPlugin *plugin, + return TRUE; + } + ++static gboolean ++trigger_rpmostree_update (GsPlugin *plugin, ++ GsApp *app, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GsPluginData *priv = gs_plugin_get_data (plugin); ++ g_autofree gchar *transaction_address = NULL; ++ g_autoptr(GVariant) options = NULL; ++ ++ /* if we can process this online do not require a trigger */ ++ if (gs_app_get_state (app) != AS_APP_STATE_UPDATABLE) ++ return TRUE; ++ ++ /* only process this app if was created by this plugin */ ++ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) ++ return TRUE; ++ ++ /* already in correct state */ ++ if (priv->update_triggered) ++ return TRUE; ++ ++ /* trigger the update */ ++ options = make_rpmostree_options_variant (FALSE, /* reboot */ ++ FALSE, /* allow-downgrade */ ++ TRUE, /* cache-only */ ++ FALSE, /* download-only */ ++ FALSE, /* skip-purge */ ++ FALSE, /* no-pull-base */ ++ FALSE, /* dry-run */ ++ FALSE); /* no-overrides */ ++ if (!gs_rpmostree_os_call_upgrade_sync (priv->os_proxy, ++ options, ++ NULL /* fd list */, ++ &transaction_address, ++ NULL /* fd list out */, ++ cancellable, ++ error)) { ++ gs_utils_error_convert_gio (error); ++ return FALSE; ++ } ++ ++ if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy, ++ transaction_address, ++ cancellable, ++ error)) { ++ gs_utils_error_convert_gio (error); ++ return FALSE; ++ } ++ ++ priv->update_triggered = TRUE; ++ ++ /* success */ ++ return TRUE; ++} ++ ++gboolean ++gs_plugin_update_app (GsPlugin *plugin, ++ GsApp *app, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GPtrArray *related = gs_app_get_related (app); ++ ++ /* we don't currently don't put all updates in the OsUpdate proxy app */ ++ if (!gs_app_has_quirk (app, AS_APP_QUIRK_IS_PROXY)) ++ return trigger_rpmostree_update (plugin, app, cancellable, error); ++ ++ /* try to trigger each related app */ ++ for (guint i = 0; i < related->len; i++) { ++ GsApp *app_tmp = g_ptr_array_index (related, i); ++ if (!trigger_rpmostree_update (plugin, app_tmp, cancellable, error)) ++ return FALSE; ++ } ++ ++ /* success */ ++ return TRUE; ++} ++ + static void + resolve_packages_app (GsPlugin *plugin, + GPtrArray *pkglist, +-- +2.16.2 + + +From 50ba9b1682e9d04627127914419e926778e6e21e Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Thu, 29 Mar 2018 20:55:14 +0200 +Subject: [PATCH 4/7] rpm-ostree: Avoid downloading updates during + gnome-software startup + +Only download updates when GS_PLUGIN_REFRESH_FLAGS_PAYLOAD is specified, +so that we don't block gnome-software startup with update downloads. +--- + plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +index 68de8943927a..2e8681c980b5 100644 +--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c ++++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +@@ -404,7 +404,7 @@ gs_plugin_refresh (GsPlugin *plugin, + { + GsPluginData *priv = gs_plugin_get_data (plugin); + +- if (flags & GS_PLUGIN_REFRESH_FLAGS_METADATA) { ++ if (flags & GS_PLUGIN_REFRESH_FLAGS_PAYLOAD) { + g_autofree gchar *transaction_address = NULL; + g_autoptr(GVariant) options = NULL; + +-- +2.16.2 + + +From 2503def95fbd1e6d7d299219d5cd0a6d591cfec6 Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Thu, 29 Mar 2018 21:03:19 +0200 +Subject: [PATCH 5/7] rpm-ostree: Don't return an error if we haven't + downloaded any updates yet + +--- + plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 19 +++++-------------- + 1 file changed, 5 insertions(+), 14 deletions(-) + +diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +index 2e8681c980b5..e03f59385efa 100644 +--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c ++++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +@@ -455,20 +455,11 @@ gs_plugin_add_updates (GsPlugin *plugin, + cached_update = gs_rpmostree_os_dup_cached_update (priv->os_proxy); + g_variant_dict_init (&cached_update_dict, cached_update); + +- if (!g_variant_dict_lookup (&cached_update_dict, "checksum", "&s", &checksum)) { +- g_set_error_literal (error, +- GS_PLUGIN_ERROR, +- GS_PLUGIN_ERROR_INVALID_FORMAT, +- "no 'checksum' in CachedUpdate dict"); +- return FALSE; +- } +- if (!g_variant_dict_lookup (&cached_update_dict, "version", "&s", &version)) { +- g_set_error_literal (error, +- GS_PLUGIN_ERROR, +- GS_PLUGIN_ERROR_INVALID_FORMAT, +- "no 'version' in CachedUpdate dict"); +- return FALSE; +- } ++ if (!g_variant_dict_lookup (&cached_update_dict, "checksum", "&s", &checksum)) ++ return TRUE; ++ if (!g_variant_dict_lookup (&cached_update_dict, "version", "&s", &version)) ++ return TRUE; ++ + g_debug ("got CachedUpdate version '%s', checksum '%s'", version, checksum); + + rpm_diff = g_variant_dict_lookup_value (&cached_update_dict, "rpm-diff", G_VARIANT_TYPE ("a{sv}")); +-- +2.16.2 + + +From 68f4c49157188e499bd36ef6e56239c78be5cc09 Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Thu, 29 Mar 2018 21:41:08 +0200 +Subject: [PATCH 6/7] rpm-ostree: Ensure D-Bus properties are updated before + reading them + +Use new Reload() API in rpm-ostree 2018.4 to make sure the daemon emits +all D-Bus properties before reading them. +--- + meson.build | 2 +- + plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 6 ++++++ + plugins/rpm-ostree/org.projectatomic.rpmostree1.xml | 6 ++++++ + 3 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/meson.build b/meson.build +index 53d10370249f..c22a34bb3894 100644 +--- a/meson.build ++++ b/meson.build +@@ -154,7 +154,7 @@ endif + + if get_option('enable-rpm-ostree') + ostree = dependency('ostree-1') +- rpm_ostree = dependency('rpm-ostree-1') ++ rpm_ostree = dependency('rpm-ostree-1', version : '>= 2018.4') + endif + + if get_option('enable-ubuntu-reviews') +diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +index e03f59385efa..d811df6f0cc3 100644 +--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c ++++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +@@ -452,6 +452,9 @@ gs_plugin_add_updates (GsPlugin *plugin, + const gchar *version = NULL; + g_auto(GVariantDict) cached_update_dict; + ++ /* ensure D-Bus properties are updated before reading them */ ++ gs_rpmostree_sysroot_call_reload_sync (priv->sysroot_proxy, cancellable, error); ++ + cached_update = gs_rpmostree_os_dup_cached_update (priv->os_proxy); + g_variant_dict_init (&cached_update_dict, cached_update); + +@@ -658,6 +661,9 @@ gs_plugin_refine (GsPlugin *plugin, + g_auto(GStrv) layered_packages = NULL; + g_autofree gchar *checksum = NULL; + ++ /* ensure D-Bus properties are updated before reading them */ ++ gs_rpmostree_sysroot_call_reload_sync (priv->sysroot_proxy, cancellable, error); ++ + booted_deployment = gs_rpmostree_os_dup_booted_deployment (priv->os_proxy); + g_assert (g_variant_lookup (booted_deployment, + "packages", "^as", +diff --git a/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml b/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml +index edfa28f319bd..5e5bf0704508 100644 +--- a/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml ++++ b/plugins/rpm-ostree/org.projectatomic.rpmostree1.xml +@@ -47,6 +47,12 @@ + + + ++ ++ ++ ++ ++ + + + +-- +2.16.2 + + +From aca91ce6ca1ad4525335ad88276ccc970c7d2852 Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Thu, 29 Mar 2018 22:34:29 +0200 +Subject: [PATCH 7/7] rpm-ostree: Use new AutomaticUpdateTrigger API + +It doesn't appear to be enough to just download updates with +Upgrade(download-only=true), but we also need to call +AutomaticUpdateTrigger(check=true) to actually make the CachedUpdate +property show up. +--- + plugins/rpm-ostree/gs-plugin-rpm-ostree.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +index d811df6f0cc3..2e8bda940cc5 100644 +--- a/plugins/rpm-ostree/gs-plugin-rpm-ostree.c ++++ b/plugins/rpm-ostree/gs-plugin-rpm-ostree.c +@@ -436,6 +436,34 @@ gs_plugin_refresh (GsPlugin *plugin, + } + } + ++ if (flags & GS_PLUGIN_REFRESH_FLAGS_PAYLOAD) { ++ g_autofree gchar *transaction_address = NULL; ++ g_autoptr(GVariant) options = NULL; ++ GVariantDict dict; ++ ++ g_variant_dict_init (&dict, NULL); ++ g_variant_dict_insert (&dict, "mode", "s", "check"); ++ options = g_variant_ref_sink (g_variant_dict_end (&dict)); ++ ++ if (!gs_rpmostree_os_call_automatic_update_trigger_sync (priv->os_proxy, ++ options, ++ NULL, ++ &transaction_address, ++ cancellable, ++ error)) { ++ gs_utils_error_convert_gio (error); ++ return FALSE; ++ } ++ ++ if (!gs_rpmostree_transaction_get_response_sync (priv->sysroot_proxy, ++ transaction_address, ++ cancellable, ++ error)) { ++ gs_utils_error_convert_gio (error); ++ return FALSE; ++ } ++ } ++ + return TRUE; + } + +-- +2.16.2 +