#!/usr/bin/env bash # ============================================================================== # 🦋 Skynet Harness AI — Linux 1-Click Swarm Farmer Installer # US Patent Pending #64/149,175 • GAMPERLAB™ # # One-liner usage (interactive key prompt): # curl -fsSL https://get.skynet-harness.ai | bash # # Non-interactive usage: # export SKYNET_NODE_KEY="sky-node-..." # curl -fsSL https://get.skynet-harness.ai | bash # ============================================================================== set -euo pipefail # Visual formatting BOLD='\033[1m' CYAN='\033[0;36m' GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # No Color # Defaults NODE_KEY="${SKYNET_NODE_KEY:-}" WALLET_ADDRESS="" NODE_NAME="$(hostname -s 2>/dev/null || echo 'linux-node')-farmer" STAGE="3" DRY_RUN=false BOOTSTRAP_HOST="https://skynet-harness.ai" INSTALL_DIR="/opt/skynet" CONFIG_DIR="/etc/skynet" LOG_DIR="/var/log/skynet" STATE_DIR="/var/lib/skynet" # ------------------------------------------------------------------------------ # Banner # ------------------------------------------------------------------------------ print_banner() { cat << "EOF" 🦋 ========================================================= 🦋 ____ _ _ _ _ / ___|| | _____ _ _ __ ___| |_ | | | | __ _ _ __ _ __ ___ ___ ___ \___ \| |/ / _ \ | | '_ \ / _ \ __| | |_| |/ _` | '__| '_ \ / _ \/ __/ __| ___) | < __/ |_| | | | __/ |_ | _ | (_| | | | | | | __/\__ \__ \ |____/|_|\_\___|\__, |_| \___|\__| |_| |_|\__,_|_| |_| |_|\___||___/___/ |___/ Decentralized Mixture-of-Experts AI Inference Swarm Custodial Token-Account & 1-Click Linux Node Installer US Patent Pending #64/149,175 • https://skynet-harness.ai 🦋 ========================================================= 🦋 EOF echo "" } # ------------------------------------------------------------------------------ # Parse Arguments # ------------------------------------------------------------------------------ parse_args() { while [[ $# -gt 0 ]]; do case "$1" in --node-key|-k|--node-key=*) echo -e "${RED}[SICHERHEITSVERSTOSS] Die Übergabe von Secrets via CLI-Argument ist aus Sicherheitsgründen untersagt!${NC}" echo -e "Der Node-Key wäre in 'ps aux' und der Shell-Historie für alle Benutzer des Systems im Klartext sichtbar." echo -e "" echo -e "Bitte nutze die sichere Übergabe per Environment-Variable:" echo -e " ${BOLD}export SKYNET_NODE_KEY=\"sky-node-...\"${NC}" echo -e " ${BOLD}curl -fsSL https://get.skynet-harness.ai | bash${NC}" echo -e "" echo -e "Oder starte das Skript ohne Argumente für eine interaktive, verdeckte Passworteingabe." exit 1 ;; --wallet) WALLET_ADDRESS="$2" shift 2 ;; --node-name|-n) NODE_NAME="$2" shift 2 ;; --stage) STAGE="$2" shift 2 ;; --dry-run) DRY_RUN=true shift ;; -h|--help) echo "Usage: export SKYNET_NODE_KEY=\"sky-node-...\" && $0 [--node-name ] [--stage ] [--dry-run]" echo "Alternativ: $0 ohne Optionen starten für eine interaktive, geschützte Schlüsselabfrage." exit 0 ;; *) echo -e "${RED}[ERROR] Unbekannte Option: $1${NC}" exit 1 ;; esac done # Interaktiver Fallback falls kein Key als Arg oder Env übergeben wurde if [[ -z "$NODE_KEY" && -z "$WALLET_ADDRESS" ]]; then if [ -t 0 ]; then echo -e "${CYAN}🔑 Skynet Node-Key Authentifizierung erforderlich.${NC}" echo -e " Generiere deinen Node-Key im Dashboard: ${BOLD}https://skynet-harness.ai/chat/${NC}" read -r -s -p " Bitte Node-Key einfügen (Eingabe bleibt verdeckt): " NODE_KEY echo "" else echo -e "${RED}[FEHLER] Kein Skynet Node-Key übergeben!${NC}" echo -e "Bitte setze deinen Node-Key sicher vor der Installation:" echo -e " ${BOLD}export SKYNET_NODE_KEY=\"sky-node-dein-key\"${NC}" echo -e " ${BOLD}curl -fsSL https://get.skynet-harness.ai | bash${NC}" echo -e "" echo -e "Oder rufe deinen Node-Key im Dashboard ab: https://skynet-harness.ai/chat/" exit 1 fi fi # Validierung des Node-Keys if [[ -n "$NODE_KEY" ]]; then if [[ ! "$NODE_KEY" =~ ^sky-node-[a-f0-9]{32,64}$ ]]; then echo -e "${YELLOW}[WARNUNG] Der Node-Key entspricht nicht dem Standardformat (sky-node-...). Fahre mit Prüfung fort...${NC}" fi elif [[ -n "$WALLET_ADDRESS" ]]; then echo -e "${YELLOW}[HINWEIS] Die Übergabe von '--wallet' ist veraltet. Verwende künftig deinen Node-Key, um Token direkt in deinem Skynet-Account zu verwahren.${NC}" fi } # ------------------------------------------------------------------------------ # Hardware & Environment Profiling # ------------------------------------------------------------------------------ profile_system() { echo -e "${CYAN}[1/5] Profiling Hardware & Operating System...${NC}" OS_NAME="Unknown Linux" if [ -f /etc/os-release ]; then # shellcheck disable=SC1091 . /etc/os-release OS_NAME="$PRETTY_NAME" elif [[ "$OSTYPE" == "darwin"* ]]; then OS_NAME="macOS $(sw_vers -productVersion 2>/dev/null || echo '')" fi ARCH="$(uname -m)" CPU_CORES="$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo '1')" TOTAL_RAM_MB="0" if [ -f /proc/meminfo ]; then TOTAL_RAM_MB="$(awk '/MemTotal:/ {print int($2/1024)}' /proc/meminfo)" elif command -v free &> /dev/null; then TOTAL_RAM_MB="$(free -m | awk '/^Mem:/{print $2}')" elif command -v sysctl &> /dev/null; then TOTAL_RAM_MB="$(( $(sysctl -n hw.memsize 2>/dev/null || echo 0) / 1024 / 1024 ))" else TOTAL_RAM_MB="2048" fi echo -e " • OS: ${BOLD}${OS_NAME} (${ARCH})${NC}" echo -e " • CPU: ${BOLD}${CPU_CORES} Cores${NC}" echo -e " • Memory: ${BOLD}${TOTAL_RAM_MB} MB RAM${NC}" # CPU Features (AVX2 / AVX-512) HAS_AVX2=false HAS_AVX512=false if grep -q "avx2" /proc/cpuinfo 2>/dev/null; then HAS_AVX2=true; fi if grep -q "avx512" /proc/cpuinfo 2>/dev/null; then HAS_AVX512=true; fi echo -e " • Vector: AVX2=${HAS_AVX2} | AVX-512=${HAS_AVX512}" # GPU Detection via nvidia-smi GPU_INFO="CPU Only (No NVIDIA GPU detected)" HAS_CUDA=false if command -v nvidia-smi &> /dev/null; then DETECTED_GPU="$(nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv,noheader 2>/dev/null | head -n 1 || echo '')" if [[ -n "$DETECTED_GPU" ]]; then GPU_INFO="NVIDIA $DETECTED_GPU" HAS_CUDA=true fi fi echo -e " • Compute: ${BOLD}${GPU_INFO}${NC}" if [ "$TOTAL_RAM_MB" -lt 1500 ]; then echo -e "${RED}[ERROR] Insufficient RAM (${TOTAL_RAM_MB}MB). Minimum required is 2048MB.${NC}" exit 1 fi } # ------------------------------------------------------------------------------ # Root Check & Prerequisites # ------------------------------------------------------------------------------ check_prerequisites() { echo -e "${CYAN}[2/5] Checking Privileges & Dependencies...${NC}" if [ "$DRY_RUN" = false ] && [ "$EUID" -ne 0 ]; then echo -e "${RED}[ERROR] Installer requires root/sudo privileges to set up system service.${NC}" echo -e "Please run with sudo: export SKYNET_NODE_KEY=\"\$NODE_KEY\" && curl -fsSL https://get.skynet-harness.ai | sudo -E bash" exit 1 fi # Check for curl and tar for cmd in curl tar grep; do if ! command -v "$cmd" &> /dev/null; then echo -e "${YELLOW}Missing '$cmd'. Attempting automatic installation...${NC}" if command -v apt-get &> /dev/null; then apt-get update -qq && apt-get install -y -qq "$cmd" elif command -v dnf &> /dev/null; then dnf install -y -q "$cmd" elif command -v yum &> /dev/null; then yum install -y -q "$cmd" elif command -v pacman &> /dev/null; then pacman -Sy --noconfirm "$cmd" fi fi done } # ------------------------------------------------------------------------------ # Node Registration with Trinity Master # ------------------------------------------------------------------------------ register_with_master() { echo -e "${CYAN}[3/5] Registering Node with Skynet Swarm Coordinator...${NC}" REG_PAYLOAD=$(cat << EOF { "nodeName": "$NODE_NAME", "nodeKey": "$NODE_KEY", "walletAddress": "$WALLET_ADDRESS", "arch": "$ARCH", "cpuCores": $CPU_CORES, "ramMb": $TOTAL_RAM_MB, "hasCuda": $HAS_CUDA, "gpuInfo": "$GPU_INFO", "stage": $STAGE } EOF ) if [ "$DRY_RUN" = true ]; then echo -e " [DRY-RUN] Would submit registration to ${BOOTSTRAP_HOST}/api/swarm/register-worker:" echo "$REG_PAYLOAD" return 0 fi REG_RESPONSE=$(curl -sS -X POST "${BOOTSTRAP_HOST}/api/swarm/register-worker" \ -H "Content-Type: application/json" \ -d "$REG_PAYLOAD" || echo '{"success":false,"error":"Connection failed"}') echo -e " • Coordinator Response: ${GREEN}${REG_RESPONSE}${NC}" } # ------------------------------------------------------------------------------ # Installation & Configuration # ------------------------------------------------------------------------------ install_daemon() { echo -e "${CYAN}[4/5] Deploying Skynet Worker Daemon...${NC}" if [ "$DRY_RUN" = true ]; then echo -e " [DRY-RUN] Skipping filesystem modifications." return 0 fi # Create Directories (Code directory belongs to root, state and log to skynet) mkdir -p "$CONFIG_DIR" "$LOG_DIR" "$STATE_DIR" "$INSTALL_DIR" chmod 755 "$INSTALL_DIR" chmod 750 "$LOG_DIR" "$STATE_DIR" # Create unprivileged system user if not exists if ! id -u skynet &>/dev/null; then useradd -r -s /usr/sbin/nologin -M -d "$STATE_DIR" skynet 2>/dev/null || true fi chown -R skynet:skynet "$STATE_DIR" "$LOG_DIR" 2>/dev/null || true # Write Configuration with Strict Group-Scoped Zero-Trust Permissions (chmod 640, root:skynet) cat << EOF > "${CONFIG_DIR}/farmer.conf" # Skynet Harness AI — Farmer Node Configuration NODE_KEY="${NODE_KEY}" WALLET_ADDRESS="${WALLET_ADDRESS}" NODE_NAME="${NODE_NAME}" STAGE="${STAGE}" COORDINATOR_URL="${BOOTSTRAP_HOST}" HAS_CUDA=${HAS_CUDA} INSTALL_TIMESTAMP="$(date -u +"%Y-%m-%dT%H:%M:%SZ")" EOF chown root:skynet "$CONFIG_DIR" 2>/dev/null || true chmod 750 "$CONFIG_DIR" chown root:skynet "${CONFIG_DIR}/farmer.conf" 2>/dev/null || true chmod 640 "${CONFIG_DIR}/farmer.conf" # Create lightweight worker execution script cat << "EOF" > "${INSTALL_DIR}/skynet_worker_daemon.py" #!/usr/bin/env python3 """ Skynet Harness AI — Headless Linux Inference Worker Daemon Periodically fetches compute challenges, executes AVX2/CUDA micro-inference, and reports verified results to earn custodial community token rewards. """ import sys import os import time import json import urllib.request import urllib.error import hashlib import math CONF_FILE = "/etc/skynet/farmer.conf" def load_config(): conf = {} if os.path.exists(CONF_FILE): with open(CONF_FILE, 'r') as f: for line in f: line = line.strip() if line and not line.startswith('#') and '=' in line: k, v = line.split('=', 1) conf[k.strip()] = v.strip().strip('"') return conf def main(): conf = load_config() coordinator = conf.get("COORDINATOR_URL", "https://skynet-harness.ai") node_key = conf.get("NODE_KEY", "") wallet = conf.get("WALLET_ADDRESS", "0x0") node_name = conf.get("NODE_NAME", "unnamed-node") masked_key = f"{node_key[:13]}...{node_key[-4:]}" if len(node_key) > 17 else "none" print(f"[Skynet Daemon] Starting worker '{node_name}' with Node-Key: {masked_key}...") print(f"[Skynet Daemon] Connected to {coordinator}. Entering inference loop...") consecutive_errors = 0 while True: try: # 1. Fetch Challenge req = urllib.request.Request(f"{coordinator}/api/swarm/challenge", headers={"User-Agent": "SkynetLinuxFarmer/1.0"}) with urllib.request.urlopen(req, timeout=10) as resp: challenge = json.loads(resp.read().decode('utf-8')) challenge_id = challenge.get("challengeId") nonce = challenge.get("nonce") vector = challenge.get("vector", []) # 2. Compute Slice Math (AVX2-optimized float multiplication) sum_val = 0.0 for i, val in enumerate(vector): sum_val += val * 0.05 # GELU activation approximation activation = sum_val * (1.0 / (1.0 + math.exp(-1.702 * sum_val))) output_hash = hashlib.sha256(f"{nonce}:{activation:.4f}".encode('utf-8')).hexdigest() # 3. Submit Proof with Job-ID & Nonce verify_payload = json.dumps({ "challengeId": challenge_id, "jobId": f"job_{challenge_id}", "nonce": nonce, "outputHash": output_hash, "gpuInfo": "Linux Dedicated Server (AVX2/CUDA)", "isWebGPU": False, "nodeKey": node_key, "wallet": wallet, "nodeName": node_name }).encode('utf-8') verify_req = urllib.request.Request( f"{coordinator}/api/swarm/verify-challenge", data=verify_payload, headers={"Content-Type": "application/json", "User-Agent": "SkynetLinuxFarmer/1.0"}, method="POST" ) with urllib.request.urlopen(verify_req, timeout=10) as v_resp: result = json.loads(v_resp.read().decode('utf-8')) if result.get("success"): print(f"[+] Verified Challenge {challenge_id[:8]}... | Reward: +16 Tokens | Total: {result.get('totalSwarmTokens')}") consecutive_errors = 0 else: print(f"[-] Verification rejected: {result}") time.sleep(1.0) # Low duty cycle pacing except Exception as e: consecutive_errors += 1 backoff = min(30, 2 ** min(consecutive_errors, 5)) print(f"[!] Worker notice: {e}. Backing off for {backoff}s...") time.sleep(backoff) if __name__ == "__main__": main() EOF chmod 755 "${INSTALL_DIR}/skynet_worker_daemon.py" chown root:root "${INSTALL_DIR}/skynet_worker_daemon.py" # Create systemd Service Unit with Zero-Trust Sandboxing cat << EOF > /etc/systemd/system/skynet-worker.service [Unit] Description=Skynet Harness AI Inference Worker Daemon (Zero-Trust Sandbox) After=network-online.target Wants=network-online.target [Service] Type=simple User=skynet Group=skynet WorkingDirectory=${STATE_DIR} ExecStart=/usr/bin/python3 ${INSTALL_DIR}/skynet_worker_daemon.py Restart=always RestartSec=5 # Zero-Trust Sandboxing & Privilege Restrictions NoNewPrivileges=true PrivateTmp=true PrivateDevices=true ProtectSystem=strict ProtectHome=true ProtectKernelTunables=true ProtectKernelModules=true ProtectControlGroups=true RestrictSUIDSGID=true LockPersonality=true RestrictNamespaces=true SystemCallArchitectures=native CapabilityBoundingSet= RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 # Write access strictly restricted to logs and state (code in /opt/skynet is read-only) ReadWritePaths=${LOG_DIR} ${STATE_DIR} StandardOutput=append:${LOG_DIR}/worker.log StandardError=append:${LOG_DIR}/worker.err.log LimitNOFILE=65535 [Install] WantedBy=multi-user.target EOF # Reload systemd and start service systemctl daemon-reload systemctl enable skynet-worker.service systemctl restart skynet-worker.service echo -e " • Service ${GREEN}skynet-worker.service${NC} installed and started." } # ------------------------------------------------------------------------------ # Final Verification & Status # ------------------------------------------------------------------------------ verify_installation() { echo -e "${CYAN}[5/5] Verifying Service Health...${NC}" if [ "$DRY_RUN" = true ]; then echo -e "${GREEN}✅ Dry-run completed successfully! System is 100% compatible with Skynet Swarm.${NC}" return 0 fi sleep 2 if systemctl is-active --quiet skynet-worker.service; then echo -e "${GREEN}✅ SUCCESS! Skynet Farmer Node is online and computing slices.${NC}" echo "" echo -e "==================================================================" echo -e " ${BOLD}Node Name:${NC} ${NODE_NAME}" if [ -n "$NODE_KEY" ]; then echo -e " ${BOLD}Account Key:${NC} ${NODE_KEY:0:13}...${NODE_KEY: -4} (${GREEN}Direct In-Account Custody${NC})" fi echo -e " ${BOLD}Service Status:${NC} ${GREEN}active (running)${NC}" echo -e " ${BOLD}Live Logs:${NC} journalctl -u skynet-worker.service -f" echo -e " ${BOLD}Config File:${NC} ${CONFIG_DIR}/farmer.conf" echo -e "==================================================================" echo -e "Your server is now mining tokens for community AI inference! 🚀" else echo -e "${RED}[ERROR] Service failed to start. Inspecting log...${NC}" journalctl -u skynet-worker.service -n 20 --no-pager exit 1 fi } # ------------------------------------------------------------------------------ # Main # ------------------------------------------------------------------------------ main() { print_banner parse_args "$@" profile_system check_prerequisites register_with_master install_daemon verify_installation } main "$@"