From 8ba1884b39b28e85f93cc3636aaa87360e5a8d8a Mon Sep 17 00:00:00 2001
From: Vikrant Chaudhary
Date: Sun, 2 Feb 2025 20:19:11 +0100
Subject: [PATCH] Have a install script for both relay and agents.
---
README.md | 6 +-
frontend/astro.config.ts | 1 +
frontend/package-lock.json | 110 ++++++++++++++++--
frontend/package.json | 2 +
frontend/src/pages/get.ts | 7 --
frontend/src/pages/index.astro | 25 ++--
frontend/src/pages/install-relay.sh.ts | 7 ++
frontend/src/pages/install.sh.ts | 7 ++
.../{get.sh => src/templates/install.sh.ejs} | 11 +-
9 files changed, 145 insertions(+), 31 deletions(-)
delete mode 100644 frontend/src/pages/get.ts
create mode 100644 frontend/src/pages/install-relay.sh.ts
create mode 100644 frontend/src/pages/install.sh.ts
rename frontend/{get.sh => src/templates/install.sh.ejs} (89%)
diff --git a/README.md b/README.md
index 335d58d..cab3f9e 100644
--- a/README.md
+++ b/README.md
@@ -37,13 +37,15 @@ Written in Rust, Webterm is built from the ground up for security, performance,
## Quickstart
-1. Install Webterm agent using Cargo:
+1. Install the Webterm agent:
```bash
- cargo install webterm-agent
+ # This command will install a single binary at /usr/bin/webterm-agent, no other files will be touched
+ curl -sSfL https://webterm.run/install.sh | bash
```
2. Start the Webterm agent:
```bash
+ # Pass --daemon to run the agent in the background
webterm-agent --device-name --secret-key
```
diff --git a/frontend/astro.config.ts b/frontend/astro.config.ts
index a8ed302..17f606d 100644
--- a/frontend/astro.config.ts
+++ b/frontend/astro.config.ts
@@ -6,6 +6,7 @@ import vitePluginSvgr from "vite-plugin-svgr";
// https://astro.build/config
export default defineConfig({
+ trailingSlash: "never",
vite: {
plugins: [webtermVersionPlugin(), vitePluginSvgr()],
build: {
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 3a1d107..4d638cd 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -20,6 +20,7 @@
"@xterm/xterm": "^5.5.0",
"astro": "^5.1.1",
"bootstrap": "^5.3.3",
+ "ejs": "^3.1.10",
"flatbuffers": "^25.1.24",
"lodash-es": "^4.17.21",
"nanostores": "^0.11.3",
@@ -29,6 +30,7 @@
},
"devDependencies": {
"@types/bootstrap": "^5.2.10",
+ "@types/ejs": "^3.1.5",
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.13.0",
"eslint": "^9.17.0",
@@ -2545,6 +2547,12 @@
"@types/ms": "*"
}
},
+ "node_modules/@types/ejs": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.5.tgz",
+ "integrity": "sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==",
+ "dev": true
+ },
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
@@ -3525,6 +3533,11 @@
"@astrojs/compiler": ">=0.27.0"
}
},
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="
+ },
"node_modules/axobject-query": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@@ -3582,8 +3595,7 @@
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/base-64": {
"version": "1.0.0",
@@ -3644,7 +3656,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -3994,8 +4005,7 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"node_modules/consola": {
"version": "3.4.0",
@@ -4219,6 +4229,20 @@
"node": ">=4"
}
},
+ "node_modules/ejs": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+ "dependencies": {
+ "jake": "^10.8.5"
+ },
+ "bin": {
+ "ejs": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/electron-to-chromium": {
"version": "1.5.88",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.88.tgz",
@@ -4695,6 +4719,33 @@
"node": ">=16.0.0"
}
},
+ "node_modules/filelist": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+ "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+ "dependencies": {
+ "minimatch": "^5.0.1"
+ }
+ },
+ "node_modules/filelist/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/filelist/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -4898,7 +4949,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -5292,6 +5342,52 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
+ "node_modules/jake": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
+ "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
+ "dependencies": {
+ "async": "^3.2.3",
+ "chalk": "^4.0.2",
+ "filelist": "^1.0.4",
+ "minimatch": "^3.1.2"
+ },
+ "bin": {
+ "jake": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/jake/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jake/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -6321,7 +6417,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -7605,7 +7700,6 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
diff --git a/frontend/package.json b/frontend/package.json
index 98cf547..bb1a45f 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -25,6 +25,7 @@
"@xterm/xterm": "^5.5.0",
"astro": "^5.1.1",
"bootstrap": "^5.3.3",
+ "ejs": "^3.1.10",
"flatbuffers": "^25.1.24",
"lodash-es": "^4.17.21",
"nanostores": "^0.11.3",
@@ -34,6 +35,7 @@
},
"devDependencies": {
"@types/bootstrap": "^5.2.10",
+ "@types/ejs": "^3.1.5",
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.13.0",
"eslint": "^9.17.0",
diff --git a/frontend/src/pages/get.ts b/frontend/src/pages/get.ts
deleted file mode 100644
index b331522..0000000
--- a/frontend/src/pages/get.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import type { APIRoute } from "astro";
-import { readFileSync } from "fs";
-
-export const GET: APIRoute = (_context): Response => {
- const script = readFileSync("./get.sh");
- return new Response(script);
-};
diff --git a/frontend/src/pages/index.astro b/frontend/src/pages/index.astro
index ee338d6..0ca75a8 100644
--- a/frontend/src/pages/index.astro
+++ b/frontend/src/pages/index.astro
@@ -41,14 +41,23 @@ import { CONFIG } from "../scripts/client/config";
Install the free and open-source agent, built with Rust for high efficiency and extremely light resource
usage.
-
-
- # Install the agent
- cargo install webterm-agent
-
- # Run the agent
- webterm-agent --device-name <DEVICE_NAME> --secret-key <SECRET_KEY>
-
+
+
+ -
+
Install the agent
+
+ curl -sSfL https://webterm.run/install.sh | bash
+
+
+
+ -
+
Run the agent (add --daemon
to run in background)
+
+
+ webterm-agent --device-name <DEVICE_NAME> --secret-key <SECRET_KEY>
+
+
+
=> {
+ const script = await ejs.renderFile("./src/templates/install.sh.ejs", { binary_name: "webterm-relay" });
+ return new Response(script);
+};
diff --git a/frontend/src/pages/install.sh.ts b/frontend/src/pages/install.sh.ts
new file mode 100644
index 0000000..ddf08ef
--- /dev/null
+++ b/frontend/src/pages/install.sh.ts
@@ -0,0 +1,7 @@
+import type { APIRoute } from "astro";
+import ejs from "ejs";
+
+export const GET: APIRoute = async (_context): Promise => {
+ const script = await ejs.renderFile("./src/templates/install.sh.ejs", { binary_name: "webterm-agent" });
+ return new Response(script);
+};
diff --git a/frontend/get.sh b/frontend/src/templates/install.sh.ejs
similarity index 89%
rename from frontend/get.sh
rename to frontend/src/templates/install.sh.ejs
index acaba75..be0098d 100644
--- a/frontend/get.sh
+++ b/frontend/src/templates/install.sh.ejs
@@ -1,13 +1,13 @@
#!/usr/bin/env bash
#
# Usage:
-# curl -sSfL https://webterm.run/get | bash
+# curl -sSfL https://webterm.run/install.sh | bash
set -euo pipefail
LATEST_VERSION_URL="https://webterm.run/latest.txt"
REPO_BASE_URL="https://github.com/nasa42/webterm/releases/download"
-BINARY_NAME="webterm-agent"
+BINARY_NAME="<%= binary_name %>"
# By default, install to /usr/bin unless the user provides INSTALL_DIR
DEFAULT_INSTALL_DIR="/usr/bin"
@@ -27,7 +27,6 @@ echo "Latest version: ${LATEST_VERSION}"
# Check if ${BINARY_NAME} is already installed and get installed version
INSTALLED_VERSION=""
if [ -x "${INSTALL_DIR}/${BINARY_NAME}" ]; then
- # Example output: "webterm-agent 0.2.0"
INSTALLED_VERSION="$("${INSTALL_DIR}/${BINARY_NAME}" --version 2>/dev/null | awk '{print $2}')"
echo "Installed version: ${INSTALLED_VERSION}"
fi
@@ -42,10 +41,10 @@ fi
ARCH="$(uname -m)"
case "${ARCH}" in
x86_64)
- ARCHIVE="webterm-agent-x86_64-unknown-linux-gnu.tar.gz"
+ ARCHIVE="${BINARY_NAME}-x86_64-unknown-linux-gnu.tar.gz"
;;
aarch64|arm64)
- ARCHIVE="webterm-agent-aarch64-unknown-linux-gnu.tar.gz"
+ ARCHIVE="${BINARY_NAME}-aarch64-unknown-linux-gnu.tar.gz"
;;
*)
echo "Unsupported architecture: ${ARCH}"
@@ -54,7 +53,7 @@ case "${ARCH}" in
;;
esac
-DOWNLOAD_URL="${REPO_BASE_URL}/webterm-agent-v${LATEST_VERSION}/${ARCHIVE}"
+DOWNLOAD_URL="${REPO_BASE_URL}/${BINARY_NAME}-v${LATEST_VERSION}/${ARCHIVE}"
echo "Downloading ${BINARY_NAME} ${LATEST_VERSION} for architecture ${ARCH}..."
curl -sSfL "${DOWNLOAD_URL}" -o "${ARCHIVE}"