Files
proxmox/scripts/deployment/provision-op-stack-operator-lxcs.sh
defiQUG dbd517b279 Sync workspace: config, docs, scripts, CI, operator rules, and submodule pointers.
- Update dbis_core, cross-chain-pmm-lps, explorer-monorepo, metamask-integration, pr-workspace/chains
- Omit embedded publish git dirs and empty placeholders from index

Made-with: Cursor
2026-04-12 06:12:20 -07:00

228 lines
8.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Provision the OP Stack operator landing zone on Proxmox r630-02.
#
# Creates:
# 5751 op-stack-deployer-1 (192.168.11.69)
# 5752 op-stack-ops-1 (192.168.11.70)
#
# Installs baseline tooling, enables SSH, seeds repo OP Stack scaffolding,
# and prepares /etc/op-stack and /opt/op-stack-bootstrap inside each CT.
#
# Usage:
# bash scripts/deployment/provision-op-stack-operator-lxcs.sh [--dry-run]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
source "$PROJECT_ROOT/.env" 2>/dev/null || true
source "$PROJECT_ROOT/config/ip-addresses.conf" 2>/dev/null || true
CT_PROXMOX_HOST="${OP_STACK_PROXMOX_HOST:-${PROXMOX_HOST_R630_02:-192.168.11.12}}"
CT_STORAGE="${OP_STACK_PROXMOX_STORAGE:-thin5}"
CT_TEMPLATE="${OP_STACK_PROXMOX_TEMPLATE:-local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst}"
CT_NETWORK="${OP_STACK_PROXMOX_NETWORK:-vmbr0}"
CT_GATEWAY="${OP_STACK_PROXMOX_GATEWAY:-${NETWORK_GATEWAY:-192.168.11.1}}"
CT_NAMESERVER="${OP_STACK_PROXMOX_NAMESERVER:-${DNS_PRIMARY:-1.1.1.1}}"
SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
DRY_RUN=false
[[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true
SSH_PUBKEY_PATH="${SSH_PUBKEY_PATH:-$HOME/.ssh/id_ed25519_proxmox.pub}"
if [[ ! -f "$SSH_PUBKEY_PATH" ]]; then
SSH_PUBKEY_PATH="${HOME}/.ssh/id_ed25519.pub"
fi
if [[ ! -f "$SSH_PUBKEY_PATH" ]]; then
echo "ERROR: No SSH public key found at ~/.ssh/id_ed25519_proxmox.pub or ~/.ssh/id_ed25519.pub"
exit 1
fi
SSH_KEY_PATH="${SSH_PUBKEY_PATH%.pub}"
DIRECT_CT_SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
if [[ -f "$SSH_KEY_PATH" ]]; then
DIRECT_CT_SSH_OPTS="-i $SSH_KEY_PATH $DIRECT_CT_SSH_OPTS"
fi
BOOTSTRAP_TAR="$(mktemp /tmp/op-stack-bootstrap.XXXXXX.tgz)"
REMOTE_BOOTSTRAP_TAR="/root/op-stack-bootstrap.tgz"
REMOTE_PUBKEY="/root/op-stack-authorized_key.pub"
trap 'rm -f "$BOOTSTRAP_TAR"' EXIT
CTS=(
"${OP_STACK_DEPLOYER_VMID:-5751}|op-stack-deployer-1|${IP_OP_STACK_DEPLOYER_CT:-192.168.11.69}|8192|4|32|op-stack-deployer-operator-workspace"
"${OP_STACK_OPS_VMID:-5752}|op-stack-ops-1|${IP_OP_STACK_OPS_CT:-192.168.11.70}|12288|6|48|op-stack-runtime-service-staging"
)
tar -C "$PROJECT_ROOT" -czf "$BOOTSTRAP_TAR" \
config/op-stack-superchain \
config/wormhole \
scripts/op-stack \
scripts/wormhole \
docs/03-deployment/OP_STACK_STANDARD_ROLLUP_SUPERCHAIN_RUNBOOK.md \
docs/03-deployment/OP_STACK_L2_AND_BESU138_BRIDGE_NOTES.md \
docs/03-deployment/WORMHOLE_NTT_EXECUTOR_OPERATOR_RUNBOOK.md \
config/systemd/op-stack-batcher.example.service \
config/systemd/op-stack-challenger.example.service \
config/systemd/op-stack-op-node.example.service \
config/systemd/op-stack-op-reth.example.service \
config/systemd/op-stack-proposer.example.service \
config/systemd/op-stack-sequencer.example.service
echo "=== OP Stack operator landing zone ==="
echo "Proxmox host: $CT_PROXMOX_HOST"
echo "Storage: $CT_STORAGE | Template: $CT_TEMPLATE | Network: $CT_NETWORK"
echo "SSH public key: $SSH_PUBKEY_PATH"
echo
for spec in "${CTS[@]}"; do
IFS="|" read -r vmid hostname ip memory cores disk description <<<"$spec"
echo " - CT $vmid $hostname @ $ip (${memory}MB RAM, ${cores} cores, ${disk}G disk)"
done
echo
if $DRY_RUN; then
echo "[DRY-RUN] Would create/bootstrap the CTs above on $CT_PROXMOX_HOST."
exit 0
fi
scp $SSH_OPTS "$SSH_PUBKEY_PATH" "root@${CT_PROXMOX_HOST}:${REMOTE_PUBKEY}"
scp $SSH_OPTS "$BOOTSTRAP_TAR" "root@${CT_PROXMOX_HOST}:${REMOTE_BOOTSTRAP_TAR}"
for spec in "${CTS[@]}"; do
IFS="|" read -r vmid hostname ip memory cores disk description <<<"$spec"
echo "=== Provisioning CT ${vmid} (${hostname}) ==="
if ssh $SSH_OPTS "root@${CT_PROXMOX_HOST}" "pct list 2>/dev/null | grep -q '^${vmid} '"; then
echo "CT ${vmid} already exists — skipping create"
else
ssh $SSH_OPTS "root@${CT_PROXMOX_HOST}" bash -s -- \
"$vmid" "$hostname" "$memory" "$cores" "$disk" "$ip" "$description" \
"$CT_TEMPLATE" "$CT_STORAGE" "$CT_NETWORK" "$CT_GATEWAY" "$CT_NAMESERVER" <<'REMOTE_CREATE'
set -euo pipefail
vmid="$1"
hostname="$2"
memory="$3"
cores="$4"
disk="$5"
ip="$6"
description="$7"
template="$8"
storage="$9"
network="${10}"
gateway="${11}"
nameserver="${12}"
pct create "$vmid" "$template" \
--hostname "$hostname" \
--memory "$memory" \
--cores "$cores" \
--rootfs "${storage}:${disk}" \
--net0 "name=eth0,bridge=${network},ip=${ip}/24,gw=${gateway}" \
--nameserver "$nameserver" \
--description "$description" \
--start 1 \
--onboot 1 \
--unprivileged 0 \
--features nesting=1,keyctl=1
REMOTE_CREATE
echo "Waiting for CT ${vmid} to boot..."
sleep 20
fi
ssh $SSH_OPTS "root@${CT_PROXMOX_HOST}" "pct start ${vmid} >/dev/null 2>&1 || true"
ssh $SSH_OPTS "root@${CT_PROXMOX_HOST}" "pct push ${vmid} ${REMOTE_PUBKEY} /root/op-stack-authorized_key.pub >/dev/null"
ssh $SSH_OPTS "root@${CT_PROXMOX_HOST}" "pct push ${vmid} ${REMOTE_BOOTSTRAP_TAR} /root/op-stack-bootstrap.tgz >/dev/null"
ssh $SSH_OPTS "root@${CT_PROXMOX_HOST}" bash -s -- "$vmid" "$hostname" <<'REMOTE_BOOTSTRAP'
set -euo pipefail
vmid="$1"
hostname="$2"
pct exec "$vmid" -- bash -lc '
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y -qq \
sudo openssh-server ca-certificates curl git jq rsync unzip zip \
tar gzip xz-utils make build-essential tmux htop python3 python3-pip golang-go
systemctl enable ssh >/dev/null 2>&1 || systemctl enable ssh.service >/dev/null 2>&1 || true
systemctl restart ssh >/dev/null 2>&1 || systemctl restart ssh.service >/dev/null 2>&1 || true
id -u opuser >/dev/null 2>&1 || useradd -m -s /bin/bash -G sudo opuser
install -d -m 700 /root/.ssh /home/opuser/.ssh
install -d -m 755 /opt/op-stack /etc/op-stack /etc/op-stack/systemd-examples /opt/op-stack-bootstrap
if ! grep -qxF "$(cat /root/op-stack-authorized_key.pub)" /root/.ssh/authorized_keys 2>/dev/null; then
cat /root/op-stack-authorized_key.pub >> /root/.ssh/authorized_keys
fi
if ! grep -qxF "$(cat /root/op-stack-authorized_key.pub)" /home/opuser/.ssh/authorized_keys 2>/dev/null; then
cat /root/op-stack-authorized_key.pub >> /home/opuser/.ssh/authorized_keys
fi
chown -R opuser:opuser /home/opuser/.ssh /opt/op-stack /opt/op-stack-bootstrap
chmod 600 /root/.ssh/authorized_keys /home/opuser/.ssh/authorized_keys
echo "opuser ALL=(ALL) NOPASSWD:ALL" >/etc/sudoers.d/90-opuser
chmod 440 /etc/sudoers.d/90-opuser
rm -rf /opt/op-stack-bootstrap/*
tar -xzf /root/op-stack-bootstrap.tgz -C /opt/op-stack-bootstrap
cp /opt/op-stack-bootstrap/config/op-stack-superchain/op-stack-l2.example.env /etc/op-stack/op-stack-l2.example.env
cp /opt/op-stack-bootstrap/config/systemd/op-stack-*.example.service /etc/op-stack/systemd-examples/ 2>/dev/null || true
case "'"${hostname}"'" in
op-stack-deployer-1)
bash /opt/op-stack-bootstrap/scripts/op-stack/prepare-operator-ct.sh deployer
;;
op-stack-ops-1)
bash /opt/op-stack-bootstrap/scripts/op-stack/prepare-operator-ct.sh ops
;;
esac
echo "'"${hostname}"'" >/etc/hostname
hostname "'"${hostname}"'"
'
REMOTE_BOOTSTRAP
ssh $DIRECT_CT_SSH_OPTS "opuser@${ip}" "hostname && id"
done
echo "Refreshing governance TOMLs inside deployer CT if cache is missing..."
ssh $DIRECT_CT_SSH_OPTS "opuser@${IP_OP_STACK_DEPLOYER_CT:-192.168.11.69}" '
set -euo pipefail
cache_dir=/opt/op-stack-bootstrap/config/op-stack-superchain/cache
required=(
standard-config-params-mainnet.toml
standard-config-roles-mainnet.toml
standard-versions-mainnet.toml
)
missing=0
for file in "${required[@]}"; do
if [[ ! -s "$cache_dir/$file" ]]; then
missing=1
fi
done
if [[ "${OP_STACK_REFRESH_TOMLS:-0}" == "1" || "$missing" == "1" ]]; then
cd /opt/op-stack-bootstrap
bash scripts/op-stack/fetch-standard-mainnet-toml.sh
else
echo "Using seeded governance TOML cache in $cache_dir"
fi
'
echo
echo "✅ OP Stack operator landing zone ready:"
echo " - 5751 op-stack-deployer-1 @ ${IP_OP_STACK_DEPLOYER_CT:-192.168.11.69}"
echo " - 5752 op-stack-ops-1 @ ${IP_OP_STACK_OPS_CT:-192.168.11.70}"
echo
echo "Next:"
echo " 1. SSH as opuser to the CTs"
echo " 2. Copy live secrets/env into /etc/op-stack/"
echo " 3. Install pinned Optimism binaries or packages"
echo " 4. Run Sepolia rehearsal from 5751, then stage runtime services from 5752"