Add a standalone worker installer and dynamic userservice port
This commit is contained in:
@@ -30,16 +30,19 @@ func main() {
|
||||
switch args[0] {
|
||||
case "setup":
|
||||
if err := runSetup(args[1:]); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "setup:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
case "serve":
|
||||
if err := runServe(args[1:]); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "serve:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
case "agent":
|
||||
if err := runAgent(args[1:]); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "agent:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
|
||||
@@ -77,10 +77,10 @@ func Serve(ctx context.Context, cfg Config) (string, func() error, error) {
|
||||
handler := usershttp.NewServer(cfg.Log, uc, issuer)
|
||||
handler = http.TimeoutHandler(handler, 15*time.Second, `{"error":"request timeout"}`)
|
||||
|
||||
// A fixed loopback port lets the coordinator's proxy reuse its config
|
||||
// unchanged; collisions are unlikely (no other process binds 18081 on a
|
||||
// fresh machine) and fail loudly.
|
||||
listener, err := (&net.ListenConfig{}).Listen(ctx, "tcp", "127.0.0.1:18081")
|
||||
// Bind an ephemeral loopback port so a second serve instance can never
|
||||
// collide with the first; the coordinator's proxy uses the returned
|
||||
// address and needs no fixed-port assumption.
|
||||
listener, err := (&net.ListenConfig{}).Listen(ctx, "tcp", "127.0.0.1:0")
|
||||
if err != nil {
|
||||
_ = db.Close()
|
||||
return "", nil, fmt.Errorf("listen for embedded userservice: %w", err)
|
||||
|
||||
+29
-7
@@ -9,6 +9,7 @@
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$Repo = "emil28092005/SciMesh"
|
||||
$Component = if ($env:SCIMESH_COMPONENT) { $env:SCIMESH_COMPONENT } else { "coordinator" }
|
||||
$Version = if ($env:SCIMESH_VERSION) { $env:SCIMESH_VERSION } else { "latest" }
|
||||
$InstallDir = if ($env:SCIMESH_INSTALL_DIR) {
|
||||
$env:SCIMESH_INSTALL_DIR
|
||||
@@ -16,6 +17,12 @@ $InstallDir = if ($env:SCIMESH_INSTALL_DIR) {
|
||||
Join-Path $env:LOCALAPPDATA "SciMesh"
|
||||
}
|
||||
|
||||
switch ($Component) {
|
||||
"coordinator" { $Binary = "coordinator" }
|
||||
"worker" { $Binary = "worker-agent" }
|
||||
default { throw "unknown component: $Component (use 'coordinator' or 'worker')" }
|
||||
}
|
||||
|
||||
$Arch = switch ($env:PROCESSOR_ARCHITECTURE) {
|
||||
"AMD64" { "amd64" }
|
||||
"ARM64" { "arm64" }
|
||||
@@ -39,20 +46,35 @@ if ($Version -eq "latest") {
|
||||
}
|
||||
}
|
||||
|
||||
$Url = "https://github.com/$Repo/releases/download/$Version/coordinator-windows-$Arch.exe"
|
||||
$Url = "https://github.com/$Repo/releases/download/$Version/$Binary-windows-$Arch.exe"
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
|
||||
$Target = Join-Path $InstallDir "coordinator.exe"
|
||||
$Target = Join-Path $InstallDir "$Binary.exe"
|
||||
|
||||
Write-Host "Downloading $Url"
|
||||
Invoke-WebRequest -Uri $Url -OutFile "$Target.tmp"
|
||||
Move-Item -Force "$Target.tmp" $Target
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "SciMesh installed: $Target"
|
||||
Write-Host "SciMesh $Component installed: $Target"
|
||||
& $Target --version
|
||||
Write-Host ""
|
||||
Write-Host "Start the platform (one command, everything embedded):"
|
||||
Write-Host " $Target serve --open"
|
||||
Write-Host ""
|
||||
Write-Host "Your data lives in ~\.scimesh. The admin login is printed on first start."
|
||||
if ($Component -eq "coordinator") {
|
||||
Write-Host "Start the platform (one command, everything embedded):"
|
||||
Write-Host " $Target serve --open"
|
||||
Write-Host ""
|
||||
Write-Host "Your data lives in ~\.scimesh. The admin login is printed on first start."
|
||||
} else {
|
||||
Write-Host "The worker needs Python 3 with the scimesh package, then a coordinator"
|
||||
Write-Host "to connect to. Run it with environment variables:"
|
||||
Write-Host ""
|
||||
Write-Host " set COORDINATOR_URL=http://COORDINATOR_HOST:8080"
|
||||
Write-Host " set WORKER_AUTH_TOKEN=<worker token from the coordinator>"
|
||||
Write-Host " set WORK_DIR=%USERPROFILE%\scimesh-worker"
|
||||
Write-Host " $Target"
|
||||
Write-Host ""
|
||||
Write-Host "For a coordinator started with 'coordinator serve', the worker token is"
|
||||
Write-Host "in ~\.scimesh\worker.token on that machine. Set SCIMESH_PIP_PACKAGE to"
|
||||
Write-Host "install scimesh into a managed venv, or install it yourself:"
|
||||
Write-Host " pip install scimesh"
|
||||
}
|
||||
|
||||
+40
-14
@@ -1,19 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
# SciMesh installer: downloads the coordinator binary for this OS/architecture
|
||||
# from the latest GitHub release and installs it locally. One command, no
|
||||
# picking from a list of files:
|
||||
# SciMesh installer: downloads a binary for this OS/architecture from the
|
||||
# newest GitHub release and installs it locally. One command, no picking from
|
||||
# a list of files:
|
||||
#
|
||||
# curl -fsSL https://raw.githubusercontent.com/emil28092005/SciMesh/main/install.sh | bash
|
||||
# curl -fsSL https://raw.githubusercontent.com/emil28092005/SciMesh/main/install.sh | bash -s worker
|
||||
#
|
||||
# Installed to ~/.local/bin/coordinator (Linux/macOS). Then run:
|
||||
#
|
||||
# coordinator serve --open
|
||||
# The first form installs the coordinator (the whole platform in one binary:
|
||||
# databases, userservice, local workers). The second installs a standalone
|
||||
# worker agent that joins an existing coordinator. Installed to ~/.local/bin
|
||||
# (Linux/macOS) or %LOCALAPPDATA%\SciMesh (Windows).
|
||||
set -eu
|
||||
|
||||
REPO="emil28092005/SciMesh"
|
||||
COMPONENT="${1:-coordinator}"
|
||||
VERSION="${SCIMESH_VERSION:-latest}"
|
||||
INSTALL_DIR="${SCIMESH_INSTALL_DIR:-$HOME/.local/bin}"
|
||||
|
||||
case "$COMPONENT" in
|
||||
coordinator) BINARY="coordinator" ;;
|
||||
worker) BINARY="worker-agent" ;;
|
||||
*) echo "unknown component: $COMPONENT (use 'coordinator' or 'worker')" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
case "$(uname -s)" in
|
||||
Linux) OS="linux" ;;
|
||||
Darwin) OS="darwin" ;;
|
||||
@@ -41,16 +50,16 @@ if [ "$VERSION" = "latest" ]; then
|
||||
fi
|
||||
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
TARGET="$INSTALL_DIR/coordinator"
|
||||
TARGET="$INSTALL_DIR/$BINARY"
|
||||
|
||||
URL="https://github.com/${REPO}/releases/download/${VERSION}/coordinator-${OS}-${ARCH}"
|
||||
URL="https://github.com/${REPO}/releases/download/${VERSION}/${BINARY}-${OS}-${ARCH}"
|
||||
echo "Downloading $URL"
|
||||
curl -fsSL -o "$TARGET.tmp" "$URL"
|
||||
chmod +x "$TARGET.tmp"
|
||||
mv "$TARGET.tmp" "$TARGET"
|
||||
|
||||
echo
|
||||
echo "SciMesh installed: $TARGET"
|
||||
echo "SciMesh $COMPONENT installed: $TARGET"
|
||||
INSTALLED_VERSION=$("$TARGET" --version 2>/dev/null | awk '{print $2}')
|
||||
"$TARGET" --version
|
||||
if [ -n "$INSTALLED_VERSION" ] && [ "$INSTALLED_VERSION" != "${VERSION#v}" ]; then
|
||||
@@ -60,8 +69,25 @@ if [ -n "$INSTALLED_VERSION" ] && [ "$INSTALLED_VERSION" != "${VERSION#v}" ]; th
|
||||
echo "minutes, or pin the version explicitly:"
|
||||
echo " SCIMESH_VERSION=${VERSION} bash <(curl -fsSL https://raw.githubusercontent.com/${REPO}/main/install.sh)"
|
||||
fi
|
||||
echo
|
||||
echo "Start the platform (one command, everything embedded):"
|
||||
echo " $TARGET serve --open"
|
||||
echo
|
||||
echo "Your data lives in ~/.scimesh. The admin login is printed on first start."
|
||||
|
||||
if [ "$COMPONENT" = "coordinator" ]; then
|
||||
echo
|
||||
echo "Start the platform (one command, everything embedded):"
|
||||
echo " $TARGET serve --open"
|
||||
echo
|
||||
echo "Your data lives in ~/.scimesh. The admin login is printed on first start."
|
||||
else
|
||||
echo
|
||||
echo "The worker needs Python 3 with the scimesh package, then a coordinator"
|
||||
echo "to connect to. Run it with environment variables:"
|
||||
echo
|
||||
echo " export COORDINATOR_URL=http://COORDINATOR_HOST:8080"
|
||||
echo " export WORKER_AUTH_TOKEN=<worker token from the coordinator>"
|
||||
echo " export WORK_DIR=~/scimesh-worker"
|
||||
echo " $TARGET"
|
||||
echo
|
||||
echo "For a coordinator started with 'coordinator serve', the worker token is"
|
||||
echo "in ~/.scimesh/worker.token on that machine. Set SCIMESH_PIP_PACKAGE to"
|
||||
echo "install scimesh into a managed venv, or install it yourself:"
|
||||
echo " pip install scimesh"
|
||||
fi
|
||||
|
||||
+15
-5
@@ -90,11 +90,21 @@ curl -L -o coordinator https://github.com/emil28092005/SciMesh/releases/latest/d
|
||||
chmod +x coordinator
|
||||
```
|
||||
|
||||
- **worker-agent** runs anywhere with Python: it spawns
|
||||
`python -m scimesh.worker.task`, so the machine needs the `scimesh`
|
||||
package in a venv (`pip install scimesh`) and the usual environment:
|
||||
`COORDINATOR_URL`, `WORKER_AUTH_TOKEN`, `WORK_DIR`. The same binary can run
|
||||
it via `coordinator agent`.
|
||||
- **worker-agent** is installed separately and joins an existing coordinator:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://raw.githubusercontent.com/emil28092005/SciMesh/main/install.sh | bash -s worker
|
||||
export COORDINATOR_URL=http://COORDINATOR_HOST:8080
|
||||
export WORKER_AUTH_TOKEN=<worker token from the coordinator>
|
||||
export WORK_DIR=~/scimesh-worker
|
||||
worker-agent
|
||||
```
|
||||
|
||||
It spawns `python -m scimesh.worker.task`, so the machine needs Python 3
|
||||
with the `scimesh` package (`pip install scimesh`, or let the managed venv
|
||||
do it via `SCIMESH_PIP_PACKAGE`). For a `coordinator serve` instance, the
|
||||
worker token is in `~/.scimesh/worker.token`. On Windows set
|
||||
`SCIMESH_COMPONENT=worker` for `install.ps1`.
|
||||
- **coordinator** needs no external services at all in its default mode:
|
||||
`coordinator serve` embeds SQLite (both databases), the userservice, and
|
||||
local workers. The `SCIMESH_DB=postgres` engine remains for cluster
|
||||
|
||||
Reference in New Issue
Block a user