Created
February 1, 2020 02:51
-
-
Save MrDOS/ed0a3da854d2a51568543bafa56f682f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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