Skip to content

Commit

Permalink
Added experimental fully automatic updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Dids committed Jun 23, 2016
1 parent 637884f commit f6567eb
Show file tree
Hide file tree
Showing 15 changed files with 203 additions and 66 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
sample.txt
node_modules
scheduler_app/node_modules
shutdown_app/node_modules
restart_app/node_modules
*.log
rust_data
.DS_Store
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
sample.txt
rust_data/
scheduler_app/node_modules/
restart_app/node_modules/
shutdown_app/node_modules/

# Docker project generated files to ignore
Expand Down
21 changes: 20 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,29 @@ ADD install.txt /install.txt
# Copy the Rust startup script
ADD start_rust.sh /start.sh

# Setup proper shutdown support
# Copy the Rust update check script
ADD update_check.sh /update_check.sh

# Install NodeJS (see below)
RUN curl -sL https://deb.nodesource.com/setup_5.x | bash -
RUN apt-get install -y nodejs

# Setup proper shutdown support
ADD shutdown_app/ /shutdown_app/
WORKDIR /shutdown_app
RUN npm install

# Setup restart support (for update automation)
ADD restart_app/ /restart_app/
WORKDIR /restart_app
RUN npm install

# Setup scheduling support
ADD scheduler_app/ /scheduler_app/
WORKDIR /scheduler_app
RUN npm install

# Set the current working directory
WORKDIR /

# Expose necessary ports
Expand All @@ -75,6 +92,8 @@ ENV RUST_RCON_PORT "28016"
ENV RUST_RCON_PASSWORD "docker"
ENV RUST_RESPAWN_ON_RESTART "0"
ENV RUST_DISABLE_AUTO_UPDATE "0"
ENV RUST_UPDATE_CHECKING "0"
ENV RUST_UPDATE_BRANCH "public"

# Start the server
ENTRYPOINT ["./start.sh"]
3 changes: 0 additions & 3 deletions docker_build.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#!/bin/bash

# Set Docker to use the machine
eval "$(docker-machine env default)"

docker build -t didstopia/rust-server:latest .
3 changes: 0 additions & 3 deletions docker_build_force.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#!/bin/bash

# Set Docker to use the machine
eval "$(docker-machine env default)"

docker build --no-cache -t didstopia/rust-server:latest .
6 changes: 0 additions & 6 deletions docker_commit.sh

This file was deleted.

5 changes: 1 addition & 4 deletions docker_push.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
#!/bin/bash

# Set Docker to use the machine
eval "$(docker-machine env default)"

docker tag -f didstopia/rust-server:latest didstopia/rust-server:latest
docker tag didstopia/rust-server:latest didstopia/rust-server:latest
docker push didstopia/rust-server:latest
5 changes: 2 additions & 3 deletions docker_run.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#!/bin/bash

# Set Docker to use the machine
eval "$(docker-machine env default)"
./docker_build.sh

# Run the server
docker run -p 28015:28015 -p 28016:28016 -p 8080:8080 -m 4g -v $(pwd)/rust_data:/steamcmd/rust -e RUST_RESPAWN_ON_RESTART=1 --name rust-server -d didstopia/rust-server:latest
docker run -p 28015:28015 -p 28016:28016 -p 8080:8080 -m 4g -v $(pwd)/rust_data:/steamcmd/rust -e RUST_RESPAWN_ON_RESTART=1 -e RUST_UPDATE_CHECKING=1 -e RUST_UPDATE_BRANCH="prerelease" --name rust-server -d didstopia/rust-server:latest
docker logs -f rust-server
38 changes: 38 additions & 0 deletions restart_app/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env node

var serverHostname = 'localhost';
var serverPort = process.env.RUST_RCON_PORT;
var serverPassword = process.env.RUST_RCON_PASSWORD;

var WebSocket = require('ws');
var ws = new WebSocket("ws://" + serverHostname + ":" + serverPort + "/" + serverPassword);
ws.on('open', function open()
{
setTimeout(function()
{
ws.send(createPacket("say NOTICE: We're updating the server, get to a safe spot!"));
setTimeout(function()
{
ws.send(createPacket("restart 60"));
setTimeout(function()
{
ws.close(1000);
}, 1000);
}, 1000 * 60);
}, 1000);
});
ws.on('close', function close()
{
process.exit(0);
});

function createPacket(command)
{
var packet =
{
Identifier: -1,
Message: command,
Name: "WebRcon"
};
return JSON.stringify(packet);
}
14 changes: 14 additions & 0 deletions restart_app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "restart_app",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "nodejs app.js"
},
"author": "",
"private": "true",
"dependencies": {
"ws": "^1.1.0"
}
}
33 changes: 33 additions & 0 deletions scheduler_app/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env node

