From e35570cf48b747cf45b95180b1f1ed09693a4afd Mon Sep 17 00:00:00 2001 From: Waleed Khan Date: Tue, 15 Dec 2015 20:07:54 -0500 Subject: [PATCH] Add Vagrant support for development --- .gitignore | 1 + Vagrantfile | 50 +++++++++ bin/build-deps.sh | 7 +- bin/provision-vagrant.sh | 221 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 276 insertions(+), 3 deletions(-) create mode 100644 Vagrantfile create mode 100755 bin/provision-vagrant.sh diff --git a/.gitignore b/.gitignore index 23f2059e5d..b07a3d1f5b 100644 --- a/.gitignore +++ b/.gitignore @@ -17,5 +17,6 @@ data/ dist/ node_modules/ local/ +.vagrant RUNNING_PID diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 0000000000..4defbfefdc --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,50 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : +Vagrant.configure(2) do |config| + config.vm.box = "ubuntu/vivid64" + + # Use this script to set up and compile the Lila installation. We set + # `privileged` to `false` because otherwise the provisioning script will run + # as root. This isn't a problem to install packages globally (`apt-get + # install`), but `sbt publish-local` will publish to `root`'s home directory! + # Then we would not be able to use those packages when logged in as + # `vagrant`. + config.vm.provision "shell", path: "bin/provision-vagrant.sh", privileged: false + + # IP address to use to connect to the virtual machine. This should be an + # entry in your hosts file. We use a static IP so that the developer doesn't + # have to keep adding new entries to their hosts file. + config.vm.network "private_network", ip: "192.168.34.34" + + # From https://stefanwrobel.com/how-to-make-vagrant-performance-not-suck. You + # may want to set `cpus` and `mem` yourself. + config.vm.provider "virtualbox" do |v| + host = RbConfig::CONFIG['host_os'] + + # Fraction of memory of host OS to allocate to VM. More is better! + memory_fraction = 0.5 + + # Give VM allocated system memory & access to all cpu cores on the host + if host =~ /darwin/ + cpus = `sysctl -n hw.ncpu`.to_i + # sysctl returns Bytes and we need to convert to MB + mem = `sysctl -n hw.memsize`.to_i / 1024 / 1024 + elsif host =~ /linux/ + cpus = `nproc`.to_i + # meminfo shows KB and we need to convert to MB + mem = `grep 'MemTotal' /proc/meminfo | sed -e 's/MemTotal://' -e 's/ kB//'`.to_i / 1024 + else # sorry Windows folks, I can't help you + cpus = 2 + mem = 4096 + end + + mem *= memory_fraction + mem = mem.to_i + + # Needed to use multiple CPUs. + v.customize ["modifyvm", :id, "--ioapic", "on"] + + v.customize ["modifyvm", :id, "--cpus", cpus] + v.customize ["modifyvm", :id, "--memory", mem] + end +end diff --git a/bin/build-deps.sh b/bin/build-deps.sh index 683c40bce3..94599737b1 100755 --- a/bin/build-deps.sh +++ b/bin/build-deps.sh @@ -1,8 +1,9 @@ #!/bin/sh +set -e -dir=`mktemp -d` +dir=$(mktemp -d) echo "Building in $dir" -cd $dir +cd "$dir" rm -rf scalalib git clone https://github.com/ornicar/scalalib @@ -28,4 +29,4 @@ cd maxmind-geoip2-scala sbt publish-local cd .. -rm -rf $dir +rm -rf "$dir" diff --git a/bin/provision-vagrant.sh b/bin/provision-vagrant.sh new file mode 100755 index 0000000000..3131ce082e --- /dev/null +++ b/bin/provision-vagrant.sh @@ -0,0 +1,221 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +# We add environment variables to these files. +readonly PROFILES=("$HOME/.bash_profile" "$HOME/.bashrc") + +# Directory containing the lila source code. +readonly LILA_DIR='/vagrant' + +# The HTTP port to listen on. +readonly PORT=9663 + +# List of packages to install with apt. +readonly DEPENDENCIES=( + git + sbt + npm + zsh + + mongodb + nginx + + gcc + make + closure-compiler + openjdk-8-jdk +) + +error() { + echo >>/dev/stderr "ERROR: $*" +} + +info() { + echo "INFO: $*" +} + +setup_application_config() { + cat >"$LILA_DIR/conf/application.conf" <<'CONF' +include "base" + +net { + domain = "l.org" + asset.domain = "en.l.org" + extra_ports = [] +} + +ai { + hash_size = 128 + threads = 1 + instances = 4 + debug = false + play { + movetime = 500 ms + } + analyse { + movetime = 2000 ms + } +} + +geoip { + file = "data/GeoLite2-City.mmdb" +} +CONF +} + +# Set compilation options so that we don't run out of memory. +setup_environment_variables() { + for i in "${PROFILES[@]}"; do + echo >>"$i" "export JAVA_OPTS='-Xms64M -Xmx3072M -Xss4M -XX:ReservedCodeCacheSize=64m -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC'" + done + + . -- "${PROFILES[0]}" +} + +# For sbt: http://www.scala-sbt.org/release/tutorial/Installing-sbt-on-Linux.html +update_apt() { + echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list + sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823 + + sudo apt-get update +} + +install_dependencies() { + sudo apt-get install -y -- "${DEPENDENCIES[@]}" + + # `npm` relies on a `node` executable, but we have `nodejs`. + # https://github.com/joyent/node/issues/3911 + sudo ln -sf '/usr/bin/nodejs' '/usr/bin/node' + + # Installed `npm` is too old, upgrade it. + sudo npm update -g + sudo npm install -g npm + + sudo npm install -g gulp +} + +setup_nginx() { + local nginx_conf + nginx_conf=$(mktemp) + + sed "s#LILA_DIR#$LILA_DIR#g" >"$nginx_conf" <<'CONF' +server { + listen 80; + + server_name l.org ~^\w\w\.l\.org$; + + error_log /var/log/nginx/lila.error.log; + access_log /var/log/nginx/lila.access.log; + + charset utf-8; + + location /assets { + alias LILA_DIR/public; + } + + location / { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_read_timeout 90s; + proxy_pass http://127.0.0.1:9663/; + } + + location /ai/ { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_pass http://127.0.0.1:9663/ai/; + } + + error_page 500 501 502 503 /oops/servererror.html; + error_page 504 /oops/timeout.html; + error_page 429 /oops/toomanyrequests.html; + location /oops/ { + root LILA_DIR/public/; + } + location = /robots.txt { + root LILA_DIR/public/; + } + +} + +server { + listen 80; + server_name ~^socket\.\w\w\.l\.org$; + charset utf-8; + location / { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_pass http://127.0.0.1:9663/; + } +} +CONF + + sudo mv -- "$nginx_conf" '/etc/nginx/sites-available/default' + sudo nginx -s reload +} + +setup_mongodb() { + # Default MongoDB database path. `mongod` will fail to launch if this + # doesn't exist. + sudo mkdir -p /data/db + + sudo service mongodb start +} + +build_lila() { + cd -- "$LILA_DIR" + git submodule update --init --recursive + + ./ui/build & + ./bin/install-stockfish & + ./bin/gen/geoip & + ./bin/build-deps.sh & + wait + + sbt compile +} + +get_ip_address() { + ifconfig eth1 | grep 'inet addr' | cut -d':' -f2 | cut -d' ' -f1 +} + +main() { + setup_application_config + setup_environment_variables + + update_apt + install_dependencies + setup_nginx + setup_mongodb + build_lila + + local ip_address + ip_address=$(get_ip_address) + + info 'Lila is all set up! Add this entry entry to your hosts file on your' + info 'host machine (not the virtual machine, or else I would have done it' + info 'for you):' + info + info " $ip_address l.org en.l.org de.l.org le.l.org fr.l.org es.l.org l1.org socket.en.l.org socket.le.l.org socket.fr.l.org ru.l.org el.l.org hu.l.org socket.hu.l.org" + info + info 'Then run "vagrant ssh" and carry out these steps inside your SSH' + info 'connection:' + info + info ' 1. cd /vagrant' + info " 2. sbt run -Dhttp.port=$PORT" + info " 3. Leave 'sbt run' running inside your virtual machine and visit" + info " http://en.l.org on your host machine. It won't load. This is" + info ' expected.' + info ' 4. Wait until sbt run has finished launching. (After it has' + info ' finished, relevant output will be printed. If the most recent' + info ' message is' + info + info ' (Server started, use Ctrl+D to stop and go back to the console...)' + info + info ' then you have not waited long enough.)' + info ' 5. Visit http://en.l.org again. It should load now.' +} + +main