Browse Source

A bunch of fixes for the installer, including making it idempotent-ish to allow resuming upon failure

Jamie Furness 11 years ago
parent
commit
cee334e83b

+ 7 - 2
config/benchmark_profile

@@ -1,3 +1,5 @@
+# Start Benchmark profile
+
 export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64
 export RESIN_HOME=~/FrameworkBenchmarks/installs/resin-4.0.36
 export GRAILS_HOME=~/FrameworkBenchmarks/installs/grails-2.3.3
@@ -20,10 +22,13 @@ export PATH="$PYTHON_HOME/bin:$PATH$JAVA_HOME/bin:$GRAILS_HOME/bin:$PLAY_HOME:$P
 
 export LD_LIBRARY_PATH='$LD_LIBRARY_PATH:/usr/local/apr/lib'
 
-export TFB_SERVER_HOST=172.16.98.122'
+export TFB_SERVER_HOST='172.16.98.122'
 export TFB_CLIENT_HOST='172.16.98.98'
 export TFB_CLIENT_USER='tfb'
 export TFB_CLIENT_IDENTITY_FILE='/home/tfb/.ssh/id_rsa-tfb-1'
 export TFB_DATABASE_HOST='172.16.98.118'
 
-source ~/.rvm/scripts/'rvm'
+export LC_ALL='en_US.UTF-8'
+
+export NUMCPUS=`grep -c '^processor' /proc/cpuinfo`
+export MAKEFLAGS="-j $NUMCPUS -l $NUMCPUS"

+ 0 - 7
config/erlang.list

@@ -1,8 +1 @@
-deb http://binaries.erlang-solutions.com/debian quantal contrib
 deb http://binaries.erlang-solutions.com/debian precise contrib
-deb http://binaries.erlang-solutions.com/debian oneiric contrib
-deb http://binaries.erlang-solutions.com/debian natty contrib
-deb http://binaries.erlang-solutions.com/debian maverick contrib
-deb http://binaries.erlang-solutions.com/debian lucid contrib
-
-deb http://binaries.erlang-solutions.com/debian squeeze contrib

+ 33 - 24
toolset/deployment/azure/azure-deployment.sh

