Vagrant and Hyper-V

Having previously dismissed Vagrant as a VirtualBox tool I’ve revisited it and found it now supports (from v1.5 onwards) Hyper-V. THis is important if like me you have Windows 8.1 Pro or 10 Pro and have the Hyper-V feature turned on as VirtualBox will not work (see this blog for a workaround if it is really necessary).

When creating VMs, Vagrant needs to be able to manage Hyper-V and create a share for the VM to link to. While you can give a standard user the ability to do the former (which I highly recommend, see the end of the article for details), creating a share needs administrator rights. So unless you are just bringing up an isolated VM, you will need to run the console as administrator to run the vagrant up command.

The other change to make is that Vagrant will not always detect Hyper-V and default back to VirtualBox. You can force it to use Hyper-V by adding –provider=hyperv to the command line each time. A better solution is to add an environment variable named VAGRANT_DEFAULT_PROVIDER with the value hyperv – this can be done from Control Panel -> User Accounts -> Change my environment variables.

The last note is about virtual switches and networking. There are some limitations with Vagrant and networking as detailed here. In order for Vagrant to detect the IP, the virtual switch you connect to must be external. If you are still having problems check out the following post.

You are almost ready to go. You should be able to follow the getting started tutorial now, and see the VM being created in Hyper-V Manager, but it is unlikely you will be able to run vagrant ssh unless you have a command line ssh installed. Putty is probably the most popular SSH tool for Windows but you don’t want to manually change the private key and have to enter the details each time.

Thankfully there is a plug-in to do this for you from Nick Downs. Download Putty and make sure it’s directory is included in your path environment variable. Then run the following command to install the plug-in.

vagrant plugin install vagrant-multi-putty

You can now use vagrant putty instead of vagrant ssh.

To grant a standard user Hyper-V administrator rights simply add them to the local Hyper-V Administrators group (Computer Management -> System Tools -> Local Users and Groups -> Groups). Once added log off and on for the change to take affect. With this done you will be able to use the Hyper-V Manager snap-in as well as vagrant commands

Running JavaScript

I’ve covered running PowerShell scripts using the powershell.exe command in this previous post. The same principle will allow you to run any script engine. For example, you can run JavaScript as long as you have node installed. Assuming you add node to the path variable (the default) there are no additional options required, just specify the script to run as the argument.

I’ll also use this opportunity to save a couple of lines. One of the many great things about Python is it gives you the source code to standard library functions. This is a great way to improve your Python ability, looking at how problems were solved in the library. I want to see if I can improve on the try catch block so I need to know what subprocess.check_output actually does.

I can see the code for check_output by opening from the lib directory. Here we can see that the main work of check_output is done by just three lines, initial the Popen object, then call its communicate and poll methods. We can take the 6 lines of the try catch block and replace them with these 3 giving us the following.

import subprocess, tempfile, sys, os

def js(command):
    commandline = ['node.exe']
    with tempfile.NamedTemporaryFile(suffix=".js",delete=False) as f:
    process = subprocess.Popen(commandline,stdout=subprocess.PIPE)
    result, unused_err = process.communicate()
    exitcode = process.poll()
    return exitcode , result

retcode, retval = js("console.log('Hello Python from JavaScript (node.js)';\n")
print("Exit code: %d\nReturned: %s&" % (retcode, retval))

You can make the same changes to replace the try catch block on the PowerShell post from a few weeks back.