diff --git a/.gitignore b/.gitignore
index ae8f5af9860d156c833bc26b04455657c6fbc3cb..39b73cdda0020fff0f4afa6953ddbf898cd282b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ packer/output-*
 *.pvm
 *.pyc
 *~
-macos*/
-images/
+iso/
+ovf/
+ova/
 xcode/
diff --git a/packer/ovf.json b/packer/ovf.json
new file mode 100644
index 0000000000000000000000000000000000000000..7d2b1ac04ae2e8913cce683fafea8a262d02f912
--- /dev/null
+++ b/packer/ovf.json
@@ -0,0 +1,44 @@
+{
+  "builders": [
+    {
+      "boot_wait": "2s",
+      "disk_size": 40960,
+      "guest_additions_mode": "disable",
+      "guest_os_type": "{{user `guest_os_type`}}",
+      "hard_drive_interface": "sata",
+      "iso_checksum_type": "none",
+      "iso_interface": "sata",
+      "iso_url": "{{user `dmg_url`}}",
+      "output_directory": "{{user `output_directory`}}",
+      "vm_name": "{{ user `machine_name`}}",
+      "shutdown_command": "echo '{{user `username`}}'|sudo -S shutdown -h now",
+      "ssh_port": 22,
+      "ssh_username": "{{user `username`}}",
+      "ssh_password": "{{user `password`}}",
+      "ssh_wait_timeout": "10000s",
+      "type": "virtualbox-iso",
+      "vboxmanage": [
+        ["modifyvm", "{{.Name}}", "--audiocontroller", "hda"],
+        ["modifyvm", "{{.Name}}", "--boot1", "dvd"],
+        ["modifyvm", "{{.Name}}", "--boot2", "disk"],
+        ["modifyvm", "{{.Name}}", "--chipset", "ich9"],
+        ["modifyvm", "{{.Name}}", "--firmware", "efi"],
+        ["modifyvm", "{{.Name}}", "--hpet", "on"],
+        ["modifyvm", "{{.Name}}", "--keyboard", "usb"],
+        ["modifyvm", "{{.Name}}", "--memory", "2048"],
+        ["modifyvm", "{{.Name}}", "--mouse", "usbtablet"],
+        ["modifyvm", "{{.Name}}", "--vram", "128"],
+        ["storagectl", "{{.Name}}", "--name", "IDE Controller", "--remove"]
+      ]
+    }
+  ],
+  "min_packer_version": "0.7.0",
+  "variables": {
+    "dmg_url": "OSX_InstallESD_10.9.5_13F34.dmg",
+    "guest_os_type": "MacOS109_64",
+    "machine_name": "macos109",
+    "output_directory": "{{env `PACKER_OUTPUT_DIR`}}",
+    "password": "gitlab",
+    "username": "gitlab"
+  }
+}
diff --git a/packer/template.json b/packer/provision.json
similarity index 73%
rename from packer/template.json
rename to packer/provision.json
index a8b5b58c2d45328da99e0d54aaa77cf7c897a7b9..a94fabf79f6d0d48bb74b320dd30c2e5a72eba5b 100644
--- a/packer/template.json
+++ b/packer/provision.json
@@ -2,32 +2,26 @@
   "builders": [
     {
       "boot_wait": "2s",
-      "disk_size": 40960,
       "guest_additions_mode": "disable",
-      "guest_os_type": "{{user `guest_os_type`}}",
-      "hard_drive_interface": "sata",
-      "iso_checksum_type": "none",
-      "iso_interface": "sata",
-      "iso_url": "{{user `iso_url`}}",
-      "output_directory": "{{user `output_directory`}}",
+      "source_path": "{{user `source_path`}}",
       "shutdown_command": "echo '{{user `username`}}'|sudo -S shutdown -h now",
       "ssh_port": 22,
       "ssh_username": "{{user `username`}}",
       "ssh_password": "{{user `password`}}",
-      "ssh_wait_timeout": "10000s",
-      "type": "virtualbox-iso",
+      "ssh_wait_timeout": "100s",
+      "type": "virtualbox-ovf",
+      "output_directory": "{{user `output_directory`}}",
+      "vm_name": "{{ user `machine_name`}}",
+      "format": "ova",
       "vboxmanage": [
         ["modifyvm", "{{.Name}}", "--audiocontroller", "hda"],
-        ["modifyvm", "{{.Name}}", "--boot1", "dvd"],
-        ["modifyvm", "{{.Name}}", "--boot2", "disk"],
         ["modifyvm", "{{.Name}}", "--chipset", "ich9"],
         ["modifyvm", "{{.Name}}", "--firmware", "efi"],
         ["modifyvm", "{{.Name}}", "--hpet", "on"],
         ["modifyvm", "{{.Name}}", "--keyboard", "usb"],
-        ["modifyvm", "{{.Name}}", "--memory", "2048"],
+        ["modifyvm", "{{.Name}}", "--memory", "4096"],
         ["modifyvm", "{{.Name}}", "--mouse", "usbtablet"],
-        ["modifyvm", "{{.Name}}", "--vram", "128"],
-        ["storagectl", "{{.Name}}", "--name", "IDE Controller", "--remove"]
+        ["modifyvm", "{{.Name}}", "--vram", "128"]
       ]
     }
   ],
