Import VM setup scripts

Imported from:
https://robotics.mvla.net/svn/frc971/2016/trunk/src/vagrant_dev_vm/

Change-Id: I4b4c50262d24b1c5d293f4a518525ee28c6db003
diff --git a/vm/README.md b/vm/README.md
new file mode 100644
index 0000000..6c50d2d
--- /dev/null
+++ b/vm/README.md
@@ -0,0 +1,66 @@
+Requirements
+--------------------------------------------------------------------------------
+1. Install Vagrant <https://www.vagrantup.com/downloads.html>
+
+1. Install VirtualBox <https://www.virtualbox.org/wiki/Downloads>
+
+1. Add `vagrant` and `VBoxManage` to your PATH.
+    - This is most likely already done by the installation binaries.
+      It's added to the system path.
+    - To test this, type these commands in a terminal:
+
+            ~$ vagrant --version
+            Vagrant 1.8.1
+            ~$ VBoxManage --version
+            5.0.14r105127
+
+    - You may need to log out and back in for the path modifications to take
+      effect.
+
+1. On my Jessie installation I had to apply the following patch before I could
+   successfully shut down and reboot the VM.
+
+        --- /opt/vagrant/embedded/gems/gems/vagrant-1.7.4/plugins/guests/debian8/cap/halt.rb    2015-07-17 13:15:13.000000000 -0700
+        +++ new_halt.rb 2015-11-18 20:11:29.003055639 -0800
+        @@ -4,7 +4,7 @@
+               class Halt
+                 def self.halt(machine)
+                   begin
+        -            machine.communicate.sudo("shutdown -h -H")
+        +            machine.communicate.sudo("systemctl poweroff")
+                   rescue IOError
+                     # Do nothing, because it probably means the machine shut down
+                     # and SSH connection was lost.
+
+Usage
+--------------------------------------------------------------------------------
+1. Check this folder out on your computer somewhere.
+
+        svn co https://robotics.mvla.net/svn/frc971/2016/trunk/src/vagrant_dev_vm
+
+1. Go into the directory and build the VM.
+
+        vagrant up
+
+1. Some errors during the `vagrant up` process can be addressed by
+   re-provisioning the vagrant box. This is useful if, for example, an
+   `apt-get` invocation timed out and caused the provisioning process to abort.
+
+        vagrant provision
+
+1. Once build, reboot the VM so it starts the GUI properly.
+
+        vagrant reload
+
+1. You can then log in and open a terminal. The username and password are both
+   `vagrant`. Or you can SSH in from the host.
+
+        vagrant ssh
+
+1. Download the code and build it.
+
+        git clone https://USERNAME@robotics.mvla.net/gerrit/971-Robot-Code
+        cd 971-Robot-Code
+        bazel build //y2016/... -- $(cat NO_BUILD_AMD64)
+
+   where USERNAME is the same username you use to log into SVN.
diff --git a/vm/Vagrantfile b/vm/Vagrantfile
new file mode 100644
index 0000000..c802a5a
--- /dev/null
+++ b/vm/Vagrantfile
@@ -0,0 +1,57 @@
+# Vagrantfile API/syntax version. Don't touch unless you know what you're
+# doing!
+VAGRANTFILE_API_VERSION = "2"
+
+# Install the necessary plugins.
+required_plugins = %w( vagrant-persistent-storage )
+required_plugins.each do |plugin|
+  unless Vagrant.has_plugin? plugin || ARGV[0] == 'plugin' then
+    exec "vagrant plugin install #{plugin};vagrant #{ARGV.join(" ")}"
+  end
+end
+
+Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
+  # All Vagrant configuration is done here. The most common configuration
+  # options are documented and commented below. For a complete reference,
+  # please see the online documentation at vagrantup.com.
+
+  # Every Vagrant virtual environment requires a box to build off of.
+  config.vm.box = "debian/jessie64"
+
+  config.vm.provider "virtualbox" do |vb|
+    # Don't boot with headless mode
+    vb.gui = true
+    vb.name = "FRC971-Development-2016"
+
+    # There are two shortcuts for modifying number of CPUs and amount of
+    # memory. Modify them to your liking.
+    vb.cpus = 2
+    vb.memory = 1024 * 2
+  end
+
+  # Use rsync to sync the /vagrant folder.
+  # NOTE: If you change these settings they will not take effect until you
+  # reboot the VM -- i.e. run a "vagrant reload".
+  config.vm.synced_folder ".", "/vagrant", type: "rsync",
+      rsync__exclude: [".git/", ".svn/", "workspace.vdi"], rsync__verbose: true
+
+  # Set up apt and install packages necessary for building the code.
+  config.vm.provision :shell, inline: "/vagrant/setup_apt.sh"
+  config.vm.provision :shell, inline: "/vagrant/setup_extra_storage.sh"
+  config.vm.provision :shell, inline: "/vagrant/setup_code_building.sh"
+  config.vm.provision :shell, inline: "/vagrant/setup_scouting.sh"
+  config.vm.provision :shell, inline: "/vagrant/setup_desktop.sh"
+  config.vm.provision :shell, inline: "/vagrant/setup_misc_packages.sh"
+  config.vm.provision :shell, inline: "/vagrant/setup_vbox_guest_additions.sh"
+
+  # Add a second disk so we have plenty of space to compile the code.
+  config.persistent_storage.enabled = true
+  config.persistent_storage.location = "workspace.vdi"
+  config.persistent_storage.size = 40000 # MiB
+  config.persistent_storage.use_lvm = false
+  config.persistent_storage.filesystem = 'ext4'
+  config.persistent_storage.mountpoint = '/home/user'
+
+  # Forward the scouting app's port.
+  config.vm.network :forwarded_port, guest: 5000, host: 5000, auto_correct: true
+end
diff --git a/vm/setup_apt.sh b/vm/setup_apt.sh
new file mode 100755
index 0000000..d31a372
--- /dev/null
+++ b/vm/setup_apt.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+
+export DEBIAN_FRONTEND=noninteractive
+
+# Set up contrib and non-free so we can install some more interesting programs.
+cat > /etc/apt/sources.list.d/contrib.list <<EOT
+deb  http://ftp.us.debian.org/debian/ jessie contrib non-free
+deb-src  http://ftp.us.debian.org/debian/ jessie contrib non-free
+EOT
+
+# Get a list of the latest packages.
+apt-get update
diff --git a/vm/setup_code_building.sh b/vm/setup_code_building.sh
new file mode 100755
index 0000000..a27b60e
--- /dev/null
+++ b/vm/setup_code_building.sh
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+
+export DEBIAN_FRONTEND=noninteractive
+
+readonly PKGS=(
+  bazel
+  clang-3.6
+  clang-format-3.5
+  gfortran
+  git
+  libblas-dev
+  liblapack-dev
+  libpython3-dev
+  libpython-dev
+  python3
+  python3-matplotlib
+  python3-numpy
+  python3-scipy
+  python-matplotlib
+  python-scipy
+  resolvconf
+  ruby
+)
+
+# Set up the backports repo.
+cat > /etc/apt/sources.list.d/backports.list <<EOT
+deb http://http.debian.net/debian jessie-backports main
+EOT
+
+# Set up the LLVM repo.
+cat > /etc/apt/sources.list.d/llvm-3.6.list <<EOT
+deb  http://llvm.org/apt/jessie/ llvm-toolchain-jessie-3.6 main
+deb-src  http://llvm.org/apt/jessie/ llvm-toolchain-jessie-3.6 main
+EOT
+
+# Set up the 971-managed bazel repo.
+cat > /etc/apt/sources.list.d/bazel-971.list <<EOT
+deb http://robotics.mvla.net/files/frc971/packages jessie main
+EOT
+
+# Enable user namespace for sandboxing.
+cat > /etc/sysctl.d/99-enable-user-namespaces.conf <<EOT
+kernel.unprivileged_userns_clone = 1
+EOT
+
+# Accept the LLVM GPG key so we can install their packages.
+wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | apt-key add -
+
+# Install all the packages that we need/want.
+apt-get update
+for pkg in "${PKGS[@]}"; do
+  apt-get install -y -f --force-yes "$pkg"
+done
diff --git a/vm/setup_desktop.sh b/vm/setup_desktop.sh
new file mode 100755
index 0000000..d713856
--- /dev/null
+++ b/vm/setup_desktop.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+
+export DEBIAN_FRONTEND=noninteractive
+
+readonly PKGS=(
+  iceweasel
+  lightdm
+  mousepad
+  xfce4
+  xfce4-terminal
+)
+
+# Install all the packages that we need/want.
+for pkg in "${PKGS[@]}"; do
+  apt-get install -y -f "$pkg"
+done
diff --git a/vm/setup_extra_storage.sh b/vm/setup_extra_storage.sh
new file mode 100755
index 0000000..5fcf4cb
--- /dev/null
+++ b/vm/setup_extra_storage.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+
+readonly EXTRA_USER=user
+readonly EXTRA_STORAGE=/home/"${EXTRA_USER}"
+
+if ! grep -q "$EXTRA_STORAGE" /etc/passwd; then
+  PASSWORD="$(echo "$EXTRA_USER" | mkpasswd -s)"
+  useradd \
+      --home="$EXTRA_STORAGE" -M \
+      --password="$PASSWORD" \
+      --shell=/bin/bash \
+      "$EXTRA_USER"
+  chown "$EXTRA_USER:$EXTRA_USER" "$EXTRA_STORAGE"
+fi
+
+usermod -a -G sudo "$EXTRA_USER"
diff --git a/vm/setup_misc_packages.sh b/vm/setup_misc_packages.sh
new file mode 100755
index 0000000..691b2be
--- /dev/null
+++ b/vm/setup_misc_packages.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+
+export DEBIAN_FRONTEND=noninteractive
+
+readonly PKGS=(
+  colordiff
+  tmux
+  vim
+)
+
+# Install all the packages that we want.
+for pkg in "${PKGS[@]}"; do
+  apt-get install -y -f "$pkg"
+done
diff --git a/vm/setup_scouting.sh b/vm/setup_scouting.sh
new file mode 100755
index 0000000..3360ff5
--- /dev/null
+++ b/vm/setup_scouting.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+
+export DEBIAN_FRONTEND=noninteractive
+
+readonly PKGS=(
+  python3
+  python3-flask
+)
+
+# Install all the packages that we need/want.
+apt-get update
+for pkg in "${PKGS[@]}"; do
+  apt-get install -y -f --force-yes "$pkg"
+done
diff --git a/vm/setup_vbox_guest_additions.sh b/vm/setup_vbox_guest_additions.sh
new file mode 100755
index 0000000..c9f4b09
--- /dev/null
+++ b/vm/setup_vbox_guest_additions.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+set -e
+set -u
+
+export DEBIAN_FRONTEND=noninteractive
+
+# Install the kernel sources before the guest additions to guarantee that
+# we can compile the kernel module.
+apt-get install -q -y linux-headers-amd64
+
+# Now we can install the guest additions.
+apt-get install -q -y \
+    virtualbox-guest-dkms \
+    virtualbox-guest-x11