Files
valheim-linode/create-linode.sh
T
2026-09-20 21:44:49 -07:00

167 lines
6.3 KiB
Bash
Executable File

#!/bin/bash
# For my use, debian for the little one, ubuntu for the big ones
# From .env, following values:
# LINODE_API_KEY (used for all Linode API calls below, via curl)
# WHICH_DOMAIN
# ROOT_PASS
source .env
# All Linode API requests use the API key sourced from .env above:
# curl -H "Authorization: Bearer $LINODE_API_KEY" https://api.linode.com/v4/...
#ROOT_PASS=$(for w in {1..3}; do echo -n $(cat /usr/share/dict/words | grep -v "'" | sed -n $(echo "$(cat /usr/share/dict/words | grep -v "'" | wc -l) * $RANDOM / 32768 + 1" | bc)p); done)
#ROOT_PASS="StartRootPass5678"
SCRIPT_ACTION=$1
LINODE_LABEL=$2
# oily 2111036
WHICH_DOMAIN="2111036"
LOGFILE="./linodes.log"
# Pre-existing Valheim volume, attached to every Linode at creation time.
# The filesystem (mkfs.ext4) was already created; see voldirections.txt.
VOLUME_ID="18073448"
VOLUME_NAME="ValVol202609"
VOLUME_DEVICE="/dev/disk/by-id/scsi-0Linode_Volume_$VOLUME_NAME"
VOLUME_MOUNT="/mnt/$VOLUME_NAME"
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>"
echo " (fixed size: 8GB shared, newest Debian image;"
echo " attaches and mounts volume $VOLUME_NAME)"
echo "Destroy: create-linode.sh d <label>"
echo "Connect: create-linode.sh x <label>"
echo " create-linode.sh x <label> get <remote source> <local dest>"
echo " create-linode.sh x <label> put <local source> <remote dest>"
echo "Update record: create-linode.sh a <label> <subdomain>"
echo "List: create-linode.sh l"
echo " (lists all Linodes, no label needed)"
fi
# Create
if [[ "$SCRIPT_ACTION" == "c" ]]; then
# Fixed size: 8GB shared, newest Debian image
INSTANCE_SIZE="g6-standard-4"
INSTANCE_IMAGE="linode/debian13"
curl -s -H "Content-Type: application/json" \
-H "Authorization: Bearer $LINODE_API_KEY" \
-X POST -d '{
"label": "'$LINODE_LABEL'",
"region": "us-central",
"type": "'$INSTANCE_SIZE'",
"image": "'$INSTANCE_IMAGE'",
"root_pass": "'$ROOT_PASS'",
"authorized_users": ["ni7ne_midpriv"]
}' \
https://api.linode.com/v4/linode/instances | jq .
sleep 60
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"
echo "Instance ID: $INSTANCE_ID"
# Attach the pre-existing Valheim volume (see voldirections.txt).
# The volume must be attached to a running Linode; the image boots on create.
curl -s -H "Content-Type: application/json" \
-H "Authorization: Bearer $LINODE_API_KEY" \
-X POST -d '{
"linode_id": '$INSTANCE_ID',
"persist_across_boots": true
}' \
https://api.linode.com/v4/volumes/$VOLUME_ID/attach | jq .
# Give the volume a moment to appear on the instance before mounting 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"
fi
# List
if [[ "$SCRIPT_ACTION" == "l" ]]; then
curl -s -H "Authorization: Bearer $LINODE_API_KEY" \
https://api.linode.com/v4/linode/instances | jq .
fi
# Destroy
if [[ "$SCRIPT_ACTION" == "d" ]]; then
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 "Destroying ID:$INSTANCE_ID Hit Ctrl-C in the next 10 seconds to cancel."
sleep 15
curl -s -H "Authorization: Bearer $LINODE_API_KEY" \
-X DELETE https://api.linode.com/v4/linode/instances/$INSTANCE_ID
echo "$(date -Iminutes) --- Id:$INSTANCE_ID --- IP:$INSTANCE_IP Destroyed $LINODE_LABEL." >>$LOGFILE
fi
# Connect
if [[ "$SCRIPT_ACTION" == "x" ]]; then
REMOTE_ACTION=$3
SCP_SOURCE=$4
SCP_DEST=$5
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")
if [[ "$REMOTE_ACTION" == "get" ]]; then
echo "get </~/source> <localdest>"
scp $INSTANCE_IP:/home/finn/$SCP_SOURCE $SCP_DEST
fi
if [[ "$REMOTE_ACTION" == "put" ]]; then
echo "put <localsource> </~/dest>"
scp $SCP_SOURCE $INSTANCE_IP:/home/finn/$SCP_DEST
fi
if [[ "$REMOTE_ACTION" == "" ]]; then
echo "Connecting: $INSTANCE_IP"
ssh root@$INSTANCE_IP
fi
fi
# Update record
if [[ "$SCRIPT_ACTION" == "a" ]]; then
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")
NI_SUBDOMAIN=$3
echo "Previous value:"
curl -s -H "Authorization: Bearer $LINODE_API_KEY" \
https://api.linode.com/v4/domains/$WHICH_DOMAIN/records | jq .
sleep 3
echo "Updating records with ip $INSTANCE_IP..."
#ni7ne:
curl -s -H "Content-Type: application/json" \
-H "Authorization: Bearer $LINODE_API_KEY" \
-X POST -d '{
"type": "A",
"name": "'$NI_SUBDOMAIN'",
"target": "'$INSTANCE_IP'",
"priority": 0,
"weight": 0,
"port": 0,
"service": null,
"protocol": null,
"ttl_sec": 14400,
"tag": null
}' \
https://api.linode.com/v4/domains/$WHICH_DOMAIN/records | jq .
echo "Update complete."
fi