Add installer
CI / Build & Test (push) Successful in 2m53s

This commit is contained in:
Raven Scott
2026-03-16 13:20:27 -04:00
parent 97d4ea359f
commit e0a9f1e942
4 changed files with 362 additions and 2 deletions
+21 -2
View File
@@ -10,6 +10,24 @@ Requires the **anisail-tunnel** binary (Bare-built, shipped in `releases/` or bu
## Installation
### 0. Install the tunnel binary (from release)
To install **anisail-tunnel** from the [latest release](https://git.ssh.surf/snxraven/anisail/releases/tag/latest-main) without building:
**macOS / Linux:**
```bash
curl -fsSL https://git.ssh.surf/snxraven/anisail/raw/branch/main/scripts/install.sh | bash
```
**Windows (PowerShell):**
```powershell
irm https://git.ssh.surf/snxraven/anisail/raw/branch/main/scripts/install.ps1 | iex
```
The script downloads the right binary for your platform, extracts it to `~/.anisail/bin` (or `%LOCALAPPDATA%\anisail\bin` on Windows), and optionally links it into `~/.local/bin` on Unix. See [docs/INSTALLATION.md](docs/INSTALLATION.md) for details, custom install paths, and build-from-source.
### 1. Install the collection
From the repo root (or after building the collection artifact):
@@ -25,9 +43,9 @@ export ANSIBLE_COLLECTIONS_PATHS="$PWD/ansible_collections"
# or symlink/copy ansible_collections/anisail into your collections path
```
### 2. Install the tunnel binary
### 2. Tunnel binary (if not using the install script)
Either use a prebuilt binary or build it yourself (requires [Node.js](https://nodejs.org/) and `npm`).
If you did not run the install script above, either use a prebuilt binary from the [releases](https://git.ssh.surf/snxraven/anisail/releases) (download the zip for your platform and extract `anisail-tunnel`) or build from source (requires [Node.js](https://nodejs.org/) and `npm`).
**Option A — Build from source (Bare binary)**
@@ -157,6 +175,7 @@ MIT
## References
- [Installation guide](docs/INSTALLATION.md) — install scripts, custom paths, uninstall
- [Holesail](https://github.com/holesail/holesail) — P2P tunnel (npm, CLI, API)
- [Ansible connection plugins](https://docs.ansible.com/ansible/devel/plugins/connection.html)
- [Developing network plugins](https://docs.ansible.com/projects/ansible/latest/network/dev_guide/developing_plugins_network.html#network-connection-plugins)
+139
View File
@@ -0,0 +1,139 @@
# Installation
This guide covers installing the **anisail-tunnel** binary (used by the Ansible connection plugin) and the Ansible collection. The tunnel can be installed via install scripts from the latest release, built from source, or copied from the collection.
---
## Quick install (tunnel binary from release)
Use the install script to download the tunnel binary for your platform from the [latest release](https://git.ssh.surf/snxraven/anisail/releases/tag/latest-main).
### macOS / Linux
```bash
curl -fsSL https://git.ssh.surf/snxraven/anisail/raw/branch/main/scripts/install.sh | bash
```
This installs `anisail-tunnel` to `~/.anisail/bin/` and optionally links it into `~/.local/bin` if that directory exists. Add to PATH if needed:
```bash
export PATH="$HOME/.anisail/bin:$PATH"
# or
export PATH="$HOME/.local/bin:$PATH"
```
### Windows (PowerShell)
```powershell
irm https://git.ssh.surf/snxraven/anisail/raw/branch/main/scripts/install.ps1 | iex
```
The binary is installed to `%LOCALAPPDATA%\anisail\bin\anisail-tunnel.exe`. You can add that directory to your user PATH, or set `ansible_holesail_tunnel_path` in inventory to the full path.
### Custom release base
To use a different server or tag (e.g. your own Gitea or a specific release):
**macOS / Linux:**
```bash
RELEASE_BASE=https://your-server.com/owner/anisail/releases/download/your-tag curl -fsSL https://git.ssh.surf/snxraven/anisail/raw/branch/main/scripts/install.sh | bash
```
**Windows:**
```powershell
$env:RELEASE_BASE = "https://your-server.com/owner/anisail/releases/download/your-tag"
irm https://git.ssh.surf/snxraven/anisail/raw/branch/main/scripts/install.ps1 | iex
```
**Custom install directory:**
- macOS/Linux: `ANISAIL_INSTALL_DIR=/opt/anisail/bin curl -fsSL ... | bash`
- Windows: `$env:ANISAIL_INSTALL_DIR = "C:\Tools\anisail"; irm ... | iex`
---
## What the install script does
### macOS / Linux (`install.sh`)
1. Detects OS and architecture (`darwin`/`linux`, `x64`/`arm64`).
2. Stops any running `anisail-tunnel` process.
3. Creates `~/.anisail/bin` (or `ANISAIL_INSTALL_DIR`).
4. Downloads `anisail-tunnel-<platform>-<arch>.zip` from the release.
5. Extracts the binary (handles zip layout with or without a subdir).
6. Sets the binary to `~/.anisail/bin/anisail-tunnel` and makes it executable.
7. If `~/.local/bin` exists, creates a symlink there so the binary is on PATH for many setups.
**Requirements:** `curl`, `unzip`.
### Windows (`install.ps1`)
1. Downloads `anisail-tunnel-win32-x64.zip` from the release.
2. Extracts to `%LOCALAPPDATA%\anisail\bin` (or `ANISAIL_INSTALL_DIR`).
3. Ensures `anisail-tunnel.exe` is at the install dir root.
4. Suggests adding the install dir to the user PATH.
**Requirements:** PowerShell, internet access. No extra tools (uses `Invoke-WebRequest` and `Expand-Archive`).
---
## Install the Ansible collection and paramiko
The connection plugin runs on your Ansible control node and needs the collection plus Python paramiko.
### Collection
From the repo (development):
```bash
ansible-galaxy collection install ansible_collections/anisail/anisail/ --force
```
Or set the collection path and use the repo as-is:
```bash
export ANSIBLE_COLLECTIONS_PATHS="/path/to/anisail/ansible_collections"
```
### Paramiko (required)
```bash
pip install paramiko
```
---
## Using the tunnel binary
- **PATH:** If `anisail-tunnel` is on your PATH, the plugin will use it automatically.
- **Explicit path:** Set in inventory: `ansible_holesail_tunnel_path: "/path/to/anisail-tunnel"` (or the full path to the script-installed binary).
- **Collection-relative:** If you copy the built binary (or the contents of a release zip) into the collection under `ansible_collections/anisail/anisail/releases/<platform>/`, the plugin will find it without PATH or `ansible_holesail_tunnel_path`.
---
## Build from source (tunnel binary)
If you prefer to build the tunnel yourself instead of using the install script:
```bash
git clone https://git.ssh.surf/snxraven/anisail.git
cd anisail
npm install
npm run build:tunnel # current platform
# or
npm run build:tunnel:all # all platforms (requires bare-build)
```
Output is under `releases/` (e.g. `releases/darwin-arm64/anisail-tunnel`). Copy the binary to a directory on PATH or set `ansible_holesail_tunnel_path`. See [README](../README.md#building-the-tunnel-binary) for details.
---
## Uninstalling
- **Tunnel (script install):** Remove the install directory and, if you created it, the symlink in `~/.local/bin`:
- macOS/Linux: `rm -rf ~/.anisail` and `rm -f ~/.local/bin/anisail-tunnel`
- Windows: remove `%LOCALAPPDATA%\anisail` and remove that path from user PATH if you added it.
- **Collection:** `ansible-galaxy collection remove anisail.anisail`
- **Paramiko:** `pip uninstall paramiko` (only if not needed for other playbooks)
+87
View File
@@ -0,0 +1,87 @@
# Anisail tunnel installer (Windows)
# Downloads the anisail-tunnel binary from the latest release.
#
# Usage (run in PowerShell as your normal user):
# irm https://git.ssh.surf/snxraven/anisail/raw/branch/main/scripts/install.ps1 | iex
#
# Or with a custom release base:
# $env:RELEASE_BASE = "https://example.com/releases/download/latest-main"; irm ... | iex
$ErrorActionPreference = "Stop"
$ReleaseBase = if ($env:RELEASE_BASE) { $env:RELEASE_BASE } else { "https://git.ssh.surf/snxraven/anisail/releases/download/latest-main" }
$InstallDir = if ($env:ANISAIL_INSTALL_DIR) { $env:ANISAIL_INSTALL_DIR } else { "$env:LOCALAPPDATA\anisail\bin" }
$ZipName = "anisail-tunnel-win32-x64.zip"
$BinName = "anisail-tunnel.exe"
Write-Host ""
Write-Host "Anisail tunnel installer" -ForegroundColor Cyan
Write-Host "========================" -ForegroundColor Cyan
Write-Host "Install : $InstallDir"
Write-Host ""
# ── Stop any running tunnel ────────────────────────────────────────────────────
Write-Host "Stopping any running anisail-tunnel..."
Get-Process | Where-Object { $_.ProcessName -like "*anisail*" } | Stop-Process -Force -ErrorAction SilentlyContinue
# ── Remove previous binary ───────────────────────────────────────────────────────
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
Remove-Item -Path (Join-Path $InstallDir "anisail-tunnel*") -Force -ErrorAction SilentlyContinue
# ── Download ───────────────────────────────────────────────────────────────────
Write-Host "Downloading $ZipName..."
$TmpZip = Join-Path $env:TEMP $ZipName
try {
Invoke-WebRequest "$ReleaseBase/$ZipName" -OutFile $TmpZip -UseBasicParsing
} catch {
Write-Host "Error: failed to download $ZipName" -ForegroundColor Red
Write-Host "Check that the release exists: $ReleaseBase/$ZipName" -ForegroundColor Red
exit 1
}
Expand-Archive -Path $TmpZip -DestinationPath $InstallDir -Force
Remove-Item $TmpZip -Force -ErrorAction SilentlyContinue
# Find the binary (zip may contain a subdir)
$Bin = Get-ChildItem -Path $InstallDir -Recurse -Filter $BinName -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
if (-not $Bin) {
Write-Host "Error: binary not found in $ZipName" -ForegroundColor Red
exit 1
}
# Normalize: move to InstallDir root and remove empty subdirs
$DestBin = Join-Path $InstallDir $BinName
if ($Bin -ne $DestBin) {
Move-Item $Bin $DestBin -Force
Get-ChildItem -Path $InstallDir -Directory | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}
$Bin = $DestBin
Write-Host " Installed: $Bin"
# ── Optional: add to user PATH ──────────────────────────────────────────────────
$BinDir = [System.IO.Path]::GetDirectoryName($Bin)
$UserPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($UserPath -and $UserPath -notlike "*$BinDir*") {
Write-Host ""
Write-Host "To add anisail-tunnel to your PATH, run:" -ForegroundColor Yellow
Write-Host " [Environment]::SetEnvironmentVariable('Path', \"`$env:Path;$BinDir\", 'User')" -ForegroundColor Yellow
Write-Host " Then restart your terminal." -ForegroundColor Yellow
}
# ── Done ───────────────────────────────────────────────────────────────────────
Write-Host ""
Write-Host "========================" -ForegroundColor Green
Write-Host "Installation complete!" -ForegroundColor Green
Write-Host ""
Write-Host "Binary: $Bin"
Write-Host ""
Write-Host "Next steps:"
Write-Host " 1. Install the Ansible collection and paramiko:"
Write-Host " ansible-galaxy collection install ansible_collections/anisail/anisail/ --force"
Write-Host " pip install paramiko"
Write-Host " 2. In inventory set: ansible_connection: anisail.anisail.holesail"
Write-Host " and ansible_holesail_key: ""hs://..."" (from target: holesail --live 22)"
Write-Host ""
Write-Host "Optional: set ansible_holesail_tunnel_path to use this binary explicitly:"
Write-Host " ansible_holesail_tunnel_path: ""$Bin"""
Write-Host ""
+115
View File
@@ -0,0 +1,115 @@
#!/usr/bin/env bash
# Anisail tunnel installer (macOS / Linux)
# Downloads the anisail-tunnel binary from the latest release.
#
# Usage:
# curl -fsSL https://git.ssh.surf/snxraven/anisail/raw/branch/main/scripts/install.sh | bash
#
# Or with a custom release base (e.g. your own Gitea):
# RELEASE_BASE=https://example.com/releases/download/latest-main curl -fsSL ... | bash
set -euo pipefail
RELEASE_BASE="${RELEASE_BASE:-https://git.ssh.surf/snxraven/anisail/releases/download/latest-main}"
INSTALL_DIR="${ANISAIL_INSTALL_DIR:-$HOME/.anisail/bin}"
BIN_NAME="anisail-tunnel"
# ── Detect platform ────────────────────────────────────────────────────────────
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
ARCH="$(uname -m)"
[[ "$ARCH" == "x86_64" ]] && ARCH="x64"
[[ "$ARCH" == "aarch64" || "$ARCH" == "arm64" ]] && ARCH="arm64"
[[ "$OS" == "darwin" ]] && PLATFORM="darwin"
[[ "$OS" == "linux" ]] && PLATFORM="linux"
if [[ -z "${PLATFORM:-}" ]]; then
echo "Unsupported OS: $OS" >&2
exit 1
fi
ZIP_NAME="${BIN_NAME}-${PLATFORM}-${ARCH}.zip"
echo ""
echo "Anisail tunnel installer"
echo "========================"
echo "Platform : ${PLATFORM}-${ARCH}"
echo "Install : ${INSTALL_DIR}"
echo ""
# ── Stop any running tunnel (optional; Ansible usually manages one-shot) ────────
echo "Stopping any running anisail-tunnel..."
pkill -f "anisail-tunnel" 2>/dev/null || true
# ── Remove previous binary (no state to preserve) ───────────────────────────────
mkdir -p "$INSTALL_DIR"
rm -f "${INSTALL_DIR}/${BIN_NAME}" "${INSTALL_DIR}/${BIN_NAME}.exe"
# ── Download ───────────────────────────────────────────────────────────────────
echo "Downloading ${ZIP_NAME}..."
TMP_ZIP="$(mktemp)"
if ! curl -fsSL "${RELEASE_BASE}/${ZIP_NAME}" -o "$TMP_ZIP"; then
echo "Error: failed to download ${ZIP_NAME}" >&2
echo "Check that the release exists: ${RELEASE_BASE}/${ZIP_NAME}" >&2
rm -f "$TMP_ZIP"
exit 1
fi
# Unzip
if ! command -v unzip >/dev/null 2>&1; then
echo "Error: 'unzip' is required to extract the release. Install it (e.g. apt install unzip, yum install unzip, brew install unzip)." >&2
rm -f "$TMP_ZIP"
exit 1
fi
unzip -q -o "$TMP_ZIP" -d "$INSTALL_DIR"
rm -f "$TMP_ZIP"
# Find the binary (zip may contain a subdir like aarch64/anisail-tunnel)
BIN=""
if [[ -f "${INSTALL_DIR}/${BIN_NAME}" ]]; then
BIN="${INSTALL_DIR}/${BIN_NAME}"
elif [[ -f "${INSTALL_DIR}/${BIN_NAME}.exe" ]]; then
BIN="${INSTALL_DIR}/${BIN_NAME}.exe"
else
BIN="$(find "$INSTALL_DIR" -type f \( -name "${BIN_NAME}" -o -name "${BIN_NAME}.exe" \) 2>/dev/null | head -1)"
fi
if [[ -z "$BIN" ]]; then
echo "Error: binary not found in ${ZIP_NAME}" >&2
exit 1
fi
# Normalize: ensure binary lives at INSTALL_DIR/anisail-tunnel[.exe]
if [[ "$(dirname "$BIN")" != "$INSTALL_DIR" ]]; then
mv "$BIN" "${INSTALL_DIR}/$(basename "$BIN")"
BIN="${INSTALL_DIR}/$(basename "$BIN")"
find "$INSTALL_DIR" -mindepth 1 -maxdepth 1 -type d -exec rm -rf {} + 2>/dev/null || true
fi
chmod +x "$BIN"
echo " Installed: $BIN"
# ── Optional: symlink into ~/.local/bin if it exists ────────────────────────────
LOCAL_BIN="$HOME/.local/bin"
if [[ -d "$LOCAL_BIN" ]] && [[ "$INSTALL_DIR" != "$LOCAL_BIN" ]]; then
ln -sf "$BIN" "${LOCAL_BIN}/${BIN_NAME}"
echo " Linked: ${LOCAL_BIN}/${BIN_NAME}"
fi
# ── Done ───────────────────────────────────────────────────────────────────────
echo ""
echo "========================"
echo "Installation complete!"
echo ""
echo "Binary: $BIN"
echo ""
echo "Next steps:"
echo " 1. Add to PATH if needed: export PATH=\"${INSTALL_DIR}:\$PATH\""
echo " (or add the above to your shell profile)"
echo " 2. Install the Ansible collection and paramiko:"
echo " ansible-galaxy collection install ansible_collections/anisail/anisail/ --force"
echo " pip install paramiko"
echo " 3. In inventory set: ansible_connection: anisail.anisail.holesail"
echo " and ansible_holesail_key: \"hs://...\" (from target: holesail --live 22)"
echo ""
echo "Optional: set ansible_holesail_tunnel_path to use this binary explicitly:"
echo " ansible_holesail_tunnel_path: \"$BIN\""
echo ""