@@ -43,6 +43,7 @@ function azure_check_configuration {
 function azure_set_variables {
     # Set variables used in several steps.
     AZURE_LINUX_USER="ubuntu"
+    AZURE_WINDOWS_USER="windows"
     AZURE_SSH_DIR="$HOME/.ssh"
     AZURE_KEY_NAME="id_rsa-${AZURE_DEPLOYMENT_NAME}"
     AZURE_KEY_FILE="${AZURE_SSH_DIR}/${AZURE_KEY_NAME}"
@@ -58,6 +59,8 @@ function azure_set_variables {
     AZURE_CONFIGURATION_OUTPUT_FILE="$BENCHMARK_WORKING_DIR/deployment-configuration.sh"
     BENCHMARK_REPOSITORY=${BENCHMARK_REPOSITORY:-"https://github.com/TechEmpower/FrameworkBenchmarks.git"}
     BENCHMARK_BRANCH=${BENCHMARK_BRANCH:-"master"}
+    UBUNTU_IMAGE_VERSION="12_04"
+    UBUNTU_IMAGE_TEMPLATE="Ubuntu_DAILY_BUILD-precise-${UBUNTU_IMAGE_VERSION}.*-LTS-amd64-server"
 
     # Under CYGWIN this script uses a helper function to call the Windows Azure command line program.
     if iscygwin; then
@@ -100,17 +103,17 @@ function azure_create_common_resources {
     # Create affinity group.
     echo ""
     echo "Creating affinity group $AZURE_DEPLOYMENT_NAME at $AZURE_DEPLOYMENT_LOCATION"
-    $AZURE_COMMAND account affinity-group create $AZURE_DEPLOYMENT_NAME --location "$AZURE_DEPLOYMENT_LOCATION" || fail "Error creating affinity group $AZURE_DEPLOYMENT_NAME."
+    $AZURE_COMMAND account affinity-group show $AZURE_DEPLOYMENT_NAME || $AZURE_COMMAND account affinity-group create $AZURE_DEPLOYMENT_NAME --label $AZURE_DEPLOYMENT_NAME --location "$AZURE_DEPLOYMENT_LOCATION" || fail "Error creating affinity group $AZURE_DEPLOYMENT_NAME."
 
     # Create storage account.
     echo ""
     echo "Creating storage account $AZURE_DEPLOYMENT_NAME"
-    $AZURE_COMMAND account storage create $AZURE_DEPLOYMENT_NAME --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating storage account $AZURE_DEPLOYMENT_NAME."
+    $AZURE_COMMAND account storage show $AZURE_DEPLOYMENT_NAME || $AZURE_COMMAND account storage create $AZURE_DEPLOYMENT_NAME --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating storage account $AZURE_DEPLOYMENT_NAME."
 
     # Create virtual network.
     echo ""
     echo "Creating virtual network $AZURE_DEPLOYMENT_NAME"
-    $AZURE_COMMAND network vnet create $AZURE_DEPLOYMENT_NAME --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating virtual network $AZURE_DEPLOYMENT_NAME."
+    $AZURE_COMMAND network vnet show $AZURE_DEPLOYMENT_NAME || $AZURE_COMMAND network vnet create $AZURE_DEPLOYMENT_NAME --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating virtual network $AZURE_DEPLOYMENT_NAME."
 
     # Create directory for keys.
     echo ""
@@ -118,20 +121,26 @@ function azure_create_common_resources {
     mkdir -p ${AZURE_SSH_DIR} || fail "Error creating directory $AZURE_SSH_DIR."
 
     # Create key files.
-    echo "Creating key pair at $AZURE_KEY_FILE"
-    ssh-keygen -t rsa -b 2048 -f "$AZURE_KEY_FILE" -C "$AZURE_KEY_NAME" -q -N "" || fail "Error creating SSH key."
-    chmod 600 "$AZURE_KEY_FILE"
-    warning "-----------------------------------------------------------------------"
-    warning "Protect this key file. It has no passphrase and is stored in plaintext."
-    warning "-----------------------------------------------------------------------"
+    if [ ! -e "$AZURE_KEY_FILE" ]; then
+        echo "Creating key pair at $AZURE_KEY_FILE"
+        ssh-keygen -t rsa -b 2048 -f "$AZURE_KEY_FILE" -C "$AZURE_KEY_NAME" -q -N "" || fail "Error creating SSH key."
+        chmod 600 "$AZURE_KEY_FILE"
+        warning "-----------------------------------------------------------------------"
+        warning "Protect this key file. It has no passphrase and is stored in plaintext."
+        warning "-----------------------------------------------------------------------"
+    fi
 
-    echo "Creating PEM file at $AZURE_PEM_FILE"
-    openssl req -new -x509 -days 365 -subj "/CN=$AZURE_DEPLOYMENT_NAME/O=Web Framework Benchmarks" -key "$AZURE_KEY_FILE" -out "$AZURE_PEM_FILE" || fail "Error creating PEM file."
-    chmod 600 "$AZURE_PEM_FILE"
+    if [ ! -e "$AZURE_PEM_FILE" ]; then
+        echo "Creating PEM file at $AZURE_PEM_FILE"
+        openssl req -new -x509 -days 365 -subj "/CN=$AZURE_DEPLOYMENT_NAME/O=Web Framework Benchmarks" -key "$AZURE_KEY_FILE" -out "$AZURE_PEM_FILE" || fail "Error creating PEM file."
+        chmod 600 "$AZURE_PEM_FILE"
+    fi
 
-    echo "Creating CER file at $AZURE_CER_FILE"
-    openssl x509 -outform der -in "$AZURE_PEM_FILE" -out "$AZURE_CER_FILE" || fail "Error creating CER file."
-    chmod 600 "$AZURE_CER_FILE"
+    if [ ! -e "$AZURE_CER_FILE" ]; then
+        echo "Creating CER file at $AZURE_CER_FILE"
+        openssl x509 -outform der -in "$AZURE_PEM_FILE" -out "$AZURE_CER_FILE" || fail "Error creating CER file."
+        chmod 600 "$AZURE_CER_FILE"
+    fi
 
     echo ""
 }
@@ -144,18 +153,18 @@ function azure_create_vms {
     # Get latest Ubuntu Server 12.04 daily VM image.
     echo ""
     echo "Latest Ubuntu Server 12.04 image:"
-    LATEST_UBUNTU_IMAGE=$($AZURE_COMMAND vm image list | grep Ubuntu_DAILY_BUILD-precise-12_04_2-LTS-amd64-server | sort | tail -1 | cut -c 10-120)
+    LATEST_UBUNTU_IMAGE=$($AZURE_COMMAND vm image list | grep $UBUNTU_IMAGE_TEMPLATE | sort | tail -1 | cut -c 10-120)
     echo $LATEST_UBUNTU_IMAGE
 
     # Create client VM.
     echo ""
     echo "Creating client VM: $CLIENT_VM_NAME"
-    $AZURE_COMMAND vm create $CLIENT_VM_NAME $LATEST_UBUNTU_IMAGE $AZURE_LINUX_USER --ssh-cert "$AZURE_PEM_FILE" --no-ssh-password --vm-name $CLIENT_VM_NAME --vm-size $AZURE_DEPLOYMENT_VM_SIZE --virtual-network-name $AZURE_DEPLOYMENT_NAME --ssh --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating virtual machine $CLIENT_VM_NAME."
+    $AZURE_COMMAND vm list | grep $CLIENT_VM_NAME || $AZURE_COMMAND vm create $CLIENT_VM_NAME $LATEST_UBUNTU_IMAGE $AZURE_LINUX_USER --ssh-cert "$AZURE_PEM_FILE" --no-ssh-password --vm-name $CLIENT_VM_NAME --vm-size $AZURE_DEPLOYMENT_VM_SIZE --virtual-network-name $AZURE_DEPLOYMENT_NAME --ssh --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating virtual machine $CLIENT_VM_NAME."
 
     # Create Ubuntu server VM.
     echo ""
     echo "Creating Linux server VM: $LINUX_SERVER_VM_NAME"
-    $AZURE_COMMAND vm create $LINUX_SERVER_VM_NAME $LATEST_UBUNTU_IMAGE $AZURE_LINUX_USER --ssh-cert "$AZURE_PEM_FILE" --no-ssh-password --vm-name $LINUX_SERVER_VM_NAME --vm-size $AZURE_DEPLOYMENT_VM_SIZE --virtual-network-name $AZURE_DEPLOYMENT_NAME --ssh --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating virtual machine $LINUX_SERVER_VM_NAME."
+    $AZURE_COMMAND vm list | grep $LINUX_SERVER_VM_NAME || $AZURE_COMMAND vm create $LINUX_SERVER_VM_NAME $LATEST_UBUNTU_IMAGE $AZURE_LINUX_USER --ssh-cert "$AZURE_PEM_FILE" --no-ssh-password --vm-name $LINUX_SERVER_VM_NAME --vm-size $AZURE_DEPLOYMENT_VM_SIZE --virtual-network-name $AZURE_DEPLOYMENT_NAME --ssh --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating virtual machine $LINUX_SERVER_VM_NAME."
 
     # Get latest Windows Server 2012 Datacenter image.
     echo ""
@@ -166,7 +175,7 @@ function azure_create_vms {
     # Create Windows server VM.
     echo ""
     echo "Creating Windows server VM: $WINDOWS_SERVER_VM_NAME"
-    $AZURE_COMMAND vm create $WINDOWS_SERVER_VM_NAME $LATEST_WINDOWS_IMAGE Administrator $AZURE_WINDOWS_PASSWORD --vm-name $WINDOWS_SERVER_VM_NAME --vm-size $AZURE_DEPLOYMENT_VM_SIZE --virtual-network-name $AZURE_DEPLOYMENT_NAME --rdp --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating virtual machine $WINDOWS_SERVER_VM_NAME."
+    $AZURE_COMMAND vm list | grep $WINDOWS_SERVER_VM_NAME || $AZURE_COMMAND vm create $WINDOWS_SERVER_VM_NAME $LATEST_WINDOWS_IMAGE $AZURE_WINDOWS_USER $AZURE_WINDOWS_PASSWORD --vm-name $WINDOWS_SERVER_VM_NAME --vm-size $AZURE_DEPLOYMENT_VM_SIZE --virtual-network-name $AZURE_DEPLOYMENT_NAME --rdp --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating virtual machine $WINDOWS_SERVER_VM_NAME."
 
     # Create SQL Server VM.
     echo ""
@@ -175,7 +184,7 @@ function azure_create_vms {
     echo $SQL_SERVER_IMAGE
     echo ""
     echo "Creating SQL Server VM: $SQL_SERVER_VM_NAME"
-    $AZURE_COMMAND vm create $SQL_SERVER_VM_NAME $SQL_SERVER_IMAGE Administrator $AZURE_WINDOWS_PASSWORD --vm-name $SQL_SERVER_VM_NAME --vm-size $AZURE_DEPLOYMENT_VM_SIZE --virtual-network-name $AZURE_DEPLOYMENT_NAME --rdp --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating virtual machine $SQL_SERVER_VM_NAME."
+    $AZURE_COMMAND vm list | grep $SQL_SERVER_VM_NAME || $AZURE_COMMAND vm create $SQL_SERVER_VM_NAME $SQL_SERVER_IMAGE $AZURE_WINDOWS_USER $AZURE_WINDOWS_PASSWORD --vm-name $SQL_SERVER_VM_NAME --vm-size $AZURE_DEPLOYMENT_VM_SIZE --virtual-network-name $AZURE_DEPLOYMENT_NAME --rdp --affinity-group $AZURE_DEPLOYMENT_NAME || fail "Error creating virtual machine $SQL_SERVER_VM_NAME."
 
     echo ""
 }
@@ -224,9 +233,9 @@ BENCHMARK_LINUX_SERVER_IP="$LINUX_SERVER_IP"
 BENCHMARK_LINUX_USER="$AZURE_LINUX_USER"
 BENCHMARK_SSH_KEY="$AZURE_KEY_FILE"
 BENCHMARK_WINDOWS_SERVER="$WINDOWS_SERVER_VM_NAME.cloudapp.net"
-BENCHMARK_WINDOWS_SERVER_USER="$WINDOWS_SERVER_VM_NAME\Administrator"
+BENCHMARK_WINDOWS_SERVER_USER="$WINDOWS_SERVER_VM_NAME\\$AZURE_WINDOWS_USER"
 BENCHMARK_SQL_SERVER="$SQL_SERVER_VM_NAME.cloudapp.net"
-BENCHMARK_SQL_SERVER_USER="$SQL_SERVER_VM_NAME\Administrator"
+BENCHMARK_SQL_SERVER_USER="$SQL_SERVER_VM_NAME\\$AZURE_WINDOWS_USER"
 BENCHMARK_WORKING_DIR="$BENCHMARK_WORKING_DIR"
 BENCHMARK_REPOSITORY="$BENCHMARK_REPOSITORY"
 BENCHMARK_BRANCH="$BENCHMARK_BRANCH"
@@ -260,11 +269,11 @@ ssh $AZURE_LINUX_USER@$LINUX_SERVER_VM_NAME.cloudapp.net -i $AZURE_KEY_FILE
 
 To connect to the Windows server VM:
 mstsc /v:$WINDOWS_SERVER_VM_NAME.cloudapp.net /admin /f
-User name: $WINDOWS_SERVER_VM_NAME\Administrator
+User name: $WINDOWS_SERVER_VM_NAME\\$AZURE_WINDOWS_USER
 
 To connect to the SQL Server VM:
 mstsc /v:$SQL_SERVER_VM_NAME.cloudapp.net /admin /f
-User name: $SQL_SERVER_VM_NAME\Administrator
+User name: $SQL_SERVER_VM_NAME\\$AZURE_WINDOWS_USER
 
 To manage the Windows Azure resources:
 https://manage.windowsazure.com

+ 1 - 1
toolset/deployment/common/bash-common.sh

@@ -62,7 +62,7 @@ function retry {
 
 # Detect CYGWIN.
 function iscygwin {
-    if [ "$(expr substr $(uname -s) 1 6)" == "CYGWIN" ]; then
+    if [ $(uname -s | grep "CYGWIN") ]; then
         true
     else
         false

+ 1 - 0
toolset/deployment/common/linux-initial-deployment.sh

@@ -32,6 +32,7 @@ cat >$BENCHMARK_REMOTE_CONFIGURATION_FILE <<_EOF_
 export BENCHMARK_HOME="/home/$BENCHMARK_LINUX_USER/FrameworkBenchmarks"
 export BENCHMARK_SERVER_IP="$BENCHMARK_LINUX_SERVER_IP"
 export BENCHMARK_CLIENT_IP="$BENCHMARK_LINUX_CLIENT_IP"
+export BENCHMARK_USER="$BENCHMARK_LINUX_USER"
 export BENCHMARK_KEY_PATH="$BENCHMARK_REMOTE_KEY_FILE"
 export BENCHMARK_REPOSITORY="$BENCHMARK_REPOSITORY"
 export BENCHMARK_BRANCH="$BENCHMARK_BRANCH"

+ 16 - 7
toolset/deployment/common/remote/lsr-step-1.sh

@@ -8,6 +8,7 @@ echo "Host:" `hostname`
 echo "Step 1: Install software on Linux server"
 
 export DEBIAN_FRONTEND=noninteractive
+export LC_ALL="en_US.UTF-8"
 
 echo ""
 source ~/benchmark-configuration.sh
@@ -27,9 +28,9 @@ echo "BENCHMARK_BRANCH: $BENCHMARK_BRANCH"
 
 echo ""
 echo "Configuring firewall"
-sudo iptables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED
-sudo iptables -A INPUT -j ACCEPT -m state --state NEW -p tcp --source 10.0.0.0/11
-sudo iptables -A OUTPUT -j ACCEPT -m state --state ESTABLISHED,RELATED
+sudo iptables -C INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED || sudo iptables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED
+sudo iptables -C INPUT -j ACCEPT -m state --state NEW -p tcp --source 10.0.0.0/11 || sudo iptables -A INPUT -j ACCEPT -m state --state NEW -p tcp --source 10.0.0.0/11
+sudo iptables -C OUTPUT -j ACCEPT -m state --state ESTABLISHED,RELATED || sudo iptables -A OUTPUT -j ACCEPT -m state --state ESTABLISHED,RELATED
 sudo iptables -L
 
 echo ""
@@ -45,9 +46,17 @@ echo "Installing git"
 sudo apt-get install git -qq
 
 echo ""
-echo "Clone FrameworkBenchmarks repository"
-git clone $BENCHMARK_REPOSITORY "$BENCHMARK_HOME" || { echo "Error cloning repository at $BENCHMARK_REPOSITORY."; exit 1; }
-cd "$BENCHMARK_HOME"
+
+if [ ! -d "$BENCHMARK_HOME" ]; then
+	echo "Clone FrameworkBenchmarks repository"
+	git clone $BENCHMARK_REPOSITORY "$BENCHMARK_HOME" || { echo "Error cloning repository at $BENCHMARK_REPOSITORY."; exit 1; }
+	cd "$BENCHMARK_HOME"
+else
+	echo "Updating FrameworkBenchmarks repository"
+	cd "$BENCHMARK_HOME"
+	git pull || { echo "Error updating repository at $BENCHMARK_REPOSITORY."; exit 1; }
+fi
+
 git checkout $BENCHMARK_BRANCH || { echo "Error checking out $BENCHMARK_BRANCH branch."; exit 1; }
 git branch
 git log -1 --pretty=format:"%H %s"
@@ -55,7 +64,7 @@ echo ""
 
 echo ""
 echo "Installing benchmark software"
-toolset/run-tests.py -s "$BENCHMARK_SERVER_IP" -c "$BENCHMARK_CLIENT_IP" -i "$BENCHMARK_KEY_PATH" --install-software --install-error-action abort --list-tests || { echo "Error installing software."; exit 1; }
+toolset/run-tests.py -s "$BENCHMARK_SERVER_IP" -c "$BENCHMARK_CLIENT_IP" -i "$BENCHMARK_KEY_PATH" -u "$BENCHMARK_USER" --install-software --install-error-action abort --list-tests || { echo "Error installing software."; exit 1; }
 
 echo ""
 echo "End of step 1"

+ 1 - 0
toolset/deployment/common/remote/lsr-step-2.sh

@@ -8,6 +8,7 @@ echo "Host:" `hostname`
 echo "Step 2: Additional setup"
 
 export DEBIAN_FRONTEND=noninteractive
+export LC_ALL="en_US.UTF-8"
 source ~/.bash_profile
 source ~/benchmark-configuration.sh
 source $BENCHMARK_HOME/toolset/deployment/common/bash-common.sh

+ 4 - 3
toolset/deployment/common/remote/lsr-step-3.sh

@@ -8,6 +8,7 @@ echo "Host:" `hostname`
 echo "Step 3: Verify setup."
 
 export DEBIAN_FRONTEND=noninteractive
+export LC_ALL="en_US.UTF-8"
 source ~/benchmark-configuration.sh
 
 echo ""
@@ -17,12 +18,12 @@ cd "$BENCHMARK_HOME" || { echo "Error changing directory."; exit 1; }
 
 echo "Verifying servlet-raw"
 echo ""
-toolset/run-tests.py -s "$BENCHMARK_SERVER_IP" -c "$BENCHMARK_CLIENT_IP" -i "$BENCHMARK_KEY_PATH" --max-threads 1 --name smoketest --test servlet-raw --type all -m verify
+toolset/run-tests.py -s "$BENCHMARK_SERVER_IP" -c "$BENCHMARK_CLIENT_IP" -i "$BENCHMARK_KEY_PATH" -u "$BENCHMARK_USER" --max-threads 1 --name smoketest --test servlet-raw --type all -m verify
 
 echo "Verifying cpoll_cppsp-postgres-raw"
 echo ""
-toolset/run-tests.py -s "$BENCHMARK_SERVER_IP" -c "$BENCHMARK_CLIENT_IP" -i "$BENCHMARK_KEY_PATH" --max-threads 1 --name smoketest --test cpoll_cppsp-postgres-raw --type all -m verify
+toolset/run-tests.py -s "$BENCHMARK_SERVER_IP" -c "$BENCHMARK_CLIENT_IP" -i "$BENCHMARK_KEY_PATH" -u "$BENCHMARK_USER" --max-threads 1 --name smoketest --test cpoll_cppsp-postgres-raw --type all -m verify
 
 echo "Verifying nodejs-mongodb"
 echo ""
-toolset/run-tests.py -s "$BENCHMARK_SERVER_IP" -c "$BENCHMARK_CLIENT_IP" -i "$BENCHMARK_KEY_PATH" --max-threads 1 --name smoketest --test nodejs-mongodb --type all -m verify
+toolset/run-tests.py -s "$BENCHMARK_SERVER_IP" -c "$BENCHMARK_CLIENT_IP" -i "$BENCHMARK_KEY_PATH" -u "$BENCHMARK_USER" --max-threads 1 --name smoketest --test nodejs-mongodb --type all -m verify

+ 222 - 153
toolset/setup/linux/installer.py

@@ -1,5 +1,6 @@
 import subprocess
 import os
+import os.path
 import time
 import traceback
 import sys
@@ -33,16 +34,16 @@ class Installer:
     #######################################
     self.__run_command("sudo apt-get update", True)
     self.__run_command("sudo apt-get upgrade", True)
-    self.__run_command("sudo apt-get install build-essential libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev python-software-properties unzip git-core libcurl4-openssl-dev libbz2-dev libmysqlclient-dev mongodb-clients libreadline6-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev libgdbm-dev ncurses-dev automake libffi-dev htop libtool bison libevent-dev libgstreamer-plugins-base0.10-0 libgstreamer0.10-0 liborc-0.4-0 libwxbase2.8-0 libwxgtk2.8-0 libgnutls-dev libjson0-dev libmcrypt-dev libicu-dev cmake gettext curl libpq-dev mercurial mlton", True)
+    self.__run_command("sudo apt-get install -y build-essential libpcre3 libpcre3-dev libpcrecpp0 libssl-dev zlib1g-dev python-software-properties unzip git-core libcurl4-openssl-dev libbz2-dev libmysqlclient-dev mongodb-clients libreadline6-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev libgdbm-dev ncurses-dev automake libffi-dev htop libtool bison libevent-dev libgstreamer-plugins-base0.10-0 libgstreamer0.10-0 liborc-0.4-0 libwxbase2.8-0 libwxgtk2.8-0 libgnutls-dev libjson0-dev libmcrypt-dev libicu-dev cmake gettext curl libpq-dev mercurial mlton", True)
     self.__run_command("sudo add-apt-repository ppa:ubuntu-toolchain-r/test", True)
     self.__run_command("sudo apt-get update", True)
-    self.__run_command("sudo apt-get install gcc-4.8 g++-4.8", True)
+    self.__run_command("sudo apt-get install -y gcc-4.8 g++-4.8", True)
 
     self.__run_command("cp ../config/benchmark_profile ../../.bash_profile")
-    self.__run_command("cat ../config/benchmark_profile >> ../../.profile")
-    self.__run_command("cat ../config/benchmark_profile >> ../../.bashrc")
+    self.__run_command("grep \"Start Benchmark profile\" ../../.profile || cat ../config/benchmark_profile >> ../../.profile")
+    self.__run_command("grep \"Start Benchmark profile\" ../../.bashrc || cat ../config/benchmark_profile >> ../../.bashrc")
     self.__run_command("source ../../.profile")
-    self.__run_command("sudo sh -c \"echo '*               -    nofile          65535' >> /etc/security/limits.conf\"")
+    self.__run_command("grep \"nofile\" /etc/security/limits.conf | grep \"65535\" || sudo sh -c \"echo '*               -    nofile          65535' >> /etc/security/limits.conf\"")
 
     ##############################################################
     # System Tools
@@ -51,16 +52,18 @@ class Installer:
     #
     # Leiningen
     #
-    self.__run_command("mkdir -p bin")
-    self.__download("https://raw.github.com/technomancy/leiningen/stable/bin/lein")
-    self.__run_command("mv lein bin/lein")
-    self.__run_command("chmod +x bin/lein")
+    if not self.__path_exists("bin/lein"):
+        self.__run_command("mkdir -p bin")
+        self.__download("https://raw.github.com/technomancy/leiningen/stable/bin/lein")
+        self.__run_command("mv lein bin/lein")
+        self.__run_command("chmod +x bin/lein")
 
     #
     # Maven
     #
-    self.__run_command("sudo apt-get install maven -qq")
-    self.__run_command("mvn -version")
+    if not self.__path_exists("/usr/bin/mvn"):
+        self.__run_command("sudo apt-get install maven -qq")
+        self.__run_command("mvn -version")
 
     #######################################
     # Languages
@@ -71,28 +74,31 @@ class Installer:
     #
     # Dart
     #
-    self.__download("http://storage.googleapis.com/dart-archive/channels/stable/release/latest/sdk/dartsdk-linux-x64-release.zip")
-    self.__run_command("unzip dartsdk-linux-x64-release.zip")
+    if not self.__path_exists("dart-sdk"):
+        self.__download("http://storage.googleapis.com/dart-archive/channels/stable/release/latest/sdk/dartsdk-linux-x64-release.zip")
+        self.__run_command("unzip dartsdk-linux-x64-release.zip")
 
     #
     # Erlang
     #
-    self.__run_command("sudo cp ../config/erlang.list /etc/apt/sources.list.d/erlang.list")
-    self.__download("http://binaries.erlang-solutions.com/debian/erlang_solutions.asc")
-    self.__run_command("sudo apt-key add erlang_solutions.asc")
-    self.__run_command("sudo apt-get update")
-    self.__run_command("sudo apt-get install esl-erlang", True)
+    if not self.__path_exists("/usr/bin/erl"):
+        self.__run_command("sudo cp ../config/erlang.list /etc/apt/sources.list.d/erlang.list")
+        self.__download("http://binaries.erlang-solutions.com/debian/erlang_solutions.asc")
+        self.__run_command("sudo apt-key add erlang_solutions.asc")
+        self.__run_command("sudo apt-get update")
+        self.__run_command("sudo apt-get install -y esl-erlang", True)
 
     #
     # nodejs
     #
-    self.__download("http://nodejs.org/dist/v0.10.8/node-v0.10.8-linux-x64.tar.gz")
-    self.__run_command("tar xzf node-v0.10.8-linux-x64.tar.gz")
+    if not self.__path_exists("node-v0.10.8-linux-x64"):
+        self.__download("http://nodejs.org/dist/v0.10.8/node-v0.10.8-linux-x64.tar.gz")
+        self.__run_command("tar xzf node-v0.10.8-linux-x64.tar.gz")
 
     #
     # Java
     #
-    self.__run_command("sudo apt-get install openjdk-7-jdk", True)
+    self.__run_command("sudo apt-get install -y openjdk-7-jdk", True)
     self.__run_command("sudo apt-get remove --purge openjdk-6-jre openjdk-6-jre-headless", True)
 
     #
@@ -108,108 +114,130 @@ class Installer:
     #
     # go
     #
-    self.__download("http://go.googlecode.com/files/go1.2.linux-amd64.tar.gz");
-    self.__run_command("tar xzf go1.2.linux-amd64.tar.gz")
+    if not self.__path_exists("go"):
+        self.__download("http://go.googlecode.com/files/go1.2.linux-amd64.tar.gz");
+        self.__run_command("tar xzf go1.2.linux-amd64.tar.gz")
 
     #
     # Perl
     #
-    self.__download("http://downloads.activestate.com/ActivePerl/releases/5.16.3.1603/ActivePerl-5.16.3.1603-x86_64-linux-glibc-2.3.5-296746.tar.gz");
-    self.__run_command("tar xzf ActivePerl-5.16.3.1603-x86_64-linux-glibc-2.3.5-296746.tar.gz");
-    self.__run_command("sudo ./install.sh --license-accepted --prefix /opt/ActivePerl-5.16 --no-install-html", cwd="ActivePerl-5.16.3.1603-x86_64-linux-glibc-2.3.5-296746", send_yes=True, retry=True)
+    if not self.__path_exists("/opt/ActivePerl-5.16/bin/perl"):
+        self.__download("http://downloads.activestate.com/ActivePerl/releases/5.16.3.1603/ActivePerl-5.16.3.1603-x86_64-linux-glibc-2.3.5-296746.tar.gz");
+        self.__run_command("tar xzf ActivePerl-5.16.3.1603-x86_64-linux-glibc-2.3.5-296746.tar.gz");
+        self.__run_command("sudo ./install.sh --license-accepted --prefix /opt/ActivePerl-5.16 --no-install-html", cwd="ActivePerl-5.16.3.1603-x86_64-linux-glibc-2.3.5-296746", send_yes=True, retry=True)
+
     self.__download("http://cpanmin.us", "cpanminus.pl")
     self.__run_command("perl cpanminus.pl --sudo App::cpanminus", retry=True)
-    self.__run_command("cpanm -f -S DBI DBD::mysql Kelp Dancer Mojolicious Kelp::Module::JSON::XS Dancer::Plugin::Database Starman Plack JSON Web::Simple DBD::Pg JSON::XS EV HTTP::Parser::XS Monoceros EV IO::Socket::IP IO::Socket::SSL", retry=True)
+    self.__run_command("cpanm -n -S DBI DBD::mysql Kelp Dancer Mojolicious Kelp::Module::JSON::XS Dancer::Plugin::Database Starman Plack JSON Web::Simple DBD::Pg JSON::XS EV HTTP::Parser::XS Monoceros EV IO::Socket::IP IO::Socket::SSL", retry=True)
 
     #
     # php
     #
-    self.__download("http://museum.php.net/php5/php-5.4.13.tar.gz")
-    self.__run_command("tar xzf php-5.4.13.tar.gz")
-    self.__run_command("./configure --with-pdo-mysql --with-mysql --with-mcrypt --enable-intl --enable-mbstring --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --with-openssl", cwd="php-5.4.13")
-    self.__run_command("make", cwd="php-5.4.13")
-    self.__run_command("sudo make install", cwd="php-5.4.13")
-    self.__run_command("printf \"\\n\" | sudo pecl install apc-beta", cwd="php-5.4.13", retry=True)
+    if not self.__path_exists("/usr/local/bin/php"):
+        self.__download("http://museum.php.net/php5/php-5.4.13.tar.gz")
+        self.__run_command("tar xzf php-5.4.13.tar.gz")
+        self.__run_command("./configure --with-pdo-mysql --with-mysql --with-mcrypt --enable-intl --enable-mbstring --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data --with-openssl", cwd="php-5.4.13")
+        self.__run_command("make", cwd="php-5.4.13")
+        self.__run_command("sudo make install", cwd="php-5.4.13")
+
+    if not self.__path_exists("/usr/local/lib/php/extensions/no-debug-non-zts-20100525/apc.so"):
+        self.__run_command("printf \"\\n\" | sudo pecl install apc-beta", cwd="php-5.4.13", retry=True)
+
     self.__run_command("sudo cp ../config/php.ini /usr/local/lib/php.ini")
     self.__run_command("sudo cp ../config/php-fpm.conf /usr/local/lib/php-fpm.conf")
 
     # Composer
-    self.__download("https://getcomposer.org/installer", "composer-installer.php")
-    self.__run_command("php composer-installer.php --install-dir=bin")
+    if not self.__path_exists("bin/composer.phar"):
+        self.__download("https://getcomposer.org/installer", "composer-installer.php")
+        self.__run_command("php composer-installer.php --install-dir=bin")
 
     # Phalcon
-    self.__run_command("git clone git://github.com/phalcon/cphalcon.git", retry=True)
-    self.__run_command("sudo ./install", cwd="cphalcon/build")
+    if not self.__path_exists("/usr/local/lib/php/extensions/no-debug-non-zts-20100525/phalcon.so"):
+        self.__run_command("test -d cphalcon || git clone git://github.com/phalcon/cphalcon.git", retry=True)
+        self.__run_command("sudo ./install", cwd="cphalcon/build")
 
     # YAF
-    self.__run_command("sudo pecl install yaf")
+    if not self.__path_exists("/usr/local/lib/php/extensions/no-debug-non-zts-20100525/yaf.so"):
+        self.__run_command("sudo pecl install yaf")
 
     #
     # Haskell
     #
-    self.__run_command("sudo apt-get install ghc cabal-install", True)
+    self.__run_command("sudo apt-get install -y ghc cabal-install", True)
 
     #
     # RingoJs
     #
-    self.__download("http://www.ringojs.org/downloads/ringojs_0.9-1_all.deb")
-    self.__run_command("sudo apt-get install jsvc", True)
-    self.__run_command("sudo dpkg -i ringojs_0.9-1_all.deb", True)
-    self.__run_command("rm ringojs_0.9-1_all.deb")
+    if not self.__path_exists("/usr/share/ringojs"):
+        self.__download("http://www.ringojs.org/downloads/ringojs_0.9-1_all.deb")
+        self.__run_command("sudo apt-get install -y jsvc", True)
+        self.__run_command("sudo dpkg -i ringojs_0.9-1_all.deb", True)
+        self.__run_command("rm ringojs_0.9-1_all.deb")
 
     #
     # Mono
     #
-    self.__run_command("git clone git://github.com/mono/mono", retry=True)
-    self.__run_command("git checkout mono-3.2.8-branch", cwd="mono")
-    self.__run_command("./autogen.sh --prefix=/usr/local", cwd="mono")
-    self.__run_command("make get-monolite-latest", cwd="mono")
-    self.__run_command("make EXTERNAL_MCS=${PWD}/mcs/class/lib/monolite/basic.exe", cwd="mono")
-    self.__run_command("sudo make install", cwd="mono")
+    if not self.__path_exists("/usr/local/bin/mono"):
+        self.__run_command("test -d mono || git clone git://github.com/mono/mono", retry=True)
+        self.__run_command("git checkout mono-3.2.8-branch", cwd="mono")
+        self.__run_command("./autogen.sh --prefix=/usr/local", cwd="mono")
+        self.__run_command("make get-monolite-latest", cwd="mono")
+        self.__run_command("make EXTERNAL_MCS=${PWD}/mcs/class/lib/monolite/basic.exe", cwd="mono")
+        self.__run_command("sudo make install", cwd="mono")
 
     self.__run_command("mozroots --import --sync", retry=True)
 
-    self.__run_command("git clone git://github.com/mono/xsp", retry=True)
-    self.__run_command("./autogen.sh --prefix=/usr/local", cwd="xsp")
-    self.__run_command("make", cwd="xsp")
-    self.__run_command("sudo make install", cwd="xsp")
+    if not self.__path_exists("/usr/local/bin/xsp"):
+        self.__run_command("test -d xsp || git clone git://github.com/mono/xsp", retry=True)
+        self.__run_command("./autogen.sh --prefix=/usr/local", cwd="xsp")
+        self.__run_command("make", cwd="xsp")
+        self.__run_command("sudo make install", cwd="xsp")
 
     #
     # Nimrod
     #
-    self.__run_command("git clone git://github.com/Araq/Nimrod.git nimrod", retry=True)
-    self.__run_command("git reset --hard \"43d12ef7495238977e4f236f6d25bce5bd687967\"", cwd="nimrod")
-    self.__run_command("git clone --depth 1 git://github.com/nimrod-code/csources.git", cwd="nimrod", retry=True)
-    self.__run_command("chmod +x build.sh", cwd="nimrod/csources")
-    self.__run_command("./build.sh", cwd="nimrod/csources")
-    self.__run_command("bin/nimrod c koch", cwd="nimrod")
+    if not self.__path_exists("nimrod/bin/nimrod"):
+        self.__run_command("test -d nimrod || git clone git://github.com/Araq/Nimrod.git nimrod", retry=True)
+        self.__run_command("git checkout 987ac2439a87d74838233a7b188e4db340495ee5", cwd="nimrod")
+        self.__run_command("test -d csources || git clone git://github.com/nimrod-code/csources.git", cwd="nimrod", retry=True)
+        self.__run_command("git checkout 704015887981932c78a033dd5ede623b2ad6ae27", cwd="nimrod/csources");
+        self.__run_command("chmod +x build.sh", cwd="nimrod/csources")
+        self.__run_command("./build.sh", cwd="nimrod/csources")
+
+    if not self.__path_exists("nimrod/koch"):
+        self.__run_command("bin/nimrod c koch", cwd="nimrod")
+
     self.__run_command("./koch boot -d:release", cwd="nimrod")
 
     #
     # Racket
     #
-    self.__download("https://github.com/plt/racket/archive/v5.3.6.tar.gz", "racket-5.3.6.tar.gz")
-    self.__run_command("tar xzf racket-5.3.6.tar.gz")
-    self.__run_command("./configure", cwd="racket-5.3.6/src")
-    self.__run_command("make", cwd="racket-5.3.6/src")
-    self.__run_command("sudo make install", cwd="racket-5.3.6/src")
+    if not self.__path_exists("racket-5.3.6/bin/racket") or not self.__path_exists("racket-5.3.6/collects/racket"):
+        self.__download("https://github.com/plt/racket/archive/v5.3.6.tar.gz", "racket-5.3.6.tar.gz")
+        self.__run_command("tar xzf racket-5.3.6.tar.gz")
+        self.__run_command("./configure", cwd="racket-5.3.6/src")
+        self.__run_command("make", cwd="racket-5.3.6/src")
+        self.__run_command("sudo make install", cwd="racket-5.3.6/src")
 
     #
     # Ur/Web
     #
-    self.__run_command("hg clone http://hg.impredicative.com/urweb")
-    self.__run_command("./autogen.sh", cwd="urweb")
-    self.__run_command("./configure", cwd="urweb")
-    self.__run_command("make", cwd="urweb")
-    self.__run_command("sudo make install", cwd="urweb")
+    if not self.__path_exists("/usr/local/bin/urweb"):
+        self.__run_command("hg clone http://hg.impredicative.com/urweb")
+        self.__run_command("./autogen.sh", cwd="urweb")
+        self.__run_command("./configure", cwd="urweb")
+        self.__run_command("make", cwd="urweb")
+        self.__run_command("sudo make install", cwd="urweb")
     
     #
     # HHVM
     #
-    self.__run_command("wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add -")
-    self.__run_command("echo deb http://dl.hhvm.com/ubuntu precise main | sudo tee /etc/apt/sources.list.d/hhvm.list")
-    self.__run_command("sudo apt-get update")
-    self.__run_command("sudo apt-get install hhvm")
+    if not self.__path_exists("/usr/bin/hhvm"):
+        self.__run_command("sudo add-apt-repository ppa:mapnik/boost", True)
+        self.__run_command("wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add -")
+        self.__run_command("echo deb http://dl.hhvm.com/ubuntu precise main | sudo tee /etc/apt/sources.list.d/hhvm.list")
+        self.__run_command("sudo apt-get update")
+        self.__run_command("sudo apt-get install -y hhvm")
 
     #######################################
     # Webservers
@@ -218,60 +246,68 @@ class Installer:
     #
     # Nginx
     #
-    self.__download("http://nginx.org/download/nginx-1.4.1.tar.gz")
-    self.__run_command("tar xzf nginx-1.4.1.tar.gz")
-    self.__run_command("./configure", cwd="nginx-1.4.1")
-    self.__run_command("make", cwd="nginx-1.4.1")
-    self.__run_command("sudo make install", cwd="nginx-1.4.1")
+    if not self.__path_exists("/usr/local/nginx/sbin/nginx"):
+        self.__download("http://nginx.org/download/nginx-1.4.1.tar.gz")
+        self.__run_command("tar xzf nginx-1.4.1.tar.gz")
+        self.__run_command("./configure", cwd="nginx-1.4.1")
+        self.__run_command("make", cwd="nginx-1.4.1")
+        self.__run_command("sudo make install", cwd="nginx-1.4.1")
 
     #
     # Openresty (nginx with lua stuff)
     #
-    self.__download("http://openresty.org/download/ngx_openresty-1.5.8.1.tar.gz")
-    self.__run_command("tar xzf ngx_openresty-1.5.8.1.tar.gz")
-    self.__run_command("./configure --with-luajit --with-http_postgres_module", cwd="ngx_openresty-1.5.8.1")
-    self.__run_command("make", cwd="ngx_openresty-1.5.8.1")
-    self.__run_command("sudo make install", cwd="ngx_openresty-1.5.8.1")
+    if not self.__path_exists("/usr/local/openresty/nginx/sbin/nginx"):
+        self.__download("http://openresty.org/download/ngx_openresty-1.5.8.1.tar.gz")
+        self.__run_command("tar xzf ngx_openresty-1.5.8.1.tar.gz")
+        self.__run_command("./configure --with-luajit --with-http_postgres_module", cwd="ngx_openresty-1.5.8.1")
+        self.__run_command("make", cwd="ngx_openresty-1.5.8.1")
+        self.__run_command("sudo make install", cwd="ngx_openresty-1.5.8.1")
     
     #
     # Lapis
     #
-    self.__run_command("sudo apt-get install luarocks")
-    self.__run_command("sudo luarocks install http://github.com/leafo/lapis/raw/master/lapis-dev-1.rockspec")
+    if not self.__path_exists("/usr/local/bin/lapis"):
+        self.__run_command("sudo apt-get install -y luarocks")
+        self.__run_command("sudo luarocks install luasec OPENSSL_LIBDIR=/usr/lib/x86_64-linux-gnu/")
+        self.__run_command("sudo luarocks install http://github.com/leafo/lapis/raw/master/lapis-dev-1.rockspec")
 
 
     #
     # Resin
     #
-
-    self.__run_command("sudo cp -r /usr/lib/jvm/java-1.7.0-openjdk-amd64/include /usr/lib/jvm/java-1.7.0-openjdk-amd64/jre/bin/")
-    self.__download("http://www.caucho.com/download/resin-4.0.36.tar.gz")
-    self.__run_command("tar xzf resin-4.0.36.tar.gz")
-    self.__run_command("./configure --prefix=`pwd`", cwd="resin-4.0.36")
-    self.__run_command("make", cwd="resin-4.0.36")
-    self.__run_command("make install", cwd="resin-4.0.36")
-    self.__run_command("mv conf/resin.properties conf/resin.properties.orig", cwd="resin-4.0.36")
-    self.__run_command("cat ../config/resin.properties > resin-4.0.36/conf/resin.properties")
-    self.__run_command("mv conf/resin.xml conf/resin.xml.orig", cwd="resin-4.0.36")
-    self.__run_command("cat ../config/resin.xml > resin-4.0.36/conf/resin.xml")
+    if not self.__path_exists("resin-4.0.36/conf/resin.xml"):
+        self.__run_command("sudo cp -r /usr/lib/jvm/java-1.7.0-openjdk-amd64/include /usr/lib/jvm/java-1.7.0-openjdk-amd64/jre/bin/")
+        self.__download("http://www.caucho.com/download/resin-4.0.36.tar.gz")
+        self.__run_command("tar xzf resin-4.0.36.tar.gz")
+        self.__run_command("./configure --prefix=`pwd`", cwd="resin-4.0.36")
+        self.__run_command("make", cwd="resin-4.0.36")
+        self.__run_command("make install", cwd="resin-4.0.36")
+        self.__run_command("mv conf/resin.properties conf/resin.properties.orig", cwd="resin-4.0.36")
+        self.__run_command("cat ../config/resin.properties > resin-4.0.36/conf/resin.properties")
+        self.__run_command("mv conf/resin.xml conf/resin.xml.orig", cwd="resin-4.0.36")
+        self.__run_command("cat ../config/resin.xml > resin-4.0.36/conf/resin.xml")
 
     #
     # Mongrel2
     #
-    self.__download("http://download.zeromq.org/zeromq-4.0.3.tar.gz")
-    self.__run_command("tar xzf zeromq-4.0.3.tar.gz")
-    self.__run_command("./configure", cwd="zeromq-4.0.3")
-    self.__run_command("make", cwd="zeromq-4.0.3")
-    self.__run_command("sudo make install", cwd="zeromq-4.0.3")
-    self.__run_command("sudo apt-get install sqlite3 libsqlite3-dev uuid uuid-runtime uuid-dev")
+    if not self.__path_exists("/usr/local/lib/libzmq.a"):
+        self.__download("http://download.zeromq.org/zeromq-4.0.3.tar.gz")
+        self.__run_command("tar xzf zeromq-4.0.3.tar.gz")
+        self.__run_command("./configure", cwd="zeromq-4.0.3")
+        self.__run_command("make", cwd="zeromq-4.0.3")
+        self.__run_command("sudo make install", cwd="zeromq-4.0.3")
+
+    self.__run_command("sudo apt-get install -y sqlite3 libsqlite3-dev uuid uuid-runtime uuid-dev")
     self.__run_command("sudo ldconfig -v")
-    self.__download("https://github.com/zedshaw/mongrel2/tarball/v1.8.1", "mongrel2.tar.gz")
-    self.__run_command("tar xvf mongrel2.tar.gz")
-    self.__run_command("mv zedshaw-mongrel2-aa2ecf8 mongrel2")
-    # for zmq4, we update the following file manually (not in v1.8.1)
-    self.__download("https://raw.github.com/zedshaw/mongrel2/9b565eeea003783c47502c2d350b99c9684ce97c/src/zmq_compat.h")
-    self.__run_command("mv -f zmq_compat.h mongrel2/src/")
-    self.__run_command("make clean all && sudo make install", cwd="mongrel2")
+
+    if not self.__path_exists("/usr/local/bin/mongrel2"):
+        self.__download("https://github.com/zedshaw/mongrel2/tarball/v1.8.1", "mongrel2.tar.gz")
+        self.__run_command("tar xvf mongrel2.tar.gz")
+        self.__run_command("mv zedshaw-mongrel2-aa2ecf8 mongrel2")
+        # for zmq4, we update the following file manually (not in v1.8.1)
+        self.__download("https://raw.github.com/zedshaw/mongrel2/9b565eeea003783c47502c2d350b99c9684ce97c/src/zmq_compat.h")
+        self.__run_command("mv -f zmq_compat.h mongrel2/src/")
+        self.__run_command("make clean all && sudo make install", cwd="mongrel2")
 
     ##############################################################
     # Frameworks
@@ -280,21 +316,24 @@ class Installer:
     #
     # Grails
     #
-    self.__download("http://dist.springframework.org.s3.amazonaws.com/release/GRAILS/grails-2.3.3.zip")
-    self.__run_command("unzip -o grails-2.3.3.zip")
+    if not self.__path_exists("grails-2.3.3"):
+        self.__download("http://dist.springframework.org.s3.amazonaws.com/release/GRAILS/grails-2.3.3.zip")
+        self.__run_command("unzip -o grails-2.3.3.zip")
 
     #
     # Play 2
     #
-    self.__download("http://downloads.typesafe.com/play/2.2.0/play-2.2.0.zip")
-    self.__run_command("unzip -o play-2.2.0.zip")
+    if not self.__path_exists("play-2.2.0"):
+        self.__download("http://downloads.typesafe.com/play/2.2.0/play-2.2.0.zip")
+        self.__run_command("unzip -o play-2.2.0.zip")
 
     #
     # Play 1
     #
-    self.__download("http://downloads.typesafe.com/releases/play-1.2.5.zip")
-    self.__run_command("unzip -o play-1.2.5.zip")
-    self.__run_command("mv play-1.2.5/play play-1.2.5/play1")
+    if not self.__path_exists("play-1.2.5"):
+        self.__download("http://downloads.typesafe.com/releases/play-1.2.5.zip")
+        self.__run_command("unzip -o play-1.2.5.zip")
+        self.__run_command("mv play-1.2.5/play play-1.2.5/play1")
 
     # siena
     self.__run_command("yes | play-1.2.5/play1 install siena")
@@ -302,21 +341,23 @@ class Installer:
     #
     # TreeFrog Framework
     #
-    self.__run_command("sudo apt-get install qt4-qmake libqt4-dev libqt4-sql-mysql libqt4-sql-psql g++", True)
-    self.__download("http://downloads.sourceforge.net/project/treefrog/src/treefrog-1.7.5.tar.gz")
-    self.__run_command("tar xzf treefrog-1.7.5.tar.gz")
-    self.__run_command("rm treefrog-1.7.5.tar.gz")
-    self.__run_command("./configure", cwd="treefrog-1.7.5")
-    self.__run_command("make", cwd="treefrog-1.7.5/src")
-    self.__run_command("sudo make install", cwd="treefrog-1.7.5/src")
-    self.__run_command("make", cwd="treefrog-1.7.5/tools")
-    self.__run_command("sudo make install", cwd="treefrog-1.7.5/tools")
+    if not self.__path_exists("/usr/bin/treefrog") or not self.__path_exists("/usr/bin/tspawn"):
+        self.__run_command("sudo apt-get install -y qt4-qmake libqt4-dev libqt4-sql-mysql libqt4-sql-psql g++", True)
+        self.__download("http://downloads.sourceforge.net/project/treefrog/src/treefrog-1.7.5.tar.gz")
+        self.__run_command("tar xzf treefrog-1.7.5.tar.gz")
+        self.__run_command("rm treefrog-1.7.5.tar.gz")
+        self.__run_command("./configure", cwd="treefrog-1.7.5")
+        self.__run_command("make", cwd="treefrog-1.7.5/src")
+        self.__run_command("sudo make install", cwd="treefrog-1.7.5/src")
+        self.__run_command("make", cwd="treefrog-1.7.5/tools")
+        self.__run_command("sudo make install", cwd="treefrog-1.7.5/tools")
 
     #
     # Vert.x
     #
-    self.__download("http://dl.bintray.com/vertx/downloads/vert.x-2.1M3.tar.gz?direct=true", "vert.x-2.1M3.tar.gz")
-    self.__run_command("tar xzf vert.x-2.1M3.tar.gz")
+    if not self.__path_exists("vert.x-2.1M3"):
+        self.__download("http://dl.bintray.com/vertx/downloads/vert.x-2.1M3.tar.gz?direct=true", "vert.x-2.1M3.tar.gz")
+        self.__run_command("tar xzf vert.x-2.1M3.tar.gz")
 
     #
     # Yesod
@@ -327,19 +368,24 @@ class Installer:
     #
     # Jester
     #
-    self.__run_command("git clone git://github.com/dom96/jester.git jester/jester", retry=True)
+    if not self.__path_exists("jester"):
+        self.__run_command("git clone git://github.com/dom96/jester.git jester/jester", retry=True)
 
     #
     # Onion
     #
-    self.__run_command("git clone https://github.com/davidmoreno/onion.git")
-    self.__run_command("mkdir build", cwd="onion")
-    self.__run_command("cmake ..", cwd="onion/build")
-    self.__run_command("make", cwd="onion/build")
+    if not self.__path_exists("onion"):
+        self.__run_command("git clone https://github.com/davidmoreno/onion.git")
+        self.__run_command("mkdir build", cwd="onion")
+        self.__run_command("cmake ..", cwd="onion/build")
+        self.__run_command("make", cwd="onion/build")
 
     # nawak
     #
-    self.__run_command("git clone git://github.com/idlewan/nawak.git nawak/nawak", retry=True)
+    if not self.__path_exists("nawak"):
+        self.__run_command("git clone git://github.com/idlewan/nawak.git nawak/nawak", retry=True)
+
+    self.__run_command("sudo apt-get -y autoremove || true");
 
     print("\nINSTALL: Finished installing server software\n")
   ############################################################
@@ -351,30 +397,36 @@ class Installer:
     pypy_bin   = "~/FrameworkBenchmarks/installs/pypy/bin"
     python_bin = "~/FrameworkBenchmarks/installs/py2/bin"
     python3_bin= "~/FrameworkBenchmarks/installs/py3/bin"
+
     def easy_install(pkg, two=True, three=False, pypy=False):
       cmd = "/easy_install -ZU '" + pkg + "'"
       if two:   self.__run_command(python_bin + cmd, retry=True)
       if three: self.__run_command(python3_bin + cmd, retry=True)
       if pypy:  self.__run_command(pypy_bin + cmd, retry=True)
 
-    self.__download("https://bitbucket.org/pypy/pypy/downloads/pypy-2.2-linux64.tar.bz2")
-    self.__run_command("tar xjf pypy-2.2-linux64.tar.bz2")
-    self.__run_command('ln -sf pypy-2.2-linux64 pypy')
-    self.__download("http://www.python.org/ftp/python/2.7.6/Python-2.7.6.tgz")
-    self.__run_command("tar xzf Python-2.7.6.tgz")
-    self.__download("http://www.python.org/ftp/python/3.3.2/Python-3.3.2.tar.xz")
-    self.__run_command("tar xJf Python-3.3.2.tar.xz")
-    self.__run_command("./configure --prefix=$HOME/FrameworkBenchmarks/installs/py2 --disable-shared CC=gcc-4.8", cwd="Python-2.7.6")
-    self.__run_command("./configure --prefix=$HOME/FrameworkBenchmarks/installs/py3 --disable-shared CC=gcc-4.8", cwd="Python-3.3.2")
-    self.__run_command("make -j2", cwd="Python-2.7.6")
-    self.__run_command("make install", cwd="Python-2.7.6")
-    self.__run_command("make -j2", cwd="Python-3.3.2")
-    self.__run_command("make install", cwd="Python-3.3.2")
+    if not self.__path_exists("pypy"):
+        self.__download("https://bitbucket.org/pypy/pypy/downloads/pypy-2.2-linux64.tar.bz2")
+        self.__run_command("tar xjf pypy-2.2-linux64.tar.bz2")
+        self.__run_command('ln -sf pypy-2.2-linux64 pypy')
+
+    if not self.__path_exists("py2"):
+        self.__download("http://www.python.org/ftp/python/2.7.6/Python-2.7.6.tgz")
+        self.__run_command("tar xzf Python-2.7.6.tgz")
+        self.__run_command("./configure --prefix=$HOME/FrameworkBenchmarks/installs/py2 --disable-shared CC=gcc-4.8", cwd="Python-2.7.6")
+        self.__run_command("make -j2", cwd="Python-2.7.6")
+        self.__run_command("make install", cwd="Python-2.7.6")
+
+    if not self.__path_exists("py3"):
+        self.__download("http://www.python.org/ftp/python/3.3.2/Python-3.3.2.tar.xz")
+        self.__run_command("tar xJf Python-3.3.2.tar.xz")
+        self.__run_command("./configure --prefix=$HOME/FrameworkBenchmarks/installs/py3 --disable-shared CC=gcc-4.8", cwd="Python-3.3.2")
+        self.__run_command("make -j2", cwd="Python-3.3.2")
+        self.__run_command("make install", cwd="Python-3.3.2")
 
     self.__download("https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py")
-    self.__run_command(pypy_bin + "/pypy ez_setup.py")
-    self.__run_command(python_bin + "/python ez_setup.py")
-    self.__run_command(python3_bin + "/python3 ez_setup.py")
+    if not self.__path_exists("easy_install", cwd=pypy_bin): self.__run_command(pypy_bin + "/pypy ez_setup.py")
+    if not self.__path_exists("easy_install", cwd=python_bin): self.__run_command(python_bin + "/python ez_setup.py")
+    if not self.__path_exists("easy_install", cwd=python3_bin): self.__run_command(python3_bin + "/python3 ez_setup.py")
 
     easy_install('pip==1.4.1', two=True, three=True, pypy=True)
     easy_install('MySQL-python==1.2.4', two=True, three=False, pypy=True)
@@ -405,7 +457,8 @@ class Installer:
     easy_install('flask==0.10.1', two=True, three=True, pypy=True)
     easy_install('sqlalchemy==0.8.3', two=True, three=False, pypy=True)
     # SQLAlchemy 0.9 supports C extension for Python 3
-    easy_install('https://bitbucket.org/zzzeek/sqlalchemy/downloads/SQLAlchemy-0.9.0b1.tar.gz', two=False, three=True)
+    easy_install('sqlalchemy==0.9.0', two=True, three=False, pypy=True)
+    # easy_install('https://bitbucket.org/zzzeek/sqlalchemy/downloads/SQLAlchemy-0.9.0b1.tar.gz', two=False, three=True)
     easy_install('Jinja2==2.7.1', two=True, three=True, pypy=True)
     easy_install('Flask-SQLAlchemy==1.0', two=True, three=True, pypy=True)
 
@@ -415,7 +468,7 @@ class Installer:
 
     # Falcon
     easy_install('Cython==0.19.2', two=True, three=True, pypy=True)
-    easy_install('falcon==0.1.7', two=True, three=True, pypy=True)
+    easy_install('falcon==0.1.8', two=True, three=True, pypy=True)
 
   ############################################################
   # __install_error
@@ -562,6 +615,22 @@ class Installer:
   # End __install_client_software
   ############################################################
 
+  ############################################################
+  # __path_exists
+  ############################################################
+  def __path_exists(self, path, cwd=None):
+    full_path = os.path.join(cwd or self.install_dir, path)
+
+    if os.path.exists(full_path):
+        print("\nEXISTS: %s " % full_path)
+        return True
+
+    print("\nNOT_EXISTS: %s" % full_path)
+    return False
+  ############################################################
+  # End __path_exists
+  ############################################################
+
   ############################################################
   # __run_command
   ############################################################
@@ -585,13 +654,13 @@ class Installer:
       try:
         # Execute command.
         if send_yes:
-          process = subprocess.Popen(command, shell=True, stdin=subprocess.PIPE, cwd=cwd)
+          process = subprocess.Popen(["/bin/bash", "-c", command], shell=False, stdin=subprocess.PIPE, cwd=cwd)
           process.communicate("yes")
           returncode = process.returncode
           if returncode:
             raise subprocess.CalledProcessError(returncode, command)
         else:
-          subprocess.check_call(command, shell=True, cwd=cwd)
+          subprocess.check_call(["/bin/bash", "-c", command], shell=False, cwd=cwd)
         break  # Exit loop if successful.
       except:
         exceptionType, exceptionValue, exceptionTraceBack = sys.exc_info()