jeff1evesque / iScanner

Backend iOS, and Android logic for facial, and iris recognition
1 stars 0 forks source link

Install, and setup Vagrant VM #4

Open jeff1evesque opened 9 years ago

jeff1evesque commented 9 years ago

Since we intend to develop non-UI logic with C++ (Objective-C for front-end), we will develop within a linux virtual machine. This will allow us to separate dependencies from different projects, and easier to deploy in a minimalistic fashion (not installing unneeded packages). Specifically, we will install, and setup Vagrant.

Note: this issue corresponds to https://github.com/jeff1evesque/machine-learning/issues/1393.

jeff1evesque commented 9 years ago

First we install vagrant, virtualbox, and download an image of Ubuntu Server 14.04:

wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.7.2_x86_64.deb
sudo dpkg --install vagrant_1.7.2_x86_64.deb
sudo apt-get install virtualbox
sudo apt-get install dkms
sudo mkdir /var/iso_images/
cd /var/iso_images/
wget http://releases.ubuntu.com/14.04.2/ubuntu-14.04.2-server-i386.iso

Note: the above ubuntu image is equivalent to eventually vagrant init ubuntu/trusty64 && vagrant up (except the ubuntu/trusty64 box provides puppet, and guest additions). Also, the dkms package is used to ensure that if the VirtualBox host kernel modules (vboxdrv, vboxnetflt, vboxnetadp) are properly updated if the linux kernel version changes during the next apt-get upgrade.

After assigning the installed ubuntu iso image to a VM instance, we get the following error when attempting to run the Ubuntu VM instance:

VT-x is disabled in the BIOS. (VERR_VMX_MSR_VMXON_DISABLED).

vbox-error

Quick research yields a suggestion to enable VT-x in the bios setup. However, the current machine being used is a dual boot between Windows 7, and Ubuntu 14.04 (windows being on the main partition).

Note: VT-x can have various different names depending on the system. For example, if the system is Intel, it may be Intel Virtualisation technology, or similar. Also, VT is generally disabled, by default, since most machines recommend it disabled unless specialized applications are being used.

In our case, we had to press the esc button, followed by F10 to enter bios. Then, scrolling over to the System Configuration tab, we set Virtualization Technology to Enabled. Upon saving the result, and booting into Ubuntu, we were able to access the above VM instance.

Note: the entered bios window, contained the following descriptive help text:

Hardware VT enables a processor feature for running multiple simultaneous Virtual Machines allowing specialized software application to run in full isolation of each other...

jeff1evesque commented 9 years ago

After starting up the VM instance, we install the corresponding Ubuntu iso image, therefore, define the following settings:

Vagrant assumes an account with default settings (i.e. username, and password) to exist within the operating system. Specifically, It will assume a username by vagrant, with the password vagrant to exist. This user will be responsible for accessing the machine (via SSH), configuring, and creating an instance of the box (spinup). Therefore, if the vagrant username doesn't exist, or the corresponding password is different, the Vagrantfile will need to be adjust, respectively.

Also, vagrant doesn't actually use, or expect any root password. However, having a generally well known root password makes it easier for the general public to modify the machine if needed. Also, publicly available base boxes usually use a root password of vagrant to keep things easy.

jeff1evesque commented 9 years ago

Guest Additions

Generally, it is recommended to install Virtualbox guest additions to add the following features:

The following will install guest additions on the Ubuntu guest:

sudo apt-get install virtualbox-guest-x11

Note: for best performance with USB devices, ensure VirtualBox extension pack is installed, and the same version as the VirtualBox.

Sudoless User

Sometimes, users can find entering password a hassle. To accommodate, the following will allow the vagrant user to execute commands without the sudo command:

visudo

Then add the following to the end of the file:

vagrant ALL=(ALL) NOPASSWD:ALL

Note: generally, after running the sudo command, successive sudo commands, will not require a password.

jeff1evesque commented 9 years ago

Recall that vagrant communicates from the host, to the guest machine over SSH. Therefore, this process requires a public, and private key. However, if the vagrant base box is to be distributed publicly, then both the public, and private key will need to be known by everyone. This means the vagrant will use an insecure key-pair.

The following steps sets up the public key on the base box:

mkdir -p /home/vagrant/.ssh
wget --no-check-certificate https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub -O /home/vagrant/.ssh/authorized_keys
# Ensure we have the correct permissions set
chmod 0700 /home/vagrant/.ssh
chmod 0600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant /home/vagrant/.ssh

This will allow the base box (containing the public key) to communicate with vagrant (containing the insecure private key). Also, according to the vagrant documentation, it is important to implement the exact file permission changes, since OpenSSH is very strict.

Note: vagrant documentation suggests using insecure key-pair.

Note: for a more secure setup, remove the trusted key from ~vagrant/.ssh/authorized_keys, create a custom key-pair, then configure the private key in the Vagrantfile with config.ssh.private_key_path, and change password for the user vagrant, and root.

jeff1evesque commented 9 years ago

Now, we should be able to create a Vagrant Base Box:

vagrant package –-base <VitualBox VM Name>

This box now can be shared via:

The latter approach is generally easier via the web-interface. However, it can be accomplished on the command line via the Atlas API.

Installing Box: from Atlas

