#!/bin/bash

#  Node Kick Start
#  - Builds a node.js v0.6.5 server
#  - Installs all dependencies

#  MUST READ:
#  -------
#  This script assumes an ec2 preconfiguration which means a user "ubuntu" is already existing on the system
#  with a home dir of /home/ubuntu and this user is already added to the sudoers file. If you do not have
#  this user set up do a search of this file for "useradd" and uncomment to have this done for you.
#  -------

#  HOWTO:
#  -------
#  curl http:///lab.slajax.com/monetrix/install.sh > install.sh && chmod 755 install.sh
#  ./install.sh -s haproxy -r http://git.slajax.com/repos/monetrix.git -n projectname -e mail@slajax.com
#  -------

aflag=no
bflag=no
flist=""

usage() {
  echo "";
  echo "  Usage: $0 <options>";
  echo "    -- ";
  echo "    This kick start will compile an ubuntu server with node.js v0.6.5 and your choice of stack dependencies";
  echo "    If you provide a repo to install, it will install the repo, start it and attempt to execute tests.js or vows.js"
  echo "    If you do not provide a repo or proviide 'new' as the option a new expressjs repo will be built"
  echo "    -- ";
  echo "  Options:";
  echo "    -s  Server < haproxy || nginx >";
  echo "    -r  Repo < path/to/git-repo.git || new >";
  echo "    -n  Name < project name >";
  echo "    -e  Email < client email for monit alerts >";
  echo "";
  exit
}

prompt() {
	echo "";
	echo "[kickstart]: $1";
	echo "";
}

if [ "$#" -lt 4 ]
  then
    usage
fi

