provisioned volume checkpoint
This commit is contained in:
+29
-11
@@ -24,6 +24,10 @@ VOLUME_NAME="ValVol202609"
|
||||
VOLUME_DEVICE="/dev/disk/by-id/scsi-0Linode_Volume_$VOLUME_NAME"
|
||||
VOLUME_MOUNT="/mnt/$VOLUME_NAME"
|
||||
|
||||
# StackScript that mounts the volume on first boot (see stackscript.md).
|
||||
# Enter the numeric StackScript ID manually after creating it in the Linode UI.
|
||||
STACKSCRIPT_ID="2225110"
|
||||
|
||||
if [[ "$SCRIPT_ACTION" == "" || "$SCRIPT_ACTION" == "--help" || "$SCRIPT_ACTION" == "-?" ]]; then
|
||||
echo "Linode helper script: create-linode.sh <action> <label> [args]"
|
||||
echo "Create: create-linode.sh c <new label>"
|
||||
@@ -45,6 +49,8 @@ if [[ "$SCRIPT_ACTION" == "c" ]]; then
|
||||
INSTANCE_SIZE="g6-standard-4"
|
||||
INSTANCE_IMAGE="linode/debian13"
|
||||
|
||||
# The StackScript (see stackscript.md) runs as root on first boot and mounts
|
||||
# the volume, so no SSH session is needed to configure it.
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $LINODE_API_KEY" \
|
||||
-X POST -d '{
|
||||
@@ -53,11 +59,29 @@ if [[ "$SCRIPT_ACTION" == "c" ]]; then
|
||||
"type": "'$INSTANCE_SIZE'",
|
||||
"image": "'$INSTANCE_IMAGE'",
|
||||
"root_pass": "'$ROOT_PASS'",
|
||||
"authorized_users": ["ni7ne_midpriv"]
|
||||
"authorized_users": ["ni7ne_midpriv"],
|
||||
"stackscript_id": '$STACKSCRIPT_ID'
|
||||
}' \
|
||||
https://api.linode.com/v4/linode/instances | jq .
|
||||
|
||||
sleep 60
|
||||
# Wait for the Linode to finish provisioning instead of blindly sleeping.
|
||||
# Poll the status until it reports "running", which is the state required
|
||||
# before the volume can be attached. 60 attempts x 10s = 10 minute ceiling.
|
||||
INSTANCE_STATUS=""
|
||||
for _ in $(seq 1 60); do
|
||||
INSTANCE_STATUS=$(curl -s -H "Authorization: Bearer $LINODE_API_KEY" https://api.linode.com/v4/linode/instances | jq -r '.data[] | select(.label == "'$LINODE_LABEL'") | .status')
|
||||
if [[ "$INSTANCE_STATUS" == "running" ]]; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting for $LINODE_LABEL to reach running (status: ${INSTANCE_STATUS:-unknown})..."
|
||||
sleep 10
|
||||
done
|
||||
|
||||
if [[ "$INSTANCE_STATUS" != "running" ]]; then
|
||||
echo "ERROR: $LINODE_LABEL did not reach running (last status: ${INSTANCE_STATUS:-unknown})." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INSTANCE_IP=$(curl -s -H "Authorization: Bearer $LINODE_API_KEY" https://api.linode.com/v4/linode/instances | jq '.data[] | select(.label == "'$LINODE_LABEL'") | .ipv4[]' | sed -e "s/\"//g")
|
||||
INSTANCE_ID=$(curl -s -H "Authorization: Bearer $LINODE_API_KEY" https://api.linode.com/v4/linode/instances | jq '.data[] | select(.label == "'$LINODE_LABEL'") | .id' | sed -e "s/\"//g")
|
||||
echo "Instance IP: $INSTANCE_IP"
|
||||
@@ -73,16 +97,10 @@ if [[ "$SCRIPT_ACTION" == "c" ]]; then
|
||||
}' \
|
||||
https://api.linode.com/v4/volumes/$VOLUME_ID/attach | jq .
|
||||
|
||||
# Give the volume a moment to appear on the instance before mounting it.
|
||||
# Give the volume a moment to appear on the instance before the StackScript
|
||||
# (which runs on first boot) mounts it.
|
||||
sleep 15
|
||||
|
||||
# SSH CONFIG BLOCK
|
||||
ssh -o "StrictHostKeyChecking no" root@$INSTANCE_IP "mkdir -p $VOLUME_MOUNT"
|
||||
ssh -o "StrictHostKeyChecking no" root@$INSTANCE_IP "mount $VOLUME_DEVICE $VOLUME_MOUNT"
|
||||
# Mount on every boot, without duplicating the line on re-runs.
|
||||
ssh -o "StrictHostKeyChecking no" root@$INSTANCE_IP "grep -q '$VOLUME_DEVICE' /etc/fstab || echo '$VOLUME_DEVICE $VOLUME_MOUNT ext4 defaults,noatime,nofail 0 2' >> /etc/fstab"
|
||||
# END SSH CONFIG BLOCK
|
||||
|
||||
echo "$(date -Iminutes) --- Id:$INSTANCE_ID --- IP:$INSTANCE_IP Summoned $LINODE_LABEL with volume $VOLUME_ID." >>$LOGFILE
|
||||
echo "Started with root pass $ROOT_PASS"
|
||||
|
||||
@@ -125,7 +143,7 @@ if [[ "$SCRIPT_ACTION" == "x" ]]; then
|
||||
|
||||
if [[ "$REMOTE_ACTION" == "" ]]; then
|
||||
echo "Connecting: $INSTANCE_IP"
|
||||
ssh root@$INSTANCE_IP
|
||||
ssh -o "StrictHostKeyChecking no" root@$INSTANCE_IP
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
# Valheim Volume StackScript
|
||||
|
||||
A Linode StackScript that mounts the pre-existing Valheim volume on first boot.
|
||||
Running it as a StackScript means the mount happens as root during deployment,
|
||||
so no SSH session (and therefore no SSH key) is needed to configure it.
|
||||
|
||||
This mirrors the steps in `voldirections.txt`. The filesystem (`mkfs.ext4`) is
|
||||
**not** created here, because that step has already been completed on the
|
||||
volume; the script only creates the mountpoint, mounts the device, and adds the
|
||||
`/etc/fstab` entry.
|
||||
|
||||
## Instructions
|
||||
|
||||
1. Log in to the Linode Cloud Manager and open **StackScripts**.
|
||||
2. Click **Create StackScript**.
|
||||
3. Set **Label** to something like `valheim-volume-mount` and choose
|
||||
**Debian 13** (or "Any") as the **Target Images**.
|
||||
4. Paste the code block below into the **Script** editor.
|
||||
5. Leave the **UDF** (User Defined Fields) section empty — the values are
|
||||
hard-coded, so nothing needs to be entered at deploy time.
|
||||
6. Click **Save**. The numeric ID of the StackScript appears in the URL and in
|
||||
the StackScript list; copy it.
|
||||
7. Put that ID in `create-linode.sh` as the `STACKSCRIPT_ID` value near the top
|
||||
of the file.
|
||||
|
||||
After that, `create-linode.sh c <label>` passes the StackScript on the create
|
||||
call and the volume is mounted automatically on first boot.
|
||||
|
||||
## StackScript
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Linode StackScript: mount the pre-existing Valheim volume on first boot.
|
||||
# Runs as root during deployment; no SSH access required.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# The volume already has an ext4 filesystem (see voldirections.txt), so only
|
||||
# the mountpoint, the mount, and the fstab entry are handled here.
|
||||
VOLUME_NAME="ValVol202609"
|
||||
VOLUME_DEVICE="/dev/disk/by-id/scsi-0Linode_Volume_${VOLUME_NAME}"
|
||||
VOLUME_MOUNT="/mnt/${VOLUME_NAME}"
|
||||
|
||||
# The volume is attached by the API after deployment starts, so wait for the
|
||||
# device to show up before trying to mount it.
|
||||
for _ in $(seq 1 30); do
|
||||
[ -e "$VOLUME_DEVICE" ] && break
|
||||
sleep 5
|
||||
done
|
||||
|
||||
if [ ! -e "$VOLUME_DEVICE" ]; then
|
||||
echo "Volume device ${VOLUME_DEVICE} did not appear; skipping mount." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$VOLUME_MOUNT"
|
||||
mount "$VOLUME_DEVICE" "$VOLUME_MOUNT"
|
||||
|
||||
# Mount on every boot, without duplicating the line on re-runs.
|
||||
grep -q "$VOLUME_DEVICE" /etc/fstab || \
|
||||
echo "${VOLUME_DEVICE} ${VOLUME_MOUNT} ext4 defaults,noatime,nofail 0 2" >> /etc/fstab
|
||||
|
||||
echo "Mounted ${VOLUME_DEVICE} at ${VOLUME_MOUNT}."
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user