Add agent install scripts and release automation

Introduced Linux (install.sh) and Windows (install.ps1) installation scripts for ServerKit agent, and exposed new backend endpoints to serve these scripts and installation instructions. Added a GitHub Actions workflow (agent-release.yml) for automated agent builds and releases. Updated ROADMAP.md and SERVERS_INTEGRATION_PLAN.md to reflect progress on installation and distribution features.
This commit is contained in:
Juan Denis committed 2026-01-21 22:57:40 -05:00
1 parent 009fb12435
commit 528c86d640
6 files changed
+1115 -94

No files matched your search

+323
View File
@@ -0,0 +1,323 @@
#Requires -RunAsAdministrator
<#
.SYNOPSIS
ServerKit Agent Installation Script for Windows
.DESCRIPTION
Downloads and installs the ServerKit Agent on Windows systems.
.PARAMETER Token
Registration token from ServerKit (required)
.PARAMETER Server
ServerKit server URL (required)
.PARAMETER Name
Display name for this server (optional)
.PARAMETER Version
Specific agent version to install (optional, defaults to latest)
.EXAMPLE
.\install.ps1 -Token "sk_reg_xxx" -Server "https://your-serverkit.com"
.EXAMPLE
irm https://your-serverkit.com/install.ps1 | iex; Install-ServerKitAgent -Token "sk_reg_xxx" -Server "https://your-serverkit.com"
.NOTES
Requires Administrator privileges.
#>
param(
[Parameter(Mandatory=$false)]
[string]$Token,
[Parameter(Mandatory=$false)]
[string]$Server,
[Parameter(Mandatory=$false)]
[string]$Name,
[Parameter(Mandatory=$false)]
[string]$Version = "latest"
)
# Configuration
$InstallDir = "$env:ProgramFiles\ServerKit"
$ConfigDir = "$env:ProgramData\ServerKit"
$ServiceName = "ServerKitAgent"
$GitHubRepo = "serverkit/serverkit"
$AgentBinary = "serverkit-agent.exe"
# Colors
function Write-ColorOutput {
param(
[string]$Message,
[string]$Type = "Info"
)
switch ($Type) {
"Info" { Write-Host "[INFO] " -ForegroundColor Cyan -NoNewline; Write-Host $Message }
"Success" { Write-Host "[SUCCESS] " -ForegroundColor Green -NoNewline; Write-Host $Message }
"Warning" { Write-Host "[WARN] " -ForegroundColor Yellow -NoNewline; Write-Host $Message }
"Error" { Write-Host "[ERROR] " -ForegroundColor Red -NoNewline; Write-Host $Message }
}
}
function Write-Banner {
Write-Host ""
Write-Host "╔═══════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
Write-Host "║ ServerKit Agent Installer ║" -ForegroundColor Cyan
Write-Host "╚═══════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
Write-Host ""
}
function Test-Administrator {
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
return $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Get-LatestVersion {
if ($Version -eq "latest") {
Write-ColorOutput "Fetching latest version..." "Info"
try {
$releases = Invoke-RestMethod -Uri "https://api.github.com/repos/$GitHubRepo/releases" -Method Get
foreach ($release in $releases) {
if ($release.tag_name -match "^agent-v(.+)$") {
$script:Version = $Matches[1]
Write-ColorOutput "Latest version: v$Version" "Info"
return
}
}
throw "No agent release found"
}
catch {
Write-ColorOutput "Failed to fetch latest version: $_" "Error"
exit 1
}
}
}
function Install-Agent {
Write-ColorOutput "Downloading ServerKit Agent v$Version..." "Info"
# Create temp directory
$tempDir = Join-Path $env:TEMP "serverkit-install-$(Get-Random)"
New-Item -ItemType Directory -Path $tempDir -Force | Out-Null
$downloadUrl = "https://github.com/$GitHubRepo/releases/download/agent-v$Version/serverkit-agent-$Version-windows-amd64.zip"
$archivePath = Join-Path $tempDir "serverkit-agent.zip"
try {
# Download
Write-ColorOutput "Downloading from: $downloadUrl" "Info"
Invoke-WebRequest -Uri $downloadUrl -OutFile $archivePath -UseBasicParsing
# Extract
Write-ColorOutput "Extracting agent..." "Info"
Expand-Archive -Path $archivePath -DestinationPath $tempDir -Force
# Create install directory
if (-not (Test-Path $InstallDir)) {
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
}
# Copy binary
$binarySource = Join-Path $tempDir "serverkit-agent-windows-amd64.exe"
$binaryDest = Join-Path $InstallDir $AgentBinary
Copy-Item -Path $binarySource -Destination $binaryDest -Force
Write-ColorOutput "Agent installed to $binaryDest" "Success"
}
catch {
Write-ColorOutput "Failed to download/install agent: $_" "Error"
exit 1
}
finally {
# Cleanup
Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue
}
}
function New-ConfigDirectory {
Write-ColorOutput "Creating configuration directory..." "Info"
if (-not (Test-Path $ConfigDir)) {
New-Item -ItemType Directory -Path $ConfigDir -Force | Out-Null
}
}
function Register-Agent {
param(
[string]$Token,
[string]$Server,
[string]$Name
)
Write-ColorOutput "Registering agent with ServerKit..." "Info"
$agentPath = Join-Path $InstallDir $AgentBinary
$arguments = @("register", "--token", $Token, "--server", $Server)
if ($Name) {
$arguments += @("--name", $Name)
}
try {
$process = Start-Process -FilePath $agentPath -ArgumentList $arguments -Wait -PassThru -NoNewWindow
if ($process.ExitCode -ne 0) {
throw "Registration command failed with exit code: $($process.ExitCode)"
}
Write-ColorOutput "Agent registered successfully" "Success"
}
catch {
Write-ColorOutput "Agent registration failed: $_" "Error"
exit 1
}
}
function Install-WindowsService {
Write-ColorOutput "Installing Windows service..." "Info"
$agentPath = Join-Path $InstallDir $AgentBinary
# Check if service already exists
$existingService = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($existingService) {
Write-ColorOutput "Stopping existing service..." "Info"
Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2
Write-ColorOutput "Removing existing service..." "Info"
sc.exe delete $ServiceName | Out-Null
Start-Sleep -Seconds 2
}
# Create the service using sc.exe
$binPath = "`"$agentPath`" start"
$result = sc.exe create $ServiceName binPath= $binPath start= auto DisplayName= "ServerKit Agent"
if ($LASTEXITCODE -ne 0) {
Write-ColorOutput "Failed to create service: $result" "Error"
exit 1
}
# Set service description
sc.exe description $ServiceName "ServerKit Agent for remote server management" | Out-Null
# Set service recovery options (restart on failure)
sc.exe failure $ServiceName reset= 86400 actions= restart/60000/restart/60000/restart/60000 | Out-Null
Write-ColorOutput "Windows service installed" "Success"
}
function Start-AgentService {
Write-ColorOutput "Starting ServerKit Agent service..." "Info"
try {
Start-Service -Name $ServiceName
Start-Sleep -Seconds 3
$service = Get-Service -Name $ServiceName
if ($service.Status -eq "Running") {
Write-ColorOutput "Agent service is running" "Success"
}
else {
Write-ColorOutput "Service failed to start. Status: $($service.Status)" "Warning"
Write-ColorOutput "Check logs in Event Viewer > Windows Logs > Application" "Info"
}
}
catch {
Write-ColorOutput "Failed to start service: $_" "Error"
}
}
function Add-ToPath {
Write-ColorOutput "Adding to system PATH..." "Info"
$currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine")
if ($currentPath -notlike "*$InstallDir*") {
$newPath = "$currentPath;$InstallDir"
[Environment]::SetEnvironmentVariable("Path", $newPath, "Machine")
Write-ColorOutput "Added $InstallDir to system PATH" "Success"
}
else {
Write-ColorOutput "Already in PATH" "Info"
}
}
function Write-SuccessMessage {
Write-Host ""
Write-Host "╔═══════════════════════════════════════════════════════════╗" -ForegroundColor Green
Write-Host "║ Installation completed successfully! ║" -ForegroundColor Green
Write-Host "╚═══════════════════════════════════════════════════════════╝" -ForegroundColor Green
Write-Host ""
Write-Host "Agent Status:"
Write-Host " Binary: $InstallDir\$AgentBinary"
Write-Host " Config: $ConfigDir\config.yaml"
Write-Host " Service: $ServiceName"
Write-Host ""
Write-Host "Useful commands:"
Write-Host " Check status: Get-Service $ServiceName"
Write-Host " View logs: Get-EventLog -LogName Application -Source $ServiceName"
Write-Host " Restart agent: Restart-Service $ServiceName"
Write-Host " Stop agent: Stop-Service $ServiceName"
Write-Host ""
}
# Main function for piped execution
function Install-ServerKitAgent {
param(
[Parameter(Mandatory=$true)]
[string]$Token,
[Parameter(Mandatory=$true)]
[string]$Server,
[Parameter(Mandatory=$false)]
[string]$Name,
[Parameter(Mandatory=$false)]
[string]$Version = "latest"
)
# Update script-level variables
$script:Version = $Version
Write-Banner
if (-not (Test-Administrator)) {
Write-ColorOutput "This script must be run as Administrator" "Error"
Write-Host "Right-click PowerShell and select 'Run as Administrator'"
exit 1
}
Get-LatestVersion
Install-Agent
New-ConfigDirectory
Register-Agent -Token $Token -Server $Server -Name $Name
Install-WindowsService
Start-AgentService
Add-ToPath
Write-SuccessMessage
}
# Direct execution with parameters
if ($Token -and $Server) {
Install-ServerKitAgent -Token $Token -Server $Server -Name $Name -Version $Version
}
elseif ($PSBoundParameters.Count -gt 0) {
Write-ColorOutput "Both -Token and -Server parameters are required" "Error"
Write-Host ""
Write-Host "Usage:"
Write-Host " .\install.ps1 -Token 'sk_reg_xxx' -Server 'https://your-serverkit.com'"
exit 1
}
else {
# Script was sourced, export the function
Write-Host "ServerKit Agent installer loaded." -ForegroundColor Cyan
Write-Host "Usage: Install-ServerKitAgent -Token 'sk_reg_xxx' -Server 'https://your-serverkit.com'" -ForegroundColor Gray
}
+348
View File
@@ -0,0 +1,348 @@
#!/bin/bash
#
# ServerKit Agent Installation Script
#
# Usage:
# curl -fsSL https://your-serverkit.com/install.sh | sudo bash -s -- --token "TOKEN" --server "URL"
#
# Options:
# --token, -t Registration token (required)
# --server, -s ServerKit server URL (required)
# --name, -n Display name for this server (optional)
# --version, -v Specific agent version to install (optional, defaults to latest)
# --help, -h Show this help message
#
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
INSTALL_DIR="/usr/local/bin"
CONFIG_DIR="/etc/serverkit"
SERVICE_USER="serverkit"
GITHUB_REPO="serverkit/serverkit"
AGENT_BINARY="serverkit-agent"
# Arguments
TOKEN=""
SERVER_URL=""
SERVER_NAME=""
VERSION="latest"
print_banner() {
echo -e "${BLUE}"
echo "╔═══════════════════════════════════════════════════════════╗"
echo "║ ServerKit Agent Installer ║"
echo "╚═══════════════════════════════════════════════════════════╝"
echo -e "${NC}"
}
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
exit 1
}
show_help() {
echo "ServerKit Agent Installation Script"
echo ""
echo "Usage: install.sh [OPTIONS]"
echo ""
echo "Options:"
echo " --token, -t Registration token (required)"
echo " --server, -s ServerKit server URL (required)"
echo " --name, -n Display name for this server (optional)"
echo " --version, -v Specific agent version (optional, defaults to latest)"
echo " --help, -h Show this help message"
echo ""
echo "Example:"
echo " curl -fsSL https://your-serverkit.com/install.sh | sudo bash -s -- \\"
echo " --token 'sk_reg_xxx' \\"
echo " --server 'https://your-serverkit.com'"
exit 0
}
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
--token|-t)
TOKEN="$2"
shift 2
;;
--server|-s)
SERVER_URL="$2"
shift 2
;;
--name|-n)
SERVER_NAME="$2"
shift 2
;;
--version|-v)
VERSION="$2"
shift 2
;;
--help|-h)
show_help
;;
*)
log_error "Unknown option: $1"
;;
esac
done
# Validate required arguments
if [[ -z "$TOKEN" ]]; then
log_error "Registration token is required. Use --token or -t"
fi
if [[ -z "$SERVER_URL" ]]; then
log_error "Server URL is required. Use --server or -s"
fi
}
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "This script must be run as root (use sudo)"
fi
}
detect_platform() {
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
case "$ARCH" in
x86_64|amd64)
ARCH="amd64"
;;
aarch64|arm64)
ARCH="arm64"
;;
*)
log_error "Unsupported architecture: $ARCH"
;;
esac
if [[ "$OS" != "linux" ]]; then
log_error "This script only supports Linux. For Windows, use install.ps1"
fi
log_info "Detected platform: ${OS}-${ARCH}"
}
check_dependencies() {
log_info "Checking dependencies..."
# Check for required tools
for cmd in curl tar; do
if ! command -v "$cmd" &> /dev/null; then
log_error "$cmd is required but not installed"
fi
done
# Check for systemd
if ! command -v systemctl &> /dev/null; then
log_warn "systemd not found. You will need to start the agent manually."
fi
}
get_latest_version() {
if [[ "$VERSION" == "latest" ]]; then
log_info "Fetching latest version..."
VERSION=$(curl -fsSL "https://api.github.com/repos/${GITHUB_REPO}/releases" | \
grep -oP '"tag_name": "agent-v\K[^"]+' | head -1)
if [[ -z "$VERSION" ]]; then
log_error "Failed to fetch latest version"
fi
log_info "Latest version: v${VERSION}"
fi
}
download_agent() {
log_info "Downloading ServerKit Agent v${VERSION}..."
DOWNLOAD_URL="https://github.com/${GITHUB_REPO}/releases/download/agent-v${VERSION}/serverkit-agent-${VERSION}-linux-${ARCH}.tar.gz"
TMP_DIR=$(mktemp -d)
ARCHIVE="${TMP_DIR}/serverkit-agent.tar.gz"
if ! curl -fsSL "$DOWNLOAD_URL" -o "$ARCHIVE"; then
rm -rf "$TMP_DIR"
log_error "Failed to download agent from: $DOWNLOAD_URL"
fi
# Extract binary
log_info "Extracting agent..."
tar -xzf "$ARCHIVE" -C "$TMP_DIR"
# Install binary
mv "${TMP_DIR}/serverkit-agent-linux-${ARCH}" "${INSTALL_DIR}/${AGENT_BINARY}"
chmod +x "${INSTALL_DIR}/${AGENT_BINARY}"
# Cleanup
rm -rf "$TMP_DIR"
log_success "Agent installed to ${INSTALL_DIR}/${AGENT_BINARY}"
}
create_user() {
if id "$SERVICE_USER" &>/dev/null; then
log_info "User $SERVICE_USER already exists"
else
log_info "Creating service user: $SERVICE_USER"
useradd -r -s /bin/false -d /nonexistent "$SERVICE_USER"
fi
# Add to docker group if it exists
if getent group docker > /dev/null 2>&1; then
usermod -aG docker "$SERVICE_USER"
log_info "Added $SERVICE_USER to docker group"
fi
}
create_config_dir() {
log_info "Creating configuration directory..."
mkdir -p "$CONFIG_DIR"
chown "$SERVICE_USER:$SERVICE_USER" "$CONFIG_DIR"
chmod 750 "$CONFIG_DIR"
}
register_agent() {
log_info "Registering agent with ServerKit..."
REGISTER_CMD="${INSTALL_DIR}/${AGENT_BINARY} register --token \"${TOKEN}\" --server \"${SERVER_URL}\""
if [[ -n "$SERVER_NAME" ]]; then
REGISTER_CMD="${REGISTER_CMD} --name \"${SERVER_NAME}\""
fi
if ! eval "$REGISTER_CMD"; then
log_error "Agent registration failed"
fi
# Fix permissions on config files
chown -R "$SERVICE_USER:$SERVICE_USER" "$CONFIG_DIR"
log_success "Agent registered successfully"
}
install_systemd_service() {
if ! command -v systemctl &> /dev/null; then
log_warn "Skipping systemd service installation (systemd not found)"
return
fi
log_info "Installing systemd service..."
cat > /etc/systemd/system/serverkit-agent.service << EOF
[Unit]
Description=ServerKit Agent
Documentation=https://github.com/${GITHUB_REPO}
After=network-online.target docker.service
Wants=network-online.target
[Service]
Type=simple
User=${SERVICE_USER}
Group=${SERVICE_USER}
ExecStart=${INSTALL_DIR}/${AGENT_BINARY} start
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=serverkit-agent
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=${CONFIG_DIR}
PrivateTmp=true
# Environment
Environment=HOME=/nonexistent
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable serverkit-agent
log_success "Systemd service installed"
}
start_service() {
if ! command -v systemctl &> /dev/null; then
log_warn "Cannot auto-start without systemd"
echo ""
echo "To start the agent manually:"
echo " ${INSTALL_DIR}/${AGENT_BINARY} start"
return
fi
log_info "Starting ServerKit Agent..."
systemctl start serverkit-agent
sleep 2
if systemctl is-active --quiet serverkit-agent; then
log_success "Agent is running"
else
log_error "Failed to start agent. Check logs with: journalctl -u serverkit-agent"
fi
}
print_success() {
echo ""
echo -e "${GREEN}╔═══════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ Installation completed successfully! ║${NC}"
echo -e "${GREEN}╚═══════════════════════════════════════════════════════════╝${NC}"
echo ""
echo "Agent Status:"
echo " Binary: ${INSTALL_DIR}/${AGENT_BINARY}"
echo " Config: ${CONFIG_DIR}/config.yaml"
echo " Service: serverkit-agent"
echo ""
echo "Useful commands:"
echo " Check status: systemctl status serverkit-agent"
echo " View logs: journalctl -u serverkit-agent -f"
echo " Restart agent: systemctl restart serverkit-agent"
echo " Stop agent: systemctl stop serverkit-agent"
echo ""
}
# Main execution
main() {
print_banner
parse_args "$@"
check_root
detect_platform
check_dependencies
get_latest_version
download_agent
create_user
create_config_dir
register_agent
install_systemd_service
start_service
print_success
}
main "$@"