mirror of https://github.com/ospab/ostp.git
feat: add --uninstall and --update CLI commands
This commit is contained in:
parent
4ab0f04a1b
commit
46c1ac4519
125
ostp/src/main.rs
125
ostp/src/main.rs
|
|
@ -38,6 +38,14 @@ struct Args {
|
||||||
|
|
||||||
/// Optional client connection share link (ostp://ACCESS_KEY@HOST:PORT) to run instantly
|
/// Optional client connection share link (ostp://ACCESS_KEY@HOST:PORT) to run instantly
|
||||||
url: Option<String>,
|
url: Option<String>,
|
||||||
|
|
||||||
|
/// Uninstall OSTP: stop service, remove binary and configuration files
|
||||||
|
#[arg(long)]
|
||||||
|
uninstall: bool,
|
||||||
|
|
||||||
|
/// Update OSTP: re-run the install script to fetch and install the latest version
|
||||||
|
#[arg(long)]
|
||||||
|
update: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_ostp_link(link: &str) -> Result<ClientConfig> {
|
fn parse_ostp_link(link: &str) -> Result<ClientConfig> {
|
||||||
|
|
@ -480,7 +488,15 @@ fn get_or_ask_public_ip(config_path: &std::path::Path) -> String {
|
||||||
|
|
||||||
async fn run_app() -> Result<()> {
|
async fn run_app() -> Result<()> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
|
if args.uninstall {
|
||||||
|
return cmd_uninstall();
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.update {
|
||||||
|
return cmd_update();
|
||||||
|
}
|
||||||
|
|
||||||
if args.generate_key {
|
if args.generate_key {
|
||||||
let mut new_keys = Vec::new();
|
let mut new_keys = Vec::new();
|
||||||
for _ in 0..args.count {
|
for _ in 0..args.count {
|
||||||
|
|
@ -899,6 +915,113 @@ async fn run_app() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Uninstall command
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn cmd_uninstall() -> Result<()> {
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
println!("[ostp] Uninstalling OSTP...");
|
||||||
|
|
||||||
|
// 1. Stop and disable systemd service (best-effort)
|
||||||
|
for action in &["stop", "disable"] {
|
||||||
|
let _ = Command::new("systemctl")
|
||||||
|
.args([action, "ostp"])
|
||||||
|
.status();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Remove the systemd unit file
|
||||||
|
let unit_path = std::path::Path::new("/etc/systemd/system/ostp.service");
|
||||||
|
if unit_path.exists() {
|
||||||
|
fs::remove_file(unit_path)?;
|
||||||
|
println!("[ostp] Removed {}", unit_path.display());
|
||||||
|
let _ = Command::new("systemctl")
|
||||||
|
.args(["daemon-reload"])
|
||||||
|
.status();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Remove binary
|
||||||
|
let bin_path = std::path::Path::new("/opt/ostp/ostp");
|
||||||
|
if bin_path.exists() {
|
||||||
|
fs::remove_file(bin_path)?;
|
||||||
|
println!("[ostp] Removed {}", bin_path.display());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Remove install directory
|
||||||
|
let install_dir = std::path::Path::new("/opt/ostp");
|
||||||
|
if install_dir.exists() {
|
||||||
|
fs::remove_dir_all(install_dir)?;
|
||||||
|
println!("[ostp] Removed {}", install_dir.display());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Remove configuration directory
|
||||||
|
let config_dir = std::path::Path::new("/etc/ostp");
|
||||||
|
if config_dir.exists() {
|
||||||
|
fs::remove_dir_all(config_dir)?;
|
||||||
|
println!("[ostp] Removed {}", config_dir.display());
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("[ostp] Uninstall complete.");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
fn cmd_uninstall() -> Result<()> {
|
||||||
|
anyhow::bail!("The 'uninstall' command is only supported on Linux/Unix systems.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Update command
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn cmd_update() -> Result<()> {
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
// Prefer the install script next to the binary, then the well-known path.
|
||||||
|
let script_candidates = [
|
||||||
|
"/opt/ostp/install.sh",
|
||||||
|
"/tmp/ostp_install.sh",
|
||||||
|
];
|
||||||
|
|
||||||
|
let script_path = script_candidates
|
||||||
|
.iter()
|
||||||
|
.find(|p| std::path::Path::new(p).exists())
|
||||||
|
.copied();
|
||||||
|
|
||||||
|
if let Some(path) = script_path {
|
||||||
|
println!("[ostp] Running update script: {}", path);
|
||||||
|
let status = Command::new("bash")
|
||||||
|
.arg(path)
|
||||||
|
.status()
|
||||||
|
.map_err(|e| anyhow!("Failed to execute install script: {e}"))?;
|
||||||
|
|
||||||
|
if !status.success() {
|
||||||
|
anyhow::bail!("Install script exited with status: {}", status);
|
||||||
|
}
|
||||||
|
println!("[ostp] Update complete.");
|
||||||
|
} else {
|
||||||
|
// Download and run the script on the fly
|
||||||
|
println!("[ostp] install.sh not found locally – downloading from GitHub...");
|
||||||
|
let status = Command::new("bash")
|
||||||
|
.args(["-c", "curl -fsSL https://raw.githubusercontent.com/ospab/ostp/main/scripts/install.sh | bash"])
|
||||||
|
.status()
|
||||||
|
.map_err(|e| anyhow!("Failed to download/run install script: {e}"))?;
|
||||||
|
|
||||||
|
if !status.success() {
|
||||||
|
anyhow::bail!("Update script exited with status: {}", status);
|
||||||
|
}
|
||||||
|
println!("[ostp] Update complete.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
fn cmd_update() -> Result<()> {
|
||||||
|
anyhow::bail!("The 'update' command is only supported on Linux/Unix systems.");
|
||||||
|
}
|
||||||
|
|
||||||
async fn run_client_directly(client_cfg: ClientConfig) -> Result<()> {
|
async fn run_client_directly(client_cfg: ClientConfig) -> Result<()> {
|
||||||
let is_tun_enabled = client_cfg.tun.as_ref().map(|t| t.enable).unwrap_or(false);
|
let is_tun_enabled = client_cfg.tun.as_ref().map(|t| t.enable).unwrap_or(false);
|
||||||
let mode_str = if is_tun_enabled { "tun" } else { "proxy" };
|
let mode_str = if is_tun_enabled { "tun" } else { "proxy" };
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue