diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2fcf2a0..152ddf2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -110,6 +110,8 @@ jobs: artifacts/* install.sh install.ps1 + uninstall.sh + uninstall.ps1 # Pre-release tags (e.g. v1.1.0-alpha.1) publish as pre-releases. prerelease: ${{ contains(github.ref_name, '-alpha') }} generate_release_notes: true diff --git a/README.md b/README.md index 55496bf..2ca809f 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,16 @@ powershell -ExecutionPolicy Bypass -c "irm https://raw.githubusercontent.com/emi ``` Set `SCIMESH_AUTO_START=0` to install without starting anything. The old demo -control room was removed: `/ui` is the admin console. A standalone +control room was removed: `/ui` is the admin console. + +To remove a component, run the matching uninstaller (data is kept unless you +pass `--purge`): + +```bash +curl -fsSL https://raw.githubusercontent.com/emil28092005/SciMesh/main/uninstall.sh | bash -s coordinator +curl -fsSL https://raw.githubusercontent.com/emil28092005/SciMesh/main/uninstall.sh | bash -s worker --purge +# Windows: irm .../uninstall.ps1 | iex (set $env:SCIMESH_COMPONENT, -Purge deletes data) +``` A standalone worker is installed the same way (`bash -s worker`, or `SCIMESH_COMPONENT=worker` on Windows); its installer opens the local setup wizard (`worker-agent setup`) in the browser automatically. diff --git a/uninstall.ps1 b/uninstall.ps1 new file mode 100644 index 0000000..565bdf3 --- /dev/null +++ b/uninstall.ps1 @@ -0,0 +1,66 @@ +# SciMesh uninstaller for Windows: stops the running component, removes its +# binary, and — when asked — deletes its data directory. +# +# powershell -ExecutionPolicy Bypass -c "irm https://raw.githubusercontent.com/emil28092005/SciMesh/main/uninstall.ps1 | iex" +# +# $env:SCIMESH_COMPONENT selects the component (coordinator | worker | all, +# default all). Data is kept unless $env:SCIMESH_PURGE -eq "1" or the +# -Purge switch is passed (in a pipe there is no interactive prompt). +param( + [switch]$Purge +) +$ErrorActionPreference = "Stop" + +$Component = if ($env:SCIMESH_COMPONENT) { $env:SCIMESH_COMPONENT } else { "all" } +if ($Purge -or $env:SCIMESH_PURGE -eq "1") { $Purge = $true } else { $Purge = $false } + +$InstallDir = if ($env:SCIMESH_INSTALL_DIR) { + $env:SCIMESH_INSTALL_DIR +} else { + Join-Path $env:LOCALAPPDATA "SciMesh" +} + +function Remove-Component { + param([string]$Name, [string]$Binary) + Write-Host "Stopping $Name…" + Get-Process -Name $Name -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue + $target = Join-Path $InstallDir $Binary + if (Test-Path $target) { + Write-Host "Removing $target…" + Remove-Item -Force $target + } +} + +function Remove-Data { + param([string]$Dir, [string]$Label) + if (-not (Test-Path $Dir)) { return } + if ($Purge) { + Remove-Item -Recurse -Force $Dir + Write-Host "Deleted $Dir" + return + } + # No interactive prompt in a pipe: keep the data by default. + Write-Host "Keeping $Dir ($Label). Pass -Purge to delete it." +} + +switch ($Component) { + "coordinator" { + Remove-Component -Name "coordinator" -Binary "coordinator.exe" + Remove-Data -Dir (Join-Path $HOME ".scimesh") -Label "secrets, databases, artifacts, users" + } + "worker" { + Remove-Component -Name "worker-agent" -Binary "worker-agent.exe" + Remove-Data -Dir (Join-Path $HOME ".scimesh-worker") -Label "worker config, runtime venv, logs" + } + "all" { + Remove-Component -Name "coordinator" -Binary "coordinator.exe" + Remove-Component -Name "worker-agent" -Binary "worker-agent.exe" + Remove-Data -Dir (Join-Path $HOME ".scimesh") -Label "secrets, databases, artifacts, users" + Remove-Data -Dir (Join-Path $HOME ".scimesh-worker") -Label "worker config, runtime venv, logs" + } + default { throw "unknown component: $Component (use 'coordinator', 'worker' or 'all')" } +} + +Write-Host "" +Write-Host "SciMesh $Component uninstalled." +Write-Host "Pass -Purge to also delete the data directories." diff --git a/uninstall.sh b/uninstall.sh new file mode 100644 index 0000000..9d9b6d8 --- /dev/null +++ b/uninstall.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# SciMesh uninstaller: stops the running component, removes its binary, and — +# when asked — deletes its data directory. +# +# curl -fsSL https://raw.githubusercontent.com/emil28092005/SciMesh/main/uninstall.sh | bash -s coordinator +# curl -fsSL https://raw.githubusercontent.com/emil28092005/SciMesh/main/uninstall.sh | bash -s worker +# curl -fsSL https://raw.githubusercontent.com/emil28092005/SciMesh/main/uninstall.sh # both +# +# Data (jobs, artifacts, users, secrets, the managed venv) is kept by default. +# Pass --purge (or set SCIMESH_PURGE=1) to delete it without asking; without +# it the script prompts interactively. Because `curl | bash` pipes have no +# interactive stdin, the default is always "keep data". +set -eu + +COMPONENT="${1:-all}" +PURGE=0 +for arg in "$@"; do + case "$arg" in + --purge) PURGE=1 ;; + esac +done +[ "${SCIMESH_PURGE:-0}" = "1" ] && PURGE=1 + +INSTALL_DIR="${SCIMESH_INSTALL_DIR:-$HOME/.local/bin}" + +remove_component() { + case "$1" in + coordinator) + echo "Stopping the coordinator (serve)…" + pkill -x coordinator 2>/dev/null || true + echo "Removing $INSTALL_DIR/coordinator…" + rm -f "$INSTALL_DIR/coordinator" + ;; + worker) + echo "Stopping the worker agent and its setup wizard…" + pkill -x worker-agent 2>/dev/null || true + echo "Removing $INSTALL_DIR/worker-agent…" + rm -f "$INSTALL_DIR/worker-agent" + ;; + *) echo "unknown component: $1 (use 'coordinator', 'worker' or 'all')" >&2; exit 1 ;; + esac +} + +remove_data() { + local dir="$1" label="$2" + if [ ! -d "$dir" ]; then + return 0 + fi + if [ "$PURGE" = "1" ]; then + rm -rf "$dir" + echo "Deleted $dir" + return 0 + fi + # In a pipe (curl | bash) stdin is exhausted, so the prompt defaults to keep. + printf "Delete %s (%s)? [y/N] " "$dir" "$label" + read -r answer || answer="" + case "$answer" in + y|Y|yes|YES) rm -rf "$dir"; echo "Deleted $dir" ;; + *) echo "Keeping $dir" ;; + esac +} + +case "$COMPONENT" in + coordinator) + remove_component coordinator + remove_data "$HOME/.scimesh" "secrets, databases, artifacts, users, managed venv" + ;; + worker) + remove_component worker + remove_data "$HOME/.scimesh-worker" "worker config, runtime venv, logs" + ;; + all) + remove_component coordinator + remove_component worker + remove_data "$HOME/.scimesh" "secrets, databases, artifacts, users, managed venv" + remove_data "$HOME/.scimesh-worker" "worker config, runtime venv, logs" + ;; + *) echo "unknown component: $COMPONENT (use 'coordinator', 'worker' or 'all')" >&2; exit 1 ;; +esac + +echo +echo "SciMesh $COMPONENT uninstalled." +echo "Pass --purge to also delete the data directories without asking."