diff --git a/libs/protocol/src/launchpad.rs b/libs/protocol/src/launchpad.rs index 3a4b5dd4..52c849fb 100644 --- a/libs/protocol/src/launchpad.rs +++ b/libs/protocol/src/launchpad.rs @@ -47,6 +47,7 @@ pub enum LaunchpadAction { Connect, ChangeSession(LaunchpadSession), SaveSettings(Box), + ResetSettings, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/libs/sdm-launchpad/src/bus.rs b/libs/sdm-launchpad/src/bus.rs index a3d87d94..b6fa064a 100644 --- a/libs/sdm-launchpad/src/bus.rs +++ b/libs/sdm-launchpad/src/bus.rs @@ -193,6 +193,10 @@ impl LaunchpadWorker { LaunchpadAction::SaveSettings(settings) => { self.save_settings(*settings).await?; }, + LaunchpadAction::ResetSettings => { + self.reset_settings().await?; + self.scope.reset_docker().await?; + }, } Ok(()) } @@ -244,6 +248,22 @@ impl LaunchpadWorker { Ok(()) } + async fn reset_settings(&mut self) -> Result<(), Error> { + debug!("Remove the settings file"); + + let mut path = self + .state + .config + .settings + .as_ref() + .map(|s| s.data_directory.clone()) + .ok_or_else(|| Error::msg("Can't reset the settings: no settings are attached to the config"))?; + path.push("config"); + path.push("settings.toml"); + tokio::fs::remove_file(path).await?; + Ok(()) + } + async fn process_report(&mut self, report: ReportEnvelope) -> Result<(), Error> { // TODO: Convert to the `LaunchpadDelta` and apply match report.details { diff --git a/libs/sdm/src/image/task/mod.rs b/libs/sdm/src/image/task/mod.rs index 7ab0a9d6..51413561 100644 --- a/libs/sdm/src/image/task/mod.rs +++ b/libs/sdm/src/image/task/mod.rs @@ -101,6 +101,10 @@ impl RunnableContext> for TaskContext Result<(), Error> { self.process_update_impl().await } + + async fn reset(&mut self) -> Result<(), Error> { + self.reset().await + } } impl TaskContext> { diff --git a/libs/sdm/src/image/task/update.rs b/libs/sdm/src/image/task/update.rs index 7377930b..07a364ab 100644 --- a/libs/sdm/src/image/task/update.rs +++ b/libs/sdm/src/image/task/update.rs @@ -46,6 +46,14 @@ impl TaskContext> { } } + pub async fn reset(&mut self) -> Result<(), Error> { + if self.image_exists().await { + drop(self.do_drop_image().await); + } + + self.try_remove_container().await + } + async fn do_initial_state(&mut self) -> Result<(), Error> { log::trace!("[Update event: Image] `do_initial_state` {}", self.inner.image_name); self.update_task_status(TaskStatus::Inactive)?; diff --git a/libs/sdm/src/network/task/mod.rs b/libs/sdm/src/network/task/mod.rs index eab6927d..03d95a48 100644 --- a/libs/sdm/src/network/task/mod.rs +++ b/libs/sdm/src/network/task/mod.rs @@ -89,6 +89,10 @@ impl RunnableContext> for TaskContext Result<(), Error> { self.process_update_impl().await } + + async fn reset(&mut self) -> Result<(), Error> { + self.reset().await + } } #[derive(Debug)] diff --git a/libs/sdm/src/network/task/update.rs b/libs/sdm/src/network/task/update.rs index 0a14b806..f0ec8855 100644 --- a/libs/sdm/src/network/task/update.rs +++ b/libs/sdm/src/network/task/update.rs @@ -39,6 +39,10 @@ impl TaskContext> { } } + pub async fn reset(&mut self) -> Result<(), Error> { + self.do_cleanup().await + } + async fn do_initial_state(&mut self) -> Result<(), Error> { log::trace!("[Update event: Network] `do_initial_state`"); self.update_task_status(TaskStatus::Inactive)?; diff --git a/libs/sdm/src/scope.rs b/libs/sdm/src/scope.rs index a198c369..9b20c3b1 100644 --- a/libs/sdm/src/scope.rs +++ b/libs/sdm/src/scope.rs @@ -70,6 +70,7 @@ pub enum ControlEvent { task_id: TaskId, }, InnerEvent(C::Inner), + Reset, } impl Clone for ControlEvent { @@ -84,6 +85,7 @@ impl Clone for ControlEvent { task_id: task_id.clone(), }, Self::InnerEvent(inner) => Self::InnerEvent(inner.clone()), + Self::Reset => Self::Reset, } } } @@ -172,4 +174,8 @@ impl SdmScope { } pub fn stop(&self) {} + + pub async fn reset_docker(&mut self) -> Result<(), Error> { + self.send(ControlEvent::Reset) + } } diff --git a/libs/sdm/src/task.rs b/libs/sdm/src/task.rs index 6220a713..1b39b063 100644 --- a/libs/sdm/src/task.rs +++ b/libs/sdm/src/task.rs @@ -77,6 +77,7 @@ pub trait RunnableTask: Sized + Send + 'static { pub trait RunnableContext { /// Subscribe to events here async fn initialize(&mut self); + async fn reset(&mut self) -> Result<(), Error>; fn reconfigure(&mut self, config: Option<&::Config>) -> bool; fn process_inner_event(&mut self, event: ::Inner); fn process_event(&mut self, event: T::Event) -> Result<(), Error>; @@ -298,7 +299,7 @@ where self.context.status.get() ); if let Some(Ok(req)) = req { - self.process_request(req); + self.process_request(req).await; } else { log::info!("Requests stream closed"); break; @@ -338,7 +339,7 @@ where } } - fn process_request(&mut self, req: ControlEvent) { + async fn process_request(&mut self, req: ControlEvent) { match req { ControlEvent::SetConfig(config) => { let config = config.as_deref(); @@ -363,6 +364,9 @@ where ControlEvent::InnerEvent(inner) => { self.process_inner_event(inner); }, + ControlEvent::Reset => { + drop(self.reset().await); + }, } } @@ -398,6 +402,10 @@ where self.context.should_start = is_active; } + pub async fn reset(&mut self) { + drop(self.context.reset().await); + } + pub fn process_inner_event(&mut self, event: ::Inner) { self.context.process_inner_event(event); } diff --git a/libs/sdm/src/volume/task/docker.rs b/libs/sdm/src/volume/task/docker.rs index 8b872aec..282fec6d 100644 --- a/libs/sdm/src/volume/task/docker.rs +++ b/libs/sdm/src/volume/task/docker.rs @@ -27,7 +27,7 @@ use anyhow::Error; use bollard::{ models::{EventMessage, EventMessageTypeEnum}, system::EventsOptions, - volume::CreateVolumeOptions, + volume::{CreateVolumeOptions, RemoveVolumeOptions}, }; use futures::TryStreamExt; @@ -73,11 +73,11 @@ impl TaskContext> { Ok(()) } - // pub async fn try_remove_volume(&mut self) -> Result<(), Error> { - // let opts = RemoveVolumeOptions { force: true }; - // self.driver.remove_volume(&self.inner.volume_name, Some(opts)).await?; - // Ok(()) - // } + pub async fn try_remove_volume(&mut self) -> Result<(), Error> { + let opts: RemoveVolumeOptions = RemoveVolumeOptions { force: true }; + self.driver.remove_volume(&self.inner.volume_name, Some(opts)).await?; + Ok(()) + } } struct EventConv { diff --git a/libs/sdm/src/volume/task/mod.rs b/libs/sdm/src/volume/task/mod.rs index 5df09d31..9f553fc0 100644 --- a/libs/sdm/src/volume/task/mod.rs +++ b/libs/sdm/src/volume/task/mod.rs @@ -90,6 +90,10 @@ impl RunnableContext> for TaskContext Result<(), Error> { self.process_update_impl().await } + + async fn reset(&mut self) -> Result<(), Error> { + self.reset().await + } } #[derive(Debug)] diff --git a/libs/sdm/src/volume/task/update.rs b/libs/sdm/src/volume/task/update.rs index 2b3697e8..cdf74465 100644 --- a/libs/sdm/src/volume/task/update.rs +++ b/libs/sdm/src/volume/task/update.rs @@ -37,6 +37,10 @@ impl TaskContext> { } } + pub async fn reset(&mut self) -> Result<(), Error> { + self.try_remove_volume().await + } + async fn do_initial_state(&mut self) -> Result<(), Error> { log::trace!("[Update event: Volume] `do_initial_state`"); self.update_task_status(TaskStatus::Inactive)?; diff --git a/ui/frontend/src/containers/SettingsContainer/ResetSettings/ResetSettings.tsx b/ui/frontend/src/containers/SettingsContainer/ResetSettings/ResetSettings.tsx index b51352e6..f526050f 100644 --- a/ui/frontend/src/containers/SettingsContainer/ResetSettings/ResetSettings.tsx +++ b/ui/frontend/src/containers/SettingsContainer/ResetSettings/ResetSettings.tsx @@ -9,7 +9,7 @@ import { import { SettingsBox, SettingsContainer } from '../styles'; import t from '../../../locales'; -function ResetSettings() { +function ResetSettings({ handleReset }: { handleReset: VoidFunction }) { const [confirmReset, setConfirmReset] = useState(false); return ( @@ -38,8 +38,8 @@ function ResetSettings() { - )} diff --git a/ui/frontend/src/containers/SettingsContainer/SettingsDialog.tsx b/ui/frontend/src/containers/SettingsContainer/SettingsDialog.tsx index 85f472fd..de99e2e5 100644 --- a/ui/frontend/src/containers/SettingsContainer/SettingsDialog.tsx +++ b/ui/frontend/src/containers/SettingsContainer/SettingsDialog.tsx @@ -107,6 +107,12 @@ function SettingsDialog() { })); }; + const handleResetSettings = () => { + emit('tari://actions', { + Action: { type: 'ResetSettings' }, + }); + } + const menuItems = [ { label: 'Tari Mining', @@ -146,7 +152,7 @@ function SettingsDialog() { }, { label: 'Reset', - component: , + component: , }, ]; diff --git a/ui/frontend/src/locales/reset.ts b/ui/frontend/src/locales/reset.ts index 56e47199..c8cfd664 100644 --- a/ui/frontend/src/locales/reset.ts +++ b/ui/frontend/src/locales/reset.ts @@ -8,6 +8,6 @@ export default { 'Clean all settings and start from scratch (requires restarting)', resetButton: 'Reset', keepEditing: 'Keep editing', - resetAndExit: 'Reset & Exit', + reset: 'Reset', }, }; diff --git a/ui/frontend/src/store/appStateStore.ts b/ui/frontend/src/store/appStateStore.ts index 82844cc9..36aa3796 100644 --- a/ui/frontend/src/store/appStateStore.ts +++ b/ui/frontend/src/store/appStateStore.ts @@ -230,6 +230,11 @@ const useAppStateStore = create((set, get) => ({ Action: { type: 'SaveSettings', payload: settings }, }); }, + reset_settings: async () => { + emit('tari://actions', { + Action: { type: 'ResetSettings' }, + }) + } })); export default useAppStateStore;