]> git.proxmox.com Git - fwupd.git/commitdiff
Add support for Quit() in fwupdmgr
authorRichard Hughes <richard@hughsie.com>
Mon, 6 Feb 2023 17:12:10 +0000 (17:12 +0000)
committerMario Limonciello <mario.limonciello@amd.com>
Thu, 23 Feb 2023 19:04:11 +0000 (13:04 -0600)
This allows us to only shut down the P2P daemon in the installed tests.
The easy fix would have been to use something like:

    gdbus call --address unix:path=/run/fwupd.sock --object-path / --method org.freedesktop.fwupd.Quit'

...but the daemon does not implement an ObjectManager, which gdbus requires.

This worked correctly for so long because the p2p tests were being run after
the bus tests, so shutting down the system daemon had no effect.

Fedora 37 seems to have flipped the order for some reason -- and now it
*sometimes* matters that we were doing the worng thing...

data/bash-completion/fwupdmgr
data/fish-completion/fwupdmgr.fish
data/installed-tests/fwupdmgr-p2p.sh
libfwupd/fwupd-client-sync.c
libfwupd/fwupd-client-sync.h
libfwupd/fwupd-client.c
libfwupd/fwupd-client.h
libfwupd/fwupd.map
src/fu-util.c

index 8fb864fd88060f57cefa9e24552f9ce95c1a8e46..34001e0ddf8d1be389f322ab63896456812f2e68 100644 (file)
@@ -26,6 +26,7 @@ _fwupdmgr_cmd_list=(
        'local-install'
        'modify-config'
        'modify-remote'
+       'quit'
        'reinstall'
        'refresh'
        'report-history'
index aab972279860ce9ac207ea0399313f6f238f2f8e..85fe77e25a707a7447215d8921acc70176542461 100644 (file)
@@ -66,6 +66,7 @@ complete -c fwupdmgr -n '__fish_use_subcommand' -x -a verify -d 'Checks cryptogr
 complete -c fwupdmgr -n '__fish_use_subcommand' -x -a verify-update -d 'Update the stored cryptographic hash with current ROM contents'
 complete -c fwupdmgr -n '__fish_use_subcommand' -x -a inhibit -d 'Inhibit the system to prevent upgrades'
 complete -c fwupdmgr -n '__fish_use_subcommand' -x -a uninhibit -d 'Uninhibit the system to allow upgrades'
+complete -c fwupdmgr -n '__fish_use_subcommand' -x -a quit -d 'Asks the daemon to quit'
 
 # commands exclusively consuming device IDs
 set -l deviceid_consumers activate clear-results downgrade get-releases get-results get-updates reinstall switch-branch unlock update verify verify-update
index 0fa734fd626c90934a7e03657de9e5b8bfb4e6ae..b4d5d94aa39972bfd8142bf02199f7dc0f22bde9 100755 (executable)
@@ -20,7 +20,7 @@ rc=$?; if [ $rc != 0 ]; then exit $rc; fi
 
 # ---
 echo "Shutting down P2P daemon..."
-gdbus call --system --dest org.freedesktop.fwupd --object-path / --method org.freedesktop.fwupd.Quit
+fwupdmgr quit
 
 # success!
 exit 0
index 294786efeb6e9ad6106490e000b52dc0f30eb39e..a52d89909a137bbaa67abf81873d1a90960df08a 100644 (file)
@@ -109,6 +109,48 @@ fwupd_client_connect(FwupdClient *self, GCancellable *cancellable, GError **erro
        return TRUE;
 }
 
+static void
+fwupd_client_quit_cb(GObject *source, GAsyncResult *res, gpointer user_data)
+{
+       FwupdClientHelper *helper = (FwupdClientHelper *)user_data;
+       helper->ret = fwupd_client_quit_finish(FWUPD_CLIENT(source), res, &helper->error);
+       g_main_loop_quit(helper->loop);
+}
+
+/**
+ * fwupd_client_quit: (skip)
+ * @self: a #FwupdClient
+ * @cancellable: (nullable): optional #GCancellable
+ * @error: (nullable): optional return location for an error
+ *
+ * Asks the daemon to quit. This can only be called by the root user.
+ *
+ * NOTE: This will only actually quit if an install is not already in progress.
+ *
+ * Returns: %TRUE for success
+ *
+ * Since: 1.8.11
+ **/
+gboolean
+fwupd_client_quit(FwupdClient *self, GCancellable *cancellable, GError **error)
+{
+       g_autoptr(FwupdClientHelper) helper = NULL;
+
+       g_return_val_if_fail(FWUPD_IS_CLIENT(self), FALSE);
+       g_return_val_if_fail(cancellable == NULL || G_IS_CANCELLABLE(cancellable), FALSE);
+       g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+       /* call async version and run loop until complete */
+       helper = fwupd_client_helper_new(self);
+       fwupd_client_quit_async(self, cancellable, fwupd_client_quit_cb, helper);
+       g_main_loop_run(helper->loop);
+       if (!helper->ret) {
+               g_propagate_error(error, g_steal_pointer(&helper->error));
+               return FALSE;
+       }
+       return TRUE;
+}
+
 static void
 fwupd_client_get_devices_cb(GObject *source, GAsyncResult *res, gpointer user_data)
 {
index bbac721fa97cef16245a860da97a6287a26159e2..d1ad3ba35d6e001d970f5aa8661e11365f18ee2c 100644 (file)
@@ -14,6 +14,10 @@ gboolean
 fwupd_client_connect(FwupdClient *self,
                     GCancellable *cancellable,
                     GError **error) G_GNUC_WARN_UNUSED_RESULT;
+gboolean
+fwupd_client_quit(FwupdClient *self,
+                 GCancellable *cancellable,
+                 GError **error) G_GNUC_WARN_UNUSED_RESULT;
 GPtrArray *
 fwupd_client_get_devices(FwupdClient *self,
                         GCancellable *cancellable,
index 77753b2d74283b5c7492023f8325e872f87d7a5e..c18b8acf5e35a85c37fd04350419f367b6be63e5 100644 (file)
@@ -976,6 +976,83 @@ fwupd_client_disconnect(FwupdClient *self, GError **error)
        return TRUE;
 }
 
+static void
+fwupd_client_quit_cb(GObject *source, GAsyncResult *res, gpointer user_data)
+{
+       g_autoptr(GTask) task = G_TASK(user_data);
+       g_autoptr(GError) error = NULL;
+       g_autoptr(GVariant) val = NULL;
+
+       val = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error);
+       if (val == NULL) {
+               fwupd_client_fixup_dbus_error(error);
+               g_task_return_error(task, g_steal_pointer(&error));
+               return;
+       }
+
+       /* success */
+       g_task_return_boolean(task, TRUE);
+}
+
+/**
+ * fwupd_client_quit_async:
+ * @self: a #FwupdClient
+ * @cancellable: (nullable): optional #GCancellable
+ * @callback: the function to run on completion
+ * @callback_data: the data to pass to @callback
+ *
+ * Asks the daemon to quit. This can only be called by the root user.
+ *
+ * NOTE: This will only actually quit if an install is not already in progress.
+ *
+ * Since: 1.8.11
+ **/
+void
+fwupd_client_quit_async(FwupdClient *self,
+                       GCancellable *cancellable,
+                       GAsyncReadyCallback callback,
+                       gpointer callback_data)
+{
+       FwupdClientPrivate *priv = GET_PRIVATE(self);
+       g_autoptr(GTask) task = NULL;
+
+       g_return_if_fail(FWUPD_IS_CLIENT(self));
+       g_return_if_fail(cancellable == NULL || G_IS_CANCELLABLE(cancellable));
+       g_return_if_fail(priv->proxy != NULL);
+
+       /* call into daemon */
+       task = g_task_new(self, cancellable, callback, callback_data);
+       g_dbus_proxy_call(priv->proxy,
+                         "Quit",
+                         NULL,
+                         G_DBUS_CALL_FLAGS_NONE,
+                         FWUPD_CLIENT_DBUS_PROXY_TIMEOUT,
+                         cancellable,
+                         fwupd_client_quit_cb,
+                         g_steal_pointer(&task));
+}
+
+/**
+ * fwupd_client_quit_finish:
+ * @self: a #FwupdClient
+ * @res: (not nullable): the asynchronous result
+ * @error: (nullable): optional return location for an error
+ *
+ * Gets the result of [method@FwupdClient.quit_async].
+ *
+ * Returns: %TRUE for success
+ *
+ * Since: 1.8.11
+ **/
+gboolean
+fwupd_client_quit_finish(FwupdClient *self, GAsyncResult *res, GError **error)
+{
+       g_return_val_if_fail(FWUPD_IS_CLIENT(self), FALSE);
+       g_return_val_if_fail(g_task_is_valid(res, self), FALSE);
+       g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+       return g_task_propagate_boolean(G_TASK(res), error);
+}
+
 static void
 fwupd_client_fixup_dbus_error(GError *error)
 {
index ed7d6a3a9ff334ef0391ec648110c58cf95a7d0f..1cddf1db501b8e7b3d42396b6fea94638a98f4ca 100644 (file)
@@ -82,6 +82,15 @@ fwupd_client_connect_finish(FwupdClient *self,
 gboolean
 fwupd_client_disconnect(FwupdClient *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
 void
+fwupd_client_quit_async(FwupdClient *self,
+                       GCancellable *cancellable,
+                       GAsyncReadyCallback callback,
+                       gpointer callback_data);
+gboolean
+fwupd_client_quit_finish(FwupdClient *self,
+                        GAsyncResult *res,
+                        GError **error) G_GNUC_WARN_UNUSED_RESULT;
+void
 fwupd_client_get_devices_async(FwupdClient *self,
                               GCancellable *cancellable,
                               GAsyncReadyCallback callback,
index 8df8c03928b1f854b1a82699798808e1d98f82e4..4ece215ee9120901f2da9c1c032ec3ace09f6a09 100644 (file)
@@ -907,6 +907,9 @@ LIBFWUPD_1.8.11 {
     fwupd_client_inhibit;
     fwupd_client_inhibit_async;
     fwupd_client_inhibit_finish;
+    fwupd_client_quit;
+    fwupd_client_quit_async;
+    fwupd_client_quit_finish;
     fwupd_client_uninhibit;
     fwupd_client_uninhibit_async;
     fwupd_client_uninhibit_finish;
index 46903479d5c5e8e9c2e9e76bdb4aa9bd247c372e..155c69712b3cf0f9be0eec860e3024f59d917788 100644 (file)
@@ -1020,6 +1020,13 @@ fu_util_uninhibit(FuUtilPrivate *priv, gchar **values, GError **error)
        return fwupd_client_uninhibit(priv->client, values[0], priv->cancellable, error);
 }
 
+static gboolean
+fu_util_quit(FuUtilPrivate *priv, gchar **values, GError **error)
+{
+       /* success */
+       return fwupd_client_quit(priv->client, priv->cancellable, error);
+}
+
 static gboolean
 fu_util_device_test(FuUtilPrivate *priv, gchar **values, GError **error)
 {
@@ -4552,6 +4559,12 @@ main(int argc, char *argv[])
                              /* TRANSLATORS: command description */
                              _("Uninhibit the system to allow upgrades"),
                              fu_util_uninhibit);
+       fu_util_cmd_array_add(cmd_array,
+                             "quit",
+                             NULL,
+                             /* TRANSLATORS: command description */
+                             _("Asks the daemon to quit"),
+                             fu_util_quit);
        fu_util_cmd_array_add(
            cmd_array,
            "get-bios-settings,get-bios-setting",