Added untracked script
This commit is contained in:
157
infra/build-machines/haskell/scripts/bootstrap-alpine.sh
Executable file
157
infra/build-machines/haskell/scripts/bootstrap-alpine.sh
Executable file
@@ -0,0 +1,157 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# bootstrap-alpine.sh — One-shot setup for Haskell build machine on Alpine Linux
|
||||||
|
#
|
||||||
|
# Usage (from workstation):
|
||||||
|
# scp bootstrap-alpine.sh root@<vm-ip>:/tmp/
|
||||||
|
# ssh root@<vm-ip> sh /tmp/bootstrap-alpine.sh
|
||||||
|
#
|
||||||
|
# What it does:
|
||||||
|
# 1. Installs system dependencies (apk)
|
||||||
|
# 2. Creates 'build' user with sudo
|
||||||
|
# 3. Installs GHCup + GHC + Cabal (single version — 8GB disk constraint)
|
||||||
|
# 4. Installs build-agent + OpenRC service
|
||||||
|
# 5. Configures SSH for key-based access
|
||||||
|
#
|
||||||
|
# Disk budget (8GB total):
|
||||||
|
# Alpine base: ~200 MB
|
||||||
|
# Build deps: ~300 MB
|
||||||
|
# GHCup + GHC: ~1800 MB
|
||||||
|
# Cabal + pkgdb: ~300 MB
|
||||||
|
# Headroom: ~5400 MB (for project builds)
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
GHC_VERSION="${GHC_VERSION:-9.8.4}"
|
||||||
|
CABAL_VERSION="${CABAL_VERSION:-3.12.1.0}"
|
||||||
|
|
||||||
|
echo "=== Haskell Build Machine Bootstrap (Alpine) ==="
|
||||||
|
echo "GHC: ${GHC_VERSION} | Cabal: ${CABAL_VERSION}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# ---- 1. System packages ----
|
||||||
|
echo "[1/5] Installing system packages..."
|
||||||
|
apk update
|
||||||
|
apk add \
|
||||||
|
build-base curl git \
|
||||||
|
gmp-dev libffi-dev zlib-dev ncurses-dev \
|
||||||
|
pkgconf openssh autossh jq rsync \
|
||||||
|
sudo shadow python3 \
|
||||||
|
musl-dev gcc g++ make \
|
||||||
|
linux-headers \
|
||||||
|
xz tar
|
||||||
|
|
||||||
|
# ---- 2. Build user ----
|
||||||
|
echo "[2/5] Creating build user..."
|
||||||
|
if ! id build >/dev/null 2>&1; then
|
||||||
|
adduser -D -s /bin/sh -h /home/build build
|
||||||
|
echo "build ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/build
|
||||||
|
chmod 440 /etc/sudoers.d/build
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create build workspace
|
||||||
|
mkdir -p /build
|
||||||
|
chown build:build /build
|
||||||
|
|
||||||
|
# SSH directory
|
||||||
|
mkdir -p /home/build/.ssh
|
||||||
|
chmod 700 /home/build/.ssh
|
||||||
|
chown build:build /home/build/.ssh
|
||||||
|
|
||||||
|
# ---- 3. Haskell toolchain ----
|
||||||
|
echo "[3/5] Installing Haskell toolchain (this takes a while)..."
|
||||||
|
|
||||||
|
# GHCup needs these env vars for non-interactive install
|
||||||
|
export BOOTSTRAP_HASKELL_NONINTERACTIVE=1
|
||||||
|
export BOOTSTRAP_HASKELL_GHC_VERSION="$GHC_VERSION"
|
||||||
|
export BOOTSTRAP_HASKELL_CABAL_VERSION="$CABAL_VERSION"
|
||||||
|
export BOOTSTRAP_HASKELL_INSTALL_STACK=0
|
||||||
|
export BOOTSTRAP_HASKELL_INSTALL_HLS=0
|
||||||
|
|
||||||
|
# Install GHCup as build user
|
||||||
|
su - build -c "
|
||||||
|
export BOOTSTRAP_HASKELL_NONINTERACTIVE=1
|
||||||
|
export BOOTSTRAP_HASKELL_GHC_VERSION='$GHC_VERSION'
|
||||||
|
export BOOTSTRAP_HASKELL_CABAL_VERSION='$CABAL_VERSION'
|
||||||
|
export BOOTSTRAP_HASKELL_INSTALL_STACK=0
|
||||||
|
export BOOTSTRAP_HASKELL_INSTALL_HLS=0
|
||||||
|
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
|
||||||
|
"
|
||||||
|
|
||||||
|
# Add ghcup to build user's profile
|
||||||
|
cat >> /home/build/.profile << 'PROFILE'
|
||||||
|
[ -f "$HOME/.ghcup/env" ] && . "$HOME/.ghcup/env"
|
||||||
|
PROFILE
|
||||||
|
|
||||||
|
# Verify installation
|
||||||
|
su - build -c '. ~/.ghcup/env && ghc --version && cabal --version'
|
||||||
|
|
||||||
|
# Pre-warm cabal package index
|
||||||
|
echo "[3/5] Warming cabal package index..."
|
||||||
|
su - build -c '. ~/.ghcup/env && cabal update'
|
||||||
|
|
||||||
|
# ---- 4. Build agent ----
|
||||||
|
echo "[4/5] Installing build-agent..."
|
||||||
|
|
||||||
|
# The agent script will be copied separately via SCP
|
||||||
|
# Here we just set up the OpenRC service skeleton
|
||||||
|
cat > /etc/init.d/build-agent << 'INITD'
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
|
name="build-agent"
|
||||||
|
description="Haskell Build Agent — State Hub registration + SSH reverse tunnel"
|
||||||
|
command="/usr/local/bin/build-agent"
|
||||||
|
command_user="build"
|
||||||
|
command_background=true
|
||||||
|
pidfile="/run/${RC_SVCNAME}.pid"
|
||||||
|
output_log="/var/log/build-agent.log"
|
||||||
|
error_log="/var/log/build-agent.log"
|
||||||
|
|
||||||
|
depend() {
|
||||||
|
need net
|
||||||
|
after firewall
|
||||||
|
}
|
||||||
|
INITD
|
||||||
|
chmod 755 /etc/init.d/build-agent
|
||||||
|
|
||||||
|
# Create placeholder env file
|
||||||
|
if [ ! -f /etc/build-agent.env ]; then
|
||||||
|
cat > /etc/build-agent.env << 'ENV'
|
||||||
|
# Custodian State Hub — access via forward tunnel
|
||||||
|
STATE_HUB_URL=http://127.0.0.1:18000
|
||||||
|
STATE_HUB_DOMAIN=railiance
|
||||||
|
SSH_RELAY_HOST=
|
||||||
|
SSH_RELAY_USER=worsch
|
||||||
|
SSH_KEY_PATH=/home/build/.ssh/id_build
|
||||||
|
REMOTE_PORT=12222
|
||||||
|
ENV
|
||||||
|
chmod 600 /etc/build-agent.env
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enable on boot
|
||||||
|
rc-update add build-agent default
|
||||||
|
|
||||||
|
# ---- 5. SSH hardening ----
|
||||||
|
echo "[5/5] Configuring SSH..."
|
||||||
|
|
||||||
|
# Enable and start sshd
|
||||||
|
rc-update add sshd default
|
||||||
|
rc-service sshd start 2>/dev/null || true
|
||||||
|
|
||||||
|
# Harden (will take effect after key injection)
|
||||||
|
sed -i 's/^#*PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
|
||||||
|
sed -i 's/^#*PubkeyAuthentication.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Bootstrap complete ==="
|
||||||
|
echo ""
|
||||||
|
echo "Disk usage:"
|
||||||
|
df -h / | tail -1
|
||||||
|
echo ""
|
||||||
|
echo "GHC location: /home/build/.ghcup/"
|
||||||
|
su - build -c '. ~/.ghcup/env && ghc --version'
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " 1. Copy build-agent.py: scp build-agent.py root@<vm>:/usr/local/bin/build-agent"
|
||||||
|
echo " 2. Copy SSH keys: scp id_build root@<vm>:/home/build/.ssh/"
|
||||||
|
echo " 3. Edit env: ssh root@<vm> vi /etc/build-agent.env"
|
||||||
|
echo " 4. Start agent: ssh root@<vm> rc-service build-agent start"
|
||||||
|
echo " 5. Disable root login: ssh root@<vm> 'sed -i s/PermitRootLogin.*/PermitRootLogin no/ /etc/ssh/sshd_config && rc-service sshd restart'"
|
||||||
Reference in New Issue
Block a user