@@ -64,7 +58,6 @@
         "../scripts/shrink.sh"
       ],
       "environment_vars": [
-        "AUTOLOGIN={{user `autologin`}}",
         "XCODE_SDK_VERSION={{user `xcode_sdk_version`}}",
         "PASSWORD={{user `password`}}",
         "USERNAME={{user `username`}}",
@@ -74,12 +67,11 @@
     }
   ],
   "variables": {
-    "autologin": "true",
-    "iso_url": "OSX_InstallESD_10.9.5_13F34.dmg",
+    "source_path": "ovf/macos109.ovf",
     "guest_os_type": "MacOS109_64",
     "machine_name": "macos109",
     "xcode_sdk_version": "109",
-    "output_directory": "{{env `PACKER_OUTPUT_DIR`}}",
+    "output_directory": "ova/macosx109.ova",
     "password": "gitlab",
     "username": "gitlab",
     "provisioning_delay": "0"
diff --git a/prepare_iso/prepare_iso.sh b/prepare_iso/prepare_iso.sh
index 6ad58eb1fb7e228f01c96e79d6d62424d978f147..e57d6e5fb76bd4c9fcf7fb6c10a3dcbbbac12513 100755
--- a/prepare_iso/prepare_iso.sh
+++ b/prepare_iso/prepare_iso.sh
@@ -1,9 +1,9 @@
 #!/bin/sh -e
 #
 # Preparation script for an OS X automated installation for use with VeeWee/Packer/Vagrant
-# 
+#
 # What the script does, in more detail:
-# 
+#
 # 1. Mounts the InstallESD.dmg using a shadow file, so the original DMG is left
 #    unchanged.
 # 2. Modifies the BaseSystem.dmg within in order to add an additional 'rc.cdrom.local'
@@ -12,7 +12,7 @@
 #    'disk0', presumably the hard disk attached to the VM.
 # 3. A 'veewee-config.pkg' installer package is built, which is added to the OS X
 #    install by way of the OSInstall.collection file. This package creates the
-#    'vagrant' user, configures sshd and sudoers, and disables setup assistants.
+#    'gitlab' user, configures sshd and sudoers, and disables setup assistants.
 # 4. veewee-config.pkg and the various support utilities are copied, and the disk
 #    image is saved to the output path.
 #
@@ -41,13 +41,13 @@ used to perform an automated installation. The new image will be named
 
 Optional switches:
   -u <user>
-    Sets the username of the root user, defaults to 'vagrant'.
+    Sets the username of the root user, defaults to 'gitlab'.
 
   -p <password>
-    Sets the password of the root user, defaults to 'vagrant'.
+    Sets the password of the root user, defaults to 'gitlab'.
 
   -i <path to image>
-    Sets the path of the avatar image for the root user, defaulting to the vagrant icon.
+    Sets the path of the avatar image for the root user, defaulting to the gitlab icon.
 
   -D <flag>
     Sets the specified flag. Valid flags are:
@@ -87,9 +87,9 @@ FIRST_BOOT_PKG_SCRIPT="$SCRIPT_DIR/create_firstboot_pkg.sh"
 [ -f "$FIRST_BOOT_PKG_SCRIPT" ] && . "$FIRST_BOOT_PKG_SCRIPT"
 
 # Parse the optional command line switches
-USER="vagrant"
-PASSWORD="vagrant"
-IMAGE_PATH="$SUPPORT_DIR/vagrant.jpg"
+USER="gitlab"
+PASSWORD="gitlab"
+IMAGE_PATH="$SUPPORT_DIR/gitlab.jpg"
 
 # Flags
 DISABLE_REMOTE_MANAGEMENT=0
@@ -184,7 +184,7 @@ MNT_ESD=$(/usr/bin/mktemp -d /tmp/veewee-osx-esd.XXXX)
 SHADOW_FILE=$(/usr/bin/mktemp /tmp/veewee-osx-shadow.XXXX)
 rm "$SHADOW_FILE"
 msg_status "Attaching input OS X installer image with shadow file.."
-hdiutil attach "$ESD" -mountpoint "$MNT_ESD" -shadow "$SHADOW_FILE" -nobrowse -owners on 
+hdiutil attach "$ESD" -mountpoint "$MNT_ESD" -shadow "$SHADOW_FILE" -nobrowse -owners on
 if [ $? -ne 0 ]; then
 	[ ! -e "$ESD" ] && msg_error "Could not find $ESD in $(pwd)"
 	msg_error "Could not mount $ESD on $MNT_ESD"
diff --git a/prepare_iso/support/gitlab.jpg b/prepare_iso/support/gitlab.jpg
index 5402cb9a35fdd7e253acb94ffa6006d4e061d840..19176dcb7e3ae9f98fcac7f110fb5e59a6faec98 100644
Binary files a/prepare_iso/support/gitlab.jpg and b/prepare_iso/support/gitlab.jpg differ
diff --git a/prepare_iso/support/gitlab.png b/prepare_iso/support/gitlab.png
index 16d2d492a0cb339f55234ee4807524df73d876a1..d753914bc3d2e04282f75831ef6157a8a94b14cf 100644
Binary files a/prepare_iso/support/gitlab.png and b/prepare_iso/support/gitlab.png differ
diff --git a/run.sh b/run.sh
index 5d41c676692d0cdab584746c4af4dcb39323e1c0..f4bdeb0183b05f672872f2c11b006e58476402ea 100755
--- a/run.sh
+++ b/run.sh
@@ -3,7 +3,15 @@
 # Original package: https://github.com/timsutton/osx-vm-templates
 
 # This script will use the setup in this package to create a virtual image for
-# macOS following the specifications on its header.
+# macOS following the specifications of the provided version number.
+# The build happens in 3 stages:
+#
+# 1. An installable DMG is created from the original Apple installation app
+# 2. A basic OVF image containing the installed ISO is generated
+# 3. The final OVA image is created by provisioning the OVF image
+#
+# It is done in 3 stages so that provisioning can be tested in a faster test
+# loop given points 1 and 2 can be very long.
 
 if [[ "$#" == "0" ]]; then
 	echo "usage: $0 <macos-version>"
@@ -15,17 +23,21 @@ fi
 username=gitlab
 password=gitlab
 curdir=`pwd`
-outdir="${curdir}/images"
+dmgdir="${curdir}/dmg"
+ovfdir="${curdir}/ovf"
+ovadir="${curdir}/ova"
 
 # Expected app and image names (cannot really guess - wait for outputs and set
 # as appropriate)
 if [[ "$1" == "10.9" ]]; then
 	app="/Applications/Install OS X Mavericks.app"
-	image="${outdir}/OSX_InstallESD_10.9.5_13F34.dmg"
-  guest_os_type="MacOS109_64"
-  machine_name="macos109"
-  xcode_sdk_version="109"
-  boxdir="${curdir}/macos10.9"
+	dmg="${dmgdir}/OSX_InstallESD_10.9.5_13F34.dmg"
+  short_ver=${1/./}
+  xcode_sdk_version=${short_ver}
+  machine_name="macos${short_ver}"
+  guest_os_type="MacOS${short_ver}_64"
+  ovf="${ovfdir}/${machine_name}.ovf"
+  ova="${ovadir}/${machine_name}.ova"
 else
 	echo "Version $1 is currently unsupported"
 	exit 1
@@ -49,33 +61,59 @@ fi
 echo "Building virtualbox machine for macOS $1..."
 echo "username = ${username}"
 echo "password = ${password}"
-echo "out dir. = ${outdir}"
 echo "app      = ${app}"
-echo "image    = ${image}"
 echo "os type  = ${guest_os_type}"
 echo "name     = ${machine_name}"
 echo "sdk vers.= ${xcode_sdk_version}"
+echo "dmg      = ${dmg}"
+echo "ovf      = ${ovf}"
+echo "ova      = ${ova}"
 
-if [ ! -r "${image}" ]; then
+if [ ! -r "${dmg}" ]; then
+  echo "Stage 1: [$(basename ${app})] -> [$(basename ${dmg})]"
 	sudo prepare_iso/prepare_iso.sh \
 		-u ${username} \
 		-p ${password} \
 		-i prepare_iso/support/gitlab.jpg \
 		-D DISABLE_REMOTE_MANAGEMENT \
-		"${image}" "${outdir}"
+		"${app}" "${dmgdir}"
+else
+  echo "Skipping stage 1: [$(basename ${dmg})] exists. Remove to force rebuild."
+fi
+
+if [ ! -r "${ovf}" ]; then
+  echo "Stage 2: [$(basename ${dmg})] -> [$(basename ${ovf})]"
+  packer build \
+    -on-error=ask \
+    -only virtualbox-iso \
+    -var dmg_url="${dmg}" \
+    -var guest_os_type="${guest_os_type}" \
+    -var output_directory="${ovfdir}" \
+    -var machine_name="${machine_name}" \
+    -var username="${username}" \
+    -var password="${password}" \
+    packer/ovf.json
+else
+  echo "Skipping stage 2: [$(basename ${ovf})] exists. Remove to force rebuild."
 fi
 
-#-var update_system=0 \
-cd packer && \
-packer build \
-  -on-error=ask \
-  -only virtualbox-iso \
-  -var iso_url="${image}" \
-  -var output_directory="${boxdir}" \
-  -var guest_os_type="${guest_os_type}" \
-  -var machine_name="${machine_name}" \
-  -var xcode_sdk_version="${xcode_sdk_version}" \
-  -var username="${username}" \
-  -var password="${password}" \
-  -var provisioning_delay=30 \
-  template.json
+exit 1
+
+if [ ! -r "${ovf2}" ]; then
+  echo "Stage 3: [$(basename ${ovf})] -> provision -> [$(basename ${ova})]"
+  cd ovf_to_ovf && \
+  packer build \
+    -on-error=ask \
+    -only virtualbox-ovf \
+    -var source_path="${ovf}" \
+    -var guest_os_type="${guest_os_type}" \
+    -var output_directory="${ovadir}" \
+    -var machine_name="${machine_name}" \
+    -var xcode_sdk_version="${xcode_sdk_version}" \
+    -var username="${username}" \
+    -var password="${password}" \
+    -var provisioning_delay=30 \
+    template.json
+else
+  echo "Skipping stage 3: [$(basename ${ova})] exists. Remove to force rebuild."
+fi
diff --git a/scripts/autologin.sh b/scripts/autologin.sh
index b7d342c06674e79288a7c2df07c69b527edaf1a3..1cafc8ee16f036248a467f1b1655674cbcc6ceae 100755
--- a/scripts/autologin.sh
+++ b/scripts/autologin.sh
@@ -1,7 +1,3 @@
-if [ "$AUTOLOGIN" != "true" ] && [ "$AUTOLOGIN" != "1" ]; then
-  exit
-fi
-
 echo "Enabling automatic GUI login for the '$USERNAME' user.."
 
 python /private/tmp/set_kcpassword.py "$PASSWORD"
diff --git a/scripts/xcode-sdk.sh b/scripts/xcode-sdk.sh
old mode 100644
new mode 100755