git.delta.rocks / remowt / refs/commits / 5cb6be498b69

difftreelog

feat properly cancel agent task

wplzsrwuYaroslav Bolyukin2024-08-12parent: #9ee216a.patch.diff
in: trunk

3 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -307,16 +307,22 @@
 ]
 
 [[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
 name = "bytes"
-version = "1.6.1"
+version = "1.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952"
+checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
 
 [[package]]
 name = "cc"
-version = "1.1.6"
+version = "1.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"
+checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
 
 [[package]]
 name = "cexpr"
@@ -644,9 +650,9 @@
 
 [[package]]
 name = "indexmap"
-version = "2.2.6"
+version = "2.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
+checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0"
 dependencies = [
  "equivalent",
  "hashbrown",
@@ -905,9 +911,12 @@
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.17"
+version = "0.2.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+dependencies = [
+ "zerocopy",
+]
 
 [[package]]
 name = "proc-macro-crate"
@@ -968,9 +977,9 @@
 
 [[package]]
 name = "regex"
-version = "1.10.5"
+version = "1.10.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
+checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -1089,11 +1098,12 @@
 
 [[package]]
 name = "serde_json"
-version = "1.0.120"
+version = "1.0.122"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"
+checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
 dependencies = [
  "itoa",
+ "memchr",
  "ryu",
  "serde",
 ]
@@ -1205,12 +1215,13 @@
 
 [[package]]
 name = "tempfile"
-version = "3.10.1"
+version = "3.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
+checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53"
 dependencies = [
  "cfg-if",
  "fastrand",
+ "once_cell",
  "rustix",
  "windows-sys",
 ]
@@ -1276,9 +1287,9 @@
 
 [[package]]
 name = "toml_datetime"
-version = "0.6.7"
+version = "0.6.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db"
+checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
 
 [[package]]
 name = "toml_edit"
@@ -1606,6 +1617,27 @@
 ]
 
 [[package]]
+name = "zerocopy"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+dependencies = [
+ "byteorder",
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.72",
+]
+
+[[package]]
 name = "zvariant"
 version = "4.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
modifiedcmds/remowt-agent/src/main.rsdiffbeforeafterboth
--- a/cmds/remowt-agent/src/main.rs
+++ b/cmds/remowt-agent/src/main.rs
@@ -2,14 +2,14 @@
 use std::collections::{BTreeMap, HashMap};
 use std::io::{stdout, Write};
 use std::marker::PhantomData;
-use std::sync::{Mutex, RwLock};
+use std::sync::{Arc, Mutex, OnceLock};
 use std::{future, process};
 
 use clap::Parser;
 use polkit_shared::{emphasize, BackendRequest, Identity, PidDisplay};
 use tokio::runtime::Handle;
 use tokio::task::{AbortHandle, JoinHandle, LocalSet};
-use tracing::trace;
+use tracing::{info, trace};
 use ui_prompt::dbus::DbusPrompterInterface;
 use ui_prompt::rofi::RofiPrompter;
 use ui_prompt::{PrependSourcePrompter, Prompter, Source};
@@ -58,16 +58,34 @@
     }
 }
 
