Files
spinifex/scripts/dev-install.sh
T
Josh Siviour f14fb64562 feat(eks): unify eks-server + eks-agent into one eks-node AMI (#288)
* feat(eks): unify eks-server + eks-agent into one eks-node AMI

Collapse the two K3s AMIs into a single spinifex-eks-node image whose role
(server vs agent) is chosen per-instance at first boot, halving build time,
storage, and CVE-rotation surface.

- scripts/images/eks-node/: superset manifest + merged setup.sh; all role
  services baked but only crond + the new eks-node-role selector enabled.
- eks-node-role first-boot selector reads SPINIFEX_K3S_ROLE, rc-update adds +
  starts the matching services (server: k3s + eks-token-webhook + k3s-first-boot
  publisher; agent: k3s-agent), records /etc/spinifex-eks/role, self-disables.
  Paths are env-overridable; eks-node-role_test.sh covers all five cases.
- mulga-eks-etcd-snapshot.sh early-exits on agent nodes.
- k3s_server_vm.go seeds SPINIFEX_K3S_ROLE=server into first-boot.env.
- Makefile/dev-install: build-eks-node-image / import-eks-node-image replace
  the server+agent targets.
- Delete scripts/images/eks-server + eks-agent. The launcher resolves the AMI
  by the spinifex:managed-by=eks tag, so running clusters (which hold the
  resolved AMI ID) are unaffected.

AMI bake + cluster boot are operational integration steps, not yet run.

* fix(eks): order eks-node-role after cloud-config/cloud-final

The first-boot role selector reads /etc/spinifex-eks/first-boot.env, which
cloud-init delivers via write_files in the cloud-config/cloud-final stages.
The selector only depended on net+cgroups, so on a fast boot it could start
before write_files landed and read a missing role env. Add an after-ordering
on cloud-config + cloud-final so the env file is always present first.
2026-06-04 12:28:56 +10:00

109 lines
4.6 KiB
Bash
Executable File

#!/bin/bash
# dev-install.sh — Full local development setup via production installer.
# Builds from source, assembles a tarball, runs setup.sh for scaffolding
# (user creation, directories, systemd units), initializes the cluster,
# and starts services via systemd.
#
# Environment variables:
# SPINIFEX_REGION Region for spx admin init (default: ap-southeast-2)
# SPINIFEX_AZ AZ for spx admin init (default: ${SPINIFEX_REGION}a)
# DEV_INSTALL_SKIP_INIT Internal flag used by reset-dev-env.sh. When 1,
# stops after setup.sh and skips setup-ovn, init,
# CA trust, service start, and LB image import —
# caller owns those steps. Do not set manually.
#
# Usage: ./scripts/dev-install.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
MULGA_ROOT="$(cd "$PROJECT_ROOT/.." && pwd)"
echo "=== Building ==="
cd "$PROJECT_ROOT" && make build
cd "$MULGA_ROOT/viperblock" && make go_build_nbd
echo "=== Assembling tarball for setup.sh ==="
STAGING=$(mktemp -d)
trap 'rm -rf "$STAGING"' EXIT
cp "$PROJECT_ROOT/bin/spx" "$STAGING/spx"
cp "$MULGA_ROOT/viperblock/lib/nbdkit-viperblock-plugin.so" "$STAGING/"
cp "$PROJECT_ROOT/scripts/setup-ovn.sh" "$STAGING/"
mkdir -p "$STAGING/systemd"
cp "$PROJECT_ROOT/build/systemd/"* "$STAGING/systemd/"
mkdir -p "$STAGING/scripts"
cp "$PROJECT_ROOT/build/scripts/"* "$STAGING/scripts/"
mkdir -p "$STAGING/udev"
cp "$PROJECT_ROOT/build/udev/"* "$STAGING/udev/"
cp "$PROJECT_ROOT/build/logrotate/spinifex" "$STAGING/logrotate-spinifex"
tar czf /tmp/spinifex-local.tar.gz -C "$STAGING" .
echo "=== Cleaning stale state from previous installs ==="
# Stop any running services before modifying files
sudo systemctl stop spinifex.target 2>/dev/null || true
sudo systemctl reset-failed 'spinifex-*' 2>/dev/null || true
# Remove stale files owned by the dev user in production paths.
# Previous dev-mode installs (admin init without sudo, start-dev.sh) leave
# files owned by tf-user that service users (spinifex-nats, etc.) can't read
# under systemd's ProtectSystem=strict sandboxing.
for dir in /var/lib/spinifex /var/log/spinifex /etc/spinifex; do
if [ -d "$dir" ]; then
# Remove PID files, stale logs, and the legacy ~/spinifex/config symlink
sudo find "$dir" -name '*.pid' -delete 2>/dev/null || true
sudo find "$dir" -name '*.log' -delete 2>/dev/null || true
sudo find "$dir" -name '*.log.*' -delete 2>/dev/null || true
fi
done
# Remove legacy data dir contents that conflict with production layout
if [ -d /var/lib/spinifex/config ]; then
sudo rm -rf /var/lib/spinifex/config
fi
echo "=== Running setup.sh (creates users, dirs, systemd units) ==="
sudo INSTALL_SPINIFEX_TARBALL=/tmp/spinifex-local.tar.gz INSTALL_SPINIFEX_SKIP_NEWGRP=1 bash "$PROJECT_ROOT/scripts/setup.sh"
rm -f /tmp/spinifex-local.tar.gz
if [ "${DEV_INSTALL_SKIP_INIT:-0}" = "1" ]; then
echo "=== DEV_INSTALL_SKIP_INIT=1 — stopping after setup.sh ==="
echo "Caller owns: setup-ovn, spx admin init, CA trust, service start, LB image."
exit 0
fi
echo "=== Setting up OVN ==="
sudo /usr/local/share/spinifex/setup-ovn.sh --management
SPINIFEX_REGION="${SPINIFEX_REGION:-ap-southeast-2}"
SPINIFEX_AZ="${SPINIFEX_AZ:-${SPINIFEX_REGION}a}"
echo "=== Initializing (region=$SPINIFEX_REGION az=$SPINIFEX_AZ) ==="
sudo spx admin init --force --region "$SPINIFEX_REGION" --az "$SPINIFEX_AZ" --node node1 --nodes 1
echo "=== Starting services ==="
sudo systemctl start spinifex.target
# Check if user needs to re-login for spinifex group membership
if ! id -Gn 2>/dev/null | grep -qw spinifex; then
newgrp spinifex
fi
echo "=== Building and installing microVM artifacts ==="
cd "$PROJECT_ROOT" && make build-lb-agent install-microvm
# Unified EKS node AMI (server + agent; role chosen at first boot). Heavy (full
# Alpine + K3s build, needs sudo + network), so it is opt-in: set
# DEV_INSTALL_EKS=1 to build + register it. Without it, `aws eks create-cluster`
# fails AMI resolution until the operator runs `make import-eks-node-image`.
if [ "${DEV_INSTALL_EKS:-0}" = "1" ]; then
echo "=== Building + importing eks-node AMI ==="
cd "$PROJECT_ROOT" && make import-eks-node-image
else
echo "=== Skipping eks-node AMI (set DEV_INSTALL_EKS=1 to enable, or run 'make import-eks-node-image') ==="
fi
echo "=== Done ==="
echo "Services: sudo systemctl status spinifex.target"
echo "Logs: journalctl -u 'spinifex-*' -f"
echo "Test: AWS_PROFILE=spinifex aws ec2 describe-instances"
echo "Iterate: make deploy (rebuild + restart all)"