uninstall.rs
1 //! Uninstall command. 2 3 use acdc_core::{Config, Paths}; 4 use acdc_service::control; 5 use acdc_tui::{output, prompt}; 6 use anyhow::Result; 7 use std::fs; 8 use std::path::PathBuf; 9 10 /// Uninstall AC/DC components. 11 pub async fn run(purge: bool, yes: bool) -> Result<()> { 12 output::section("Uninstall AC/DC"); 13 14 if !yes { 15 println!(); 16 output::warning("This will:"); 17 println!(" - Stop all running node services"); 18 println!(" - Remove installed binaries (adnet, alphaos, deltaos)"); 19 if purge { 20 println!(" - Delete all configuration files"); 21 println!(" - Delete all data (blockchain data, logs)"); 22 output::warning("PURGE MODE: All data will be permanently deleted!"); 23 } 24 println!(); 25 26 if !prompt::confirm("Proceed with uninstall?") { 27 output::info("Cancelled", "No changes made"); 28 return Ok(()); 29 } 30 } 31 32 // Stop all services first 33 output::status("Stopping services..."); 34 let config = Config::load_default().ok(); 35 if let Some(cfg) = &config { 36 for node in &cfg.nodes.instances { 37 let _ = control::stop(&node.id).await; 38 } 39 } 40 output::success("Services stopped"); 41 42 // Remove installed binaries 43 output::status("Removing binaries..."); 44 let binaries = ["adnet", "alphaos", "deltaos"]; 45 let bin_paths = ["/usr/local/bin", "/opt/ac-dc/bin"]; 46 47 for bin in &binaries { 48 for dir in &bin_paths { 49 let path = PathBuf::from(dir).join(bin); 50 if path.exists() { 51 if let Err(e) = fs::remove_file(&path) { 52 output::warning(&format!("Could not remove {}: {}", path.display(), e)); 53 } else { 54 output::success(&format!("Removed {}", path.display())); 55 } 56 } 57 } 58 } 59 60 // Remove systemd services 61 output::status("Removing systemd services..."); 62 let systemd_dir = PathBuf::from("/etc/systemd/system"); 63 if let Ok(entries) = fs::read_dir(&systemd_dir) { 64 for entry in entries.flatten() { 65 let name = entry.file_name().to_string_lossy().to_string(); 66 if name.starts_with("ac-dc-") && name.ends_with(".service") { 67 let path = entry.path(); 68 if let Err(e) = fs::remove_file(&path) { 69 output::warning(&format!("Could not remove {}: {}", path.display(), e)); 70 } 71 } 72 } 73 } 74 75 if purge { 76 output::status("Purging data and configuration..."); 77 let paths = Paths::default(); 78 79 // Remove config directory 80 if paths.config_dir.exists() { 81 if let Err(e) = fs::remove_dir_all(&paths.config_dir) { 82 output::warning(&format!( 83 "Could not remove config dir {}: {}", 84 paths.config_dir.display(), 85 e 86 )); 87 } else { 88 output::success(&format!("Removed {}", paths.config_dir.display())); 89 } 90 } 91 92 // Remove data directory 93 if paths.data_dir.exists() { 94 if let Err(e) = fs::remove_dir_all(&paths.data_dir) { 95 output::warning(&format!( 96 "Could not remove data dir {}: {}", 97 paths.data_dir.display(), 98 e 99 )); 100 } else { 101 output::success(&format!("Removed {}", paths.data_dir.display())); 102 } 103 } 104 } 105 106 println!(); 107 output::success("Uninstall complete"); 108 109 if !purge { 110 println!(); 111 output::info( 112 "Note", 113 "Configuration and data were preserved. Use --purge to remove everything.", 114 ); 115 } 116 117 println!(); 118 output::info( 119 "ac-dc binary", 120 "The ac-dc binary itself was not removed. To remove it:", 121 ); 122 println!(" sudo rm /usr/local/bin/ac-dc"); 123 124 Ok(()) 125 }