- 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
228 lines
8.2 KiB
Bash
Executable File
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"
|