cd [choose_directory]/
vagrant box add jeff1evesque/mybox
vagrant init --force --minimal jeff1esque/mybox
vagrant up

Note: replace jeff1evesque, and myBox with respect to the box stored on Atlas (or, alternate location). Also, if the box has already been installed (previous iteration), then the corresponding step can be ignored.

Alternatively, if the box may reside on an alternate location:

vagrant box add ubuntu/trusty64
vagrant init ubuntu/trusty64
vagrant up

Installing Box: from Local

cd [choose_directory]/
vagrant add /path/to/mybox
vagrant init
vagrant up

Note: mybox, is the locally stored vagrant box.

It is important to know, that the vagrant init command, generates the vagrantfile. This file is generally versioned (i.e. github). By versioning, we can simply execute either vagrant init, or vagrant add once. Then, if the VM instance is removed, successive installation instances (the same VM) requires just the vagrantfile (cloned from github), and the vagrant up command (since the box already exists).

Note: the vagrant box list will show all the boxes that have already been installed on the host machine.

Note: an alternative to creating a custom box, is to use preconfigured boxes by Atlas.

jeff1evesque commented 9 years ago

After cloning a git repository (containing a vagrantfile) on the host machine, then spinning up a VM instance, a /vagrant/ directory on the guest machine (VM Instance) will contain the mounted parent directory containing the vagrantfile from the host machine. In this case, it would be the directory containing the cloned git repository.

Therefore, modifying the git repository on the VM, would modify the same mounted directory on the host machine. This is one way to pass files into the box for pre-puppet (or chef) build (i.e. shell provisioner).

jeff1evesque commented 9 years ago

We temporarily comment out the minimal gnome-ui installation from default.pp:

# git: install git if not 'present'.
class git {
    package {'git':
        ensure => present,
    }
}

# gnome ui: install gnome-ui if not 'present' (double quote needed).
class gnome {
    $gnome_packages = ["xorg", "gnome-core", "gnome-system-tools", "gnome-app-install"]
#    package {$gnome_packages:
#        ensure => present,
#    }
}

# implement classes
include git
include gnome

After executing vagrant up, we get the following output:

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'ubuntu/trusty64'...
==> default: Matching MAC address for NAT networking
==> default: Checking if box 'ubuntu/trusty64' is up to date...
==> default: Setting the name of the VM: iScanner_default_1429966863487_9782
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
==> default: Forwarding ports...
==> default: 22 => 2222 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot.  This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout.  Retrying...
    default: Warning: Remote connection disconnect.  Retrying...
    default: 
    default: Vagrant insecure key detected.  Vagrant will automatically replace
    default: this with a newly generated keypair for better security
    default:
    default: Inserting generated public key within guest...
    default: Removing insercure key from the guest if its present
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Mounting shared folders...
    default: /vagrant => C:/Users/Jeffrey/iScanner
    default: /tmp/vagrant-puppet/manifests-a11324675765e76f66557bd3efb87767dde3 => C:/Users/Jeffrey/iScanner/manifests
==> default: Running provisioner: puppet...
==> default: Running Puppet with default.pp...
==> default: stdin: is not a tty
==> default: Notice: Compiled catalog for vagrant-ubuntu-trusty-64.wp.comcast.net in environment production in 0.18 seconds
==> default: Notice: /Stage[main]/Git/Package[git]/ensure: ensure change 'purged' to 'present'
==> default: Notice: Finished catalog run in 10.97 seconds

However, the VM box we created (Ubuntu Server) is initially running, and does not have a corresponding window. So, we goto the Virtualbox Manager, and explicitly Power Off the VM. Then, we were able to start the same VM on the next attempt, and have a desired corresponding VM window:

vm

However, when navigating to the /vagrant directory on the VM, we notice the directory is empty, and is not mounted with the directory on the host machine containing the Vagrantfile.

Note: the host machine is windows 7, the guest is ubuntu Server 14.04, Also, we have VirtualBox 4.3.26, as well as Vagrant 1.7.2.

Note: despite the above confusing output regarding git ensure change 'purged' to 'present', the git package installed successfully.

jeff1evesque commented 9 years ago

When we uncomment the following lines from our Vagrantfile:

...
  config.vm.provider "virtualbox" do |vb|
    # Display the VirtualBox GUI when booting the machine
    vb.gui = true

  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  end
...

Then, each time we run vagrant up, or vagrant reload, a VirtualBox GUI is run, respectively. After we login, we notice the /vagrant directory is properly mounted from the host machine:

vagrant-gui

Note: uncommenting the vb.gui = true logic can be useful during development, and testing.

However, if we sudo reboot, or perform any methods to power off the virtual machine, the /vagrant directory is no longer mounted on the VM on successive start ups:

vagrant-shared-gone

The reason for this, is because vagrant provisions the VM (guest), which includes mounting the directory between the host, and the guest /vagrant directory. So, if we reboot the VM (guest), then it has no idea to establish the mount with the host, since rebooting doesn't mean reprovisioning.

To remedy this problem: if the VM is rebooted, or powered off, then either two commands must be made on the host machine, in order to synch the shared (mounted) directory:

It is important to know that virtual machines should be destroyed via Vagrant, and not the virtual machine wrapper (i.e. VirtualBox, VMware). Instead, the command vagrant destroy can be made. If more than one VM exists, specify the machine name after the command.