mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-21 11:46:37 +00:00
daemon race fix
This commit is contained in:
@@ -177,6 +177,24 @@ mkdir -p "$(dirname "$DONE_MARKER")"
|
||||
touch "$DONE_MARKER"
|
||||
|
||||
systemctl start spinifex.target
|
||||
|
||||
# Wait for the daemon to bring up external networking. When external_mode=pool
|
||||
# is configured the daemon creates br-ext (the OVN external bridge) during
|
||||
# startup; launching instances before it is ready results in no public IP being
|
||||
# assigned. ip link requires no root and avoids parsing daemon logs.
|
||||
if grep -q 'external_mode.*pool' /etc/spinifex/spinifex.toml 2>/dev/null; then
|
||||
echo "[firstboot] waiting for external networking (br-ext)..."
|
||||
for _i in $(seq 1 30); do
|
||||
if ip link show br-ext >/dev/null 2>&1; then
|
||||
echo "[firstboot] br-ext ready (${_i}s)"
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if ! ip link show br-ext >/dev/null 2>&1; then
|
||||
echo "[firstboot] warning: br-ext not up after 30s — external networking may be delayed"
|
||||
fi
|
||||
fi
|
||||
`, cfg.Hostname, setupOVN, clusterCmd)
|
||||
|
||||
path := filepath.Join(root, "usr/local/bin/spinifex-firstboot.sh")
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# Installing Spinifex from Bootable USB
|
||||
|
||||
|
||||
Spinifex is designed for bare-metal hardware, edge nodes and data-centre use. Follow this guide to install Spinifex from a bootbale USB using the Spinifex ISO.
|
||||
Spinifex is designed for bare-metal hardware, edge nodes and data-centre use. Follow this guide to install Spinifex from a bootable USB using the Spinifex ISO.
|
||||
|
||||
Note this tutorial is for x86 architecture.
|
||||
Also note, this procedure COMPLETELY WIPES the target disk. For systems with multiple disks, ensure the correct one is targeted.
|
||||
|
||||
## Booting Media
|
||||
|
||||
For this tutorial, a USB drive with at least 8GB of memory is required. Note that burning the Spinifex ISO onto the USB completely wipes the USB, so ensure no important data is stored on the USB used.
|
||||
For this tutorial, a USB drive with at least 8GB of memory is required. Note that flashing the Spinifex ISO onto the USB completely wipes the USB, so ensure no important data is stored on the USB used.
|
||||
|
||||
## Balena Etcher installation
|
||||
|
||||
For this tutorial download Balena Etcher to simplify the ISO burning process.
|
||||
For this tutorial download Balena Etcher to simplify the ISO flash process.
|
||||
|
||||
* [Balena Etcher](https://etcher.balena.io)
|
||||
|
||||
@@ -21,7 +21,7 @@ For this tutorial download Balena Etcher to simplify the ISO burning process.
|
||||
|
||||
Next, download the Spinifex ISO (x86)
|
||||
|
||||
* [Spinifex ISO](cloudflare link here)
|
||||
* [Spinifex ISO](https://iso.mulgadc.com/spinifex.iso)
|
||||
|
||||
## Flash Media
|
||||
Once installed, open Balena Etcher.
|
||||
@@ -36,7 +36,10 @@ You can now safely eject the USB drive if it was not ejected automatically.
|
||||
|
||||
## Boot From USB drive
|
||||
Insert your newly flashed USB drive into the target device and turn it on.
|
||||
|
||||

|
||||
|
||||
|
||||
As it boots, quickly press the correct key for your device to bring up the BIOS/UEFI menu (commonly F2, F10, F12, ESC or DEL) (image) and change the boot order such that the flashed USB drive has first priority, then continue to boot.
|
||||
|
||||
If done succesfully, the Spinifex ISO GRUB menu will appear.
|
||||
@@ -44,7 +47,17 @@ If done succesfully, the Spinifex ISO GRUB menu will appear.
|
||||
From this menu you can select which method of install is used (console recommended). Headless mode can be configured by mounting the USB on a host device after flashing and editing the grub.cfg file with the desired values.
|
||||
|
||||
## Setting up the Spinifex Node
|
||||
In console mode, follow the installation prompts to set the required networking values for the Spinifex node. We recommend using automatic IP (DHCP) but this can also be configured manually. Set a hostname (eg node1) and admin password.
|
||||
In console mode, follow the installation prompts to set the required networking values for the Spinifex node.
|
||||
|
||||
The installer will default to the most sensible disk to install on depending on system configuration - ensure this default is correct before installation, as the process will wipe the disk.
|
||||
|
||||
For network configuration, it is recommended to use automatic IP (DHCP), but this can also be configured manually.
|
||||
|
||||
Network interfaces will be automatically detected. In the event that none are detected, the user can manually input the name of the network interface. in the event that multiple network interfaces are detected, the installer will prompt for WAN selection first, followed by LAN.
|
||||
|
||||
A hostname (eg node1) and admin password must be set, followed by the "cluster role" - whether the node is the first in a new cluster, or joining an already an existing one.
|
||||
|
||||
Once configuration is complete, a summary of the configuration will be shown.
|
||||
|
||||

|
||||
|
||||
|
||||
+88
-2
@@ -78,7 +78,7 @@ if [ -z "$AMI_ID" ] || [ "$AMI_ID" = "None" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SUBNET_ID=$(aws ec2 describe-subnets --query "Subnets[0].SubnetId" --output text)
|
||||
SUBNET_ID=$(aws ec2 describe-subnets --query 'Subnets[?MapPublicIpOnLaunch==`true`].SubnetId | [0]' --output text)
|
||||
if [ -z "$SUBNET_ID" ] || [ "$SUBNET_ID" = "None" ]; then
|
||||
echo "❌ No subnet found"
|
||||
exit 1
|
||||
@@ -94,4 +94,90 @@ INSTANCE_ID=$(aws ec2 run-instances \
|
||||
--count 1 \
|
||||
--query 'Instances[0].InstanceId' --output text)
|
||||
|
||||
echo "✅ Smoke test passed — instance $INSTANCE_ID launched ($INSTANCE_TYPE)"
|
||||
if [ -z "$INSTANCE_ID" ] || [ "$INSTANCE_ID" = "None" ] || [ "$INSTANCE_ID" = "null" ]; then
|
||||
echo "❌ run-instances returned no InstanceId"
|
||||
exit 1
|
||||
fi
|
||||
echo " Instance ID: $INSTANCE_ID"
|
||||
|
||||
# --- Wait for running state ---
|
||||
echo "==> Waiting for instance to reach running state"
|
||||
COUNT=0
|
||||
STATE="unknown"
|
||||
while [ $COUNT -lt 60 ]; do
|
||||
DESCRIBE=$(aws ec2 describe-instances --instance-ids "$INSTANCE_ID" 2>/dev/null) || {
|
||||
sleep 2; COUNT=$((COUNT + 1)); continue
|
||||
}
|
||||
STATE=$(echo "$DESCRIBE" | jq -r '.Reservations[0].Instances[0].State.Name // "not-found"')
|
||||
[ "$STATE" = "running" ] && break
|
||||
if [ "$STATE" = "terminated" ]; then
|
||||
echo "❌ Instance terminated unexpectedly"
|
||||
exit 1
|
||||
fi
|
||||
sleep 2
|
||||
COUNT=$((COUNT + 1))
|
||||
done
|
||||
if [ "$STATE" != "running" ]; then
|
||||
echo "❌ Instance failed to reach running state (last: $STATE)"
|
||||
exit 1
|
||||
fi
|
||||
echo " Instance is running"
|
||||
|
||||
# --- Resolve SSH endpoint (public IP or QEMU hostfwd) ---
|
||||
echo "==> Resolving SSH endpoint"
|
||||
INST_PUBLIC_IP=$(aws ec2 describe-instances --instance-ids "$INSTANCE_ID" \
|
||||
--query 'Reservations[0].Instances[0].PublicIpAddress' --output text 2>/dev/null || echo "None")
|
||||
|
||||
SSH_INST_PORT=22
|
||||
if [ -n "$INST_PUBLIC_IP" ] && [ "$INST_PUBLIC_IP" != "None" ] && [ "$INST_PUBLIC_IP" != "null" ]; then
|
||||
SSH_INST_HOST="$INST_PUBLIC_IP"
|
||||
echo " SSH via public IP: $SSH_INST_HOST"
|
||||
else
|
||||
# Production OVN networking — instance is reachable via its private IP from this node.
|
||||
SSH_INST_HOST=$(aws ec2 describe-instances --instance-ids "$INSTANCE_ID" \
|
||||
--query 'Reservations[0].Instances[0].PrivateIpAddress' --output text 2>/dev/null || echo "")
|
||||
if [ -z "$SSH_INST_HOST" ] || [ "$SSH_INST_HOST" = "None" ] || [ "$SSH_INST_HOST" = "null" ]; then
|
||||
echo "❌ Could not determine IP for $INSTANCE_ID"
|
||||
exit 1
|
||||
fi
|
||||
echo " SSH via private IP (OVN): $SSH_INST_HOST"
|
||||
fi
|
||||
|
||||
# --- Wait for SSH ---
|
||||
echo "==> Waiting for SSH on $SSH_INST_HOST:$SSH_INST_PORT"
|
||||
SSH_READY=0
|
||||
for _i in $(seq 1 300); do
|
||||
if ssh -o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o ConnectTimeout=2 \
|
||||
-o BatchMode=yes \
|
||||
-p "$SSH_INST_PORT" \
|
||||
-i "$SSH_KEY" \
|
||||
ec2-user@"$SSH_INST_HOST" 'echo ready' >/dev/null 2>&1; then
|
||||
SSH_READY=1
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
if [ $SSH_READY -eq 0 ]; then
|
||||
echo "❌ SSH not ready after 300s"
|
||||
exit 1
|
||||
fi
|
||||
echo " SSH is ready"
|
||||
|
||||
# --- Verify instance identity via SSH ---
|
||||
echo "==> Verifying instance"
|
||||
SSH_OUT=$(ssh -o StrictHostKeyChecking=no \
|
||||
-o UserKnownHostsFile=/dev/null \
|
||||
-o ConnectTimeout=5 \
|
||||
-o BatchMode=yes \
|
||||
-p "$SSH_INST_PORT" \
|
||||
-i "$SSH_KEY" \
|
||||
ec2-user@"$SSH_INST_HOST" 'id && hostname' 2>&1)
|
||||
echo " $SSH_OUT"
|
||||
if ! echo "$SSH_OUT" | grep -q "ec2-user"; then
|
||||
echo "❌ Expected ec2-user in SSH output"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Smoke test passed — instance $INSTANCE_ID launched, running, and SSH-verified"
|
||||
|
||||
Reference in New Issue
Block a user