Before We Begin
Some precautionary notes to be aware of:
- A virtual machine with OS X is going to be large. An OS X base box will be approximately 5.65GB. This exceeds the recommended box size Vagrant states for portability. This is unavoidable. Bare it in mind and ensure you have the disk space, in addition to the patience when spawning boxes. Larger boxes take longer to download and clone. As I am doing this for development and administration purposes, the spawn times are acceptable for the sake of repeatable testing. To reduce pull times you might want to host the box on a local HTTP server inside your network rather than on the Cloud, but this is optional.
- Your version of Vagrant MUST be 1.3.0 or higher. Support for OS X didn’t exist without work arounds and hacks prior to 1.3.0.
This article has been tested with the following:
- Apple OS X Mountain Lion (Host & Guest)
- VMware Fusion 5.0.3
- Vagrant 1.3.5
- Vagrant’s plugin vagrant-vmware-fusion 2.0.8
Note: An OS X Mavericks Host & Guest will follow the same steps but will require VMware Fusion 6.x at minimum.
Creating an OS X Virtual Machine in VMware Fusion
Create a new virtual machine in VMware Fusion.
If you are unfamiliar with creating a OS X VMware Fusion VM leave requests for a tutorial. Otherwise I am going to make assumptions you know how to do this at present. Things to note when creating the virtual machine in VMware Fusion:
- When saving the VM, change the name of the file to mountain64-1_vmware.vmwarevm.
- Change the virtual machine hard disk settings not to split the hard drive into 2GB files.
- On the first boot of the system, the initial user fields Full Name, Username, and Password are populated with
Configuring the Guest OS
All steps should be considered within the Guest OS unless otherwise stated.
Install VMware Tools
As the first step we’ll install VMware Tools to allow for copy/pasting between the Host and Guest.
On the Host with VMware Fusion selected:
- From the Apple menu bar select Virtual Machine > Update VMware Tools… The menu option may also read Install VMware Tools, Reinstall VMware Tools or Update VMware Tools.
- Click Install on the dialog that opens.
On the Guest:
- Once the disk image is mount. Double-click the Install Vmware Tools package.
- Follow the default prompts until the installation completes. Note the installation will prompt you for your Administrator’s password.
- Restart once the installation completes.
- Log back in when prompted.
You can now copy/paste commands between the Host and Guest for the remainder of this article, if desired.
Updating the OS
To reduce the number of updates needed each time the box spawns run software updates.
- Open the Terminal and run:
$ sudo softwareupdate --install --all
- Wait for the updates to complete. Reboot. Repeat as necessary or until no further updates are available.
Disable the Firewall in OS X
OS X defaults the firewall settings to disabled. Ensure this is the case by validating your Security & Privacy settings.
- Navigate to System Preferences > Security & Privacy.
- Select the Firewall tab view.
- Ensure the Firewall is Off.
This article isn’t about security of a box, so the firewall setting should be turned off for simplicity. If you have tighter restrictions play with the Firewall Options… at your leisure.
Enabling Remote Login
For Vagrant to SSH into an OS X box we only need to enable Remote Login.
- Navigate to System Preferences > Sharing.
- Check Remote Login to turn it On
- Optional. Change the access permissions as necessary. All Users is selected by default. If you change this option to Only these users:, add the vagrant user you created.
Download Vagrant’s insecure key
Our vagrant user will use a SSH key to obtain authorized access to the box.
$ mkdir -p /Users/vagrant/.ssh $ chmod 0700 /Users/vagrant/.ssh $ curl -o /Users/vagrant/.ssh/authorized_keys --url https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub $ chmod 0600 /Users/vagrant/.ssh/authorized_keys $ chown -R vagrant /Users/vagrant/.ssh
Setting up password-less sudo
The vagrant user requires password-less sudo permission, run the following in Terminal:
$ sudo visudo
Add or modify the following lines as necessary:
Defaults env_keep += 'SSH_AUTH_SOCK' Defaults:vagrant !requiretty # Add the vagrant user at the end of the file vagrant ALL=NOPASSWD: ALL
Exit and save.
Optimizing the Guest
If we looked at the size of our VMware file at this point we’ll see it at around 16.26GB or 14.11GB, running or shutdown respectively. Shutting down the VM and shrinking it at this point will barely put a dent in reducing the VM size; it would only be decreased the VM by only 0.02GB.
However if we zero out the free space on the guest disk and shrink it we can reduce the VM to approximately 7.48GB.
- Open a Terminal and type:
$ diskutil secureErase freespace 0 Macintosh HD $ sudo halt
Finalizing the Box
From this point on everything done will be on the Host.
- Open a Terminal and change directory to the location the Virtual Machine was saved. Typically this is ~/Documents/Virtual Machines/.
- Change directory into the .vmwarevm file for your Virtual Machine.
Create a metadata.json
- Run the following in Terminal:
$ vi metadata.json
- Type the following contents into your editor:
- Save the file.
- Exit your editor.
Shrinking the Virtual Machine
- Open Terminal and type:
$ /Applications/VMware Fusion.app/Contents/Library/vmware-vdiskmanager -k
- Type a ‘space’ and the path to your VM’s virtual disk file.
- Hit return.
The above should have shrunk the virtual disk to around 7.48GB.
Packaging the Virtual Machine
Using tar and gzip to package the virtual machine reduces the box size. After boxed the VM should be around 5.63GB.
- Run the following in Terminal:
$ tar -cvzf mountain64-1_vmware.box ./*
After compression has completed. Move the .box file to a more suitable project working directory or a web server. For this example we’ll use ~/workspace/vagrant-example. This folder will likely not exist on your system so create it before trying to move it obviously.
Start Up the Vagrant OS X Base Box
In Terminal change directory to our project workspace, ~/workspace/vagrant-example. Run the following:
$ vagrant box add mountain64 mountain64-1_vmware.box $ vagrant init mountain64 mountain64-1_vmware.box
At this point if we want to run the virtual machine in headless mode we can just run:
$ vagrant up --provider=vmware_fusion
Or if we wanted to run in GUI mode, modify the generated Vagrantfile in our project workspace. Add the following lines:
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.provider :vmware_fusion do |v| v.gui = true end # Existing Vagrantfile generated template...
$ vagrant up --provider=vmware_fusion
If successful you’ll see the following output in Terminal:
Bringing machine 'default' up with 'vmware_fusion' provider... [default] Cloning VMware VM: 'mountain64'. This can take some time... [default] Verifying vmnet devices are healthy... [default] Preparing network adapters... [default] Fixed port collision for 22 => 2222. Now on port 2200. [default] Starting the VMware VM... [default] Waiting for the VM to finish booting... [default] The machine is booted and ready! [default] Forwarding ports... [default] -- 22 => 2200 [default] Configuring network adapters within the VM... [default] Enabling and configuring shared folders... [default] -- /Users/username/workspace/vagrant-example: /vagrant