From 06158663111e1b41abb437dc5f819f96f6287617 Mon Sep 17 00:00:00 2001 From: Bobban Rydh Date: Wed, 2 Sep 2026 22:21:05 +0200 Subject: [PATCH] Add agent uninstall script and UI reveal Lets a server be cleanly removed from agent management: uninstall.sh stops/disables the systemd timer and deletes the unit files, the installed script, and the credentials env file, without touching the server's entry or task history in the app. install.sh now prints the uninstall command on success, and the Servers page has an "Uninstall" button that reveals the same command (safe to show anytime since it carries no secret). --- README.md | 20 ++++++++++++++++++ agent/linux/install.sh | 1 + agent/linux/uninstall.sh | 38 ++++++++++++++++++++++++++++++++++ web/src/pages/ServersAdmin.tsx | 15 ++++++++++++++ web/src/styles.css | 5 +++++ 5 files changed, 79 insertions(+) create mode 100644 agent/linux/uninstall.sh diff --git a/README.md b/README.md index 3af5970..03b9c44 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,26 @@ Tasks that stop appearing in a server's report are marked **stale** rather than deleted (so a temporary agent failure doesn't wipe history) and are hidden by default — toggle "Show stale/missing tasks" to see them. +To remove the agent from a server, run: + +```sh +curl -fsSL https://schedule.example.lan/agent/linux/uninstall.sh | bash +``` + +This stops and deletes the systemd timer/service, the installed script, and +`/etc/schedule-task-manager-agent.env` (which holds the API token). It does +not delete the server's entry or task history in the app — the same "Uninstall" +button on the Servers page shows this command, and "Delete" removes the entry +entirely if you no longer want it tracked. + +## 5. Manually tracked tasks + +Not everything is discoverable by the agent — e.g. a scheduled job running +inside a Docker container. Use **Add task** on the Dashboard to log those by +hand. Manually entered tasks are never touched by agent reports (they have +their own `origin`), so they won't be marked stale or overwritten by the next +sync. + ## Environment variables See [`.env.example`](.env.example) for the full list with descriptions. diff --git a/agent/linux/install.sh b/agent/linux/install.sh index 994add6..36aa887 100644 --- a/agent/linux/install.sh +++ b/agent/linux/install.sh @@ -69,3 +69,4 @@ echo "Installed. Running an initial report now..." "$INSTALL_DIR/schedule-task-manager-agent.sh" echo "Done. The agent reports every ${INTERVAL_MINUTES} minute(s) via the 'schedule-task-manager-agent.timer' systemd timer." +echo "To remove it later: curl -fsSL $API_URL/agent/linux/uninstall.sh | bash" diff --git a/agent/linux/uninstall.sh b/agent/linux/uninstall.sh new file mode 100644 index 0000000..474aa51 --- /dev/null +++ b/agent/linux/uninstall.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Removes the Schedule Task Manager agent from this server: stops and deletes +# its systemd timer/service, the installed script, and its credentials file. +# +# Usage: +# curl -fsSL https://schedule.example.lan/agent/linux/uninstall.sh | bash +# +set -euo pipefail + +INSTALL_DIR="/usr/local/bin" +CONFIG_DIR="/etc" +SYSTEMD_DIR="/etc/systemd/system" + +if [[ "$EUID" -ne 0 ]]; then + echo "This uninstaller must be run as root." >&2 + exit 1 +fi + +echo "Removing Schedule Task Manager agent..." + +if command -v systemctl >/dev/null 2>&1; then + systemctl disable --now schedule-task-manager-agent.timer >/dev/null 2>&1 || true +fi + +rm -f \ + "$SYSTEMD_DIR/schedule-task-manager-agent.timer" \ + "$SYSTEMD_DIR/schedule-task-manager-agent.service" \ + "$CONFIG_DIR/schedule-task-manager-agent.env" \ + "$INSTALL_DIR/schedule-task-manager-agent.sh" \ + /tmp/stm-agent-response.json + +if command -v systemctl >/dev/null 2>&1; then + systemctl daemon-reload +fi + +echo "Done. The agent no longer runs or reports from this server." +echo "Its entry (and task history) in Schedule Task Manager is untouched —" \ + "delete it from the Servers page if you no longer want it tracked." diff --git a/web/src/pages/ServersAdmin.tsx b/web/src/pages/ServersAdmin.tsx index b4384e0..554ebef 100644 --- a/web/src/pages/ServersAdmin.tsx +++ b/web/src/pages/ServersAdmin.tsx @@ -7,6 +7,7 @@ export default function ServersAdmin() { const [hostname, setHostname] = useState(""); const [description, setDescription] = useState(""); const [newToken, setNewToken] = useState<{ server: ServerRecord; token: string } | null>(null); + const [uninstallFor, setUninstallFor] = useState(null); const [error, setError] = useState(null); const load = () => api.servers.list().then((res) => setServers(res.servers)); @@ -96,6 +97,17 @@ export default function ServersAdmin() { )} + {uninstallFor && ( +
+

Uninstall agent from {uninstallFor.name}

+

Run this on the server to stop and remove the agent (its entry here is kept):

+
{`curl -fsSL ${window.location.origin}/agent/linux/uninstall.sh | bash`}
+ +
+ )} +

Servers

@@ -119,6 +131,9 @@ export default function ServersAdmin() { + diff --git a/web/src/styles.css b/web/src/styles.css index ba50cf6..b64d4d3 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -375,6 +375,11 @@ tr.stale { margin-bottom: 1.5rem; } +.uninstall-reveal { + background: var(--surface); + border: 1px solid var(--border); +} + .token-value { display: block; background: var(--surface);