Skip to content

Instantly share code, notes, and snippets.

@MrDOS
Created February 1, 2020 02:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MrDOS/ed0a3da854d2a51568543bafa56f682f to your computer and use it in GitHub Desktop.
Save MrDOS/ed0a3da854d2a51568543bafa56f682f to your computer and use it in GitHub Desktop.
#! /bin/sh
# Configure an Ubuntu system for running Space Engineers. Flagrantly untested.
# Seriously, I haven't even run this once.
# TODO: Report progress to the web UI.
# TODO: Error checking/early failure.
# User data should contain:
#
# AWS_ACCESS_KEY_ID: The access key ID,
# AWS_SECRET_ACCESS_KEY: secret,
# AWS_REGION: and AWS region for configuration of the AWS CLI.
# GAME_EBS_VOLUME: The EBS volume which stores the game data.
eval $(ec2metadata --user-data)
if [ -z "$AWS_ACCESS_KEY_ID" ] \
|| [ -z "$AWS_SECRET_ACCESS_KEY" ] \
|| [ -z "$AWS_REGION" ] \
|| [ -z "$GAME_EBS_VOLUME" ]
then
echo "$0: missing configuration in user data!" 1>&2
exit 1
fi
# The maximum amount of time for which the game can be idle (no logged-in
# players) before shutting down the server.
MAX_GAME_IDLE=$(expr 15 \* 60) # seconds
# How frequently to check the number of logged-in players, and whether or not
# our instance is about to be interrupted.
CHECK_INTERVAL=5 # seconds
# The Linux distribution we're running on...
DISTRO="$(lsb_release --id | cut -d ':' -f 2 | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')"
# ...and the codename of the release version.
RELEASE="$(lsb_release --codename | cut -d ':' -f 2 | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')"
# These are used to ensure we pull in the appropriate build of Wine.
# Tell APT where to get the newest upstream Wine build.
dpkg --add-architecture i386
wget -nc https://dl.winehq.org/wine-builds/winehq.key
apt-key add winehq.key
apt-add-repository "deb https://dl.winehq.org/wine-builds/$DISTRO/ $RELEASE main"
if [ "$DISTRO" == "ubuntu" ] && [ "$RELEASE" == "bionic" ]
then
# Required for `libfaudio0`.
add-apt-repository ppa:cybermax-dexter/sdl2-backport
fi
# Get the system up to date.
apt update
apt upgrade -y
# Steam prompts for license acceptance.
cat <<ACCEPT | debconf-set-selections
steam steam/license note ""
steam steam/question select "I AGREE"
ACCEPT
# xvfb/x11vnc aren't typically necessary, but are nice to have around in case
# you need to run winecfg.
apt install -y awscli \
steamcmd \
winehq-stable \
winetricks \
xvfb \
x11vnc
# Create a user to run the game. We need to match the UID/GID which match
# the contents of the data EBS volume attached below.
groupadd --gid 1001 spaceengineers
useradd --uid 1001 \
--gid 1001 \
--home-dir /home/spaceengineers \
--create-home \
--shell /bin/bash \
spaceengineers
# TODO: How do we securely get these environment variables into the instance?
# `ec2metadata --user-data`? https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
# specifically warns against using this mechanism for key injection.
# Another option would be to attach the volume via the AWS CLI from outside
# the EC2 instance. Then have this script sit at the while-loop waiting for the
# block device to show up.
aws configure set aws_access_key_id "$AWS_ACCESS_KEY_ID"
aws configure set aws_secret_access_key "$AWS_SECRET_ACCESS_KEY"
aws configure set region "$AWS_REGION"
# Game data (the game user's home directory) is stored in its own EBS volume.
# The last argument is supposed to be the attachment point, but this seems to
# be ignored. Not sure if this is because the EC2 instance type I was testing
# with pretends that EBS volumes are NVMe, or if this would happen everywhere.
# The attachment indicated by `aws ec2 describe-volumes --volume-id ...`
# incorrectly reports the same attachment point as asked for in the
# `attach-volume` invocation, so that's not helpful for determining the real
# attachment point.
aws ec2 attach-volume --instance-id $(ec2metadata --instance-id) \
--volume-id "$GAME_EBS_VOLUME" \
--device /dev/xvdf
while ! [ -e /dev/nvme1n1 ]
then
sleep 1
fi
# TODO: Diff the output of lsblk before/after running the `attach-volume` to
# confirm the EC2 volume attachment point.
mount /dev/nvme1n1 /home/spaceengineers
# Log in as the game user.
su spaceengineers
# Update Space Engineers.
# force_install_dir needs to be an absolute path; the shell will expand ~.
steamcmd +login anonymous \
+force_install_dir ~/spaceengineers \
+app_update 298740 validate \
+quit
# Launch Space Engineers. This assumes `wine64 winecfg` has already been used
# to seed a 64-bit Wine prefix, and `winetricks dotnet461` has been installed.
cd ~/spaceengineers/DedicatedServer64
wine64 SpaceEngineersDedicated.exe -console &
se_pid=$!
# TODO: Confirm successful game start.
sleep 60
# Switch login back to `ubuntu`.
exit
# Wait until we need to shut down.
last_game_activity=$(date +%s)
while true
do
# TODO: Poll VRAGE remote management API.
if true
then
last_game_activity=$(date +%s)
fi
# Has the game been idle for long enough to warrant termination?
now=$(date +%s)
if [ $(expr $now - $last_game_activity) -gt $MAX_GAME_IDLE ]
then
break
fi
# Does EC2 want to interrupt us?
if [ "$(ec2metadata --instance-action)" != "none" ]
then
break
fi
sleep $CHECK_INTERVAL
done
# Wait for the SE server to terminate.
kill $se_pid
while kill -0 $se_pid
do
sleep 1
done
# Shutdown should cleanly shut down everything and unmount the data EBS volume.
systemctl shutdown
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment