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
306 "piper",306 "piper",
307]307]
308
309[[package]]
310name = "byteorder"
311version = "1.5.0"
312source = "registry+https://github.com/rust-lang/crates.io-index"
313checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
308314
309[[package]]315[[package]]
310name = "bytes"316name = "bytes"
311version = "1.6.1"317version = "1.7.1"
312source = "registry+https://github.com/rust-lang/crates.io-index"318source = "registry+https://github.com/rust-lang/crates.io-index"
313checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952"319checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
314320
315[[package]]321[[package]]
316name = "cc"322name = "cc"
317version = "1.1.6"323version = "1.1.7"
318source = "registry+https://github.com/rust-lang/crates.io-index"324source = "registry+https://github.com/rust-lang/crates.io-index"
319checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"325checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
320326
321[[package]]327[[package]]
322name = "cexpr"328name = "cexpr"
644650
645[[package]]651[[package]]
646name = "indexmap"652name = "indexmap"
647version = "2.2.6"653version = "2.3.0"
648source = "registry+https://github.com/rust-lang/crates.io-index"654source = "registry+https://github.com/rust-lang/crates.io-index"
649checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"655checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0"
650dependencies = [656dependencies = [
651 "equivalent",657 "equivalent",
652 "hashbrown",658 "hashbrown",
905911
906[[package]]912[[package]]
907name = "ppv-lite86"913name = "ppv-lite86"
908version = "0.2.17"914version = "0.2.20"
909source = "registry+https://github.com/rust-lang/crates.io-index"915source = "registry+https://github.com/rust-lang/crates.io-index"
910checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"916checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
917dependencies = [
918 "zerocopy",
919]
911920
912[[package]]921[[package]]
913name = "proc-macro-crate"922name = "proc-macro-crate"
968977
969[[package]]978[[package]]
970name = "regex"979name = "regex"
971version = "1.10.5"980version = "1.10.6"
972source = "registry+https://github.com/rust-lang/crates.io-index"981source = "registry+https://github.com/rust-lang/crates.io-index"
973checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"982checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
974dependencies = [983dependencies = [
975 "aho-corasick",984 "aho-corasick",
976 "memchr",985 "memchr",
10891098
1090[[package]]1099[[package]]
1091name = "serde_json"1100name = "serde_json"
1092version = "1.0.120"1101version = "1.0.122"
1093source = "registry+https://github.com/rust-lang/crates.io-index"1102source = "registry+https://github.com/rust-lang/crates.io-index"
1094checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5"1103checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da"
1095dependencies = [1104dependencies = [
1096 "itoa",1105 "itoa",
1106 "memchr",
1097 "ryu",1107 "ryu",
1098 "serde",1108 "serde",
1099]1109]
12051215
1206[[package]]1216[[package]]
1207name = "tempfile"1217name = "tempfile"
1208version = "3.10.1"1218version = "3.11.0"
1209source = "registry+https://github.com/rust-lang/crates.io-index"1219source = "registry+https://github.com/rust-lang/crates.io-index"
1210checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"1220checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53"
1211dependencies = [1221dependencies = [
1212 "cfg-if",1222 "cfg-if",
1213 "fastrand",1223 "fastrand",
1224 "once_cell",
1214 "rustix",1225 "rustix",
1215 "windows-sys",1226 "windows-sys",
1216]1227]
12761287
1277[[package]]1288[[package]]
1278name = "toml_datetime"1289name = "toml_datetime"
1279version = "0.6.7"1290version = "0.6.8"
1280source = "registry+https://github.com/rust-lang/crates.io-index"1291source = "registry+https://github.com/rust-lang/crates.io-index"
1281checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db"1292checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
12821293
1283[[package]]1294[[package]]
1284name = "toml_edit"1295name = "toml_edit"
1605 "zbus",1616 "zbus",
1606]1617]
1618
1619[[package]]
1620name = "zerocopy"
1621version = "0.7.35"
1622source = "registry+https://github.com/rust-lang/crates.io-index"
1623checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
1624dependencies = [
1625 "byteorder",
1626 "zerocopy-derive",
1627]
1628
1629[[package]]
1630name = "zerocopy-derive"
1631version = "0.7.35"
1632source = "registry+https://github.com/rust-lang/crates.io-index"
1633checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
1634dependencies = [
1635 "proc-macro2",
1636 "quote",
1637 "syn 2.0.72",
1638]
16071639
1608[[package]]1640[[package]]
1609name = "zvariant"1641name = "zvariant"
modifiedcmds/remowt-agent/src/main.rsdiffbeforeafterboth
2use std::collections::{BTreeMap, HashMap};2use std::collections::{BTreeMap, HashMap};
3use std::io::{stdout, Write};3use std::io::{stdout, Write};
4use std::marker::PhantomData;4use std::marker::PhantomData;
5use std::sync::{Mutex, RwLock};5use std::sync::{Arc, Mutex, OnceLock};
6use std::{future, process};6use std::{future, process};
77
8use clap::Parser;8use clap::Parser;
9use polkit_shared::{emphasize, BackendRequest, Identity, PidDisplay};9use polkit_shared::{emphasize, BackendRequest, Identity, PidDisplay};
10use tokio::runtime::Handle;10use tokio::runtime::Handle;
11use tokio::task::{AbortHandle, JoinHandle, LocalSet};11use tokio::task::{AbortHandle, JoinHandle, LocalSet};
12use tracing::trace;12use tracing::{info, trace};
13use ui_prompt::dbus::DbusPrompterInterface;13use ui_prompt::dbus::DbusPrompterInterface;
14use ui_prompt::rofi::RofiPrompter;14use ui_prompt::rofi::RofiPrompter;
15use ui_prompt::{PrependSourcePrompter, Prompter, Source};15use ui_prompt::{PrependSourcePrompter, Prompter, Source};
58 }58 }
59}59}
60
61struct CancelTaskOnDrop {
62 tasks: Arc<Mutex<HashMap<String, AbortHandle>>>,
63 handle: String,
64}
65impl Drop for CancelTaskOnDrop {
66 fn drop(&mut self) {
67 info!("cancel on drop");
68 if let Some(task) = self
69 .tasks
70 .lock()
71 .expect("not poisoned")
72 .remove(&self.handle)
73 {
74 task.abort();
75 }
76 }
77}
6078
61struct Agent {79struct Agent {
62 helper: PolkitHelperProxy<'static>,80 helper: PolkitHelperProxy<'static>,
63 tasks: Mutex<HashMap<String, AbortHandle>>,81 tasks: Arc<Mutex<HashMap<String, AbortHandle>>>,
64 connection: Connection,82 connection: Connection,
65}83}
66impl Agent {84impl Agent {
67 async fn new(connection: Connection) -> anyhow::Result<Self> {85 async fn new(connection: Connection) -> anyhow::Result<Self> {
68 Ok(Self {86 Ok(Self {
69 helper: PolkitHelperProxy::new(&connection).await?,87 helper: PolkitHelperProxy::new(&connection).await?,
70 tasks: Mutex::new(HashMap::new()),88 tasks: Arc::new(Mutex::new(HashMap::new())),
71 connection,89 connection,
72 })90 })
73 }91 }
78 /// BeginAuthentication method96 /// BeginAuthentication method
79 #[allow(clippy::too_many_arguments)]97 #[allow(clippy::too_many_arguments)]
80 async fn begin_authentication(98 async fn begin_authentication(
81 &mut self,99 &self,
82 action_id: String,100 action_id: String,
83 message: String,101 message: String,
84 icon_name: String,102 icon_name: String,
87 identities: Vec<Identity>,105 identities: Vec<Identity>,
88 ) -> zbus::fdo::Result<()> {106 ) -> zbus::fdo::Result<()> {
89 use std::fmt::Write;107 use std::fmt::Write;
90 trace!("begin auth");108 info!("begin auth");
109 let _cancel_guard = Arc::new(OnceLock::new());
91 let task = {110 let task = {
92 let connection = self.connection.clone();111 let connection = self.connection.clone();
93 let helper = self.helper.clone();112 let helper = self.helper.clone();
94 let cookie = cookie.clone();113 let cookie = cookie.clone();
114 let _cancel_guard = _cancel_guard.clone();
95 tokio::task::spawn(async move {115 tokio::task::spawn(async move {
116 let _cancel_guard = _cancel_guard.clone();
96 trace!("conversation task");117 trace!("conversation task");
97 let mut description = format!("{message}\n\n<b>Action id:</b> {action_id}",);118 let mut description = format!("{message}\n\n<b>Action id:</b> {action_id}",);
98 if let Some(subject) = details.remove("polkit.caller-pid") {119 if let Some(subject) = details.remove("polkit.caller-pid") {
121 identities.iter().map(|v| v.to_string()).collect();142 identities.iter().map(|v| v.to_string()).collect();
122 let identity_displays: Vec<&str> =143 let identity_displays: Vec<&str> =
123 identity_displays.iter().map(|v| v.as_str()).collect();144 identity_displays.iter().map(|v| v.as_str()).collect();
145 info!("choose identity");
124 let choosen_identity = match identity_displays.len() {146 let choosen_identity = match identity_displays.len() {
125 0 => {147 0 => {
126 return Err(fdo::Error::AuthFailed(148 return Err(fdo::Error::AuthFailed(
139 .await?161 .await?
140 }162 }
141 };163 };
164 info!("identity chosen");
142165
143 let _ = write!(166 let _ = write!(
144 description,167 description,
148 prompter.description = description;171 prompter.description = description;
149172
150 prompter.source.push(Source(Cow::Borrowed("polkit daemon")));173 prompter.source.push(Source(Cow::Borrowed("polkit daemon")));
174 // let connection = Connection::system().await?;
175 // let helper = PolkitHelperProxy::new(&connection).await?;
151 let prompter = TemporaryPrompterInterface::new(connection, prompter).await;176 let prompter = TemporaryPrompterInterface::new(connection, prompter).await;
177 info!("init conv");
152 helper178 helper
153 .init_conversation(179 .init_conversation(
154 BackendRequest {180 BackendRequest {
171 .lock()196 .lock()
172 .unwrap()197 .unwrap()
173 .insert(cookie.clone(), task.abort_handle());198 .insert(cookie.clone(), task.abort_handle());
174 let result = task.await.expect("join error");199 info!("abort handle stored");
175 // The only way to no reach this line, is to either panic in previous line, or if authorization cancelled,200 let _ = _cancel_guard.set(CancelTaskOnDrop {
176 // while cancellation will remove task by itself.
177 // TODO: But still it would be better to have abort guard, which will remove it from HashMap
178 self.tasks.lock().unwrap().remove(&cookie);201 tasks: self.tasks.clone(),
179202 handle: cookie.clone(),
180 result203 });
204
205 let _ = task.await;
206
207 Ok(())
181 }208 }
182209
183 /// CancelAuthentication method210 /// CancelAuthentication method
184 async fn cancel_authentication(&self, cookie: &str) -> zbus::fdo::Result<()> {211 async fn cancel_authentication(&self, cookie: &str) -> zbus::fdo::Result<()> {
185 trace!("cancel auth");212 info!("auth cancelled");
186 if let Some(abort) = self.tasks.lock().unwrap().remove(cookie) {213 if let Some(abort) = self.tasks.lock().unwrap().remove(cookie) {
214 info!("abort handle found");
187 abort.abort();215 abort.abort();
188 }216 }
189 // debug!("Authentication cancled ! {cookie}");217 // debug!("Authentication cancled ! {cookie}");
modifiednix/nixos-modules.nixdiffbeforeafterboth
10 ];10 ];
11 systemd.services.remowt-polkit-helper = {11 systemd.services.remowt-polkit-helper = {
12 aliases = ["dbus-lach.polkit.helper1.service"];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;
13 };16 };
14 };17 };
15 };18 };