Extend ONOS+P4 VM scripts to build tutorial VM

With Lubuntu desktop and P4-enabled code editors

Change-Id: I0c287c1d039da5f227d43994340b20a01ffc2617
diff --git a/tools/dev/p4vm/README.md b/tools/dev/p4vm/README.md
index 11cccd3..af56b8f 100644
--- a/tools/dev/p4vm/README.md
+++ b/tools/dev/p4vm/README.md
@@ -17,11 +17,18 @@
 - p4c (P4 compiler)
 - Mininet (network emulator)
 
+### Tutorial VM
+
+It is possible to generate a variant of the VM to be used during tutorials. This
+version of the VM comes with a Lubuntu desktop environment and various code
+editors with P4 syntax highlighting (vim, Sublime Text, and Atom).
+
 ## Recommended system requirements
 
-The VM is configured with 4 GB of RAM and 2 CPU cores, while the disk has size
-of approx. 8 GB. For a flawless experience we recommend running the VM on a host
-system that has at least the double of resources.
+The VM is configured with 4 GB of RAM and 2 CPU cores (4 cores for the tutorial
+variant), while the disk has size of approx. 8 GB. For a flawless experience we
+recommend running the VM on a host system that has at least the double of
+resources.
 
 These are the recommended minimum requirements to be able to run a Mininet
 network with 1-10 BMv2 devices controlled by 1 ONOS instance. To emulate larger
@@ -44,6 +51,9 @@
 Pre-built OVA package (approx. 3.5 GB):
 <http://onlab.vicci.org/onos/onos-p4-dev.ova>
 
+The tutorial variant of the OVA package can be found here (approx 5.5 GB):
+<http://onlab.vicci.org/onos/onos-p4-tutorial.ova>
+
 ### Login credentials
 
 The VM comes with one user with sudo privileges named `sdn` with password `rocks`.