var debug = false;

var child_process = require('child_process');

var startupDelayInSeconds = 60 * 5; // TODO: Set to 5 minutes
var runIntervalInSeconds = 60 * 15; // TODO: Set to 15 minutes

if (debug)
{
startupDelayInSeconds = 1;
runIntervalInSeconds = 60;
}

// Start the endless loop after a delay (allow the server to start)
setTimeout(function()
{
checkForUpdates();
}, 1000 * startupDelayInSeconds);

function checkForUpdates()
{
setTimeout(function()
{
if (debug) console.log("Scheduled update triggered");
child_process.exec('bash /update_check.sh', { timeout: 60 * 1000, env: process.env }, function (err, stdout, stderr)
{
if (debug) console.log(stdout);
checkForUpdates();
});
}, 1000 * runIntervalInSeconds);
}
11 changes: 11 additions & 0 deletions scheduler_app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "scheduler_app",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "nodejs app.js"
},
"author": "",
"private": "true",
}
21 changes: 21 additions & 0 deletions start_rust.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ else
# Install/update Rust from install.txt
echo "Installing/updating Rust.."
bash /steamcmd/steamcmd.sh +runscript /install.txt

# Run the update check if it's not been run before
if [ ! -f "/steamcmd/rust/build.id" ]; then
./update_check.sh
else
OLD_BUILDID="$(cat /steamcmd/rust/build.id)"
STRING_SIZE=${#OLD_BUILDID}
if [ "$STRING_SIZE" -lt "6" ]; then
./update_check.sh
fi
fi
fi

# Check if this is actually a modded server
Expand Down Expand Up @@ -108,6 +119,16 @@ if [ -f "/steamcmd/rust/seed_override" ]; then
fi
fi

# Use an intermediary file to pass env vars to cron
if [ -f "/root/.profile" ]; then
rm -fr /root/.profile
fi
env |sed 's/^\(.*\)$/export \1/g' >/root/.profile

# Start cron
echo "Starting scheduled task manager.."
node /scheduler_app/app.js &

# Set the working directory
cd /steamcmd/rust

Expand Down
46 changes: 0 additions & 46 deletions steamcmd_parser.py

This file was deleted.

59 changes: 59 additions & 0 deletions update_check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash

set -m

# Check if we are auto-updating or not
if [ "$RUST_UPDATE_CHECKING" = "1" ]; then
echo "Checking Steam for updates.."
else
## REMOVE THIS
echo "Updates disabled"
exit
fi

# Get the old build id (default to 0)
OLD_BUILDID=0
if [ -f "/steamcmd/rust/build.id" ]; then
OLD_BUILDID="$(cat /steamcmd/rust/build.id)"
fi

# Minimal validation for the update branch
STRING_SIZE=${#RUST_UPDATE_BRANCH}
if [ "$STRING_SIZE" -lt "1" ]; then
RUST_UPDATE_BRANCH=public
fi

# Get the new build id directly from Steam
NEW_BUILDID="$(./steamcmd/steamcmd.sh +login anonymous +app_info_update 1 +app_info_print "258550" +quit | grep -EA 1000 "^\s+\"branches\"$" | grep -EA 5 "^\s+\"$RUST_UPDATE_BRANCH\"$" | grep -m 1 -EB 10 "^\s+}$" | grep -E "^\s+\"buildid\"\s+" | tr '[:blank:]"' ' ' | tr -s ' ' | sed "s/ buildid //g" | xargs)"

# Check that we actually got a new build id
STRING_SIZE=${#NEW_BUILDID}
if [ "$STRING_SIZE" -lt "6" ]; then
echo "Error getting latest build id from Steam, automatic updates disabled.."
exit
fi

# Skip update checking if this is the first time
if [ ! -f "/steamcmd/rust/build.id" ]; then
echo "First time running update check (build id not found), skipping update.."
echo $NEW_BUILDID > /steamcmd/rust/build.id
exit
else
STRING_SIZE=${#OLD_BUILDID}
if [ "$STRING_SIZE" -lt "6" ]; then
echo "First time running update check (build id empty), skipping update.."
echo $NEW_BUILDID > /steamcmd/rust/build.id
exit
fi
fi

# Check if the builds match and quit if so
if [ "$OLD_BUILDID" = "$NEW_BUILDID" ]; then
echo "Build id $OLD_BUILDID is already the latest, skipping update.."
exit
else
echo "Latest build id ($NEW_BUILDID) is newer than the current one ($OLD_BUILDID), restarting the server and forcing an update.."
echo $NEW_BUILDID > /steamcmd/rust/build.id
node /restart_app/app.js &
exit
fi

0 comments on commit f6567eb

Please sign in to comment.