87 lines
3.4 KiB
Bash
Executable File
87 lines
3.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Provision the dedicated storage VM from a Debian 13 cloud image driven by a
|
|
# cloud-init NoCloud seed. It comes up serving NFS (/srv/nfs) and an iSCSI LUN.
|
|
set -euo pipefail
|
|
source "$(dirname "$0")/lab.env"
|
|
|
|
sudo -v # prompt for the sudo password once, up front
|
|
|
|
PUBKEY="$(cat "$SSH_PUB")"
|
|
BASE_IMG="${LIB_DIR}/${DEBIAN_IMG}"
|
|
OS_DISK="${LIB_DIR}/${STORE_NAME}.qcow2"
|
|
DATA_DISK="${LIB_DIR}/${STORE_NAME}-data.qcow2"
|
|
SEED_ISO="${LIB_DIR}/${STORE_NAME}-seed.iso"
|
|
|
|
echo "==> Fetching Debian cloud image (if needed)"
|
|
if ! sudo test -f "$BASE_IMG"; then
|
|
sudo curl -fL --progress-bar -o "$BASE_IMG" "$DEBIAN_URL"
|
|
fi
|
|
|
|
echo "==> Building cloud-init seed ISO"
|
|
SEED_SRC="${BUILD_DIR}/cloud-init"
|
|
mkdir -p "$SEED_SRC"
|
|
sed -e "s|@@ROOT_PASSWORD@@|${ROOT_PASSWORD}|g" \
|
|
-e "s|@@SSH_PUBKEY@@|${PUBKEY}|g" \
|
|
-e "s|@@ISCSI_IQN@@|${ISCSI_IQN}|g" \
|
|
-e "s|@@ISCSI_LUN_GB@@|${ISCSI_LUN_GB}|g" \
|
|
"${SCRIPT_DIR}/cloud-init/user-data" > "${SEED_SRC}/user-data"
|
|
cp "${SCRIPT_DIR}/cloud-init/meta-data" "${SEED_SRC}/meta-data"
|
|
genisoimage -quiet -output "${BUILD_DIR}/${STORE_NAME}-seed.iso" \
|
|
-volid cidata -joliet -rock "${SEED_SRC}/user-data" "${SEED_SRC}/meta-data"
|
|
sudo cp -f "${BUILD_DIR}/${STORE_NAME}-seed.iso" "$SEED_ISO"
|
|
|
|
echo "==> Preparing disks"
|
|
if sudo virsh dominfo "$STORE_NAME" >/dev/null 2>&1; then
|
|
echo " $STORE_NAME already defined; destroying + undefining first"
|
|
sudo virsh destroy "$STORE_NAME" 2>/dev/null || true
|
|
sudo virsh undefine "$STORE_NAME" --remove-all-storage 2>/dev/null || true
|
|
fi
|
|
sudo cp -f "$BASE_IMG" "$OS_DISK"
|
|
sudo qemu-img resize "$OS_DISK" 12G
|
|
sudo qemu-img create -f qcow2 "$DATA_DISK" "${STORE_DATA_DISK_GB}G" >/dev/null
|
|
command -v restorecon >/dev/null && sudo restorecon -R "$LIB_DIR" || true
|
|
|
|
echo "==> Creating storage VM"
|
|
sudo virt-install \
|
|
--connect qemu:///system \
|
|
--name "$STORE_NAME" \
|
|
--memory "$STORE_RAM_MB" \
|
|
--vcpus "$STORE_VCPU" \
|
|
--cpu host-passthrough \
|
|
--machine q35 \
|
|
--osinfo detect=on,name=debian12 \
|
|
--import \
|
|
--disk "path=${OS_DISK},format=qcow2,bus=virtio" \
|
|
--disk "path=${DATA_DISK},format=qcow2,bus=virtio" \
|
|
--disk "path=${SEED_ISO},device=cdrom" \
|
|
--network "network=${NET_NAME},mac=${STORE_MAC},model=virtio" \
|
|
--graphics vnc,listen=127.0.0.1 \
|
|
--noautoconsole
|
|
|
|
echo "==> Waiting for storage VM ($STORE_IP) over SSH"
|
|
tries=0
|
|
while ! lab_ssh "$STORE_IP" true >/dev/null 2>&1; do
|
|
sleep 10; tries=$((tries+1))
|
|
if (( tries % 6 == 0 )); then echo " still waiting ... (${tries}0s)"; fi
|
|
if (( tries > 90 )); then echo "ERROR: storage VM not reachable after 15m"; exit 1; fi
|
|
done
|
|
|
|
# count helper: emit a single integer, never fail (grep -c exits 1 on zero match)
|
|
remote_count() { lab_ssh "$STORE_IP" "$1 2>/dev/null | grep -c -- '$2'; true" 2>/dev/null | tr -dc '0-9' | tail -c1; }
|
|
|
|
echo "==> Verifying services (cloud-init may still be finishing; retrying)"
|
|
nfs_ok=0; iscsi_ok=0
|
|
for i in $(seq 1 30); do
|
|
nfs_ok=$(remote_count "exportfs -v" "/srv/nfs"); nfs_ok=${nfs_ok:-0}
|
|
iscsi_ok=$(remote_count "tgtadm --mode target --op show" "${ISCSI_IQN}"); iscsi_ok=${iscsi_ok:-0}
|
|
if (( nfs_ok >= 1 && iscsi_ok >= 1 )); then break; fi
|
|
sleep 10
|
|
done
|
|
echo " NFS export present: ${nfs_ok}, iSCSI target present: ${iscsi_ok}"
|
|
(( nfs_ok >= 1 && iscsi_ok >= 1 )) || {
|
|
echo "WARN: storage services not confirmed. Check that the VM has internet (apt) and"
|
|
echo " 'cloud-init status --long' on ${STORE_IP}. See README troubleshooting."; }
|
|
|
|
echo
|
|
echo "Storage VM ready. Next: ./06-form-cluster.sh"
|