Entering a Windows Studio from a Mac

This post will walk you through how to enter a Windows Studio on a Mac. Be aware that this is completely unsupported and purely experimental.

What will you need?

  • VirtualBox (I used 6.0)
  • Vagrant (I used 2.2.4)
  • Docker (I used 18.09.6)

What this does

This uses Vagrant to create a Windows Server 2016 Core VM with Docker enabled. Contrary to popular belief, this does not require Hyper-V on the guest VM since it will not be using Hyper-V Container isolation (required on Windows 10). We will use the Windows Docker daemon as the Docker host on the Mac. Vagrant will sync our local key and artifact caches as well as our source code to the Windows VM so that they can be mounted into the remote container.

The end result should be a Habitat Studio that feels very similar to entering a Linux Studio on a Mac.

Steps to get things working

  1. Save the following Vagrantfile in the root of your source directory:
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "StefanScherer/windows_2016_docker"
  config.vm.network :forwarded_port, guest: 2375, host: 22375, id: "docker", auto_correct: true
  config.vm.synced_folder "~/.hab/cache/keys", "/hab/cache/keys"
  config.vm.synced_folder "~/.hab/cache/artifacts", "/hab/cache/artifacts"

  config.vm.provision "shell", inline: <<-SHELL
    set-content C:/ProgramData/docker/config/daemon.json -Value '{"hosts":["tcp://0.0.0.0:2375"]}'
    Restart-Service docker
    $env:DOCKER_HOST="tcp://localhost:2375"
    docker pull habitat-docker-registry.bintray.io/win-studio-x86_64-windows
  SHELL
end
  1. Run vagrant up from the source directory where you saved the Vagrantfile

This will pull down StefanScherer’s vagrant box that handles all of the Docker setup. It will sync the Habitat artifact and keys caches. Make sure these directories exist locally. It will also configure the remote Docker daemon to listen on tcp://0.0.0.0:2375 and forward 2375 to 22375 locally. Finally it will pull down the latest version of Habitat’s Windows Studio Docker image.

  1. Run the following export command to instruct your Docker client to use the Windows Docker daemon as your Docker host:
export DOCKER_HOST=tcp://0.0.0.0:22375`
  1. Run the following docker run command replacing mwrock with your own origin:
docker run --rm --tty --interactive --env HAB_LICENSE=accept-no-persist --env HAB_ORIGIN=mwrock --volume C:\\vagrant:c:/src --volume C:\\hab/cache/keys:c:/hab/cache/keys --volume C:\\hab/cache/artifacts:c:/hab/cache/artifacts habitat-docker-registry.bintray.io/win-studio-x86_64-windows:0.81.0 enter -n -o c:/

This is very similar to the same docker run command that hab studio enter runs under the hood.

Note that by default Vagrant creates a c:\vagrant directory synced to the local folder where your Vagrantfile exists which should be your source code.

Congratulations! You are now inside a Windows Studio and should be able to edit the plan files in your local editor and build them to a local results folder from which you can upload to the depot. Note that I get some permissions errors when syncing the origin keys but everything still “seems” to work.

Room for improvement

The above was the result of a experiment I conducted at the ChefConf 2019 hack day. Here are a few thoughts I have to make this better:

  • Leverage StefanScherer’s Packer templates to create your own image that pulls down the Habitat image as part of the image build. The templates support a docker_images variable that defaults to mcr.microsoft.com/windows/servercore:ltsc2016. Changing this to habitat-docker-registry.bintray.io/win-studio-x86_64-windows will make the vagrant up at least 5 minutes faster.
  • Figure out why the permissions errors occur because they are annoying.

Hi @mwrock. This is great work! I just wanted to add a sample script that I’m using in conjunction with what you’ve explained above.

The following script, alongside the Vagrantfile above, allows me on my Mac to setup either a linux habitat studio hab studio enter or a windows one ./hab_studio_enter.sh <ORIGIN>. If no <ORIGIN> is specified then ‘core’ is assumed. I’ve been able to build and test both linux and windows plans in the same directory on my Mac alone.

Save the following script alongside the Vagrantfile and call it ‘hab_studio_enter.sh’:

#!/bin/bash

_hab_origin="${1:-core}"
echo "starting the windows habitat studio with HAB_ORIGIN=${_hab_origin}"
if [[ ! -f "Vagrantfile" ]]; then echo "Vagrantfile needs to be in the same directory" && exit 1; fi

(
    export DOCKER_HOST=tcp://0.0.0.0:22375
    docker run --rm --tty --interactive \
        --env HAB_LICENSE=accept-no-persist \
        --env HAB_ORIGIN=${_hab_origin} \
        --volume C:\\vagrant:c:/src \
        --volume C:\\hab/cache/keys:c:/hab/cache/keys \
        --volume C:\\hab/cache/artifacts:c:/hab/cache/artifacts habitat-docker-registry.bintray.io/win-studio-x86_64-windows:0.81.0 enter -n -o c:/
)