# -*- mode: ruby -*-
# vi: set ft=ruby :

# This gives us the ability of resizing disks from the size put in 
# the Vagrant Box. Some OS may force you to use gparted or similar 
# to really take advantage of the extra space you put here. 
ENV['VAGRANT_EXPERIMENTAL'] = 'disks'

###################################################################
### 					GENERAL CONTROL VARIABLES 				###
###################################################################

# Please use only Vagrant Boxes from the Vagrant Cloud that come 
# from trusted or official providers!

## Machine Info:
## -------------

# This base Vagrant box supports VirtualBox, Hyper-V and VMWare Desktop.
BOX_NAME = "hashicorp/bionic64"

# The name of the box that will appear into the GUI 
MACHINE_NAME = "Ubuntu SSI Image"

# The description of the box that will show into the GUI 
MACHINE_DESCRIPTION = "The base Ubuntu image for the EII SSI course"

# Type of OS, needed for some of the Hypervisors
OS_TYPE = "Ubuntu_64"

# This determines the set of customization scripts that will be used
OS_CLASS = "debian"

## Machine Characteristics:
## ------------------------

# In Mb, if you can afford it, more memory is always welcome :). 
# Be careful not to push this too hard! 
RAM = 2048

# If you can afford it, more cores are always welcome :). 
# Be careful not to push this too hard!
CORES = 2

# Size of the box disk
DISK_SIZE = "80GB"

# Amount of available VRAM. Consider if your VM is going to have a GUI 
# or not to choose this.
VRAM = 128

# The name of the HD controller greatly varies depending on the box you use
HD_CONTROLLER = "SATA Controller"

## Virtualization parameters:
## --------------------------

# Change to false to run the machine in headless mode 
# (i. e. no VBox Window will be open)
GUI = true

# Audio device, or none for servers
AUDIO = "none"

# Turns on/off 3D acceleration. This does not behave too well on some Linux 
# distros if turned on right now (at least in VirtualBox) 
VIDEO_3D = "on"

# VirtualBox remote screen
VRDE = "off"

## Provisioning parameters:
## --------------------------

# Type of provisioner. I only use shell provisioners to not requiring installing 
# more software. But this makes it easy to incorporate Ansible, Puppet, 
# Chef or whatever automation you like!
PROVISION_TYPE = "shell"

# Provisioner file extension
PROVISION_FILE_EXTENSION = ".sh"

#######################################################################
### 				VIRTUAL MACHINE CONFIGURATION 					###
#######################################################################

Vagrant.configure("2") do |config|
  # For a complete reference, please see the online documentation at
  # https://docs.vagrantup.com.
  Vagrant.require_version ">= 2.1.18"

  config.vm.box = BOX_NAME
  config.vm.disk :disk, size: DISK_SIZE, primary: true

  # Copy the files required by the Box provisioner
  config.vm.provision "file", source: "../../../customization_files/" + \ 
    OS_CLASS + "_customization/", destination: "/home/vagrant/custom_files" 
  config.vm.provision "file", source: "../../../customization_scripts/" + \
    OS_CLASS + "_customization/", destination: "/home/vagrant/custom_scripts"
 
  # Automatically install software   
  config.vm.provision "Software Installation", type: PROVISION_TYPE, \ 
    path: "provisioners/" + PROVISION_TYPE + "/provision" + PROVISION_FILE_EXTENSION, \ 
    reboot: true 

  # This is the VirtualBox VM solution. Use this if you can, as it has more options and optimizations
  config.vm.provider "virtualbox" do |vb|
    vb.name = MACHINE_NAME  
    vb.memory = RAM
    vb.cpus = CORES
    vb.gui = GUI

    # Base configuration
    vb.customize ["modifyvm", :id, "--audio", AUDIO]        
    vb.customize ["modifyvm", :id, "--clipboard-mode", "bidirectional"]
    vb.customize ["modifyvm", :id, "--description", MACHINE_DESCRIPTION]    
    vb.customize ["modifyvm", :id, "--ostype", OS_TYPE]

    # High-performance configuration: please note that several of these options are not 
    # available in the VirtualBox GUI. Thus, the performance of this machine should be higher 
    # than the ones created via GUI

    # Use VBoxManage to customize the VM for high-performance options and other things
    vb.customize ["modifyvm", :id, "--acpi", "on"]
    vb.customize ["modifyvm", :id, "--accelerate3d", VIDEO_3D]
    vb.customize ["modifyvm", :id, "--apic", "on"]    
    vb.customize ["modifyvm", :id, "--biosapic", "x2apic"]  
    vb.customize ["modifyvm", :id, "--cpu-profile", "host"]
    vb.customize ["modifyvm", :id, "--graphicscontroller", "vmsvga"]
    vb.customize ["modifyvm", :id, "--hpet", "on"]
    vb.customize ["modifyvm", :id, "--hwvirtex", "on"]
    vb.customize ["modifyvm", :id, "--largepages", "on"]
    vb.customize ["modifyvm", :id, "--longmode", "on"]
    vb.customize ["modifyvm", :id, "--nestedpaging", "on"]            
    vb.customize ["modifyvm", :id, "--pae", "on"]
    # If you have a MAC host and get an error, comment this line, 
    # as this feature is not currently supported on MAC (yet)
    vb.customize ["modifyvm", :id, "--pagefusion", "on"]
    vb.customize ["modifyvm", :id, "--rtcuseutc", "on"]
    vb.customize ["modifyvm", :id, "--spec-ctrl", "off"]
    vb.customize ["modifyvm", :id, "--x2apic", "on"]
    vb.customize ["modifyvm", :id, "--vram", VRAM]
    vb.customize ["modifyvm", :id, "--vtxux", "on"]  
    vb.customize ["modifyvm", :id, "--vtxvpid", "on"]	
    vb.customize ["modifyvm", :id, "--vrde", VRDE]		    
    vb.customize ["storagectl", :id, "--name", HD_CONTROLLER, "--hostiocache", "on"]

    # Shared folder (host path, guest path)
    config.vm.synced_folder "./shared", "/host_data"     
  end

  # This is the Hyper-V solution, for Windows hosts. 
  # Vagrant provides much less control for Hyper-V guests. 
  # WARNING: Video might lag in GUI mode. 
  config.vm.provider "hyperv" do |hv|
    hv.vmname = MACHINE_NAME
    hv.memory = RAM
    hv.cpus = CORES
    
    # Shared folders in Hyper-V are disabled because it uses the vulnerable SMBv1 protocol.
    # Additionally, the base box used may not support SMB 
    config.vm.synced_folder ".", "/vagrant", disabled: true
    
    # This tries to give you the best possible Hyper-V user experience with the machine
    hv.enable_enhanced_session_mode = true
    hv.vm_integration_services = {
        guest_service_interface: true,
        heartbeat: true,
        key_value_pair_exchange: true,
        shutdown: true,
        time_synchronization: true,
        vss: true,
    }
  end

  # VMWare Desktop very basic configuration 
  config.vm.provider "vmware_desktop" do |vmw|
    # If you need to update this, search for "VMX file parameters"
    vmw.gui = GUI
    vmw.vmx["memsize"] = RAM
    vmw.vmx["numvcpus"] = CORES
    vmw.vmx["displayName"] = MACHINE_NAME
    vmw.vmx["svga.autodetect"] = "TRUE"
    vmw.vmx["sound.present"] = "FALSE"
  end
end