@@ -57,7 +67,7 @@
 machine:
 
 - [Vagrant](https://www.vagrantup.com/) (tested v2.0.1)
-- [VirtualBox](https://www.virtualbox.org/wiki/Downloads) (tested with v5.2.2)
+- [VirtualBox](https://www.virtualbox.org/wiki/Downloads) (tested with v5.2.8)
 
 Optionally, to export the VM as an OVA package you will also need
 [sshpass](https://gist.github.com/arunoda/7790979).
@@ -99,3 +109,20 @@
 4. generate a file named `onos-p4-dev.ova`.
 
 The generated OVA file will have size of approx. 3.5-4 GB.
+
+### Building the tutorial VM
+
+To build the tutorial VM, simply set the environment variable `P4_VM_TYPE` to `tutorial` before building.
+
+For example:
+
+```bash
+P4_VM_TYPE=tutorial vagrant up
+```
+
+In alternative, to generate the OVA package:
+
+```bash
+P4_VM_TYPE=tutorial ./export-ova.sh
+```
+
diff --git a/tools/dev/p4vm/Vagrantfile b/tools/dev/p4vm/Vagrantfile
index 69580be..e6f124c 100644
--- a/tools/dev/p4vm/Vagrantfile
+++ b/tools/dev/p4vm/Vagrantfile
@@ -1,14 +1,24 @@
+P4_VM_TYPE = ENV['P4_VM_TYPE'] || "dev"
+
 Vagrant.configure(2) do |config|
   config.vm.box = "bento/ubuntu-16.04"
   config.vm.provider "virtualbox" do |vb|
-    vb.name = "ONOS-P4 Dev " + Time.now.strftime("(%Y-%m-%d)")
+    vb.name = "ONOS+P4 " + P4_VM_TYPE + " " + Time.now.strftime("(%Y-%m-%d)")
     vb.gui = true
-    vb.cpus = 2
+    vb.cpus = P4_VM_TYPE == "tutorial" ? 4 : 2
     vb.memory = 4096
+    if P4_VM_TYPE == "tutorial"
+        vb.customize ["storageattach", :id,
+                        "--storagectl", "IDE Controller",
+                        "--port", "0", "--device", "1",
+                        "--type", "dvddrive",
+                        "--medium", "emptydrive"]
+        vb.customize ['modifyvm', :id, '--clipboard', 'bidirectional']
+    end
   end
-  config.vm.hostname = "onos-p4-dev"
+  config.vm.hostname = "onos-p4-" + P4_VM_TYPE
   # By default vagrant creates a NAT interface.
   # Create a second one host-only.
   config.vm.network "private_network", :type => 'dhcp', :adapter => 2
-  config.vm.provision "shell", path: "root-bootstrap.sh"
+  config.vm.provision "shell", path: "root-bootstrap.sh", :args => P4_VM_TYPE
 end
diff --git a/tools/dev/p4vm/export-ova.sh b/tools/dev/p4vm/export-ova.sh
index 757f94b..32e1694 100755
--- a/tools/dev/p4vm/export-ova.sh
+++ b/tools/dev/p4vm/export-ova.sh
@@ -2,6 +2,8 @@
 
 set -xe
 
+VM_TYPE=${P4_VM_TYPE:-dev}
+
 # Remove references to the existing vagrant-built VM (if any).
 # We want to build a new one from scratch, not start an existing one.
 rm -rf .vagrant/
@@ -24,5 +26,5 @@
 # Remove vagrant shared folder
 vboxmanage sharedfolder remove ${VB_UUID} -name "vagrant"
 
-rm -rf onos-p4-dev.ova
-vboxmanage export ${VB_UUID} -o onos-p4-dev.ova
+rm -rf onos-p4-${VM_TYPE}.ova
+vboxmanage export ${VB_UUID} -o onos-p4-${VM_TYPE}.ova
diff --git a/tools/dev/p4vm/pre-ova-cleanup.sh b/tools/dev/p4vm/pre-ova-cleanup.sh
index 1f52148..e63c344 100755
--- a/tools/dev/p4vm/pre-ova-cleanup.sh
+++ b/tools/dev/p4vm/pre-ova-cleanup.sh
@@ -15,4 +15,6 @@
 rm -rf ~/p4tools/libyang/build
 rm -rf ~/p4tools/sysrepo/build
 
+sudo apt-get -y autoremove
+
 cat /dev/null > ~/.bash_history
diff --git a/tools/dev/p4vm/root-bootstrap.sh b/tools/dev/p4vm/root-bootstrap.sh
index ff23fc5..dfbfd46 100755
--- a/tools/dev/p4vm/root-bootstrap.sh
+++ b/tools/dev/p4vm/root-bootstrap.sh
@@ -1,6 +1,8 @@
 #!/bin/bash
 set -xe
 
+VM_TYPE=${1:-dev}
+
 # Create user sdn
 useradd -m -d /home/sdn -s /bin/bash sdn
 echo "sdn:rocks" | chpasswd
@@ -9,14 +11,34 @@
 usermod -aG vboxsf sdn
 update-locale LC_ALL="en_US.UTF-8"
 
+if [ ${VM_TYPE} = "tutorial" ]
+then
+    cp /vagrant/tutorial-bootstrap.sh /home/sdn/tutorial.sh
+    sudo chown sdn:sdn /home/sdn/tutorial.sh
+    su sdn <<'EOF'
+bash /home/sdn/tutorial.sh
+EOF
+    rm -rf /home/sdn/tutorial.sh
+fi
+
 # Java 8
 apt-get install software-properties-common -y
 add-apt-repository ppa:webupd8team/java -y
 apt-get update
 echo "oracle-java8-installer shared/accepted-oracle-license-v1-1 select true" | debconf-set-selections
 
-apt-get -y install \
-    oracle-java8-installer oracle-java8-set-default \
+# Workaround to: https://stackoverflow.com/questions/46815897/jdk-8-is-not-installed-error-404-not-found
+set +e
+apt-get install -y oracle-java8-installer
+set -e
+sed -i 's|JAVA_VERSION=8u161|JAVA_VERSION=8u171|' /var/lib/dpkg/info/oracle-java8-installer.*
+sed -i 's|PARTNER_URL=http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c3b165be4555a1fa6e98c45e0808/|PARTNER_URL=http://download.oracle.com/otn-pub/java/jdk/8u171-b11/512cd62ec5174c3487ac17c61aaa89e8/|' /var/lib/dpkg/info/oracle-java8-installer.*
+sed -i 's|SHA256SUM_TGZ="6dbc56a0e3310b69e91bb64db63a485bd7b6a8083f08e48047276380a0e2021e"|SHA256SUM_TGZ="b6dd2837efaaec4109b36cfbb94a774db100029f98b0d78be68c27bec0275982"|' /var/lib/dpkg/info/oracle-java8-installer.*
+sed -i 's|J_DIR=jdk1.8.0_161|J_DIR=jdk1.8.0_171|' /var/lib/dpkg/info/oracle-java8-installer.*
+
+apt-get -y --no-install-recommends install \
+    oracle-java8-installer \
+    oracle-java8-set-default \
     zip unzip \
     bridge-utils \
     avahi-daemon \
diff --git a/tools/dev/p4vm/tutorial-bootstrap.sh b/tools/dev/p4vm/tutorial-bootstrap.sh
new file mode 100755
index 0000000..0ec444d
--- /dev/null
+++ b/tools/dev/p4vm/tutorial-bootstrap.sh
@@ -0,0 +1,100 @@
+#!/usr/bin/env bash
+
+# Installs Lubuntu desktop and code editors.
+# Largely inspired by the P4.org tutorial VM scripts:
+# https://github.com/p4lang/tutorials/
+
+set -xe
+
+sudo add-apt-repository ppa:webupd8team/sublime-text-3 -y
+sudo add-apt-repository ppa:webupd8team/atom -y
+sudo apt-get update
+
+sudo DEBIAN_FRONTEND=noninteractive apt-get -y install wireshark
+echo "wireshark-common wireshark-common/install-setuid boolean true" | sudo debconf-set-selections
+sudo DEBIAN_FRONTEND=noninteractive dpkg-reconfigure wireshark-common
+
+sudo apt-get -y --no-install-recommends install \
+    lubuntu-desktop \
+    atom \
+    sublime-text-installer \
+    vim \
+    wget
+
+# Disable screensaver
+sudo apt-get -y remove light-locker
+
+# Automatically log into the SDN user
+cat << EOF | sudo tee -a /etc/lightdm/lightdm.conf.d/10-lightdm.conf
+[SeatDefaults]
+autologin-user=sdn
+autologin-user-timeout=0
+user-session=Lubuntu
+EOF
+
+# Vim
+cd /home/sdn
+mkdir -p .vim
+mkdir -p .vim/ftdetect
+mkdir -p .vim/syntax
+echo "au BufRead,BufNewFile *.p4      set filetype=p4" >> .vim/ftdetect/p4.vim
+echo "set bg=dark" >> .vimrc
+wget https://raw.githubusercontent.com/p4lang/tutorials/master/P4D2_2018_East/vm/p4.vim
+mv p4.vim .vim/syntax/p4.vim
+
+# Sublime
+cd /home/sdn
+mkdir -p ~/.config/sublime-text-3/Packages/
+cd .config/sublime-text-3/Packages/
+git clone https://github.com/c3m3gyanesh/p4-syntax-highlighter.git
+
+# Atom
+apm install language-p4
+
+# Adding Desktop icons
+DESKTOP=/home/sdn/Desktop
+mkdir -p ${DESKTOP}
+
+cat > ${DESKTOP}/Terminal << EOF
+[Desktop Entry]
+Encoding=UTF-8
+Type=Application
+Name=Terminal
+Name[en_US]=Terminal
+Icon=konsole
+Exec=/usr/bin/x-terminal-emulator
+Comment[en_US]=
+EOF
+
+cat > ${DESKTOP}/Wireshark << EOF
+[Desktop Entry]
+Encoding=UTF-8
+Type=Application
+Name=Wireshark
+Name[en_US]=Wireshark
+Icon=wireshark
+Exec=/usr/bin/wireshark
+Comment[en_US]=
+EOF
+
+cat > ${DESKTOP}/Sublime\ Text << EOF
+[Desktop Entry]
+Encoding=UTF-8
+Type=Application
+Name=Sublime Text
+Name[en_US]=Sublime Text
+Icon=sublime-text
+Exec=/opt/sublime_text/sublime_text
+Comment[en_US]=
+EOF
+
+cat > ${DESKTOP}/Atom << EOF
+[Desktop Entry]
+Encoding=UTF-8
+Type=Application
+Name=Atom
+Name[en_US]=Atom
+Icon=atom
+Exec=/usr/bin/atom
+Comment[en_US]=
+EOF
diff --git a/tools/dev/p4vm/upload-ova.sh b/tools/dev/p4vm/upload-ova.sh
index 93d5012..0b2cfd3 100755
--- a/tools/dev/p4vm/upload-ova.sh
+++ b/tools/dev/p4vm/upload-ova.sh
@@ -1,4 +1,6 @@
 #!/usr/bin/env bash
 
-python $ONOS_ROOT/tools/build/uploadToS3.py -f onos-p4-dev.ova ./onos-p4-dev.ova
+VM_TYPE=${P4_VM_TYPE:-dev}
+
+python $ONOS_ROOT/tools/build/uploadToS3.py -f onos-p4-${VM_TYPE}.ova ./onos-p4-${VM_TYPE}.ova
 
diff --git a/tools/dev/p4vm/user-bootstrap.sh b/tools/dev/p4vm/user-bootstrap.sh
index b7a7739..fdbaf5b 100755
--- a/tools/dev/p4vm/user-bootstrap.sh
+++ b/tools/dev/p4vm/user-bootstrap.sh
@@ -7,7 +7,7 @@
 
 # ONOS
 git clone https://github.com/opennetworkinglab/onos.git
-tee -a ~/.profile <<EOF
+tee -a ~/.bashrc <<EOF
 
 # ONOS
 export ONOS_ROOT=~/onos