set -- $(getopt abfs:r:n:e: "$@")
while [ $# -gt 0 ]
do
    case "$1" in
    (-a) aflag=yes;;
    (-b) bflag=yes;;
    (-f) flist="$flist $2"; shift;;
    (-r) r="$r $2"; shift;;
    (-s) s="$s $2"; shift;;
    (-n) n="$n $2"; shift;;
    (-e) e="$e $2"; shift;;
    (--) shift; break;;
    (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;;
    (*)  break;;
    esac
    shift
done

prompt "updating build essentials";

sudo apt-get -y install build-essential;

# TODO: add an option for this (not neccessary for ec2 servers)
#sudo useradd -d /home/ubuntu/ -m ubuntu;
#sudo passwd ubuntu;
#sudo echo "ubuntu ALL=(ALL) ALL" >> /etc/sudoers;

# Update and install NodeJS
prompt "getting node dependencies";
sudo apt-get update;
sudo apt-get install -y g++ curl libssl-dev openssl apache2-utils pkg-config make;
sudo apt-get install -y git-core;

prompt "pulling node v0.4.9 from Joyent"; 

sudo git clone --depth 1 https://github.com/joyent/node.git;
cd node;
sudo git checkout v0.6.5;
sudo ./configure --prefix=/usr;
sudo make;
sudo make install;


##################################################

# Install NPM
prompt "installing node package manager";
sudo apt-get install libexpat1-dev
sudo curl http://npmjs.org/install.sh | sudo sh;

##################################################

# Setup git remote master

if [[ "$r" == ""  || "$r" == " new" ]]; then
  prompt "creating new project in /home/ubuntu/www";
  mkdir /home/ubuntu/www;
else
  prompt "copying repo $r to /home/ubuntu/www";
  git clone $r /home/ubuntu/www;
fi

cd /home/ubuntu/www
sudo npm install;
su ubuntu -c "sudo npm install -g vows";
su ubuntu -c "sudo npm install -g forever";
su ubuntu -c "sudo npm install -g dox";
  
prompt "creating repo and adding post hook for git push deployments";
mkdir /home/ubuntu/repo;
cd /home/ubuntu/repo;
git init --bare;

##################################################

# Create git hook
cat > /home/ubuntu/repo/hooks/post-receive << EOF
#!/bin/sh
GIT_WORK_TREE=/home/ubuntu/www
export GIT_WORK_TREE;
git checkout -f;
chmod 755 /home/ubuntu/www/start.sh;
chmod 755 /home/ubuntu/www/stop.sh;
cd /home/ubuntu/www/; ./stop.sh; ./start.sh prod;
EOF

chmod +x /home/ubuntu/repo/hooks/post-receive;

##################################################
# Install HAProxy

cd ~;

if [ "$s" == " haproxy" ]
	then 
		prompt "installing haproxy";
		wget http://haproxy.1wt.eu/download/1.5/src/devel/haproxy-1.5-dev6.tar.gz;
		tar xzf haproxy-1.5-dev6.tar.gz
		cd haproxy*;
		sudo make install;

		prompt "configuring haproxy"
		# HAProxy config
		mkdir /etc/haproxy;
		cat > /etc/haproxy/haproxy.cfg << EOF
		global
		  maxconn 4096

		defaults
		  mode http

		frontend all 0.0.0.0:80
		  timeout client 86400000
		  default_backend www_prod

		  acl is_dev hdr_dom(host) -i dev
		  acl is_websocket hdr(upgrade) -i websocket
		  acl is_websocket hdr_beg(host) -i ws

		  use_backend www_prod if is_websocket
		  use_backend www_dev if is_dev
  
		backend www_dev
		  option forwardfor
		  timeout server 86400000
		  timeout connect 4000
		  server dev 127.0.0.1:3000 weight 1 maxconn 10000 check

		backend www_prod
		  option forwardfor
		  timeout server 86400000
		  timeout connect 4000
		  server nodejs 127.0.0.1:4000 weight 1 maxconn 10000 check
EOF
		
		prompt "testing haproxy";
		# Test haproxy config
		sudo haproxy -c -f /etc/haproxy/haproxy.cfg
		prompt "starting haproxy";
		sudo haproxy -D -f /etc/haproxy/haproxy.cfg

fi

##################################################
# Install Nginx

if [ "$s" == " nginx" ]
	then
		prompt "installing nginx";
		sudo apt-get install -y nginx;
		cd /etc/nginx;
		sudo openssl req -new -x509 -nodes -out server.crt -keyout server.key;

		sudo cat > /etc/nginx/sites-available/default << EOF
		upstream nodejs {
	    server 127.0.0.1:4000;
		}

		server {
		  listen 0.0.0.0:80;
		  access_log /var/log/nginx/access.log;

		  location / {
		    proxy_set_header X-Real-IP $/remote_addr;
		    proxy_set_header X-Forwarded-For $/proxy_add_x_forwarded_for;
				proxy_set_header Host $/http_host;
		    proxy_set_header X-NginX-Proxy true;

		    proxy_pass http://nodejs/;
				proxy_redirect off;
		  }
		}

		server {
		  listen   443;
	    ssl    on;
			sl_certificate    /etc/ssl/certs/pledgeapp-purematters-com.crt;
		  ssl_certificate_key    /etc/ssl/certs/pledgeapp-purematters-com.key;

		  server_name your.domain.com;
		  access_log /var/log/nginx/nginx.vhost.access.log;
		  error_log /var/log/nginx/nginx.vhost.error.log;

		  location / {
        proxy_set_header X-Real-IP $/remote_addr;
        proxy_set_header X-Forwarded-For $/proxy_add_x_forwarded_for;
        proxy_set_header Host $/http_host;
        proxy_set_header X-NginX-Proxy true;

		    proxy_pass http://nodejs/;
		    proxy_redirect off;
		  }
		}

EOF
		sudo /etc/init.d/nginx restart;
fi

##################################################
# Install MongoDB
prompt "installing mongo";
wget http://fastdl.mongodb.org/linux/mongodb-linux-i686-2.0.2.tgz;
tar -xvzf mongodb-linux-*;
sudo cp -R mongodb-linux-*/bin/* /usr/bin/;
sudo mkdir -p /var/data/db;
sudo chown -R ubuntu.ubuntu /var/data;
sudo touch /var/log/mongo.log;
sudo chown ubuntu.ubuntu /var/log/mongo.log;

##################################################
# Installing Monit

prompt "setting up monit"
sudo apt-get install monit;
sudo mkdir /etc/monit.d/;
sudo sed -i 's/startup=0/startup=1/' /etc/default/monit;
sudo sed -i 's/# set daemon  120/set daemon 120/' /etc/monit/monitrc
sudo sed -i 's/#  include/include/' /etc/monit/monitrc

sudo cat >> /etc/monit/monitrc << EOF
set logfile /var/log/monit.log
set alert mail@slajax.com
set alert$e
set mailserver mail.slajax.com port 25
    username "relay+slajax.com" password "r3l4y" localhost
    with timeout 15 seconds
set mail-format {
    from:     monit@$n
    subject:  [monit][%ACTION]:$n %SERVICE - %EVENT
    message:  Dear Admin,

    On %DATE on$n the %SERVICE %EVENT.

Your faithful servant,
monit
}
EOF
sudo sed -i 's/@ /@/g' /etc/monit/monitrc;
sudo sed -i 's/%/$/g' /etc/monit/monitrc;

sudo cat > /etc/monit.d/mongod << EOF
#!monit
check host mongod with address localhost
    start program = "/usr/bin/sudo -u ubuntu /etc/monit/mongo-start.sh"
    stop program = "/usr/bin/sudo -u /usr/bin/pkill -f mongod"
    if failed port 28017 protocol HTTP
        request /
        with timeout 10 seconds
        then start

EOF

# mongo-start.sh
sudo cat > /etc/monit/mongo-start.sh << EOF
#!/bin/bash

if [ -f /var/data/db/mongod.lock ]
  then
    /usr/bin/sudo -u ubuntu rm /var/data/db/mongod.lock;
fi

/usr/bin/sudo -u ubuntu /usr/bin/mongod --auth --fork --logpath /home/ubuntu/mongodb.log --logappend;
EOF

sudo chmod 755 /etc/monit/mongo-start.sh;

if [ "$s" == " haproxy" ]
	then 
		sudo cat > /etc/monit.d/haproxy << EOF
#!monit
check host haproxy with address localhost
    start program = "/usr/bin/sudo haproxy -D -f /etc/haproxy/haproxy.cfg"
    stop program = "/usr/bin/sudo /usr/bin/pkill -f haproxy"
    if failed port 80 protocol HTTP
        request /
        with timeout 10 seconds
        then start

EOF
fi

if [ "$s" == " nginx" ]
  then
    sudo cat > /etc/monit.d/nginx << EOF
#!monit
check host nginx with address localhost
    start program = "/usr/bin/sudo /etc/init.d/nginx restart"
    stop program = "/usr/bin/sudo /etc/init.d/nginx stop"
    if failed port 80 protocol HTTP
        request /
        with timeout 10 seconds
        then start

EOF
fi

sudo /etc/init.d/monit restart;



#############################################
# Cleaning up

sleep 3;
prompt "cleaning up";
sudo chown -R ubuntu.ubuntu /home/ubuntu/*;
sudo rm -Rf /home/ubuntu/haproxy* /home/ubuntu/mongodb-* /home/ubuntu/node install.sh;

sleep 3;
prompt "starting server";

cd /home/ubuntu/www;
chmod 755 start.sh stop.sh;
su ubuntu -c "./start.sh";
sleep 5;

if [ -f "vows.js" ]
then
	prompt "running tests... ";
  cd /home/ubuntu/www;
  vows --spec vows.js;
fi

if [ -f "tests.js" ]
then
	prompt "running tests...";
  cd /home/ubuntu/www;
  vows --spec tests.js;
fi

prompt "Done Installing";