+struct CancelTaskOnDrop {
+    tasks: Arc<Mutex<HashMap<String, AbortHandle>>>,
+    handle: String,
+}
+impl Drop for CancelTaskOnDrop {
+    fn drop(&mut self) {
+        info!("cancel on drop");
+        if let Some(task) = self
+            .tasks
+            .lock()
+            .expect("not poisoned")
+            .remove(&self.handle)
+        {
+            task.abort();
+        }
+    }
+}
+
 struct Agent {
     helper: PolkitHelperProxy<'static>,
-    tasks: Mutex<HashMap<String, AbortHandle>>,
+    tasks: Arc<Mutex<HashMap<String, AbortHandle>>>,
     connection: Connection,
 }
 impl Agent {
     async fn new(connection: Connection) -> anyhow::Result<Self> {
         Ok(Self {
             helper: PolkitHelperProxy::new(&connection).await?,
-            tasks: Mutex::new(HashMap::new()),
+            tasks: Arc::new(Mutex::new(HashMap::new())),
             connection,
         })
     }
@@ -78,7 +96,7 @@
     /// BeginAuthentication method
     #[allow(clippy::too_many_arguments)]
     async fn begin_authentication(
-        &mut self,
+        &self,
         action_id: String,
         message: String,
         icon_name: String,
@@ -87,12 +105,15 @@
         identities: Vec<Identity>,
     ) -> zbus::fdo::Result<()> {
         use std::fmt::Write;
-        trace!("begin auth");
+        info!("begin auth");
+        let _cancel_guard = Arc::new(OnceLock::new());
         let task = {
             let connection = self.connection.clone();
             let helper = self.helper.clone();
             let cookie = cookie.clone();
+            let _cancel_guard = _cancel_guard.clone();
             tokio::task::spawn(async move {
+                let _cancel_guard = _cancel_guard.clone();
                 trace!("conversation task");
                 let mut description = format!("{message}\n\n<b>Action id:</b> {action_id}",);
                 if let Some(subject) = details.remove("polkit.caller-pid") {
@@ -121,6 +142,7 @@
                     identities.iter().map(|v| v.to_string()).collect();
                 let identity_displays: Vec<&str> =
                     identity_displays.iter().map(|v| v.as_str()).collect();
+                info!("choose identity");
                 let choosen_identity = match identity_displays.len() {
                     0 => {
                         return Err(fdo::Error::AuthFailed(
@@ -139,6 +161,7 @@
                             .await?
                     }
                 };
+                info!("identity chosen");
 
                 let _ = write!(
                     description,
@@ -148,7 +171,10 @@
                 prompter.description = description;
 
                 prompter.source.push(Source(Cow::Borrowed("polkit daemon")));
+                // let connection = Connection::system().await?;
+                // let helper = PolkitHelperProxy::new(&connection).await?;
                 let prompter = TemporaryPrompterInterface::new(connection, prompter).await;
+                info!("init conv");
                 helper
                     .init_conversation(
                         BackendRequest {
@@ -166,24 +192,26 @@
                 Ok(())
             })
         };
-
         self.tasks
             .lock()
             .unwrap()
             .insert(cookie.clone(), task.abort_handle());
-        let result = task.await.expect("join error");
-        // The only way to no reach this line, is to either panic in previous line, or if authorization cancelled,
-        // while cancellation will remove task by itself.
-        // TODO: But still it would be better to have abort guard, which will remove it from HashMap
-        self.tasks.lock().unwrap().remove(&cookie);
+        info!("abort handle stored");
+        let _ = _cancel_guard.set(CancelTaskOnDrop {
+            tasks: self.tasks.clone(),
+            handle: cookie.clone(),
+        });
+
+        let _ = task.await;
 
-        result
+        Ok(())
     }
 
     /// CancelAuthentication method
     async fn cancel_authentication(&self, cookie: &str) -> zbus::fdo::Result<()> {
-        trace!("cancel auth");
+        info!("auth cancelled");
         if let Some(abort) = self.tasks.lock().unwrap().remove(cookie) {
+            info!("abort handle found");
             abort.abort();
         }
         // debug!("Authentication cancled ! {cookie}");
modifiednix/nixos-modules.nixdiffbeforeafterboth
before · nix/nixos-modules.nix
1{config, ...}: {2  flake.nixosModules = rec {3    default = polkit-backend;4    polkit-backend = {pkgs, ...}: {5      services.dbus.packages = [6        config.flake.packages.${pkgs.stdenv.system}.polkit-backend7      ];8      systemd.packages = [9        config.flake.packages.${pkgs.stdenv.system}.polkit-backend10      ];11      systemd.services.remowt-polkit-helper = {12        aliases = ["dbus-lach.polkit.helper1.service"];13      };14    };15  };16}
after · nix/nixos-modules.nix
1{config, ...}: {2  flake.nixosModules = rec {3    default = polkit-backend;4    polkit-backend = {pkgs, ...}: {5      services.dbus.packages = [6        config.flake.packages.${pkgs.stdenv.system}.polkit-backend7      ];8      systemd.packages = [9        config.flake.packages.${pkgs.stdenv.system}.polkit-backend10      ];11      systemd.services.remowt-polkit-helper = {12        aliases = ["dbus-lach.polkit.helper1.service"];13        # Restarting can kill in-progress auth requests.14        # It is good to have it restarted for security, but I didn't decided on the flow yet, graceful shutdown?..15        unitConfig.X-RestartIfChanged = false;16      };17    };18  };19}